xref: /freebsd-src/contrib/llvm-project/llvm/lib/Analysis/CFG.cpp (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
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