LLVM: lib/Analysis/CFG.cpp Source File (original) (raw)
1
2
3
4
5
6
7
8
9
10
11
12
13
18
19using namespace llvm;
20
21
22
23
25 "dom-tree-reachability-max-bbs-to-explore", cl::Hidden,
26 cl::desc("Max number of BBs to explore for reachability analysis"),
28
29
30
31
32
33
35 SmallVectorImpl<std::pair<const BasicBlock*,const BasicBlock*> > &Result) {
36 const BasicBlock *BB = &F.getEntryBlock();
38 return;
39
43
47 do {
48 std::pair<const BasicBlock *, const_succ_iterator> &Top = VisitStack.back();
49 const BasicBlock *ParentBB = Top.first;
51
52 bool FoundNew = false;
54 BB = *I++;
55 if (Visited.insert(BB).second) {
56 FoundNew = true;
57 break;
58 }
59
60 if (InStack.count(BB))
61 Result.push_back(std::make_pair(ParentBB, BB));
62 }
63
64 if (FoundNew) {
65
68 } else {
69
71 }
72 } while (!VisitStack.empty());
73}
74
75
76
77
78
82#ifndef NDEBUG
83 unsigned e = Term->getNumSuccessors();
84#endif
85 for (unsigned i = 0; ; ++i) {
86 assert(i != e && "Didn't find edge?");
87 if (Term->getSuccessor(i) == Succ)
88 return i;
89 }
90}
91
92
93
94
96 bool AllowIdenticalEdges) {
97 assert(SuccNum < TI->getNumSuccessors() && "Illegal edge specification!");
99}
100
102 bool AllowIdenticalEdges) {
103 assert(TI->isTerminator() && "Must be a terminator to have successors!");
105
107 "No edge between TI's block and Dest.");
108
110
111
112 assert(I != E && "No preds, but we have an edge to the block?");
114 ++I;
115 if (!AllowIdenticalEdges)
116 return I != E;
117
118
119
121 if (*I != FirstPred)
122 return true;
123 return false;
124}
125
126
127
130 return L ? L->getOutermostLoop() : nullptr;
131}
132
133template
135 const StopSetT &StopSet,
138
139
140 if (DT) {
141 for (auto *BB : StopSet) {
143 DT = nullptr;
144 break;
145 }
146 }
147 }
148
149
150
151 if (ExclusionSet && !ExclusionSet->empty())
152 DT = nullptr;
153
154
155
156
158 if (LI && ExclusionSet) {
159 for (auto *BB : *ExclusionSet) {
161 LoopsWithHoles.insert(L);
162 }
163 }
164
166 if (LI) {
167 for (auto *StopSetBB : StopSet) {
170 }
171 }
172
175 do {
177 if (!Visited.insert(BB).second)
178 continue;
179 if (StopSet.contains(BB))
180 return true;
181 if (ExclusionSet && ExclusionSet->count(BB))
182 continue;
183 if (DT) {
185 return DT->dominates(BB, StopBB);
186 }))
187 return true;
188 }
189
190 const Loop *Outer = nullptr;
191 if (LI) {
193
194
195
196
197 if (LoopsWithHoles.count(Outer))
198 Outer = nullptr;
199 if (StopLoops.contains(Outer))
200 return true;
201 }
202
203 if (!--Limit) {
204
205
206 return true;
207 }
208
209 if (Outer) {
210
211
212
213 Outer->getExitBlocks(Worklist);
214 } else {
216 }
217 } while (!Worklist.empty());
218
219
220
221 return false;
222}
223
225public:
227
229
231
234
235private:
236 T Elem;
237};
238
243 return isReachableImpl<SingleEntrySet<const BasicBlock *>>(
245 LI);
246}
247
253 return isReachableImpl<SmallPtrSetImpl<const BasicBlock *>>(
254 Worklist, StopSet, ExclusionSet, DT, LI);
255}
256
261 assert(A->getParent() == B->getParent() &&
262 "This analysis is function-local!");
263
264 if (DT) {
266 return false;
267 if (!ExclusionSet || ExclusionSet->empty()) {
269 return true;
271 return false;
272 }
273 }
274
277
279}
280
285 assert(A->getParent()->getParent() == B->getParent()->getParent() &&
286 "This analysis is function-local!");
287
288 if (A->getParent() == B->getParent()) {
289
290
291
292
293
295
296
297
298 if (LI && LI->getLoopFor(BB) != nullptr)
299 return true;
300
301
302 if (A == B || A->comesBefore(B))
303 return true;
304
305
306
308 return false;
309
310
313 if (Worklist.empty()) {
314
315 return false;
316 }
317
319 ExclusionSet, DT, LI);
320 }
321
323 A->getParent(), B->getParent(), ExclusionSet, DT, LI);
324}
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static cl::opt< unsigned > DefaultMaxBBsToExplore("dom-tree-reachability-max-bbs-to-explore", cl::Hidden, cl::desc("Max number of BBs to explore for reachability analysis"), cl::init(32))
static bool isReachableImpl(SmallVectorImpl< BasicBlock * > &Worklist, const StopSetT &StopSet, const SmallPtrSetImpl< BasicBlock * > *ExclusionSet, const DominatorTree *DT, const LoopInfo *LI)
static const Loop * getOutermostLoop(const LoopInfo *LI, const BasicBlock *BB)
std::optional< std::vector< StOtherPiece > > Other
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
const_iterator end() const
const_iterator begin() const
bool contains(T Other) const
LLVM Basic Block Representation.
bool isEntryBlock() const
Return true if this is the entry block of the containing function.
const Instruction * getTerminator() const LLVM_READONLY
Returns the terminator instruction if the block is well formed or null if the block is not well forme...
Concrete subclass of DominatorTreeBase that is used to compute a normal dominator tree.
bool isReachableFromEntry(const Use &U) const
Provide an overload for a Use.
bool dominates(const BasicBlock *BB, const Use &U) const
Return true if the (end of the) basic block BB dominates the use U.
unsigned getNumSuccessors() const LLVM_READONLY
Return the number of successors that this instruction has.
BasicBlock * getSuccessor(unsigned Idx) const LLVM_READONLY
Return the specified successor. This instruction must be a terminator.
bool isTerminator() const
LoopT * getLoopFor(const BlockT *BB) const
Return the inner most loop that BB lives in.
Represents a single loop in the control flow graph.
A templated base class for SmallPtrSet which provides the typesafe interface that is common across al...
bool erase(PtrType Ptr)
Remove pointer from the set.
size_type count(ConstPtrType Ptr) const
count - Return 1 if the specified pointer is in the set, 0 otherwise.
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
bool contains(ConstPtrType Ptr) const
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
void append(ItTy in_start, ItTy in_end)
Add the specified range to the end of the SmallVector.
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
const ParentTy * getParent() const
initializer< Ty > init(const Ty &Val)
This is an optimization pass for GlobalISel generic memory operations.
bool succ_empty(const Instruction *I)
unsigned GetSuccessorNumber(const BasicBlock *BB, const BasicBlock *Succ)
Search for the specified successor of basic block BB and return its position in the terminator instru...
auto pred_end(const MachineBasicBlock *BB)
bool isPotentiallyReachableFromMany(SmallVectorImpl< BasicBlock * > &Worklist, const BasicBlock *StopBB, const SmallPtrSetImpl< BasicBlock * > *ExclusionSet, const DominatorTree *DT=nullptr, const LoopInfo *LI=nullptr)
Determine whether there is at least one path from a block in 'Worklist' to 'StopBB' without passing t...
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
bool isManyPotentiallyReachableFromMany(SmallVectorImpl< BasicBlock * > &Worklist, const SmallPtrSetImpl< const BasicBlock * > &StopSet, const SmallPtrSetImpl< BasicBlock * > *ExclusionSet, const DominatorTree *DT=nullptr, const LoopInfo *LI=nullptr)
Determine whether there is a potentially a path from at least one block in 'Worklist' to at least one...
RNSuccIterator< NodeRef, BlockT, RegionT > succ_begin(NodeRef Node)
RNSuccIterator< NodeRef, BlockT, RegionT > succ_end(NodeRef Node)
bool isCriticalEdge(const Instruction *TI, unsigned SuccNum, bool AllowIdenticalEdges=false)
Return true if the specified edge is a critical edge.
auto pred_begin(const MachineBasicBlock *BB)
auto predecessors(const MachineBasicBlock *BB)
bool is_contained(R &&Range, const E &Element)
Returns true if Element is found in Range.
void FindFunctionBackedges(const Function &F, SmallVectorImpl< std::pair< const BasicBlock *, const BasicBlock * > > &Result)
Analyze the specified function to find all of the loop backedges in the function and return them.
bool isPotentiallyReachable(const Instruction *From, const Instruction *To, const SmallPtrSetImpl< BasicBlock * > *ExclusionSet=nullptr, const DominatorTree *DT=nullptr, const LoopInfo *LI=nullptr)
Determine whether instruction 'To' is reachable from 'From', without passing through any blocks in Ex...