Move from Stage 0 to Stage 1.

Only emit one PHI node for IV uses with identical bases and strides (after
moving foldable immediates to the load/store instruction).

This implements LoopStrengthReduce/dont_insert_redundant_ops.ll, allowing
us to generate this PPC code for test1:

        or r30, r3, r3
.LBB_test1_1:   ; Loop
        li r2, 0
        stw r2, 0(r30)
        stw r2, 4(r30)
        bl L_pred$stub
        addi r30, r30, 8
        cmplwi cr0, r3, 0
        bne .LBB_test1_1        ; Loop

instead of this code:

        or r30, r3, r3
        or r29, r3, r3
.LBB_test1_1:   ; Loop
        li r2, 0
        stw r2, 0(r29)
        stw r2, 4(r30)
        bl L_pred$stub
        addi r30, r30, 8        ;; Two iv's with step of 8
        addi r29, r29, 8
        cmplwi cr0, r3, 0
        bne .LBB_test1_1        ; Loop

llvm-svn: 22635
This commit is contained in:
Chris Lattner 2005-08-03 22:51:21 +00:00
parent 3a18a39587
commit db23c74e5e
1 changed files with 31 additions and 27 deletions

View File

@ -554,24 +554,25 @@ void LoopStrengthReduce::StrengthReduceStridedIVUsers(Value *Stride,
SomeLoopPHI->getIncomingBlock(SomeLoopPHI->getIncomingBlock(0) == Preheader);
// FIXME: This loop needs increasing levels of intelligence.
// STAGE 0: just emit everything as its own base. <-- We are here
// STAGE 0: just emit everything as its own base.
// STAGE 1: factor out common vars from bases, and try and push resulting
// constants into Imm field.
// constants into Imm field. <-- We are here
// STAGE 2: factor out large constants to try and make more constants
// acceptable for target loads and stores.
std::sort(UsersToProcess.begin(), UsersToProcess.end());
// Sort by the base value, so that all IVs with identical bases are next to
// each other.
std::sort(UsersToProcess.begin(), UsersToProcess.end());
while (!UsersToProcess.empty()) {
SCEVHandle Base = UsersToProcess.front().first;
// Create a new Phi for this base, and stick it in the loop header.
Value *Replaced = UsersToProcess.front().second.OperandValToReplace;
const Type *ReplacedTy = Replaced->getType();
PHINode *NewPHI = new PHINode(ReplacedTy, Replaced->getName()+".str",
PhiInsertBefore);
const Type *ReplacedTy = Base->getType();
PHINode *NewPHI = new PHINode(ReplacedTy, "iv.", PhiInsertBefore);
// Emit the initial base value into the loop preheader, and add it to the
// Phi node.
Value *BaseV = Rewriter.expandCodeFor(UsersToProcess.front().first,
PreInsertPt, ReplacedTy);
Value *BaseV = Rewriter.expandCodeFor(Base, PreInsertPt, ReplacedTy);
NewPHI->addIncoming(BaseV, Preheader);
// Emit the increment of the base value before the terminator of the loop
@ -585,28 +586,31 @@ void LoopStrengthReduce::StrengthReduceStridedIVUsers(Value *Stride,
NewPHI->addIncoming(IncV, LatchBlock);
// Emit the code to add the immediate offset to the Phi value, just before
// the instruction that we identified as using this stride and base.
// First, empty the SCEVExpander's expression map so that we are guaranteed
// to have the code emitted where we expect it.
Rewriter.clear();
SCEVHandle NewValSCEV = SCEVAddExpr::get(SCEVUnknown::get(NewPHI),
UsersToProcess.front().second.Imm);
Value *newVal = Rewriter.expandCodeFor(NewValSCEV,
UsersToProcess.front().second.Inst,
ReplacedTy);
// the instructions that we identified as using this stride and base.
while (!UsersToProcess.empty() && UsersToProcess.front().first == Base) {
BasedUser &User = UsersToProcess.front().second;
// Replace the use of the operand Value with the new Phi we just created.
DEBUG(std::cerr << "REPLACING: " << *Replaced << "IN: " <<
*UsersToProcess.front().second.Inst << "WITH: "<< *newVal << '\n');
UsersToProcess.front().second.Inst->replaceUsesOfWith(Replaced, newVal);
// Clear the SCEVExpander's expression map so that we are guaranteed
// to have the code emitted where we expect it.
Rewriter.clear();
SCEVHandle NewValSCEV = SCEVAddExpr::get(SCEVUnknown::get(NewPHI),
User.Imm);
Value *Replaced = UsersToProcess.front().second.OperandValToReplace;
Value *newVal = Rewriter.expandCodeFor(NewValSCEV, User.Inst,
Replaced->getType());
// Mark old value we replaced as possibly dead, so that it is elminated
// if we just replaced the last use of that value.
DeadInsts.insert(cast<Instruction>(Replaced));
// Replace the use of the operand Value with the new Phi we just created.
DEBUG(std::cerr << "REPLACING: " << *Replaced << "IN: " <<
*User.Inst << "WITH: "<< *newVal << '\n');
User.Inst->replaceUsesOfWith(Replaced, newVal);
UsersToProcess.erase(UsersToProcess.begin());
++NumReduced;
// Mark old value we replaced as possibly dead, so that it is elminated
// if we just replaced the last use of that value.
DeadInsts.insert(cast<Instruction>(Replaced));
UsersToProcess.erase(UsersToProcess.begin());
++NumReduced;
}
// TODO: Next, find out which base index is the most common, pull it out.
}