40#ifndef LLVM_SUPPORT_GENERICLOOPINFO_H 
   41#define LLVM_SUPPORT_GENERICLOOPINFO_H 
   53template <
class N, 
class M> 
class LoopBase;
 
   59template <
class BlockT, 
class LoopT> 
class LoopBase {
 
   62  std::vector<LoopT *> SubLoops;
 
   65  std::vector<BlockT *> Blocks;
 
   69#if LLVM_ENABLE_ABI_BREAKING_CHECKS 
   71  bool IsInvalid = 
false;
 
   74  LoopBase(
const LoopBase<BlockT, LoopT> &) = 
delete;
 
   75  const LoopBase<BlockT, LoopT> &
 
   76  operator=(
const LoopBase<BlockT, LoopT> &) = 
delete;
 
   85    for (
const LoopT *CurLoop = ParentLoop; CurLoop;
 
   86         CurLoop = CurLoop->ParentLoop)
 
 
  104    const LoopT *L = 
static_cast<const LoopT *
>(
this);
 
  105    while (L->ParentLoop)
 
 
  111    LoopT *L = 
static_cast<LoopT *
>(
this);
 
  112    while (L->ParentLoop)
 
 
  130    return contains(L->getParentLoop());
 
 
  136    return DenseBlockSet.count(BB);
 
 
  140  template <
class InstT> 
bool contains(
const InstT *Inst)
 const {
 
 
  153  typedef typename std::vector<LoopT *>::const_iterator 
iterator;
 
  189    return Blocks.size();
 
 
  202    return DenseBlockSet;
 
 
  208    return DenseBlockSet;
 
 
  218#if LLVM_ENABLE_ABI_BREAKING_CHECKS 
 
  251                          [&](BlockT *Pred) { 
return contains(Pred); });
 
 
  305  typedef std::pair<BlockT *, BlockT *> 
Edge;
 
  340  template <
class Type>
 
  344    PreOrderWorklist.
append(L.rbegin(), L.rend());
 
  346    while (!PreOrderWorklist.
empty()) {
 
  350      PreOrderWorklist.
append(L->rbegin(), L->rend());
 
 
  359    const LoopT *CurLoop = 
static_cast<const LoopT *
>(
this);
 
  362    return PreOrderLoops;
 
 
  366    LoopT *CurLoop = 
static_cast<LoopT *
>(
this);
 
  369    return PreOrderLoops;
 
 
  393    assert(!NewChild->ParentLoop && 
"NewChild already has a parent!");
 
  394    NewChild->ParentLoop = 
static_cast<LoopT *
>(
this);
 
  395    SubLoops.push_back(NewChild);
 
 
  402    assert(
I != SubLoops.end() && 
"Cannot remove end iterator!");
 
  404    assert(Child->ParentLoop == 
this && 
"Child is not a child of this loop!");
 
  405    SubLoops.erase(SubLoops.begin() + (
I - 
begin()));
 
  406    Child->ParentLoop = 
nullptr;
 
 
  421    Blocks.push_back(BB);
 
  422    DenseBlockSet.insert(BB);
 
 
  428    std::reverse(Blocks.begin() + from, Blocks.end());
 
 
  434    Blocks.reserve(
size);
 
 
  443    for (
unsigned i = 0;; ++i) {
 
  444      assert(i != Blocks.size() && 
"Loop does not contain BB!");
 
  445      if (Blocks[i] == BB) {
 
  446        Blocks[i] = Blocks[0];
 
 
  458    auto I = 
find(Blocks, BB);
 
  459    assert(
I != Blocks.end() && 
"N is not in this list!");
 
  462    DenseBlockSet.erase(BB);
 
 
  479             unsigned Depth = 0) 
const;
 
  487  explicit LoopBase(BlockT *BB) : ParentLoop(nullptr) {
 
  488    Blocks.push_back(BB);
 
  489    DenseBlockSet.insert(BB);
 
 
  502    for (
auto *SubLoop : SubLoops)
 
  505#if LLVM_ENABLE_ABI_BREAKING_CHECKS 
  510    DenseBlockSet.clear();
 
  511    ParentLoop = 
nullptr;
 
 
 
  515template <
class BlockT, 
class LoopT>
 
  526template <
class BlockT, 
class LoopT> 
class LoopInfoBase {
 
  529  std::vector<LoopT *> TopLevelLoops;
 
  532  friend class LoopBase<BlockT, LoopT>;
 
  535  void operator=(
const LoopInfoBase &) = 
delete;
 
  544        TopLevelLoops(
std::
move(Arg.TopLevelLoops)),
 
  545        LoopAllocator(
std::
move(Arg.LoopAllocator)) {
 
  547    Arg.TopLevelLoops.clear();
 
 
  550    BBMap = std::move(
RHS.BBMap);
 
  552    for (
auto *L : TopLevelLoops)
 
  555    TopLevelLoops = std::move(
RHS.TopLevelLoops);
 
  556    LoopAllocator = std::move(
RHS.LoopAllocator);
 
  557    RHS.TopLevelLoops.clear();
 
 
  564    for (
auto *L : TopLevelLoops)
 
  566    TopLevelLoops.clear();
 
  567    LoopAllocator.Reset();
 
 
  571    LoopT *Storage = LoopAllocator.Allocate<LoopT>();
 
  572    return new (Storage) LoopT(std::forward<ArgsTy>(Args)...);
 
 
  578  typedef typename std::vector<LoopT *>::const_iterator 
iterator;
 
  585  bool empty()
 const { 
return TopLevelLoops.empty(); }
 
  606  LoopT *
getLoopFor(
const BlockT *BB)
 const { 
return BBMap.lookup(BB); }
 
  615    return L ? L->getLoopDepth() : 0;
 
 
  632    return L && L->getHeader() == BB;
 
 
  645    assert(
I != 
end() && 
"Cannot remove end iterator!");
 
  647    assert(L->isOutermost() && 
"Not a top-level loop!");
 
  648    TopLevelLoops.erase(TopLevelLoops.begin() + (
I - 
begin()));
 
 
  666    auto I = 
find(TopLevelLoops, OldLoop);
 
  667    assert(
I != TopLevelLoops.end() && 
"Old loop not at top level!");
 
  669    assert(!NewLoop->ParentLoop && !OldLoop->ParentLoop &&
 
  670           "Loops already embedded into a subloop!");
 
 
  675    assert(New->isOutermost() && 
"Loop already in subloop!");
 
  676    TopLevelLoops.push_back(New);
 
 
  683    auto I = BBMap.find(BB);
 
  684    if (
I != BBMap.end()) {
 
  685      for (LoopT *L = 
I->second; L; L = L->getParentLoop())
 
  686        L->removeBlockFromLoop(BB);
 
 
  695                                      const LoopT *ParentLoop) {
 
  698    if (SubLoop == ParentLoop)
 
 
  726    LoopAllocator.Deallocate(L);
 
 
 
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
This file defines the BumpPtrAllocator interface.
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
This file defines the DenseSet and SmallDenseSet classes.
This file defines a set of templates that efficiently compute a dominator tree over a generic graph.
This file builds on the ADT/GraphTraits.h file to build a generic graph post order iterator.
This file defines generic set operations that may be used on set's of different types,...
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
const_pointer const_iterator
Implements a dense probed hash-table based set.
Core dominator tree base class.
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.
bool contains(const LoopT *L) const
Return true if the specified loop is contained within in this loop.
SmallPtrSetImpl< const BlockT * > & getBlocksSet()
Return a direct, mutable handle to the blocks set so that we can mutate it efficiently.
static void getInnerLoopsInPreorder(const LoopT &L, SmallVectorImpl< Type > &PreOrderLoops)
Return all inner loops in the loop nest rooted by the loop in preorder, with siblings in forward prog...
bool isOutermost() const
Return true if the loop does not have a parent (natural) loop.
BlockT * getLoopLatch() const
If there is a single latch block for this loop, return it.
bool isInnermost() const
Return true if the loop does not contain any (natural) loops.
void removeBlockFromLoop(BlockT *BB)
This removes the specified basic block from the current loop, updating the Blocks as appropriate.
void getExitBlocks(SmallVectorImpl< BlockT * > &ExitBlocks) const
Return all of the successor blocks of this loop.
bool contains(const InstT *Inst) const
Return true if the specified instruction is in 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.
SmallVector< LoopT *, 4 > getLoopsInPreorder()
unsigned getNumBackEdges() const
Calculate the number of back edges to the loop header.
void reverseBlock(unsigned from)
interface to reverse Blocks[from, end of loop] in this loop
SmallVector< const LoopT *, 4 > getLoopsInPreorder() const
Return all loops in the loop nest rooted by the loop in preorder, with siblings in forward program or...
BlockT * getUniqueLatchExitBlock() const
Return the unique exit block for the latch, or null if there are multiple different exit blocks or th...
void getExitingBlocks(SmallVectorImpl< BlockT * > &ExitingBlocks) const
Return all blocks inside the loop that have successors outside of the loop.
const std::vector< LoopT * > & getSubLoops() const
Return the loops contained entirely within this loop.
BlockT * getHeader() const
const LoopT * getOutermostLoop() const
Get the outermost loop in which this loop is contained.
void getLoopLatches(SmallVectorImpl< BlockT * > &LoopLatches) const
Return all loop latch blocks of this loop.
unsigned getLoopDepth() const
Return the nesting level of this loop.
LoopBase()
This creates an empty 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.
std::vector< BlockT * > & getBlocksVector()
Return a direct, mutable handle to the blocks vector so that we can mutate it efficiently with techni...
std::vector< LoopT * >::const_reverse_iterator reverse_iterator
LoopT * removeChildLoop(LoopT *Child)
This removes the specified child from being a subloop of this loop.
std::vector< LoopT * >::const_iterator iterator
void reserveBlocks(unsigned size)
interface to do reserve() for Blocks
iterator_range< block_iterator > blocks() const
block_iterator block_end() const
std::pair< BlockT *, BlockT * > Edge
Edge type.
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 contains(const BlockT *BB) const
Return true if the specified basic block is in this loop.
bool isLoopLatch(const BlockT *BB) const
void addChildLoop(LoopT *NewChild)
Add the specified loop to be a child of this loop.
void getExitEdges(SmallVectorImpl< Edge > &ExitEdges) const
Return all pairs of (inside_block,outside_block).
void addBlockEntry(BlockT *BB)
This adds a basic block directly to the basic block list.
ArrayRef< BlockT * >::const_iterator block_iterator
std::vector< LoopT * > & getSubLoopsVector()
reverse_iterator rbegin() const
BlockT * getExitBlock() const
If getExitBlocks would return exactly one block, return that block.
bool hasNoExitBlocks() const
Return true if this loop does not have any exit blocks.
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< BlockT * > getBlocks() const
Get a list of the basic blocks which make up this loop.
reverse_iterator rend() const
BlockT * getExitingBlock() const
If getExitingBlocks would return exactly one block, return that block.
LoopT * getOutermostLoop()
void getUniqueExitBlocks(SmallVectorImpl< BlockT * > &ExitBlocks) const
Return all unique successor blocks of this loop.
void setParentLoop(LoopT *L)
This is a raw interface for bypassing addChildLoop.
LoopT * getParentLoop() const
Return the parent loop if it exists or nullptr for top level loops.
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...
const SmallPtrSetImpl< const BlockT * > & getBlocksSet() const
Return a direct, immutable handle to the blocks set.
bool isLoopExiting(const BlockT *BB) const
True if terminator in the block can branch to another block that is outside of the current loop.
block_iterator block_begin() const
void moveToHeader(BlockT *BB)
This method is used to move BB (which must be part of this loop) to be the loop header of the loop (t...
BlockT * getUniqueExitBlock() const
If getUniqueExitBlocks would return exactly one block, return that block.
LoopT * removeChildLoop(iterator I)
This removes the specified child from being a subloop of this loop.
This class builds and contains all of the top-level loop structures in the specified function.
const std::vector< LoopT * > & getTopLevelLoops() const
Return the top-level loops.
void verify(const DominatorTreeBase< BlockT, false > &DomTree) const
void addTopLevelLoop(LoopT *New)
This adds the specified loop to the collection of top-level loops.
void analyze(const DominatorTreeBase< BlockT, false > &DomTree)
Create the loop forest using a stable algorithm.
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
reverse_iterator rend() const
void changeTopLevelLoop(LoopT *OldLoop, LoopT *NewLoop)
Replace the specified loop in the top-level loops list with the indicated loop.
void removeBlock(BlockT *BB)
This method completely removes BB from all data structures, including all of the Loop objects it is n...
LoopInfoBase(LoopInfoBase &&Arg)
LoopT * AllocateLoop(ArgsTy &&...Args)
const LoopT * operator[](const BlockT *BB) const
Same as getLoopFor.
bool isLoopHeader(const BlockT *BB) const
LoopT * removeLoop(iterator I)
This removes the specified top-level loop from this loop info object.
LoopT * getSmallestCommonLoop(BlockT *A, BlockT *B) const
Find the innermost loop containing both given blocks.
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.
void changeLoopFor(BlockT *BB, LoopT *L)
Change the top-level loop that contains BB to the specified loop.
unsigned getLoopDepth(const BlockT *BB) const
Return the loop nesting level of the specified block.
std::vector< LoopT * > & getTopLevelLoopsVector()
Return the top-level loops.
static bool isNotAlreadyContainedIn(const LoopT *SubLoop, const LoopT *ParentLoop)
std::vector< Loop * >::const_reverse_iterator reverse_iterator
reverse_iterator rbegin() const
LoopT * getLoopFor(const BlockT *BB) const
Return the inner most loop that BB lives in.
LoopInfoBase & operator=(LoopInfoBase &&RHS)
void destroy(LoopT *L)
Destroy a loop that has been removed from the LoopInfo nest.
std::vector< Loop * >::const_iterator iterator
Represents a single loop in the control flow graph.
A templated base class for SmallPtrSet which provides the typesafe interface that is common across al...
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...
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.
A range adaptor for a pair of iterators.
This class implements an extremely fast bulk output stream that can only output to a stream.
This is an optimization pass for GlobalISel generic memory operations.
auto find(R &&Range, const T &Val)
Provide wrappers to std::find which take ranges instead of having to pass begin/end explicitly.
auto size(R &&Range, std::enable_if_t< std::is_base_of< std::random_access_iterator_tag, typename std::iterator_traits< decltype(Range.begin())>::iterator_category >::value, void > *=nullptr)
Get the size of a range.
iterator_range< T > make_range(T x, T y)
Convenience function for iterating over sub-ranges.
BumpPtrAllocatorImpl BumpPtrAllocator
The standard BumpPtrAllocator which just uses the default template parameters.
iterator_range< typename GraphTraits< Inverse< GraphType > >::ChildIteratorType > inverse_children(const typename GraphTraits< GraphType >::NodeRef &G)
raw_ostream & operator<<(raw_ostream &OS, const APFixedPoint &FX)
OutputIt move(R &&Range, OutputIt Out)
Provide wrappers to std::move which take ranges instead of having to pass begin/end explicitly.
auto count_if(R &&Range, UnaryPredicate P)
Wrapper function around std::count_if to count the number of times an element satisfying a given pred...
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.
Implement std::hash so that hash_code can be used in STL containers.