xref: /openbsd-src/gnu/llvm/llvm/lib/Analysis/CFG.cpp (revision d415bd752c734aee168c4ee86ff32e8cc249eb16)
109467b48Spatrick //===-- CFG.cpp - BasicBlock analysis --------------------------------------==//
209467b48Spatrick //
309467b48Spatrick // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
409467b48Spatrick // See https://llvm.org/LICENSE.txt for license information.
509467b48Spatrick // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
609467b48Spatrick //
709467b48Spatrick //===----------------------------------------------------------------------===//
809467b48Spatrick //
909467b48Spatrick // This family of functions performs analyses on basic blocks, and instructions
1009467b48Spatrick // contained within basic blocks.
1109467b48Spatrick //
1209467b48Spatrick //===----------------------------------------------------------------------===//
1309467b48Spatrick 
1409467b48Spatrick #include "llvm/Analysis/CFG.h"
1509467b48Spatrick #include "llvm/Analysis/LoopInfo.h"
1609467b48Spatrick #include "llvm/IR/Dominators.h"
1773471bf0Spatrick #include "llvm/Support/CommandLine.h"
1809467b48Spatrick 
1909467b48Spatrick using namespace llvm;
2009467b48Spatrick 
2173471bf0Spatrick // The max number of basic blocks explored during reachability analysis between
2273471bf0Spatrick // two basic blocks. This is kept reasonably small to limit compile time when
2373471bf0Spatrick // repeatedly used by clients of this analysis (such as captureTracking).
2473471bf0Spatrick static cl::opt<unsigned> DefaultMaxBBsToExplore(
2573471bf0Spatrick     "dom-tree-reachability-max-bbs-to-explore", cl::Hidden,
2673471bf0Spatrick     cl::desc("Max number of BBs to explore for reachability analysis"),
2773471bf0Spatrick     cl::init(32));
2873471bf0Spatrick 
2909467b48Spatrick /// FindFunctionBackedges - Analyze the specified function to find all of the
3009467b48Spatrick /// loop backedges in the function and return them.  This is a relatively cheap
3109467b48Spatrick /// (compared to computing dominators and loop info) analysis.
3209467b48Spatrick ///
3309467b48Spatrick /// The output is added to Result, as pairs of <from,to> edge info.
FindFunctionBackedges(const Function & F,SmallVectorImpl<std::pair<const BasicBlock *,const BasicBlock * >> & Result)3409467b48Spatrick void llvm::FindFunctionBackedges(const Function &F,
3509467b48Spatrick      SmallVectorImpl<std::pair<const BasicBlock*,const BasicBlock*> > &Result) {
3609467b48Spatrick   const BasicBlock *BB = &F.getEntryBlock();
3709467b48Spatrick   if (succ_empty(BB))
3809467b48Spatrick     return;
3909467b48Spatrick 
4009467b48Spatrick   SmallPtrSet<const BasicBlock*, 8> Visited;
41097a140dSpatrick   SmallVector<std::pair<const BasicBlock *, const_succ_iterator>, 8> VisitStack;
4209467b48Spatrick   SmallPtrSet<const BasicBlock*, 8> InStack;
4309467b48Spatrick 
4409467b48Spatrick   Visited.insert(BB);
4509467b48Spatrick   VisitStack.push_back(std::make_pair(BB, succ_begin(BB)));
4609467b48Spatrick   InStack.insert(BB);
4709467b48Spatrick   do {
48097a140dSpatrick     std::pair<const BasicBlock *, const_succ_iterator> &Top = VisitStack.back();
4909467b48Spatrick     const BasicBlock *ParentBB = Top.first;
50097a140dSpatrick     const_succ_iterator &I = Top.second;
5109467b48Spatrick 
5209467b48Spatrick     bool FoundNew = false;
5309467b48Spatrick     while (I != succ_end(ParentBB)) {
5409467b48Spatrick       BB = *I++;
5509467b48Spatrick       if (Visited.insert(BB).second) {
5609467b48Spatrick         FoundNew = true;
5709467b48Spatrick         break;
5809467b48Spatrick       }
5909467b48Spatrick       // Successor is in VisitStack, it's a back edge.
6009467b48Spatrick       if (InStack.count(BB))
6109467b48Spatrick         Result.push_back(std::make_pair(ParentBB, BB));
6209467b48Spatrick     }
6309467b48Spatrick 
6409467b48Spatrick     if (FoundNew) {
6509467b48Spatrick       // Go down one level if there is a unvisited successor.
6609467b48Spatrick       InStack.insert(BB);
6709467b48Spatrick       VisitStack.push_back(std::make_pair(BB, succ_begin(BB)));
6809467b48Spatrick     } else {
6909467b48Spatrick       // Go up one level.
7009467b48Spatrick       InStack.erase(VisitStack.pop_back_val().first);
7109467b48Spatrick     }
7209467b48Spatrick   } while (!VisitStack.empty());
7309467b48Spatrick }
7409467b48Spatrick 
7509467b48Spatrick /// GetSuccessorNumber - Search for the specified successor of basic block BB
7609467b48Spatrick /// and return its position in the terminator instruction's list of
7709467b48Spatrick /// successors.  It is an error to call this with a block that is not a
7809467b48Spatrick /// successor.
GetSuccessorNumber(const BasicBlock * BB,const BasicBlock * Succ)7909467b48Spatrick unsigned llvm::GetSuccessorNumber(const BasicBlock *BB,
8009467b48Spatrick     const BasicBlock *Succ) {
8109467b48Spatrick   const Instruction *Term = BB->getTerminator();
8209467b48Spatrick #ifndef NDEBUG
8309467b48Spatrick   unsigned e = Term->getNumSuccessors();
8409467b48Spatrick #endif
8509467b48Spatrick   for (unsigned i = 0; ; ++i) {
8609467b48Spatrick     assert(i != e && "Didn't find edge?");
8709467b48Spatrick     if (Term->getSuccessor(i) == Succ)
8809467b48Spatrick       return i;
8909467b48Spatrick   }
9009467b48Spatrick }
9109467b48Spatrick 
9209467b48Spatrick /// isCriticalEdge - Return true if the specified edge is a critical edge.
9309467b48Spatrick /// Critical edges are edges from a block with multiple successors to a block
9409467b48Spatrick /// with multiple predecessors.
isCriticalEdge(const Instruction * TI,unsigned SuccNum,bool AllowIdenticalEdges)9509467b48Spatrick bool llvm::isCriticalEdge(const Instruction *TI, unsigned SuccNum,
9609467b48Spatrick                           bool AllowIdenticalEdges) {
9709467b48Spatrick   assert(SuccNum < TI->getNumSuccessors() && "Illegal edge specification!");
9809467b48Spatrick   return isCriticalEdge(TI, TI->getSuccessor(SuccNum), AllowIdenticalEdges);
9909467b48Spatrick }
10009467b48Spatrick 
isCriticalEdge(const Instruction * TI,const BasicBlock * Dest,bool AllowIdenticalEdges)10109467b48Spatrick bool llvm::isCriticalEdge(const Instruction *TI, const BasicBlock *Dest,
10209467b48Spatrick                           bool AllowIdenticalEdges) {
10309467b48Spatrick   assert(TI->isTerminator() && "Must be a terminator to have successors!");
10409467b48Spatrick   if (TI->getNumSuccessors() == 1) return false;
10509467b48Spatrick 
10673471bf0Spatrick   assert(is_contained(predecessors(Dest), TI->getParent()) &&
10709467b48Spatrick          "No edge between TI's block and Dest.");
10809467b48Spatrick 
10909467b48Spatrick   const_pred_iterator I = pred_begin(Dest), E = pred_end(Dest);
11009467b48Spatrick 
11109467b48Spatrick   // If there is more than one predecessor, this is a critical edge...
11209467b48Spatrick   assert(I != E && "No preds, but we have an edge to the block?");
11309467b48Spatrick   const BasicBlock *FirstPred = *I;
11409467b48Spatrick   ++I;        // Skip one edge due to the incoming arc from TI.
11509467b48Spatrick   if (!AllowIdenticalEdges)
11609467b48Spatrick     return I != E;
11709467b48Spatrick 
11809467b48Spatrick   // If AllowIdenticalEdges is true, then we allow this edge to be considered
11909467b48Spatrick   // non-critical iff all preds come from TI's block.
12009467b48Spatrick   for (; I != E; ++I)
12109467b48Spatrick     if (*I != FirstPred)
12209467b48Spatrick       return true;
12309467b48Spatrick   return false;
12409467b48Spatrick }
12509467b48Spatrick 
12609467b48Spatrick // LoopInfo contains a mapping from basic block to the innermost loop. Find
12709467b48Spatrick // the outermost loop in the loop nest that contains BB.
getOutermostLoop(const LoopInfo * LI,const BasicBlock * BB)12809467b48Spatrick static const Loop *getOutermostLoop(const LoopInfo *LI, const BasicBlock *BB) {
12909467b48Spatrick   const Loop *L = LI->getLoopFor(BB);
130*d415bd75Srobert   return L ? L->getOutermostLoop() : nullptr;
13109467b48Spatrick }
13209467b48Spatrick 
isPotentiallyReachableFromMany(SmallVectorImpl<BasicBlock * > & Worklist,const BasicBlock * StopBB,const SmallPtrSetImpl<BasicBlock * > * ExclusionSet,const DominatorTree * DT,const LoopInfo * LI)13309467b48Spatrick bool llvm::isPotentiallyReachableFromMany(
134*d415bd75Srobert     SmallVectorImpl<BasicBlock *> &Worklist, const BasicBlock *StopBB,
13509467b48Spatrick     const SmallPtrSetImpl<BasicBlock *> *ExclusionSet, const DominatorTree *DT,
13609467b48Spatrick     const LoopInfo *LI) {
13709467b48Spatrick   // When the stop block is unreachable, it's dominated from everywhere,
13809467b48Spatrick   // regardless of whether there's a path between the two blocks.
13909467b48Spatrick   if (DT && !DT->isReachableFromEntry(StopBB))
14009467b48Spatrick     DT = nullptr;
14109467b48Spatrick 
14209467b48Spatrick   // We can't skip directly from a block that dominates the stop block if the
14309467b48Spatrick   // exclusion block is potentially in between.
14409467b48Spatrick   if (ExclusionSet && !ExclusionSet->empty())
14509467b48Spatrick     DT = nullptr;
14609467b48Spatrick 
14709467b48Spatrick   // Normally any block in a loop is reachable from any other block in a loop,
14809467b48Spatrick   // however excluded blocks might partition the body of a loop to make that
14909467b48Spatrick   // untrue.
15009467b48Spatrick   SmallPtrSet<const Loop *, 8> LoopsWithHoles;
15109467b48Spatrick   if (LI && ExclusionSet) {
152*d415bd75Srobert     for (auto *BB : *ExclusionSet) {
15309467b48Spatrick       if (const Loop *L = getOutermostLoop(LI, BB))
15409467b48Spatrick         LoopsWithHoles.insert(L);
15509467b48Spatrick     }
15609467b48Spatrick   }
15709467b48Spatrick 
15809467b48Spatrick   const Loop *StopLoop = LI ? getOutermostLoop(LI, StopBB) : nullptr;
15909467b48Spatrick 
16073471bf0Spatrick   unsigned Limit = DefaultMaxBBsToExplore;
16109467b48Spatrick   SmallPtrSet<const BasicBlock*, 32> Visited;
16209467b48Spatrick   do {
16309467b48Spatrick     BasicBlock *BB = Worklist.pop_back_val();
16409467b48Spatrick     if (!Visited.insert(BB).second)
16509467b48Spatrick       continue;
16609467b48Spatrick     if (BB == StopBB)
16709467b48Spatrick       return true;
16809467b48Spatrick     if (ExclusionSet && ExclusionSet->count(BB))
16909467b48Spatrick       continue;
17009467b48Spatrick     if (DT && DT->dominates(BB, StopBB))
17109467b48Spatrick       return true;
17209467b48Spatrick 
17309467b48Spatrick     const Loop *Outer = nullptr;
17409467b48Spatrick     if (LI) {
17509467b48Spatrick       Outer = getOutermostLoop(LI, BB);
17609467b48Spatrick       // If we're in a loop with a hole, not all blocks in the loop are
17709467b48Spatrick       // reachable from all other blocks. That implies we can't simply jump to
17809467b48Spatrick       // the loop's exit blocks, as that exit might need to pass through an
17909467b48Spatrick       // excluded block. Clear Outer so we process BB's successors.
18009467b48Spatrick       if (LoopsWithHoles.count(Outer))
18109467b48Spatrick         Outer = nullptr;
18209467b48Spatrick       if (StopLoop && Outer == StopLoop)
18309467b48Spatrick         return true;
18409467b48Spatrick     }
18509467b48Spatrick 
18609467b48Spatrick     if (!--Limit) {
18709467b48Spatrick       // We haven't been able to prove it one way or the other. Conservatively
18809467b48Spatrick       // answer true -- that there is potentially a path.
18909467b48Spatrick       return true;
19009467b48Spatrick     }
19109467b48Spatrick 
19209467b48Spatrick     if (Outer) {
19309467b48Spatrick       // All blocks in a single loop are reachable from all other blocks. From
19409467b48Spatrick       // any of these blocks, we can skip directly to the exits of the loop,
19509467b48Spatrick       // ignoring any other blocks inside the loop body.
19609467b48Spatrick       Outer->getExitBlocks(Worklist);
19709467b48Spatrick     } else {
19809467b48Spatrick       Worklist.append(succ_begin(BB), succ_end(BB));
19909467b48Spatrick     }
20009467b48Spatrick   } while (!Worklist.empty());
20109467b48Spatrick 
20209467b48Spatrick   // We have exhausted all possible paths and are certain that 'To' can not be
20309467b48Spatrick   // reached from 'From'.
20409467b48Spatrick   return false;
20509467b48Spatrick }
20609467b48Spatrick 
isPotentiallyReachable(const BasicBlock * A,const BasicBlock * B,const SmallPtrSetImpl<BasicBlock * > * ExclusionSet,const DominatorTree * DT,const LoopInfo * LI)20773471bf0Spatrick bool llvm::isPotentiallyReachable(
20873471bf0Spatrick     const BasicBlock *A, const BasicBlock *B,
20973471bf0Spatrick     const SmallPtrSetImpl<BasicBlock *> *ExclusionSet, const DominatorTree *DT,
21073471bf0Spatrick     const LoopInfo *LI) {
21109467b48Spatrick   assert(A->getParent() == B->getParent() &&
21209467b48Spatrick          "This analysis is function-local!");
21309467b48Spatrick 
21473471bf0Spatrick   if (DT) {
21573471bf0Spatrick     if (DT->isReachableFromEntry(A) && !DT->isReachableFromEntry(B))
21673471bf0Spatrick       return false;
21773471bf0Spatrick     if (!ExclusionSet || ExclusionSet->empty()) {
21873471bf0Spatrick       if (A->isEntryBlock() && DT->isReachableFromEntry(B))
21973471bf0Spatrick         return true;
22073471bf0Spatrick       if (B->isEntryBlock() && DT->isReachableFromEntry(A))
22173471bf0Spatrick         return false;
22273471bf0Spatrick     }
22373471bf0Spatrick   }
22473471bf0Spatrick 
22509467b48Spatrick   SmallVector<BasicBlock*, 32> Worklist;
22609467b48Spatrick   Worklist.push_back(const_cast<BasicBlock*>(A));
22709467b48Spatrick 
228*d415bd75Srobert   return isPotentiallyReachableFromMany(Worklist, B, ExclusionSet, DT, LI);
22909467b48Spatrick }
23009467b48Spatrick 
isPotentiallyReachable(const Instruction * A,const Instruction * B,const SmallPtrSetImpl<BasicBlock * > * ExclusionSet,const DominatorTree * DT,const LoopInfo * LI)23109467b48Spatrick bool llvm::isPotentiallyReachable(
23209467b48Spatrick     const Instruction *A, const Instruction *B,
23309467b48Spatrick     const SmallPtrSetImpl<BasicBlock *> *ExclusionSet, const DominatorTree *DT,
23409467b48Spatrick     const LoopInfo *LI) {
23509467b48Spatrick   assert(A->getParent()->getParent() == B->getParent()->getParent() &&
23609467b48Spatrick          "This analysis is function-local!");
23709467b48Spatrick 
23809467b48Spatrick   if (A->getParent() == B->getParent()) {
23909467b48Spatrick     // The same block case is special because it's the only time we're looking
24009467b48Spatrick     // within a single block to see which instruction comes first. Once we
24109467b48Spatrick     // start looking at multiple blocks, the first instruction of the block is
24209467b48Spatrick     // reachable, so we only need to determine reachability between whole
24309467b48Spatrick     // blocks.
24409467b48Spatrick     BasicBlock *BB = const_cast<BasicBlock *>(A->getParent());
24509467b48Spatrick 
24609467b48Spatrick     // If the block is in a loop then we can reach any instruction in the block
24709467b48Spatrick     // from any other instruction in the block by going around a backedge.
24809467b48Spatrick     if (LI && LI->getLoopFor(BB) != nullptr)
24909467b48Spatrick       return true;
25009467b48Spatrick 
25173471bf0Spatrick     // If A comes before B, then B is definitively reachable from A.
25273471bf0Spatrick     if (A == B || A->comesBefore(B))
25309467b48Spatrick       return true;
25409467b48Spatrick 
25509467b48Spatrick     // Can't be in a loop if it's the entry block -- the entry block may not
25609467b48Spatrick     // have predecessors.
25773471bf0Spatrick     if (BB->isEntryBlock())
25809467b48Spatrick       return false;
25909467b48Spatrick 
26009467b48Spatrick     // Otherwise, continue doing the normal per-BB CFG walk.
26173471bf0Spatrick     SmallVector<BasicBlock*, 32> Worklist;
26209467b48Spatrick     Worklist.append(succ_begin(BB), succ_end(BB));
26309467b48Spatrick     if (Worklist.empty()) {
26409467b48Spatrick       // We've proven that there's no path!
26509467b48Spatrick       return false;
26609467b48Spatrick     }
26709467b48Spatrick 
268*d415bd75Srobert     return isPotentiallyReachableFromMany(Worklist, B->getParent(),
269*d415bd75Srobert                                           ExclusionSet, DT, LI);
27073471bf0Spatrick   }
27173471bf0Spatrick 
27273471bf0Spatrick   return isPotentiallyReachable(
27373471bf0Spatrick       A->getParent(), B->getParent(), ExclusionSet, DT, LI);
27409467b48Spatrick }
275