[llvm] r336572 - [LoopInfo] Port loop exit interfaces from Loop to LoopBase
Diego Caballero via llvm-commits
llvm-commits at lists.llvm.org
Mon Jul 9 10:52:49 PDT 2018
Author: dcaballe
Date: Mon Jul 9 10:52:49 2018
New Revision: 336572
URL: http://llvm.org/viewvc/llvm-project?rev=336572&view=rev
Log:
[LoopInfo] Port loop exit interfaces from Loop to LoopBase
This patch ports hasDedicatedExits, getUniqueExitBlocks and
getUniqueExitBlock in Loop to LoopBase so that they can be used
from other LoopBase sub-classes.
Reviewers: chandlerc, sanjoy, hfinkel, fhahn
Reviewed By: chandlerc
Differential Revision: https://reviews.llvm.org/D48817
Modified:
llvm/trunk/include/llvm/Analysis/LoopInfo.h
llvm/trunk/include/llvm/Analysis/LoopInfoImpl.h
llvm/trunk/lib/Analysis/LoopInfo.cpp
Modified: llvm/trunk/include/llvm/Analysis/LoopInfo.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/LoopInfo.h?rev=336572&r1=336571&r2=336572&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Analysis/LoopInfo.h (original)
+++ llvm/trunk/include/llvm/Analysis/LoopInfo.h Mon Jul 9 10:52:49 2018
@@ -261,6 +261,20 @@ public:
/// Otherwise return null.
BlockT *getExitBlock() const;
+ /// Return true if no exit block for the loop has a predecessor that is
+ /// outside the loop.
+ bool hasDedicatedExits() const;
+
+ /// Return all unique successor blocks of this loop.
+ /// These are the blocks _outside of the current loop_ which are branched to.
+ /// This assumes that loop exits are in canonical form, i.e. all exits are
+ /// dedicated exits.
+ void getUniqueExitBlocks(SmallVectorImpl<BlockT *> &ExitBlocks) const;
+
+ /// If getUniqueExitBlocks would return exactly one block, return that block.
+ /// Otherwise return null.
+ BlockT *getUniqueExitBlock() const;
+
/// Edge type.
typedef std::pair<const BlockT *, const BlockT *> Edge;
@@ -553,20 +567,6 @@ public:
/// unrolling pass is run more than once (which it generally is).
void setLoopAlreadyUnrolled();
- /// Return true if no exit block for the loop has a predecessor that is
- /// outside the loop.
- bool hasDedicatedExits() const;
-
- /// Return all unique successor blocks of this loop.
- /// These are the blocks _outside of the current loop_ which are branched to.
- /// This assumes that loop exits are in canonical form, i.e. all exits are
- /// dedicated exits.
- void getUniqueExitBlocks(SmallVectorImpl<BasicBlock *> &ExitBlocks) const;
-
- /// If getUniqueExitBlocks would return exactly one block, return that block.
- /// Otherwise return null.
- BasicBlock *getUniqueExitBlock() const;
-
void dump() const;
void dumpVerbose() const;
Modified: llvm/trunk/include/llvm/Analysis/LoopInfoImpl.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/LoopInfoImpl.h?rev=336572&r1=336571&r2=336572&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Analysis/LoopInfoImpl.h (original)
+++ llvm/trunk/include/llvm/Analysis/LoopInfoImpl.h Mon Jul 9 10:52:49 2018
@@ -82,6 +82,74 @@ BlockT *LoopBase<BlockT, LoopT>::getExit
return nullptr;
}
+template <class BlockT, class LoopT>
+bool LoopBase<BlockT, LoopT>::hasDedicatedExits() const {
+ // Each predecessor of each exit block of a normal loop is contained
+ // within the loop.
+ SmallVector<BlockT *, 4> ExitBlocks;
+ getExitBlocks(ExitBlocks);
+ for (BlockT *EB : ExitBlocks)
+ for (BlockT *Predecessor : children<Inverse<BlockT *>>(EB))
+ if (!contains(Predecessor))
+ return false;
+ // All the requirements are met.
+ return true;
+}
+
+template <class BlockT, class LoopT>
+void LoopBase<BlockT, LoopT>::getUniqueExitBlocks(
+ SmallVectorImpl<BlockT *> &ExitBlocks) const {
+ typedef GraphTraits<BlockT *> BlockTraits;
+ typedef GraphTraits<Inverse<BlockT *>> InvBlockTraits;
+
+ assert(hasDedicatedExits() &&
+ "getUniqueExitBlocks assumes the loop has canonical form exits!");
+
+ SmallVector<BlockT *, 32> SwitchExitBlocks;
+ for (BlockT *Block : this->blocks()) {
+ SwitchExitBlocks.clear();
+ for (BlockT *Successor : children<BlockT *>(Block)) {
+ // If block is inside the loop then it is not an exit block.
+ if (contains(Successor))
+ continue;
+
+ BlockT *FirstPred = *InvBlockTraits::child_begin(Successor);
+
+ // If current basic block is this exit block's first predecessor then only
+ // insert exit block in to the output ExitBlocks vector. This ensures that
+ // same exit block is not inserted twice into ExitBlocks vector.
+ if (Block != FirstPred)
+ continue;
+
+ // If a terminator has more then two successors, for example SwitchInst,
+ // then it is possible that there are multiple edges from current block to
+ // one exit block.
+ if (std::distance(BlockTraits::child_begin(Block),
+ BlockTraits::child_end(Block)) <= 2) {
+ ExitBlocks.push_back(Successor);
+ continue;
+ }
+
+ // In case of multiple edges from current block to exit block, collect
+ // only one edge in ExitBlocks. Use switchExitBlocks to keep track of
+ // duplicate edges.
+ if (!is_contained(SwitchExitBlocks, Successor)) {
+ SwitchExitBlocks.push_back(Successor);
+ ExitBlocks.push_back(Successor);
+ }
+ }
+ }
+}
+
+template <class BlockT, class LoopT>
+BlockT *LoopBase<BlockT, LoopT>::getUniqueExitBlock() const {
+ SmallVector<BlockT *, 8> UniqueExitBlocks;
+ getUniqueExitBlocks(UniqueExitBlocks);
+ if (UniqueExitBlocks.size() == 1)
+ return UniqueExitBlocks[0];
+ return nullptr;
+}
+
/// getExitEdges - Return all pairs of (_inside_block_,_outside_block_).
template <class BlockT, class LoopT>
void LoopBase<BlockT, LoopT>::getExitEdges(
Modified: llvm/trunk/lib/Analysis/LoopInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/LoopInfo.cpp?rev=336572&r1=336571&r2=336572&view=diff
==============================================================================
--- llvm/trunk/lib/Analysis/LoopInfo.cpp (original)
+++ llvm/trunk/lib/Analysis/LoopInfo.cpp Mon Jul 9 10:52:49 2018
@@ -378,69 +378,6 @@ Loop::LocRange Loop::getLocRange() const
return LocRange();
}
-bool Loop::hasDedicatedExits() const {
- // Each predecessor of each exit block of a normal loop is contained
- // within the loop.
- SmallVector<BasicBlock *, 4> ExitBlocks;
- getExitBlocks(ExitBlocks);
- for (BasicBlock *BB : ExitBlocks)
- for (BasicBlock *Predecessor : predecessors(BB))
- if (!contains(Predecessor))
- return false;
- // All the requirements are met.
- return true;
-}
-
-void Loop::getUniqueExitBlocks(
- SmallVectorImpl<BasicBlock *> &ExitBlocks) const {
- assert(hasDedicatedExits() &&
- "getUniqueExitBlocks assumes the loop has canonical form exits!");
-
- SmallVector<BasicBlock *, 32> SwitchExitBlocks;
- for (BasicBlock *BB : this->blocks()) {
- SwitchExitBlocks.clear();
- for (BasicBlock *Successor : successors(BB)) {
- // If block is inside the loop then it is not an exit block.
- if (contains(Successor))
- continue;
-
- pred_iterator PI = pred_begin(Successor);
- BasicBlock *FirstPred = *PI;
-
- // If current basic block is this exit block's first predecessor
- // then only insert exit block in to the output ExitBlocks vector.
- // This ensures that same exit block is not inserted twice into
- // ExitBlocks vector.
- if (BB != FirstPred)
- continue;
-
- // If a terminator has more then two successors, for example SwitchInst,
- // then it is possible that there are multiple edges from current block
- // to one exit block.
- if (succ_size(BB) <= 2) {
- ExitBlocks.push_back(Successor);
- continue;
- }
-
- // In case of multiple edges from current block to exit block, collect
- // only one edge in ExitBlocks. Use switchExitBlocks to keep track of
- // duplicate edges.
- if (!is_contained(SwitchExitBlocks, Successor)) {
- SwitchExitBlocks.push_back(Successor);
- ExitBlocks.push_back(Successor);
- }
- }
- }
-}
-
-BasicBlock *Loop::getUniqueExitBlock() const {
- SmallVector<BasicBlock *, 8> UniqueExitBlocks;
- getUniqueExitBlocks(UniqueExitBlocks);
- if (UniqueExitBlocks.size() == 1)
- return UniqueExitBlocks[0];
- return nullptr;
-}
-
#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
LLVM_DUMP_METHOD void Loop::dump() const { print(dbgs()); }
More information about the llvm-commits
mailing list