10b57cec5SDimitry Andric //===- SIAnnotateControlFlow.cpp ------------------------------------------===// 20b57cec5SDimitry Andric // 30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60b57cec5SDimitry Andric // 70b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 80b57cec5SDimitry Andric // 90b57cec5SDimitry Andric /// \file 100b57cec5SDimitry Andric /// Annotates the control flow with hardware specific intrinsics. 110b57cec5SDimitry Andric // 120b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 130b57cec5SDimitry Andric 140b57cec5SDimitry Andric #include "AMDGPU.h" 15e8d8bef9SDimitry Andric #include "GCNSubtarget.h" 160b57cec5SDimitry Andric #include "llvm/Analysis/LegacyDivergenceAnalysis.h" 170b57cec5SDimitry Andric #include "llvm/Analysis/LoopInfo.h" 180b57cec5SDimitry Andric #include "llvm/CodeGen/TargetPassConfig.h" 190b57cec5SDimitry Andric #include "llvm/IR/BasicBlock.h" 200b57cec5SDimitry Andric #include "llvm/IR/Constants.h" 210b57cec5SDimitry Andric #include "llvm/IR/Dominators.h" 22e8d8bef9SDimitry Andric #include "llvm/IR/IntrinsicsAMDGPU.h" 23480093f4SDimitry Andric #include "llvm/InitializePasses.h" 24e8d8bef9SDimitry Andric #include "llvm/Target/TargetMachine.h" 250b57cec5SDimitry Andric #include "llvm/Transforms/Utils/BasicBlockUtils.h" 260b57cec5SDimitry Andric #include "llvm/Transforms/Utils/Local.h" 270b57cec5SDimitry Andric 280b57cec5SDimitry Andric using namespace llvm; 290b57cec5SDimitry Andric 300b57cec5SDimitry Andric #define DEBUG_TYPE "si-annotate-control-flow" 310b57cec5SDimitry Andric 320b57cec5SDimitry Andric namespace { 330b57cec5SDimitry Andric 340b57cec5SDimitry Andric // Complex types used in this pass 350b57cec5SDimitry Andric using StackEntry = std::pair<BasicBlock *, Value *>; 360b57cec5SDimitry Andric using StackVector = SmallVector<StackEntry, 16>; 370b57cec5SDimitry Andric 380b57cec5SDimitry Andric class SIAnnotateControlFlow : public FunctionPass { 390b57cec5SDimitry Andric LegacyDivergenceAnalysis *DA; 400b57cec5SDimitry Andric 410b57cec5SDimitry Andric Type *Boolean; 420b57cec5SDimitry Andric Type *Void; 430b57cec5SDimitry Andric Type *IntMask; 440b57cec5SDimitry Andric Type *ReturnStruct; 450b57cec5SDimitry Andric 460b57cec5SDimitry Andric ConstantInt *BoolTrue; 470b57cec5SDimitry Andric ConstantInt *BoolFalse; 480b57cec5SDimitry Andric UndefValue *BoolUndef; 490b57cec5SDimitry Andric Constant *IntMaskZero; 500b57cec5SDimitry Andric 510b57cec5SDimitry Andric Function *If; 520b57cec5SDimitry Andric Function *Else; 530b57cec5SDimitry Andric Function *IfBreak; 540b57cec5SDimitry Andric Function *Loop; 550b57cec5SDimitry Andric Function *EndCf; 560b57cec5SDimitry Andric 570b57cec5SDimitry Andric DominatorTree *DT; 580b57cec5SDimitry Andric StackVector Stack; 590b57cec5SDimitry Andric 600b57cec5SDimitry Andric LoopInfo *LI; 610b57cec5SDimitry Andric 620b57cec5SDimitry Andric void initialize(Module &M, const GCNSubtarget &ST); 630b57cec5SDimitry Andric 640b57cec5SDimitry Andric bool isUniform(BranchInst *T); 650b57cec5SDimitry Andric 660b57cec5SDimitry Andric bool isTopOfStack(BasicBlock *BB); 670b57cec5SDimitry Andric 680b57cec5SDimitry Andric Value *popSaved(); 690b57cec5SDimitry Andric 700b57cec5SDimitry Andric void push(BasicBlock *BB, Value *Saved); 710b57cec5SDimitry Andric 720b57cec5SDimitry Andric bool isElse(PHINode *Phi); 730b57cec5SDimitry Andric 74fe6060f1SDimitry Andric bool hasKill(const BasicBlock *BB); 75fe6060f1SDimitry Andric 760b57cec5SDimitry Andric void eraseIfUnused(PHINode *Phi); 770b57cec5SDimitry Andric 780b57cec5SDimitry Andric void openIf(BranchInst *Term); 790b57cec5SDimitry Andric 800b57cec5SDimitry Andric void insertElse(BranchInst *Term); 810b57cec5SDimitry Andric 820b57cec5SDimitry Andric Value * 830b57cec5SDimitry Andric handleLoopCondition(Value *Cond, PHINode *Broken, llvm::Loop *L, 840b57cec5SDimitry Andric BranchInst *Term); 850b57cec5SDimitry Andric 860b57cec5SDimitry Andric void handleLoop(BranchInst *Term); 870b57cec5SDimitry Andric 880b57cec5SDimitry Andric void closeControlFlow(BasicBlock *BB); 890b57cec5SDimitry Andric 900b57cec5SDimitry Andric public: 910b57cec5SDimitry Andric static char ID; 920b57cec5SDimitry Andric 930b57cec5SDimitry Andric SIAnnotateControlFlow() : FunctionPass(ID) {} 940b57cec5SDimitry Andric 950b57cec5SDimitry Andric bool runOnFunction(Function &F) override; 960b57cec5SDimitry Andric 970b57cec5SDimitry Andric StringRef getPassName() const override { return "SI annotate control flow"; } 980b57cec5SDimitry Andric 990b57cec5SDimitry Andric void getAnalysisUsage(AnalysisUsage &AU) const override { 1000b57cec5SDimitry Andric AU.addRequired<LoopInfoWrapperPass>(); 1010b57cec5SDimitry Andric AU.addRequired<DominatorTreeWrapperPass>(); 1020b57cec5SDimitry Andric AU.addRequired<LegacyDivergenceAnalysis>(); 103fe6060f1SDimitry Andric AU.addPreserved<LoopInfoWrapperPass>(); 1040b57cec5SDimitry Andric AU.addPreserved<DominatorTreeWrapperPass>(); 1050b57cec5SDimitry Andric AU.addRequired<TargetPassConfig>(); 1060b57cec5SDimitry Andric FunctionPass::getAnalysisUsage(AU); 1070b57cec5SDimitry Andric } 1080b57cec5SDimitry Andric }; 1090b57cec5SDimitry Andric 1100b57cec5SDimitry Andric } // end anonymous namespace 1110b57cec5SDimitry Andric 1120b57cec5SDimitry Andric INITIALIZE_PASS_BEGIN(SIAnnotateControlFlow, DEBUG_TYPE, 1130b57cec5SDimitry Andric "Annotate SI Control Flow", false, false) 1140b57cec5SDimitry Andric INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass) 1150b57cec5SDimitry Andric INITIALIZE_PASS_DEPENDENCY(LegacyDivergenceAnalysis) 1160b57cec5SDimitry Andric INITIALIZE_PASS_DEPENDENCY(TargetPassConfig) 1170b57cec5SDimitry Andric INITIALIZE_PASS_END(SIAnnotateControlFlow, DEBUG_TYPE, 1180b57cec5SDimitry Andric "Annotate SI Control Flow", false, false) 1190b57cec5SDimitry Andric 1200b57cec5SDimitry Andric char SIAnnotateControlFlow::ID = 0; 1210b57cec5SDimitry Andric 1220b57cec5SDimitry Andric /// Initialize all the types and constants used in the pass 1230b57cec5SDimitry Andric void SIAnnotateControlFlow::initialize(Module &M, const GCNSubtarget &ST) { 1240b57cec5SDimitry Andric LLVMContext &Context = M.getContext(); 1250b57cec5SDimitry Andric 1260b57cec5SDimitry Andric Void = Type::getVoidTy(Context); 1270b57cec5SDimitry Andric Boolean = Type::getInt1Ty(Context); 1280b57cec5SDimitry Andric IntMask = ST.isWave32() ? Type::getInt32Ty(Context) 1290b57cec5SDimitry Andric : Type::getInt64Ty(Context); 1300b57cec5SDimitry Andric ReturnStruct = StructType::get(Boolean, IntMask); 1310b57cec5SDimitry Andric 1320b57cec5SDimitry Andric BoolTrue = ConstantInt::getTrue(Context); 1330b57cec5SDimitry Andric BoolFalse = ConstantInt::getFalse(Context); 1340b57cec5SDimitry Andric BoolUndef = UndefValue::get(Boolean); 1350b57cec5SDimitry Andric IntMaskZero = ConstantInt::get(IntMask, 0); 1360b57cec5SDimitry Andric 1370b57cec5SDimitry Andric If = Intrinsic::getDeclaration(&M, Intrinsic::amdgcn_if, { IntMask }); 1380b57cec5SDimitry Andric Else = Intrinsic::getDeclaration(&M, Intrinsic::amdgcn_else, 1390b57cec5SDimitry Andric { IntMask, IntMask }); 1400b57cec5SDimitry Andric IfBreak = Intrinsic::getDeclaration(&M, Intrinsic::amdgcn_if_break, 1415ffd83dbSDimitry Andric { IntMask }); 1420b57cec5SDimitry Andric Loop = Intrinsic::getDeclaration(&M, Intrinsic::amdgcn_loop, { IntMask }); 1430b57cec5SDimitry Andric EndCf = Intrinsic::getDeclaration(&M, Intrinsic::amdgcn_end_cf, { IntMask }); 1440b57cec5SDimitry Andric } 1450b57cec5SDimitry Andric 1460b57cec5SDimitry Andric /// Is the branch condition uniform or did the StructurizeCFG pass 1470b57cec5SDimitry Andric /// consider it as such? 1480b57cec5SDimitry Andric bool SIAnnotateControlFlow::isUniform(BranchInst *T) { 1490b57cec5SDimitry Andric return DA->isUniform(T) || 1500b57cec5SDimitry Andric T->getMetadata("structurizecfg.uniform") != nullptr; 1510b57cec5SDimitry Andric } 1520b57cec5SDimitry Andric 1530b57cec5SDimitry Andric /// Is BB the last block saved on the stack ? 1540b57cec5SDimitry Andric bool SIAnnotateControlFlow::isTopOfStack(BasicBlock *BB) { 1550b57cec5SDimitry Andric return !Stack.empty() && Stack.back().first == BB; 1560b57cec5SDimitry Andric } 1570b57cec5SDimitry Andric 1580b57cec5SDimitry Andric /// Pop the last saved value from the control flow stack 1590b57cec5SDimitry Andric Value *SIAnnotateControlFlow::popSaved() { 1600b57cec5SDimitry Andric return Stack.pop_back_val().second; 1610b57cec5SDimitry Andric } 1620b57cec5SDimitry Andric 1630b57cec5SDimitry Andric /// Push a BB and saved value to the control flow stack 1640b57cec5SDimitry Andric void SIAnnotateControlFlow::push(BasicBlock *BB, Value *Saved) { 1650b57cec5SDimitry Andric Stack.push_back(std::make_pair(BB, Saved)); 1660b57cec5SDimitry Andric } 1670b57cec5SDimitry Andric 1680b57cec5SDimitry Andric /// Can the condition represented by this PHI node treated like 1690b57cec5SDimitry Andric /// an "Else" block? 1700b57cec5SDimitry Andric bool SIAnnotateControlFlow::isElse(PHINode *Phi) { 1710b57cec5SDimitry Andric BasicBlock *IDom = DT->getNode(Phi->getParent())->getIDom()->getBlock(); 1720b57cec5SDimitry Andric for (unsigned i = 0, e = Phi->getNumIncomingValues(); i != e; ++i) { 1730b57cec5SDimitry Andric if (Phi->getIncomingBlock(i) == IDom) { 1740b57cec5SDimitry Andric 1750b57cec5SDimitry Andric if (Phi->getIncomingValue(i) != BoolTrue) 1760b57cec5SDimitry Andric return false; 1770b57cec5SDimitry Andric 1780b57cec5SDimitry Andric } else { 1790b57cec5SDimitry Andric if (Phi->getIncomingValue(i) != BoolFalse) 1800b57cec5SDimitry Andric return false; 1810b57cec5SDimitry Andric 1820b57cec5SDimitry Andric } 1830b57cec5SDimitry Andric } 1840b57cec5SDimitry Andric return true; 1850b57cec5SDimitry Andric } 1860b57cec5SDimitry Andric 187fe6060f1SDimitry Andric bool SIAnnotateControlFlow::hasKill(const BasicBlock *BB) { 188fe6060f1SDimitry Andric for (const Instruction &I : *BB) { 189fe6060f1SDimitry Andric if (const CallInst *CI = dyn_cast<CallInst>(&I)) 190fe6060f1SDimitry Andric if (CI->getIntrinsicID() == Intrinsic::amdgcn_kill) 191fe6060f1SDimitry Andric return true; 192fe6060f1SDimitry Andric } 193fe6060f1SDimitry Andric return false; 194fe6060f1SDimitry Andric } 195fe6060f1SDimitry Andric 1960b57cec5SDimitry Andric // Erase "Phi" if it is not used any more 1970b57cec5SDimitry Andric void SIAnnotateControlFlow::eraseIfUnused(PHINode *Phi) { 1980b57cec5SDimitry Andric if (RecursivelyDeleteDeadPHINode(Phi)) { 1990b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << "Erased unused condition phi\n"); 2000b57cec5SDimitry Andric } 2010b57cec5SDimitry Andric } 2020b57cec5SDimitry Andric 2030b57cec5SDimitry Andric /// Open a new "If" block 2040b57cec5SDimitry Andric void SIAnnotateControlFlow::openIf(BranchInst *Term) { 2050b57cec5SDimitry Andric if (isUniform(Term)) 2060b57cec5SDimitry Andric return; 2070b57cec5SDimitry Andric 2080b57cec5SDimitry Andric Value *Ret = CallInst::Create(If, Term->getCondition(), "", Term); 2090b57cec5SDimitry Andric Term->setCondition(ExtractValueInst::Create(Ret, 0, "", Term)); 2100b57cec5SDimitry Andric push(Term->getSuccessor(1), ExtractValueInst::Create(Ret, 1, "", Term)); 2110b57cec5SDimitry Andric } 2120b57cec5SDimitry Andric 2130b57cec5SDimitry Andric /// Close the last "If" block and open a new "Else" block 2140b57cec5SDimitry Andric void SIAnnotateControlFlow::insertElse(BranchInst *Term) { 2150b57cec5SDimitry Andric if (isUniform(Term)) { 2160b57cec5SDimitry Andric return; 2170b57cec5SDimitry Andric } 2180b57cec5SDimitry Andric Value *Ret = CallInst::Create(Else, popSaved(), "", Term); 2190b57cec5SDimitry Andric Term->setCondition(ExtractValueInst::Create(Ret, 0, "", Term)); 2200b57cec5SDimitry Andric push(Term->getSuccessor(1), ExtractValueInst::Create(Ret, 1, "", Term)); 2210b57cec5SDimitry Andric } 2220b57cec5SDimitry Andric 2230b57cec5SDimitry Andric /// Recursively handle the condition leading to a loop 2240b57cec5SDimitry Andric Value *SIAnnotateControlFlow::handleLoopCondition( 2250b57cec5SDimitry Andric Value *Cond, PHINode *Broken, llvm::Loop *L, BranchInst *Term) { 2260b57cec5SDimitry Andric if (Instruction *Inst = dyn_cast<Instruction>(Cond)) { 2270b57cec5SDimitry Andric BasicBlock *Parent = Inst->getParent(); 2280b57cec5SDimitry Andric Instruction *Insert; 2290b57cec5SDimitry Andric if (L->contains(Inst)) { 2300b57cec5SDimitry Andric Insert = Parent->getTerminator(); 2310b57cec5SDimitry Andric } else { 2320b57cec5SDimitry Andric Insert = L->getHeader()->getFirstNonPHIOrDbgOrLifetime(); 2330b57cec5SDimitry Andric } 2340b57cec5SDimitry Andric 2350b57cec5SDimitry Andric Value *Args[] = { Cond, Broken }; 2360b57cec5SDimitry Andric return CallInst::Create(IfBreak, Args, "", Insert); 2370b57cec5SDimitry Andric } 2380b57cec5SDimitry Andric 2390b57cec5SDimitry Andric // Insert IfBreak in the loop header TERM for constant COND other than true. 2400b57cec5SDimitry Andric if (isa<Constant>(Cond)) { 2410b57cec5SDimitry Andric Instruction *Insert = Cond == BoolTrue ? 2420b57cec5SDimitry Andric Term : L->getHeader()->getTerminator(); 2430b57cec5SDimitry Andric 2440b57cec5SDimitry Andric Value *Args[] = { Cond, Broken }; 2450b57cec5SDimitry Andric return CallInst::Create(IfBreak, Args, "", Insert); 2460b57cec5SDimitry Andric } 2470b57cec5SDimitry Andric 248*04eeddc0SDimitry Andric if (isa<Argument>(Cond)) { 249*04eeddc0SDimitry Andric Instruction *Insert = L->getHeader()->getFirstNonPHIOrDbgOrLifetime(); 250*04eeddc0SDimitry Andric Value *Args[] = { Cond, Broken }; 251*04eeddc0SDimitry Andric return CallInst::Create(IfBreak, Args, "", Insert); 252*04eeddc0SDimitry Andric } 253*04eeddc0SDimitry Andric 2540b57cec5SDimitry Andric llvm_unreachable("Unhandled loop condition!"); 2550b57cec5SDimitry Andric } 2560b57cec5SDimitry Andric 2570b57cec5SDimitry Andric /// Handle a back edge (loop) 2580b57cec5SDimitry Andric void SIAnnotateControlFlow::handleLoop(BranchInst *Term) { 2590b57cec5SDimitry Andric if (isUniform(Term)) 2600b57cec5SDimitry Andric return; 2610b57cec5SDimitry Andric 2620b57cec5SDimitry Andric BasicBlock *BB = Term->getParent(); 2630b57cec5SDimitry Andric llvm::Loop *L = LI->getLoopFor(BB); 2640b57cec5SDimitry Andric if (!L) 2650b57cec5SDimitry Andric return; 2660b57cec5SDimitry Andric 2670b57cec5SDimitry Andric BasicBlock *Target = Term->getSuccessor(1); 2680b57cec5SDimitry Andric PHINode *Broken = PHINode::Create(IntMask, 0, "phi.broken", &Target->front()); 2690b57cec5SDimitry Andric 2700b57cec5SDimitry Andric Value *Cond = Term->getCondition(); 2710b57cec5SDimitry Andric Term->setCondition(BoolTrue); 2720b57cec5SDimitry Andric Value *Arg = handleLoopCondition(Cond, Broken, L, Term); 2730b57cec5SDimitry Andric 2740b57cec5SDimitry Andric for (BasicBlock *Pred : predecessors(Target)) { 2750b57cec5SDimitry Andric Value *PHIValue = IntMaskZero; 2760b57cec5SDimitry Andric if (Pred == BB) // Remember the value of the previous iteration. 2770b57cec5SDimitry Andric PHIValue = Arg; 2780b57cec5SDimitry Andric // If the backedge from Pred to Target could be executed before the exit 2790b57cec5SDimitry Andric // of the loop at BB, it should not reset or change "Broken", which keeps 2800b57cec5SDimitry Andric // track of the number of threads exited the loop at BB. 2810b57cec5SDimitry Andric else if (L->contains(Pred) && DT->dominates(Pred, BB)) 2820b57cec5SDimitry Andric PHIValue = Broken; 2830b57cec5SDimitry Andric Broken->addIncoming(PHIValue, Pred); 2840b57cec5SDimitry Andric } 2850b57cec5SDimitry Andric 2860b57cec5SDimitry Andric Term->setCondition(CallInst::Create(Loop, Arg, "", Term)); 2870b57cec5SDimitry Andric 2880b57cec5SDimitry Andric push(Term->getSuccessor(0), Arg); 2890b57cec5SDimitry Andric } 2900b57cec5SDimitry Andric 2910b57cec5SDimitry Andric /// Close the last opened control flow 2920b57cec5SDimitry Andric void SIAnnotateControlFlow::closeControlFlow(BasicBlock *BB) { 2930b57cec5SDimitry Andric llvm::Loop *L = LI->getLoopFor(BB); 2940b57cec5SDimitry Andric 2950b57cec5SDimitry Andric assert(Stack.back().first == BB); 2960b57cec5SDimitry Andric 2970b57cec5SDimitry Andric if (L && L->getHeader() == BB) { 2980b57cec5SDimitry Andric // We can't insert an EndCF call into a loop header, because it will 2990b57cec5SDimitry Andric // get executed on every iteration of the loop, when it should be 3000b57cec5SDimitry Andric // executed only once before the loop. 3010b57cec5SDimitry Andric SmallVector <BasicBlock *, 8> Latches; 3020b57cec5SDimitry Andric L->getLoopLatches(Latches); 3030b57cec5SDimitry Andric 3040b57cec5SDimitry Andric SmallVector<BasicBlock *, 2> Preds; 3050b57cec5SDimitry Andric for (BasicBlock *Pred : predecessors(BB)) { 3060b57cec5SDimitry Andric if (!is_contained(Latches, Pred)) 3070b57cec5SDimitry Andric Preds.push_back(Pred); 3080b57cec5SDimitry Andric } 3090b57cec5SDimitry Andric 3100b57cec5SDimitry Andric BB = SplitBlockPredecessors(BB, Preds, "endcf.split", DT, LI, nullptr, 3110b57cec5SDimitry Andric false); 3120b57cec5SDimitry Andric } 3130b57cec5SDimitry Andric 3140b57cec5SDimitry Andric Value *Exec = popSaved(); 3150b57cec5SDimitry Andric Instruction *FirstInsertionPt = &*BB->getFirstInsertionPt(); 316e8d8bef9SDimitry Andric if (!isa<UndefValue>(Exec) && !isa<UnreachableInst>(FirstInsertionPt)) { 317e8d8bef9SDimitry Andric Instruction *ExecDef = cast<Instruction>(Exec); 318e8d8bef9SDimitry Andric BasicBlock *DefBB = ExecDef->getParent(); 319e8d8bef9SDimitry Andric if (!DT->dominates(DefBB, BB)) { 320e8d8bef9SDimitry Andric // Split edge to make Def dominate Use 321e8d8bef9SDimitry Andric FirstInsertionPt = &*SplitEdge(DefBB, BB, DT, LI)->getFirstInsertionPt(); 322e8d8bef9SDimitry Andric } 3230b57cec5SDimitry Andric CallInst::Create(EndCf, Exec, "", FirstInsertionPt); 3240b57cec5SDimitry Andric } 325e8d8bef9SDimitry Andric } 3260b57cec5SDimitry Andric 3270b57cec5SDimitry Andric /// Annotate the control flow with intrinsics so the backend can 3280b57cec5SDimitry Andric /// recognize if/then/else and loops. 3290b57cec5SDimitry Andric bool SIAnnotateControlFlow::runOnFunction(Function &F) { 3300b57cec5SDimitry Andric DT = &getAnalysis<DominatorTreeWrapperPass>().getDomTree(); 3310b57cec5SDimitry Andric LI = &getAnalysis<LoopInfoWrapperPass>().getLoopInfo(); 3320b57cec5SDimitry Andric DA = &getAnalysis<LegacyDivergenceAnalysis>(); 3330b57cec5SDimitry Andric TargetPassConfig &TPC = getAnalysis<TargetPassConfig>(); 3340b57cec5SDimitry Andric const TargetMachine &TM = TPC.getTM<TargetMachine>(); 3350b57cec5SDimitry Andric 3360b57cec5SDimitry Andric initialize(*F.getParent(), TM.getSubtarget<GCNSubtarget>(F)); 3370b57cec5SDimitry Andric for (df_iterator<BasicBlock *> I = df_begin(&F.getEntryBlock()), 3380b57cec5SDimitry Andric E = df_end(&F.getEntryBlock()); I != E; ++I) { 3390b57cec5SDimitry Andric BasicBlock *BB = *I; 3400b57cec5SDimitry Andric BranchInst *Term = dyn_cast<BranchInst>(BB->getTerminator()); 3410b57cec5SDimitry Andric 3420b57cec5SDimitry Andric if (!Term || Term->isUnconditional()) { 3430b57cec5SDimitry Andric if (isTopOfStack(BB)) 3440b57cec5SDimitry Andric closeControlFlow(BB); 3450b57cec5SDimitry Andric 3460b57cec5SDimitry Andric continue; 3470b57cec5SDimitry Andric } 3480b57cec5SDimitry Andric 3490b57cec5SDimitry Andric if (I.nodeVisited(Term->getSuccessor(1))) { 3500b57cec5SDimitry Andric if (isTopOfStack(BB)) 3510b57cec5SDimitry Andric closeControlFlow(BB); 3520b57cec5SDimitry Andric 353e8d8bef9SDimitry Andric if (DT->dominates(Term->getSuccessor(1), BB)) 3540b57cec5SDimitry Andric handleLoop(Term); 3550b57cec5SDimitry Andric continue; 3560b57cec5SDimitry Andric } 3570b57cec5SDimitry Andric 3580b57cec5SDimitry Andric if (isTopOfStack(BB)) { 3590b57cec5SDimitry Andric PHINode *Phi = dyn_cast<PHINode>(Term->getCondition()); 360fe6060f1SDimitry Andric if (Phi && Phi->getParent() == BB && isElse(Phi) && !hasKill(BB)) { 3610b57cec5SDimitry Andric insertElse(Term); 3620b57cec5SDimitry Andric eraseIfUnused(Phi); 3630b57cec5SDimitry Andric continue; 3640b57cec5SDimitry Andric } 3650b57cec5SDimitry Andric 3660b57cec5SDimitry Andric closeControlFlow(BB); 3670b57cec5SDimitry Andric } 3680b57cec5SDimitry Andric 3690b57cec5SDimitry Andric openIf(Term); 3700b57cec5SDimitry Andric } 3710b57cec5SDimitry Andric 3720b57cec5SDimitry Andric if (!Stack.empty()) { 3730b57cec5SDimitry Andric // CFG was probably not structured. 3740b57cec5SDimitry Andric report_fatal_error("failed to annotate CFG"); 3750b57cec5SDimitry Andric } 3760b57cec5SDimitry Andric 3770b57cec5SDimitry Andric return true; 3780b57cec5SDimitry Andric } 3790b57cec5SDimitry Andric 3800b57cec5SDimitry Andric /// Create the annotation pass 3810b57cec5SDimitry Andric FunctionPass *llvm::createSIAnnotateControlFlowPass() { 3820b57cec5SDimitry Andric return new SIAnnotateControlFlow(); 3830b57cec5SDimitry Andric } 384