[llvm-commits] [llvm] r52617 - in /llvm/trunk: lib/Transforms/Scalar/LoopStrengthReduce.cpp test/Transforms/LoopStrengthReduce/dead-phi.ll
Dan Gohman
gohman at apple.com
Sun Jun 22 13:44:02 PDT 2008
Author: djg
Date: Sun Jun 22 15:44:02 2008
New Revision: 52617
URL: http://llvm.org/viewvc/llvm-project?rev=52617&view=rev
Log:
Improve LSR's dead-phi detection to handle use-def cycles
with more than two nodes.
Added:
llvm/trunk/test/Transforms/LoopStrengthReduce/dead-phi.ll
Modified:
llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp
Modified: llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp?rev=52617&r1=52616&r2=52617&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp (original)
+++ llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp Sun Jun 22 15:44:02 2008
@@ -1810,31 +1810,28 @@
DeleteTriviallyDeadInstructions(DeadInsts);
BasicBlock::iterator I = L->getHeader()->begin();
- PHINode *PN;
- while ((PN = dyn_cast<PHINode>(I))) {
- ++I; // Preincrement iterator to avoid invalidating it when deleting PN.
-
- // At this point, we know that we have killed one or more GEP
- // instructions. It is worth checking to see if the cann indvar is also
- // dead, so that we can remove it as well. The requirements for the cann
- // indvar to be considered dead are:
- // 1. the cann indvar has one use
- // 2. the use is an add instruction
- // 3. the add has one use
- // 4. the add is used by the cann indvar
- // If all four cases above are true, then we can remove both the add and
- // the cann indvar.
+ while (PHINode *PN = dyn_cast<PHINode>(I++)) {
+ // At this point, we know that we have killed one or more IV users.
+ // It is worth checking to see if the cann indvar is also
+ // dead, so that we can remove it as well.
+ //
+ // We can remove a PHI if it is on a cycle in the def-use graph
+ // where each node in the cycle has degree one, i.e. only one use,
+ // and is an instruction with no side effects.
+ //
// FIXME: this needs to eliminate an induction variable even if it's being
// compared against some value to decide loop termination.
if (PN->hasOneUse()) {
- Instruction *BO = dyn_cast<Instruction>(*PN->use_begin());
- if (BO && (isa<BinaryOperator>(BO) || isa<CmpInst>(BO))) {
- if (BO->hasOneUse() && PN == *(BO->use_begin())) {
- DeadInsts.insert(BO);
- // Break the cycle, then delete the PHI.
+ for (Instruction *J = dyn_cast<Instruction>(*PN->use_begin());
+ J && J->hasOneUse() && !J->mayWriteToMemory();
+ J = dyn_cast<Instruction>(*J->use_begin())) {
+ // If we find the original PHI, we've discovered a cycle.
+ if (J == PN) {
+ // Break the cycle and mark the PHI for deletion.
SE->deleteValueFromRecords(PN);
PN->replaceAllUsesWith(UndefValue::get(PN->getType()));
- PN->eraseFromParent();
+ DeadInsts.insert(PN);
+ break;
}
}
}
Added: llvm/trunk/test/Transforms/LoopStrengthReduce/dead-phi.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/LoopStrengthReduce/dead-phi.ll?rev=52617&view=auto
==============================================================================
--- llvm/trunk/test/Transforms/LoopStrengthReduce/dead-phi.ll (added)
+++ llvm/trunk/test/Transforms/LoopStrengthReduce/dead-phi.ll Sun Jun 22 15:44:02 2008
@@ -0,0 +1,21 @@
+; RUN: llvm-as < %s | opt -loop-reduce | llvm-dis | grep phi | count 1
+
+define void @foo(i32 %n) {
+entry:
+ br label %loop
+
+loop:
+ %i = phi i32 [ 0, %entry ], [ %i.next, %loop ]
+
+ ; These three instructions form an isolated cycle and can be deleted.
+ %j = phi i32 [ 0, %entry ], [ %j.y, %loop ]
+ %j.x = add i32 %j, 1
+ %j.y = mul i32 %j.x, 2
+
+ %i.next = add i32 %i, 1
+ %c = icmp ne i32 %i.next, %n
+ br i1 %c, label %loop, label %exit
+
+exit:
+ ret void
+}
More information about the llvm-commits
mailing list