blob: 2e1d12d2346e565fcc359c9b51782576f218a60a [file] [log] [blame]
Evan Chengbbf1db72009-05-07 05:42:24 +00001//===-- CodePlacementOpt.cpp - Code Placement pass. -----------------------===//
Evan Chengfb8075d2008-02-28 00:43:03 +00002//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
Evan Chengbbf1db72009-05-07 05:42:24 +000010// This file implements the pass that optimize code placement and align loop
11// headers to target specific alignment boundary.
Evan Chengfb8075d2008-02-28 00:43:03 +000012//
13//===----------------------------------------------------------------------===//
14
Evan Chengbbf1db72009-05-07 05:42:24 +000015#define DEBUG_TYPE "code-placement"
Evan Chengfb8075d2008-02-28 00:43:03 +000016#include "llvm/CodeGen/MachineLoopInfo.h"
17#include "llvm/CodeGen/MachineFunctionPass.h"
18#include "llvm/CodeGen/Passes.h"
Evan Cheng45e00102009-05-08 06:34:09 +000019#include "llvm/Target/TargetInstrInfo.h"
Evan Chengfb8075d2008-02-28 00:43:03 +000020#include "llvm/Target/TargetLowering.h"
21#include "llvm/Target/TargetMachine.h"
Evan Chengfb8075d2008-02-28 00:43:03 +000022#include "llvm/Support/Compiler.h"
23#include "llvm/Support/Debug.h"
Evan Cheng45e00102009-05-08 06:34:09 +000024#include "llvm/ADT/Statistic.h"
Evan Chengfb8075d2008-02-28 00:43:03 +000025using namespace llvm;
26
Evan Cheng45e00102009-05-08 06:34:09 +000027STATISTIC(NumHeaderAligned, "Number of loop header aligned");
28STATISTIC(NumIntraElim, "Number of intra loop branches eliminated");
29STATISTIC(NumIntraMoved, "Number of intra loop branches moved");
30
Evan Chengfb8075d2008-02-28 00:43:03 +000031namespace {
Evan Chengbbf1db72009-05-07 05:42:24 +000032 class CodePlacementOpt : public MachineFunctionPass {
Evan Cheng7132e122009-05-07 05:49:39 +000033 const MachineLoopInfo *MLI;
Evan Cheng45e00102009-05-08 06:34:09 +000034 const TargetInstrInfo *TII;
35 const TargetLowering *TLI;
36
37 /// ChangedMBBs - BBs which are modified by OptimizeIntraLoopEdges.
38 SmallPtrSet<MachineBasicBlock*, 8> ChangedMBBs;
39
40 /// UncondJmpMBBs - A list of BBs which are in loops and end with
41 /// unconditional branches.
42 SmallVector<std::pair<MachineBasicBlock*,MachineBasicBlock*>, 4>
43 UncondJmpMBBs;
44
45 /// LoopHeaders - A list of BBs which are loop headers.
46 SmallVector<MachineBasicBlock*, 4> LoopHeaders;
Evan Cheng7132e122009-05-07 05:49:39 +000047
Evan Chengfb8075d2008-02-28 00:43:03 +000048 public:
49 static char ID;
Evan Chengbbf1db72009-05-07 05:42:24 +000050 CodePlacementOpt() : MachineFunctionPass(&ID) {}
Evan Chengfb8075d2008-02-28 00:43:03 +000051
52 virtual bool runOnMachineFunction(MachineFunction &MF);
Evan Chengbbf1db72009-05-07 05:42:24 +000053 virtual const char *getPassName() const {
54 return "Code Placement Optimizater";
55 }
Evan Chengfb8075d2008-02-28 00:43:03 +000056
57 virtual void getAnalysisUsage(AnalysisUsage &AU) const {
58 AU.addRequired<MachineLoopInfo>();
Evan Cheng8b56a902008-09-22 22:21:38 +000059 AU.addPreservedID(MachineDominatorsID);
Evan Chengfb8075d2008-02-28 00:43:03 +000060 MachineFunctionPass::getAnalysisUsage(AU);
61 }
Evan Cheng7132e122009-05-07 05:49:39 +000062
63 private:
Evan Cheng45e00102009-05-08 06:34:09 +000064 bool OptimizeIntraLoopEdges();
Evan Cheng7132e122009-05-07 05:49:39 +000065 bool AlignLoops(MachineFunction &MF);
Evan Chengfb8075d2008-02-28 00:43:03 +000066 };
67
Evan Chengbbf1db72009-05-07 05:42:24 +000068 char CodePlacementOpt::ID = 0;
Evan Chengfb8075d2008-02-28 00:43:03 +000069} // end anonymous namespace
70
Evan Chengbbf1db72009-05-07 05:42:24 +000071FunctionPass *llvm::createCodePlacementOptPass() {
72 return new CodePlacementOpt();
73}
Evan Chengfb8075d2008-02-28 00:43:03 +000074
Evan Cheng45e00102009-05-08 06:34:09 +000075/// OptimizeBackEdges - Place loop back edges to move unconditional branches
76/// out of the loop.
77///
78/// A:
79/// ...
80/// <fallthrough to B>
81///
82/// B: --> loop header
83/// ...
84/// jcc <cond> C, [exit]
85///
86/// C:
87/// ...
88/// jmp B
89///
90/// ==>
91///
92/// A:
93/// ...
94/// jmp B
95///
96/// C: --> new loop header
97/// ...
98/// <fallthough to B>
99///
100/// B:
101/// ...
102/// jcc <cond> C, [exit]
103///
104bool CodePlacementOpt::OptimizeIntraLoopEdges() {
Evan Cheng45e00102009-05-08 06:34:09 +0000105 bool Changed = false;
106 for (unsigned i = 0, e = UncondJmpMBBs.size(); i != e; ++i) {
107 MachineBasicBlock *MBB = UncondJmpMBBs[i].first;
108 MachineBasicBlock *SuccMBB = UncondJmpMBBs[i].second;
109 MachineLoop *L = MLI->getLoopFor(MBB);
110 assert(L && "BB is expected to be in a loop!");
111
112 if (ChangedMBBs.count(MBB)) {
113 // BB has been modified, re-analyze.
114 MachineBasicBlock *TBB = 0, *FBB = 0;
115 SmallVector<MachineOperand, 4> Cond;
116 if (TII->AnalyzeBranch(*MBB, TBB, FBB, Cond) || !Cond.empty())
117 continue;
118 if (MLI->getLoopFor(TBB) != L || TBB->isLandingPad())
119 continue;
120 SuccMBB = TBB;
121 } else {
122 assert(MLI->getLoopFor(SuccMBB) == L &&
123 "Successor is not in the same loop!");
124 }
125
126 if (MBB->isLayoutSuccessor(SuccMBB)) {
127 // Successor is right after MBB, just eliminate the unconditional jmp.
128 // Can this happen?
129 TII->RemoveBranch(*MBB);
130 ChangedMBBs.insert(MBB);
131 ++NumIntraElim;
132 continue;
133 }
134
135 // Now check if the predecessor is fallthrough from any BB. If there is,
136 // that BB should be from outside the loop since edge will become a jmp.
137 bool OkToMove = true;
138 MachineBasicBlock *FtMBB = 0, *FtTBB = 0, *FtFBB = 0;
139 SmallVector<MachineOperand, 4> FtCond;
140 for (MachineBasicBlock::pred_iterator PI = SuccMBB->pred_begin(),
141 PE = SuccMBB->pred_end(); PI != PE; ++PI) {
142 MachineBasicBlock *PredMBB = *PI;
143 if (PredMBB->isLayoutSuccessor(SuccMBB)) {
144 if (TII->AnalyzeBranch(*PredMBB, FtTBB, FtFBB, FtCond)) {
145 OkToMove = false;
146 break;
147 }
148 if (!FtTBB)
149 FtTBB = SuccMBB;
150 else if (!FtFBB) {
151 assert(FtFBB != SuccMBB && "Unexpected control flow!");
152 FtFBB = SuccMBB;
153 }
154
155 // A fallthrough.
156 FtMBB = PredMBB;
157 MachineLoop *PL = MLI->getLoopFor(PredMBB);
Bob Wilson74b0ccc2009-05-12 03:48:10 +0000158 if (PL && (PL == L || PL->getLoopDepth() >= L->getLoopDepth()))
Evan Cheng45e00102009-05-08 06:34:09 +0000159 OkToMove = false;
Bob Wilson74b0ccc2009-05-12 03:48:10 +0000160
161 break;
Evan Cheng45e00102009-05-08 06:34:09 +0000162 }
163 }
164
165 if (!OkToMove)
166 continue;
167
168 // Is it profitable? If SuccMBB can fallthrough itself, that can be changed
169 // into a jmp.
170 MachineBasicBlock *TBB = 0, *FBB = 0;
171 SmallVector<MachineOperand, 4> Cond;
172 if (TII->AnalyzeBranch(*SuccMBB, TBB, FBB, Cond))
173 continue;
174 if (!TBB && Cond.empty())
175 TBB = next(MachineFunction::iterator(SuccMBB));
176 else if (!FBB && !Cond.empty())
177 FBB = next(MachineFunction::iterator(SuccMBB));
178
179 // This calculate the cost of the transformation. Also, it finds the *only*
180 // intra-loop edge if there is one.
181 int Cost = 0;
182 bool HasOneIntraSucc = true;
183 MachineBasicBlock *IntraSucc = 0;
184 for (MachineBasicBlock::succ_iterator SI = SuccMBB->succ_begin(),
185 SE = SuccMBB->succ_end(); SI != SE; ++SI) {
186 MachineBasicBlock *SSMBB = *SI;
187 if (MLI->getLoopFor(SSMBB) == L) {
188 if (!IntraSucc)
189 IntraSucc = SSMBB;
190 else
191 HasOneIntraSucc = false;
192 }
193
194 if (SuccMBB->isLayoutSuccessor(SSMBB))
195 // This will become a jmp.
196 ++Cost;
Nick Lewycky0ab2dce2009-05-08 06:57:41 +0000197 else if (MBB->isLayoutSuccessor(SSMBB)) {
Evan Cheng45e00102009-05-08 06:34:09 +0000198 // One of the successor will become the new fallthrough.
199 if (SSMBB == FBB) {
200 FBB = 0;
201 --Cost;
202 } else if (!FBB && SSMBB == TBB && Cond.empty()) {
203 TBB = 0;
204 --Cost;
Evan Cheng4b7f7a62009-05-08 09:35:53 +0000205 } else if (!Cond.empty() && !TII->ReverseBranchCondition(Cond)) {
206 assert(SSMBB == TBB);
Evan Cheng45e00102009-05-08 06:34:09 +0000207 TBB = FBB;
208 FBB = 0;
209 --Cost;
210 }
Nick Lewycky0ab2dce2009-05-08 06:57:41 +0000211 }
Evan Cheng45e00102009-05-08 06:34:09 +0000212 }
213 if (Cost)
214 continue;
215
216 // Now, let's move the successor to below the BB to eliminate the jmp.
217 SuccMBB->moveAfter(MBB);
218 TII->RemoveBranch(*MBB);
219 TII->RemoveBranch(*SuccMBB);
220 if (TBB)
221 TII->InsertBranch(*SuccMBB, TBB, FBB, Cond);
222 ChangedMBBs.insert(MBB);
223 ChangedMBBs.insert(SuccMBB);
224 if (FtMBB) {
225 TII->RemoveBranch(*FtMBB);
226 TII->InsertBranch(*FtMBB, FtTBB, FtFBB, FtCond);
227 ChangedMBBs.insert(FtMBB);
228 }
229
230 // If BB is the loop latch, we may have a new loop headr.
231 if (MBB == L->getLoopLatch()) {
232 assert(MLI->isLoopHeader(SuccMBB) &&
233 "Only succ of loop latch is not the header?");
234 if (HasOneIntraSucc && IntraSucc)
235 std::replace(LoopHeaders.begin(),LoopHeaders.end(), SuccMBB, IntraSucc);
236 }
237 }
238
239 ++NumIntraMoved;
240 return Changed;
241}
242
Evan Cheng0269d3c2009-05-08 19:01:44 +0000243/// HeaderShouldBeAligned - Return true if the specified loop header block
244/// should be aligned. For now, we will not align it if all the predcessors
245/// (i.e. loop back edges) are laid out above the header. FIXME: Do not
246/// align small loops.
247static bool HeaderShouldBeAligned(MachineBasicBlock *MBB) {
248 for (MachineBasicBlock::pred_iterator PI = MBB->pred_begin(),
249 PE = MBB->pred_end(); PI != PE; ++PI) {
250 MachineBasicBlock *PredMBB = *PI;
Evan Cheng53744052009-05-09 19:18:01 +0000251 if (PredMBB == MBB || PredMBB->getNumber() > MBB->getNumber())
Evan Cheng0269d3c2009-05-08 19:01:44 +0000252 return true;
253 }
254 return false;
255}
256
Evan Cheng7132e122009-05-07 05:49:39 +0000257/// AlignLoops - Align loop headers to target preferred alignments.
258///
259bool CodePlacementOpt::AlignLoops(MachineFunction &MF) {
Evan Cheng45e00102009-05-08 06:34:09 +0000260 const Function *F = MF.getFunction();
261 if (F->hasFnAttr(Attribute::OptimizeForSize))
Evan Cheng4f658e92008-02-29 17:52:15 +0000262 return false;
263
264 unsigned Align = TLI->getPrefLoopAlignment();
Evan Chengfb8075d2008-02-28 00:43:03 +0000265 if (!Align)
266 return false; // Don't care about loop alignment.
267
Evan Cheng45e00102009-05-08 06:34:09 +0000268 // Make sure blocks are numbered in order
269 MF.RenumberBlocks();
Devang Patel4ae641f2008-10-01 23:18:38 +0000270
Evan Cheng7132e122009-05-07 05:49:39 +0000271 bool Changed = false;
Evan Cheng45e00102009-05-08 06:34:09 +0000272 for (unsigned i = 0, e = LoopHeaders.size(); i != e; ++i) {
273 MachineBasicBlock *HeaderMBB = LoopHeaders[i];
274 MachineBasicBlock *PredMBB = prior(MachineFunction::iterator(HeaderMBB));
Evan Cheng0269d3c2009-05-08 19:01:44 +0000275 if (MLI->getLoopFor(HeaderMBB) == MLI->getLoopFor(PredMBB))
Evan Cheng45e00102009-05-08 06:34:09 +0000276 // If previously BB is in the same loop, don't align this BB. We want
277 // to prevent adding noop's inside a loop.
Evan Cheng0269d3c2009-05-08 19:01:44 +0000278 continue;
279 if (HeaderShouldBeAligned(HeaderMBB)) {
Evan Cheng45e00102009-05-08 06:34:09 +0000280 HeaderMBB->setAlignment(Align);
Evan Cheng7132e122009-05-07 05:49:39 +0000281 Changed = true;
Evan Cheng45e00102009-05-08 06:34:09 +0000282 ++NumHeaderAligned;
Evan Chengdf908412008-11-27 01:16:00 +0000283 }
Evan Chengfb8075d2008-02-28 00:43:03 +0000284 }
285
Evan Cheng7132e122009-05-07 05:49:39 +0000286 return Changed;
287}
288
289bool CodePlacementOpt::runOnMachineFunction(MachineFunction &MF) {
290 MLI = &getAnalysis<MachineLoopInfo>();
291 if (MLI->empty())
292 return false; // No loops.
293
Evan Cheng45e00102009-05-08 06:34:09 +0000294 TLI = MF.getTarget().getTargetLowering();
295 TII = MF.getTarget().getInstrInfo();
296
297 // Analyze the BBs first and keep track of loop headers and BBs that
298 // end with an unconditional jmp to another block in the same loop.
299 for (MachineFunction::iterator I = MF.begin(), E = MF.end(); I != E; ++I) {
300 MachineBasicBlock *MBB = I;
301 if (MBB->isLandingPad())
302 continue;
303 MachineLoop *L = MLI->getLoopFor(MBB);
304 if (!L)
305 continue;
306 if (MLI->isLoopHeader(MBB))
307 LoopHeaders.push_back(MBB);
308
309 MachineBasicBlock *TBB = 0, *FBB = 0;
310 SmallVector<MachineOperand, 4> Cond;
311 if (TII->AnalyzeBranch(*MBB, TBB, FBB, Cond) || !Cond.empty())
312 continue;
313 if (MLI->getLoopFor(TBB) == L && !TBB->isLandingPad())
314 UncondJmpMBBs.push_back(std::make_pair(MBB, TBB));
315 }
316
317 bool Changed = OptimizeIntraLoopEdges();
318
Evan Cheng7132e122009-05-07 05:49:39 +0000319 Changed |= AlignLoops(MF);
320
Evan Cheng45e00102009-05-08 06:34:09 +0000321 ChangedMBBs.clear();
322 UncondJmpMBBs.clear();
323 LoopHeaders.clear();
324
Evan Cheng7132e122009-05-07 05:49:39 +0000325 return Changed;
Evan Chengfb8075d2008-02-28 00:43:03 +0000326}