summaryrefslogtreecommitdiff
path: root/lib/Transforms/Utils/BreakCriticalEdges.cpp
diff options
context:
space:
mode:
authorDan Gohman <gohman@apple.com>2009-09-08 15:45:00 +0000
committerDan Gohman <gohman@apple.com>2009-09-08 15:45:00 +0000
commit5c89b5240c90eb8171f999e5f06f815502d0321c (patch)
treef34aa8c5b5b7783f84d985d44c086360683dc226 /lib/Transforms/Utils/BreakCriticalEdges.cpp
parent6ca0b9e7220911a6d1fccf34e532e69c7e37cd2f (diff)
downloadllvm-5c89b5240c90eb8171f999e5f06f815502d0321c.tar.gz
llvm-5c89b5240c90eb8171f999e5f06f815502d0321c.tar.bz2
llvm-5c89b5240c90eb8171f999e5f06f815502d0321c.tar.xz
Re-apply r80926, with fixes: keep the domtree informed of new blocks
that get created during loop unswitching, and fix SplitBlockPredecessors' LCSSA updating code to create new PHIs instead of trying to just move existing ones. Also, optimize Loop::verifyLoop, since it gets called a lot. Use searches on a sorted list of blocks instead of calling the "contains" function, as is done in other places in the Loop class, since "contains" does a linear search. Also, don't call verifyLoop from LoopSimplify or LCSSA, as the PassManager is already calling verifyLoop as part of LoopInfo's verifyAnalysis. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@81221 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Transforms/Utils/BreakCriticalEdges.cpp')
-rw-r--r--lib/Transforms/Utils/BreakCriticalEdges.cpp75
1 files changed, 67 insertions, 8 deletions
diff --git a/lib/Transforms/Utils/BreakCriticalEdges.cpp b/lib/Transforms/Utils/BreakCriticalEdges.cpp
index 632aa2b723..59350a71a7 100644
--- a/lib/Transforms/Utils/BreakCriticalEdges.cpp
+++ b/lib/Transforms/Utils/BreakCriticalEdges.cpp
@@ -122,9 +122,9 @@ bool llvm::isCriticalEdge(const TerminatorInst *TI, unsigned SuccNum,
/// false otherwise. This ensures that all edges to that dest go to one block
/// instead of each going to a different block.
//
-bool llvm::SplitCriticalEdge(TerminatorInst *TI, unsigned SuccNum, Pass *P,
- bool MergeIdenticalEdges) {
- if (!isCriticalEdge(TI, SuccNum, MergeIdenticalEdges)) return false;
+BasicBlock *llvm::SplitCriticalEdge(TerminatorInst *TI, unsigned SuccNum,
+ Pass *P, bool MergeIdenticalEdges) {
+ if (!isCriticalEdge(TI, SuccNum, MergeIdenticalEdges)) return 0;
BasicBlock *TIBB = TI->getParent();
BasicBlock *DestBB = TI->getSuccessor(SuccNum);
@@ -172,7 +172,7 @@ bool llvm::SplitCriticalEdge(TerminatorInst *TI, unsigned SuccNum, Pass *P,
// If we don't have a pass object, we can't update anything...
- if (P == 0) return true;
+ if (P == 0) return NewBB;
// Now update analysis information. Since the only predecessor of NewBB is
// the TIBB, TIBB clearly dominates NewBB. TIBB usually doesn't dominate
@@ -254,9 +254,9 @@ bool llvm::SplitCriticalEdge(TerminatorInst *TI, unsigned SuccNum, Pass *P,
// Update LoopInfo if it is around.
if (LoopInfo *LI = P->getAnalysisIfAvailable<LoopInfo>()) {
- // If one or the other blocks were not in a loop, the new block is not
- // either, and thus LI doesn't need to be updated.
- if (Loop *TIL = LI->getLoopFor(TIBB))
+ if (Loop *TIL = LI->getLoopFor(TIBB)) {
+ // If one or the other blocks were not in a loop, the new block is not
+ // either, and thus LI doesn't need to be updated.
if (Loop *DestLoop = LI->getLoopFor(DestBB)) {
if (TIL == DestLoop) {
// Both in the same loop, the NewBB joins loop.
@@ -278,6 +278,65 @@ bool llvm::SplitCriticalEdge(TerminatorInst *TI, unsigned SuccNum, Pass *P,
P->addBasicBlockToLoop(NewBB, LI->getBase());
}
}
+ // If TIBB is in a loop and DestBB is outside of that loop, split the
+ // other exit blocks of the loop that also have predecessors outside
+ // the loop, to maintain a LoopSimplify guarantee.
+ if (!TIL->contains(DestBB) &&
+ P->mustPreserveAnalysisID(LoopSimplifyID)) {
+ // For each unique exit block...
+ SmallVector<BasicBlock *, 4> ExitBlocks;
+ TIL->getExitBlocks(ExitBlocks);
+ for (unsigned i = 0, e = ExitBlocks.size(); i != e; ++i) {
+ // Collect all the preds that are inside the loop, and note
+ // whether there are any preds outside the loop.
+ SmallVector<BasicBlock *, 4> Preds;
+ bool AllPredsInLoop = false;
+ BasicBlock *Exit = ExitBlocks[i];
+ for (pred_iterator I = pred_begin(Exit), E = pred_end(Exit);
+ I != E; ++I)
+ if (TIL->contains(*I))
+ Preds.push_back(*I);
+ else
+ AllPredsInLoop = true;
+ // If there are any preds not in the loop, we'll need to split
+ // the edges. The Preds.empty() check is needed because a block
+ // may appear multiple times in the list. We can't use
+ // getUniqueExitBlocks above because that depends on LoopSimplify
+ // form, which we're in the process of restoring!
+ if (Preds.empty() || !AllPredsInLoop) continue;
+ BasicBlock *NewBB = SplitBlockPredecessors(Exit,
+ Preds.data(), Preds.size(),
+ "split", P);
+ // Update LCSSA form by creating new PHIs in the new exit blocks
+ // as needed.
+ if (P->mustPreserveAnalysisID(LCSSAID))
+ for (BasicBlock::iterator I = Exit->begin();
+ PHINode *PN = dyn_cast<PHINode>(I); ++I) {
+ unsigned Idx = PN->getBasicBlockIndex(NewBB);
+ Value *V = PN->getIncomingValue(Idx);
+ // If the PHI is already suitable, don't create a new one.
+ if (PHINode *VP = dyn_cast<PHINode>(V))
+ if (VP->getParent() == NewBB)
+ continue;
+ // A new PHI is needed. Create one and populate it.
+ PHINode *NewPN =
+ PHINode::Create(PN->getType(), "split", NewBB->getTerminator());
+ for (unsigned i = 0, e = Preds.size(); i != e; ++i)
+ NewPN->addIncoming(V, Preds[i]);
+ PN->setIncomingValue(Idx, NewPN);
+ }
+ }
+ }
+ // LCSSA form was updated above for the case where LoopSimplify is
+ // available, which means that all predecessors of loop exit blocks
+ // are within the loop. Without LoopSimplify form, it would be
+ // necessary to insert a new phi.
+ assert((!P->mustPreserveAnalysisID(LCSSAID) ||
+ P->mustPreserveAnalysisID(LoopSimplifyID)) &&
+ "SplitCriticalEdge doesn't know how to update LCCSA form "
+ "without LoopSimplify!");
+ }
}
- return true;
+
+ return NewBB;
}