#define DEBUG_TYPE "loop-simplify"
+STATISTIC(NumInserted, "Number of pre-header or exit blocks inserted");
STATISTIC(NumNested , "Number of nested loops split out");
// If the block isn't already, move the new block to right after some 'outside
return PreheaderBB;
}
+/// \brief Ensure that the loop preheader dominates all exit blocks.
+///
+/// This method is used to split exit blocks that have predecessors outside of
+/// the loop.
+static BasicBlock *rewriteLoopExitBlock(Loop *L, BasicBlock *Exit,
+ DominatorTree *DT, LoopInfo *LI,
+ bool PreserveLCSSA) {
+ SmallVector<BasicBlock*, 8> LoopBlocks;
+ for (pred_iterator I = pred_begin(Exit), E = pred_end(Exit); I != E; ++I) {
+ BasicBlock *P = *I;
+ if (L->contains(P)) {
+ // Don't do this if the loop is exited via an indirect branch.
+ if (isa<IndirectBrInst>(P->getTerminator())) return nullptr;
+
+ LoopBlocks.push_back(P);
+ }
+ }
+
+ assert(!LoopBlocks.empty() && "No edges coming in from outside the loop?");
+ BasicBlock *NewExitBB = nullptr;
+
+ NewExitBB = SplitBlockPredecessors(Exit, LoopBlocks, ".loopexit", DT, LI,
+ PreserveLCSSA);
+ if (!NewExitBB)
+ return nullptr;
+
+ DEBUG(dbgs() << "LoopSimplify: Creating dedicated exit block "
+ << NewExitBB->getName() << "\n");
+ return NewExitBB;
+}
+
/// Add the specified block, and all of its predecessors, to the specified set,
/// if it's not already in there. Stop predecessor traversal when we reach
/// StopBlock.
// Split edges to exit blocks from the inner loop, if they emerged in the
// process of separating the outer one.
- formDedicatedExitBlocks(L, DT, LI, PreserveLCSSA);
+ SmallVector<BasicBlock *, 8> ExitBlocks;
+ L->getExitBlocks(ExitBlocks);
+ SmallSetVector<BasicBlock *, 8> ExitBlockSet(ExitBlocks.begin(),
+ ExitBlocks.end());
+ for (BasicBlock *ExitBlock : ExitBlockSet) {
+ if (any_of(predecessors(ExitBlock),
+ [L](BasicBlock *BB) { return !L->contains(BB); })) {
+ rewriteLoopExitBlock(L, ExitBlock, DT, LI, PreserveLCSSA);
+ }
+ }
if (PreserveLCSSA) {
// Fix LCSSA form for L. Some values, which previously were only used inside
BasicBlock *Preheader = L->getLoopPreheader();
if (!Preheader) {
Preheader = InsertPreheaderForLoop(L, DT, LI, PreserveLCSSA);
- if (Preheader)
+ if (Preheader) {
+ ++NumInserted;
Changed = true;
+ }
}
// Next, check to make sure that all exit nodes of the loop only have
// predecessors that are inside of the loop. This check guarantees that the
// loop preheader/header will dominate the exit blocks. If the exit block has
// predecessors from outside of the loop, split the edge now.
- if (formDedicatedExitBlocks(L, DT, LI, PreserveLCSSA))
- Changed = true;
+ SmallVector<BasicBlock*, 8> ExitBlocks;
+ L->getExitBlocks(ExitBlocks);
+
+ SmallSetVector<BasicBlock *, 8> ExitBlockSet(ExitBlocks.begin(),
+ ExitBlocks.end());
+ for (BasicBlock *ExitBlock : ExitBlockSet) {
+ if (any_of(predecessors(ExitBlock),
+ [L](BasicBlock *BB) { return !L->contains(BB); })) {
+ rewriteLoopExitBlock(L, ExitBlock, DT, LI, PreserveLCSSA);
+ ++NumInserted;
+ Changed = true;
+ }
+ }
// If the header has more than two predecessors at this point (from the
// preheader and from multiple backedges), we must adjust the loop.
// insert a new block that all backedges target, then make it jump to the
// loop header.
LoopLatch = insertUniqueBackedgeBlock(L, Preheader, DT, LI);
- if (LoopLatch)
+ if (LoopLatch) {
+ ++NumInserted;
Changed = true;
+ }
}
const DataLayout &DL = L->getHeader()->getModule()->getDataLayout();
// loop-invariant instructions out of the way to open up more
// opportunities, and the disadvantage of having the responsibility
// to preserve dominator information.
- auto HasUniqueExitBlock = [&]() {
- BasicBlock *UniqueExit = nullptr;
- for (auto *ExitingBB : ExitingBlocks)
- for (auto *SuccBB : successors(ExitingBB)) {
- if (L->contains(SuccBB))
- continue;
-
- if (!UniqueExit)
- UniqueExit = SuccBB;
- else if (UniqueExit != SuccBB)
- return false;
- }
-
- return true;
- };
- if (HasUniqueExitBlock()) {
+ if (ExitBlockSet.size() == 1) {
for (unsigned i = 0, e = ExitingBlocks.size(); i != e; ++i) {
BasicBlock *ExitingBlock = ExitingBlocks[i];
if (!ExitingBlock->getSinglePredecessor()) continue;
#include "llvm/IR/ValueHandle.h"
#include "llvm/Pass.h"
#include "llvm/Support/Debug.h"
-#include "llvm/Transforms/Utils/BasicBlockUtils.h"
using namespace llvm;
using namespace llvm::PatternMatch;
return true;
}
-bool llvm::formDedicatedExitBlocks(Loop *L, DominatorTree *DT, LoopInfo *LI,
- bool PreserveLCSSA) {
- bool Changed = false;
-
- // We re-use a vector for the in-loop predecesosrs.
- SmallVector<BasicBlock *, 4> InLoopPredecessors;
-
- auto RewriteExit = [&](BasicBlock *BB) {
- // See if there are any non-loop predecessors of this exit block and
- // keep track of the in-loop predecessors.
- bool IsDedicatedExit = true;
- for (auto *PredBB : predecessors(BB))
- if (L->contains(PredBB)) {
- if (isa<IndirectBrInst>(PredBB->getTerminator()))
- // We cannot rewrite exiting edges from an indirectbr.
- return false;
-
- InLoopPredecessors.push_back(PredBB);
- } else {
- IsDedicatedExit = false;
- }
-
- // Nothing to do if this is already a dedicated exit.
- if (IsDedicatedExit) {
- InLoopPredecessors.clear();
- return false;
- }
-
- assert(!InLoopPredecessors.empty() && "Must have *some* loop predecessor!");
- auto *NewExitBB = SplitBlockPredecessors(
- BB, InLoopPredecessors, ".loopexit", DT, LI, PreserveLCSSA);
-
- if (!NewExitBB)
- DEBUG(dbgs() << "WARNING: Can't create a dedicated exit block for loop: "
- << *L << "\n");
- else
- DEBUG(dbgs() << "LoopSimplify: Creating dedicated exit block "
- << NewExitBB->getName() << "\n");
- InLoopPredecessors.clear();
- return true;
- };
-
- // Walk the exit blocks directly rather than building up a data structure for
- // them, but only visit each one once.
- SmallPtrSet<BasicBlock *, 4> Visited;
- for (auto *BB : L->blocks())
- for (auto *SuccBB : successors(BB)) {
- // We're looking for exit blocks so skip in-loop successors.
- if (L->contains(SuccBB))
- continue;
-
- // Visit each exit block exactly once.
- if (!Visited.insert(SuccBB).second)
- continue;
-
- Changed |= RewriteExit(SuccBB);
- }
-
- return Changed;
-}
-
/// \brief Returns the instructions that use values defined in the loop.
SmallVector<Instruction *, 8> llvm::findDefsUsedOutsideOfLoop(Loop *L) {
SmallVector<Instruction *, 8> UsedOutside;