aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/Transforms/Scalar/LoopRotation.cpp17
-rw-r--r--lib/Transforms/Utils/BreakCriticalEdges.cpp75
-rw-r--r--test/Transforms/LoopUnswitch/preserve-analyses.ll34
3 files changed, 86 insertions, 40 deletions
diff --git a/lib/Transforms/Scalar/LoopRotation.cpp b/lib/Transforms/Scalar/LoopRotation.cpp
index 4b10d1006e..ca394bdc46 100644
--- a/lib/Transforms/Scalar/LoopRotation.cpp
+++ b/lib/Transforms/Scalar/LoopRotation.cpp
@@ -542,22 +542,7 @@ void LoopRotate::preserveCanonicalLoopForm(LPPassManager &LPM) {
// Preserve canonical loop form, which means Exit block should
// have only one predecessor.
- BasicBlock *NExit = SplitEdge(L->getLoopLatch(), Exit, this);
-
- // Preserve LCSSA.
- for (BasicBlock::iterator I = Exit->begin();
- (PN = dyn_cast<PHINode>(I)); ++I) {
- unsigned N = PN->getNumIncomingValues();
- for (unsigned index = 0; index != N; ++index)
- if (PN->getIncomingBlock(index) == NExit) {
- PHINode *NewPN = PHINode::Create(PN->getType(), PN->getName(),
- NExit->begin());
- NewPN->addIncoming(PN->getIncomingValue(index), L->getLoopLatch());
- PN->setIncomingValue(index, NewPN);
- PN->setIncomingBlock(index, NExit);
- break;
- }
- }
+ SplitEdge(L->getLoopLatch(), Exit, this);
assert(NewHeader && L->getHeader() == NewHeader &&
"Invalid loop header after loop rotation");
diff --git a/lib/Transforms/Utils/BreakCriticalEdges.cpp b/lib/Transforms/Utils/BreakCriticalEdges.cpp
index 5c0afbeece..849b2b5d5c 100644
--- a/lib/Transforms/Utils/BreakCriticalEdges.cpp
+++ b/lib/Transforms/Utils/BreakCriticalEdges.cpp
@@ -117,6 +117,38 @@ bool llvm::isCriticalEdge(const TerminatorInst *TI, unsigned SuccNum,
return false;
}
+/// CreatePHIsForSplitLoopExit - When a loop exit edge is split, LCSSA form
+/// may require new PHIs in the new exit block. This function inserts the
+/// new PHIs, as needed. Preds is a list of preds inside the loop, SplitBB
+/// is the new loop exit block, and DestBB is the old loop exit, now the
+/// successor of SplitBB.
+static void CreatePHIsForSplitLoopExit(SmallVectorImpl<BasicBlock *> &Preds,
+ BasicBlock *SplitBB,
+ BasicBlock *DestBB) {
+ // SplitBB shouldn't have anything non-trivial in it yet.
+ assert(SplitBB->getFirstNonPHI() == SplitBB->getTerminator() &&
+ "SplitBB has non-PHI nodes!");
+
+ // For each PHI in the destination block...
+ for (BasicBlock::iterator I = DestBB->begin();
+ PHINode *PN = dyn_cast<PHINode>(I); ++I) {
+ unsigned Idx = PN->getBasicBlockIndex(SplitBB);
+ Value *V = PN->getIncomingValue(Idx);
+ // If the input is a PHI which already satisfies LCSSA, don't create
+ // a new one.
+ if (const PHINode *VP = dyn_cast<PHINode>(V))
+ if (VP->getParent() == SplitBB)
+ continue;
+ // Otherwise a new PHI is needed. Create one and populate it.
+ PHINode *NewPN = PHINode::Create(PN->getType(), "split",
+ SplitBB->getTerminator());
+ for (unsigned i = 0, e = Preds.size(); i != e; ++i)
+ NewPN->addIncoming(V, Preds[i]);
+ // Update the original PHI.
+ PN->setIncomingValue(Idx, NewPN);
+ }
+}
+
/// SplitCriticalEdge - If this edge is a critical edge, insert a new node to
/// split the critical edge. This will update DominatorTree and
/// DominatorFrontier information if it is available, thus calling this pass
@@ -285,6 +317,16 @@ BasicBlock *llvm::SplitCriticalEdge(TerminatorInst *TI, unsigned SuccNum,
// the loop, to maintain a LoopSimplify guarantee.
if (!TIL->contains(DestBB) &&
P->mustPreserveAnalysisID(LoopSimplifyID)) {
+ assert(!TIL->contains(NewBB) &&
+ "Split point for loop exit is contained in loop!");
+
+ // Update LCSSA form in the newly created exit block.
+ if (P->mustPreserveAnalysisID(LCSSAID)) {
+ SmallVector<BasicBlock *, 1> OrigPred;
+ OrigPred.push_back(TIBB);
+ CreatePHIsForSplitLoopExit(OrigPred, NewBB, DestBB);
+ }
+
// For each unique exit block...
SmallVector<BasicBlock *, 4> ExitBlocks;
TIL->getExitBlocks(ExitBlocks);
@@ -292,41 +334,26 @@ BasicBlock *llvm::SplitCriticalEdge(TerminatorInst *TI, unsigned SuccNum,
// 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;
+ bool HasPredOutsideOfLoop = 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;
+ HasPredOutsideOfLoop = 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);
- }
+ if (!Preds.empty() && HasPredOutsideOfLoop) {
+ BasicBlock *NewExitBB =
+ SplitBlockPredecessors(Exit, Preds.data(), Preds.size(),
+ "split", P);
+ if (P->mustPreserveAnalysisID(LCSSAID))
+ CreatePHIsForSplitLoopExit(Preds, NewExitBB, Exit);
+ }
}
}
// LCSSA form was updated above for the case where LoopSimplify is
diff --git a/test/Transforms/LoopUnswitch/preserve-analyses.ll b/test/Transforms/LoopUnswitch/preserve-analyses.ll
index 1a0e9e6c87..8d3f1382f3 100644
--- a/test/Transforms/LoopUnswitch/preserve-analyses.ll
+++ b/test/Transforms/LoopUnswitch/preserve-analyses.ll
@@ -93,3 +93,37 @@ bb6: ; preds = %bb2
return: ; preds = %bb8, %bb
ret void
}
+
+; This function requires special handling to preserve LCSSA form.
+; PR4934
+
+define void @pnp_check_irq() nounwind noredzone {
+entry:
+ %conv56 = trunc i64 undef to i32 ; <i32> [#uses=1]
+ br label %while.cond.i
+
+while.cond.i: ; preds = %while.cond.i.backedge, %entry
+ %call.i25 = call i8* @pci_get_device() nounwind noredzone ; <i8*> [#uses=2]
+ br i1 undef, label %if.then65, label %while.body.i
+
+while.body.i: ; preds = %while.cond.i
+ br i1 undef, label %if.then31.i.i, label %while.cond.i.backedge
+
+while.cond.i.backedge: ; preds = %if.then31.i.i, %while.body.i
+ br label %while.cond.i
+
+if.then31.i.i: ; preds = %while.body.i
+ switch i32 %conv56, label %while.cond.i.backedge [
+ i32 14, label %if.then42.i.i
+ i32 15, label %if.then42.i.i
+ ]
+
+if.then42.i.i: ; preds = %if.then31.i.i, %if.then31.i.i
+ %call.i25.lcssa48 = phi i8* [ %call.i25, %if.then31.i.i ], [ %call.i25, %if.then31.i.i ] ; <i8*> [#uses=0]
+ unreachable
+
+if.then65: ; preds = %while.cond.i
+ unreachable
+}
+
+declare i8* @pci_get_device() noredzone