Do not simplifyLatch for loops where hoisting increments couldresult in extra live range interferance

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@220872 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Yi Jiang
2014-10-29 20:19:47 +00:00
parent 3262c451c4
commit a5ca5d9f82
3 changed files with 34 additions and 7 deletions

View File

@ -194,8 +194,13 @@ static void RewriteUsesOfClonedInstructions(BasicBlock *OrigHeader,
/// heuristics. We handle a single arithmetic instruction along with any type
/// conversions.
static bool shouldSpeculateInstrs(BasicBlock::iterator Begin,
BasicBlock::iterator End) {
BasicBlock::iterator End, Loop *L) {
bool seenIncrement = false;
bool MultiExitLoop = false;
if (!L->getExitingBlock())
MultiExitLoop = true;
for (BasicBlock::iterator I = Begin; I != End; ++I) {
if (!isSafeToSpeculativelyExecute(I))
@ -219,11 +224,33 @@ static bool shouldSpeculateInstrs(BasicBlock::iterator Begin,
case Instruction::Xor:
case Instruction::Shl:
case Instruction::LShr:
case Instruction::AShr:
case Instruction::AShr: {
Value *IVOpnd = nullptr;
if (isa<ConstantInt>(I->getOperand(0)))
IVOpnd = I->getOperand(1);
if (isa<ConstantInt>(I->getOperand(1))) {
if (IVOpnd)
return false;
IVOpnd = I->getOperand(0);
}
// If increment operand is used outside of the loop, this speculation
// could cause extra live range interference.
if (MultiExitLoop && IVOpnd) {
for (User *UseI : IVOpnd->users()) {
auto *UserInst = cast<Instruction>(UseI);
if (!L->contains(UserInst))
return false;
}
}
if (seenIncrement)
return false;
seenIncrement = true;
break;
}
case Instruction::Trunc:
case Instruction::ZExt:
case Instruction::SExt:
@ -259,7 +286,7 @@ bool LoopRotate::simplifyLoopLatch(Loop *L) {
if (!BI)
return false;
if (!shouldSpeculateInstrs(Latch->begin(), Jmp))
if (!shouldSpeculateInstrs(Latch->begin(), Jmp, L))
return false;
DEBUG(dbgs() << "Folding loop latch " << Latch->getName() << " into "