15 #ifndef LLVM_ANALYSIS_LOOPINFOIMPL_H
16 #define LLVM_ANALYSIS_LOOPINFOIMPL_H
34 template<
class BlockT,
class LoopT>
38 for (
block_iterator BI = block_begin(), BE = block_end(); BI != BE; ++BI)
39 for (
typename BlockTraits::ChildIteratorType
I =
40 BlockTraits::child_begin(*BI),
E = BlockTraits::child_end(*BI);
51 template<
class BlockT,
class LoopT>
54 getExitingBlocks(ExitingBlocks);
55 if (ExitingBlocks.
size() == 1)
56 return ExitingBlocks[0];
63 template<
class BlockT,
class LoopT>
67 for (
block_iterator BI = block_begin(), BE = block_end(); BI != BE; ++BI)
68 for (
typename BlockTraits::ChildIteratorType
I =
69 BlockTraits::child_begin(*BI),
E = BlockTraits::child_end(*BI);
78 template<
class BlockT,
class LoopT>
81 getExitBlocks(ExitBlocks);
82 if (ExitBlocks.
size() == 1)
88 template<
class BlockT,
class LoopT>
92 for (
block_iterator BI = block_begin(), BE = block_end(); BI != BE; ++BI)
93 for (
typename BlockTraits::ChildIteratorType
I =
94 BlockTraits::child_begin(*BI),
E = BlockTraits::child_end(*BI);
108 template<
class BlockT,
class LoopT>
111 BlockT *Out = getLoopPredecessor();
112 if (!Out)
return nullptr;
116 typename BlockTraits::ChildIteratorType
SI = BlockTraits::child_begin(Out);
118 if (SI != BlockTraits::child_end(Out))
130 template<
class BlockT,
class LoopT>
133 BlockT *Out =
nullptr;
136 BlockT *Header = getHeader();
138 for (
typename InvBlockTraits::ChildIteratorType PI =
139 InvBlockTraits::child_begin(Header),
140 PE = InvBlockTraits::child_end(Header); PI != PE; ++PI) {
141 typename InvBlockTraits::NodeRef
N = *PI;
150 assert(Out &&
"Header of loop has no predecessors from outside loop?");
156 template<
class BlockT,
class LoopT>
158 BlockT *Header = getHeader();
160 typename InvBlockTraits::ChildIteratorType PI =
161 InvBlockTraits::child_begin(Header);
162 typename InvBlockTraits::ChildIteratorType PE =
163 InvBlockTraits::child_end(Header);
164 BlockT *Latch =
nullptr;
165 for (; PI != PE; ++PI) {
166 typename InvBlockTraits::NodeRef
N = *PI;
168 if (Latch)
return nullptr;
186 template<
class BlockT,
class LoopT>
190 if (!Blocks.empty()) {
191 auto SameHeader = LIB[getHeader()];
192 assert(
contains(SameHeader) && getHeader() == SameHeader->getHeader()
193 &&
"Incorrect LI specified for this loop!");
196 assert(NewBB &&
"Cannot add a null basic block to the loop!");
197 assert(!LIB[NewBB] &&
"BasicBlock already in the loop!");
199 LoopT *
L =
static_cast<LoopT *
>(
this);
202 LIB.BBMap[NewBB] =
L;
207 L = L->getParentLoop();
215 template<
class BlockT,
class LoopT>
218 assert(OldChild->ParentLoop ==
this &&
"This loop is already broken!");
219 assert(!NewChild->ParentLoop &&
"NewChild already has a parent!");
220 typename std::vector<LoopT *>::iterator
I =
find(SubLoops, OldChild);
221 assert(I != SubLoops.end() &&
"OldChild not in loop!");
223 OldChild->ParentLoop =
nullptr;
224 NewChild->ParentLoop =
static_cast<LoopT *
>(
this);
228 template<
class BlockT,
class LoopT>
231 assert(!Blocks.empty() &&
"Loop header is missing");
235 getExitBlocks(ExitBBs);
237 VisitSet.
insert(ExitBBs.begin(), ExitBBs.end());
243 unsigned NumVisited = 0;
246 for ( ; BI != BE; ++BI) {
252 "Loop block has no in-loop successors!");
256 [&](BlockT *B){
return contains(B);}) &&
257 "Loop block has no in-loop predecessors!");
266 if (BB == getHeader()) {
267 assert(!OutsideLoopPreds.
empty() &&
"Loop is unreachable!");
268 }
else if (!OutsideLoopPreds.
empty()) {
272 BlockT *EntryBB = &BB->getParent()->front();
274 for (
unsigned i = 0, e = OutsideLoopPreds.
size();
i != e; ++
i)
275 assert(CB != OutsideLoopPreds[
i] &&
276 "Loop has multiple entry points!");
279 "Loop contains function entry block!");
284 assert(NumVisited == getNumBlocks() &&
"Unreachable block in loop");
289 for (
block_iterator BI = (*I)->block_begin(), BE = (*I)->block_end();
292 "Loop does not contain all the blocks of a subloop!");
298 "Loop is not a subloop of its parent!");
304 template<
class BlockT,
class LoopT>
307 Loops->
insert(static_cast<const LoopT *>(
this));
312 (*I)->verifyLoopNest(Loops);
315 template<
class BlockT,
class LoopT>
317 bool Verbose)
const {
318 OS.
indent(Depth*2) <<
"Loop at depth " << getLoopDepth()
321 BlockT *
H = getHeader();
322 for (
unsigned i = 0;
i < getBlocks().size(); ++
i) {
323 BlockT *BB = getBlocks()[
i];
326 BB->printAsOperand(OS,
false);
329 if (BB == H) OS <<
"<header>";
330 if (isLoopLatch(BB)) OS <<
"<latch>";
331 if (isLoopExiting(BB)) OS <<
"<exiting>";
338 (*I)->print(OS, Depth+2);
349 template<
class BlockT,
class LoopT>
355 unsigned NumBlocks = 0;
356 unsigned NumSubloops = 0;
359 std::vector<BlockT *> ReverseCFGWorklist(Backedges.
begin(), Backedges.
end());
360 while (!ReverseCFGWorklist.empty()) {
361 BlockT *PredBB = ReverseCFGWorklist.back();
362 ReverseCFGWorklist.pop_back();
372 if (PredBB == L->getHeader())
375 ReverseCFGWorklist.insert(ReverseCFGWorklist.end(),
376 InvBlockTraits::child_begin(PredBB),
377 InvBlockTraits::child_end(PredBB));
381 while (LoopT *Parent = Subloop->getParentLoop())
389 Subloop->setParentLoop(L);
391 NumBlocks += Subloop->getBlocks().capacity();
392 PredBB = Subloop->getHeader();
397 for (
typename InvBlockTraits::ChildIteratorType PI =
398 InvBlockTraits::child_begin(PredBB),
399 PE = InvBlockTraits::child_end(PredBB); PI != PE; ++PI) {
401 ReverseCFGWorklist.push_back(*PI);
405 L->getSubLoopsVector().reserve(NumSubloops);
406 L->reserveBlocks(NumBlocks);
410 template<
class BlockT,
class LoopT>
413 typedef typename BlockTraits::ChildIteratorType SuccIterTy;
427 template<
class BlockT,
class LoopT>
436 template<
class BlockT,
class LoopT>
438 LoopT *Subloop = LI->getLoopFor(Block);
439 if (Subloop && Block == Subloop->getHeader()) {
442 if (Subloop->getParentLoop())
443 Subloop->getParentLoop()->getSubLoopsVector().push_back(Subloop);
445 LI->addTopLevelLoop(Subloop);
449 Subloop->reverseBlock(1);
451 Subloop->getSubLoopsVector().end());
453 Subloop = Subloop->getParentLoop();
455 for (; Subloop; Subloop = Subloop->getParentLoop())
456 Subloop->addBlockEntry(Block);
473 template<
class BlockT,
class LoopT>
481 BlockT *Header = DomNode->getBlock();
486 for (
typename InvBlockTraits::ChildIteratorType PI =
487 InvBlockTraits::child_begin(Header),
488 PE = InvBlockTraits::child_end(Header); PI != PE; ++PI) {
490 BlockT *Backedge = *PI;
499 if (!Backedges.
empty()) {
500 LoopT *
L =
new LoopT(Header);
511 template<
class BlockT,
class LoopT>
513 for (
unsigned i = 0;
i < TopLevelLoops.size(); ++
i)
514 TopLevelLoops[
i]->print(OS);
517 E = BBMap.end();
I !=
E; ++
I)
518 OS <<
"BB '" <<
I->first->getName() <<
"' level = "
519 <<
I->second->getLoopDepth() <<
"\n";
523 template <
typename T>
525 std::sort(BB1.begin(), BB1.end());
526 std::sort(BB2.begin(), BB2.end());
530 template <
class BlockT,
class LoopT>
535 LoopHeaders[L.getHeader()] = &
L;
540 template <
class BlockT,
class LoopT>
545 assert(!(*I)->getParentLoop() &&
"Top-level loop has a parent!");
546 (*I)->verifyLoopNest(&Loops);
551 for (
auto &Entry : BBMap) {
552 const BlockT *BB = Entry.first;
553 LoopT *
L = Entry.second;
555 assert(L->contains(BB) &&
"orphaned block");
565 for (LoopT *
L : *
this)
567 for (LoopT *L : OtherLI)
570 "LoopInfo is incorrect.");
572 auto compareLoops = [&](
const LoopT *L1,
const LoopT *L2) {
573 BlockT *H1 = L1->getHeader();
574 BlockT *H2 = L2->getHeader();
577 std::vector<BlockT *> BB1 = L1->getBlocks();
578 std::vector<BlockT *> BB2 = L2->getBlocks();
582 std::vector<BlockT *> SubLoopHeaders1;
583 std::vector<BlockT *> SubLoopHeaders2;
585 SubLoopHeaders1.push_back(L->getHeader());
587 SubLoopHeaders2.push_back(L->getHeader());
594 for (
auto &
I : LoopHeaders1) {
596 bool LoopsMatch = compareLoops(LoopHeaders1[H], LoopHeaders2[H]);
597 assert(LoopsMatch &&
"LoopInfo is incorrect.");
void push_back(const T &Elt)
const_iterator end(StringRef path)
Get end iterator over path.
bool compareVectors(std::vector< T > &BB1, std::vector< T > &BB2)
Implements a dense probed hash-table based set.
raw_ostream & indent(unsigned NumSpaces)
indent - Insert 'NumSpaces' spaces.
void replaceChildLoopWith(LoopT *OldChild, LoopT *NewChild)
This is used when splitting loops up.
const_iterator begin(StringRef path)
Get begin iterator over path.
void insertIntoLoop(BlockT *Block)
Add a single Block to its ancestor loops in PostOrder.
void changeLoopFor(BlockT *BB, LoopT *L)
Change the top-level loop that contains BB to the specified loop.
LoopT * getLoopFor(const BlockT *BB) const
Return the inner most loop that BB lives in.
BlockT * getExitBlock() const
If getExitBlocks would return exactly one block, return that block.
return AArch64::GPR64RegClass contains(Reg)
std::vector< LoopT * >::const_iterator iterator
iterator/begin/end - The interface to the top-level loops in the current function.
BlockT * getLoopLatch() const
If there is a single latch block for this loop, return it.
void getExitEdges(SmallVectorImpl< Edge > &ExitEdges) const
Return all pairs of (inside_block,outside_block).
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
void getExitingBlocks(SmallVectorImpl< BlockT * > &ExitingBlocks) const
Return all blocks inside the loop that have successors outside of the loop.
DomTreeNodeBase< NodeT > * getRootNode()
getRootNode - This returns the entry node for the CFG of the function.
static void discoverAndMapSubloop(LoopT *L, ArrayRef< BlockT * > Backedges, LoopInfoBase< BlockT, LoopT > *LI, const DominatorTreeBase< BlockT > &DomTree)
Stable LoopInfo Analysis - Build a loop tree using stable iterators so the result does / not depend o...
LLVM_NODISCARD bool empty() const
void getExitBlocks(SmallVectorImpl< BlockT * > &ExitBlocks) const
Return all of the successor blocks of this loop.
auto reverse(ContainerTy &&C, typename std::enable_if< has_rbegin< ContainerTy >::value >::type *=nullptr) -> decltype(make_range(C.rbegin(), C.rend()))
void addBasicBlockToLoop(BlockT *NewBB, LoopInfoBase< BlockT, LoopT > &LI)
This method is used by other analyses to update loop information.
void traverse(BlockT *EntryBlock)
Top-level driver for the forward DFS within the loop.
Base class for the actual dominator tree node.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory)...
static GCRegistry::Add< OcamlGC > B("ocaml","ocaml 3.10-compatible GC")
static GCRegistry::Add< CoreCLRGC > E("coreclr","CoreCLR-compatible GC")
void verifyLoop() const
Verify loop structure.
Core dominator tree base class.
PopulateLoopsDFS(LoopInfoBase< BlockT, LoopT > *li)
BlockT * getLoopPreheader() const
If there is a preheader for this loop, return it.
bool isReachableFromEntry(const NodeT *A) const
isReachableFromEntry - Return true if A is dominated by the entry block of the function containing it...
bool dominates(const DomTreeNodeBase< NodeT > *A, const DomTreeNodeBase< NodeT > *B) const
dominates - Returns true iff A dominates B.
df_ext_iterator< T, SetTy > df_ext_end(const T &G, SetTy &S)
std::pair< iterator, bool > insert(const ValueT &V)
void analyze(const DominatorTreeBase< BlockT > &DomTree)
Create the loop forest using a stable algorithm.
df_ext_iterator< T, SetTy > df_ext_begin(const T &G, SetTy &S)
bool any_of(R &&Range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly...
BlockT * getExitingBlock() const
If getExitingBlocks would return exactly one block, return that block.
iterator_range< po_iterator< T > > post_order(const T &G)
void addBlockEntry(BlockT *BB)
This adds a basic block directly to the basic block list.
std::pair< const BlockT *, const BlockT * > Edge
Edge type.
auto find(R &&Range, const T &Val) -> decltype(std::begin(Range))
Provide wrappers to std::find which take ranges instead of having to pass begin/end explicitly...
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small...
std::pair< iterator, bool > insert(NodeRef N)
std::vector< BlockT * >::const_iterator block_iterator
void verifyLoopNest(DenseSet< const LoopT * > *Loops) const
Verify loop structure of this loop and all nested loops.
size_type count(const ValueT &V) const
Return 1 if the specified key is in the set, 0 otherwise.
LLVM_ATTRIBUTE_ALWAYS_INLINE size_type size() const
BlockT * getLoopPredecessor() const
If the given loop's header has exactly one unique predecessor outside the loop, return it...
static void addInnerLoopsToHeadersMap(DenseMap< BlockT *, const LoopT * > &LoopHeaders, const LoopInfoBase< BlockT, LoopT > &LI, const LoopT &L)
iterator_range< df_iterator< T > > depth_first(const T &G)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
static const Function * getParent(const Value *V)
This class implements an extremely fast bulk output stream that can only output to a stream...
void print(raw_ostream &OS, unsigned Depth=0, bool Verbose=false) const
Print loop with all the BBs inside it.
std::vector< LoopT * >::const_iterator iterator
Populate all loop data in a stable order during a single forward DFS.
bool is_contained(R &&Range, const E &Element)
Wrapper function around std::find to detect if an element exists in a container.