summaryrefslogtreecommitdiff
path: root/lib/Analysis/ScalarEvolutionExpander.cpp
diff options
context:
space:
mode:
authorDan Gohman <gohman@apple.com>2010-02-16 00:20:08 +0000
committerDan Gohman <gohman@apple.com>2010-02-16 00:20:08 +0000
commit22e621908fdb121474f4806f15ec5c0ce2efeb0a (patch)
tree97c29cd5847bb60c7aec4071fa8867132dfe6388 /lib/Analysis/ScalarEvolutionExpander.cpp
parent7dc9747e891a1d7945daad8d2752f2fc7d2ccf92 (diff)
downloadllvm-22e621908fdb121474f4806f15ec5c0ce2efeb0a.tar.gz
llvm-22e621908fdb121474f4806f15ec5c0ce2efeb0a.tar.bz2
llvm-22e621908fdb121474f4806f15ec5c0ce2efeb0a.tar.xz
When reusing an existing PHI node in a loop, be even more
strict about the requirements. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@96301 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Analysis/ScalarEvolutionExpander.cpp')
-rw-r--r--lib/Analysis/ScalarEvolutionExpander.cpp50
1 files changed, 39 insertions, 11 deletions
diff --git a/lib/Analysis/ScalarEvolutionExpander.cpp b/lib/Analysis/ScalarEvolutionExpander.cpp
index b026a3bee0..c2e1f8902f 100644
--- a/lib/Analysis/ScalarEvolutionExpander.cpp
+++ b/lib/Analysis/ScalarEvolutionExpander.cpp
@@ -646,18 +646,46 @@ SCEVExpander::getAddRecExprPHILiterally(const SCEVAddRecExpr *Normalized,
SE.getEffectiveSCEVType(Normalized->getType())) &&
SE.getSCEV(PN) == Normalized)
if (BasicBlock *LatchBlock = L->getLoopLatch()) {
- // Remember this PHI, even in post-inc mode.
- InsertedValues.insert(PN);
- // Remember the increment.
Instruction *IncV =
- cast<Instruction>(PN->getIncomingValueForBlock(LatchBlock)
- ->stripPointerCasts());
- rememberInstruction(IncV);
- // Make sure the increment is where we want it. But don't move it
- // down past a potential existing post-inc user.
- if (L == IVIncInsertLoop && !SE.DT->dominates(IncV, IVIncInsertPos))
- IncV->moveBefore(IVIncInsertPos);
- return PN;
+ cast<Instruction>(PN->getIncomingValueForBlock(LatchBlock));
+
+ // Determine if this is a well-behaved chain of instructions leading
+ // back to the PHI. It probably will be, if we're scanning an inner
+ // loop already visited by LSR for example, but it wouldn't have
+ // to be.
+ do {
+ if (IncV->getNumOperands() == 0 || isa<PHINode>(IncV)) {
+ IncV = 0;
+ break;
+ }
+ IncV = dyn_cast<Instruction>(IncV->getOperand(0));
+ if (!IncV)
+ break;
+ if (IncV->mayHaveSideEffects()) {
+ IncV = 0;
+ break;
+ }
+ } while (IncV != PN);
+
+ if (IncV) {
+ // Ok, the add recurrence looks usable.
+ // Remember this PHI, even in post-inc mode.
+ InsertedValues.insert(PN);
+ // Remember the increment.
+ IncV = cast<Instruction>(PN->getIncomingValueForBlock(LatchBlock));
+ rememberInstruction(IncV);
+ if (L == IVIncInsertLoop)
+ do {
+ if (SE.DT->dominates(IncV, IVIncInsertPos))
+ break;
+ // Make sure the increment is where we want it. But don't move it
+ // down past a potential existing post-inc user.
+ IncV->moveBefore(IVIncInsertPos);
+ IVIncInsertPos = IncV;
+ IncV = cast<Instruction>(IncV->getOperand(0));
+ } while (IncV != PN);
+ return PN;
+ }
}
// Save the original insertion point so we can restore it when we're done.