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