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 | 148a972b670b23322766d36b897f17cb057f85a4 (patch) | |
| tree | 2ad636046abe0d2d15c727b8bed6ed3ae14697be /llvm/lib | |
| parent | 9503c46a2efbd2d698a9e6fc12592b26ddf184d6 (diff) | |
| download | bcm5719-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.cpp | 50 |
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. |

