blob: bd947a5c32c26212695a23d5c52a6a649e634b3e [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"
Christian Konig43770272013-03-26 10:24:20 +000019#include "llvm/ADT/MapVector.h"
Benjamin Kramer5c352902013-05-23 17:10:37 +000020#include "llvm/ADT/SCCIterator.h"
Tom Stellard6b7d99d2012-12-19 22:10:31 +000021#include "llvm/Analysis/RegionInfo.h"
Chandler Carruth58a2cbe2013-01-02 10:22:59 +000022#include "llvm/Analysis/RegionIterator.h"
Tom Stellard6b7d99d2012-12-19 22:10:31 +000023#include "llvm/Analysis/RegionPass.h"
Chandler Carruth0b8c9a82013-01-02 11:36:10 +000024#include "llvm/IR/Module.h"
Christian Konigef6b2482013-02-16 11:27:50 +000025#include "llvm/Support/PatternMatch.h"
Benjamin Kramer5c352902013-05-23 17:10:37 +000026#include "llvm/Transforms/Utils/SSAUpdater.h"
Tom Stellard6b7d99d2012-12-19 22:10:31 +000027
28using namespace llvm;
Christian Konigef6b2482013-02-16 11:27:50 +000029using namespace llvm::PatternMatch;
Tom Stellard6b7d99d2012-12-19 22:10:31 +000030
31namespace {
32
33// Definition of the complex types used in this pass.
34
35typedef std::pair<BasicBlock *, Value *> BBValuePair;
Tom Stellard6b7d99d2012-12-19 22:10:31 +000036
37typedef SmallVector<RegionNode*, 8> RNVector;
38typedef SmallVector<BasicBlock*, 8> BBVector;
Tom Stellard27f5d062013-02-08 22:24:37 +000039typedef SmallVector<BranchInst*, 8> BranchVector;
Tom Stellard6b7d99d2012-12-19 22:10:31 +000040typedef SmallVector<BBValuePair, 2> BBValueVector;
41
Tom Stellard27f5d062013-02-08 22:24:37 +000042typedef SmallPtrSet<BasicBlock *, 8> BBSet;
43
Christian Konig43770272013-03-26 10:24:20 +000044typedef MapVector<PHINode *, BBValueVector> PhiMap;
45typedef MapVector<BasicBlock *, BBVector> BB2BBVecMap;
46
Christian Konigf0e469b2013-02-16 11:27:29 +000047typedef DenseMap<DomTreeNode *, unsigned> DTN2UnsignedMap;
Tom Stellard6b7d99d2012-12-19 22:10:31 +000048typedef DenseMap<BasicBlock *, PhiMap> BBPhiMap;
49typedef DenseMap<BasicBlock *, Value *> BBPredicates;
50typedef DenseMap<BasicBlock *, BBPredicates> PredMap;
Christian Konig623977d2013-02-16 11:27:45 +000051typedef DenseMap<BasicBlock *, BasicBlock*> BB2BBMap;
Tom Stellard6b7d99d2012-12-19 22:10:31 +000052
53// The name for newly created blocks.
54
55static const char *FlowBlockName = "Flow";
56
Christian Konigf0e469b2013-02-16 11:27:29 +000057/// @brief Find the nearest common dominator for multiple BasicBlocks
58///
59/// Helper class for AMDGPUStructurizeCFG
60/// TODO: Maybe move into common code
61class NearestCommonDominator {
62
63 DominatorTree *DT;
64
65 DTN2UnsignedMap IndexMap;
66
67 BasicBlock *Result;
68 unsigned ResultIndex;
69 bool ExplicitMentioned;
70
71public:
72 /// \brief Start a new query
73 NearestCommonDominator(DominatorTree *DomTree) {
74 DT = DomTree;
75 Result = 0;
76 }
77
78 /// \brief Add BB to the resulting dominator
79 void addBlock(BasicBlock *BB, bool Remember = true) {
80
81 DomTreeNode *Node = DT->getNode(BB);
82
83 if (Result == 0) {
84 unsigned Numbering = 0;
85 for (;Node;Node = Node->getIDom())
86 IndexMap[Node] = ++Numbering;
87 Result = BB;
88 ResultIndex = 1;
89 ExplicitMentioned = Remember;
90 return;
91 }
92
93 for (;Node;Node = Node->getIDom())
94 if (IndexMap.count(Node))
95 break;
96 else
97 IndexMap[Node] = 0;
98
99 assert(Node && "Dominator tree invalid!");
100
101 unsigned Numbering = IndexMap[Node];
102 if (Numbering > ResultIndex) {
103 Result = Node->getBlock();
104 ResultIndex = Numbering;
105 ExplicitMentioned = Remember && (Result == BB);
106 } else if (Numbering == ResultIndex) {
107 ExplicitMentioned |= Remember;
108 }
109 }
110
111 /// \brief Is "Result" one of the BBs added with "Remember" = True?
112 bool wasResultExplicitMentioned() {
113 return ExplicitMentioned;
114 }
115
116 /// \brief Get the query result
117 BasicBlock *getResult() {
118 return Result;
119 }
120};
121
Tom Stellard6b7d99d2012-12-19 22:10:31 +0000122/// @brief Transforms the control flow graph on one single entry/exit region
123/// at a time.
124///
125/// After the transform all "If"/"Then"/"Else" style control flow looks like
126/// this:
127///
128/// \verbatim
129/// 1
130/// ||
131/// | |
132/// 2 |
133/// | /
134/// |/
135/// 3
136/// || Where:
137/// | | 1 = "If" block, calculates the condition
138/// 4 | 2 = "Then" subregion, runs if the condition is true
139/// | / 3 = "Flow" blocks, newly inserted flow blocks, rejoins the flow
140/// |/ 4 = "Else" optional subregion, runs if the condition is false
141/// 5 5 = "End" block, also rejoins the control flow
142/// \endverbatim
143///
144/// Control flow is expressed as a branch where the true exit goes into the
145/// "Then"/"Else" region, while the false exit skips the region
146/// The condition for the optional "Else" region is expressed as a PHI node.
147/// The incomming values of the PHI node are true for the "If" edge and false
148/// for the "Then" edge.
149///
150/// Additionally to that even complicated loops look like this:
151///
152/// \verbatim
153/// 1
154/// ||
155/// | |
156/// 2 ^ Where:
157/// | / 1 = "Entry" block
158/// |/ 2 = "Loop" optional subregion, with all exits at "Flow" block
159/// 3 3 = "Flow" block, with back edge to entry block
160/// |
161/// \endverbatim
162///
163/// The back edge of the "Flow" block is always on the false side of the branch
164/// while the true side continues the general flow. So the loop condition
165/// consist of a network of PHI nodes where the true incoming values expresses
166/// breaks and the false values expresses continue states.
167class AMDGPUStructurizeCFG : public RegionPass {
168
169 static char ID;
170
171 Type *Boolean;
172 ConstantInt *BoolTrue;
173 ConstantInt *BoolFalse;
174 UndefValue *BoolUndef;
175
176 Function *Func;
177 Region *ParentRegion;
178
179 DominatorTree *DT;
180
181 RNVector Order;
Tom Stellardf4e471a2013-02-08 22:24:38 +0000182 BBSet Visited;
Christian Konig623977d2013-02-16 11:27:45 +0000183
Tom Stellard6b7d99d2012-12-19 22:10:31 +0000184 BBPhiMap DeletedPhis;
Tom Stellard13cf6cb2013-02-08 22:24:35 +0000185 BB2BBVecMap AddedPhis;
Christian Konig623977d2013-02-16 11:27:45 +0000186
187 PredMap Predicates;
Tom Stellard27f5d062013-02-08 22:24:37 +0000188 BranchVector Conditions;
Tom Stellard6b7d99d2012-12-19 22:10:31 +0000189
Christian Konig623977d2013-02-16 11:27:45 +0000190 BB2BBMap Loops;
191 PredMap LoopPreds;
192 BranchVector LoopConds;
193
194 RegionNode *PrevNode;
Tom Stellard6b7d99d2012-12-19 22:10:31 +0000195
196 void orderNodes();
197
Christian Konig623977d2013-02-16 11:27:45 +0000198 void analyzeLoops(RegionNode *N);
199
Christian Konigef6b2482013-02-16 11:27:50 +0000200 Value *invert(Value *Condition);
201
Tom Stellard27f5d062013-02-08 22:24:37 +0000202 Value *buildCondition(BranchInst *Term, unsigned Idx, bool Invert);
Tom Stellard6b7d99d2012-12-19 22:10:31 +0000203
Christian Konig623977d2013-02-16 11:27:45 +0000204 void gatherPredicates(RegionNode *N);
Tom Stellard6b7d99d2012-12-19 22:10:31 +0000205
206 void collectInfos();
207
Christian Konig623977d2013-02-16 11:27:45 +0000208 void insertConditions(bool Loops);
Tom Stellard27f5d062013-02-08 22:24:37 +0000209
Tom Stellard13cf6cb2013-02-08 22:24:35 +0000210 void delPhiValues(BasicBlock *From, BasicBlock *To);
211
212 void addPhiValues(BasicBlock *From, BasicBlock *To);
213
214 void setPhiValues();
215
Tom Stellard6b7d99d2012-12-19 22:10:31 +0000216 void killTerminator(BasicBlock *BB);
217
Tom Stellardf4e471a2013-02-08 22:24:38 +0000218 void changeExit(RegionNode *Node, BasicBlock *NewExit,
219 bool IncludeDominator);
Tom Stellard6b7d99d2012-12-19 22:10:31 +0000220
Tom Stellardf4e471a2013-02-08 22:24:38 +0000221 BasicBlock *getNextFlow(BasicBlock *Dominator);
Tom Stellard6b7d99d2012-12-19 22:10:31 +0000222
Christian Konig623977d2013-02-16 11:27:45 +0000223 BasicBlock *needPrefix(bool NeedEmpty);
Tom Stellard6b7d99d2012-12-19 22:10:31 +0000224
Tom Stellardf4e471a2013-02-08 22:24:38 +0000225 BasicBlock *needPostfix(BasicBlock *Flow, bool ExitUseAllowed);
226
Christian Konig623977d2013-02-16 11:27:45 +0000227 void setPrevNode(BasicBlock *BB);
Tom Stellardf4e471a2013-02-08 22:24:38 +0000228
229 bool dominatesPredicates(BasicBlock *BB, RegionNode *Node);
230
Christian Konig623977d2013-02-16 11:27:45 +0000231 bool isPredictableTrue(RegionNode *Node);
Tom Stellardf4e471a2013-02-08 22:24:38 +0000232
Christian Konig623977d2013-02-16 11:27:45 +0000233 void wireFlow(bool ExitUseAllowed, BasicBlock *LoopEnd);
234
235 void handleLoops(bool ExitUseAllowed, BasicBlock *LoopEnd);
Tom Stellard6b7d99d2012-12-19 22:10:31 +0000236
237 void createFlow();
238
Tom Stellard6b7d99d2012-12-19 22:10:31 +0000239 void rebuildSSA();
240
241public:
242 AMDGPUStructurizeCFG():
243 RegionPass(ID) {
244
245 initializeRegionInfoPass(*PassRegistry::getPassRegistry());
246 }
247
Christian Konig777962f2013-03-01 09:46:11 +0000248 using Pass::doInitialization;
Tom Stellard6b7d99d2012-12-19 22:10:31 +0000249 virtual bool doInitialization(Region *R, RGPassManager &RGM);
250
251 virtual bool runOnRegion(Region *R, RGPassManager &RGM);
252
253 virtual const char *getPassName() const {
254 return "AMDGPU simplify control flow";
255 }
256
257 void getAnalysisUsage(AnalysisUsage &AU) const {
258
259 AU.addRequired<DominatorTree>();
260 AU.addPreserved<DominatorTree>();
261 RegionPass::getAnalysisUsage(AU);
262 }
263
264};
265
266} // end anonymous namespace
267
268char AMDGPUStructurizeCFG::ID = 0;
269
270/// \brief Initialize the types and constants used in the pass
271bool AMDGPUStructurizeCFG::doInitialization(Region *R, RGPassManager &RGM) {
Tom Stellard6b7d99d2012-12-19 22:10:31 +0000272 LLVMContext &Context = R->getEntry()->getContext();
273
274 Boolean = Type::getInt1Ty(Context);
275 BoolTrue = ConstantInt::getTrue(Context);
276 BoolFalse = ConstantInt::getFalse(Context);
277 BoolUndef = UndefValue::get(Boolean);
278
279 return false;
280}
281
282/// \brief Build up the general order of nodes
283void AMDGPUStructurizeCFG::orderNodes() {
Tom Stellard6b7d99d2012-12-19 22:10:31 +0000284 scc_iterator<Region *> I = scc_begin(ParentRegion),
285 E = scc_end(ParentRegion);
286 for (Order.clear(); I != E; ++I) {
287 std::vector<RegionNode *> &Nodes = *I;
288 Order.append(Nodes.begin(), Nodes.end());
289 }
290}
291
Christian Konig623977d2013-02-16 11:27:45 +0000292/// \brief Determine the end of the loops
293void AMDGPUStructurizeCFG::analyzeLoops(RegionNode *N) {
294
295 if (N->isSubRegion()) {
296 // Test for exit as back edge
297 BasicBlock *Exit = N->getNodeAs<Region>()->getExit();
298 if (Visited.count(Exit))
299 Loops[Exit] = N->getEntry();
300
301 } else {
302 // Test for sucessors as back edge
303 BasicBlock *BB = N->getNodeAs<BasicBlock>();
304 BranchInst *Term = cast<BranchInst>(BB->getTerminator());
305
306 for (unsigned i = 0, e = Term->getNumSuccessors(); i != e; ++i) {
307 BasicBlock *Succ = Term->getSuccessor(i);
308
309 if (Visited.count(Succ))
310 Loops[Succ] = BB;
311 }
312 }
313}
314
Christian Konigef6b2482013-02-16 11:27:50 +0000315/// \brief Invert the given condition
316Value *AMDGPUStructurizeCFG::invert(Value *Condition) {
317
318 // First: Check if it's a constant
319 if (Condition == BoolTrue)
320 return BoolFalse;
321
322 if (Condition == BoolFalse)
323 return BoolTrue;
324
325 if (Condition == BoolUndef)
326 return BoolUndef;
327
328 // Second: If the condition is already inverted, return the original value
329 if (match(Condition, m_Not(m_Value(Condition))))
330 return Condition;
331
332 // Third: Check all the users for an invert
333 BasicBlock *Parent = cast<Instruction>(Condition)->getParent();
334 for (Value::use_iterator I = Condition->use_begin(),
335 E = Condition->use_end(); I != E; ++I) {
336
337 Instruction *User = dyn_cast<Instruction>(*I);
338 if (!User || User->getParent() != Parent)
339 continue;
340
341 if (match(*I, m_Not(m_Specific(Condition))))
342 return *I;
343 }
344
345 // Last option: Create a new instruction
346 return BinaryOperator::CreateNot(Condition, "", Parent->getTerminator());
347}
348
Tom Stellard27f5d062013-02-08 22:24:37 +0000349/// \brief Build the condition for one edge
350Value *AMDGPUStructurizeCFG::buildCondition(BranchInst *Term, unsigned Idx,
351 bool Invert) {
352 Value *Cond = Invert ? BoolFalse : BoolTrue;
353 if (Term->isConditional()) {
354 Cond = Term->getCondition();
Tom Stellard6b7d99d2012-12-19 22:10:31 +0000355
Tom Stellard27f5d062013-02-08 22:24:37 +0000356 if (Idx != Invert)
Christian Konigef6b2482013-02-16 11:27:50 +0000357 Cond = invert(Cond);
Tom Stellard27f5d062013-02-08 22:24:37 +0000358 }
359 return Cond;
360}
361
Tom Stellard27f5d062013-02-08 22:24:37 +0000362/// \brief Analyze the predecessors of each block and build up predicates
Christian Konig623977d2013-02-16 11:27:45 +0000363void AMDGPUStructurizeCFG::gatherPredicates(RegionNode *N) {
364
Tom Stellard6b7d99d2012-12-19 22:10:31 +0000365 RegionInfo *RI = ParentRegion->getRegionInfo();
Tom Stellard27f5d062013-02-08 22:24:37 +0000366 BasicBlock *BB = N->getEntry();
367 BBPredicates &Pred = Predicates[BB];
Christian Konig623977d2013-02-16 11:27:45 +0000368 BBPredicates &LPred = LoopPreds[BB];
Tom Stellard6b7d99d2012-12-19 22:10:31 +0000369
Tom Stellard27f5d062013-02-08 22:24:37 +0000370 for (pred_iterator PI = pred_begin(BB), PE = pred_end(BB);
371 PI != PE; ++PI) {
Tom Stellard6b7d99d2012-12-19 22:10:31 +0000372
Christian Konig623977d2013-02-16 11:27:45 +0000373 // Ignore it if it's a branch from outside into our region entry
374 if (!ParentRegion->contains(*PI))
Tom Stellard27f5d062013-02-08 22:24:37 +0000375 continue;
Tom Stellard6b7d99d2012-12-19 22:10:31 +0000376
Tom Stellard27f5d062013-02-08 22:24:37 +0000377 Region *R = RI->getRegionFor(*PI);
378 if (R == ParentRegion) {
Tom Stellard6b7d99d2012-12-19 22:10:31 +0000379
Tom Stellard27f5d062013-02-08 22:24:37 +0000380 // It's a top level block in our region
381 BranchInst *Term = cast<BranchInst>((*PI)->getTerminator());
382 for (unsigned i = 0, e = Term->getNumSuccessors(); i != e; ++i) {
383 BasicBlock *Succ = Term->getSuccessor(i);
384 if (Succ != BB)
385 continue;
Tom Stellard6b7d99d2012-12-19 22:10:31 +0000386
Tom Stellard27f5d062013-02-08 22:24:37 +0000387 if (Visited.count(*PI)) {
388 // Normal forward edge
389 if (Term->isConditional()) {
390 // Try to treat it like an ELSE block
391 BasicBlock *Other = Term->getSuccessor(!i);
Christian Konig623977d2013-02-16 11:27:45 +0000392 if (Visited.count(Other) && !Loops.count(Other) &&
Tom Stellard27f5d062013-02-08 22:24:37 +0000393 !Pred.count(Other) && !Pred.count(*PI)) {
Tom Stellard6b7d99d2012-12-19 22:10:31 +0000394
Tom Stellard27f5d062013-02-08 22:24:37 +0000395 Pred[Other] = BoolFalse;
396 Pred[*PI] = BoolTrue;
397 continue;
398 }
399 }
Christian Konig623977d2013-02-16 11:27:45 +0000400 Pred[*PI] = buildCondition(Term, i, false);
401
Tom Stellard27f5d062013-02-08 22:24:37 +0000402 } else {
403 // Back edge
Christian Konig623977d2013-02-16 11:27:45 +0000404 LPred[*PI] = buildCondition(Term, i, true);
Tom Stellard27f5d062013-02-08 22:24:37 +0000405 }
Tom Stellard27f5d062013-02-08 22:24:37 +0000406 }
407
408 } else {
409
410 // It's an exit from a sub region
411 while(R->getParent() != ParentRegion)
412 R = R->getParent();
413
414 // Edge from inside a subregion to its entry, ignore it
415 if (R == N)
416 continue;
417
418 BasicBlock *Entry = R->getEntry();
Christian Konig623977d2013-02-16 11:27:45 +0000419 if (Visited.count(Entry))
420 Pred[Entry] = BoolTrue;
421 else
422 LPred[Entry] = BoolFalse;
Tom Stellard6b7d99d2012-12-19 22:10:31 +0000423 }
424 }
425}
426
427/// \brief Collect various loop and predicate infos
428void AMDGPUStructurizeCFG::collectInfos() {
Tom Stellard6b7d99d2012-12-19 22:10:31 +0000429
430 // Reset predicate
431 Predicates.clear();
432
433 // and loop infos
Christian Konig623977d2013-02-16 11:27:45 +0000434 Loops.clear();
435 LoopPreds.clear();
Tom Stellard6b7d99d2012-12-19 22:10:31 +0000436
Tom Stellard27f5d062013-02-08 22:24:37 +0000437 // Reset the visited nodes
438 Visited.clear();
439
440 for (RNVector::reverse_iterator OI = Order.rbegin(), OE = Order.rend();
441 OI != OE; ++OI) {
Tom Stellard6b7d99d2012-12-19 22:10:31 +0000442
443 // Analyze all the conditions leading to a node
Christian Konig623977d2013-02-16 11:27:45 +0000444 gatherPredicates(*OI);
Tom Stellard6b7d99d2012-12-19 22:10:31 +0000445
Tom Stellard27f5d062013-02-08 22:24:37 +0000446 // Remember that we've seen this node
Tom Stellardf4e471a2013-02-08 22:24:38 +0000447 Visited.insert((*OI)->getEntry());
Tom Stellard6b7d99d2012-12-19 22:10:31 +0000448
Christian Konig623977d2013-02-16 11:27:45 +0000449 // Find the last back edges
450 analyzeLoops(*OI);
Tom Stellard27f5d062013-02-08 22:24:37 +0000451 }
Tom Stellard27f5d062013-02-08 22:24:37 +0000452}
453
454/// \brief Insert the missing branch conditions
Christian Konig623977d2013-02-16 11:27:45 +0000455void AMDGPUStructurizeCFG::insertConditions(bool Loops) {
456 BranchVector &Conds = Loops ? LoopConds : Conditions;
457 Value *Default = Loops ? BoolTrue : BoolFalse;
Tom Stellard27f5d062013-02-08 22:24:37 +0000458 SSAUpdater PhiInserter;
459
Christian Konig623977d2013-02-16 11:27:45 +0000460 for (BranchVector::iterator I = Conds.begin(),
461 E = Conds.end(); I != E; ++I) {
Tom Stellard27f5d062013-02-08 22:24:37 +0000462
463 BranchInst *Term = *I;
Tom Stellard27f5d062013-02-08 22:24:37 +0000464 assert(Term->isConditional());
465
Christian Konig623977d2013-02-16 11:27:45 +0000466 BasicBlock *Parent = Term->getParent();
467 BasicBlock *SuccTrue = Term->getSuccessor(0);
468 BasicBlock *SuccFalse = Term->getSuccessor(1);
Tom Stellard27f5d062013-02-08 22:24:37 +0000469
Christian Konig25bd8842013-02-16 11:27:40 +0000470 PhiInserter.Initialize(Boolean, "");
471 PhiInserter.AddAvailableValue(&Func->getEntryBlock(), Default);
Christian Konig623977d2013-02-16 11:27:45 +0000472 PhiInserter.AddAvailableValue(Loops ? SuccFalse : Parent, Default);
Christian Konig25bd8842013-02-16 11:27:40 +0000473
Christian Konig623977d2013-02-16 11:27:45 +0000474 BBPredicates &Preds = Loops ? LoopPreds[SuccFalse] : Predicates[SuccTrue];
Christian Konig25bd8842013-02-16 11:27:40 +0000475
476 NearestCommonDominator Dominator(DT);
477 Dominator.addBlock(Parent, false);
478
479 Value *ParentValue = 0;
Tom Stellard27f5d062013-02-08 22:24:37 +0000480 for (BBPredicates::iterator PI = Preds.begin(), PE = Preds.end();
481 PI != PE; ++PI) {
482
Christian Konig25bd8842013-02-16 11:27:40 +0000483 if (PI->first == Parent) {
484 ParentValue = PI->second;
485 break;
486 }
Tom Stellard27f5d062013-02-08 22:24:37 +0000487 PhiInserter.AddAvailableValue(PI->first, PI->second);
Christian Konig25bd8842013-02-16 11:27:40 +0000488 Dominator.addBlock(PI->first);
Tom Stellard27f5d062013-02-08 22:24:37 +0000489 }
490
Christian Konig25bd8842013-02-16 11:27:40 +0000491 if (ParentValue) {
492 Term->setCondition(ParentValue);
493 } else {
494 if (!Dominator.wasResultExplicitMentioned())
495 PhiInserter.AddAvailableValue(Dominator.getResult(), Default);
496
Tom Stellard27f5d062013-02-08 22:24:37 +0000497 Term->setCondition(PhiInserter.GetValueInMiddleOfBlock(Parent));
Christian Konig25bd8842013-02-16 11:27:40 +0000498 }
Tom Stellard6b7d99d2012-12-19 22:10:31 +0000499 }
500}
501
Tom Stellard13cf6cb2013-02-08 22:24:35 +0000502/// \brief Remove all PHI values coming from "From" into "To" and remember
503/// them in DeletedPhis
504void AMDGPUStructurizeCFG::delPhiValues(BasicBlock *From, BasicBlock *To) {
505 PhiMap &Map = DeletedPhis[To];
506 for (BasicBlock::iterator I = To->begin(), E = To->end();
507 I != E && isa<PHINode>(*I);) {
508
509 PHINode &Phi = cast<PHINode>(*I++);
510 while (Phi.getBasicBlockIndex(From) != -1) {
511 Value *Deleted = Phi.removeIncomingValue(From, false);
512 Map[&Phi].push_back(std::make_pair(From, Deleted));
513 }
514 }
515}
516
517/// \brief Add a dummy PHI value as soon as we knew the new predecessor
518void AMDGPUStructurizeCFG::addPhiValues(BasicBlock *From, BasicBlock *To) {
519 for (BasicBlock::iterator I = To->begin(), E = To->end();
520 I != E && isa<PHINode>(*I);) {
521
522 PHINode &Phi = cast<PHINode>(*I++);
523 Value *Undef = UndefValue::get(Phi.getType());
524 Phi.addIncoming(Undef, From);
525 }
526 AddedPhis[To].push_back(From);
527}
528
529/// \brief Add the real PHI value as soon as everything is set up
530void AMDGPUStructurizeCFG::setPhiValues() {
531
532 SSAUpdater Updater;
533 for (BB2BBVecMap::iterator AI = AddedPhis.begin(), AE = AddedPhis.end();
534 AI != AE; ++AI) {
535
536 BasicBlock *To = AI->first;
537 BBVector &From = AI->second;
538
539 if (!DeletedPhis.count(To))
540 continue;
541
542 PhiMap &Map = DeletedPhis[To];
543 for (PhiMap::iterator PI = Map.begin(), PE = Map.end();
544 PI != PE; ++PI) {
545
546 PHINode *Phi = PI->first;
547 Value *Undef = UndefValue::get(Phi->getType());
548 Updater.Initialize(Phi->getType(), "");
549 Updater.AddAvailableValue(&Func->getEntryBlock(), Undef);
550 Updater.AddAvailableValue(To, Undef);
551
Christian Konig4c79c712013-02-16 11:27:35 +0000552 NearestCommonDominator Dominator(DT);
553 Dominator.addBlock(To, false);
Tom Stellard13cf6cb2013-02-08 22:24:35 +0000554 for (BBValueVector::iterator VI = PI->second.begin(),
555 VE = PI->second.end(); VI != VE; ++VI) {
556
557 Updater.AddAvailableValue(VI->first, VI->second);
Christian Konig4c79c712013-02-16 11:27:35 +0000558 Dominator.addBlock(VI->first);
Tom Stellard13cf6cb2013-02-08 22:24:35 +0000559 }
560
Christian Konig4c79c712013-02-16 11:27:35 +0000561 if (!Dominator.wasResultExplicitMentioned())
562 Updater.AddAvailableValue(Dominator.getResult(), Undef);
563
Tom Stellard13cf6cb2013-02-08 22:24:35 +0000564 for (BBVector::iterator FI = From.begin(), FE = From.end();
565 FI != FE; ++FI) {
566
567 int Idx = Phi->getBasicBlockIndex(*FI);
568 assert(Idx != -1);
569 Phi->setIncomingValue(Idx, Updater.GetValueAtEndOfBlock(*FI));
570 }
571 }
572
573 DeletedPhis.erase(To);
574 }
575 assert(DeletedPhis.empty());
576}
577
Tom Stellardf4e471a2013-02-08 22:24:38 +0000578/// \brief Remove phi values from all successors and then remove the terminator.
Tom Stellard6b7d99d2012-12-19 22:10:31 +0000579void AMDGPUStructurizeCFG::killTerminator(BasicBlock *BB) {
Tom Stellard6b7d99d2012-12-19 22:10:31 +0000580 TerminatorInst *Term = BB->getTerminator();
581 if (!Term)
582 return;
583
584 for (succ_iterator SI = succ_begin(BB), SE = succ_end(BB);
585 SI != SE; ++SI) {
586
587 delPhiValues(BB, *SI);
588 }
589
590 Term->eraseFromParent();
591}
592
Tom Stellardf4e471a2013-02-08 22:24:38 +0000593/// \brief Let node exit(s) point to NewExit
594void AMDGPUStructurizeCFG::changeExit(RegionNode *Node, BasicBlock *NewExit,
595 bool IncludeDominator) {
Tom Stellard6b7d99d2012-12-19 22:10:31 +0000596
Tom Stellardf4e471a2013-02-08 22:24:38 +0000597 if (Node->isSubRegion()) {
598 Region *SubRegion = Node->getNodeAs<Region>();
599 BasicBlock *OldExit = SubRegion->getExit();
600 BasicBlock *Dominator = 0;
Tom Stellard6b7d99d2012-12-19 22:10:31 +0000601
Tom Stellardf4e471a2013-02-08 22:24:38 +0000602 // Find all the edges from the sub region to the exit
603 for (pred_iterator I = pred_begin(OldExit), E = pred_end(OldExit);
604 I != E;) {
605
606 BasicBlock *BB = *I++;
607 if (!SubRegion->contains(BB))
608 continue;
609
610 // Modify the edges to point to the new exit
611 delPhiValues(BB, OldExit);
612 BB->getTerminator()->replaceUsesOfWith(OldExit, NewExit);
613 addPhiValues(BB, NewExit);
614
615 // Find the new dominator (if requested)
616 if (IncludeDominator) {
617 if (!Dominator)
618 Dominator = BB;
619 else
620 Dominator = DT->findNearestCommonDominator(Dominator, BB);
621 }
Tom Stellard6b7d99d2012-12-19 22:10:31 +0000622 }
623
Tom Stellardf4e471a2013-02-08 22:24:38 +0000624 // Change the dominator (if requested)
625 if (Dominator)
626 DT->changeImmediateDominator(NewExit, Dominator);
Tom Stellard6b7d99d2012-12-19 22:10:31 +0000627
Tom Stellardf4e471a2013-02-08 22:24:38 +0000628 // Update the region info
629 SubRegion->replaceExit(NewExit);
Tom Stellard6b7d99d2012-12-19 22:10:31 +0000630
Tom Stellard6b7d99d2012-12-19 22:10:31 +0000631 } else {
Tom Stellardf4e471a2013-02-08 22:24:38 +0000632 BasicBlock *BB = Node->getNodeAs<BasicBlock>();
633 killTerminator(BB);
634 BranchInst::Create(NewExit, BB);
635 addPhiValues(BB, NewExit);
636 if (IncludeDominator)
637 DT->changeImmediateDominator(NewExit, BB);
Tom Stellard6b7d99d2012-12-19 22:10:31 +0000638 }
Tom Stellard6b7d99d2012-12-19 22:10:31 +0000639}
640
Tom Stellard6b7d99d2012-12-19 22:10:31 +0000641/// \brief Create a new flow node and update dominator tree and region info
Tom Stellardf4e471a2013-02-08 22:24:38 +0000642BasicBlock *AMDGPUStructurizeCFG::getNextFlow(BasicBlock *Dominator) {
Tom Stellard6b7d99d2012-12-19 22:10:31 +0000643 LLVMContext &Context = Func->getContext();
644 BasicBlock *Insert = Order.empty() ? ParentRegion->getExit() :
645 Order.back()->getEntry();
646 BasicBlock *Flow = BasicBlock::Create(Context, FlowBlockName,
647 Func, Insert);
Tom Stellardf4e471a2013-02-08 22:24:38 +0000648 DT->addNewBlock(Flow, Dominator);
Tom Stellard6b7d99d2012-12-19 22:10:31 +0000649 ParentRegion->getRegionInfo()->setRegionFor(Flow, ParentRegion);
Tom Stellard6b7d99d2012-12-19 22:10:31 +0000650 return Flow;
651}
652
Tom Stellardf4e471a2013-02-08 22:24:38 +0000653/// \brief Create a new or reuse the previous node as flow node
Christian Konig623977d2013-02-16 11:27:45 +0000654BasicBlock *AMDGPUStructurizeCFG::needPrefix(bool NeedEmpty) {
Tom Stellardf4e471a2013-02-08 22:24:38 +0000655
Christian Konig623977d2013-02-16 11:27:45 +0000656 BasicBlock *Entry = PrevNode->getEntry();
Tom Stellardf4e471a2013-02-08 22:24:38 +0000657
Christian Konig623977d2013-02-16 11:27:45 +0000658 if (!PrevNode->isSubRegion()) {
659 killTerminator(Entry);
660 if (!NeedEmpty || Entry->getFirstInsertionPt() == Entry->end())
661 return Entry;
Tom Stellardf4e471a2013-02-08 22:24:38 +0000662
Christian Konig623977d2013-02-16 11:27:45 +0000663 }
Tom Stellardf4e471a2013-02-08 22:24:38 +0000664
Christian Konig623977d2013-02-16 11:27:45 +0000665 // create a new flow node
666 BasicBlock *Flow = getNextFlow(Entry);
Tom Stellardf4e471a2013-02-08 22:24:38 +0000667
Christian Konig623977d2013-02-16 11:27:45 +0000668 // and wire it up
669 changeExit(PrevNode, Flow, true);
670 PrevNode = ParentRegion->getBBNode(Flow);
671 return Flow;
Tom Stellardf4e471a2013-02-08 22:24:38 +0000672}
673
674/// \brief Returns the region exit if possible, otherwise just a new flow node
675BasicBlock *AMDGPUStructurizeCFG::needPostfix(BasicBlock *Flow,
676 bool ExitUseAllowed) {
677
678 if (Order.empty() && ExitUseAllowed) {
679 BasicBlock *Exit = ParentRegion->getExit();
680 DT->changeImmediateDominator(Exit, Flow);
681 addPhiValues(Flow, Exit);
682 return Exit;
683 }
684 return getNextFlow(Flow);
685}
686
Christian Konig623977d2013-02-16 11:27:45 +0000687/// \brief Set the previous node
688void AMDGPUStructurizeCFG::setPrevNode(BasicBlock *BB) {
689 PrevNode = ParentRegion->contains(BB) ? ParentRegion->getBBNode(BB) : 0;
Tom Stellardf4e471a2013-02-08 22:24:38 +0000690}
691
692/// \brief Does BB dominate all the predicates of Node ?
693bool AMDGPUStructurizeCFG::dominatesPredicates(BasicBlock *BB, RegionNode *Node) {
694 BBPredicates &Preds = Predicates[Node->getEntry()];
695 for (BBPredicates::iterator PI = Preds.begin(), PE = Preds.end();
696 PI != PE; ++PI) {
697
698 if (!DT->dominates(BB, PI->first))
699 return false;
700 }
701 return true;
702}
703
Tom Stellard6b7d99d2012-12-19 22:10:31 +0000704/// \brief Can we predict that this node will always be called?
Christian Konig623977d2013-02-16 11:27:45 +0000705bool AMDGPUStructurizeCFG::isPredictableTrue(RegionNode *Node) {
Tom Stellardf4e471a2013-02-08 22:24:38 +0000706
Christian Konig623977d2013-02-16 11:27:45 +0000707 BBPredicates &Preds = Predicates[Node->getEntry()];
708 bool Dominated = false;
709
710 // Regionentry is always true
711 if (PrevNode == 0)
712 return true;
Tom Stellard6b7d99d2012-12-19 22:10:31 +0000713
714 for (BBPredicates::iterator I = Preds.begin(), E = Preds.end();
715 I != E; ++I) {
716
717 if (I->second != BoolTrue)
718 return false;
719
Christian Konig623977d2013-02-16 11:27:45 +0000720 if (!Dominated && DT->dominates(I->first, PrevNode->getEntry()))
Tom Stellard6b7d99d2012-12-19 22:10:31 +0000721 Dominated = true;
722 }
Tom Stellardf4e471a2013-02-08 22:24:38 +0000723
724 // TODO: The dominator check is too strict
Tom Stellard6b7d99d2012-12-19 22:10:31 +0000725 return Dominated;
726}
727
Tom Stellardf4e471a2013-02-08 22:24:38 +0000728/// Take one node from the order vector and wire it up
Christian Konig623977d2013-02-16 11:27:45 +0000729void AMDGPUStructurizeCFG::wireFlow(bool ExitUseAllowed,
730 BasicBlock *LoopEnd) {
Tom Stellard6b7d99d2012-12-19 22:10:31 +0000731
Tom Stellardf4e471a2013-02-08 22:24:38 +0000732 RegionNode *Node = Order.pop_back_val();
Christian Konig623977d2013-02-16 11:27:45 +0000733 Visited.insert(Node->getEntry());
Tom Stellard6b7d99d2012-12-19 22:10:31 +0000734
Christian Konig623977d2013-02-16 11:27:45 +0000735 if (isPredictableTrue(Node)) {
Tom Stellardf4e471a2013-02-08 22:24:38 +0000736 // Just a linear flow
Christian Konig623977d2013-02-16 11:27:45 +0000737 if (PrevNode) {
738 changeExit(PrevNode, Node->getEntry(), true);
Tom Stellard6b7d99d2012-12-19 22:10:31 +0000739 }
Christian Konig623977d2013-02-16 11:27:45 +0000740 PrevNode = Node;
Tom Stellard6b7d99d2012-12-19 22:10:31 +0000741
742 } else {
Tom Stellardf4e471a2013-02-08 22:24:38 +0000743 // Insert extra prefix node (or reuse last one)
Christian Konig623977d2013-02-16 11:27:45 +0000744 BasicBlock *Flow = needPrefix(false);
Tom Stellard6b7d99d2012-12-19 22:10:31 +0000745
Tom Stellardf4e471a2013-02-08 22:24:38 +0000746 // Insert extra postfix node (or use exit instead)
747 BasicBlock *Entry = Node->getEntry();
Christian Konig623977d2013-02-16 11:27:45 +0000748 BasicBlock *Next = needPostfix(Flow, ExitUseAllowed);
Tom Stellardf4e471a2013-02-08 22:24:38 +0000749
750 // let it point to entry and next block
751 Conditions.push_back(BranchInst::Create(Entry, Next, BoolUndef, Flow));
752 addPhiValues(Flow, Entry);
753 DT->changeImmediateDominator(Entry, Flow);
754
Christian Konig623977d2013-02-16 11:27:45 +0000755 PrevNode = Node;
756 while (!Order.empty() && !Visited.count(LoopEnd) &&
Tom Stellardf4e471a2013-02-08 22:24:38 +0000757 dominatesPredicates(Entry, Order.back())) {
Christian Konig623977d2013-02-16 11:27:45 +0000758 handleLoops(false, LoopEnd);
Tom Stellardf4e471a2013-02-08 22:24:38 +0000759 }
760
Christian Konig623977d2013-02-16 11:27:45 +0000761 changeExit(PrevNode, Next, false);
762 setPrevNode(Next);
763 }
764}
765
766void AMDGPUStructurizeCFG::handleLoops(bool ExitUseAllowed,
767 BasicBlock *LoopEnd) {
768 RegionNode *Node = Order.back();
769 BasicBlock *LoopStart = Node->getEntry();
770
771 if (!Loops.count(LoopStart)) {
772 wireFlow(ExitUseAllowed, LoopEnd);
773 return;
Tom Stellard6b7d99d2012-12-19 22:10:31 +0000774 }
775
Christian Konig623977d2013-02-16 11:27:45 +0000776 if (!isPredictableTrue(Node))
777 LoopStart = needPrefix(true);
778
779 LoopEnd = Loops[Node->getEntry()];
780 wireFlow(false, LoopEnd);
781 while (!Visited.count(LoopEnd)) {
782 handleLoops(false, LoopEnd);
783 }
784
785 // Create an extra loop end node
786 LoopEnd = needPrefix(false);
787 BasicBlock *Next = needPostfix(LoopEnd, ExitUseAllowed);
788 LoopConds.push_back(BranchInst::Create(Next, LoopStart,
789 BoolUndef, LoopEnd));
790 addPhiValues(LoopEnd, LoopStart);
791 setPrevNode(Next);
Tom Stellard6b7d99d2012-12-19 22:10:31 +0000792}
793
Tom Stellard6b7d99d2012-12-19 22:10:31 +0000794/// After this function control flow looks like it should be, but
Tom Stellardf4e471a2013-02-08 22:24:38 +0000795/// branches and PHI nodes only have undefined conditions.
Tom Stellard6b7d99d2012-12-19 22:10:31 +0000796void AMDGPUStructurizeCFG::createFlow() {
Tom Stellardf4e471a2013-02-08 22:24:38 +0000797
798 BasicBlock *Exit = ParentRegion->getExit();
799 bool EntryDominatesExit = DT->dominates(ParentRegion->getEntry(), Exit);
800
Tom Stellard6b7d99d2012-12-19 22:10:31 +0000801 DeletedPhis.clear();
Tom Stellard13cf6cb2013-02-08 22:24:35 +0000802 AddedPhis.clear();
Tom Stellardf4e471a2013-02-08 22:24:38 +0000803 Conditions.clear();
Christian Konig623977d2013-02-16 11:27:45 +0000804 LoopConds.clear();
Tom Stellard6b7d99d2012-12-19 22:10:31 +0000805
Christian Konig623977d2013-02-16 11:27:45 +0000806 PrevNode = 0;
807 Visited.clear();
808
Tom Stellard6b7d99d2012-12-19 22:10:31 +0000809 while (!Order.empty()) {
Christian Konig623977d2013-02-16 11:27:45 +0000810 handleLoops(EntryDominatesExit, 0);
Tom Stellard6b7d99d2012-12-19 22:10:31 +0000811 }
812
Christian Konig623977d2013-02-16 11:27:45 +0000813 if (PrevNode)
814 changeExit(PrevNode, Exit, EntryDominatesExit);
Tom Stellardf4e471a2013-02-08 22:24:38 +0000815 else
816 assert(EntryDominatesExit);
Tom Stellard6b7d99d2012-12-19 22:10:31 +0000817}
818
Tom Stellard6b7d99d2012-12-19 22:10:31 +0000819/// Handle a rare case where the disintegrated nodes instructions
820/// no longer dominate all their uses. Not sure if this is really nessasary
821void AMDGPUStructurizeCFG::rebuildSSA() {
Tom Stellard6b7d99d2012-12-19 22:10:31 +0000822 SSAUpdater Updater;
823 for (Region::block_iterator I = ParentRegion->block_begin(),
824 E = ParentRegion->block_end();
825 I != E; ++I) {
826
827 BasicBlock *BB = *I;
828 for (BasicBlock::iterator II = BB->begin(), IE = BB->end();
829 II != IE; ++II) {
830
831 bool Initialized = false;
832 for (Use *I = &II->use_begin().getUse(), *Next; I; I = Next) {
833
834 Next = I->getNext();
835
836 Instruction *User = cast<Instruction>(I->getUser());
837 if (User->getParent() == BB) {
838 continue;
839
840 } else if (PHINode *UserPN = dyn_cast<PHINode>(User)) {
841 if (UserPN->getIncomingBlock(*I) == BB)
842 continue;
843 }
844
845 if (DT->dominates(II, User))
846 continue;
847
848 if (!Initialized) {
849 Value *Undef = UndefValue::get(II->getType());
850 Updater.Initialize(II->getType(), "");
851 Updater.AddAvailableValue(&Func->getEntryBlock(), Undef);
852 Updater.AddAvailableValue(BB, II);
853 Initialized = true;
854 }
855 Updater.RewriteUseAfterInsertions(*I);
856 }
857 }
858 }
859}
860
861/// \brief Run the transformation for each region found
862bool AMDGPUStructurizeCFG::runOnRegion(Region *R, RGPassManager &RGM) {
Tom Stellard6b7d99d2012-12-19 22:10:31 +0000863 if (R->isTopLevelRegion())
864 return false;
865
866 Func = R->getEntry()->getParent();
867 ParentRegion = R;
868
869 DT = &getAnalysis<DominatorTree>();
870
871 orderNodes();
872 collectInfos();
873 createFlow();
Christian Konig623977d2013-02-16 11:27:45 +0000874 insertConditions(false);
875 insertConditions(true);
Tom Stellard13cf6cb2013-02-08 22:24:35 +0000876 setPhiValues();
Tom Stellard6b7d99d2012-12-19 22:10:31 +0000877 rebuildSSA();
878
Tom Stellard27f5d062013-02-08 22:24:37 +0000879 // Cleanup
Tom Stellard6b7d99d2012-12-19 22:10:31 +0000880 Order.clear();
881 Visited.clear();
Tom Stellard6b7d99d2012-12-19 22:10:31 +0000882 DeletedPhis.clear();
Tom Stellard13cf6cb2013-02-08 22:24:35 +0000883 AddedPhis.clear();
Christian Konig623977d2013-02-16 11:27:45 +0000884 Predicates.clear();
Tom Stellard27f5d062013-02-08 22:24:37 +0000885 Conditions.clear();
Christian Konig623977d2013-02-16 11:27:45 +0000886 Loops.clear();
887 LoopPreds.clear();
888 LoopConds.clear();
Tom Stellard6b7d99d2012-12-19 22:10:31 +0000889
890 return true;
891}
892
893/// \brief Create the pass
894Pass *llvm::createAMDGPUStructurizeCFGPass() {
895 return new AMDGPUStructurizeCFG();
896}