LLVM: include/llvm/Analysis/LoopIterator.h Source File (original) (raw)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23#ifndef LLVM_ANALYSIS_LOOPITERATOR_H
24#define LLVM_ANALYSIS_LOOPITERATOR_H
25
28
29namespace llvm {
30
31class LoopBlocksTraversal;
32
33
34
35
36
37
38
39
41 using NodeRef = std::pair<const Loop *, BasicBlock *>;
42
43
44
47 WrappedSuccIterator, succ_iterator,
48 typename std::iterator_traits<succ_iterator>::iterator_category,
49 NodeRef, std::ptrdiff_t, NodeRef *, NodeRef> {
52 typename std::iterator_traits<succ_iterator>::iterator_category,
54
55 const Loop *L;
56
57 public:
59 : BaseT(Begin), L(L) {}
60
62 };
63
67 return N.second != L->getHeader() && L->contains(N.second);
68 }
69 };
70
73
75
81 .begin();
82 }
83
89 .end();
90 }
91};
92
93
94
95
96
98public:
99
100 typedef std::vector<BasicBlock*>::const_iterator POIterator;
101 typedef std::vector<BasicBlock*>::const_reverse_iterator RPOIterator;
102
104
105private:
107
108
109
110
112 std::vector<BasicBlock*> PostBlocks;
113
114public:
116 L(Container), PostNumbers(NextPowerOf2(Container->getNumBlocks())) {
118 }
119
121
122
124
125
126 bool isComplete() const { return PostBlocks.size() == L->getNumBlocks(); }
127
128
131 return PostBlocks.begin();
132 }
134
135
138 return PostBlocks.rbegin();
139 }
141
142
144
145
148 return I != PostNumbers.end() && I->second;
149 }
150
151
154 assert(I != PostNumbers.end() && "block not visited by DFS");
155 assert(I->second && "block not finished by DFS");
156 return I->second;
157 }
158
159
161 return 1 + PostBlocks.size() - getPostorder(BB);
162 }
163
165 PostNumbers.clear();
166 PostBlocks.clear();
167 }
168};
169
170
171
173private:
175
176public:
178
179
182 }
183
184
187};
188
189
192public:
194
197};
198
199
201public:
202
204
205private:
208
209public:
211 DFS(Storage), LI(LInfo) {}
212
213
214
215
217 assert(DFS.PostBlocks.empty() && "Need clear DFS result before traversing");
218 assert(DFS.L->getNumBlocks() && "po_iterator cannot handle an empty graph");
220 }
222
224 }
225
226
227
228
229
230
233 return false;
234
235 return DFS.PostNumbers.insert(std::make_pair(BB, 0)).second;
236 }
237
238
239
241 assert(DFS.PostNumbers.count(BB) && "Loop DFS skipped preorder");
242 DFS.PostBlocks.push_back(BB);
243 DFS.PostNumbers[BB] = DFS.PostBlocks.size();
244 }
245};
246
249 return LBT.visitPreorder(To);
250}
251
254 LBT.finishPostorder(BB);
255}
256
257}
258
259#endif
BlockVerifier::State From
This file builds on the ADT/GraphTraits.h file to build a generic graph post order iterator.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
LLVM Basic Block Representation.
iterator find(const_arg_type_t< KeyT > Val)
size_type count(const_arg_type_t< KeyT > Val) const
Return 1 if the specified key is in the map, 0 otherwise.
void reserve(size_type NumEntries)
Grow the densemap so that it can contain at least NumEntries items before resizing again.
bool contains(const LoopT *L) const
Return true if the specified loop is contained within in this loop.
unsigned getNumBlocks() const
Get the number of blocks in this loop in constant time.
BlockT * getHeader() const
Store the result of a depth first search within basic blocks contained by a single loop.
RPOIterator beginRPO() const
Reverse iterate over the cached postorder blocks.
bool hasPreorder(BasicBlock *BB) const
Return true if this block has been preorder visited.
unsigned getPostorder(BasicBlock *BB) const
Get a block's postorder number.
std::vector< BasicBlock * >::const_reverse_iterator RPOIterator
bool hasPostorder(BasicBlock *BB) const
Return true if this block has a postorder number.
unsigned getRPO(BasicBlock *BB) const
Get a block's reverse postorder number.
LoopBlocksDFS(Loop *Container)
bool isComplete() const
Return true if postorder numbers are assigned to all loop blocks.
POIterator beginPostorder() const
Iterate over the cached postorder blocks.
POIterator endPostorder() const
std::vector< BasicBlock * >::const_iterator POIterator
Postorder list iterators.
void perform(const LoopInfo *LI)
Traverse the loop blocks and store the DFS result.
RPOIterator endRPO() const
Wrapper class to LoopBlocksDFS that provides a standard begin()/end() interface for the DFS reverse p...
LoopBlocksDFS::RPOIterator end() const
LoopBlocksDFS::RPOIterator begin() const
Reverse iterate over the cached postorder blocks.
LoopBlocksRPO(Loop *Container)
void perform(const LoopInfo *LI)
Traverse the loop blocks and store the DFS result.
Traverse the blocks in a loop using a depth-first search.
bool visitPreorder(BasicBlock *BB)
Called by po_iterator upon reaching a block via a CFG edge.
void finishPostorder(BasicBlock *BB)
Called by po_iterator each time it advances, indicating a block's postorder.
LoopBlocksTraversal(LoopBlocksDFS &Storage, const LoopInfo *LInfo)
po_iterator< BasicBlock *, LoopBlocksTraversal, true > POTIterator
Graph traversal iterator.
POTIterator begin()
Postorder traversal over the graph.
NodeRef operator*() const
WrappedSuccIterator(succ_iterator Begin, const Loop *L)
LoopT * getLoopFor(const BlockT *BB) const
Return the inner most loop that BB lives in.
Represents a single loop in the control flow graph.
Specialization of filter_iterator_base for forward iteration only.
CRTP base class for adapting an iterator to a different type.
po_iterator_storage(LoopBlocksTraversal &lbs)
Default po_iterator_storage implementation with an internal set object.
bool insertEdge(std::optional< NodeRef > From, NodeRef To)
void finishPostorder(NodeRef BB)
This is an optimization pass for GlobalISel generic memory operations.
po_ext_iterator< T, SetType > po_ext_end(T G, SetType &S)
SuccIterator< Instruction, BasicBlock > succ_iterator
iterator_range< filter_iterator< detail::IterOfRange< RangeT >, PredicateT > > make_filter_range(RangeT &&Range, PredicateT Pred)
Convenience function that takes a range of elements and a predicate, and return a new filter_iterator...
RNSuccIterator< NodeRef, BlockT, RegionT > succ_begin(NodeRef Node)
RNSuccIterator< NodeRef, BlockT, RegionT > succ_end(NodeRef Node)
po_ext_iterator< T, SetType > po_ext_begin(T G, SetType &S)
constexpr uint64_t NextPowerOf2(uint64_t A)
Returns the next power of two (in 64-bits) that is strictly greater than A.
bool operator()(NodeRef N) const
static ChildIteratorType child_end(NodeRef Node)
std::pair< const Loop *, BasicBlock * > NodeRef
static ChildIteratorType child_begin(NodeRef Node)
static NodeRef getEntryNode(const Loop &G)