blob: e1c7790d410bf62ad3c17b55e7e39a82ceba4c07 [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;
45typedef DenseMap<BasicBlock *, unsigned> VisitedMap;
Tom Stellard13cf6cb2013-02-08 22:24:35 +000046typedef DenseMap<BasicBlock *, BBVector> BB2BBVecMap;
Tom Stellard6b7d99d2012-12-19 22:10:31 +000047
48// The name for newly created blocks.
49
50static const char *FlowBlockName = "Flow";
51
52/// @brief Transforms the control flow graph on one single entry/exit region
53/// at a time.
54///
55/// After the transform all "If"/"Then"/"Else" style control flow looks like
56/// this:
57///
58/// \verbatim
59/// 1
60/// ||
61/// | |
62/// 2 |
63/// | /
64/// |/
65/// 3
66/// || Where:
67/// | | 1 = "If" block, calculates the condition
68/// 4 | 2 = "Then" subregion, runs if the condition is true
69/// | / 3 = "Flow" blocks, newly inserted flow blocks, rejoins the flow
70/// |/ 4 = "Else" optional subregion, runs if the condition is false
71/// 5 5 = "End" block, also rejoins the control flow
72/// \endverbatim
73///
74/// Control flow is expressed as a branch where the true exit goes into the
75/// "Then"/"Else" region, while the false exit skips the region
76/// The condition for the optional "Else" region is expressed as a PHI node.
77/// The incomming values of the PHI node are true for the "If" edge and false
78/// for the "Then" edge.
79///
80/// Additionally to that even complicated loops look like this:
81///
82/// \verbatim
83/// 1
84/// ||
85/// | |
86/// 2 ^ Where:
87/// | / 1 = "Entry" block
88/// |/ 2 = "Loop" optional subregion, with all exits at "Flow" block
89/// 3 3 = "Flow" block, with back edge to entry block
90/// |
91/// \endverbatim
92///
93/// The back edge of the "Flow" block is always on the false side of the branch
94/// while the true side continues the general flow. So the loop condition
95/// consist of a network of PHI nodes where the true incoming values expresses
96/// breaks and the false values expresses continue states.
97class AMDGPUStructurizeCFG : public RegionPass {
98
99 static char ID;
100
101 Type *Boolean;
102 ConstantInt *BoolTrue;
103 ConstantInt *BoolFalse;
104 UndefValue *BoolUndef;
105
106 Function *Func;
107 Region *ParentRegion;
108
109 DominatorTree *DT;
110
111 RNVector Order;
112 VisitedMap Visited;
113 PredMap Predicates;
114 BBPhiMap DeletedPhis;
Tom Stellard13cf6cb2013-02-08 22:24:35 +0000115 BB2BBVecMap AddedPhis;
Tom Stellard27f5d062013-02-08 22:24:37 +0000116 BranchVector Conditions;
Tom Stellard6b7d99d2012-12-19 22:10:31 +0000117
118 BasicBlock *LoopStart;
119 BasicBlock *LoopEnd;
Tom Stellard27f5d062013-02-08 22:24:37 +0000120 BBSet LoopTargets;
Tom Stellard6b7d99d2012-12-19 22:10:31 +0000121 BBPredicates LoopPred;
122
123 void orderNodes();
124
Tom Stellard27f5d062013-02-08 22:24:37 +0000125 Value *buildCondition(BranchInst *Term, unsigned Idx, bool Invert);
Tom Stellard6b7d99d2012-12-19 22:10:31 +0000126
Tom Stellard27f5d062013-02-08 22:24:37 +0000127 bool analyzeLoopStart(BasicBlock *From, BasicBlock *To, Value *Condition);
Tom Stellard6b7d99d2012-12-19 22:10:31 +0000128
Tom Stellard27f5d062013-02-08 22:24:37 +0000129 void analyzeNode(RegionNode *N);
130
131 void analyzeLoopEnd(RegionNode *N);
Tom Stellard6b7d99d2012-12-19 22:10:31 +0000132
133 void collectInfos();
134
Tom Stellard27f5d062013-02-08 22:24:37 +0000135 void insertConditions();
136
Tom Stellard13cf6cb2013-02-08 22:24:35 +0000137 void delPhiValues(BasicBlock *From, BasicBlock *To);
138
139 void addPhiValues(BasicBlock *From, BasicBlock *To);
140
141 void setPhiValues();
142
Tom Stellard6b7d99d2012-12-19 22:10:31 +0000143 bool dominatesPredicates(BasicBlock *A, BasicBlock *B);
144
145 void killTerminator(BasicBlock *BB);
146
147 RegionNode *skipChained(RegionNode *Node);
148
Tom Stellard6b7d99d2012-12-19 22:10:31 +0000149 BasicBlock *getNextFlow(BasicBlock *Prev);
150
151 bool isPredictableTrue(BasicBlock *Prev, BasicBlock *Node);
152
153 BasicBlock *wireFlowBlock(BasicBlock *Prev, RegionNode *Node);
154
155 void createFlow();
156
Tom Stellard6b7d99d2012-12-19 22:10:31 +0000157 void rebuildSSA();
158
159public:
160 AMDGPUStructurizeCFG():
161 RegionPass(ID) {
162
163 initializeRegionInfoPass(*PassRegistry::getPassRegistry());
164 }
165
166 virtual bool doInitialization(Region *R, RGPassManager &RGM);
167
168 virtual bool runOnRegion(Region *R, RGPassManager &RGM);
169
170 virtual const char *getPassName() const {
171 return "AMDGPU simplify control flow";
172 }
173
174 void getAnalysisUsage(AnalysisUsage &AU) const {
175
176 AU.addRequired<DominatorTree>();
177 AU.addPreserved<DominatorTree>();
178 RegionPass::getAnalysisUsage(AU);
179 }
180
181};
182
183} // end anonymous namespace
184
185char AMDGPUStructurizeCFG::ID = 0;
186
187/// \brief Initialize the types and constants used in the pass
188bool AMDGPUStructurizeCFG::doInitialization(Region *R, RGPassManager &RGM) {
Tom Stellard6b7d99d2012-12-19 22:10:31 +0000189 LLVMContext &Context = R->getEntry()->getContext();
190
191 Boolean = Type::getInt1Ty(Context);
192 BoolTrue = ConstantInt::getTrue(Context);
193 BoolFalse = ConstantInt::getFalse(Context);
194 BoolUndef = UndefValue::get(Boolean);
195
196 return false;
197}
198
199/// \brief Build up the general order of nodes
200void AMDGPUStructurizeCFG::orderNodes() {
Tom Stellard6b7d99d2012-12-19 22:10:31 +0000201 scc_iterator<Region *> I = scc_begin(ParentRegion),
202 E = scc_end(ParentRegion);
203 for (Order.clear(); I != E; ++I) {
204 std::vector<RegionNode *> &Nodes = *I;
205 Order.append(Nodes.begin(), Nodes.end());
206 }
207}
208
Tom Stellard27f5d062013-02-08 22:24:37 +0000209/// \brief Build the condition for one edge
210Value *AMDGPUStructurizeCFG::buildCondition(BranchInst *Term, unsigned Idx,
211 bool Invert) {
212 Value *Cond = Invert ? BoolFalse : BoolTrue;
213 if (Term->isConditional()) {
214 Cond = Term->getCondition();
Tom Stellard6b7d99d2012-12-19 22:10:31 +0000215
Tom Stellard27f5d062013-02-08 22:24:37 +0000216 if (Idx != Invert)
217 Cond = BinaryOperator::CreateNot(Cond, "", Term);
218 }
219 return Cond;
220}
221
222/// \brief Analyze the start of a loop and insert predicates as necessary
223bool AMDGPUStructurizeCFG::analyzeLoopStart(BasicBlock *From, BasicBlock *To,
224 Value *Condition) {
225 LoopPred[From] = Condition;
226 LoopTargets.insert(To);
227 if (!LoopStart) {
228 LoopStart = To;
229 return true;
230
231 } else if (LoopStart == To)
232 return true;
233
234 // We need to handle the case of intersecting loops, e. g.
235 //
236 // /----<-----
237 // | |
238 // -> A -> B -> C -> D
239 // | |
240 // -----<----/
241
242 RNVector::reverse_iterator OI = Order.rbegin(), OE = Order.rend();
243
244 for (;OI != OE; ++OI)
245 if ((*OI)->getEntry() == LoopStart)
246 break;
247
248 for (;OI != OE && (*OI)->getEntry() != To; ++OI) {
249 BBPredicates &Pred = Predicates[(*OI)->getEntry()];
250 if (!Pred.count(From))
251 Pred[From] = Condition;
252 }
253 return false;
254}
255
256/// \brief Analyze the predecessors of each block and build up predicates
257void AMDGPUStructurizeCFG::analyzeNode(RegionNode *N) {
Tom Stellard6b7d99d2012-12-19 22:10:31 +0000258 RegionInfo *RI = ParentRegion->getRegionInfo();
Tom Stellard27f5d062013-02-08 22:24:37 +0000259 BasicBlock *BB = N->getEntry();
260 BBPredicates &Pred = Predicates[BB];
Tom Stellard6b7d99d2012-12-19 22:10:31 +0000261
Tom Stellard27f5d062013-02-08 22:24:37 +0000262 for (pred_iterator PI = pred_begin(BB), PE = pred_end(BB);
263 PI != PE; ++PI) {
Tom Stellard6b7d99d2012-12-19 22:10:31 +0000264
Tom Stellard27f5d062013-02-08 22:24:37 +0000265 if (!ParentRegion->contains(*PI)) {
266 // It's a branch from outside into our region entry
267 Pred[*PI] = BoolTrue;
268 continue;
Tom Stellard6b7d99d2012-12-19 22:10:31 +0000269 }
270
Tom Stellard27f5d062013-02-08 22:24:37 +0000271 Region *R = RI->getRegionFor(*PI);
272 if (R == ParentRegion) {
Tom Stellard6b7d99d2012-12-19 22:10:31 +0000273
Tom Stellard27f5d062013-02-08 22:24:37 +0000274 // It's a top level block in our region
275 BranchInst *Term = cast<BranchInst>((*PI)->getTerminator());
276 for (unsigned i = 0, e = Term->getNumSuccessors(); i != e; ++i) {
277 BasicBlock *Succ = Term->getSuccessor(i);
278 if (Succ != BB)
279 continue;
Tom Stellard6b7d99d2012-12-19 22:10:31 +0000280
Tom Stellard27f5d062013-02-08 22:24:37 +0000281 if (Visited.count(*PI)) {
282 // Normal forward edge
283 if (Term->isConditional()) {
284 // Try to treat it like an ELSE block
285 BasicBlock *Other = Term->getSuccessor(!i);
286 if (Visited.count(Other) && !LoopTargets.count(Other) &&
287 !Pred.count(Other) && !Pred.count(*PI)) {
Tom Stellard6b7d99d2012-12-19 22:10:31 +0000288
Tom Stellard27f5d062013-02-08 22:24:37 +0000289 Pred[Other] = BoolFalse;
290 Pred[*PI] = BoolTrue;
291 continue;
292 }
293 }
294
295 } else {
296 // Back edge
297 if (analyzeLoopStart(*PI, BB, buildCondition(Term, i, true)))
298 continue;
299 }
300 Pred[*PI] = buildCondition(Term, i, false);
301 }
302
303 } else {
304
305 // It's an exit from a sub region
306 while(R->getParent() != ParentRegion)
307 R = R->getParent();
308
309 // Edge from inside a subregion to its entry, ignore it
310 if (R == N)
311 continue;
312
313 BasicBlock *Entry = R->getEntry();
314 if (!Visited.count(Entry))
315 if (analyzeLoopStart(Entry, BB, BoolFalse))
316 continue;
317
318 Pred[Entry] = BoolTrue;
319 }
Tom Stellard6b7d99d2012-12-19 22:10:31 +0000320 }
321}
322
Tom Stellard27f5d062013-02-08 22:24:37 +0000323/// \brief Determine the end of the loop
324void AMDGPUStructurizeCFG::analyzeLoopEnd(RegionNode *N) {
Tom Stellard6b7d99d2012-12-19 22:10:31 +0000325
Tom Stellard27f5d062013-02-08 22:24:37 +0000326 if (N->isSubRegion()) {
327 // Test for exit as back edge
328 BasicBlock *Exit = N->getNodeAs<Region>()->getExit();
329 if (Visited.count(Exit))
330 LoopEnd = N->getEntry();
331
332 } else {
333 // Test for sucessors as back edge
334 BasicBlock *BB = N->getNodeAs<BasicBlock>();
335 BranchInst *Term = cast<BranchInst>(BB->getTerminator());
Tom Stellard6b7d99d2012-12-19 22:10:31 +0000336
337 for (unsigned i = 0, e = Term->getNumSuccessors(); i != e; ++i) {
338 BasicBlock *Succ = Term->getSuccessor(i);
Tom Stellard6b7d99d2012-12-19 22:10:31 +0000339
Tom Stellard27f5d062013-02-08 22:24:37 +0000340 if (Visited.count(Succ))
341 LoopEnd = BB;
Tom Stellard6b7d99d2012-12-19 22:10:31 +0000342 }
343 }
344}
345
346/// \brief Collect various loop and predicate infos
347void AMDGPUStructurizeCFG::collectInfos() {
Tom Stellard27f5d062013-02-08 22:24:37 +0000348 unsigned Number = 0;
Tom Stellard6b7d99d2012-12-19 22:10:31 +0000349
350 // Reset predicate
351 Predicates.clear();
352
353 // and loop infos
354 LoopStart = LoopEnd = 0;
Tom Stellard27f5d062013-02-08 22:24:37 +0000355 LoopTargets.clear();
Tom Stellard6b7d99d2012-12-19 22:10:31 +0000356 LoopPred.clear();
357
Tom Stellard27f5d062013-02-08 22:24:37 +0000358 // Reset the visited nodes
359 Visited.clear();
360
361 for (RNVector::reverse_iterator OI = Order.rbegin(), OE = Order.rend();
362 OI != OE; ++OI) {
Tom Stellard6b7d99d2012-12-19 22:10:31 +0000363
364 // Analyze all the conditions leading to a node
Tom Stellard27f5d062013-02-08 22:24:37 +0000365 analyzeNode(*OI);
Tom Stellard6b7d99d2012-12-19 22:10:31 +0000366
Tom Stellard27f5d062013-02-08 22:24:37 +0000367 // Remember that we've seen this node
368 Visited[(*OI)->getEntry()] = ++Number;
Tom Stellard6b7d99d2012-12-19 22:10:31 +0000369
Tom Stellard27f5d062013-02-08 22:24:37 +0000370 // Find the last back edge
371 analyzeLoopEnd(*OI);
372 }
373
374 // Both or neither must be set
375 assert(!LoopStart == !LoopEnd);
376}
377
378/// \brief Insert the missing branch conditions
379void AMDGPUStructurizeCFG::insertConditions() {
380 SSAUpdater PhiInserter;
381
382 for (BranchVector::iterator I = Conditions.begin(),
383 E = Conditions.end(); I != E; ++I) {
384
385 BranchInst *Term = *I;
386 BasicBlock *Parent = Term->getParent();
387
388 assert(Term->isConditional());
389
390 PhiInserter.Initialize(Boolean, "");
391 if (Parent == LoopEnd) {
392 PhiInserter.AddAvailableValue(LoopStart, BoolTrue);
393 } else {
394 PhiInserter.AddAvailableValue(&Func->getEntryBlock(), BoolFalse);
395 PhiInserter.AddAvailableValue(Parent, BoolFalse);
396 }
397
398 bool ParentHasValue = false;
399 BasicBlock *Succ = Term->getSuccessor(0);
400 BBPredicates &Preds = (Parent == LoopEnd) ? LoopPred : Predicates[Succ];
401 for (BBPredicates::iterator PI = Preds.begin(), PE = Preds.end();
402 PI != PE; ++PI) {
403
404 PhiInserter.AddAvailableValue(PI->first, PI->second);
405 ParentHasValue |= PI->first == Parent;
406 }
407
408 if (ParentHasValue)
409 Term->setCondition(PhiInserter.GetValueAtEndOfBlock(Parent));
410 else
411 Term->setCondition(PhiInserter.GetValueInMiddleOfBlock(Parent));
Tom Stellard6b7d99d2012-12-19 22:10:31 +0000412 }
413}
414
Tom Stellard13cf6cb2013-02-08 22:24:35 +0000415/// \brief Remove all PHI values coming from "From" into "To" and remember
416/// them in DeletedPhis
417void AMDGPUStructurizeCFG::delPhiValues(BasicBlock *From, BasicBlock *To) {
418 PhiMap &Map = DeletedPhis[To];
419 for (BasicBlock::iterator I = To->begin(), E = To->end();
420 I != E && isa<PHINode>(*I);) {
421
422 PHINode &Phi = cast<PHINode>(*I++);
423 while (Phi.getBasicBlockIndex(From) != -1) {
424 Value *Deleted = Phi.removeIncomingValue(From, false);
425 Map[&Phi].push_back(std::make_pair(From, Deleted));
426 }
427 }
428}
429
430/// \brief Add a dummy PHI value as soon as we knew the new predecessor
431void AMDGPUStructurizeCFG::addPhiValues(BasicBlock *From, BasicBlock *To) {
432 for (BasicBlock::iterator I = To->begin(), E = To->end();
433 I != E && isa<PHINode>(*I);) {
434
435 PHINode &Phi = cast<PHINode>(*I++);
436 Value *Undef = UndefValue::get(Phi.getType());
437 Phi.addIncoming(Undef, From);
438 }
439 AddedPhis[To].push_back(From);
440}
441
442/// \brief Add the real PHI value as soon as everything is set up
443void AMDGPUStructurizeCFG::setPhiValues() {
444
445 SSAUpdater Updater;
446 for (BB2BBVecMap::iterator AI = AddedPhis.begin(), AE = AddedPhis.end();
447 AI != AE; ++AI) {
448
449 BasicBlock *To = AI->first;
450 BBVector &From = AI->second;
451
452 if (!DeletedPhis.count(To))
453 continue;
454
455 PhiMap &Map = DeletedPhis[To];
456 for (PhiMap::iterator PI = Map.begin(), PE = Map.end();
457 PI != PE; ++PI) {
458
459 PHINode *Phi = PI->first;
460 Value *Undef = UndefValue::get(Phi->getType());
461 Updater.Initialize(Phi->getType(), "");
462 Updater.AddAvailableValue(&Func->getEntryBlock(), Undef);
463 Updater.AddAvailableValue(To, Undef);
464
465 for (BBValueVector::iterator VI = PI->second.begin(),
466 VE = PI->second.end(); VI != VE; ++VI) {
467
468 Updater.AddAvailableValue(VI->first, VI->second);
469 }
470
471 for (BBVector::iterator FI = From.begin(), FE = From.end();
472 FI != FE; ++FI) {
473
474 int Idx = Phi->getBasicBlockIndex(*FI);
475 assert(Idx != -1);
476 Phi->setIncomingValue(Idx, Updater.GetValueAtEndOfBlock(*FI));
477 }
478 }
479
480 DeletedPhis.erase(To);
481 }
482 assert(DeletedPhis.empty());
483}
484
Tom Stellard6b7d99d2012-12-19 22:10:31 +0000485/// \brief Does A dominate all the predicates of B ?
486bool AMDGPUStructurizeCFG::dominatesPredicates(BasicBlock *A, BasicBlock *B) {
Tom Stellard6b7d99d2012-12-19 22:10:31 +0000487 BBPredicates &Preds = Predicates[B];
488 for (BBPredicates::iterator PI = Preds.begin(), PE = Preds.end();
489 PI != PE; ++PI) {
490
491 if (!DT->dominates(A, PI->first))
492 return false;
493 }
494 return true;
495}
496
497/// \brief Remove phi values from all successors and the remove the terminator.
498void AMDGPUStructurizeCFG::killTerminator(BasicBlock *BB) {
Tom Stellard6b7d99d2012-12-19 22:10:31 +0000499 TerminatorInst *Term = BB->getTerminator();
500 if (!Term)
501 return;
502
503 for (succ_iterator SI = succ_begin(BB), SE = succ_end(BB);
504 SI != SE; ++SI) {
505
506 delPhiValues(BB, *SI);
507 }
508
509 Term->eraseFromParent();
510}
511
512/// First: Skip forward to the first region node that either isn't a subregion or not
513/// dominating it's exit, remove all the skipped nodes from the node order.
514///
515/// Second: Handle the first successor directly if the resulting nodes successor
516/// predicates are still dominated by the original entry
517RegionNode *AMDGPUStructurizeCFG::skipChained(RegionNode *Node) {
Tom Stellard6b7d99d2012-12-19 22:10:31 +0000518 BasicBlock *Entry = Node->getEntry();
519
520 // Skip forward as long as it is just a linear flow
521 while (true) {
522 BasicBlock *Entry = Node->getEntry();
523 BasicBlock *Exit;
524
525 if (Node->isSubRegion()) {
526 Exit = Node->getNodeAs<Region>()->getExit();
527 } else {
528 TerminatorInst *Term = Entry->getTerminator();
529 if (Term->getNumSuccessors() != 1)
530 break;
531 Exit = Term->getSuccessor(0);
532 }
533
534 // It's a back edge, break here so we can insert a loop node
535 if (!Visited.count(Exit))
536 return Node;
537
538 // More than node edges are pointing to exit
539 if (!DT->dominates(Entry, Exit))
540 return Node;
541
542 RegionNode *Next = ParentRegion->getNode(Exit);
543 RNVector::iterator I = std::find(Order.begin(), Order.end(), Next);
544 assert(I != Order.end());
545
546 Visited.erase(Next->getEntry());
547 Order.erase(I);
548 Node = Next;
549 }
550
551 BasicBlock *BB = Node->getEntry();
552 TerminatorInst *Term = BB->getTerminator();
553 if (Term->getNumSuccessors() != 2)
554 return Node;
555
556 // Our node has exactly two succesors, check if we can handle
557 // any of them directly
558 BasicBlock *Succ = Term->getSuccessor(0);
559 if (!Visited.count(Succ) || !dominatesPredicates(Entry, Succ)) {
560 Succ = Term->getSuccessor(1);
561 if (!Visited.count(Succ) || !dominatesPredicates(Entry, Succ))
562 return Node;
563 } else {
564 BasicBlock *Succ2 = Term->getSuccessor(1);
565 if (Visited.count(Succ2) && Visited[Succ] > Visited[Succ2] &&
566 dominatesPredicates(Entry, Succ2))
567 Succ = Succ2;
568 }
569
570 RegionNode *Next = ParentRegion->getNode(Succ);
571 RNVector::iterator E = Order.end();
572 RNVector::iterator I = std::find(Order.begin(), E, Next);
573 assert(I != E);
574
575 killTerminator(BB);
Tom Stellard6b7d99d2012-12-19 22:10:31 +0000576 Visited.erase(Succ);
577 Order.erase(I);
578 return ParentRegion->getNode(wireFlowBlock(BB, Next));
579}
580
Tom Stellard6b7d99d2012-12-19 22:10:31 +0000581/// \brief Create a new flow node and update dominator tree and region info
582BasicBlock *AMDGPUStructurizeCFG::getNextFlow(BasicBlock *Prev) {
Tom Stellard6b7d99d2012-12-19 22:10:31 +0000583 LLVMContext &Context = Func->getContext();
584 BasicBlock *Insert = Order.empty() ? ParentRegion->getExit() :
585 Order.back()->getEntry();
586 BasicBlock *Flow = BasicBlock::Create(Context, FlowBlockName,
587 Func, Insert);
588 DT->addNewBlock(Flow, Prev);
589 ParentRegion->getRegionInfo()->setRegionFor(Flow, ParentRegion);
Tom Stellard6b7d99d2012-12-19 22:10:31 +0000590 return Flow;
591}
592
593/// \brief Can we predict that this node will always be called?
594bool AMDGPUStructurizeCFG::isPredictableTrue(BasicBlock *Prev,
595 BasicBlock *Node) {
Tom Stellard6b7d99d2012-12-19 22:10:31 +0000596 BBPredicates &Preds = Predicates[Node];
597 bool Dominated = false;
598
599 for (BBPredicates::iterator I = Preds.begin(), E = Preds.end();
600 I != E; ++I) {
601
602 if (I->second != BoolTrue)
603 return false;
604
605 if (!Dominated && DT->dominates(I->first, Prev))
606 Dominated = true;
607 }
608 return Dominated;
609}
610
611/// \brief Wire up the new control flow by inserting or updating the branch
612/// instructions at node exits
613BasicBlock *AMDGPUStructurizeCFG::wireFlowBlock(BasicBlock *Prev,
614 RegionNode *Node) {
Tom Stellard6b7d99d2012-12-19 22:10:31 +0000615 BasicBlock *Entry = Node->getEntry();
616
Tom Stellard27f5d062013-02-08 22:24:37 +0000617 if (LoopStart == Entry)
Tom Stellard6b7d99d2012-12-19 22:10:31 +0000618 LoopStart = Prev;
Tom Stellard6b7d99d2012-12-19 22:10:31 +0000619
620 // Wire it up temporary, skipChained may recurse into us
621 BranchInst::Create(Entry, Prev);
622 DT->changeImmediateDominator(Entry, Prev);
623 addPhiValues(Prev, Entry);
624
625 Node = skipChained(Node);
626
627 BasicBlock *Next = getNextFlow(Prev);
628 if (!isPredictableTrue(Prev, Entry)) {
629 // Let Prev point to entry and next block
630 Prev->getTerminator()->eraseFromParent();
Tom Stellard27f5d062013-02-08 22:24:37 +0000631 Conditions.push_back(BranchInst::Create(Entry, Next, BoolUndef, Prev));
Tom Stellard6b7d99d2012-12-19 22:10:31 +0000632 } else {
633 DT->changeImmediateDominator(Next, Entry);
634 }
635
636 // Let node exit(s) point to next block
637 if (Node->isSubRegion()) {
638 Region *SubRegion = Node->getNodeAs<Region>();
639 BasicBlock *Exit = SubRegion->getExit();
640
641 // Find all the edges from the sub region to the exit
642 BBVector ToDo;
643 for (pred_iterator I = pred_begin(Exit), E = pred_end(Exit); I != E; ++I) {
644 if (SubRegion->contains(*I))
645 ToDo.push_back(*I);
646 }
647
648 // Modify the edges to point to the new flow block
649 for (BBVector::iterator I = ToDo.begin(), E = ToDo.end(); I != E; ++I) {
650 delPhiValues(*I, Exit);
651 TerminatorInst *Term = (*I)->getTerminator();
652 Term->replaceUsesOfWith(Exit, Next);
653 }
654
655 // Update the region info
656 SubRegion->replaceExit(Next);
657
658 } else {
659 BasicBlock *BB = Node->getNodeAs<BasicBlock>();
660 killTerminator(BB);
661 BranchInst::Create(Next, BB);
662
663 if (BB == LoopEnd)
664 LoopEnd = 0;
665 }
666
667 return Next;
668}
669
670/// Destroy node order and visited map, build up flow order instead.
671/// After this function control flow looks like it should be, but
672/// branches only have undefined conditions.
673void AMDGPUStructurizeCFG::createFlow() {
Tom Stellard6b7d99d2012-12-19 22:10:31 +0000674 DeletedPhis.clear();
Tom Stellard13cf6cb2013-02-08 22:24:35 +0000675 AddedPhis.clear();
Tom Stellard6b7d99d2012-12-19 22:10:31 +0000676
677 BasicBlock *Prev = Order.pop_back_val()->getEntry();
678 assert(Prev == ParentRegion->getEntry() && "Incorrect node order!");
679 Visited.erase(Prev);
680
681 if (LoopStart == Prev) {
682 // Loop starts at entry, split entry so that we can predicate it
683 BasicBlock::iterator Insert = Prev->getFirstInsertionPt();
684 BasicBlock *Split = Prev->splitBasicBlock(Insert, FlowBlockName);
685 DT->addNewBlock(Split, Prev);
686 ParentRegion->getRegionInfo()->setRegionFor(Split, ParentRegion);
687 Predicates[Split] = Predicates[Prev];
688 Order.push_back(ParentRegion->getBBNode(Split));
Tom Stellard6b7d99d2012-12-19 22:10:31 +0000689
690 } else if (LoopStart == Order.back()->getEntry()) {
691 // Loop starts behind entry, split entry so that we can jump to it
692 Instruction *Term = Prev->getTerminator();
693 BasicBlock *Split = Prev->splitBasicBlock(Term, FlowBlockName);
694 DT->addNewBlock(Split, Prev);
695 ParentRegion->getRegionInfo()->setRegionFor(Split, ParentRegion);
696 Prev = Split;
697 }
698
699 killTerminator(Prev);
Tom Stellard6b7d99d2012-12-19 22:10:31 +0000700
701 while (!Order.empty()) {
702 RegionNode *Node = Order.pop_back_val();
703 Visited.erase(Node->getEntry());
704 Prev = wireFlowBlock(Prev, Node);
705 if (LoopStart && !LoopEnd) {
706 // Create an extra loop end node
707 LoopEnd = Prev;
708 Prev = getNextFlow(LoopEnd);
Tom Stellard27f5d062013-02-08 22:24:37 +0000709 Conditions.push_back(BranchInst::Create(Prev, LoopStart,
710 BoolUndef, LoopEnd));
Tom Stellard6b7d99d2012-12-19 22:10:31 +0000711 addPhiValues(LoopEnd, LoopStart);
712 }
713 }
714
715 BasicBlock *Exit = ParentRegion->getExit();
716 BranchInst::Create(Exit, Prev);
717 addPhiValues(Prev, Exit);
718 if (DT->dominates(ParentRegion->getEntry(), Exit))
719 DT->changeImmediateDominator(Exit, Prev);
720
Tom Stellard6b7d99d2012-12-19 22:10:31 +0000721 assert(Order.empty());
722 assert(Visited.empty());
Tom Stellard6b7d99d2012-12-19 22:10:31 +0000723}
724
Tom Stellard6b7d99d2012-12-19 22:10:31 +0000725/// Handle a rare case where the disintegrated nodes instructions
726/// no longer dominate all their uses. Not sure if this is really nessasary
727void AMDGPUStructurizeCFG::rebuildSSA() {
Tom Stellard6b7d99d2012-12-19 22:10:31 +0000728 SSAUpdater Updater;
729 for (Region::block_iterator I = ParentRegion->block_begin(),
730 E = ParentRegion->block_end();
731 I != E; ++I) {
732
733 BasicBlock *BB = *I;
734 for (BasicBlock::iterator II = BB->begin(), IE = BB->end();
735 II != IE; ++II) {
736
737 bool Initialized = false;
738 for (Use *I = &II->use_begin().getUse(), *Next; I; I = Next) {
739
740 Next = I->getNext();
741
742 Instruction *User = cast<Instruction>(I->getUser());
743 if (User->getParent() == BB) {
744 continue;
745
746 } else if (PHINode *UserPN = dyn_cast<PHINode>(User)) {
747 if (UserPN->getIncomingBlock(*I) == BB)
748 continue;
749 }
750
751 if (DT->dominates(II, User))
752 continue;
753
754 if (!Initialized) {
755 Value *Undef = UndefValue::get(II->getType());
756 Updater.Initialize(II->getType(), "");
757 Updater.AddAvailableValue(&Func->getEntryBlock(), Undef);
758 Updater.AddAvailableValue(BB, II);
759 Initialized = true;
760 }
761 Updater.RewriteUseAfterInsertions(*I);
762 }
763 }
764 }
765}
766
767/// \brief Run the transformation for each region found
768bool AMDGPUStructurizeCFG::runOnRegion(Region *R, RGPassManager &RGM) {
Tom Stellard6b7d99d2012-12-19 22:10:31 +0000769 if (R->isTopLevelRegion())
770 return false;
771
772 Func = R->getEntry()->getParent();
773 ParentRegion = R;
774
775 DT = &getAnalysis<DominatorTree>();
776
777 orderNodes();
778 collectInfos();
779 createFlow();
780 insertConditions();
Tom Stellard13cf6cb2013-02-08 22:24:35 +0000781 setPhiValues();
Tom Stellard6b7d99d2012-12-19 22:10:31 +0000782 rebuildSSA();
783
Tom Stellard27f5d062013-02-08 22:24:37 +0000784 // Cleanup
Tom Stellard6b7d99d2012-12-19 22:10:31 +0000785 Order.clear();
786 Visited.clear();
787 Predicates.clear();
788 DeletedPhis.clear();
Tom Stellard13cf6cb2013-02-08 22:24:35 +0000789 AddedPhis.clear();
Tom Stellard27f5d062013-02-08 22:24:37 +0000790 Conditions.clear();
791 LoopTargets.clear();
792 LoopPred.clear();
Tom Stellard6b7d99d2012-12-19 22:10:31 +0000793
794 return true;
795}
796
797/// \brief Create the pass
798Pass *llvm::createAMDGPUStructurizeCFGPass() {
799 return new AMDGPUStructurizeCFG();
800}