1
0
mirror of https://github.com/c64scene-ar/llvm-6502.git synced 2025-04-11 00:39:36 +00:00

Make RewriteLoopExitValues far less nested by using continue in the loop

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@34891 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Chris Lattner 2007-03-03 22:48:48 +00:00
parent a9569f10de
commit c9838f25d5

@ -322,102 +322,105 @@ void IndVarSimplify::RewriteLoopExitValues(Loop *L) {
std::set<Instruction*> InstructionsToDelete;
for (unsigned i = 0, e = L->getBlocks().size(); i != e; ++i)
if (LI->getLoopFor(L->getBlocks()[i]) == L) { // Not in a subloop...
BasicBlock *BB = L->getBlocks()[i];
for (BasicBlock::iterator I = BB->begin(), E = BB->end(); I != E;) {
if (I->getType()->isInteger()) { // Is an integer instruction
SCEVHandle SH = SE->getSCEV(I);
if (SH->hasComputableLoopEvolution(L) || // Varies predictably
HasConstantItCount) {
// Find out if this predictably varying value is actually used
// outside of the loop. "extra" as opposed to "intra".
std::vector<Instruction*> ExtraLoopUsers;
for (Value::use_iterator UI = I->use_begin(), E = I->use_end();
UI != E; ++UI) {
Instruction *User = cast<Instruction>(*UI);
if (!L->contains(User->getParent())) {
// If this is a PHI node in the exit block and we're inserting,
// into the exit block, it must have a single entry. In this
// case, we can't insert the code after the PHI and have the PHI
// still use it. Instead, don't insert the the PHI.
if (PHINode *PN = dyn_cast<PHINode>(User)) {
// FIXME: This is a case where LCSSA pessimizes code, this
// should be fixed better.
if (PN->getNumOperands() == 2 &&
PN->getParent() == BlockToInsertInto)
continue;
}
ExtraLoopUsers.push_back(User);
}
}
if (!ExtraLoopUsers.empty()) {
// Okay, this instruction has a user outside of the current loop
// and varies predictably in this loop. Evaluate the value it
// contains when the loop exits, and insert code for it.
SCEVHandle ExitValue = SE->getSCEVAtScope(I, L->getParentLoop());
if (!isa<SCEVCouldNotCompute>(ExitValue)) {
Changed = true;
++NumReplaced;
// Remember the next instruction. The rewriter can move code
// around in some cases.
BasicBlock::iterator NextI = I; ++NextI;
Value *NewVal = Rewriter.expandCodeFor(ExitValue, InsertPt,
I->getType());
DOUT << "INDVARS: RLEV: AfterLoopVal = " << *NewVal
<< " LoopVal = " << *I << "\n";
// Rewrite any users of the computed value outside of the loop
// with the newly computed value.
for (unsigned i = 0, e = ExtraLoopUsers.size(); i != e; ++i) {
PHINode* PN = dyn_cast<PHINode>(ExtraLoopUsers[i]);
if (PN && PN->getNumOperands() == 2 &&
!L->contains(PN->getParent())) {
// We're dealing with an LCSSA Phi. Handle it specially.
Instruction* LCSSAInsertPt = BlockToInsertInto->begin();
Instruction* NewInstr = dyn_cast<Instruction>(NewVal);
if (NewInstr && !isa<PHINode>(NewInstr) &&
!L->contains(NewInstr->getParent()))
for (unsigned j = 0; j < NewInstr->getNumOperands(); ++j){
Instruction* PredI =
dyn_cast<Instruction>(NewInstr->getOperand(j));
if (PredI && L->contains(PredI->getParent())) {
PHINode* NewLCSSA = new PHINode(PredI->getType(),
PredI->getName() + ".lcssa",
LCSSAInsertPt);
NewLCSSA->addIncoming(PredI,
BlockToInsertInto->getSinglePredecessor());
NewInstr->replaceUsesOfWith(PredI, NewLCSSA);
}
}
PN->replaceAllUsesWith(NewVal);
PN->eraseFromParent();
} else {
ExtraLoopUsers[i]->replaceUsesOfWith(I, NewVal);
}
}
// If this instruction is dead now, schedule it to be removed.
if (I->use_empty())
InstructionsToDelete.insert(I);
I = NextI;
continue; // Skip the ++I
}
}
}
}
// Next instruction. Continue instruction skips this.
++I;
// Loop over all of the integer-valued instructions in this loop, but that are
// not in a subloop.
for (unsigned i = 0, e = L->getBlocks().size(); i != e; ++i) {
if (LI->getLoopFor(L->getBlocks()[i]) != L)
continue; // The Block is in a subloop, skip it.
BasicBlock *BB = L->getBlocks()[i];
for (BasicBlock::iterator II = BB->begin(), E = BB->end(); II != E; ) {
Instruction *I = II++;
if (!I->getType()->isInteger())
continue; // SCEV only supports integer expressions for now.
SCEVHandle SH = SE->getSCEV(I);
if (!HasConstantItCount &&
!SH->hasComputableLoopEvolution(L)) { // Varies predictably
continue; // Cannot exit evolution for the loop value.
}
}
// Find out if this predictably varying value is actually used
// outside of the loop. "Extra" is as opposed to "intra".
std::vector<Instruction*> ExtraLoopUsers;
for (Value::use_iterator UI = I->use_begin(), E = I->use_end();
UI != E; ++UI) {
Instruction *User = cast<Instruction>(*UI);
if (!L->contains(User->getParent())) {
// If this is a PHI node in the exit block and we're inserting,
// into the exit block, it must have a single entry. In this
// case, we can't insert the code after the PHI and have the PHI
// still use it. Instead, don't insert the the PHI.
if (PHINode *PN = dyn_cast<PHINode>(User)) {
// FIXME: This is a case where LCSSA pessimizes code, this
// should be fixed better.
if (PN->getNumOperands() == 2 &&
PN->getParent() == BlockToInsertInto)
continue;
}
ExtraLoopUsers.push_back(User);
}
}
// If nothing outside the loop uses this value, don't rewrite it.
if (ExtraLoopUsers.empty())
continue;
// Okay, this instruction has a user outside of the current loop
// and varies predictably *inside* the loop. Evaluate the value it
// contains when the loop exits if possible.
SCEVHandle ExitValue = SE->getSCEVAtScope(I, L->getParentLoop());
if (isa<SCEVCouldNotCompute>(ExitValue))
continue;
Changed = true;
++NumReplaced;
Value *NewVal = Rewriter.expandCodeFor(ExitValue, InsertPt,
I->getType());
DOUT << "INDVARS: RLEV: AfterLoopVal = " << *NewVal
<< " LoopVal = " << *I << "\n";
// Rewrite any users of the computed value outside of the loop
// with the newly computed value.
for (unsigned i = 0, e = ExtraLoopUsers.size(); i != e; ++i) {
PHINode* PN = dyn_cast<PHINode>(ExtraLoopUsers[i]);
if (PN && PN->getNumOperands() == 2 &&
!L->contains(PN->getParent())) {
// We're dealing with an LCSSA Phi. Handle it specially.
Instruction* LCSSAInsertPt = BlockToInsertInto->begin();
Instruction* NewInstr = dyn_cast<Instruction>(NewVal);
if (NewInstr && !isa<PHINode>(NewInstr) &&
!L->contains(NewInstr->getParent()))
for (unsigned j = 0; j != NewInstr->getNumOperands(); ++j) {
Instruction* PredI =
dyn_cast<Instruction>(NewInstr->getOperand(j));
if (PredI && L->contains(PredI->getParent())) {
PHINode* NewLCSSA = new PHINode(PredI->getType(),
PredI->getName() + ".lcssa",
LCSSAInsertPt);
NewLCSSA->addIncoming(PredI,
BlockToInsertInto->getSinglePredecessor());
NewInstr->replaceUsesOfWith(PredI, NewLCSSA);
}
}
PN->replaceAllUsesWith(NewVal);
PN->eraseFromParent();
} else {
ExtraLoopUsers[i]->replaceUsesOfWith(I, NewVal);
}
}
// If this instruction is dead now, schedule it to be removed.
if (I->use_empty())
InstructionsToDelete.insert(I);
}
}
DeleteTriviallyDeadInstructions(InstructionsToDelete);
}