diff options
author | Dan Gohman <gohman@apple.com> | 2010-02-16 00:20:08 +0000 |
---|---|---|
committer | Dan Gohman <gohman@apple.com> | 2010-02-16 00:20:08 +0000 |
commit | 22e621908fdb121474f4806f15ec5c0ce2efeb0a (patch) | |
tree | 97c29cd5847bb60c7aec4071fa8867132dfe6388 /lib/Analysis/ScalarEvolutionExpander.cpp | |
parent | 7dc9747e891a1d7945daad8d2752f2fc7d2ccf92 (diff) |
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.cpp | 50 |
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. |