blob: 4276651d3bc80a2d30b589df627d4bfd36eeac29 [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 Cheng45e00102009-05-08 06:34:09 +000022#include "llvm/Support/CommandLine.h"
Evan Chengfb8075d2008-02-28 00:43:03 +000023#include "llvm/Support/Compiler.h"
24#include "llvm/Support/Debug.h"
Evan Cheng45e00102009-05-08 06:34:09 +000025#include "llvm/ADT/Statistic.h"
Evan Chengfb8075d2008-02-28 00:43:03 +000026using namespace llvm;
27
Evan Cheng45e00102009-05-08 06:34:09 +000028static cl::opt<bool>
29OptLoopBBPlacement("opt-loop-bb-placement",
30 cl::init(false), cl::Hidden,
31 cl::desc("Optimize block placements in loops"));
32
33STATISTIC(NumHeaderAligned, "Number of loop header aligned");
34STATISTIC(NumIntraElim, "Number of intra loop branches eliminated");
35STATISTIC(NumIntraMoved, "Number of intra loop branches moved");
36
Evan Chengfb8075d2008-02-28 00:43:03 +000037namespace {
Evan Chengbbf1db72009-05-07 05:42:24 +000038 class CodePlacementOpt : public MachineFunctionPass {
Evan Cheng7132e122009-05-07 05:49:39 +000039 const MachineLoopInfo *MLI;
Evan Cheng45e00102009-05-08 06:34:09 +000040 const TargetInstrInfo *TII;
41 const TargetLowering *TLI;
42
43 /// ChangedMBBs - BBs which are modified by OptimizeIntraLoopEdges.
44 SmallPtrSet<MachineBasicBlock*, 8> ChangedMBBs;
45
46 /// UncondJmpMBBs - A list of BBs which are in loops and end with
47 /// unconditional branches.
48 SmallVector<std::pair<MachineBasicBlock*,MachineBasicBlock*>, 4>
49 UncondJmpMBBs;
50
51 /// LoopHeaders - A list of BBs which are loop headers.
52 SmallVector<MachineBasicBlock*, 4> LoopHeaders;
Evan Cheng7132e122009-05-07 05:49:39 +000053
Evan Chengfb8075d2008-02-28 00:43:03 +000054 public:
55 static char ID;
Evan Chengbbf1db72009-05-07 05:42:24 +000056 CodePlacementOpt() : MachineFunctionPass(&ID) {}
Evan Chengfb8075d2008-02-28 00:43:03 +000057
58 virtual bool runOnMachineFunction(MachineFunction &MF);
Evan Chengbbf1db72009-05-07 05:42:24 +000059 virtual const char *getPassName() const {
60 return "Code Placement Optimizater";
61 }
Evan Chengfb8075d2008-02-28 00:43:03 +000062
63 virtual void getAnalysisUsage(AnalysisUsage &AU) const {
64 AU.addRequired<MachineLoopInfo>();
Evan Cheng8b56a902008-09-22 22:21:38 +000065 AU.addPreservedID(MachineDominatorsID);
Evan Chengfb8075d2008-02-28 00:43:03 +000066 MachineFunctionPass::getAnalysisUsage(AU);
67 }
Evan Cheng7132e122009-05-07 05:49:39 +000068
69 private:
Evan Cheng45e00102009-05-08 06:34:09 +000070 bool OptimizeIntraLoopEdges();
Evan Cheng7132e122009-05-07 05:49:39 +000071 bool AlignLoops(MachineFunction &MF);
Evan Chengfb8075d2008-02-28 00:43:03 +000072 };
73
Evan Chengbbf1db72009-05-07 05:42:24 +000074 char CodePlacementOpt::ID = 0;
Evan Chengfb8075d2008-02-28 00:43:03 +000075} // end anonymous namespace
76
Evan Chengbbf1db72009-05-07 05:42:24 +000077FunctionPass *llvm::createCodePlacementOptPass() {
78 return new CodePlacementOpt();
79}
Evan Chengfb8075d2008-02-28 00:43:03 +000080
Evan Cheng45e00102009-05-08 06:34:09 +000081/// OptimizeBackEdges - Place loop back edges to move unconditional branches
82/// out of the loop.
83///
84/// A:
85/// ...
86/// <fallthrough to B>
87///
88/// B: --> loop header
89/// ...
90/// jcc <cond> C, [exit]
91///
92/// C:
93/// ...
94/// jmp B
95///
96/// ==>
97///
98/// A:
99/// ...
100/// jmp B
101///
102/// C: --> new loop header
103/// ...
104/// <fallthough to B>
105///
106/// B:
107/// ...
108/// jcc <cond> C, [exit]
109///
110bool CodePlacementOpt::OptimizeIntraLoopEdges() {
111 if (!OptLoopBBPlacement)
112 return false;
113
114 bool Changed = false;
115 for (unsigned i = 0, e = UncondJmpMBBs.size(); i != e; ++i) {
116 MachineBasicBlock *MBB = UncondJmpMBBs[i].first;
117 MachineBasicBlock *SuccMBB = UncondJmpMBBs[i].second;
118 MachineLoop *L = MLI->getLoopFor(MBB);
119 assert(L && "BB is expected to be in a loop!");
120
121 if (ChangedMBBs.count(MBB)) {
122 // BB has been modified, re-analyze.
123 MachineBasicBlock *TBB = 0, *FBB = 0;
124 SmallVector<MachineOperand, 4> Cond;
125 if (TII->AnalyzeBranch(*MBB, TBB, FBB, Cond) || !Cond.empty())
126 continue;
127 if (MLI->getLoopFor(TBB) != L || TBB->isLandingPad())
128 continue;
129 SuccMBB = TBB;
130 } else {
131 assert(MLI->getLoopFor(SuccMBB) == L &&
132 "Successor is not in the same loop!");
133 }
134
135 if (MBB->isLayoutSuccessor(SuccMBB)) {
136 // Successor is right after MBB, just eliminate the unconditional jmp.
137 // Can this happen?
138 TII->RemoveBranch(*MBB);
139 ChangedMBBs.insert(MBB);
140 ++NumIntraElim;
141 continue;
142 }
143
144 // Now check if the predecessor is fallthrough from any BB. If there is,
145 // that BB should be from outside the loop since edge will become a jmp.
146 bool OkToMove = true;
147 MachineBasicBlock *FtMBB = 0, *FtTBB = 0, *FtFBB = 0;
148 SmallVector<MachineOperand, 4> FtCond;
149 for (MachineBasicBlock::pred_iterator PI = SuccMBB->pred_begin(),
150 PE = SuccMBB->pred_end(); PI != PE; ++PI) {
151 MachineBasicBlock *PredMBB = *PI;
152 if (PredMBB->isLayoutSuccessor(SuccMBB)) {
153 if (TII->AnalyzeBranch(*PredMBB, FtTBB, FtFBB, FtCond)) {
154 OkToMove = false;
155 break;
156 }
157 if (!FtTBB)
158 FtTBB = SuccMBB;
159 else if (!FtFBB) {
160 assert(FtFBB != SuccMBB && "Unexpected control flow!");
161 FtFBB = SuccMBB;
162 }
163
164 // A fallthrough.
165 FtMBB = PredMBB;
166 MachineLoop *PL = MLI->getLoopFor(PredMBB);
167 if (PL && (PL == L || PL->getLoopDepth() >= L->getLoopDepth())) {
168 OkToMove = false;
169 break;
170 }
171 }
172 }
173
174 if (!OkToMove)
175 continue;
176
177 // Is it profitable? If SuccMBB can fallthrough itself, that can be changed
178 // into a jmp.
179 MachineBasicBlock *TBB = 0, *FBB = 0;
180 SmallVector<MachineOperand, 4> Cond;
181 if (TII->AnalyzeBranch(*SuccMBB, TBB, FBB, Cond))
182 continue;
183 if (!TBB && Cond.empty())
184 TBB = next(MachineFunction::iterator(SuccMBB));
185 else if (!FBB && !Cond.empty())
186 FBB = next(MachineFunction::iterator(SuccMBB));
187
188 // This calculate the cost of the transformation. Also, it finds the *only*
189 // intra-loop edge if there is one.
190 int Cost = 0;
191 bool HasOneIntraSucc = true;
192 MachineBasicBlock *IntraSucc = 0;
193 for (MachineBasicBlock::succ_iterator SI = SuccMBB->succ_begin(),
194 SE = SuccMBB->succ_end(); SI != SE; ++SI) {
195 MachineBasicBlock *SSMBB = *SI;
196 if (MLI->getLoopFor(SSMBB) == L) {
197 if (!IntraSucc)
198 IntraSucc = SSMBB;
199 else
200 HasOneIntraSucc = false;
201 }
202
203 if (SuccMBB->isLayoutSuccessor(SSMBB))
204 // This will become a jmp.
205 ++Cost;
Nick Lewycky0ab2dce2009-05-08 06:57:41 +0000206 else if (MBB->isLayoutSuccessor(SSMBB)) {
Evan Cheng45e00102009-05-08 06:34:09 +0000207 // One of the successor will become the new fallthrough.
208 if (SSMBB == FBB) {
209 FBB = 0;
210 --Cost;
211 } else if (!FBB && SSMBB == TBB && Cond.empty()) {
212 TBB = 0;
213 --Cost;
Evan Cheng4b7f7a62009-05-08 09:35:53 +0000214 } else if (!Cond.empty() && !TII->ReverseBranchCondition(Cond)) {
215 assert(SSMBB == TBB);
Evan Cheng45e00102009-05-08 06:34:09 +0000216 TBB = FBB;
217 FBB = 0;
218 --Cost;
219 }
Nick Lewycky0ab2dce2009-05-08 06:57:41 +0000220 }
Evan Cheng45e00102009-05-08 06:34:09 +0000221 }
222 if (Cost)
223 continue;
224
225 // Now, let's move the successor to below the BB to eliminate the jmp.
226 SuccMBB->moveAfter(MBB);
227 TII->RemoveBranch(*MBB);
228 TII->RemoveBranch(*SuccMBB);
229 if (TBB)
230 TII->InsertBranch(*SuccMBB, TBB, FBB, Cond);
231 ChangedMBBs.insert(MBB);
232 ChangedMBBs.insert(SuccMBB);
233 if (FtMBB) {
234 TII->RemoveBranch(*FtMBB);
235 TII->InsertBranch(*FtMBB, FtTBB, FtFBB, FtCond);
236 ChangedMBBs.insert(FtMBB);
237 }
238
239 // If BB is the loop latch, we may have a new loop headr.
240 if (MBB == L->getLoopLatch()) {
241 assert(MLI->isLoopHeader(SuccMBB) &&
242 "Only succ of loop latch is not the header?");
243 if (HasOneIntraSucc && IntraSucc)
244 std::replace(LoopHeaders.begin(),LoopHeaders.end(), SuccMBB, IntraSucc);
245 }
246 }
247
248 ++NumIntraMoved;
249 return Changed;
250}
251
Evan Cheng7132e122009-05-07 05:49:39 +0000252/// AlignLoops - Align loop headers to target preferred alignments.
253///
254bool CodePlacementOpt::AlignLoops(MachineFunction &MF) {
Evan Cheng45e00102009-05-08 06:34:09 +0000255 const Function *F = MF.getFunction();
256 if (F->hasFnAttr(Attribute::OptimizeForSize))
Evan Cheng4f658e92008-02-29 17:52:15 +0000257 return false;
258
259 unsigned Align = TLI->getPrefLoopAlignment();
Evan Chengfb8075d2008-02-28 00:43:03 +0000260 if (!Align)
261 return false; // Don't care about loop alignment.
262
Evan Cheng45e00102009-05-08 06:34:09 +0000263 // Make sure blocks are numbered in order
264 MF.RenumberBlocks();
Devang Patel4ae641f2008-10-01 23:18:38 +0000265
Evan Cheng7132e122009-05-07 05:49:39 +0000266 bool Changed = false;
Evan Cheng45e00102009-05-08 06:34:09 +0000267 for (unsigned i = 0, e = LoopHeaders.size(); i != e; ++i) {
268 MachineBasicBlock *HeaderMBB = LoopHeaders[i];
269 MachineBasicBlock *PredMBB = prior(MachineFunction::iterator(HeaderMBB));
270 if (MLI->getLoopFor(HeaderMBB) != MLI->getLoopFor(PredMBB)) {
271 // If previously BB is in the same loop, don't align this BB. We want
272 // to prevent adding noop's inside a loop.
273 HeaderMBB->setAlignment(Align);
Evan Cheng7132e122009-05-07 05:49:39 +0000274 Changed = true;
Evan Cheng45e00102009-05-08 06:34:09 +0000275 ++NumHeaderAligned;
Evan Chengdf908412008-11-27 01:16:00 +0000276 }
Evan Chengfb8075d2008-02-28 00:43:03 +0000277 }
278
Evan Cheng7132e122009-05-07 05:49:39 +0000279 return Changed;
280}
281
282bool CodePlacementOpt::runOnMachineFunction(MachineFunction &MF) {
283 MLI = &getAnalysis<MachineLoopInfo>();
284 if (MLI->empty())
285 return false; // No loops.
286
Evan Cheng45e00102009-05-08 06:34:09 +0000287 TLI = MF.getTarget().getTargetLowering();
288 TII = MF.getTarget().getInstrInfo();
289
290 // Analyze the BBs first and keep track of loop headers and BBs that
291 // end with an unconditional jmp to another block in the same loop.
292 for (MachineFunction::iterator I = MF.begin(), E = MF.end(); I != E; ++I) {
293 MachineBasicBlock *MBB = I;
294 if (MBB->isLandingPad())
295 continue;
296 MachineLoop *L = MLI->getLoopFor(MBB);
297 if (!L)
298 continue;
299 if (MLI->isLoopHeader(MBB))
300 LoopHeaders.push_back(MBB);
301
302 MachineBasicBlock *TBB = 0, *FBB = 0;
303 SmallVector<MachineOperand, 4> Cond;
304 if (TII->AnalyzeBranch(*MBB, TBB, FBB, Cond) || !Cond.empty())
305 continue;
306 if (MLI->getLoopFor(TBB) == L && !TBB->isLandingPad())
307 UncondJmpMBBs.push_back(std::make_pair(MBB, TBB));
308 }
309
310 bool Changed = OptimizeIntraLoopEdges();
311
Evan Cheng7132e122009-05-07 05:49:39 +0000312 Changed |= AlignLoops(MF);
313
Evan Cheng45e00102009-05-08 06:34:09 +0000314 ChangedMBBs.clear();
315 UncondJmpMBBs.clear();
316 LoopHeaders.clear();
317
Evan Cheng7132e122009-05-07 05:49:39 +0000318 return Changed;
Evan Chengfb8075d2008-02-28 00:43:03 +0000319}