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
This commit is contained in:
Dan Gohman 2010-02-16 00:20:08 +00:00
parent 7dc9747e89
commit 22e621908f

View File

@ -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.