12cab237bSDimitry Andric //===- SIAnnotateControlFlow.cpp ------------------------------------------===//
28f0fd8f6SDimitry Andric //
38f0fd8f6SDimitry Andric //                     The LLVM Compiler Infrastructure
48f0fd8f6SDimitry Andric //
58f0fd8f6SDimitry Andric // This file is distributed under the University of Illinois Open Source
68f0fd8f6SDimitry Andric // License. See LICENSE.TXT for details.
78f0fd8f6SDimitry Andric //
88f0fd8f6SDimitry Andric //===----------------------------------------------------------------------===//
98f0fd8f6SDimitry Andric //
108f0fd8f6SDimitry Andric /// \file
118f0fd8f6SDimitry Andric /// Annotates the control flow with hardware specific intrinsics.
128f0fd8f6SDimitry Andric //
138f0fd8f6SDimitry Andric //===----------------------------------------------------------------------===//
148f0fd8f6SDimitry Andric 
158f0fd8f6SDimitry Andric #include "AMDGPU.h"
168f0fd8f6SDimitry Andric #include "llvm/ADT/DepthFirstIterator.h"
172cab237bSDimitry Andric #include "llvm/ADT/STLExtras.h"
182cab237bSDimitry Andric #include "llvm/ADT/SmallVector.h"
19*b5893f02SDimitry Andric #include "llvm/Analysis/LegacyDivergenceAnalysis.h"
208f0fd8f6SDimitry Andric #include "llvm/Analysis/LoopInfo.h"
214ba319b5SDimitry Andric #include "llvm/Transforms/Utils/Local.h"
222cab237bSDimitry Andric #include "llvm/IR/BasicBlock.h"
232cab237bSDimitry Andric #include "llvm/IR/CFG.h"
242cab237bSDimitry Andric #include "llvm/IR/Constant.h"
258f0fd8f6SDimitry Andric #include "llvm/IR/Constants.h"
262cab237bSDimitry Andric #include "llvm/IR/DerivedTypes.h"
278f0fd8f6SDimitry Andric #include "llvm/IR/Dominators.h"
282cab237bSDimitry Andric #include "llvm/IR/Function.h"
292cab237bSDimitry Andric #include "llvm/IR/Instruction.h"
308f0fd8f6SDimitry Andric #include "llvm/IR/Instructions.h"
312cab237bSDimitry Andric #include "llvm/IR/Intrinsics.h"
328f0fd8f6SDimitry Andric #include "llvm/IR/Module.h"
332cab237bSDimitry Andric #include "llvm/IR/Type.h"
342cab237bSDimitry Andric #include "llvm/IR/ValueHandle.h"
358f0fd8f6SDimitry Andric #include "llvm/Pass.h"
362cab237bSDimitry Andric #include "llvm/Support/Casting.h"
372cab237bSDimitry Andric #include "llvm/Support/Debug.h"
382cab237bSDimitry Andric #include "llvm/Support/ErrorHandling.h"
392cab237bSDimitry Andric #include "llvm/Support/raw_ostream.h"
408f0fd8f6SDimitry Andric #include "llvm/Transforms/Utils/BasicBlockUtils.h"
412cab237bSDimitry Andric #include <cassert>
422cab237bSDimitry Andric #include <utility>
438f0fd8f6SDimitry Andric 
448f0fd8f6SDimitry Andric using namespace llvm;
458f0fd8f6SDimitry Andric 
468f0fd8f6SDimitry Andric #define DEBUG_TYPE "si-annotate-control-flow"
478f0fd8f6SDimitry Andric 
488f0fd8f6SDimitry Andric namespace {
498f0fd8f6SDimitry Andric 
508f0fd8f6SDimitry Andric // Complex types used in this pass
512cab237bSDimitry Andric using StackEntry = std::pair<BasicBlock *, Value *>;
522cab237bSDimitry Andric using StackVector = SmallVector<StackEntry, 16>;
538f0fd8f6SDimitry Andric 
548f0fd8f6SDimitry Andric class SIAnnotateControlFlow : public FunctionPass {
55*b5893f02SDimitry Andric   LegacyDivergenceAnalysis *DA;
568f0fd8f6SDimitry Andric 
578f0fd8f6SDimitry Andric   Type *Boolean;
588f0fd8f6SDimitry Andric   Type *Void;
598f0fd8f6SDimitry Andric   Type *Int64;
608f0fd8f6SDimitry Andric   Type *ReturnStruct;
618f0fd8f6SDimitry Andric 
628f0fd8f6SDimitry Andric   ConstantInt *BoolTrue;
638f0fd8f6SDimitry Andric   ConstantInt *BoolFalse;
648f0fd8f6SDimitry Andric   UndefValue *BoolUndef;
658f0fd8f6SDimitry Andric   Constant *Int64Zero;
668f0fd8f6SDimitry Andric 
677a7e6055SDimitry Andric   Function *If;
687a7e6055SDimitry Andric   Function *Else;
697a7e6055SDimitry Andric   Function *IfBreak;
707a7e6055SDimitry Andric   Function *Loop;
717a7e6055SDimitry Andric   Function *EndCf;
728f0fd8f6SDimitry Andric 
738f0fd8f6SDimitry Andric   DominatorTree *DT;
748f0fd8f6SDimitry Andric   StackVector Stack;
758f0fd8f6SDimitry Andric 
768f0fd8f6SDimitry Andric   LoopInfo *LI;
778f0fd8f6SDimitry Andric 
783ca95b02SDimitry Andric   bool isUniform(BranchInst *T);
793ca95b02SDimitry Andric 
808f0fd8f6SDimitry Andric   bool isTopOfStack(BasicBlock *BB);
818f0fd8f6SDimitry Andric 
828f0fd8f6SDimitry Andric   Value *popSaved();
838f0fd8f6SDimitry Andric 
848f0fd8f6SDimitry Andric   void push(BasicBlock *BB, Value *Saved);
858f0fd8f6SDimitry Andric 
868f0fd8f6SDimitry Andric   bool isElse(PHINode *Phi);
878f0fd8f6SDimitry Andric 
888f0fd8f6SDimitry Andric   void eraseIfUnused(PHINode *Phi);
898f0fd8f6SDimitry Andric 
908f0fd8f6SDimitry Andric   void openIf(BranchInst *Term);
918f0fd8f6SDimitry Andric 
928f0fd8f6SDimitry Andric   void insertElse(BranchInst *Term);
938f0fd8f6SDimitry Andric 
94f37b6182SDimitry Andric   Value *
95f37b6182SDimitry Andric   handleLoopCondition(Value *Cond, PHINode *Broken, llvm::Loop *L,
96*b5893f02SDimitry Andric                       BranchInst *Term);
978f0fd8f6SDimitry Andric 
988f0fd8f6SDimitry Andric   void handleLoop(BranchInst *Term);
998f0fd8f6SDimitry Andric 
1008f0fd8f6SDimitry Andric   void closeControlFlow(BasicBlock *BB);
1018f0fd8f6SDimitry Andric 
1028f0fd8f6SDimitry Andric public:
1033ca95b02SDimitry Andric   static char ID;
1043ca95b02SDimitry Andric 
SIAnnotateControlFlow()1052cab237bSDimitry Andric   SIAnnotateControlFlow() : FunctionPass(ID) {}
1068f0fd8f6SDimitry Andric 
1078f0fd8f6SDimitry Andric   bool doInitialization(Module &M) override;
1088f0fd8f6SDimitry Andric 
1098f0fd8f6SDimitry Andric   bool runOnFunction(Function &F) override;
1108f0fd8f6SDimitry Andric 
getPassName() const111d88c1a5aSDimitry Andric   StringRef getPassName() const override { return "SI annotate control flow"; }
1128f0fd8f6SDimitry Andric 
getAnalysisUsage(AnalysisUsage & AU) const1138f0fd8f6SDimitry Andric   void getAnalysisUsage(AnalysisUsage &AU) const override {
1148f0fd8f6SDimitry Andric     AU.addRequired<LoopInfoWrapperPass>();
1158f0fd8f6SDimitry Andric     AU.addRequired<DominatorTreeWrapperPass>();
116*b5893f02SDimitry Andric     AU.addRequired<LegacyDivergenceAnalysis>();
1178f0fd8f6SDimitry Andric     AU.addPreserved<DominatorTreeWrapperPass>();
1188f0fd8f6SDimitry Andric     FunctionPass::getAnalysisUsage(AU);
1198f0fd8f6SDimitry Andric   }
1208f0fd8f6SDimitry Andric };
1218f0fd8f6SDimitry Andric 
1228f0fd8f6SDimitry Andric } // end anonymous namespace
1238f0fd8f6SDimitry Andric 
1243ca95b02SDimitry Andric INITIALIZE_PASS_BEGIN(SIAnnotateControlFlow, DEBUG_TYPE,
1253ca95b02SDimitry Andric                       "Annotate SI Control Flow", false, false)
1267a7e6055SDimitry Andric INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass)
127*b5893f02SDimitry Andric INITIALIZE_PASS_DEPENDENCY(LegacyDivergenceAnalysis)
1283ca95b02SDimitry Andric INITIALIZE_PASS_END(SIAnnotateControlFlow, DEBUG_TYPE,
1293ca95b02SDimitry Andric                     "Annotate SI Control Flow", false, false)
1303ca95b02SDimitry Andric 
1318f0fd8f6SDimitry Andric char SIAnnotateControlFlow::ID = 0;
1328f0fd8f6SDimitry Andric 
1334ba319b5SDimitry Andric /// Initialize all the types and constants used in the pass
doInitialization(Module & M)1348f0fd8f6SDimitry Andric bool SIAnnotateControlFlow::doInitialization(Module &M) {
1358f0fd8f6SDimitry Andric   LLVMContext &Context = M.getContext();
1368f0fd8f6SDimitry Andric 
1378f0fd8f6SDimitry Andric   Void = Type::getVoidTy(Context);
1388f0fd8f6SDimitry Andric   Boolean = Type::getInt1Ty(Context);
1398f0fd8f6SDimitry Andric   Int64 = Type::getInt64Ty(Context);
1405517e702SDimitry Andric   ReturnStruct = StructType::get(Boolean, Int64);
1418f0fd8f6SDimitry Andric 
1428f0fd8f6SDimitry Andric   BoolTrue = ConstantInt::getTrue(Context);
1438f0fd8f6SDimitry Andric   BoolFalse = ConstantInt::getFalse(Context);
1448f0fd8f6SDimitry Andric   BoolUndef = UndefValue::get(Boolean);
1458f0fd8f6SDimitry Andric   Int64Zero = ConstantInt::get(Int64, 0);
1468f0fd8f6SDimitry Andric 
1477a7e6055SDimitry Andric   If = Intrinsic::getDeclaration(&M, Intrinsic::amdgcn_if);
1487a7e6055SDimitry Andric   Else = Intrinsic::getDeclaration(&M, Intrinsic::amdgcn_else);
1497a7e6055SDimitry Andric   IfBreak = Intrinsic::getDeclaration(&M, Intrinsic::amdgcn_if_break);
1507a7e6055SDimitry Andric   Loop = Intrinsic::getDeclaration(&M, Intrinsic::amdgcn_loop);
1517a7e6055SDimitry Andric   EndCf = Intrinsic::getDeclaration(&M, Intrinsic::amdgcn_end_cf);
1528f0fd8f6SDimitry Andric   return false;
1538f0fd8f6SDimitry Andric }
1548f0fd8f6SDimitry Andric 
1554ba319b5SDimitry Andric /// Is the branch condition uniform or did the StructurizeCFG pass
1563ca95b02SDimitry Andric /// consider it as such?
isUniform(BranchInst * T)1573ca95b02SDimitry Andric bool SIAnnotateControlFlow::isUniform(BranchInst *T) {
158*b5893f02SDimitry Andric   return DA->isUniform(T) ||
1593ca95b02SDimitry Andric          T->getMetadata("structurizecfg.uniform") != nullptr;
1603ca95b02SDimitry Andric }
1613ca95b02SDimitry Andric 
1624ba319b5SDimitry Andric /// Is BB the last block saved on the stack ?
isTopOfStack(BasicBlock * BB)1638f0fd8f6SDimitry Andric bool SIAnnotateControlFlow::isTopOfStack(BasicBlock *BB) {
1648f0fd8f6SDimitry Andric   return !Stack.empty() && Stack.back().first == BB;
1658f0fd8f6SDimitry Andric }
1668f0fd8f6SDimitry Andric 
1674ba319b5SDimitry Andric /// Pop the last saved value from the control flow stack
popSaved()1688f0fd8f6SDimitry Andric Value *SIAnnotateControlFlow::popSaved() {
1698f0fd8f6SDimitry Andric   return Stack.pop_back_val().second;
1708f0fd8f6SDimitry Andric }
1718f0fd8f6SDimitry Andric 
1724ba319b5SDimitry Andric /// Push a BB and saved value to the control flow stack
push(BasicBlock * BB,Value * Saved)1738f0fd8f6SDimitry Andric void SIAnnotateControlFlow::push(BasicBlock *BB, Value *Saved) {
1748f0fd8f6SDimitry Andric   Stack.push_back(std::make_pair(BB, Saved));
1758f0fd8f6SDimitry Andric }
1768f0fd8f6SDimitry Andric 
1774ba319b5SDimitry Andric /// Can the condition represented by this PHI node treated like
1788f0fd8f6SDimitry Andric /// an "Else" block?
isElse(PHINode * Phi)1798f0fd8f6SDimitry Andric bool SIAnnotateControlFlow::isElse(PHINode *Phi) {
1808f0fd8f6SDimitry Andric   BasicBlock *IDom = DT->getNode(Phi->getParent())->getIDom()->getBlock();
1818f0fd8f6SDimitry Andric   for (unsigned i = 0, e = Phi->getNumIncomingValues(); i != e; ++i) {
1828f0fd8f6SDimitry Andric     if (Phi->getIncomingBlock(i) == IDom) {
1838f0fd8f6SDimitry Andric 
1848f0fd8f6SDimitry Andric       if (Phi->getIncomingValue(i) != BoolTrue)
1858f0fd8f6SDimitry Andric         return false;
1868f0fd8f6SDimitry Andric 
1878f0fd8f6SDimitry Andric     } else {
1888f0fd8f6SDimitry Andric       if (Phi->getIncomingValue(i) != BoolFalse)
1898f0fd8f6SDimitry Andric         return false;
1908f0fd8f6SDimitry Andric 
1918f0fd8f6SDimitry Andric     }
1928f0fd8f6SDimitry Andric   }
1938f0fd8f6SDimitry Andric   return true;
1948f0fd8f6SDimitry Andric }
1958f0fd8f6SDimitry Andric 
1964ba319b5SDimitry Andric // Erase "Phi" if it is not used any more
eraseIfUnused(PHINode * Phi)1978f0fd8f6SDimitry Andric void SIAnnotateControlFlow::eraseIfUnused(PHINode *Phi) {
1982cab237bSDimitry Andric   if (RecursivelyDeleteDeadPHINode(Phi)) {
1994ba319b5SDimitry Andric     LLVM_DEBUG(dbgs() << "Erased unused condition phi\n");
2007a7e6055SDimitry Andric   }
2018f0fd8f6SDimitry Andric }
2028f0fd8f6SDimitry Andric 
2034ba319b5SDimitry Andric /// Open a new "If" block
openIf(BranchInst * Term)2048f0fd8f6SDimitry Andric void SIAnnotateControlFlow::openIf(BranchInst *Term) {
2057a7e6055SDimitry Andric   if (isUniform(Term))
2063ca95b02SDimitry Andric     return;
2077a7e6055SDimitry Andric 
2088f0fd8f6SDimitry Andric   Value *Ret = CallInst::Create(If, Term->getCondition(), "", Term);
2098f0fd8f6SDimitry Andric   Term->setCondition(ExtractValueInst::Create(Ret, 0, "", Term));
2108f0fd8f6SDimitry Andric   push(Term->getSuccessor(1), ExtractValueInst::Create(Ret, 1, "", Term));
2118f0fd8f6SDimitry Andric }
2128f0fd8f6SDimitry Andric 
2134ba319b5SDimitry Andric /// Close the last "If" block and open a new "Else" block
insertElse(BranchInst * Term)2148f0fd8f6SDimitry Andric void SIAnnotateControlFlow::insertElse(BranchInst *Term) {
2153ca95b02SDimitry Andric   if (isUniform(Term)) {
2163ca95b02SDimitry Andric     return;
2173ca95b02SDimitry Andric   }
2188f0fd8f6SDimitry Andric   Value *Ret = CallInst::Create(Else, popSaved(), "", Term);
2198f0fd8f6SDimitry Andric   Term->setCondition(ExtractValueInst::Create(Ret, 0, "", Term));
2208f0fd8f6SDimitry Andric   push(Term->getSuccessor(1), ExtractValueInst::Create(Ret, 1, "", Term));
2218f0fd8f6SDimitry Andric }
2228f0fd8f6SDimitry Andric 
2234ba319b5SDimitry Andric /// Recursively handle the condition leading to a loop
handleLoopCondition(Value * Cond,PHINode * Broken,llvm::Loop * L,BranchInst * Term)2247a7e6055SDimitry Andric Value *SIAnnotateControlFlow::handleLoopCondition(
225*b5893f02SDimitry Andric     Value *Cond, PHINode *Broken, llvm::Loop *L, BranchInst *Term) {
2267a7e6055SDimitry Andric   if (Instruction *Inst = dyn_cast<Instruction>(Cond)) {
2278f0fd8f6SDimitry Andric     BasicBlock *Parent = Inst->getParent();
2288f0fd8f6SDimitry Andric     Instruction *Insert;
2298f0fd8f6SDimitry Andric     if (L->contains(Inst)) {
2308f0fd8f6SDimitry Andric       Insert = Parent->getTerminator();
2318f0fd8f6SDimitry Andric     } else {
2328f0fd8f6SDimitry Andric       Insert = L->getHeader()->getFirstNonPHIOrDbgOrLifetime();
2338f0fd8f6SDimitry Andric     }
2347a7e6055SDimitry Andric 
2358f0fd8f6SDimitry Andric     Value *Args[] = { Cond, Broken };
2368f0fd8f6SDimitry Andric     return CallInst::Create(IfBreak, Args, "", Insert);
2378f0fd8f6SDimitry Andric   }
2387a7e6055SDimitry Andric 
2397a7e6055SDimitry Andric   // Insert IfBreak in the loop header TERM for constant COND other than true.
2407a7e6055SDimitry Andric   if (isa<Constant>(Cond)) {
2417a7e6055SDimitry Andric     Instruction *Insert = Cond == BoolTrue ?
2427a7e6055SDimitry Andric       Term : L->getHeader()->getTerminator();
2437a7e6055SDimitry Andric 
2447a7e6055SDimitry Andric     Value *Args[] = { Cond, Broken };
2457a7e6055SDimitry Andric     return CallInst::Create(IfBreak, Args, "", Insert);
2467a7e6055SDimitry Andric   }
2477a7e6055SDimitry Andric 
2487a7e6055SDimitry Andric   llvm_unreachable("Unhandled loop condition!");
2498f0fd8f6SDimitry Andric }
2508f0fd8f6SDimitry Andric 
2514ba319b5SDimitry Andric /// Handle a back edge (loop)
handleLoop(BranchInst * Term)2528f0fd8f6SDimitry Andric void SIAnnotateControlFlow::handleLoop(BranchInst *Term) {
2537a7e6055SDimitry Andric   if (isUniform(Term))
2543ca95b02SDimitry Andric     return;
2553ca95b02SDimitry Andric 
2568f0fd8f6SDimitry Andric   BasicBlock *BB = Term->getParent();
2578f0fd8f6SDimitry Andric   llvm::Loop *L = LI->getLoopFor(BB);
258d88c1a5aSDimitry Andric   if (!L)
259d88c1a5aSDimitry Andric     return;
2608f0fd8f6SDimitry Andric 
2617a7e6055SDimitry Andric   BasicBlock *Target = Term->getSuccessor(1);
2627a7e6055SDimitry Andric   PHINode *Broken = PHINode::Create(Int64, 0, "phi.broken", &Target->front());
2637a7e6055SDimitry Andric 
2648f0fd8f6SDimitry Andric   Value *Cond = Term->getCondition();
2658f0fd8f6SDimitry Andric   Term->setCondition(BoolTrue);
266*b5893f02SDimitry Andric   Value *Arg = handleLoopCondition(Cond, Broken, L, Term);
2678f0fd8f6SDimitry Andric 
2687a7e6055SDimitry Andric   for (BasicBlock *Pred : predecessors(Target))
2697a7e6055SDimitry Andric     Broken->addIncoming(Pred == BB ? Arg : Int64Zero, Pred);
2708f0fd8f6SDimitry Andric 
2718f0fd8f6SDimitry Andric   Term->setCondition(CallInst::Create(Loop, Arg, "", Term));
2727a7e6055SDimitry Andric 
2738f0fd8f6SDimitry Andric   push(Term->getSuccessor(0), Arg);
2747a7e6055SDimitry Andric }
2757a7e6055SDimitry Andric 
2764ba319b5SDimitry Andric /// Close the last opened control flow
closeControlFlow(BasicBlock * BB)2778f0fd8f6SDimitry Andric void SIAnnotateControlFlow::closeControlFlow(BasicBlock *BB) {
2788f0fd8f6SDimitry Andric   llvm::Loop *L = LI->getLoopFor(BB);
2798f0fd8f6SDimitry Andric 
2803ca95b02SDimitry Andric   assert(Stack.back().first == BB);
2813ca95b02SDimitry Andric 
2828f0fd8f6SDimitry Andric   if (L && L->getHeader() == BB) {
2838f0fd8f6SDimitry Andric     // We can't insert an EndCF call into a loop header, because it will
2848f0fd8f6SDimitry Andric     // get executed on every iteration of the loop, when it should be
2858f0fd8f6SDimitry Andric     // executed only once before the loop.
2868f0fd8f6SDimitry Andric     SmallVector <BasicBlock *, 8> Latches;
2878f0fd8f6SDimitry Andric     L->getLoopLatches(Latches);
2888f0fd8f6SDimitry Andric 
2897a7e6055SDimitry Andric     SmallVector<BasicBlock *, 2> Preds;
2907a7e6055SDimitry Andric     for (BasicBlock *Pred : predecessors(BB)) {
2917a7e6055SDimitry Andric       if (!is_contained(Latches, Pred))
2927a7e6055SDimitry Andric         Preds.push_back(Pred);
2938f0fd8f6SDimitry Andric     }
2947a7e6055SDimitry Andric 
295*b5893f02SDimitry Andric     BB = SplitBlockPredecessors(BB, Preds, "endcf.split", DT, LI, nullptr,
296*b5893f02SDimitry Andric                                 false);
2978f0fd8f6SDimitry Andric   }
2988f0fd8f6SDimitry Andric 
2993ca95b02SDimitry Andric   Value *Exec = popSaved();
3007a7e6055SDimitry Andric   Instruction *FirstInsertionPt = &*BB->getFirstInsertionPt();
3017a7e6055SDimitry Andric   if (!isa<UndefValue>(Exec) && !isa<UnreachableInst>(FirstInsertionPt))
3027a7e6055SDimitry Andric     CallInst::Create(EndCf, Exec, "", FirstInsertionPt);
3038f0fd8f6SDimitry Andric }
3048f0fd8f6SDimitry Andric 
3054ba319b5SDimitry Andric /// Annotate the control flow with intrinsics so the backend can
3068f0fd8f6SDimitry Andric /// recognize if/then/else and loops.
runOnFunction(Function & F)3078f0fd8f6SDimitry Andric bool SIAnnotateControlFlow::runOnFunction(Function &F) {
3088f0fd8f6SDimitry Andric   DT = &getAnalysis<DominatorTreeWrapperPass>().getDomTree();
3098f0fd8f6SDimitry Andric   LI = &getAnalysis<LoopInfoWrapperPass>().getLoopInfo();
310*b5893f02SDimitry Andric   DA = &getAnalysis<LegacyDivergenceAnalysis>();
3118f0fd8f6SDimitry Andric 
3128f0fd8f6SDimitry Andric   for (df_iterator<BasicBlock *> I = df_begin(&F.getEntryBlock()),
3138f0fd8f6SDimitry Andric        E = df_end(&F.getEntryBlock()); I != E; ++I) {
3147a7e6055SDimitry Andric     BasicBlock *BB = *I;
3157a7e6055SDimitry Andric     BranchInst *Term = dyn_cast<BranchInst>(BB->getTerminator());
3168f0fd8f6SDimitry Andric 
3178f0fd8f6SDimitry Andric     if (!Term || Term->isUnconditional()) {
3187a7e6055SDimitry Andric       if (isTopOfStack(BB))
3197a7e6055SDimitry Andric         closeControlFlow(BB);
3203ca95b02SDimitry Andric 
3218f0fd8f6SDimitry Andric       continue;
3228f0fd8f6SDimitry Andric     }
3238f0fd8f6SDimitry Andric 
3248f0fd8f6SDimitry Andric     if (I.nodeVisited(Term->getSuccessor(1))) {
3257a7e6055SDimitry Andric       if (isTopOfStack(BB))
3267a7e6055SDimitry Andric         closeControlFlow(BB);
3273ca95b02SDimitry Andric 
3288f0fd8f6SDimitry Andric       handleLoop(Term);
3298f0fd8f6SDimitry Andric       continue;
3308f0fd8f6SDimitry Andric     }
3318f0fd8f6SDimitry Andric 
3327a7e6055SDimitry Andric     if (isTopOfStack(BB)) {
3338f0fd8f6SDimitry Andric       PHINode *Phi = dyn_cast<PHINode>(Term->getCondition());
3347a7e6055SDimitry Andric       if (Phi && Phi->getParent() == BB && isElse(Phi)) {
3358f0fd8f6SDimitry Andric         insertElse(Term);
3368f0fd8f6SDimitry Andric         eraseIfUnused(Phi);
3378f0fd8f6SDimitry Andric         continue;
3388f0fd8f6SDimitry Andric       }
3397a7e6055SDimitry Andric 
3407a7e6055SDimitry Andric       closeControlFlow(BB);
3418f0fd8f6SDimitry Andric     }
3427a7e6055SDimitry Andric 
3438f0fd8f6SDimitry Andric     openIf(Term);
3448f0fd8f6SDimitry Andric   }
3458f0fd8f6SDimitry Andric 
3464ba319b5SDimitry Andric   if (!Stack.empty()) {
3474ba319b5SDimitry Andric     // CFG was probably not structured.
3484ba319b5SDimitry Andric     report_fatal_error("failed to annotate CFG");
3494ba319b5SDimitry Andric   }
3504ba319b5SDimitry Andric 
3518f0fd8f6SDimitry Andric   return true;
3528f0fd8f6SDimitry Andric }
3538f0fd8f6SDimitry Andric 
3544ba319b5SDimitry Andric /// Create the annotation pass
createSIAnnotateControlFlowPass()3558f0fd8f6SDimitry Andric FunctionPass *llvm::createSIAnnotateControlFlowPass() {
3568f0fd8f6SDimitry Andric   return new SIAnnotateControlFlow();
3578f0fd8f6SDimitry Andric }
358