aboutsummaryrefslogtreecommitdiffstats
path: root/lib/Transforms/Scalar/LoopUnswitch.cpp
diff options
context:
space:
mode:
authorEvan Cheng <evan.cheng@apple.com>2011-05-24 23:12:57 +0000
committerEvan Cheng <evan.cheng@apple.com>2011-05-24 23:12:57 +0000
commit424641ef83fbb99640d3e2758148a9d3ea2b3830 (patch)
tree6c88b8efb55649e29eefa4d18efa6b31e0f01900 /lib/Transforms/Scalar/LoopUnswitch.cpp
parentfef50062eae28fc6d893cd3ef528f8ca85cd50b0 (diff)
downloadexternal_llvm-424641ef83fbb99640d3e2758148a9d3ea2b3830.tar.gz
external_llvm-424641ef83fbb99640d3e2758148a9d3ea2b3830.tar.bz2
external_llvm-424641ef83fbb99640d3e2758148a9d3ea2b3830.zip
Fix LoopUnswitch bug. RewriteLoopBodyWithConditionConstant can delete a dead
case of a switch instruction. Back off this optimization when this would eliminate all of the predecessors to the latch. Sorry, I am unable to reduce a reasonably sized test case. rdar://9486843 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@132022 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Transforms/Scalar/LoopUnswitch.cpp')
-rw-r--r--lib/Transforms/Scalar/LoopUnswitch.cpp47
1 files changed, 34 insertions, 13 deletions
diff --git a/lib/Transforms/Scalar/LoopUnswitch.cpp b/lib/Transforms/Scalar/LoopUnswitch.cpp
index b4e3d318a5..9761d68297 100644
--- a/lib/Transforms/Scalar/LoopUnswitch.cpp
+++ b/lib/Transforms/Scalar/LoopUnswitch.cpp
@@ -786,8 +786,13 @@ void LoopUnswitch::RemoveBlockIfDead(BasicBlock *BB,
// If this is the edge to the header block for a loop, remove the loop and
// promote all subloops.
if (Loop *BBLoop = LI->getLoopFor(BB)) {
- if (BBLoop->getLoopLatch() == BB)
+ if (BBLoop->getLoopLatch() == BB) {
RemoveLoopFromHierarchy(BBLoop);
+ if (currentLoop == BBLoop) {
+ currentLoop = 0;
+ redoLoop = false;
+ }
+ }
}
// Remove the block from the loop info, which removes it from any loops it
@@ -859,7 +864,6 @@ void LoopUnswitch::RewriteLoopBodyWithConditionConstant(Loop *L, Value *LIC,
// FOLD boolean conditions (X|LIC), (X&LIC). Fold conditional branches,
// selects, switches.
- std::vector<User*> Users(LIC->use_begin(), LIC->use_end());
std::vector<Instruction*> Worklist;
LLVMContext &Context = Val->getContext();
@@ -875,13 +879,14 @@ void LoopUnswitch::RewriteLoopBodyWithConditionConstant(Loop *L, Value *LIC,
Replacement = ConstantInt::get(Type::getInt1Ty(Val->getContext()),
!cast<ConstantInt>(Val)->getZExtValue());
- for (unsigned i = 0, e = Users.size(); i != e; ++i)
- if (Instruction *U = cast<Instruction>(Users[i])) {
- if (!L->contains(U))
- continue;
- U->replaceUsesOfWith(LIC, Replacement);
- Worklist.push_back(U);
- }
+ for (Value::use_iterator UI = LIC->use_begin(), E = LIC->use_end();
+ UI != E; ++UI) {
+ Instruction *U = cast<Instruction>(*UI);
+ if (!L->contains(U))
+ continue;
+ U->replaceUsesOfWith(LIC, Replacement);
+ Worklist.push_back(U);
+ }
SimplifyCode(Worklist, L);
return;
}
@@ -889,8 +894,9 @@ void LoopUnswitch::RewriteLoopBodyWithConditionConstant(Loop *L, Value *LIC,
// Otherwise, we don't know the precise value of LIC, but we do know that it
// is certainly NOT "Val". As such, simplify any uses in the loop that we
// can. This case occurs when we unswitch switch statements.
- for (unsigned i = 0, e = Users.size(); i != e; ++i) {
- Instruction *U = cast<Instruction>(Users[i]);
+ for (Value::use_iterator UI = LIC->use_begin(), E = LIC->use_end();
+ UI != E; ++UI) {
+ Instruction *U = cast<Instruction>(*UI);
if (!L->contains(U))
continue;
@@ -910,12 +916,27 @@ void LoopUnswitch::RewriteLoopBodyWithConditionConstant(Loop *L, Value *LIC,
// successor if they become single-entry, those PHI nodes may
// be in the Users list.
+ BasicBlock *Switch = SI->getParent();
+ BasicBlock *SISucc = SI->getSuccessor(DeadCase);
+ BasicBlock *Latch = L->getLoopLatch();
+ // If the DeadCase successor dominates all of the predecessors of the
+ // loop latch, then the transformation isn't safe since it will delete
+ // the predecessor edges to the latch.
+ if (Latch) {
+ bool DominateAll = true;
+ for (pred_iterator PI = pred_begin(Latch), PE = pred_end(Latch);
+ DominateAll && PI != PE; ++PI)
+ if (!DT->dominates(SISucc, *PI))
+ DominateAll = false;
+ if (DominateAll)
+ continue;
+ }
+
// FIXME: This is a hack. We need to keep the successor around
// and hooked up so as to preserve the loop structure, because
// trying to update it is complicated. So instead we preserve the
// loop structure and put the block on a dead code path.
- BasicBlock *Switch = SI->getParent();
- SplitEdge(Switch, SI->getSuccessor(DeadCase), this);
+ SplitEdge(Switch, SISucc, this);
// Compute the successors instead of relying on the return value
// of SplitEdge, since it may have split the switch successor
// after PHI nodes.