24 #ifndef LLVM_ANALYSIS_LOOPITERATOR_H 25 #define LLVM_ANALYSIS_LOOPITERATOR_H 32 class LoopBlocksTraversal;
42 using NodeRef = std::pair<const Loop *, BasicBlock *>;
48 WrappedSuccIterator, succ_iterator,
49 typename std::iterator_traits<succ_iterator>::iterator_category,
50 NodeRef, std::ptrdiff_t, NodeRef *, NodeRef> {
53 typename std::iterator_traits<succ_iterator>::iterator_category,
54 NodeRef, std::ptrdiff_t, NodeRef *, NodeRef>;
60 :
BaseT(Begin), L(L) {}
67 const Loop *L = N.first;
80 {
succ_end(Node.second), Node.first}),
88 {
succ_end(Node.second), Node.first}),
102 typedef std::vector<BasicBlock*>::const_reverse_iterator
RPOIterator;
113 std::vector<BasicBlock*> PostBlocks;
117 L(Container), PostNumbers(
NextPowerOf2(Container->getNumBlocks())) {
131 assert(isComplete() &&
"bad loop DFS");
132 return PostBlocks.begin();
138 assert(isComplete() &&
"bad loop DFS");
139 return PostBlocks.rbegin();
141 RPOIterator
endRPO()
const {
return PostBlocks.rend(); }
149 return I != PostNumbers.
end() && I->second;
155 assert(I != PostNumbers.
end() &&
"block not visited by DFS");
156 assert(I->second &&
"block not finished by DFS");
162 return 1 + PostBlocks.size() - getPostorder(BB);
212 DFS(Storage), LI(LInfo) {}
218 assert(DFS.PostBlocks.empty() &&
"Need clear DFS result before traversing");
236 return DFS.PostNumbers.
insert(std::make_pair(BB, 0)).second;
242 assert(DFS.PostNumbers.
count(BB) &&
"Loop DFS skipped preorder");
243 DFS.PostBlocks.push_back(BB);
244 DFS.PostNumbers[BB] = DFS.PostBlocks.size();
250 return LBT.visitPreorder(To);
255 LBT.finishPostorder(BB);
bool hasPostorder(BasicBlock *BB) const
Return true if this block has a postorder number.
po_ext_iterator< T, SetType > po_ext_end(T G, SetType &S)
const_iterator end(StringRef path)
Get end iterator over path.
const_iterator begin(StringRef path, Style style=Style::native)
Get begin iterator over path.
This class represents lattice values for constants.
LoopBlocksDFS(Loop *Container)
block Block Frequency true
bool isComplete() const
Return true if postorder numbers are assigned to all loop blocks.
std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)
Traverse the blocks in a loop using a depth-first search.
po_iterator_storage(LoopBlocksTraversal &lbs)
POIterator beginPostorder() const
Iterate over the cached postorder blocks.
LoopT * getLoopFor(const BlockT *BB) const
Return the inner most loop that BB lives in.
POTIterator begin()
Postorder traversal over the graph.
bool hasPreorder(BasicBlock *BB) const
Return true if this block has been preorder visited.
void finishPostorder(NodeRef BB)
RPOIterator endRPO() const
BlockT * getHeader() const
Interval::succ_iterator succ_begin(Interval *I)
succ_begin/succ_end - define methods so that Intervals may be used just like BasicBlocks can with the...
void perform(LoopInfo *LI)
Traverse the loop blocks and store the DFS result.
static ChildIteratorType child_end(NodeRef Node)
Interval::succ_iterator succ_end(Interval *I)
iterator find(const_arg_type_t< KeyT > Val)
po_iterator< BasicBlock *, LoopBlocksTraversal, true > POTIterator
Graph traversal iterator.
std::pair< const Loop *, BasicBlock * > NodeRef
NodeRef operator*() const
LLVM Basic Block Representation.
LoopBlocksDFS::RPOIterator begin() const
Reverse iterate over the cached postorder blocks.
CRTP base class for adapting an iterator to a different type.
WrappedSuccIterator(succ_iterator Begin, const Loop *L)
Default po_iterator_storage implementation with an internal set object.
std::vector< BasicBlock * >::const_reverse_iterator RPOIterator
void reserve(size_type NumEntries)
Grow the densemap so that it can contain at least NumEntries items before resizing again...
bool insertEdge(Optional< NodeRef > From, NodeRef To)
static NodeRef getEntryNode(const Loop &G)
uint64_t NextPowerOf2(uint64_t A)
Returns the next power of two (in 64-bits) that is strictly greater than A.
bool contains(const LoopT *L) const
Return true if the specified loop is contained within in this loop.
unsigned getRPO(BasicBlock *BB) const
Get a block's reverse postorder number.
BlockVerifier::State From
static ChildIteratorType child_begin(NodeRef Node)
bool visitPreorder(BasicBlock *BB)
Called by po_iterator upon reaching a block via a CFG edge.
Store the result of a depth first search within basic blocks contained by a single loop...
POIterator endPostorder() const
unsigned getNumBlocks() const
Get the number of blocks in this loop in constant time.
SuccIterator< Instruction, BasicBlock > succ_iterator
Represents a single loop in the control flow graph.
po_ext_iterator< T, SetType > po_ext_begin(T G, SetType &S)
std::vector< BasicBlock * >::const_iterator POIterator
Postorder list iterators.
LoopBlocksRPO(Loop *Container)
LoopBlocksTraversal(LoopBlocksDFS &Storage, LoopInfo *LInfo)
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...
size_type count(const_arg_type_t< KeyT > Val) const
Return 1 if the specified key is in the map, 0 otherwise.
Wrapper class to LoopBlocksDFS that provides a standard begin()/end() interface for the DFS reverse p...
void finishPostorder(BasicBlock *BB)
Called by po_iterator each time it advances, indicating a block's postorder.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
RPOIterator beginRPO() const
Reverse iterate over the cached postorder blocks.
Specialization of filter_iterator_base for forward iteration only.
unsigned getPostorder(BasicBlock *BB) const
Get a block's postorder number.
void perform(LoopInfo *LI)
Traverse the loop blocks and store the DFS result.
LoopBlocksDFS::RPOIterator end() const
bool operator()(NodeRef N) const