15 #ifndef LLVM_ANALYSIS_LOOPINFOIMPL_H 16 #define LLVM_ANALYSIS_LOOPINFOIMPL_H 34 template <
class BlockT,
class LoopT>
37 assert(!isInvalid() &&
"Loop not in a valid state!");
38 for (
const auto BB : blocks())
39 for (
const auto &Succ : children<BlockT *>(BB))
49 template <
class BlockT,
class LoopT>
51 assert(!isInvalid() &&
"Loop not in a valid state!");
53 getExitingBlocks(ExitingBlocks);
54 if (ExitingBlocks.
size() == 1)
55 return ExitingBlocks[0];
62 template <
class BlockT,
class LoopT>
65 assert(!isInvalid() &&
"Loop not in a valid state!");
66 for (
const auto BB : blocks())
67 for (
const auto &Succ : children<BlockT *>(BB))
75 template <
class BlockT,
class LoopT>
77 assert(!isInvalid() &&
"Loop not in a valid state!");
79 getExitBlocks(ExitBlocks);
80 if (ExitBlocks.
size() == 1)
85 template <
class BlockT,
class LoopT>
90 getExitBlocks(ExitBlocks);
91 for (BlockT *EB : ExitBlocks)
99 template <
class BlockT,
class LoopT>
105 assert(hasDedicatedExits() &&
106 "getUniqueExitBlocks assumes the loop has canonical form exits!");
109 for (BlockT *Block : this->blocks()) {
110 SwitchExitBlocks.
clear();
111 for (BlockT *
Successor : children<BlockT *>(Block)) {
116 BlockT *FirstPred = *InvBlockTraits::child_begin(
Successor);
121 if (Block != FirstPred)
127 if (std::distance(BlockTraits::child_begin(Block),
128 BlockTraits::child_end(Block)) <= 2) {
144 template <
class BlockT,
class LoopT>
147 getUniqueExitBlocks(UniqueExitBlocks);
148 if (UniqueExitBlocks.
size() == 1)
149 return UniqueExitBlocks[0];
154 template <
class BlockT,
class LoopT>
157 assert(!isInvalid() &&
"Loop not in a valid state!");
158 for (
const auto BB : blocks())
159 for (
const auto &Succ : children<BlockT *>(BB))
173 template <
class BlockT,
class LoopT>
175 assert(!isInvalid() &&
"Loop not in a valid state!");
177 BlockT *Out = getLoopPredecessor();
182 if (!Out->isLegalToHoistInto())
187 typename BlockTraits::ChildIteratorType
SI = BlockTraits::child_begin(Out);
189 if (SI != BlockTraits::child_end(Out))
201 template <
class BlockT,
class LoopT>
203 assert(!isInvalid() &&
"Loop not in a valid state!");
205 BlockT *Out =
nullptr;
208 BlockT *Header = getHeader();
211 if (Out && Out != Pred)
218 assert(Out &&
"Header of loop has no predecessors from outside loop?");
224 template <
class BlockT,
class LoopT>
226 assert(!isInvalid() &&
"Loop not in a valid state!");
227 BlockT *Header = getHeader();
228 BlockT *Latch =
nullptr;
250 template <
class BlockT,
class LoopT>
253 assert(!isInvalid() &&
"Loop not in a valid state!");
255 if (!Blocks.empty()) {
256 auto SameHeader = LIB[getHeader()];
257 assert(
contains(SameHeader) && getHeader() == SameHeader->getHeader() &&
258 "Incorrect LI specified for this loop!");
261 assert(NewBB &&
"Cannot add a null basic block to the loop!");
262 assert(!LIB[NewBB] &&
"BasicBlock already in the loop!");
264 LoopT *L =
static_cast<LoopT *
>(
this);
267 LIB.BBMap[NewBB] = L;
271 L->addBlockEntry(NewBB);
272 L = L->getParentLoop();
280 template <
class BlockT,
class LoopT>
283 assert(!isInvalid() &&
"Loop not in a valid state!");
284 assert(OldChild->ParentLoop ==
this &&
"This loop is already broken!");
285 assert(!NewChild->ParentLoop &&
"NewChild already has a parent!");
286 typename std::vector<LoopT *>::iterator
I =
find(SubLoops, OldChild);
287 assert(I != SubLoops.end() &&
"OldChild not in loop!");
289 OldChild->ParentLoop =
nullptr;
290 NewChild->ParentLoop =
static_cast<LoopT *
>(
this);
294 template <
class BlockT,
class LoopT>
296 assert(!isInvalid() &&
"Loop not in a valid state!");
298 assert(!Blocks.empty() &&
"Loop header is missing");
302 getExitBlocks(ExitBBs);
304 VisitSet.
insert(ExitBBs.begin(), ExitBBs.end());
313 for (; BI != BE; ++BI) {
318 [&](BlockT *
B) {
return contains(B); }) &&
319 "Loop block has no in-loop successors!");
323 [&](BlockT *B) {
return contains(B); }) &&
324 "Loop block has no in-loop predecessors!");
334 if (BB == getHeader()) {
335 assert(!OutsideLoopPreds.
empty() &&
"Loop is unreachable!");
336 }
else if (!OutsideLoopPreds.
empty()) {
340 BlockT *EntryBB = &BB->getParent()->front();
342 for (
unsigned i = 0, e = OutsideLoopPreds.
size(); i != e; ++i)
343 assert(CB != OutsideLoopPreds[i] &&
344 "Loop has multiple entry points!");
347 "Loop contains function entry block!");
352 if (VisitedBBs.
size() != getNumBlocks()) {
353 dbgs() <<
"The following blocks are unreachable in the loop: ";
354 for (
auto BB : Blocks) {
355 if (!VisitedBBs.
count(BB)) {
356 dbgs() << *BB <<
"\n";
359 assert(
false &&
"Unreachable block in loop");
365 for (
block_iterator BI = (*I)->block_begin(), BE = (*I)->block_end();
368 "Loop does not contain all the blocks of a subloop!");
374 "Loop is not a subloop of its parent!");
380 template <
class BlockT,
class LoopT>
383 assert(!isInvalid() &&
"Loop not in a valid state!");
384 Loops->
insert(static_cast<const LoopT *>(
this));
389 (*I)->verifyLoopNest(Loops);
392 template <
class BlockT,
class LoopT>
394 bool Verbose)
const {
396 if (static_cast<const LoopT *>(
this)->isAnnotatedParallel())
398 OS <<
"Loop at depth " << getLoopDepth() <<
" containing: ";
400 BlockT *
H = getHeader();
401 for (
unsigned i = 0; i < getBlocks().size(); ++i) {
402 BlockT *BB = getBlocks()[i];
406 BB->printAsOperand(OS,
false);
414 if (isLoopExiting(BB))
422 (*I)->print(OS, Depth + 2);
433 template <
class BlockT,
class LoopT>
439 unsigned NumBlocks = 0;
440 unsigned NumSubloops = 0;
443 std::vector<BlockT *> ReverseCFGWorklist(Backedges.
begin(), Backedges.
end());
444 while (!ReverseCFGWorklist.empty()) {
445 BlockT *PredBB = ReverseCFGWorklist.back();
446 ReverseCFGWorklist.pop_back();
456 if (PredBB == L->getHeader())
459 ReverseCFGWorklist.insert(ReverseCFGWorklist.end(),
460 InvBlockTraits::child_begin(PredBB),
461 InvBlockTraits::child_end(PredBB));
464 while (LoopT *Parent = Subloop->getParentLoop())
472 Subloop->setParentLoop(L);
474 NumBlocks += Subloop->getBlocksVector().capacity();
475 PredBB = Subloop->getHeader();
482 ReverseCFGWorklist.push_back(Pred);
486 L->getSubLoopsVector().reserve(NumSubloops);
487 L->reserveBlocks(NumBlocks);
493 typedef typename BlockTraits::ChildIteratorType SuccIterTy;
507 template <
class BlockT,
class LoopT>
516 template <
class BlockT,
class LoopT>
518 LoopT *Subloop = LI->getLoopFor(Block);
519 if (Subloop && Block == Subloop->getHeader()) {
522 if (Subloop->getParentLoop())
523 Subloop->getParentLoop()->getSubLoopsVector().push_back(Subloop);
525 LI->addTopLevelLoop(Subloop);
529 Subloop->reverseBlock(1);
531 Subloop->getSubLoopsVector().end());
533 Subloop = Subloop->getParentLoop();
535 for (; Subloop; Subloop = Subloop->getParentLoop())
536 Subloop->addBlockEntry(Block);
553 template <
class BlockT,
class LoopT>
559 BlockT *Header = DomNode->getBlock();
565 if (DomTree.
dominates(Header, Backedge) &&
571 if (!Backedges.
empty()) {
572 LoopT *L = AllocateLoop(Header);
582 template <
class BlockT,
class LoopT>
590 for (LoopT *RootL :
reverse(*
this)) {
592 "Must start with an empty preorder walk worklist.");
598 PreOrderWorklist.
append(L->rbegin(), L->rend());
600 }
while (!PreOrderWorklist.
empty());
603 return PreOrderLoops;
606 template <
class BlockT,
class LoopT>
615 for (LoopT *RootL : *
this) {
617 "Must start with an empty preorder walk worklist.");
623 PreOrderWorklist.
append(L->begin(), L->end());
625 }
while (!PreOrderWorklist.
empty());
628 return PreOrderLoops;
632 template <
class BlockT,
class LoopT>
634 for (
unsigned i = 0; i < TopLevelLoops.size(); ++i)
635 TopLevelLoops[i]->
print(OS);
638 E = BBMap.end();
I !=
E; ++
I)
639 OS <<
"BB '" <<
I->first->getName() <<
"' level = " 640 <<
I->second->getLoopDepth() <<
"\n";
644 template <
typename T>
651 template <
class BlockT,
class LoopT>
655 LoopHeaders[L.getHeader()] = &L;
661 template <
class BlockT,
class LoopT>
664 BlockT *
H = L->getHeader();
665 BlockT *OtherH = OtherL->getHeader();
667 "Mismatched headers even though found in the same map entry!");
669 assert(L->getLoopDepth() == OtherL->getLoopDepth() &&
670 "Mismatched loop depth!");
671 const LoopT *ParentL = L, *OtherParentL = OtherL;
673 assert(ParentL->getHeader() == OtherParentL->getHeader() &&
674 "Mismatched parent loop headers!");
675 ParentL = ParentL->getParentLoop();
676 OtherParentL = OtherParentL->getParentLoop();
679 for (
const LoopT *SubL : *L) {
680 BlockT *SubH = SubL->getHeader();
681 const LoopT *OtherSubL = OtherLoopHeaders.
lookup(SubH);
682 assert(OtherSubL &&
"Inner loop is missing in computed loop info!");
683 OtherLoopHeaders.
erase(SubH);
687 std::vector<BlockT *> BBs = L->getBlocks();
688 std::vector<BlockT *> OtherBBs = OtherL->getBlocks();
690 "Mismatched basic blocks in the loops!");
696 [&OtherBlocksSet](
const BlockT *BB) {
697 return OtherBlocksSet.
count(BB);
699 "Mismatched basic blocks in BlocksSets!");
703 template <
class BlockT,
class LoopT>
708 assert(!(*I)->getParentLoop() &&
"Top-level loop has a parent!");
709 (*I)->verifyLoopNest(&Loops);
714 for (
auto &Entry : BBMap) {
715 const BlockT *BB = Entry.first;
716 LoopT *L = Entry.second;
718 assert(L->contains(BB) &&
"orphaned block");
719 for (LoopT *ChildLoop : *L)
720 assert(!ChildLoop->contains(BB) &&
721 "BBMap should point to the innermost loop containing BB");
732 for (LoopT *L : OtherLI)
738 for (LoopT *L : *
this) {
739 BlockT *Header = L->getHeader();
740 const LoopT *OtherL = OtherLoopHeaders.
lookup(Header);
741 assert(OtherL &&
"Top level loop is missing in computed loop info!");
743 OtherLoopHeaders.
erase(Header);
750 if (!OtherLoopHeaders.
empty()) {
751 for (
const auto &HeaderAndLoop : OtherLoopHeaders)
752 dbgs() <<
"Found new loop: " << *HeaderAndLoop.second <<
"\n";
const_iterator end(StringRef path)
Get end iterator over path.
iterator_range< typename GraphTraits< GraphType >::ChildIteratorType > children(const typename GraphTraits< GraphType >::NodeRef &G)
BlockT * getLoopLatch() const
If there is a single latch block for this loop, return it.
const_iterator begin(StringRef path, Style style=Style::native)
Get begin iterator over path.
This class represents lattice values for constants.
static void compareLoops(const LoopT *L, const LoopT *OtherL, DenseMap< BlockT *, const LoopT *> &OtherLoopHeaders)
bool compareVectors(std::vector< T > &BB1, std::vector< T > &BB2)
bool hasDedicatedExits() const
Return true if no exit block for the loop has a predecessor that is outside the loop.
Implements a dense probed hash-table based set.
void push_back(const T &Elt)
BlockT * getLoopPreheader() const
If there is a preheader for this loop, return it.
static void discoverAndMapSubloop(LoopT *L, ArrayRef< BlockT *> Backedges, LoopInfoBase< BlockT, LoopT > *LI, const DomTreeBase< BlockT > &DomTree)
Stable LoopInfo Analysis - Build a loop tree using stable iterators so the result does / not depend o...
raw_ostream & indent(unsigned NumSpaces)
indent - Insert 'NumSpaces' spaces.
bool isReachableFromEntry(const NodeT *A) const
isReachableFromEntry - Return true if A is dominated by the entry block of the function containing it...
void replaceChildLoopWith(LoopT *OldChild, LoopT *NewChild)
This is used when splitting loops up.
void insertIntoLoop(BlockT *Block)
Add a single Block to its ancestor loops in PostOrder.
bool all_of(R &&range, UnaryPredicate P)
Provide wrappers to std::all_of which take ranges instead of having to pass begin/end explicitly...
return AArch64::GPR64RegClass contains(Reg)
void verify(const DominatorTreeBase< BlockT, false > &DomTree) const
void print(raw_ostream &OS, unsigned Depth=0, bool Verbose=false) const
Print loop with all the BBs inside it.
LoopT * getLoopFor(const BlockT *BB) const
Return the inner most loop that BB lives in.
std::vector< Loop *>::const_iterator iterator
iterator/begin/end - The interface to the top-level loops in the current function.
void addInnerLoopsToHeadersMap(DenseMap< BlockT *, const LoopT *> &LoopHeaders, const LoopInfoBase< BlockT, LoopT > &LI, const LoopT &L)
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()))
std::vector< Loop *>::const_iterator iterator
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)...
Core dominator tree base class.
bool erase(const KeyT &Val)
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
PopulateLoopsDFS(LoopInfoBase< BlockT, LoopT > *li)
df_ext_iterator< T, SetTy > df_ext_end(const T &G, SetTy &S)
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
std::pair< iterator, bool > insert(const ValueT &V)
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
void analyze(const DominatorTreeBase< BlockT, false > &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...
static void print(raw_ostream &Out, object::Archive::Kind Kind, T Val)
iterator_range< po_iterator< T > > post_order(const T &G)
size_type count(ConstPtrType Ptr) const
count - Return 1 if the specified pointer is in the set, 0 otherwise.
BlockT * getExitBlock() const
If getExitBlocks would return exactly one block, return that block.
DomTreeNodeBase< NodeT > * getRootNode()
getRootNode - This returns the entry node for the CFG of the function.
void getExitingBlocks(SmallVectorImpl< BlockT *> &ExitingBlocks) const
Return all blocks inside the loop that have successors outside of the loop.
BlockT * getUniqueExitBlock() const
If getUniqueExitBlocks would return exactly one block, return that block.
auto find(R &&Range, const T &Val) -> decltype(adl_begin(Range))
Provide wrappers to std::find which take ranges instead of having to pass begin/end explicitly...
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
void sort(IteratorTy Start, IteratorTy End)
void getExitEdges(SmallVectorImpl< Edge > &ExitEdges) const
Return all pairs of (inside_block,outside_block).
BlockT * getLoopPredecessor() const
If the given loop's header has exactly one unique predecessor outside the loop, return it...
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements...
void print(raw_ostream &OS) const
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small...
LLVM_NODISCARD T pop_back_val()
std::pair< iterator, bool > insert(NodeRef N)
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
void append(in_iter in_start, in_iter in_end)
Add the specified range to the end of the SmallVector.
bool dominates(const DomTreeNodeBase< NodeT > *A, const DomTreeNodeBase< NodeT > *B) const
dominates - Returns true iff A dominates B.
void verifyLoopNest(DenseSet< const LoopT *> *Loops) const
Verify loop structure of this loop and all nested loops.
void emplace_back(ArgTypes &&... Args)
LLVM_NODISCARD bool empty() const
SmallVector< LoopT *, 4 > getLoopsInReverseSiblingPreorder()
Return all of the loops in the function in preorder across the loop nests, with siblings in reverse p...
void changeLoopFor(BlockT *BB, LoopT *L)
Change the top-level loop that contains BB to the specified loop.
size_type count(const_arg_type_t< ValueT > V) const
Return 1 if the specified key is in the set, 0 otherwise.
LLVM_NODISCARD bool empty() const
ValueT lookup(const_arg_type_t< KeyT > Val) const
lookup - Return the entry for the specified key, or a default constructed value if no such entry exis...
SmallVector< LoopT *, 4 > getLoopsInPreorder()
Return all of the loops in the function in preorder across the loop nests, with siblings in forward p...
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 verifyLoop() const
Verify loop structure.
void getUniqueExitBlocks(SmallVectorImpl< BlockT *> &ExitBlocks) const
Return all unique successor blocks of this loop.
UnaryPredicate for_each(R &&Range, UnaryPredicate P)
Provide wrappers to std::for_each which take ranges instead of having to pass begin/end explicitly...
BlockT * getExitingBlock() const
If getExitingBlocks would return exactly one block, return that block.
Populate all loop data in a stable order during a single forward DFS.
This class builds and contains all of the top-level loop structures in the specified function...
bool is_contained(R &&Range, const E &Element)
Wrapper function around std::find to detect if an element exists in a container.