summaryrefslogtreecommitdiffstats
path: root/llvm/lib
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
commit148a972b670b23322766d36b897f17cb057f85a4 (patch)
tree2ad636046abe0d2d15c727b8bed6ed3ae14697be /llvm/lib
parent9503c46a2efbd2d698a9e6fc12592b26ddf184d6 (diff)
downloadbcm5719-llvm-148a972b670b23322766d36b897f17cb057f85a4.tar.gz
bcm5719-llvm-148a972b670b23322766d36b897f17cb057f85a4.zip
When reusing an existing PHI node in a loop, be even more
strict about the requirements. llvm-svn: 96301
Diffstat (limited to 'llvm/lib')
-rw-r--r--llvm/lib/Analysis/ScalarEvolutionExpander.cpp50
1 files changed, 39 insertions, 11 deletions
diff --git a/llvm/lib/Analysis/ScalarEvolutionExpander.cpp b/llvm/lib/Analysis/ScalarEvolutionExpander.cpp
index b026a3bee0a..c2e1f8902f8 100644
--- a/llvm/lib/Analysis/ScalarEvolutionExpander.cpp
+++ b/llvm/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.
OpenPOWER on IntegriCloud