10b57cec5SDimitry Andric //===-- CFG.cpp - BasicBlock analysis --------------------------------------==// 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 // This family of functions performs analyses on basic blocks, and instructions 100b57cec5SDimitry Andric // contained within basic blocks. 110b57cec5SDimitry Andric // 120b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 130b57cec5SDimitry Andric 140b57cec5SDimitry Andric #include "llvm/Analysis/CFG.h" 150b57cec5SDimitry Andric #include "llvm/Analysis/LoopInfo.h" 160b57cec5SDimitry Andric #include "llvm/IR/Dominators.h" 17e8d8bef9SDimitry Andric #include "llvm/Support/CommandLine.h" 180b57cec5SDimitry Andric 190b57cec5SDimitry Andric using namespace llvm; 200b57cec5SDimitry Andric 21e8d8bef9SDimitry Andric // The max number of basic blocks explored during reachability analysis between 22e8d8bef9SDimitry Andric // two basic blocks. This is kept reasonably small to limit compile time when 23e8d8bef9SDimitry Andric // repeatedly used by clients of this analysis (such as captureTracking). 24e8d8bef9SDimitry Andric static cl::opt<unsigned> DefaultMaxBBsToExplore( 25e8d8bef9SDimitry Andric "dom-tree-reachability-max-bbs-to-explore", cl::Hidden, 26e8d8bef9SDimitry Andric cl::desc("Max number of BBs to explore for reachability analysis"), 27e8d8bef9SDimitry Andric cl::init(32)); 28e8d8bef9SDimitry Andric 290b57cec5SDimitry Andric /// FindFunctionBackedges - Analyze the specified function to find all of the 300b57cec5SDimitry Andric /// loop backedges in the function and return them. This is a relatively cheap 310b57cec5SDimitry Andric /// (compared to computing dominators and loop info) analysis. 320b57cec5SDimitry Andric /// 330b57cec5SDimitry Andric /// The output is added to Result, as pairs of <from,to> edge info. 340b57cec5SDimitry Andric void llvm::FindFunctionBackedges(const Function &F, 350b57cec5SDimitry Andric SmallVectorImpl<std::pair<const BasicBlock*,const BasicBlock*> > &Result) { 360b57cec5SDimitry Andric const BasicBlock *BB = &F.getEntryBlock(); 370b57cec5SDimitry Andric if (succ_empty(BB)) 380b57cec5SDimitry Andric return; 390b57cec5SDimitry Andric 400b57cec5SDimitry Andric SmallPtrSet<const BasicBlock*, 8> Visited; 415ffd83dbSDimitry Andric SmallVector<std::pair<const BasicBlock *, const_succ_iterator>, 8> VisitStack; 420b57cec5SDimitry Andric SmallPtrSet<const BasicBlock*, 8> InStack; 430b57cec5SDimitry Andric 440b57cec5SDimitry Andric Visited.insert(BB); 450b57cec5SDimitry Andric VisitStack.push_back(std::make_pair(BB, succ_begin(BB))); 460b57cec5SDimitry Andric InStack.insert(BB); 470b57cec5SDimitry Andric do { 485ffd83dbSDimitry Andric std::pair<const BasicBlock *, const_succ_iterator> &Top = VisitStack.back(); 490b57cec5SDimitry Andric const BasicBlock *ParentBB = Top.first; 505ffd83dbSDimitry Andric const_succ_iterator &I = Top.second; 510b57cec5SDimitry Andric 520b57cec5SDimitry Andric bool FoundNew = false; 530b57cec5SDimitry Andric while (I != succ_end(ParentBB)) { 540b57cec5SDimitry Andric BB = *I++; 550b57cec5SDimitry Andric if (Visited.insert(BB).second) { 560b57cec5SDimitry Andric FoundNew = true; 570b57cec5SDimitry Andric break; 580b57cec5SDimitry Andric } 590b57cec5SDimitry Andric // Successor is in VisitStack, it's a back edge. 600b57cec5SDimitry Andric if (InStack.count(BB)) 610b57cec5SDimitry Andric Result.push_back(std::make_pair(ParentBB, BB)); 620b57cec5SDimitry Andric } 630b57cec5SDimitry Andric 640b57cec5SDimitry Andric if (FoundNew) { 650b57cec5SDimitry Andric // Go down one level if there is a unvisited successor. 660b57cec5SDimitry Andric InStack.insert(BB); 670b57cec5SDimitry Andric VisitStack.push_back(std::make_pair(BB, succ_begin(BB))); 680b57cec5SDimitry Andric } else { 690b57cec5SDimitry Andric // Go up one level. 700b57cec5SDimitry Andric InStack.erase(VisitStack.pop_back_val().first); 710b57cec5SDimitry Andric } 720b57cec5SDimitry Andric } while (!VisitStack.empty()); 730b57cec5SDimitry Andric } 740b57cec5SDimitry Andric 750b57cec5SDimitry Andric /// GetSuccessorNumber - Search for the specified successor of basic block BB 760b57cec5SDimitry Andric /// and return its position in the terminator instruction's list of 770b57cec5SDimitry Andric /// successors. It is an error to call this with a block that is not a 780b57cec5SDimitry Andric /// successor. 790b57cec5SDimitry Andric unsigned llvm::GetSuccessorNumber(const BasicBlock *BB, 800b57cec5SDimitry Andric const BasicBlock *Succ) { 810b57cec5SDimitry Andric const Instruction *Term = BB->getTerminator(); 820b57cec5SDimitry Andric #ifndef NDEBUG 830b57cec5SDimitry Andric unsigned e = Term->getNumSuccessors(); 840b57cec5SDimitry Andric #endif 850b57cec5SDimitry Andric for (unsigned i = 0; ; ++i) { 860b57cec5SDimitry Andric assert(i != e && "Didn't find edge?"); 870b57cec5SDimitry Andric if (Term->getSuccessor(i) == Succ) 880b57cec5SDimitry Andric return i; 890b57cec5SDimitry Andric } 900b57cec5SDimitry Andric } 910b57cec5SDimitry Andric 920b57cec5SDimitry Andric /// isCriticalEdge - Return true if the specified edge is a critical edge. 930b57cec5SDimitry Andric /// Critical edges are edges from a block with multiple successors to a block 940b57cec5SDimitry Andric /// with multiple predecessors. 950b57cec5SDimitry Andric bool llvm::isCriticalEdge(const Instruction *TI, unsigned SuccNum, 960b57cec5SDimitry Andric bool AllowIdenticalEdges) { 970b57cec5SDimitry Andric assert(SuccNum < TI->getNumSuccessors() && "Illegal edge specification!"); 988bcb0991SDimitry Andric return isCriticalEdge(TI, TI->getSuccessor(SuccNum), AllowIdenticalEdges); 998bcb0991SDimitry Andric } 1008bcb0991SDimitry Andric 1018bcb0991SDimitry Andric bool llvm::isCriticalEdge(const Instruction *TI, const BasicBlock *Dest, 1028bcb0991SDimitry Andric bool AllowIdenticalEdges) { 1038bcb0991SDimitry Andric assert(TI->isTerminator() && "Must be a terminator to have successors!"); 1040b57cec5SDimitry Andric if (TI->getNumSuccessors() == 1) return false; 1050b57cec5SDimitry Andric 106e8d8bef9SDimitry Andric assert(is_contained(predecessors(Dest), TI->getParent()) && 1078bcb0991SDimitry Andric "No edge between TI's block and Dest."); 1088bcb0991SDimitry Andric 1090b57cec5SDimitry Andric const_pred_iterator I = pred_begin(Dest), E = pred_end(Dest); 1100b57cec5SDimitry Andric 1110b57cec5SDimitry Andric // If there is more than one predecessor, this is a critical edge... 1120b57cec5SDimitry Andric assert(I != E && "No preds, but we have an edge to the block?"); 1130b57cec5SDimitry Andric const BasicBlock *FirstPred = *I; 1140b57cec5SDimitry Andric ++I; // Skip one edge due to the incoming arc from TI. 1150b57cec5SDimitry Andric if (!AllowIdenticalEdges) 1160b57cec5SDimitry Andric return I != E; 1170b57cec5SDimitry Andric 1180b57cec5SDimitry Andric // If AllowIdenticalEdges is true, then we allow this edge to be considered 1190b57cec5SDimitry Andric // non-critical iff all preds come from TI's block. 1200b57cec5SDimitry Andric for (; I != E; ++I) 1210b57cec5SDimitry Andric if (*I != FirstPred) 1220b57cec5SDimitry Andric return true; 1230b57cec5SDimitry Andric return false; 1240b57cec5SDimitry Andric } 1250b57cec5SDimitry Andric 1260b57cec5SDimitry Andric // LoopInfo contains a mapping from basic block to the innermost loop. Find 1270b57cec5SDimitry Andric // the outermost loop in the loop nest that contains BB. 1280b57cec5SDimitry Andric static const Loop *getOutermostLoop(const LoopInfo *LI, const BasicBlock *BB) { 1290b57cec5SDimitry Andric const Loop *L = LI->getLoopFor(BB); 13081ad6265SDimitry Andric return L ? L->getOutermostLoop() : nullptr; 1310b57cec5SDimitry Andric } 1320b57cec5SDimitry Andric 133*0fca6ea1SDimitry Andric template <class StopSetT> 134*0fca6ea1SDimitry Andric static bool isReachableImpl(SmallVectorImpl<BasicBlock *> &Worklist, 135*0fca6ea1SDimitry Andric const StopSetT &StopSet, 136*0fca6ea1SDimitry Andric const SmallPtrSetImpl<BasicBlock *> *ExclusionSet, 137*0fca6ea1SDimitry Andric const DominatorTree *DT, const LoopInfo *LI) { 138*0fca6ea1SDimitry Andric // When a stop block is unreachable, it's dominated from everywhere, 1390b57cec5SDimitry Andric // regardless of whether there's a path between the two blocks. 140*0fca6ea1SDimitry Andric if (DT) { 141*0fca6ea1SDimitry Andric for (auto *BB : StopSet) { 142*0fca6ea1SDimitry Andric if (!DT->isReachableFromEntry(BB)) { 1430b57cec5SDimitry Andric DT = nullptr; 144*0fca6ea1SDimitry Andric break; 145*0fca6ea1SDimitry Andric } 146*0fca6ea1SDimitry Andric } 147*0fca6ea1SDimitry Andric } 1480b57cec5SDimitry Andric 1490b57cec5SDimitry Andric // We can't skip directly from a block that dominates the stop block if the 1500b57cec5SDimitry Andric // exclusion block is potentially in between. 1510b57cec5SDimitry Andric if (ExclusionSet && !ExclusionSet->empty()) 1520b57cec5SDimitry Andric DT = nullptr; 1530b57cec5SDimitry Andric 1540b57cec5SDimitry Andric // Normally any block in a loop is reachable from any other block in a loop, 1550b57cec5SDimitry Andric // however excluded blocks might partition the body of a loop to make that 1560b57cec5SDimitry Andric // untrue. 1570b57cec5SDimitry Andric SmallPtrSet<const Loop *, 8> LoopsWithHoles; 1580b57cec5SDimitry Andric if (LI && ExclusionSet) { 159fcaf7f86SDimitry Andric for (auto *BB : *ExclusionSet) { 1600b57cec5SDimitry Andric if (const Loop *L = getOutermostLoop(LI, BB)) 1610b57cec5SDimitry Andric LoopsWithHoles.insert(L); 1620b57cec5SDimitry Andric } 1630b57cec5SDimitry Andric } 1640b57cec5SDimitry Andric 165*0fca6ea1SDimitry Andric SmallPtrSet<const Loop *, 2> StopLoops; 166*0fca6ea1SDimitry Andric if (LI) { 167*0fca6ea1SDimitry Andric for (auto *StopSetBB : StopSet) { 168*0fca6ea1SDimitry Andric if (const Loop *L = getOutermostLoop(LI, StopSetBB)) 169*0fca6ea1SDimitry Andric StopLoops.insert(L); 170*0fca6ea1SDimitry Andric } 171*0fca6ea1SDimitry Andric } 1720b57cec5SDimitry Andric 173e8d8bef9SDimitry Andric unsigned Limit = DefaultMaxBBsToExplore; 1740b57cec5SDimitry Andric SmallPtrSet<const BasicBlock*, 32> Visited; 1750b57cec5SDimitry Andric do { 1760b57cec5SDimitry Andric BasicBlock *BB = Worklist.pop_back_val(); 1770b57cec5SDimitry Andric if (!Visited.insert(BB).second) 1780b57cec5SDimitry Andric continue; 179*0fca6ea1SDimitry Andric if (StopSet.contains(BB)) 1800b57cec5SDimitry Andric return true; 1810b57cec5SDimitry Andric if (ExclusionSet && ExclusionSet->count(BB)) 1820b57cec5SDimitry Andric continue; 183*0fca6ea1SDimitry Andric if (DT) { 184*0fca6ea1SDimitry Andric if (llvm::any_of(StopSet, [&](const BasicBlock *StopBB) { 185*0fca6ea1SDimitry Andric return DT->dominates(BB, StopBB); 186*0fca6ea1SDimitry Andric })) 1870b57cec5SDimitry Andric return true; 188*0fca6ea1SDimitry Andric } 1890b57cec5SDimitry Andric 1900b57cec5SDimitry Andric const Loop *Outer = nullptr; 1910b57cec5SDimitry Andric if (LI) { 1920b57cec5SDimitry Andric Outer = getOutermostLoop(LI, BB); 1930b57cec5SDimitry Andric // If we're in a loop with a hole, not all blocks in the loop are 1940b57cec5SDimitry Andric // reachable from all other blocks. That implies we can't simply jump to 1950b57cec5SDimitry Andric // the loop's exit blocks, as that exit might need to pass through an 1960b57cec5SDimitry Andric // excluded block. Clear Outer so we process BB's successors. 1970b57cec5SDimitry Andric if (LoopsWithHoles.count(Outer)) 1980b57cec5SDimitry Andric Outer = nullptr; 199*0fca6ea1SDimitry Andric if (StopLoops.contains(Outer)) 2000b57cec5SDimitry Andric return true; 2010b57cec5SDimitry Andric } 2020b57cec5SDimitry Andric 2030b57cec5SDimitry Andric if (!--Limit) { 2040b57cec5SDimitry Andric // We haven't been able to prove it one way or the other. Conservatively 2050b57cec5SDimitry Andric // answer true -- that there is potentially a path. 2060b57cec5SDimitry Andric return true; 2070b57cec5SDimitry Andric } 2080b57cec5SDimitry Andric 2090b57cec5SDimitry Andric if (Outer) { 2100b57cec5SDimitry Andric // All blocks in a single loop are reachable from all other blocks. From 2110b57cec5SDimitry Andric // any of these blocks, we can skip directly to the exits of the loop, 2120b57cec5SDimitry Andric // ignoring any other blocks inside the loop body. 2130b57cec5SDimitry Andric Outer->getExitBlocks(Worklist); 2140b57cec5SDimitry Andric } else { 2150b57cec5SDimitry Andric Worklist.append(succ_begin(BB), succ_end(BB)); 2160b57cec5SDimitry Andric } 2170b57cec5SDimitry Andric } while (!Worklist.empty()); 2180b57cec5SDimitry Andric 2190b57cec5SDimitry Andric // We have exhausted all possible paths and are certain that 'To' can not be 2200b57cec5SDimitry Andric // reached from 'From'. 2210b57cec5SDimitry Andric return false; 2220b57cec5SDimitry Andric } 2230b57cec5SDimitry Andric 224*0fca6ea1SDimitry Andric template <class T> class SingleEntrySet { 225*0fca6ea1SDimitry Andric public: 226*0fca6ea1SDimitry Andric using const_iterator = const T *; 227*0fca6ea1SDimitry Andric 228*0fca6ea1SDimitry Andric SingleEntrySet(T Elem) : Elem(Elem) {} 229*0fca6ea1SDimitry Andric 230*0fca6ea1SDimitry Andric bool contains(T Other) const { return Elem == Other; } 231*0fca6ea1SDimitry Andric 232*0fca6ea1SDimitry Andric const_iterator begin() const { return &Elem; } 233*0fca6ea1SDimitry Andric const_iterator end() const { return &Elem + 1; } 234*0fca6ea1SDimitry Andric 235*0fca6ea1SDimitry Andric private: 236*0fca6ea1SDimitry Andric T Elem; 237*0fca6ea1SDimitry Andric }; 238*0fca6ea1SDimitry Andric 239*0fca6ea1SDimitry Andric bool llvm::isPotentiallyReachableFromMany( 240*0fca6ea1SDimitry Andric SmallVectorImpl<BasicBlock *> &Worklist, const BasicBlock *StopBB, 241*0fca6ea1SDimitry Andric const SmallPtrSetImpl<BasicBlock *> *ExclusionSet, const DominatorTree *DT, 242*0fca6ea1SDimitry Andric const LoopInfo *LI) { 243*0fca6ea1SDimitry Andric return isReachableImpl<SingleEntrySet<const BasicBlock *>>( 244*0fca6ea1SDimitry Andric Worklist, SingleEntrySet<const BasicBlock *>(StopBB), ExclusionSet, DT, 245*0fca6ea1SDimitry Andric LI); 246*0fca6ea1SDimitry Andric } 247*0fca6ea1SDimitry Andric 248*0fca6ea1SDimitry Andric bool llvm::isManyPotentiallyReachableFromMany( 249*0fca6ea1SDimitry Andric SmallVectorImpl<BasicBlock *> &Worklist, 250*0fca6ea1SDimitry Andric const SmallPtrSetImpl<const BasicBlock *> &StopSet, 251*0fca6ea1SDimitry Andric const SmallPtrSetImpl<BasicBlock *> *ExclusionSet, const DominatorTree *DT, 252*0fca6ea1SDimitry Andric const LoopInfo *LI) { 253*0fca6ea1SDimitry Andric return isReachableImpl<SmallPtrSetImpl<const BasicBlock *>>( 254*0fca6ea1SDimitry Andric Worklist, StopSet, ExclusionSet, DT, LI); 255*0fca6ea1SDimitry Andric } 256*0fca6ea1SDimitry Andric 257fe6060f1SDimitry Andric bool llvm::isPotentiallyReachable( 258fe6060f1SDimitry Andric const BasicBlock *A, const BasicBlock *B, 259fe6060f1SDimitry Andric const SmallPtrSetImpl<BasicBlock *> *ExclusionSet, const DominatorTree *DT, 260fe6060f1SDimitry Andric const LoopInfo *LI) { 2610b57cec5SDimitry Andric assert(A->getParent() == B->getParent() && 2620b57cec5SDimitry Andric "This analysis is function-local!"); 2630b57cec5SDimitry Andric 264fe6060f1SDimitry Andric if (DT) { 265fe6060f1SDimitry Andric if (DT->isReachableFromEntry(A) && !DT->isReachableFromEntry(B)) 266fe6060f1SDimitry Andric return false; 267fe6060f1SDimitry Andric if (!ExclusionSet || ExclusionSet->empty()) { 268fe6060f1SDimitry Andric if (A->isEntryBlock() && DT->isReachableFromEntry(B)) 269fe6060f1SDimitry Andric return true; 270fe6060f1SDimitry Andric if (B->isEntryBlock() && DT->isReachableFromEntry(A)) 271fe6060f1SDimitry Andric return false; 272fe6060f1SDimitry Andric } 273fe6060f1SDimitry Andric } 274fe6060f1SDimitry Andric 2750b57cec5SDimitry Andric SmallVector<BasicBlock*, 32> Worklist; 2760b57cec5SDimitry Andric Worklist.push_back(const_cast<BasicBlock*>(A)); 2770b57cec5SDimitry Andric 278bdd1243dSDimitry Andric return isPotentiallyReachableFromMany(Worklist, B, ExclusionSet, DT, LI); 2790b57cec5SDimitry Andric } 2800b57cec5SDimitry Andric 2810b57cec5SDimitry Andric bool llvm::isPotentiallyReachable( 2820b57cec5SDimitry Andric const Instruction *A, const Instruction *B, 2830b57cec5SDimitry Andric const SmallPtrSetImpl<BasicBlock *> *ExclusionSet, const DominatorTree *DT, 2840b57cec5SDimitry Andric const LoopInfo *LI) { 2850b57cec5SDimitry Andric assert(A->getParent()->getParent() == B->getParent()->getParent() && 2860b57cec5SDimitry Andric "This analysis is function-local!"); 2870b57cec5SDimitry Andric 2880b57cec5SDimitry Andric if (A->getParent() == B->getParent()) { 2890b57cec5SDimitry Andric // The same block case is special because it's the only time we're looking 2900b57cec5SDimitry Andric // within a single block to see which instruction comes first. Once we 2910b57cec5SDimitry Andric // start looking at multiple blocks, the first instruction of the block is 2920b57cec5SDimitry Andric // reachable, so we only need to determine reachability between whole 2930b57cec5SDimitry Andric // blocks. 2940b57cec5SDimitry Andric BasicBlock *BB = const_cast<BasicBlock *>(A->getParent()); 2950b57cec5SDimitry Andric 2960b57cec5SDimitry Andric // If the block is in a loop then we can reach any instruction in the block 2970b57cec5SDimitry Andric // from any other instruction in the block by going around a backedge. 2980b57cec5SDimitry Andric if (LI && LI->getLoopFor(BB) != nullptr) 2990b57cec5SDimitry Andric return true; 3000b57cec5SDimitry Andric 301fe6060f1SDimitry Andric // If A comes before B, then B is definitively reachable from A. 302fe6060f1SDimitry Andric if (A == B || A->comesBefore(B)) 3030b57cec5SDimitry Andric return true; 3040b57cec5SDimitry Andric 3050b57cec5SDimitry Andric // Can't be in a loop if it's the entry block -- the entry block may not 3060b57cec5SDimitry Andric // have predecessors. 307fe6060f1SDimitry Andric if (BB->isEntryBlock()) 3080b57cec5SDimitry Andric return false; 3090b57cec5SDimitry Andric 3100b57cec5SDimitry Andric // Otherwise, continue doing the normal per-BB CFG walk. 311fe6060f1SDimitry Andric SmallVector<BasicBlock*, 32> Worklist; 3120b57cec5SDimitry Andric Worklist.append(succ_begin(BB), succ_end(BB)); 3130b57cec5SDimitry Andric if (Worklist.empty()) { 3140b57cec5SDimitry Andric // We've proven that there's no path! 3150b57cec5SDimitry Andric return false; 3160b57cec5SDimitry Andric } 3170b57cec5SDimitry Andric 318bdd1243dSDimitry Andric return isPotentiallyReachableFromMany(Worklist, B->getParent(), 319bdd1243dSDimitry Andric ExclusionSet, DT, LI); 320fe6060f1SDimitry Andric } 321fe6060f1SDimitry Andric 322fe6060f1SDimitry Andric return isPotentiallyReachable( 323fe6060f1SDimitry Andric A->getParent(), B->getParent(), ExclusionSet, DT, LI); 3240b57cec5SDimitry Andric } 325