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