summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp
diff options
context:
space:
mode:
authorDan Gohman <gohman@apple.com>2008-06-22 20:44:02 +0000
committerDan Gohman <gohman@apple.com>2008-06-22 20:44:02 +0000
commit5ca5e024808c0b053e44b0974bd8daf3c4dfbc3a (patch)
tree21579f84b4bb3274e5bcb5d077627c5aa579454a /llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp
parent90071075e2f5885fdf9edfa67e1b435c3331dd3a (diff)
downloadbcm5719-llvm-5ca5e024808c0b053e44b0974bd8daf3c4dfbc3a.tar.gz
bcm5719-llvm-5ca5e024808c0b053e44b0974bd8daf3c4dfbc3a.zip
Improve LSR's dead-phi detection to handle use-def cycles
with more than two nodes. llvm-svn: 52617
Diffstat (limited to 'llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp')
-rw-r--r--llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp37
1 files changed, 17 insertions, 20 deletions
diff --git a/llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp b/llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp
index dd459f56906..d825ea789b5 100644
--- a/llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp
+++ b/llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp
@@ -1810,31 +1810,28 @@ bool LoopStrengthReduce::runOnLoop(Loop *L, LPPassManager &LPM) {
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;
}
}
}
OpenPOWER on IntegriCloud