xref: /src/contrib/llvm-project/llvm/lib/Target/AMDGPU/SIAnnotateControlFlow.cpp (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
1044eb2f6SDimitry Andric //===- SIAnnotateControlFlow.cpp ------------------------------------------===//
24a16efa3SDimitry Andric //
3e6d15924SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4e6d15924SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
5e6d15924SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
64a16efa3SDimitry Andric //
74a16efa3SDimitry Andric //===----------------------------------------------------------------------===//
84a16efa3SDimitry Andric //
94a16efa3SDimitry Andric /// \file
104a16efa3SDimitry Andric /// Annotates the control flow with hardware specific intrinsics.
114a16efa3SDimitry Andric //
124a16efa3SDimitry Andric //===----------------------------------------------------------------------===//
134a16efa3SDimitry Andric 
144a16efa3SDimitry Andric #include "AMDGPU.h"
15b60736ecSDimitry Andric #include "GCNSubtarget.h"
16608e6659SDimitry Andric #include "llvm/Analysis/LoopInfo.h"
177fa27ce4SDimitry Andric #include "llvm/Analysis/UniformityAnalysis.h"
18e6d15924SDimitry Andric #include "llvm/CodeGen/TargetPassConfig.h"
19044eb2f6SDimitry Andric #include "llvm/IR/BasicBlock.h"
20f8af5cf6SDimitry Andric #include "llvm/IR/Constants.h"
215ca98fd9SDimitry Andric #include "llvm/IR/Dominators.h"
22b1c73532SDimitry Andric #include "llvm/IR/IRBuilder.h"
23b60736ecSDimitry Andric #include "llvm/IR/IntrinsicsAMDGPU.h"
24706b4fc4SDimitry Andric #include "llvm/InitializePasses.h"
25b60736ecSDimitry Andric #include "llvm/Target/TargetMachine.h"
264a16efa3SDimitry Andric #include "llvm/Transforms/Utils/BasicBlockUtils.h"
27e6d15924SDimitry Andric #include "llvm/Transforms/Utils/Local.h"
284a16efa3SDimitry Andric 
294a16efa3SDimitry Andric using namespace llvm;
304a16efa3SDimitry Andric 
315ca98fd9SDimitry Andric #define DEBUG_TYPE "si-annotate-control-flow"
325ca98fd9SDimitry Andric 
334a16efa3SDimitry Andric namespace {
344a16efa3SDimitry Andric 
354a16efa3SDimitry Andric // Complex types used in this pass
36044eb2f6SDimitry Andric using StackEntry = std::pair<BasicBlock *, Value *>;
37044eb2f6SDimitry Andric using StackVector = SmallVector<StackEntry, 16>;
384a16efa3SDimitry Andric 
394a16efa3SDimitry Andric class SIAnnotateControlFlow : public FunctionPass {
407fa27ce4SDimitry Andric   UniformityInfo *UA;
414a16efa3SDimitry Andric 
424a16efa3SDimitry Andric   Type *Boolean;
434a16efa3SDimitry Andric   Type *Void;
44e6d15924SDimitry Andric   Type *IntMask;
454a16efa3SDimitry Andric   Type *ReturnStruct;
464a16efa3SDimitry Andric 
474a16efa3SDimitry Andric   ConstantInt *BoolTrue;
484a16efa3SDimitry Andric   ConstantInt *BoolFalse;
494a16efa3SDimitry Andric   UndefValue *BoolUndef;
50e6d15924SDimitry Andric   Constant *IntMaskZero;
514a16efa3SDimitry Andric 
5271d5a254SDimitry Andric   Function *If;
5371d5a254SDimitry Andric   Function *Else;
5471d5a254SDimitry Andric   Function *IfBreak;
5571d5a254SDimitry Andric   Function *Loop;
5671d5a254SDimitry Andric   Function *EndCf;
574a16efa3SDimitry Andric 
584a16efa3SDimitry Andric   DominatorTree *DT;
594a16efa3SDimitry Andric   StackVector Stack;
604a16efa3SDimitry Andric 
61608e6659SDimitry Andric   LoopInfo *LI;
62608e6659SDimitry Andric 
63e6d15924SDimitry Andric   void initialize(Module &M, const GCNSubtarget &ST);
64e6d15924SDimitry Andric 
6501095a5dSDimitry Andric   bool isUniform(BranchInst *T);
6601095a5dSDimitry Andric 
674a16efa3SDimitry Andric   bool isTopOfStack(BasicBlock *BB);
684a16efa3SDimitry Andric 
694a16efa3SDimitry Andric   Value *popSaved();
704a16efa3SDimitry Andric 
714a16efa3SDimitry Andric   void push(BasicBlock *BB, Value *Saved);
724a16efa3SDimitry Andric 
734a16efa3SDimitry Andric   bool isElse(PHINode *Phi);
744a16efa3SDimitry Andric 
75344a3780SDimitry Andric   bool hasKill(const BasicBlock *BB);
76344a3780SDimitry Andric 
77145449b1SDimitry Andric   bool eraseIfUnused(PHINode *Phi);
784a16efa3SDimitry Andric 
79145449b1SDimitry Andric   bool openIf(BranchInst *Term);
804a16efa3SDimitry Andric 
81145449b1SDimitry Andric   bool insertElse(BranchInst *Term);
824a16efa3SDimitry Andric 
83a303c417SDimitry Andric   Value *
84a303c417SDimitry Andric   handleLoopCondition(Value *Cond, PHINode *Broken, llvm::Loop *L,
85d8e91e46SDimitry Andric                       BranchInst *Term);
864a16efa3SDimitry Andric 
87145449b1SDimitry Andric   bool handleLoop(BranchInst *Term);
884a16efa3SDimitry Andric 
89145449b1SDimitry Andric   bool closeControlFlow(BasicBlock *BB);
904a16efa3SDimitry Andric 
914a16efa3SDimitry Andric public:
9201095a5dSDimitry Andric   static char ID;
9301095a5dSDimitry Andric 
SIAnnotateControlFlow()94044eb2f6SDimitry Andric   SIAnnotateControlFlow() : FunctionPass(ID) {}
954a16efa3SDimitry Andric 
965ca98fd9SDimitry Andric   bool runOnFunction(Function &F) override;
974a16efa3SDimitry Andric 
getPassName() const98b915e9e0SDimitry Andric   StringRef getPassName() const override { return "SI annotate control flow"; }
994a16efa3SDimitry Andric 
getAnalysisUsage(AnalysisUsage & AU) const1005ca98fd9SDimitry Andric   void getAnalysisUsage(AnalysisUsage &AU) const override {
1015a5ac124SDimitry Andric     AU.addRequired<LoopInfoWrapperPass>();
1025ca98fd9SDimitry Andric     AU.addRequired<DominatorTreeWrapperPass>();
1037fa27ce4SDimitry Andric     AU.addRequired<UniformityInfoWrapperPass>();
104344a3780SDimitry Andric     AU.addPreserved<LoopInfoWrapperPass>();
1055ca98fd9SDimitry Andric     AU.addPreserved<DominatorTreeWrapperPass>();
106e6d15924SDimitry Andric     AU.addRequired<TargetPassConfig>();
1074a16efa3SDimitry Andric     FunctionPass::getAnalysisUsage(AU);
1084a16efa3SDimitry Andric   }
1094a16efa3SDimitry Andric };
1104a16efa3SDimitry Andric 
1114a16efa3SDimitry Andric } // end anonymous namespace
1124a16efa3SDimitry Andric 
11301095a5dSDimitry Andric INITIALIZE_PASS_BEGIN(SIAnnotateControlFlow, DEBUG_TYPE,
11401095a5dSDimitry Andric                       "Annotate SI Control Flow", false, false)
11571d5a254SDimitry Andric INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass)
1167fa27ce4SDimitry Andric INITIALIZE_PASS_DEPENDENCY(UniformityInfoWrapperPass)
117e6d15924SDimitry Andric INITIALIZE_PASS_DEPENDENCY(TargetPassConfig)
11801095a5dSDimitry Andric INITIALIZE_PASS_END(SIAnnotateControlFlow, DEBUG_TYPE,
11901095a5dSDimitry Andric                     "Annotate SI Control Flow", false, false)
12001095a5dSDimitry Andric 
1214a16efa3SDimitry Andric char SIAnnotateControlFlow::ID = 0;
1224a16efa3SDimitry Andric 
123eb11fae6SDimitry Andric /// Initialize all the types and constants used in the pass
initialize(Module & M,const GCNSubtarget & ST)124e6d15924SDimitry Andric void SIAnnotateControlFlow::initialize(Module &M, const GCNSubtarget &ST) {
1254a16efa3SDimitry Andric   LLVMContext &Context = M.getContext();
1264a16efa3SDimitry Andric 
1274a16efa3SDimitry Andric   Void = Type::getVoidTy(Context);
1284a16efa3SDimitry Andric   Boolean = Type::getInt1Ty(Context);
129e6d15924SDimitry Andric   IntMask = ST.isWave32() ? Type::getInt32Ty(Context)
130e6d15924SDimitry Andric                            : Type::getInt64Ty(Context);
131e6d15924SDimitry Andric   ReturnStruct = StructType::get(Boolean, IntMask);
1324a16efa3SDimitry Andric 
1334a16efa3SDimitry Andric   BoolTrue = ConstantInt::getTrue(Context);
1344a16efa3SDimitry Andric   BoolFalse = ConstantInt::getFalse(Context);
135e3b55780SDimitry Andric   BoolUndef = PoisonValue::get(Boolean);
136e6d15924SDimitry Andric   IntMaskZero = ConstantInt::get(IntMask, 0);
1374a16efa3SDimitry Andric 
138e6d15924SDimitry Andric   If = Intrinsic::getDeclaration(&M, Intrinsic::amdgcn_if, { IntMask });
139e6d15924SDimitry Andric   Else = Intrinsic::getDeclaration(&M, Intrinsic::amdgcn_else,
140e6d15924SDimitry Andric                                    { IntMask, IntMask });
141e6d15924SDimitry Andric   IfBreak = Intrinsic::getDeclaration(&M, Intrinsic::amdgcn_if_break,
142cfca06d7SDimitry Andric                                       { IntMask });
143e6d15924SDimitry Andric   Loop = Intrinsic::getDeclaration(&M, Intrinsic::amdgcn_loop, { IntMask });
144e6d15924SDimitry Andric   EndCf = Intrinsic::getDeclaration(&M, Intrinsic::amdgcn_end_cf, { IntMask });
1454a16efa3SDimitry Andric }
1464a16efa3SDimitry Andric 
147eb11fae6SDimitry Andric /// Is the branch condition uniform or did the StructurizeCFG pass
14801095a5dSDimitry Andric /// consider it as such?
isUniform(BranchInst * T)14901095a5dSDimitry Andric bool SIAnnotateControlFlow::isUniform(BranchInst *T) {
150ac9a064cSDimitry Andric   return UA->isUniform(T) || T->hasMetadata("structurizecfg.uniform");
15101095a5dSDimitry Andric }
15201095a5dSDimitry Andric 
153eb11fae6SDimitry Andric /// Is BB the last block saved on the stack ?
isTopOfStack(BasicBlock * BB)1544a16efa3SDimitry Andric bool SIAnnotateControlFlow::isTopOfStack(BasicBlock *BB) {
1554a16efa3SDimitry Andric   return !Stack.empty() && Stack.back().first == BB;
1564a16efa3SDimitry Andric }
1574a16efa3SDimitry Andric 
158eb11fae6SDimitry Andric /// Pop the last saved value from the control flow stack
popSaved()1594a16efa3SDimitry Andric Value *SIAnnotateControlFlow::popSaved() {
1604a16efa3SDimitry Andric   return Stack.pop_back_val().second;
1614a16efa3SDimitry Andric }
1624a16efa3SDimitry Andric 
163eb11fae6SDimitry Andric /// Push a BB and saved value to the control flow stack
push(BasicBlock * BB,Value * Saved)1644a16efa3SDimitry Andric void SIAnnotateControlFlow::push(BasicBlock *BB, Value *Saved) {
165e3b55780SDimitry Andric   Stack.push_back(std::pair(BB, Saved));
1664a16efa3SDimitry Andric }
1674a16efa3SDimitry Andric 
168eb11fae6SDimitry Andric /// Can the condition represented by this PHI node treated like
1694a16efa3SDimitry Andric /// an "Else" block?
isElse(PHINode * Phi)1704a16efa3SDimitry Andric bool SIAnnotateControlFlow::isElse(PHINode *Phi) {
1714a16efa3SDimitry Andric   BasicBlock *IDom = DT->getNode(Phi->getParent())->getIDom()->getBlock();
1724a16efa3SDimitry Andric   for (unsigned i = 0, e = Phi->getNumIncomingValues(); i != e; ++i) {
1734a16efa3SDimitry Andric     if (Phi->getIncomingBlock(i) == IDom) {
1744a16efa3SDimitry Andric 
1754a16efa3SDimitry Andric       if (Phi->getIncomingValue(i) != BoolTrue)
1764a16efa3SDimitry Andric         return false;
1774a16efa3SDimitry Andric 
1784a16efa3SDimitry Andric     } else {
1794a16efa3SDimitry Andric       if (Phi->getIncomingValue(i) != BoolFalse)
1804a16efa3SDimitry Andric         return false;
1814a16efa3SDimitry Andric 
1824a16efa3SDimitry Andric     }
1834a16efa3SDimitry Andric   }
1844a16efa3SDimitry Andric   return true;
1854a16efa3SDimitry Andric }
1864a16efa3SDimitry Andric 
hasKill(const BasicBlock * BB)187344a3780SDimitry Andric bool SIAnnotateControlFlow::hasKill(const BasicBlock *BB) {
188344a3780SDimitry Andric   for (const Instruction &I : *BB) {
189344a3780SDimitry Andric     if (const CallInst *CI = dyn_cast<CallInst>(&I))
190344a3780SDimitry Andric       if (CI->getIntrinsicID() == Intrinsic::amdgcn_kill)
191344a3780SDimitry Andric         return true;
192344a3780SDimitry Andric   }
193344a3780SDimitry Andric   return false;
194344a3780SDimitry Andric }
195344a3780SDimitry Andric 
196145449b1SDimitry Andric // Erase "Phi" if it is not used any more. Return true if any change was made.
eraseIfUnused(PHINode * Phi)197145449b1SDimitry Andric bool SIAnnotateControlFlow::eraseIfUnused(PHINode *Phi) {
198145449b1SDimitry Andric   bool Changed = RecursivelyDeleteDeadPHINode(Phi);
199145449b1SDimitry Andric   if (Changed)
200eb11fae6SDimitry Andric     LLVM_DEBUG(dbgs() << "Erased unused condition phi\n");
201145449b1SDimitry Andric   return Changed;
2024a16efa3SDimitry Andric }
2034a16efa3SDimitry Andric 
204eb11fae6SDimitry Andric /// Open a new "If" block
openIf(BranchInst * Term)205145449b1SDimitry Andric bool SIAnnotateControlFlow::openIf(BranchInst *Term) {
20671d5a254SDimitry Andric   if (isUniform(Term))
207145449b1SDimitry Andric     return false;
20871d5a254SDimitry Andric 
209b1c73532SDimitry Andric   IRBuilder<> IRB(Term);
210b1c73532SDimitry Andric   Value *IfCall = IRB.CreateCall(If, {Term->getCondition()});
211b1c73532SDimitry Andric   Value *Cond = IRB.CreateExtractValue(IfCall, {0});
212b1c73532SDimitry Andric   Value *Mask = IRB.CreateExtractValue(IfCall, {1});
213b1c73532SDimitry Andric   Term->setCondition(Cond);
214b1c73532SDimitry Andric   push(Term->getSuccessor(1), Mask);
215145449b1SDimitry Andric   return true;
2164a16efa3SDimitry Andric }
2174a16efa3SDimitry Andric 
218eb11fae6SDimitry Andric /// Close the last "If" block and open a new "Else" block
insertElse(BranchInst * Term)219145449b1SDimitry Andric bool SIAnnotateControlFlow::insertElse(BranchInst *Term) {
22001095a5dSDimitry Andric   if (isUniform(Term)) {
221145449b1SDimitry Andric     return false;
22201095a5dSDimitry Andric   }
223b1c73532SDimitry Andric 
224b1c73532SDimitry Andric   IRBuilder<> IRB(Term);
225b1c73532SDimitry Andric   Value *ElseCall = IRB.CreateCall(Else, {popSaved()});
226b1c73532SDimitry Andric   Value *Cond = IRB.CreateExtractValue(ElseCall, {0});
227b1c73532SDimitry Andric   Value *Mask = IRB.CreateExtractValue(ElseCall, {1});
228b1c73532SDimitry Andric   Term->setCondition(Cond);
229b1c73532SDimitry Andric   push(Term->getSuccessor(1), Mask);
230145449b1SDimitry Andric   return true;
2314a16efa3SDimitry Andric }
2324a16efa3SDimitry Andric 
233eb11fae6SDimitry Andric /// Recursively handle the condition leading to a loop
handleLoopCondition(Value * Cond,PHINode * Broken,llvm::Loop * L,BranchInst * Term)23471d5a254SDimitry Andric Value *SIAnnotateControlFlow::handleLoopCondition(
235d8e91e46SDimitry Andric     Value *Cond, PHINode *Broken, llvm::Loop *L, BranchInst *Term) {
236b1c73532SDimitry Andric 
237b1c73532SDimitry Andric   auto CreateBreak = [this, Cond, Broken](Instruction *I) -> CallInst * {
238b1c73532SDimitry Andric     return IRBuilder<>(I).CreateCall(IfBreak, {Cond, Broken});
239b1c73532SDimitry Andric   };
240b1c73532SDimitry Andric 
24171d5a254SDimitry Andric   if (Instruction *Inst = dyn_cast<Instruction>(Cond)) {
2424a16efa3SDimitry Andric     BasicBlock *Parent = Inst->getParent();
243f03b5bedSDimitry Andric     Instruction *Insert;
244f03b5bedSDimitry Andric     if (L->contains(Inst)) {
245f03b5bedSDimitry Andric       Insert = Parent->getTerminator();
246f03b5bedSDimitry Andric     } else {
247f03b5bedSDimitry Andric       Insert = L->getHeader()->getFirstNonPHIOrDbgOrLifetime();
248f03b5bedSDimitry Andric     }
24971d5a254SDimitry Andric 
250b1c73532SDimitry Andric     return CreateBreak(Insert);
2514a16efa3SDimitry Andric   }
25271d5a254SDimitry Andric 
25371d5a254SDimitry Andric   // Insert IfBreak in the loop header TERM for constant COND other than true.
25471d5a254SDimitry Andric   if (isa<Constant>(Cond)) {
25571d5a254SDimitry Andric     Instruction *Insert = Cond == BoolTrue ?
25671d5a254SDimitry Andric       Term : L->getHeader()->getTerminator();
25771d5a254SDimitry Andric 
258b1c73532SDimitry Andric     return CreateBreak(Insert);
25971d5a254SDimitry Andric   }
26071d5a254SDimitry Andric 
2616f8fc217SDimitry Andric   if (isa<Argument>(Cond)) {
2626f8fc217SDimitry Andric     Instruction *Insert = L->getHeader()->getFirstNonPHIOrDbgOrLifetime();
263b1c73532SDimitry Andric     return CreateBreak(Insert);
2646f8fc217SDimitry Andric   }
2656f8fc217SDimitry Andric 
26671d5a254SDimitry Andric   llvm_unreachable("Unhandled loop condition!");
2674a16efa3SDimitry Andric }
2684a16efa3SDimitry Andric 
269eb11fae6SDimitry Andric /// Handle a back edge (loop)
handleLoop(BranchInst * Term)270145449b1SDimitry Andric bool SIAnnotateControlFlow::handleLoop(BranchInst *Term) {
27171d5a254SDimitry Andric   if (isUniform(Term))
272145449b1SDimitry Andric     return false;
27301095a5dSDimitry Andric 
274f03b5bedSDimitry Andric   BasicBlock *BB = Term->getParent();
275f03b5bedSDimitry Andric   llvm::Loop *L = LI->getLoopFor(BB);
276b915e9e0SDimitry Andric   if (!L)
277145449b1SDimitry Andric     return false;
2784a16efa3SDimitry Andric 
27971d5a254SDimitry Andric   BasicBlock *Target = Term->getSuccessor(1);
280b1c73532SDimitry Andric   PHINode *Broken = PHINode::Create(IntMask, 0, "phi.broken");
281b1c73532SDimitry Andric   Broken->insertBefore(Target->begin());
28271d5a254SDimitry Andric 
2834a16efa3SDimitry Andric   Value *Cond = Term->getCondition();
2844a16efa3SDimitry Andric   Term->setCondition(BoolTrue);
285d8e91e46SDimitry Andric   Value *Arg = handleLoopCondition(Cond, Broken, L, Term);
2864a16efa3SDimitry Andric 
287e6d15924SDimitry Andric   for (BasicBlock *Pred : predecessors(Target)) {
288e6d15924SDimitry Andric     Value *PHIValue = IntMaskZero;
289e6d15924SDimitry Andric     if (Pred == BB) // Remember the value of the previous iteration.
290e6d15924SDimitry Andric       PHIValue = Arg;
291e6d15924SDimitry Andric     // If the backedge from Pred to Target could be executed before the exit
292e6d15924SDimitry Andric     // of the loop at BB, it should not reset or change "Broken", which keeps
293e6d15924SDimitry Andric     // track of the number of threads exited the loop at BB.
294e6d15924SDimitry Andric     else if (L->contains(Pred) && DT->dominates(Pred, BB))
295e6d15924SDimitry Andric       PHIValue = Broken;
296e6d15924SDimitry Andric     Broken->addIncoming(PHIValue, Pred);
297e6d15924SDimitry Andric   }
2984a16efa3SDimitry Andric 
299b1c73532SDimitry Andric   CallInst *LoopCall = IRBuilder<>(Term).CreateCall(Loop, {Arg});
300b1c73532SDimitry Andric   Term->setCondition(LoopCall);
30171d5a254SDimitry Andric 
3024a16efa3SDimitry Andric   push(Term->getSuccessor(0), Arg);
303145449b1SDimitry Andric 
304145449b1SDimitry Andric   return true;
30571d5a254SDimitry Andric }
30671d5a254SDimitry Andric 
307eb11fae6SDimitry Andric /// Close the last opened control flow
closeControlFlow(BasicBlock * BB)308145449b1SDimitry Andric bool SIAnnotateControlFlow::closeControlFlow(BasicBlock *BB) {
309608e6659SDimitry Andric   llvm::Loop *L = LI->getLoopFor(BB);
310608e6659SDimitry Andric 
31101095a5dSDimitry Andric   assert(Stack.back().first == BB);
31201095a5dSDimitry Andric 
313608e6659SDimitry Andric   if (L && L->getHeader() == BB) {
314608e6659SDimitry Andric     // We can't insert an EndCF call into a loop header, because it will
315608e6659SDimitry Andric     // get executed on every iteration of the loop, when it should be
316608e6659SDimitry Andric     // executed only once before the loop.
317608e6659SDimitry Andric     SmallVector <BasicBlock *, 8> Latches;
318608e6659SDimitry Andric     L->getLoopLatches(Latches);
319608e6659SDimitry Andric 
32071d5a254SDimitry Andric     SmallVector<BasicBlock *, 2> Preds;
32171d5a254SDimitry Andric     for (BasicBlock *Pred : predecessors(BB)) {
32271d5a254SDimitry Andric       if (!is_contained(Latches, Pred))
32371d5a254SDimitry Andric         Preds.push_back(Pred);
324608e6659SDimitry Andric     }
32571d5a254SDimitry Andric 
326d8e91e46SDimitry Andric     BB = SplitBlockPredecessors(BB, Preds, "endcf.split", DT, LI, nullptr,
327d8e91e46SDimitry Andric                                 false);
3284a16efa3SDimitry Andric   }
3294a16efa3SDimitry Andric 
33001095a5dSDimitry Andric   Value *Exec = popSaved();
3314df029ccSDimitry Andric   BasicBlock::iterator FirstInsertionPt = BB->getFirstInsertionPt();
332b60736ecSDimitry Andric   if (!isa<UndefValue>(Exec) && !isa<UnreachableInst>(FirstInsertionPt)) {
333b60736ecSDimitry Andric     Instruction *ExecDef = cast<Instruction>(Exec);
334b60736ecSDimitry Andric     BasicBlock *DefBB = ExecDef->getParent();
335b60736ecSDimitry Andric     if (!DT->dominates(DefBB, BB)) {
336b60736ecSDimitry Andric       // Split edge to make Def dominate Use
3374df029ccSDimitry Andric       FirstInsertionPt = SplitEdge(DefBB, BB, DT, LI)->getFirstInsertionPt();
338b60736ecSDimitry Andric     }
339ac9a064cSDimitry Andric     IRBuilder<> IRB(FirstInsertionPt->getParent(), FirstInsertionPt);
340ac9a064cSDimitry Andric     // TODO: StructurizeCFG 'Flow' blocks have debug locations from the
341ac9a064cSDimitry Andric     // condition, for now just avoid copying these DebugLocs so that stepping
342ac9a064cSDimitry Andric     // out of the then/else block in a debugger doesn't step to the condition.
343ac9a064cSDimitry Andric     IRB.SetCurrentDebugLocation(DebugLoc());
344ac9a064cSDimitry Andric     IRB.CreateCall(EndCf, {Exec});
3454a16efa3SDimitry Andric   }
346145449b1SDimitry Andric 
347145449b1SDimitry Andric   return true;
348b60736ecSDimitry Andric }
3494a16efa3SDimitry Andric 
350eb11fae6SDimitry Andric /// Annotate the control flow with intrinsics so the backend can
3514a16efa3SDimitry Andric /// recognize if/then/else and loops.
runOnFunction(Function & F)3524a16efa3SDimitry Andric bool SIAnnotateControlFlow::runOnFunction(Function &F) {
3535ca98fd9SDimitry Andric   DT = &getAnalysis<DominatorTreeWrapperPass>().getDomTree();
3545a5ac124SDimitry Andric   LI = &getAnalysis<LoopInfoWrapperPass>().getLoopInfo();
3557fa27ce4SDimitry Andric   UA = &getAnalysis<UniformityInfoWrapperPass>().getUniformityInfo();
356e6d15924SDimitry Andric   TargetPassConfig &TPC = getAnalysis<TargetPassConfig>();
357e6d15924SDimitry Andric   const TargetMachine &TM = TPC.getTM<TargetMachine>();
358e6d15924SDimitry Andric 
359145449b1SDimitry Andric   bool Changed = false;
360e6d15924SDimitry Andric   initialize(*F.getParent(), TM.getSubtarget<GCNSubtarget>(F));
3614a16efa3SDimitry Andric   for (df_iterator<BasicBlock *> I = df_begin(&F.getEntryBlock()),
3624a16efa3SDimitry Andric        E = df_end(&F.getEntryBlock()); I != E; ++I) {
36371d5a254SDimitry Andric     BasicBlock *BB = *I;
36471d5a254SDimitry Andric     BranchInst *Term = dyn_cast<BranchInst>(BB->getTerminator());
3654a16efa3SDimitry Andric 
3664a16efa3SDimitry Andric     if (!Term || Term->isUnconditional()) {
36771d5a254SDimitry Andric       if (isTopOfStack(BB))
368145449b1SDimitry Andric         Changed |= closeControlFlow(BB);
36901095a5dSDimitry Andric 
3704a16efa3SDimitry Andric       continue;
3714a16efa3SDimitry Andric     }
3724a16efa3SDimitry Andric 
3734a16efa3SDimitry Andric     if (I.nodeVisited(Term->getSuccessor(1))) {
37471d5a254SDimitry Andric       if (isTopOfStack(BB))
375145449b1SDimitry Andric         Changed |= closeControlFlow(BB);
37601095a5dSDimitry Andric 
377b60736ecSDimitry Andric       if (DT->dominates(Term->getSuccessor(1), BB))
378145449b1SDimitry Andric         Changed |= handleLoop(Term);
3794a16efa3SDimitry Andric       continue;
3804a16efa3SDimitry Andric     }
3814a16efa3SDimitry Andric 
38271d5a254SDimitry Andric     if (isTopOfStack(BB)) {
3834a16efa3SDimitry Andric       PHINode *Phi = dyn_cast<PHINode>(Term->getCondition());
384344a3780SDimitry Andric       if (Phi && Phi->getParent() == BB && isElse(Phi) && !hasKill(BB)) {
385145449b1SDimitry Andric         Changed |= insertElse(Term);
386145449b1SDimitry Andric         Changed |= eraseIfUnused(Phi);
3874a16efa3SDimitry Andric         continue;
3884a16efa3SDimitry Andric       }
38971d5a254SDimitry Andric 
390145449b1SDimitry Andric       Changed |= closeControlFlow(BB);
3914a16efa3SDimitry Andric     }
39271d5a254SDimitry Andric 
393145449b1SDimitry Andric     Changed |= openIf(Term);
3944a16efa3SDimitry Andric   }
3954a16efa3SDimitry Andric 
396eb11fae6SDimitry Andric   if (!Stack.empty()) {
397eb11fae6SDimitry Andric     // CFG was probably not structured.
398eb11fae6SDimitry Andric     report_fatal_error("failed to annotate CFG");
399eb11fae6SDimitry Andric   }
400eb11fae6SDimitry Andric 
401145449b1SDimitry Andric   return Changed;
4024a16efa3SDimitry Andric }
4034a16efa3SDimitry Andric 
404eb11fae6SDimitry Andric /// Create the annotation pass
createSIAnnotateControlFlowPass()4054a16efa3SDimitry Andric FunctionPass *llvm::createSIAnnotateControlFlowPass() {
4064a16efa3SDimitry Andric   return new SIAnnotateControlFlow();
4074a16efa3SDimitry Andric }
408