blob: c4c9762115c2a9ce522e0e05958f921a164ad414 [file] [log] [blame]
Tom Stellard6b7d99d2012-12-19 22:10:31 +00001//===-- AMDGPUStructurizeCFG.cpp - ------------------===//
2//
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//
10/// \file
11/// The pass implemented in this file transforms the programs control flow
12/// graph into a form that's suitable for code generation on hardware that
13/// implements control flow by execution masking. This currently includes all
14/// AMD GPUs but may as well be useful for other types of hardware.
15//
16//===----------------------------------------------------------------------===//
17
18#include "AMDGPU.h"
Tom Stellard6b7d99d2012-12-19 22:10:31 +000019#include "llvm/ADT/SCCIterator.h"
Tom Stellard6b7d99d2012-12-19 22:10:31 +000020#include "llvm/Analysis/RegionInfo.h"
Chandler Carruth58a2cbe2013-01-02 10:22:59 +000021#include "llvm/Analysis/RegionIterator.h"
Tom Stellard6b7d99d2012-12-19 22:10:31 +000022#include "llvm/Analysis/RegionPass.h"
Chandler Carruth0b8c9a82013-01-02 11:36:10 +000023#include "llvm/IR/Module.h"
Tom Stellard6b7d99d2012-12-19 22:10:31 +000024#include "llvm/Transforms/Utils/SSAUpdater.h"
25
26using namespace llvm;
27
28namespace {
29
30// Definition of the complex types used in this pass.
31
32typedef std::pair<BasicBlock *, Value *> BBValuePair;
Tom Stellard6b7d99d2012-12-19 22:10:31 +000033
34typedef SmallVector<RegionNode*, 8> RNVector;
35typedef SmallVector<BasicBlock*, 8> BBVector;
Tom Stellard27f5d062013-02-08 22:24:37 +000036typedef SmallVector<BranchInst*, 8> BranchVector;
Tom Stellard6b7d99d2012-12-19 22:10:31 +000037typedef SmallVector<BBValuePair, 2> BBValueVector;
38
Tom Stellard27f5d062013-02-08 22:24:37 +000039typedef SmallPtrSet<BasicBlock *, 8> BBSet;
40
Tom Stellard6b7d99d2012-12-19 22:10:31 +000041typedef DenseMap<PHINode *, BBValueVector> PhiMap;
42typedef DenseMap<BasicBlock *, PhiMap> BBPhiMap;
43typedef DenseMap<BasicBlock *, Value *> BBPredicates;
44typedef DenseMap<BasicBlock *, BBPredicates> PredMap;
Tom Stellard13cf6cb2013-02-08 22:24:35 +000045typedef DenseMap<BasicBlock *, BBVector> BB2BBVecMap;
Tom Stellard6b7d99d2012-12-19 22:10:31 +000046
47// The name for newly created blocks.
48
49static const char *FlowBlockName = "Flow";
50
51/// @brief Transforms the control flow graph on one single entry/exit region
52/// at a time.
53///
54/// After the transform all "If"/"Then"/"Else" style control flow looks like
55/// this:
56///
57/// \verbatim
58/// 1
59/// ||
60/// | |
61/// 2 |
62/// | /
63/// |/
64/// 3
65/// || Where:
66/// | | 1 = "If" block, calculates the condition
67/// 4 | 2 = "Then" subregion, runs if the condition is true
68/// | / 3 = "Flow" blocks, newly inserted flow blocks, rejoins the flow
69/// |/ 4 = "Else" optional subregion, runs if the condition is false
70/// 5 5 = "End" block, also rejoins the control flow
71/// \endverbatim
72///
73/// Control flow is expressed as a branch where the true exit goes into the
74/// "Then"/"Else" region, while the false exit skips the region
75/// The condition for the optional "Else" region is expressed as a PHI node.
76/// The incomming values of the PHI node are true for the "If" edge and false
77/// for the "Then" edge.
78///
79/// Additionally to that even complicated loops look like this:
80///
81/// \verbatim
82/// 1
83/// ||
84/// | |
85/// 2 ^ Where:
86/// | / 1 = "Entry" block
87/// |/ 2 = "Loop" optional subregion, with all exits at "Flow" block
88/// 3 3 = "Flow" block, with back edge to entry block
89/// |
90/// \endverbatim
91///
92/// The back edge of the "Flow" block is always on the false side of the branch
93/// while the true side continues the general flow. So the loop condition
94/// consist of a network of PHI nodes where the true incoming values expresses
95/// breaks and the false values expresses continue states.
96class AMDGPUStructurizeCFG : public RegionPass {
97
98 static char ID;
99
100 Type *Boolean;
101 ConstantInt *BoolTrue;
102 ConstantInt *BoolFalse;
103 UndefValue *BoolUndef;
104
105 Function *Func;
106 Region *ParentRegion;
107
108 DominatorTree *DT;
109
110 RNVector Order;
Tom Stellardf4e471a2013-02-08 22:24:38 +0000111 BBSet Visited;
Tom Stellard6b7d99d2012-12-19 22:10:31 +0000112 PredMap Predicates;
113 BBPhiMap DeletedPhis;
Tom Stellard13cf6cb2013-02-08 22:24:35 +0000114 BB2BBVecMap AddedPhis;
Tom Stellard27f5d062013-02-08 22:24:37 +0000115 BranchVector Conditions;
Tom Stellard6b7d99d2012-12-19 22:10:31 +0000116
117 BasicBlock *LoopStart;
118 BasicBlock *LoopEnd;
Tom Stellard27f5d062013-02-08 22:24:37 +0000119 BBSet LoopTargets;
Tom Stellard6b7d99d2012-12-19 22:10:31 +0000120 BBPredicates LoopPred;
121
122 void orderNodes();
123
Tom Stellard27f5d062013-02-08 22:24:37 +0000124 Value *buildCondition(BranchInst *Term, unsigned Idx, bool Invert);
Tom Stellard6b7d99d2012-12-19 22:10:31 +0000125
Tom Stellard27f5d062013-02-08 22:24:37 +0000126 bool analyzeLoopStart(BasicBlock *From, BasicBlock *To, Value *Condition);
Tom Stellard6b7d99d2012-12-19 22:10:31 +0000127
Tom Stellard27f5d062013-02-08 22:24:37 +0000128 void analyzeNode(RegionNode *N);
129
130 void analyzeLoopEnd(RegionNode *N);
Tom Stellard6b7d99d2012-12-19 22:10:31 +0000131
132 void collectInfos();
133
Tom Stellard27f5d062013-02-08 22:24:37 +0000134 void insertConditions();
135
Tom Stellard13cf6cb2013-02-08 22:24:35 +0000136 void delPhiValues(BasicBlock *From, BasicBlock *To);
137
138 void addPhiValues(BasicBlock *From, BasicBlock *To);
139
140 void setPhiValues();
141
Tom Stellard6b7d99d2012-12-19 22:10:31 +0000142 void killTerminator(BasicBlock *BB);
143
Tom Stellardf4e471a2013-02-08 22:24:38 +0000144 void changeExit(RegionNode *Node, BasicBlock *NewExit,
145 bool IncludeDominator);
Tom Stellard6b7d99d2012-12-19 22:10:31 +0000146
Tom Stellardf4e471a2013-02-08 22:24:38 +0000147 BasicBlock *getNextFlow(BasicBlock *Dominator);
Tom Stellard6b7d99d2012-12-19 22:10:31 +0000148
Tom Stellardf4e471a2013-02-08 22:24:38 +0000149 BasicBlock *needPrefix(RegionNode *&Prev, RegionNode *Node);
Tom Stellard6b7d99d2012-12-19 22:10:31 +0000150
Tom Stellardf4e471a2013-02-08 22:24:38 +0000151 BasicBlock *needPostfix(BasicBlock *Flow, bool ExitUseAllowed);
152
153 RegionNode *getNextPrev(BasicBlock *Next);
154
155 bool dominatesPredicates(BasicBlock *BB, RegionNode *Node);
156
157 bool isPredictableTrue(RegionNode *Who, RegionNode *Where);
158
159 RegionNode *wireFlow(RegionNode *&Prev, bool ExitUseAllowed);
Tom Stellard6b7d99d2012-12-19 22:10:31 +0000160
161 void createFlow();
162
Tom Stellard6b7d99d2012-12-19 22:10:31 +0000163 void rebuildSSA();
164
165public:
166 AMDGPUStructurizeCFG():
167 RegionPass(ID) {
168
169 initializeRegionInfoPass(*PassRegistry::getPassRegistry());
170 }
171
172 virtual bool doInitialization(Region *R, RGPassManager &RGM);
173
174 virtual bool runOnRegion(Region *R, RGPassManager &RGM);
175
176 virtual const char *getPassName() const {
177 return "AMDGPU simplify control flow";
178 }
179
180 void getAnalysisUsage(AnalysisUsage &AU) const {
181
182 AU.addRequired<DominatorTree>();
183 AU.addPreserved<DominatorTree>();
184 RegionPass::getAnalysisUsage(AU);
185 }
186
187};
188
189} // end anonymous namespace
190
191char AMDGPUStructurizeCFG::ID = 0;
192
193/// \brief Initialize the types and constants used in the pass
194bool AMDGPUStructurizeCFG::doInitialization(Region *R, RGPassManager &RGM) {
Tom Stellard6b7d99d2012-12-19 22:10:31 +0000195 LLVMContext &Context = R->getEntry()->getContext();
196
197 Boolean = Type::getInt1Ty(Context);
198 BoolTrue = ConstantInt::getTrue(Context);
199 BoolFalse = ConstantInt::getFalse(Context);
200 BoolUndef = UndefValue::get(Boolean);
201
202 return false;
203}
204
205/// \brief Build up the general order of nodes
206void AMDGPUStructurizeCFG::orderNodes() {
Tom Stellard6b7d99d2012-12-19 22:10:31 +0000207 scc_iterator<Region *> I = scc_begin(ParentRegion),
208 E = scc_end(ParentRegion);
209 for (Order.clear(); I != E; ++I) {
210 std::vector<RegionNode *> &Nodes = *I;
211 Order.append(Nodes.begin(), Nodes.end());
212 }
213}
214
Tom Stellard27f5d062013-02-08 22:24:37 +0000215/// \brief Build the condition for one edge
216Value *AMDGPUStructurizeCFG::buildCondition(BranchInst *Term, unsigned Idx,
217 bool Invert) {
218 Value *Cond = Invert ? BoolFalse : BoolTrue;
219 if (Term->isConditional()) {
220 Cond = Term->getCondition();
Tom Stellard6b7d99d2012-12-19 22:10:31 +0000221
Tom Stellard27f5d062013-02-08 22:24:37 +0000222 if (Idx != Invert)
223 Cond = BinaryOperator::CreateNot(Cond, "", Term);
224 }
225 return Cond;
226}
227
228/// \brief Analyze the start of a loop and insert predicates as necessary
229bool AMDGPUStructurizeCFG::analyzeLoopStart(BasicBlock *From, BasicBlock *To,
230 Value *Condition) {
231 LoopPred[From] = Condition;
232 LoopTargets.insert(To);
233 if (!LoopStart) {
234 LoopStart = To;
235 return true;
236
237 } else if (LoopStart == To)
238 return true;
239
240 // We need to handle the case of intersecting loops, e. g.
241 //
242 // /----<-----
243 // | |
244 // -> A -> B -> C -> D
245 // | |
246 // -----<----/
247
248 RNVector::reverse_iterator OI = Order.rbegin(), OE = Order.rend();
249
250 for (;OI != OE; ++OI)
251 if ((*OI)->getEntry() == LoopStart)
252 break;
253
254 for (;OI != OE && (*OI)->getEntry() != To; ++OI) {
255 BBPredicates &Pred = Predicates[(*OI)->getEntry()];
256 if (!Pred.count(From))
257 Pred[From] = Condition;
258 }
259 return false;
260}
261
262/// \brief Analyze the predecessors of each block and build up predicates
263void AMDGPUStructurizeCFG::analyzeNode(RegionNode *N) {
Tom Stellard6b7d99d2012-12-19 22:10:31 +0000264 RegionInfo *RI = ParentRegion->getRegionInfo();
Tom Stellard27f5d062013-02-08 22:24:37 +0000265 BasicBlock *BB = N->getEntry();
266 BBPredicates &Pred = Predicates[BB];
Tom Stellard6b7d99d2012-12-19 22:10:31 +0000267
Tom Stellard27f5d062013-02-08 22:24:37 +0000268 for (pred_iterator PI = pred_begin(BB), PE = pred_end(BB);
269 PI != PE; ++PI) {
Tom Stellard6b7d99d2012-12-19 22:10:31 +0000270
Tom Stellard27f5d062013-02-08 22:24:37 +0000271 if (!ParentRegion->contains(*PI)) {
272 // It's a branch from outside into our region entry
273 Pred[*PI] = BoolTrue;
274 continue;
Tom Stellard6b7d99d2012-12-19 22:10:31 +0000275 }
276
Tom Stellard27f5d062013-02-08 22:24:37 +0000277 Region *R = RI->getRegionFor(*PI);
278 if (R == ParentRegion) {
Tom Stellard6b7d99d2012-12-19 22:10:31 +0000279
Tom Stellard27f5d062013-02-08 22:24:37 +0000280 // It's a top level block in our region
281 BranchInst *Term = cast<BranchInst>((*PI)->getTerminator());
282 for (unsigned i = 0, e = Term->getNumSuccessors(); i != e; ++i) {
283 BasicBlock *Succ = Term->getSuccessor(i);
284 if (Succ != BB)
285 continue;
Tom Stellard6b7d99d2012-12-19 22:10:31 +0000286
Tom Stellard27f5d062013-02-08 22:24:37 +0000287 if (Visited.count(*PI)) {
288 // Normal forward edge
289 if (Term->isConditional()) {
290 // Try to treat it like an ELSE block
291 BasicBlock *Other = Term->getSuccessor(!i);
292 if (Visited.count(Other) && !LoopTargets.count(Other) &&
293 !Pred.count(Other) && !Pred.count(*PI)) {
Tom Stellard6b7d99d2012-12-19 22:10:31 +0000294
Tom Stellard27f5d062013-02-08 22:24:37 +0000295 Pred[Other] = BoolFalse;
296 Pred[*PI] = BoolTrue;
297 continue;
298 }
299 }
300
301 } else {
302 // Back edge
303 if (analyzeLoopStart(*PI, BB, buildCondition(Term, i, true)))
304 continue;
305 }
306 Pred[*PI] = buildCondition(Term, i, false);
307 }
308
309 } else {
310
311 // It's an exit from a sub region
312 while(R->getParent() != ParentRegion)
313 R = R->getParent();
314
315 // Edge from inside a subregion to its entry, ignore it
316 if (R == N)
317 continue;
318
319 BasicBlock *Entry = R->getEntry();
320 if (!Visited.count(Entry))
321 if (analyzeLoopStart(Entry, BB, BoolFalse))
322 continue;
323
324 Pred[Entry] = BoolTrue;
325 }
Tom Stellard6b7d99d2012-12-19 22:10:31 +0000326 }
327}
328
Tom Stellard27f5d062013-02-08 22:24:37 +0000329/// \brief Determine the end of the loop
330void AMDGPUStructurizeCFG::analyzeLoopEnd(RegionNode *N) {
Tom Stellard6b7d99d2012-12-19 22:10:31 +0000331
Tom Stellard27f5d062013-02-08 22:24:37 +0000332 if (N->isSubRegion()) {
333 // Test for exit as back edge
334 BasicBlock *Exit = N->getNodeAs<Region>()->getExit();
335 if (Visited.count(Exit))
336 LoopEnd = N->getEntry();
337
338 } else {
339 // Test for sucessors as back edge
340 BasicBlock *BB = N->getNodeAs<BasicBlock>();
341 BranchInst *Term = cast<BranchInst>(BB->getTerminator());
Tom Stellard6b7d99d2012-12-19 22:10:31 +0000342
343 for (unsigned i = 0, e = Term->getNumSuccessors(); i != e; ++i) {
344 BasicBlock *Succ = Term->getSuccessor(i);
Tom Stellard6b7d99d2012-12-19 22:10:31 +0000345
Tom Stellard27f5d062013-02-08 22:24:37 +0000346 if (Visited.count(Succ))
347 LoopEnd = BB;
Tom Stellard6b7d99d2012-12-19 22:10:31 +0000348 }
349 }
350}
351
352/// \brief Collect various loop and predicate infos
353void AMDGPUStructurizeCFG::collectInfos() {
Tom Stellard6b7d99d2012-12-19 22:10:31 +0000354
355 // Reset predicate
356 Predicates.clear();
357
358 // and loop infos
359 LoopStart = LoopEnd = 0;
Tom Stellard27f5d062013-02-08 22:24:37 +0000360 LoopTargets.clear();
Tom Stellard6b7d99d2012-12-19 22:10:31 +0000361 LoopPred.clear();
362
Tom Stellard27f5d062013-02-08 22:24:37 +0000363 // Reset the visited nodes
364 Visited.clear();
365
366 for (RNVector::reverse_iterator OI = Order.rbegin(), OE = Order.rend();
367 OI != OE; ++OI) {
Tom Stellard6b7d99d2012-12-19 22:10:31 +0000368
369 // Analyze all the conditions leading to a node
Tom Stellard27f5d062013-02-08 22:24:37 +0000370 analyzeNode(*OI);
Tom Stellard6b7d99d2012-12-19 22:10:31 +0000371
Tom Stellard27f5d062013-02-08 22:24:37 +0000372 // Remember that we've seen this node
Tom Stellardf4e471a2013-02-08 22:24:38 +0000373 Visited.insert((*OI)->getEntry());
Tom Stellard6b7d99d2012-12-19 22:10:31 +0000374
Tom Stellard27f5d062013-02-08 22:24:37 +0000375 // Find the last back edge
376 analyzeLoopEnd(*OI);
377 }
378
379 // Both or neither must be set
380 assert(!LoopStart == !LoopEnd);
381}
382
383/// \brief Insert the missing branch conditions
384void AMDGPUStructurizeCFG::insertConditions() {
385 SSAUpdater PhiInserter;
386
387 for (BranchVector::iterator I = Conditions.begin(),
388 E = Conditions.end(); I != E; ++I) {
389
390 BranchInst *Term = *I;
391 BasicBlock *Parent = Term->getParent();
392
393 assert(Term->isConditional());
394
395 PhiInserter.Initialize(Boolean, "");
396 if (Parent == LoopEnd) {
397 PhiInserter.AddAvailableValue(LoopStart, BoolTrue);
398 } else {
399 PhiInserter.AddAvailableValue(&Func->getEntryBlock(), BoolFalse);
400 PhiInserter.AddAvailableValue(Parent, BoolFalse);
401 }
402
403 bool ParentHasValue = false;
404 BasicBlock *Succ = Term->getSuccessor(0);
405 BBPredicates &Preds = (Parent == LoopEnd) ? LoopPred : Predicates[Succ];
406 for (BBPredicates::iterator PI = Preds.begin(), PE = Preds.end();
407 PI != PE; ++PI) {
408
409 PhiInserter.AddAvailableValue(PI->first, PI->second);
410 ParentHasValue |= PI->first == Parent;
411 }
412
413 if (ParentHasValue)
414 Term->setCondition(PhiInserter.GetValueAtEndOfBlock(Parent));
415 else
416 Term->setCondition(PhiInserter.GetValueInMiddleOfBlock(Parent));
Tom Stellard6b7d99d2012-12-19 22:10:31 +0000417 }
418}
419
Tom Stellard13cf6cb2013-02-08 22:24:35 +0000420/// \brief Remove all PHI values coming from "From" into "To" and remember
421/// them in DeletedPhis
422void AMDGPUStructurizeCFG::delPhiValues(BasicBlock *From, BasicBlock *To) {
423 PhiMap &Map = DeletedPhis[To];
424 for (BasicBlock::iterator I = To->begin(), E = To->end();
425 I != E && isa<PHINode>(*I);) {
426
427 PHINode &Phi = cast<PHINode>(*I++);
428 while (Phi.getBasicBlockIndex(From) != -1) {
429 Value *Deleted = Phi.removeIncomingValue(From, false);
430 Map[&Phi].push_back(std::make_pair(From, Deleted));
431 }
432 }
433}
434
435/// \brief Add a dummy PHI value as soon as we knew the new predecessor
436void AMDGPUStructurizeCFG::addPhiValues(BasicBlock *From, BasicBlock *To) {
437 for (BasicBlock::iterator I = To->begin(), E = To->end();
438 I != E && isa<PHINode>(*I);) {
439
440 PHINode &Phi = cast<PHINode>(*I++);
441 Value *Undef = UndefValue::get(Phi.getType());
442 Phi.addIncoming(Undef, From);
443 }
444 AddedPhis[To].push_back(From);
445}
446
447/// \brief Add the real PHI value as soon as everything is set up
448void AMDGPUStructurizeCFG::setPhiValues() {
449
450 SSAUpdater Updater;
451 for (BB2BBVecMap::iterator AI = AddedPhis.begin(), AE = AddedPhis.end();
452 AI != AE; ++AI) {
453
454 BasicBlock *To = AI->first;
455 BBVector &From = AI->second;
456
457 if (!DeletedPhis.count(To))
458 continue;
459
460 PhiMap &Map = DeletedPhis[To];
461 for (PhiMap::iterator PI = Map.begin(), PE = Map.end();
462 PI != PE; ++PI) {
463
464 PHINode *Phi = PI->first;
465 Value *Undef = UndefValue::get(Phi->getType());
466 Updater.Initialize(Phi->getType(), "");
467 Updater.AddAvailableValue(&Func->getEntryBlock(), Undef);
468 Updater.AddAvailableValue(To, Undef);
469
470 for (BBValueVector::iterator VI = PI->second.begin(),
471 VE = PI->second.end(); VI != VE; ++VI) {
472
473 Updater.AddAvailableValue(VI->first, VI->second);
474 }
475
476 for (BBVector::iterator FI = From.begin(), FE = From.end();
477 FI != FE; ++FI) {
478
479 int Idx = Phi->getBasicBlockIndex(*FI);
480 assert(Idx != -1);
481 Phi->setIncomingValue(Idx, Updater.GetValueAtEndOfBlock(*FI));
482 }
483 }
484
485 DeletedPhis.erase(To);
486 }
487 assert(DeletedPhis.empty());
488}
489
Tom Stellardf4e471a2013-02-08 22:24:38 +0000490/// \brief Remove phi values from all successors and then remove the terminator.
Tom Stellard6b7d99d2012-12-19 22:10:31 +0000491void AMDGPUStructurizeCFG::killTerminator(BasicBlock *BB) {
Tom Stellard6b7d99d2012-12-19 22:10:31 +0000492 TerminatorInst *Term = BB->getTerminator();
493 if (!Term)
494 return;
495
496 for (succ_iterator SI = succ_begin(BB), SE = succ_end(BB);
497 SI != SE; ++SI) {
498
499 delPhiValues(BB, *SI);
500 }
501
502 Term->eraseFromParent();
503}
504
Tom Stellardf4e471a2013-02-08 22:24:38 +0000505/// \brief Let node exit(s) point to NewExit
506void AMDGPUStructurizeCFG::changeExit(RegionNode *Node, BasicBlock *NewExit,
507 bool IncludeDominator) {
Tom Stellard6b7d99d2012-12-19 22:10:31 +0000508
Tom Stellardf4e471a2013-02-08 22:24:38 +0000509 if (Node->isSubRegion()) {
510 Region *SubRegion = Node->getNodeAs<Region>();
511 BasicBlock *OldExit = SubRegion->getExit();
512 BasicBlock *Dominator = 0;
Tom Stellard6b7d99d2012-12-19 22:10:31 +0000513
Tom Stellardf4e471a2013-02-08 22:24:38 +0000514 // Find all the edges from the sub region to the exit
515 for (pred_iterator I = pred_begin(OldExit), E = pred_end(OldExit);
516 I != E;) {
517
518 BasicBlock *BB = *I++;
519 if (!SubRegion->contains(BB))
520 continue;
521
522 // Modify the edges to point to the new exit
523 delPhiValues(BB, OldExit);
524 BB->getTerminator()->replaceUsesOfWith(OldExit, NewExit);
525 addPhiValues(BB, NewExit);
526
527 // Find the new dominator (if requested)
528 if (IncludeDominator) {
529 if (!Dominator)
530 Dominator = BB;
531 else
532 Dominator = DT->findNearestCommonDominator(Dominator, BB);
533 }
Tom Stellard6b7d99d2012-12-19 22:10:31 +0000534 }
535
Tom Stellardf4e471a2013-02-08 22:24:38 +0000536 // Change the dominator (if requested)
537 if (Dominator)
538 DT->changeImmediateDominator(NewExit, Dominator);
Tom Stellard6b7d99d2012-12-19 22:10:31 +0000539
Tom Stellardf4e471a2013-02-08 22:24:38 +0000540 // Update the region info
541 SubRegion->replaceExit(NewExit);
Tom Stellard6b7d99d2012-12-19 22:10:31 +0000542
Tom Stellard6b7d99d2012-12-19 22:10:31 +0000543 } else {
Tom Stellardf4e471a2013-02-08 22:24:38 +0000544 BasicBlock *BB = Node->getNodeAs<BasicBlock>();
545 killTerminator(BB);
546 BranchInst::Create(NewExit, BB);
547 addPhiValues(BB, NewExit);
548 if (IncludeDominator)
549 DT->changeImmediateDominator(NewExit, BB);
Tom Stellard6b7d99d2012-12-19 22:10:31 +0000550 }
Tom Stellard6b7d99d2012-12-19 22:10:31 +0000551}
552
Tom Stellard6b7d99d2012-12-19 22:10:31 +0000553/// \brief Create a new flow node and update dominator tree and region info
Tom Stellardf4e471a2013-02-08 22:24:38 +0000554BasicBlock *AMDGPUStructurizeCFG::getNextFlow(BasicBlock *Dominator) {
Tom Stellard6b7d99d2012-12-19 22:10:31 +0000555 LLVMContext &Context = Func->getContext();
556 BasicBlock *Insert = Order.empty() ? ParentRegion->getExit() :
557 Order.back()->getEntry();
558 BasicBlock *Flow = BasicBlock::Create(Context, FlowBlockName,
559 Func, Insert);
Tom Stellardf4e471a2013-02-08 22:24:38 +0000560 DT->addNewBlock(Flow, Dominator);
Tom Stellard6b7d99d2012-12-19 22:10:31 +0000561 ParentRegion->getRegionInfo()->setRegionFor(Flow, ParentRegion);
Tom Stellard6b7d99d2012-12-19 22:10:31 +0000562 return Flow;
563}
564
Tom Stellardf4e471a2013-02-08 22:24:38 +0000565/// \brief Create a new or reuse the previous node as flow node
566BasicBlock *AMDGPUStructurizeCFG::needPrefix(RegionNode *&Prev,
567 RegionNode *Node) {
568
569 if (!Prev || Prev->isSubRegion() ||
570 (Node && Node->getEntry() == LoopStart)) {
571
572 // We need to insert a flow node, first figure out the dominator
573 DomTreeNode *Dominator = Prev ? DT->getNode(Prev->getEntry()) : 0;
574 if (!Dominator)
575 Dominator = DT->getNode(Node->getEntry())->getIDom();
576 assert(Dominator && "Illegal loop to function entry");
577
578 // then create the flow node
579 BasicBlock *Flow = getNextFlow(Dominator->getBlock());
580
581 // wire up the new flow
582 if (Prev) {
583 changeExit(Prev, Flow, true);
584 } else {
585 // Parent regions entry needs predicates, create a new region entry
586 BasicBlock *Entry = Node->getEntry();
587 for (pred_iterator I = pred_begin(Entry), E = pred_end(Entry);
588 I != E;) {
589
590 BasicBlock *BB = *(I++);
591 if (ParentRegion->contains(BB))
592 continue;
593
594 // Remove PHY values from outside to our entry node
595 delPhiValues(BB, Entry);
596
597 // Update the branch instructions
598 BB->getTerminator()->replaceUsesOfWith(Entry, Flow);
599 }
600
601 // Populate the region tree with the new entry
602 for (Region *R = ParentRegion; R && R->getEntry() == Entry;
603 R = R->getParent()) {
604 R->replaceEntry(Flow);
605 }
606 }
607 Prev = ParentRegion->getBBNode(Flow);
608
609 } else {
610 killTerminator(Prev->getEntry());
611 }
612
613 return Prev->getEntry();
614}
615
616/// \brief Returns the region exit if possible, otherwise just a new flow node
617BasicBlock *AMDGPUStructurizeCFG::needPostfix(BasicBlock *Flow,
618 bool ExitUseAllowed) {
619
620 if (Order.empty() && ExitUseAllowed) {
621 BasicBlock *Exit = ParentRegion->getExit();
622 DT->changeImmediateDominator(Exit, Flow);
623 addPhiValues(Flow, Exit);
624 return Exit;
625 }
626 return getNextFlow(Flow);
627}
628
629/// \brief Returns the region node for Netx, or null if Next is the exit
630RegionNode *AMDGPUStructurizeCFG::getNextPrev(BasicBlock *Next) {
631 return ParentRegion->contains(Next) ? ParentRegion->getBBNode(Next) : 0;
632}
633
634/// \brief Does BB dominate all the predicates of Node ?
635bool AMDGPUStructurizeCFG::dominatesPredicates(BasicBlock *BB, RegionNode *Node) {
636 BBPredicates &Preds = Predicates[Node->getEntry()];
637 for (BBPredicates::iterator PI = Preds.begin(), PE = Preds.end();
638 PI != PE; ++PI) {
639
640 if (!DT->dominates(BB, PI->first))
641 return false;
642 }
643 return true;
644}
645
Tom Stellard6b7d99d2012-12-19 22:10:31 +0000646/// \brief Can we predict that this node will always be called?
Tom Stellardf4e471a2013-02-08 22:24:38 +0000647bool AMDGPUStructurizeCFG::isPredictableTrue(RegionNode *Who,
648 RegionNode *Where) {
649
650 BBPredicates &Preds = Predicates[Who->getEntry()];
651 bool Dominated = Where == 0;
Tom Stellard6b7d99d2012-12-19 22:10:31 +0000652
653 for (BBPredicates::iterator I = Preds.begin(), E = Preds.end();
654 I != E; ++I) {
655
656 if (I->second != BoolTrue)
657 return false;
658
Tom Stellardf4e471a2013-02-08 22:24:38 +0000659 if (!Dominated && DT->dominates(I->first, Where->getEntry()))
Tom Stellard6b7d99d2012-12-19 22:10:31 +0000660 Dominated = true;
661 }
Tom Stellardf4e471a2013-02-08 22:24:38 +0000662
663 // TODO: The dominator check is too strict
Tom Stellard6b7d99d2012-12-19 22:10:31 +0000664 return Dominated;
665}
666
Tom Stellardf4e471a2013-02-08 22:24:38 +0000667/// Take one node from the order vector and wire it up
668RegionNode *AMDGPUStructurizeCFG::wireFlow(RegionNode *&Prev,
669 bool ExitUseAllowed) {
Tom Stellard6b7d99d2012-12-19 22:10:31 +0000670
Tom Stellardf4e471a2013-02-08 22:24:38 +0000671 RegionNode *Node = Order.pop_back_val();
Tom Stellard6b7d99d2012-12-19 22:10:31 +0000672
Tom Stellardf4e471a2013-02-08 22:24:38 +0000673 if (isPredictableTrue(Node, Prev)) {
674 // Just a linear flow
675 if (Prev) {
676 changeExit(Prev, Node->getEntry(), true);
Tom Stellard6b7d99d2012-12-19 22:10:31 +0000677 }
Tom Stellardf4e471a2013-02-08 22:24:38 +0000678 Prev = Node;
Tom Stellard6b7d99d2012-12-19 22:10:31 +0000679
680 } else {
Tom Stellardf4e471a2013-02-08 22:24:38 +0000681 // Insert extra prefix node (or reuse last one)
682 BasicBlock *Flow = needPrefix(Prev, Node);
683 if (Node->getEntry() == LoopStart)
684 LoopStart = Flow;
Tom Stellard6b7d99d2012-12-19 22:10:31 +0000685
Tom Stellardf4e471a2013-02-08 22:24:38 +0000686 // Insert extra postfix node (or use exit instead)
687 BasicBlock *Entry = Node->getEntry();
688 BasicBlock *Next = needPostfix(Flow, ExitUseAllowed && Entry != LoopEnd);
689
690 // let it point to entry and next block
691 Conditions.push_back(BranchInst::Create(Entry, Next, BoolUndef, Flow));
692 addPhiValues(Flow, Entry);
693 DT->changeImmediateDominator(Entry, Flow);
694
695 Prev = Node;
696 while (!Order.empty() && Node->getEntry() != LoopEnd &&
697 !LoopTargets.count(Order.back()->getEntry()) &&
698 dominatesPredicates(Entry, Order.back())) {
699 Node = wireFlow(Prev, false);
700 }
701
702 changeExit(Prev, Next, false);
703 Prev = getNextPrev(Next);
Tom Stellard6b7d99d2012-12-19 22:10:31 +0000704 }
705
Tom Stellardf4e471a2013-02-08 22:24:38 +0000706 return Node;
Tom Stellard6b7d99d2012-12-19 22:10:31 +0000707}
708
Tom Stellard6b7d99d2012-12-19 22:10:31 +0000709/// After this function control flow looks like it should be, but
Tom Stellardf4e471a2013-02-08 22:24:38 +0000710/// branches and PHI nodes only have undefined conditions.
Tom Stellard6b7d99d2012-12-19 22:10:31 +0000711void AMDGPUStructurizeCFG::createFlow() {
Tom Stellardf4e471a2013-02-08 22:24:38 +0000712
713 BasicBlock *Exit = ParentRegion->getExit();
714 bool EntryDominatesExit = DT->dominates(ParentRegion->getEntry(), Exit);
715
Tom Stellard6b7d99d2012-12-19 22:10:31 +0000716 DeletedPhis.clear();
Tom Stellard13cf6cb2013-02-08 22:24:35 +0000717 AddedPhis.clear();
Tom Stellardf4e471a2013-02-08 22:24:38 +0000718 Conditions.clear();
Tom Stellard6b7d99d2012-12-19 22:10:31 +0000719
Tom Stellardf4e471a2013-02-08 22:24:38 +0000720 RegionNode *Prev = 0;
Tom Stellard6b7d99d2012-12-19 22:10:31 +0000721 while (!Order.empty()) {
Tom Stellardf4e471a2013-02-08 22:24:38 +0000722
723 RegionNode *Node = wireFlow(Prev, EntryDominatesExit);
724
725 // Create an extra loop end node
726 if (Node->getEntry() == LoopEnd) {
727 LoopEnd = needPrefix(Prev, 0);
728 BasicBlock *Next = needPostfix(LoopEnd, EntryDominatesExit);
729
730 Conditions.push_back(BranchInst::Create(Next, LoopStart,
Tom Stellard27f5d062013-02-08 22:24:37 +0000731 BoolUndef, LoopEnd));
Tom Stellard6b7d99d2012-12-19 22:10:31 +0000732 addPhiValues(LoopEnd, LoopStart);
Tom Stellardf4e471a2013-02-08 22:24:38 +0000733 Prev = getNextPrev(Next);
Tom Stellard6b7d99d2012-12-19 22:10:31 +0000734 }
735 }
736
Tom Stellardf4e471a2013-02-08 22:24:38 +0000737 if (Prev)
738 changeExit(Prev, Exit, EntryDominatesExit);
739 else
740 assert(EntryDominatesExit);
Tom Stellard6b7d99d2012-12-19 22:10:31 +0000741}
742
Tom Stellard6b7d99d2012-12-19 22:10:31 +0000743/// Handle a rare case where the disintegrated nodes instructions
744/// no longer dominate all their uses. Not sure if this is really nessasary
745void AMDGPUStructurizeCFG::rebuildSSA() {
Tom Stellard6b7d99d2012-12-19 22:10:31 +0000746 SSAUpdater Updater;
747 for (Region::block_iterator I = ParentRegion->block_begin(),
748 E = ParentRegion->block_end();
749 I != E; ++I) {
750
751 BasicBlock *BB = *I;
752 for (BasicBlock::iterator II = BB->begin(), IE = BB->end();
753 II != IE; ++II) {
754
755 bool Initialized = false;
756 for (Use *I = &II->use_begin().getUse(), *Next; I; I = Next) {
757
758 Next = I->getNext();
759
760 Instruction *User = cast<Instruction>(I->getUser());
761 if (User->getParent() == BB) {
762 continue;
763
764 } else if (PHINode *UserPN = dyn_cast<PHINode>(User)) {
765 if (UserPN->getIncomingBlock(*I) == BB)
766 continue;
767 }
768
769 if (DT->dominates(II, User))
770 continue;
771
772 if (!Initialized) {
773 Value *Undef = UndefValue::get(II->getType());
774 Updater.Initialize(II->getType(), "");
775 Updater.AddAvailableValue(&Func->getEntryBlock(), Undef);
776 Updater.AddAvailableValue(BB, II);
777 Initialized = true;
778 }
779 Updater.RewriteUseAfterInsertions(*I);
780 }
781 }
782 }
783}
784
785/// \brief Run the transformation for each region found
786bool AMDGPUStructurizeCFG::runOnRegion(Region *R, RGPassManager &RGM) {
Tom Stellard6b7d99d2012-12-19 22:10:31 +0000787 if (R->isTopLevelRegion())
788 return false;
789
790 Func = R->getEntry()->getParent();
791 ParentRegion = R;
792
793 DT = &getAnalysis<DominatorTree>();
794
795 orderNodes();
796 collectInfos();
797 createFlow();
798 insertConditions();
Tom Stellard13cf6cb2013-02-08 22:24:35 +0000799 setPhiValues();
Tom Stellard6b7d99d2012-12-19 22:10:31 +0000800 rebuildSSA();
801
Tom Stellard27f5d062013-02-08 22:24:37 +0000802 // Cleanup
Tom Stellard6b7d99d2012-12-19 22:10:31 +0000803 Order.clear();
804 Visited.clear();
805 Predicates.clear();
806 DeletedPhis.clear();
Tom Stellard13cf6cb2013-02-08 22:24:35 +0000807 AddedPhis.clear();
Tom Stellard27f5d062013-02-08 22:24:37 +0000808 Conditions.clear();
809 LoopTargets.clear();
810 LoopPred.clear();
Tom Stellard6b7d99d2012-12-19 22:10:31 +0000811
812 return true;
813}
814
815/// \brief Create the pass
816Pass *llvm::createAMDGPUStructurizeCFGPass() {
817 return new AMDGPUStructurizeCFG();
818}