14#ifndef LLVM_SUPPORT_GENERICLOOPINFOIMPL_H
15#define LLVM_SUPPORT_GENERICLOOPINFOIMPL_H
32template <
class BlockT,
class LoopT>
36 for (
const auto BB :
blocks())
47template <
class BlockT,
class LoopT>
50 auto notInLoop = [&](BlockT *BB) {
return !
contains(BB); };
51 auto isExitBlock = [&](BlockT *BB,
bool AllowRepeats) -> BlockT * {
52 assert(!AllowRepeats &&
"Unexpected parameter value.");
63template <
class BlockT,
class LoopT>
67 for (
const auto BB :
blocks())
76template <
class BlockT,
class LoopT>
79 assert(!L->isInvalid() &&
"Loop not in a valid state!");
80 auto notInLoop = [&](BlockT *BB,
81 bool AllowRepeats) -> std::pair<BlockT *, bool> {
82 assert(AllowRepeats == Unique &&
"Unexpected parameter value.");
83 return {!L->contains(BB) ? BB :
nullptr,
false};
85 auto singleExitBlock = [&](BlockT *BB,
86 bool AllowRepeats) -> std::pair<BlockT *, bool> {
87 assert(AllowRepeats == Unique &&
"Unexpected parameter value.");
94template <
class BlockT,
class LoopT>
106template <
class BlockT,
class LoopT>
111template <
class BlockT,
class LoopT>
117 for (BlockT *EB : UniqueExitBlocks)
127template <
class BlockT,
class LoopT,
typename PredicateT>
131 assert(!L->isInvalid() &&
"Loop not in a valid state!");
134 for (BlockT *BB : Filtered)
141template <
class BlockT,
class LoopT>
145 [](
const BlockT *BB) {
return true; });
148template <
class BlockT,
class LoopT>
152 assert(Latch &&
"Latch block must exists");
154 [Latch](
const BlockT *BB) {
return BB != Latch; });
157template <
class BlockT,
class LoopT>
162template <
class BlockT,
class LoopT>
165 BlockT *Latch = L.getLoopLatch();
166 assert(Latch &&
"Latch block must exists");
167 auto IsExitBlock = [&L](BlockT *BB,
bool AllowRepeats) -> BlockT * {
168 assert(!AllowRepeats &&
"Unexpected parameter value.");
169 return !L.contains(BB) ? BB :
nullptr;
175template <
class BlockT,
class LoopT>
178 for (
const auto BB : L.blocks())
180 if (!L.contains(Succ))
186template <
class BlockT>
189template <
class BlockT>
196 return Block->isLegalToHoistInto();
209template <
class BlockT,
class LoopT>
234template <
class BlockT,
class LoopT>
238 BlockT *Out =
nullptr;
244 if (Out && Out != Pred)
255template <
class BlockT,
class LoopT>
259 BlockT *Latch =
nullptr;
281template <
class BlockT,
class LoopT>
289 "Incorrect LI specified for this loop!");
292 assert(NewBB &&
"Cannot add a null basic block to the loop!");
293 assert(!LIB[NewBB] &&
"BasicBlock already in the loop!");
295 LoopT *L =
static_cast<LoopT *
>(
this);
302 L->addBlockEntry(NewBB);
303 L = L->getParentLoop();
311template <
class BlockT,
class LoopT>
315 assert(OldChild->ParentLoop ==
this &&
"This loop is already broken!");
316 assert(!NewChild->ParentLoop &&
"NewChild already has a parent!");
317 typename std::vector<LoopT *>::iterator
I =
find(SubLoops, OldChild);
318 assert(
I != SubLoops.end() &&
"OldChild not in loop!");
320 OldChild->ParentLoop =
nullptr;
321 NewChild->ParentLoop =
static_cast<LoopT *
>(
this);
325template <
class BlockT,
class LoopT>
344 "Loop block has no in-loop successors!");
348 "Loop block has no in-loop predecessors!");
356 assert(!OutsideLoopPreds.empty() &&
"Loop is unreachable!");
357 }
else if (!OutsideLoopPreds.empty()) {
361 BlockT *EntryBB = &BB->getParent()->front();
363 for (
unsigned i = 0, e = OutsideLoopPreds.size(); i != e; ++i)
364 assert(CB != OutsideLoopPreds[i] &&
365 "Loop has multiple entry points!");
368 "Loop contains function entry block!");
374 dbgs() <<
"The following blocks are unreachable in the loop: ";
376 if (!VisitedBBs.
count(BB)) {
377 dbgs() << *BB <<
"\n";
380 assert(
false &&
"Unreachable block in loop");
386 for (block_iterator BI = (*I)->block_begin(), BE = (*I)->block_end();
389 "Loop does not contain all the blocks of a subloop!");
395 "Loop is not a subloop of its parent!");
401template <
class BlockT,
class LoopT>
405 Loops->insert(
static_cast<const LoopT *
>(
this));
410 (*I)->verifyLoopNest(
Loops);
413template <
class BlockT,
class LoopT>
415 bool PrintNested,
unsigned Depth)
const {
419 OS <<
"Loop at depth " <<
getLoopDepth() <<
" containing: ";
422 for (
unsigned i = 0; i <
getBlocks().size(); ++i) {
427 BB->printAsOperand(OS,
false);
446 (*I)->print(OS,
false, PrintNested,
Depth + 2);
462template <
class BlockT,
class LoopT>
468template <
class BlockT,
class LoopT>
477template <
class BlockT,
class LoopT>
480 using BlockTraits = GraphTraits<BlockT *>;
481 auto num = [](
const BlockT *BB) {
482 return GraphTraits<const BlockT *>::getNumber(BB);
490 constexpr unsigned NoBlock = ~0
u;
493 constexpr unsigned Unvisited = 0;
494 constexpr unsigned OffPath = 1;
495 constexpr unsigned IsHeader = 2;
496 constexpr unsigned IsReentered = 3;
497 constexpr unsigned FirstOnPath = IsReentered + 1;
505 unsigned LoopHeader = 0;
518 auto tagLoopHeader = [&](
unsigned B,
unsigned H) {
522 unsigned IH =
Info[
B].LoopHeader;
529 if (Info[IH].Pos >= Info[
H].Pos) {
547 typename BlockTraits::ChildIteratorType Cur, End;
550 unsigned Counter = FirstOnPath;
551 auto open = [&](BlockT *BB) {
552 unsigned B = num(BB);
553 Info[
B].Pos = Counter++;
554 Info[
B].LoopHeader = NoBlock;
556 {BB, BlockTraits::child_begin(BB), BlockTraits::child_end(BB)});
560 while (!
Stack.empty()) {
561 Frame &Top =
Stack.back();
562 if (Top.Cur == Top.End) {
564 unsigned B0 = num(Top.Block);
565 Info[B0].Pos = OffPath;
566 Postorder.push_back(Top.Block);
568 if (!
Stack.empty() && Info[B0].LoopHeader != NoBlock)
569 tagLoopHeader(num(
Stack.back().Block), Info[B0].LoopHeader);
572 BlockT *B0P = Top.Block;
573 BlockT *B1P = *Top.Cur++;
574 unsigned B1 = num(B1P);
575 if (Info[B1].Pos == Unvisited) {
578 }
else if (Info[B1].Pos >= FirstOnPath) {
580 Headers.push_back(B1);
581 tagLoopHeader(num(B0P), B1);
587 for (
unsigned H = Info[B1].LoopHeader;
H != NoBlock;
589 if (Info[
H].Pos >= FirstOnPath) {
590 tagLoopHeader(num(B0P),
H);
602 for (
unsigned H : Headers)
603 Info[
H].Pos = IsHeader;
605 if (!Reentries.empty()) {
610 for (
unsigned H : Reentries)
611 Info[
H].Pos = IsReentered;
623 for (BlockT *BB : Postorder) {
624 unsigned B = num(BB);
626 if (
unsigned P = Info[
B].LoopHeader;
P != NoBlock) {
627 NextSibling[
B] = FirstChild[
P];
631 for (BlockT *Header : Postorder) {
632 unsigned H = num(Header);
633 if (Info[
H].Pos != IsReentered)
637 auto enqueue = [&](BlockT *Pred) {
638 unsigned P = num(Pred);
641 for (
unsigned A =
P;
A != NoBlock;
A = Info[
A].LoopHeader)
642 if (Info[
A].LoopHeader ==
H) {
655 assert(DomNode &&
"header missing from the dominator tree");
656 bool HasBackedge =
false;
659 if (PredNode && DomTree.
dominates(DomNode, PredNode)) {
665 for (
unsigned I = 0;
I != Worklist.
size(); ++
I)
668 if (Blocks[num(Pred)])
671 Info[
H].Pos = HasBackedge ? IsHeader : OffPath;
675 unsigned Parent =
Info[
H].LoopHeader;
676 unsigned Kept = NoBlock;
677 for (
unsigned B = FirstChild[
H],
Next;
B != NoBlock;
B =
Next) {
678 Next = NextSibling[
B];
680 NextSibling[
B] = Kept;
684 Info[
B].LoopHeader = Parent;
685 if (Parent != NoBlock) {
686 NextSibling[
B] = FirstChild[Parent];
687 FirstChild[Parent] =
B;
691 FirstChild[
H] = Kept;
693 if (
none_of(Headers, [&](
unsigned H) {
return Info[
H].Pos == IsHeader; }))
699 BBMap.resize(MaxNumber);
701 unsigned B = num(BB);
702 unsigned H =
Info[
B].LoopHeader;
703 LoopT *Enclosing =
H == NoBlock ? nullptr : BBMap[
H];
704 LoopT *
L = Enclosing;
705 if (Info[
B].Pos == IsHeader) {
706 L = allocateLoop(BB);
707 L->setParentLoop(Enclosing);
717 for (BlockT *BB : Postorder) {
718 LoopT *L = lookupLoopFor(BB);
723 if (BB != pendingHeader(L))
726 if (LoopT *Parent = L->getParentLoop())
727 Parent->BlockLen += L->BlockLen;
729 TopLevelLoops.push_back(L);
732 assert(!LoopsPO.
empty() &&
"discovered loops but found no header");
734 BlockLayout.reset(
new BlockT *[PO.
size()]);
735 BlockT **RootCursor = BlockLayout.get();
737 if (L->BlockCapacity == 0) {
740 if (LoopT *Parent = L->getParentLoop()) {
741 assert(Parent->BlockCapacity != 0 &&
742 "parent slice not carved before child");
743 L->BlockData = Parent->BlockData + Parent->BlockCapacity;
744 Parent->BlockCapacity += L->BlockLen;
745 Parent->SubLoops.push_back(L);
747 L->BlockData = RootCursor;
748 RootCursor += L->BlockLen;
752 L->BlockData[
L->BlockCapacity++] = BB;
757 for (LoopT *L : LoopsPO) {
758 assert(
L->BlockCapacity ==
L->BlockLen &&
"layout slice not fully used");
759 L->BlockCapacity = LoopT::BorrowedCapacity;
763template <
class BlockT,
class LoopT>
772 for (LoopT *RootL :
reverse(*
this)) {
774 LoopT::getInnerLoopsInPreorder(*RootL, PreOrderLoops);
777 return PreOrderLoops;
780template <
class BlockT,
class LoopT>
789 for (LoopT *RootL : *
this) {
791 "Must start with an empty preorder walk worklist.");
797 PreOrderWorklist.
append(L->begin(), L->end());
799 }
while (!PreOrderWorklist.
empty());
802 return PreOrderLoops;
805template <
class BlockT,
class LoopT>
813 unsigned DepthA =
A->getLoopDepth(), DepthB =
B->getLoopDepth();
814 for (; DepthA > DepthB; --DepthA)
815 A =
A->getParentLoop();
816 for (; DepthB > DepthA; --DepthB)
817 B =
B->getParentLoop();
823 A =
A->getParentLoop();
824 B =
B->getParentLoop();
830template <
class BlockT,
class LoopT>
837template <
class BlockT,
class LoopT>
839 for (
unsigned i = 0; i < TopLevelLoops.size(); ++i)
840 TopLevelLoops[i]->
print(OS);
850template <
class BlockT,
class LoopT>
854 LoopHeaders[L.getHeader()] = &L;
860template <
class BlockT,
class LoopT>
863 BlockT *
H = L->getHeader();
864 BlockT *OtherH = OtherL->getHeader();
866 "Mismatched headers even though found in the same map entry!");
868 assert(L->getLoopDepth() == OtherL->getLoopDepth() &&
869 "Mismatched loop depth!");
870 const LoopT *ParentL = L, *OtherParentL = OtherL;
872 assert(ParentL->getHeader() == OtherParentL->getHeader() &&
873 "Mismatched parent loop headers!");
874 ParentL = ParentL->getParentLoop();
875 OtherParentL = OtherParentL->getParentLoop();
878 for (
const LoopT *SubL : *L) {
879 BlockT *SubH = SubL->getHeader();
880 const LoopT *OtherSubL = OtherLoopHeaders.
lookup(SubH);
881 assert(OtherSubL &&
"Inner loop is missing in computed loop info!");
882 OtherLoopHeaders.
erase(SubH);
886 std::vector<BlockT *> BBs = L->getBlocks();
887 std::vector<BlockT *> OtherBBs = OtherL->getBlocks();
889 "Mismatched basic blocks in the loops!");
893template <
class BlockT,
class LoopT>
897 assert((*I)->isOutermost() &&
"Top-level loop has a parent!");
898 (*I)->verifyLoopNest(&
Loops);
904 for (
const LoopT *L :
Loops)
905 assert(L->LI ==
this &&
"Loop has a stale owning-LoopInfo back-pointer");
912 while (!Worklist.
empty()) {
916 for (
const BlockT *BB : L->getBlocks()) {
921 Worklist.
append(L->begin(), L->end());
927 "BBMap should point to the innermost loop containing the block");
931 LoopInfoBase<BlockT, LoopT> OtherLI;
938 for (LoopT *L : OtherLI)
944 for (LoopT *L : *
this) {
945 BlockT *Header = L->getHeader();
946 const LoopT *OtherL = OtherLoopHeaders.
lookup(Header);
947 assert(OtherL &&
"Top level loop is missing in computed loop info!");
949 OtherLoopHeaders.
erase(Header);
956 if (!OtherLoopHeaders.
empty()) {
957 for (
const auto &HeaderAndLoop : OtherLoopHeaders)
958 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 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.
DomTreeNodeBase< NodeT > * getRootNode()
getRootNode - This returns the entry node for the CFG of the function.
bool dominates(const DomTreeNodeBase< NodeT > *A, const DomTreeNodeBase< NodeT > *B) const
dominates - Returns true iff A dominates B.
void updateDFSNumbers() const
updateDFSNumbers - Assign In and Out numbers to the nodes while walking dominator tree in dfs order.
void recalculate(ParentType &Func)
recalculate - compute a dominator tree for the given function
DomTreeNodeBase< NodeT > * getNode(const NodeT *BB) const
getNode - return the (Post)DominatorTree node for the specified basic block.
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.
unsigned getNumBlocks() const
Get the number of blocks in this loop in constant time.
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.
void replaceChildLoopWith(LoopT *OldChild, LoopT *NewChild)
This is used when splitting loops up.
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.
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.
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.
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
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)
auto find(R &&Range, const T &Val)
Provide wrappers to std::find which take ranges instead of having to pass begin/end explicitly.
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...
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
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)