xref: /freebsd/contrib/llvm-project/llvm/lib/Analysis/CFG.cpp (revision 480093f4440d54b30b3025afeac24b48f2ba7a2e)
1 //===-- CFG.cpp - BasicBlock analysis --------------------------------------==//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This family of functions performs analyses on basic blocks, and instructions
10 // contained within basic blocks.
11 //
12 //===----------------------------------------------------------------------===//
13 
14 #include "llvm/Analysis/CFG.h"
15 #include "llvm/ADT/SmallPtrSet.h"
16 #include "llvm/ADT/SmallSet.h"
17 #include "llvm/Analysis/LoopInfo.h"
18 #include "llvm/IR/Dominators.h"
19 
20 using namespace llvm;
21 
22 /// FindFunctionBackedges - Analyze the specified function to find all of the
23 /// loop backedges in the function and return them.  This is a relatively cheap
24 /// (compared to computing dominators and loop info) analysis.
25 ///
26 /// The output is added to Result, as pairs of <from,to> edge info.
27 void llvm::FindFunctionBackedges(const Function &F,
28      SmallVectorImpl<std::pair<const BasicBlock*,const BasicBlock*> > &Result) {
29   const BasicBlock *BB = &F.getEntryBlock();
30   if (succ_empty(BB))
31     return;
32 
33   SmallPtrSet<const BasicBlock*, 8> Visited;
34   SmallVector<std::pair<const BasicBlock*, succ_const_iterator>, 8> VisitStack;
35   SmallPtrSet<const BasicBlock*, 8> InStack;
36 
37   Visited.insert(BB);
38   VisitStack.push_back(std::make_pair(BB, succ_begin(BB)));
39   InStack.insert(BB);
40   do {
41     std::pair<const BasicBlock*, succ_const_iterator> &Top = VisitStack.back();
42     const BasicBlock *ParentBB = Top.first;
43     succ_const_iterator &I = Top.second;
44 
45     bool FoundNew = false;
46     while (I != succ_end(ParentBB)) {
47       BB = *I++;
48       if (Visited.insert(BB).second) {
49         FoundNew = true;
50         break;
51       }
52       // Successor is in VisitStack, it's a back edge.
53       if (InStack.count(BB))
54         Result.push_back(std::make_pair(ParentBB, BB));
55     }
56 
57     if (FoundNew) {
58       // Go down one level if there is a unvisited successor.
59       InStack.insert(BB);
60       VisitStack.push_back(std::make_pair(BB, succ_begin(BB)));
61     } else {
62       // Go up one level.
63       InStack.erase(VisitStack.pop_back_val().first);
64     }
65   } while (!VisitStack.empty());
66 }
67 
68 /// GetSuccessorNumber - Search for the specified successor of basic block BB
69 /// and return its position in the terminator instruction's list of
70 /// successors.  It is an error to call this with a block that is not a
71 /// successor.
72 unsigned llvm::GetSuccessorNumber(const BasicBlock *BB,
73     const BasicBlock *Succ) {
74   const Instruction *Term = BB->getTerminator();
75 #ifndef NDEBUG
76   unsigned e = Term->getNumSuccessors();
77 #endif
78   for (unsigned i = 0; ; ++i) {
79     assert(i != e && "Didn't find edge?");
80     if (Term->getSuccessor(i) == Succ)
81       return i;
82   }
83 }
84 
85 /// isCriticalEdge - Return true if the specified edge is a critical edge.
86 /// Critical edges are edges from a block with multiple successors to a block
87 /// with multiple predecessors.
88 bool llvm::isCriticalEdge(const Instruction *TI, unsigned SuccNum,
89                           bool AllowIdenticalEdges) {
90   assert(SuccNum < TI->getNumSuccessors() && "Illegal edge specification!");
91   return isCriticalEdge(TI, TI->getSuccessor(SuccNum), AllowIdenticalEdges);
92 }
93 
94 bool llvm::isCriticalEdge(const Instruction *TI, const BasicBlock *Dest,
95                           bool AllowIdenticalEdges) {
96   assert(TI->isTerminator() && "Must be a terminator to have successors!");
97   if (TI->getNumSuccessors() == 1) return false;
98 
99   assert(find(predecessors(Dest), TI->getParent()) != pred_end(Dest) &&
100          "No edge between TI's block and Dest.");
101 
102   const_pred_iterator I = pred_begin(Dest), E = pred_end(Dest);
103 
104   // If there is more than one predecessor, this is a critical edge...
105   assert(I != E && "No preds, but we have an edge to the block?");
106   const BasicBlock *FirstPred = *I;
107   ++I;        // Skip one edge due to the incoming arc from TI.
108   if (!AllowIdenticalEdges)
109     return I != E;
110 
111   // If AllowIdenticalEdges is true, then we allow this edge to be considered
112   // non-critical iff all preds come from TI's block.
113   for (; I != E; ++I)
114     if (*I != FirstPred)
115       return true;
116   return false;
117 }
118 
119 // LoopInfo contains a mapping from basic block to the innermost loop. Find
120 // the outermost loop in the loop nest that contains BB.
121 static const Loop *getOutermostLoop(const LoopInfo *LI, const BasicBlock *BB) {
122   const Loop *L = LI->getLoopFor(BB);
123   if (L) {
124     while (const Loop *Parent = L->getParentLoop())
125       L = Parent;
126   }
127   return L;
128 }
129 
130 bool llvm::isPotentiallyReachableFromMany(
131     SmallVectorImpl<BasicBlock *> &Worklist, BasicBlock *StopBB,
132     const SmallPtrSetImpl<BasicBlock *> *ExclusionSet, const DominatorTree *DT,
133     const LoopInfo *LI) {
134   // When the stop block is unreachable, it's dominated from everywhere,
135   // regardless of whether there's a path between the two blocks.
136   if (DT && !DT->isReachableFromEntry(StopBB))
137     DT = nullptr;
138 
139   // We can't skip directly from a block that dominates the stop block if the
140   // exclusion block is potentially in between.
141   if (ExclusionSet && !ExclusionSet->empty())
142     DT = nullptr;
143 
144   // Normally any block in a loop is reachable from any other block in a loop,
145   // however excluded blocks might partition the body of a loop to make that
146   // untrue.
147   SmallPtrSet<const Loop *, 8> LoopsWithHoles;
148   if (LI && ExclusionSet) {
149     for (auto BB : *ExclusionSet) {
150       if (const Loop *L = getOutermostLoop(LI, BB))
151         LoopsWithHoles.insert(L);
152     }
153   }
154 
155   const Loop *StopLoop = LI ? getOutermostLoop(LI, StopBB) : nullptr;
156 
157   // Limit the number of blocks we visit. The goal is to avoid run-away compile
158   // times on large CFGs without hampering sensible code. Arbitrarily chosen.
159   unsigned Limit = 32;
160   SmallPtrSet<const BasicBlock*, 32> Visited;
161   do {
162     BasicBlock *BB = Worklist.pop_back_val();
163     if (!Visited.insert(BB).second)
164       continue;
165     if (BB == StopBB)
166       return true;
167     if (ExclusionSet && ExclusionSet->count(BB))
168       continue;
169     if (DT && DT->dominates(BB, StopBB))
170       return true;
171 
172     const Loop *Outer = nullptr;
173     if (LI) {
174       Outer = getOutermostLoop(LI, BB);
175       // If we're in a loop with a hole, not all blocks in the loop are
176       // reachable from all other blocks. That implies we can't simply jump to
177       // the loop's exit blocks, as that exit might need to pass through an
178       // excluded block. Clear Outer so we process BB's successors.
179       if (LoopsWithHoles.count(Outer))
180         Outer = nullptr;
181       if (StopLoop && Outer == StopLoop)
182         return true;
183     }
184 
185     if (!--Limit) {
186       // We haven't been able to prove it one way or the other. Conservatively
187       // answer true -- that there is potentially a path.
188       return true;
189     }
190 
191     if (Outer) {
192       // All blocks in a single loop are reachable from all other blocks. From
193       // any of these blocks, we can skip directly to the exits of the loop,
194       // ignoring any other blocks inside the loop body.
195       Outer->getExitBlocks(Worklist);
196     } else {
197       Worklist.append(succ_begin(BB), succ_end(BB));
198     }
199   } while (!Worklist.empty());
200 
201   // We have exhausted all possible paths and are certain that 'To' can not be
202   // reached from 'From'.
203   return false;
204 }
205 
206 bool llvm::isPotentiallyReachable(const BasicBlock *A, const BasicBlock *B,
207                                   const DominatorTree *DT, const LoopInfo *LI) {
208   assert(A->getParent() == B->getParent() &&
209          "This analysis is function-local!");
210 
211   SmallVector<BasicBlock*, 32> Worklist;
212   Worklist.push_back(const_cast<BasicBlock*>(A));
213 
214   return isPotentiallyReachableFromMany(Worklist, const_cast<BasicBlock *>(B),
215                                         nullptr, DT, LI);
216 }
217 
218 bool llvm::isPotentiallyReachable(
219     const Instruction *A, const Instruction *B,
220     const SmallPtrSetImpl<BasicBlock *> *ExclusionSet, const DominatorTree *DT,
221     const LoopInfo *LI) {
222   assert(A->getParent()->getParent() == B->getParent()->getParent() &&
223          "This analysis is function-local!");
224 
225   SmallVector<BasicBlock*, 32> Worklist;
226 
227   if (A->getParent() == B->getParent()) {
228     // The same block case is special because it's the only time we're looking
229     // within a single block to see which instruction comes first. Once we
230     // start looking at multiple blocks, the first instruction of the block is
231     // reachable, so we only need to determine reachability between whole
232     // blocks.
233     BasicBlock *BB = const_cast<BasicBlock *>(A->getParent());
234 
235     // If the block is in a loop then we can reach any instruction in the block
236     // from any other instruction in the block by going around a backedge.
237     if (LI && LI->getLoopFor(BB) != nullptr)
238       return true;
239 
240     // Linear scan, start at 'A', see whether we hit 'B' or the end first.
241     for (BasicBlock::const_iterator I = A->getIterator(), E = BB->end(); I != E;
242          ++I) {
243       if (&*I == B)
244         return true;
245     }
246 
247     // Can't be in a loop if it's the entry block -- the entry block may not
248     // have predecessors.
249     if (BB == &BB->getParent()->getEntryBlock())
250       return false;
251 
252     // Otherwise, continue doing the normal per-BB CFG walk.
253     Worklist.append(succ_begin(BB), succ_end(BB));
254 
255     if (Worklist.empty()) {
256       // We've proven that there's no path!
257       return false;
258     }
259   } else {
260     Worklist.push_back(const_cast<BasicBlock*>(A->getParent()));
261   }
262 
263   if (DT) {
264     if (DT->isReachableFromEntry(A->getParent()) &&
265         !DT->isReachableFromEntry(B->getParent()))
266       return false;
267     if (!ExclusionSet || ExclusionSet->empty()) {
268       if (A->getParent() == &A->getParent()->getParent()->getEntryBlock() &&
269           DT->isReachableFromEntry(B->getParent()))
270         return true;
271       if (B->getParent() == &A->getParent()->getParent()->getEntryBlock() &&
272           DT->isReachableFromEntry(A->getParent()))
273         return false;
274     }
275   }
276 
277   return isPotentiallyReachableFromMany(
278       Worklist, const_cast<BasicBlock *>(B->getParent()), ExclusionSet, DT, LI);
279 }
280