23#ifndef LLVM_ANALYSIS_LOOPITERATOR_H
24#define LLVM_ANALYSIS_LOOPITERATOR_H
40 typedef std::vector<BasicBlock*>::const_iterator
POIterator;
41 typedef std::vector<BasicBlock*>::const_reverse_iterator
RPOIterator;
52 std::vector<BasicBlock*> PostBlocks;
56 L(Container), PostNumbers(
NextPowerOf2(Container->getNumBlocks())) {
66 bool isComplete()
const {
return PostBlocks.size() == L->getNumBlocks(); }
71 return PostBlocks.begin();
78 return PostBlocks.rbegin();
87 auto I = PostNumbers.find(BB);
88 return I != PostNumbers.end() &&
I->second;
93 auto I = PostNumbers.find(BB);
94 assert(
I != PostNumbers.end() &&
"block not visited by DFS");
95 assert(
I->second &&
"block not finished by DFS");
132 GraphTraits<Function *>> {
138 : DFS(Storage), LI(LInfo) {}
144 assert(DFS.PostBlocks.empty() &&
"Need clear DFS result before traversing");
145 assert(DFS.L->getNumBlocks() &&
"cannot handle an empty graph");
146 init(DFS.L->getHeader());
157 if (!DFS.L->contains(LI->getLoopFor(BB)))
160 return DFS.PostNumbers.insert(std::make_pair(BB, 0)).second;
165 assert(DFS.PostNumbers.count(BB) &&
"Loop DFS skipped preorder");
166 DFS.PostBlocks.push_back(BB);
167 DFS.PostNumbers[BB] = DFS.PostBlocks.size();
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
This file builds on the ADT/GraphTraits.h file to build a generic graph post order iterator.
LLVM Basic Block Representation.
unsigned getNumBlocks() const
Get the number of blocks in this loop in constant time.
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)
friend class LoopBlocksTraversal
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.
LLVM_ABI void perform(const LoopInfo *LI)
Traverse the loop blocks and store the DFS result.
RPOIterator endRPO() const
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.
iterator begin()
Postorder traversal over the graph.
bool insertEdge(std::optional< BasicBlock * >, BasicBlock *BB)
Called upon reaching a block via a CFG edge.
void finishPostorder(BasicBlock *BB)
Called each time the iterator advances, indicating a block's postorder.
LoopBlocksTraversal(LoopBlocksDFS &Storage, const LoopInfo *LInfo)
Represents a single loop in the control flow graph.
PostOrderTraversalBase()=default
This is an optimization pass for GlobalISel generic memory operations.
constexpr uint64_t NextPowerOf2(uint64_t A)
Returns the next power of two (in 64-bits) that is strictly greater than A.