14#ifndef LLVM_SUPPORT_GENERICLOOPINFOIMPL_H
15#define LLVM_SUPPORT_GENERICLOOPINFOIMPL_H
33template <
class BlockT,
class LoopT>
37 for (
const auto BB :
blocks())
48template <
class BlockT,
class LoopT>
51 auto notInLoop = [&](BlockT *BB) {
return !
contains(BB); };
52 auto isExitBlock = [&](BlockT *BB,
bool AllowRepeats) -> BlockT * {
53 assert(!AllowRepeats &&
"Unexpected parameter value.");
64template <
class BlockT,
class LoopT>
68 for (
const auto BB :
blocks())
77template <
class BlockT,
class LoopT>
80 assert(!L->isInvalid() &&
"Loop not in a valid state!");
81 auto notInLoop = [&](BlockT *BB,
82 bool AllowRepeats) -> std::pair<BlockT *, bool> {
83 assert(AllowRepeats == Unique &&
"Unexpected parameter value.");
84 return {!L->contains(BB) ? BB :
nullptr,
false};
86 auto singleExitBlock = [&](BlockT *BB,
87 bool AllowRepeats) -> std::pair<BlockT *, bool> {
88 assert(AllowRepeats == Unique &&
"Unexpected parameter value.");
95template <
class BlockT,
class LoopT>
107template <
class BlockT,
class LoopT>
112template <
class BlockT,
class LoopT>
118 for (BlockT *EB : UniqueExitBlocks)
128template <
class BlockT,
class LoopT,
typename PredicateT>
132 assert(!L->isInvalid() &&
"Loop not in a valid state!");
135 for (BlockT *BB : Filtered)
142template <
class BlockT,
class LoopT>
146 [](
const BlockT *BB) {
return true; });
149template <
class BlockT,
class LoopT>
153 assert(Latch &&
"Latch block must exists");
155 [Latch](
const BlockT *BB) {
return BB != Latch; });
158template <
class BlockT,
class LoopT>
163template <
class BlockT,
class LoopT>
166 BlockT *Latch = L.getLoopLatch();
167 assert(Latch &&
"Latch block must exists");
168 auto IsExitBlock = [&L](BlockT *BB,
bool AllowRepeats) -> BlockT * {
169 assert(!AllowRepeats &&
"Unexpected parameter value.");
170 return !L.contains(BB) ? BB :
nullptr;
176template <
class BlockT,
class LoopT>
179 for (
const auto BB : L.blocks())
181 if (!L.contains(Succ))
187template <
class BlockT>
190template <
class BlockT>
197 return Block->isLegalToHoistInto();
210template <
class BlockT,
class LoopT>
235template <
class BlockT,
class LoopT>
239 BlockT *Out =
nullptr;
245 if (Out && Out != Pred)
256template <
class BlockT,
class LoopT>
260 BlockT *Latch =
nullptr;
282template <
class BlockT,
class LoopT>
290 "Incorrect LI specified for this loop!");
293 assert(NewBB &&
"Cannot add a null basic block to the loop!");
294 assert(!LIB[NewBB] &&
"BasicBlock already in the loop!");
296 LoopT *L =
static_cast<LoopT *
>(
this);
303 L->addBlockEntry(NewBB);
304 L = L->getParentLoop();
309template <
class BlockT,
class LoopT>
328 "Loop block has no in-loop successors!");
332 "Loop block has no in-loop predecessors!");
340 assert(!OutsideLoopPreds.empty() &&
"Loop is unreachable!");
341 }
else if (!OutsideLoopPreds.empty()) {
345 BlockT *EntryBB = &BB->getParent()->front();
347 for (
unsigned i = 0, e = OutsideLoopPreds.size(); i != e; ++i)
348 assert(CB != OutsideLoopPreds[i] &&
349 "Loop has multiple entry points!");
352 "Loop contains function entry block!");
357 if (VisitedBBs.
size() != getNumBlocks()) {
358 dbgs() <<
"The following blocks are unreachable in the loop: ";
359 for (
auto *BB : getBlocks()) {
360 if (!VisitedBBs.
count(BB)) {
361 dbgs() << *BB <<
"\n";
364 assert(
false &&
"Unreachable block in loop");
370 for (block_iterator BI = (*I)->block_begin(), BE = (*I)->block_end();
373 "Loop does not contain all the blocks of a subloop!");
379 "Loop is not a subloop of its parent!");
385template <
class BlockT,
class LoopT>
389 Loops->insert(
static_cast<const LoopT *
>(
this));
394 (*I)->verifyLoopNest(
Loops);
397template <
class BlockT,
class LoopT>
399 bool PrintNested,
unsigned Depth)
const {
403 OS <<
"Loop at depth " <<
getLoopDepth() <<
" containing: ";
406 for (
unsigned i = 0; i <
getBlocks().size(); ++i) {
411 BB->printAsOperand(OS,
false);
430 (*I)->print(OS,
false, PrintNested,
Depth + 2);
446template <
class BlockT,
class LoopT>
448 analyzeImpl(DomTree, {});
451template <
class BlockT,
class LoopT>
452void LoopInfoBase<BlockT, LoopT>::analyzeImpl(
455 DomTree.getRootNode()->getBlock()->getParent(),
459template <
class BlockT,
class LoopT>
468template <
class BlockT,
class LoopT>
471 analyzeImpl(
F, GetDomTree, {});
474template <
class BlockT,
class LoopT>
481 ReuseByHeader[L->getHeader()] = L;
485 TopLevelLoops.clear();
489 [&](BlockT *Header) {
return ReuseByHeader.
lookup(Header); });
493 for (
auto [Header, L] : ReuseByHeader)
494 if (lookupLoopFor(Header) != L)
499template <
class BlockT,
class LoopT>
500void LoopInfoBase<BlockT, LoopT>::analyzeImpl(
502 ReuseLoopT ReuseLoop) {
504 auto num = [](
const BlockT *BB) {
509 BlockNumberEpoch = GraphTraits<ParentT>::getNumberEpoch(ParentPtr);
510 unsigned MaxNumber = GraphTraits<ParentT>::getMaxNumber(ParentPtr);
513 constexpr unsigned NoBlock = ~0u;
516 constexpr unsigned Unvisited = 0;
517 constexpr unsigned OffPath = 1;
518 constexpr unsigned IsHeader = 2;
519 constexpr unsigned IsReentered = 3;
520 constexpr unsigned FirstOnPath = IsReentered + 1;
528 unsigned LoopHeader = 0;
541 auto tagLoopHeader = [&](
unsigned B,
unsigned H) {
545 unsigned IH =
Info[
B].LoopHeader;
552 if (Info[IH].Pos >= Info[
H].Pos) {
570 typename BlockTraits::ChildIteratorType Cur, End;
573 unsigned Counter = FirstOnPath;
574 auto open = [&](BlockT *BB) {
575 unsigned B = num(BB);
576 Info[
B].Pos = Counter++;
577 Info[
B].LoopHeader = NoBlock;
579 {BB, BlockTraits::child_begin(BB), BlockTraits::child_end(BB)});
583 while (!
Stack.empty()) {
584 Frame &Top =
Stack.back();
585 if (Top.Cur == Top.End) {
587 unsigned B0 = num(Top.Block);
589 Postorder.push_back(Top.Block);
591 if (!
Stack.empty() && Info[B0].LoopHeader != NoBlock)
592 tagLoopHeader(num(
Stack.back().Block), Info[B0].LoopHeader);
595 BlockT *B0P = Top.Block;
596 BlockT *B1P = *Top.Cur++;
597 unsigned B1 = num(B1P);
598 if (Info[B1].Pos == Unvisited) {
601 }
else if (Info[B1].Pos >= FirstOnPath) {
603 Headers.push_back(B1);
604 tagLoopHeader(num(B0P), B1);
610 for (
unsigned H = Info[B1].LoopHeader;
H != NoBlock;
611 H = Info[
H].LoopHeader) {
612 if (Info[
H].Pos >= FirstOnPath) {
613 tagLoopHeader(num(B0P),
H);
625 for (
unsigned H : Headers)
626 Info[
H].Pos = IsHeader;
628 if (!Reentries.empty()) {
633 for (
unsigned H : Reentries)
634 Info[
H].Pos = IsReentered;
636 assert(DomTree.getRootNode()->getBlock() ==
638 DomTree.updateDFSNumbers();
646 for (BlockT *BB : Postorder) {
647 unsigned B = num(BB);
649 if (
unsigned P = Info[
B].LoopHeader;
P != NoBlock) {
650 NextSibling[
B] = FirstChild[
P];
654 for (BlockT *Header : Postorder) {
655 unsigned H = num(Header);
656 if (Info[
H].Pos != IsReentered)
660 auto enqueue = [&](BlockT *Pred) {
661 unsigned P = num(Pred);
664 for (
unsigned A =
P;
A != NoBlock;
A =
Info[
A].LoopHeader)
665 if (Info[
A].LoopHeader ==
H) {
673 Worklist.push_back(Pred);
678 assert(DomNode &&
"header missing from the dominator tree");
679 bool HasBackedge =
false;
682 if (PredNode && DomTree.dominates(DomNode, PredNode)) {
688 for (
unsigned I = 0;
I != Worklist.size(); ++
I)
691 if (Blocks[num(Pred)])
694 Info[
H].Pos = HasBackedge ? IsHeader : OffPath;
698 unsigned Parent =
Info[
H].LoopHeader;
699 unsigned Kept = NoBlock;
700 for (
unsigned B = FirstChild[
H],
Next;
B != NoBlock;
B =
Next) {
701 Next = NextSibling[
B];
703 NextSibling[
B] = Kept;
707 Info[
B].LoopHeader = Parent;
708 if (Parent != NoBlock) {
709 NextSibling[
B] = FirstChild[Parent];
710 FirstChild[Parent] =
B;
714 FirstChild[
H] = Kept;
716 if (
none_of(Headers, [&](
unsigned H) {
return Info[
H].Pos == IsHeader; }))
722 BBMap.resize(MaxNumber);
724 unsigned B = num(BB);
725 unsigned H = Info[
B].LoopHeader;
726 LoopT *Enclosing =
H == NoBlock ? nullptr : BBMap[
H];
727 LoopT *L = Enclosing;
728 if (Info[
B].Pos == IsHeader) {
729 L = allocateLoop(BB, ReuseLoop);
730 L->setParentLoop(Enclosing);
740 for (BlockT *BB : Postorder) {
741 LoopT *L = lookupLoopFor(BB);
746 if (BB != pendingHeader(L))
749 if (LoopT *Parent = L->getParentLoop())
750 Parent->BlockLen += L->BlockLen;
752 TopLevelLoops.push_back(L);
755 assert(!LoopsPO.
empty() &&
"discovered loops but found no header");
757 BlockLayout.reset(
new BlockT *[PO.
size()]);
758 BlockT **RootCursor = BlockLayout.get();
760 if (L->BlockCapacity == 0) {
763 if (LoopT *Parent = L->getParentLoop()) {
764 assert(Parent->BlockCapacity != 0 &&
765 "parent slice not carved before child");
766 L->BlockData = Parent->BlockData + Parent->BlockCapacity;
767 Parent->BlockCapacity += L->BlockLen;
768 Parent->SubLoops.push_back(L);
770 L->BlockData = RootCursor;
771 RootCursor += L->BlockLen;
775 L->BlockData[L->BlockCapacity++] = BB;
780 for (LoopT *L : LoopsPO) {
781 assert(L->BlockCapacity == L->BlockLen &&
"layout slice not fully used");
782 L->BlockCapacity = LoopT::BorrowedCapacity;
786template <
class BlockT,
class LoopT>
795 for (LoopT *RootL :
reverse(*
this)) {
797 LoopT::getInnerLoopsInPreorder(*RootL, PreOrderLoops);
800 return PreOrderLoops;
803template <
class BlockT,
class LoopT>
812 for (LoopT *RootL : *
this) {
814 "Must start with an empty preorder walk worklist.");
820 PreOrderWorklist.
append(L->begin(), L->end());
822 }
while (!PreOrderWorklist.
empty());
825 return PreOrderLoops;
828template <
class BlockT,
class LoopT>
836 unsigned DepthA =
A->getLoopDepth(), DepthB =
B->getLoopDepth();
837 for (; DepthA > DepthB; --DepthA)
838 A =
A->getParentLoop();
839 for (; DepthB > DepthA; --DepthB)
840 B =
B->getParentLoop();
846 A =
A->getParentLoop();
847 B =
B->getParentLoop();
853template <
class BlockT,
class LoopT>
860template <
class BlockT,
class LoopT>
862 for (
unsigned i = 0; i < TopLevelLoops.size(); ++i)
863 TopLevelLoops[i]->
print(OS);
873template <
class BlockT,
class LoopT>
877 LoopHeaders[L.getHeader()] = &L;
883template <
class BlockT,
class LoopT>
886 BlockT *
H = L->getHeader();
887 BlockT *OtherH = OtherL->getHeader();
889 "Mismatched headers even though found in the same map entry!");
891 assert(L->getLoopDepth() == OtherL->getLoopDepth() &&
892 "Mismatched loop depth!");
893 const LoopT *ParentL = L, *OtherParentL = OtherL;
895 assert(ParentL->getHeader() == OtherParentL->getHeader() &&
896 "Mismatched parent loop headers!");
897 ParentL = ParentL->getParentLoop();
898 OtherParentL = OtherParentL->getParentLoop();
901 for (
const LoopT *SubL : *L) {
902 BlockT *SubH = SubL->getHeader();
903 const LoopT *OtherSubL = OtherLoopHeaders.
lookup(SubH);
904 assert(OtherSubL &&
"Inner loop is missing in computed loop info!");
905 OtherLoopHeaders.
erase(SubH);
909 std::vector<BlockT *> BBs = L->getBlocks();
910 std::vector<BlockT *> OtherBBs = OtherL->getBlocks();
912 "Mismatched basic blocks in the loops!");
916template <
class BlockT,
class LoopT>
920 assert((*I)->isOutermost() &&
"Top-level loop has a parent!");
921 (*I)->verifyLoopNest(&
Loops);
927 for (
const LoopT *L :
Loops)
928 assert(L->LI ==
this &&
"Loop has a stale owning-LoopInfo back-pointer");
935 while (!Worklist.
empty()) {
939 for (
const BlockT *BB : L->getBlocks()) {
944 Worklist.
append(L->begin(), L->end());
950 "BBMap should point to the innermost loop containing the block");
954 LoopInfoBase<BlockT, LoopT> OtherLI;
961 for (LoopT *L : OtherLI)
967 for (LoopT *L : *
this) {
968 BlockT *Header = L->getHeader();
969 const LoopT *OtherL = OtherLoopHeaders.
lookup(Header);
970 assert(OtherL &&
"Top level loop is missing in computed loop info!");
972 OtherLoopHeaders.
erase(Header);
979 if (!OtherLoopHeaders.
empty()) {
980 for (
const auto &HeaderAndLoop : OtherLoopHeaders)
981 dbgs() <<
"Found new loop: " << *HeaderAndLoop.second <<
"\n";
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static const Function * getParent(const Value *V)
bbsections Prepares for basic block by splitting functions into clusters of basic blocks
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
This file defines the DenseSet and SmallDenseSet classes.
This file builds on the ADT/GraphTraits.h file to build generic depth first graph iterator.
static bool isExitBlock(BasicBlock *BB, const SmallVectorImpl< BasicBlock * > &ExitBlocks)
Return true if the specified block is in the list.
This file implements a map that provides insertion order iteration.
This file builds on the ADT/GraphTraits.h file to build a generic graph post order iterator.
static bool contains(SmallPtrSetImpl< ConstantExpr * > &Cache, ConstantExpr *Expr, Constant *C)
ValueT lookup(const_arg_type_t< KeyT > Val) const
Return the entry for the specified key, or a default constructed value if no such entry exists.
bool erase(const KeyT &Val)
Implements a dense probed hash-table based set.
Base class for the actual dominator tree node.
void recalculate(ParentType &Func)
recalculate - compute a dominator tree for the given function
Instances of this class are used to represent loops that are detected in the flow graph.
bool isAnnotatedParallel() const
Returns true if the loop is annotated parallel.
typename std::vector< LoopT * >::const_iterator iterator
BlockT * getLoopLatch() const
If there is a single latch block for this loop, return it.
void getExitBlocks(SmallVectorImpl< BlockT * > &ExitBlocks) const
Return all of the successor blocks of this loop.
void verifyLoop() const
Verify loop structure.
void verifyLoopNest(DenseSet< const LoopT * > *Loops) const
Verify loop structure of this loop and all nested loops.
void getExitingBlocks(SmallVectorImpl< BlockT * > &ExitingBlocks) const
Return all blocks inside the loop that have successors outside of the loop.
BlockT * getHeader() const
unsigned getLoopDepth() const
Return the nesting level of this loop.
void print(raw_ostream &OS, bool Verbose=false, bool PrintNested=true, unsigned Depth=0) const
Print loop with all the BBs inside it.
void addBasicBlockToLoop(BlockT *NewBB, LoopInfoBase< BlockT, LoopT > &LI)
This method is used by other analyses to update loop information.
bool isInvalid() const
Return true if this loop is no longer valid.
BlockT * getLoopPredecessor() const
If the given loop's header has exactly one unique predecessor outside the loop, return it.
bool isLoopLatch(const BlockT *BB) const
BlockT * getExitBlock() const
If getExitBlocks would return exactly one block, return that block.
BlockT * getLoopPreheader() const
If there is a preheader for this loop, return it.
ArrayRef< BasicBlock * > getBlocks() const
BlockT * getExitingBlock() const
If getExitingBlocks would return exactly one block, return that block.
void getUniqueExitBlocks(SmallVectorImpl< BlockT * > &ExitBlocks) const
Return all unique successor blocks of this loop.
bool hasDedicatedExits() const
Return true if no exit block for the loop has a predecessor that is outside the loop.
void getUniqueNonLatchExitBlocks(SmallVectorImpl< BlockT * > &ExitBlocks) const
Return all unique successor blocks of this loop except successors from Latch block are not considered...
bool isLoopExiting(const BlockT *BB) const
True if terminator in the block can branch to another block that is outside of the current loop.
BlockT * getUniqueExitBlock() const
If getUniqueExitBlocks would return exactly one block, return that block.
This class builds and contains all of the top-level loop structures in the specified function.
SmallVector< std::pair< LoopT *, BlockT * >, 4 > recompute(const DominatorTreeBase< BlockT, false > &DomTree)
Rebuild the loop forest from the CFG, refilling the existing loop object of every block that still he...
bool hasNoExitBlocks(const LoopT &L) const
Return true if L does not have any exit blocks.
SmallVector< LoopT *, 4 > getLoopsInReverseSiblingPreorder() const
Return all of the loops in the function in preorder across the loop nests, with siblings in reverse p...
void print(raw_ostream &OS) const
SmallVector< LoopT *, 4 > getLoopsInPreorder() const
Return all of the loops in the function in preorder across the loop nests, with siblings in forward p...
LoopT * getSmallestCommonLoop(LoopT *A, LoopT *B) const
Find the innermost loop containing both given loops.
typename std::vector< LoopT * >::const_iterator iterator
iterator/begin/end - The interface to the top-level loops in the current function.
void analyze(ParentT F)
Create the loop forest for a function.
BlockT * getUniqueLatchExitBlock(const LoopT &L) const
Return the unique exit block for the latch of L, or null if there are multiple different exit blocks ...
void getExitEdges(const LoopT &L, SmallVectorImpl< Edge > &ExitEdges) const
Return all pairs of (inside_block,outside_block).
LoopT * getLoopFor(const BlockT *BB) const
Return the inner most loop that BB lives in.
void changeLoopFor(const BlockT *BB, LoopT *L)
Change the top-level loop that contains BB to the specified loop.
This class implements a map that also provides access to all stored values in a deterministic order.
ValueT lookup(const KeyT &Key) const
size_type count(ConstPtrType Ptr) const
count - Return 1 if the specified pointer is in the set, 0 otherwise.
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
reference emplace_back(ArgTypes &&... Args)
void reserve(size_type N)
void append(ItTy in_start, ItTy in_end)
Add the specified range to the end of the SmallVector.
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
An efficient, type-erasing, non-owning reference to a callable.
This class implements an extremely fast bulk output stream that can only output to a stream.
raw_ostream & indent(unsigned NumSpaces)
indent - Insert 'NumSpaces' spaces.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
decltype(&BlockT::isLegalToHoistInto) has_hoist_check
llvm::is_detected< has_hoist_check, BlockT > detect_has_hoist_check
bool isLegalToHoistInto(BlockT *Block)
SFINAE functions that dispatch to the isLegalToHoistInto member function or return false,...
NodeAddr< BlockNode * > Block
LLVM_ABI iterator begin() const
This is an optimization pass for GlobalISel generic memory operations.
iterator_range< df_ext_iterator< T, SetTy > > depth_first_ext(const T &G, SetTy &S)
Printable print(const GCNRegPressure &RP, const GCNSubtarget *ST=nullptr, unsigned DynamicVGPRBlockSize=0)
static void compareLoops(const LoopT *L, const LoopT *OtherL, DenseMap< BlockT *, const LoopT * > &OtherLoopHeaders)
auto enumerate(FirstRange &&First, RestRanges &&...Rest)
Given two or more input ranges, returns a new range whose values are tuples (A, B,...
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
auto reverse(ContainerTy &&C)
void sort(IteratorTy Start, IteratorTy End)
DominatorTreeBase< T, false > DomTreeBase
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
bool none_of(R &&Range, UnaryPredicate P)
Provide wrappers to std::none_of which take ranges instead of having to pass begin/end explicitly.
bool hasSingleElement(ContainerTy &&C)
Returns true if the given container only contains a single element.
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...
std::pair< BlockT *, bool > getExitBlockHelper(const LoopBase< BlockT, LoopT > *L, bool Unique)
getExitBlock - If getExitBlocks would return exactly one block, return that block.
std::pair< T *, bool > find_singleton_nested(R &&Range, Predicate P, bool AllowRepeats=false)
Return a pair consisting of the single value in Range that satisfies P(<member of Range> ,...
T * find_singleton(R &&Range, Predicate P, bool AllowRepeats=false)
Return the single value in Range that satisfies P(<member of Range> *, AllowRepeats)->T * returning n...
iterator_range< typename GraphTraits< Inverse< GraphType > >::ChildIteratorType > inverse_children(const typename GraphTraits< GraphType >::NodeRef &G)
void addInnerLoopsToHeadersMap(DenseMap< BlockT *, const LoopT * > &LoopHeaders, const LoopInfoBase< BlockT, LoopT > &LI, const LoopT &L)
void getUniqueExitBlocksHelper(const LoopT *L, SmallVectorImpl< BlockT * > &ExitBlocks, PredicateT Pred)
typename detail::detector< void, Op, Args... >::value_t is_detected
Detects if a given trait holds for some set of arguments 'Args'.
iterator_range< typename GraphTraits< GraphType >::ChildIteratorType > children(const typename GraphTraits< GraphType >::NodeRef &G)
bool is_contained(R &&Range, const E &Element)
Returns true if Element is found in Range.
bool compareVectors(std::vector< T > &BB1, std::vector< T > &BB2)
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Next
iterator_range< df_iterator< T > > depth_first(const T &G)
std::pair< iterator, bool > insert(NodeRef N)