[llvm-commits] CVS: llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp
Chris Lattner
lattner at cs.uiuc.edu
Fri Feb 3 23:37:02 PST 2006
Changes in directory llvm/lib/Transforms/Scalar:
LoopStrengthReduce.cpp updated: 1.73 -> 1.74
---
Log message:
Fix two significant bugs in LSR:
1. When rewriting code in outer loops, sometimes we would insert code into
inner loops that is invariant in that loop.
2. Notice that 4*(2+x) is 8+4*x and use that to simplify expressions.
This is a performance neutral change.
---
Diffs of the changes: (+75 -14)
LoopStrengthReduce.cpp | 89 +++++++++++++++++++++++++++++++++++++++++--------
1 files changed, 75 insertions(+), 14 deletions(-)
Index: llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp
diff -u llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp:1.73 llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp:1.74
--- llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp:1.73 Sun Jan 22 17:32:06 2006
+++ llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp Sat Feb 4 01:36:50 2006
@@ -477,6 +477,10 @@
void RewriteInstructionToUseNewBase(const SCEVHandle &NewBase,
SCEVExpander &Rewriter, Loop *L,
Pass *P);
+
+ Value *InsertCodeForBaseAtPosition(const SCEVHandle &NewBase,
+ SCEVExpander &Rewriter,
+ Instruction *IP, Loop *L);
void dump() const;
};
}
@@ -490,6 +494,41 @@
std::cerr << " Inst: " << *Inst;
}
+Value *BasedUser::InsertCodeForBaseAtPosition(const SCEVHandle &NewBase,
+ SCEVExpander &Rewriter,
+ Instruction *IP, Loop *L) {
+ // Figure out where we *really* want to insert this code. In particular, if
+ // the user is inside of a loop that is nested inside of L, we really don't
+ // want to insert this expression before the user, we'd rather pull it out as
+ // many loops as possible.
+ LoopInfo &LI = Rewriter.getLoopInfo();
+ Instruction *BaseInsertPt = IP;
+
+ // Figure out the most-nested loop that IP is in.
+ Loop *InsertLoop = LI.getLoopFor(IP->getParent());
+
+ // If InsertLoop is not L, and InsertLoop is nested inside of L, figure out
+ // the preheader of the outer-most loop where NewBase is not loop invariant.
+ while (InsertLoop && NewBase->isLoopInvariant(InsertLoop)) {
+ BaseInsertPt = InsertLoop->getLoopPreheader()->getTerminator();
+ InsertLoop = InsertLoop->getParentLoop();
+ }
+
+ // If there is no immediate value, skip the next part.
+ if (SCEVConstant *SC = dyn_cast<SCEVConstant>(Imm))
+ if (SC->getValue()->isNullValue())
+ return Rewriter.expandCodeFor(NewBase, BaseInsertPt,
+ OperandValToReplace->getType());
+
+ Value *Base = Rewriter.expandCodeFor(NewBase, BaseInsertPt);
+
+ // Always emit the immediate (if non-zero) into the same block as the user.
+ SCEVHandle NewValSCEV = SCEVAddExpr::get(SCEVUnknown::get(Base), Imm);
+ return Rewriter.expandCodeFor(NewValSCEV, IP,
+ OperandValToReplace->getType());
+}
+
+
// Once we rewrite the code to insert the new IVs we want, update the
// operands of Inst to use the new expression 'NewBase', with 'Imm' added
// to it.
@@ -497,9 +536,7 @@
SCEVExpander &Rewriter,
Loop *L, Pass *P) {
if (!isa<PHINode>(Inst)) {
- SCEVHandle NewValSCEV = SCEVAddExpr::get(NewBase, Imm);
- Value *NewVal = Rewriter.expandCodeFor(NewValSCEV, Inst,
- OperandValToReplace->getType());
+ Value *NewVal = InsertCodeForBaseAtPosition(NewBase, Rewriter, Inst, L);
// Replace the use of the operand Value with the new Phi we just created.
Inst->replaceUsesOfWith(OperandValToReplace, NewVal);
DEBUG(std::cerr << " CHANGED: IMM =" << *Imm << " Inst = " << *Inst);
@@ -539,11 +576,8 @@
Value *&Code = InsertedCode[PN->getIncomingBlock(i)];
if (!Code) {
// Insert the code into the end of the predecessor block.
- BasicBlock::iterator InsertPt =PN->getIncomingBlock(i)->getTerminator();
-
- SCEVHandle NewValSCEV = SCEVAddExpr::get(NewBase, Imm);
- Code = Rewriter.expandCodeFor(NewValSCEV, InsertPt,
- OperandValToReplace->getType());
+ Instruction *InsertPt = PN->getIncomingBlock(i)->getTerminator();
+ Code = InsertCodeForBaseAtPosition(NewBase, Rewriter, InsertPt, L);
}
// Replace the use of the operand Value with the new Phi we just created.
@@ -627,16 +661,18 @@
std::vector<SCEVHandle> NewOps;
NewOps.reserve(SAE->getNumOperands());
- for (unsigned i = 0; i != SAE->getNumOperands(); ++i)
- if (isAddress && isTargetConstant(SAE->getOperand(i))) {
- Imm = SCEVAddExpr::get(Imm, SAE->getOperand(i));
- } else if (!SAE->getOperand(i)->isLoopInvariant(L)) {
+ for (unsigned i = 0; i != SAE->getNumOperands(); ++i) {
+ SCEVHandle NewOp = SAE->getOperand(i);
+ MoveImmediateValues(NewOp, Imm, isAddress, L);
+
+ if (!NewOp->isLoopInvariant(L)) {
// If this is a loop-variant expression, it must stay in the immediate
// field of the expression.
- Imm = SCEVAddExpr::get(Imm, SAE->getOperand(i));
+ Imm = SCEVAddExpr::get(Imm, NewOp);
} else {
- NewOps.push_back(SAE->getOperand(i));
+ NewOps.push_back(NewOp);
}
+ }
if (NewOps.empty())
Val = SCEVUnknown::getIntegerSCEV(0, Val->getType());
@@ -654,6 +690,31 @@
Val = SCEVAddRecExpr::get(Ops, SARE->getLoop());
}
return;
+ } else if (SCEVMulExpr *SME = dyn_cast<SCEVMulExpr>(Val)) {
+ // Transform "8 * (4 + v)" -> "32 + 8*V" if "32" fits in the immed field.
+ if (isAddress && isTargetConstant(SME->getOperand(0)) &&
+ SME->getNumOperands() == 2 && SME->isLoopInvariant(L)) {
+
+ SCEVHandle SubImm = SCEVUnknown::getIntegerSCEV(0, Val->getType());
+ SCEVHandle NewOp = SME->getOperand(1);
+ MoveImmediateValues(NewOp, SubImm, isAddress, L);
+
+ // If we extracted something out of the subexpressions, see if we can
+ // simplify this!
+ if (NewOp != SME->getOperand(1)) {
+ // Scale SubImm up by "8". If the result is a target constant, we are
+ // good.
+ SubImm = SCEVMulExpr::get(SubImm, SME->getOperand(0));
+ if (isTargetConstant(SubImm)) {
+ // Accumulate the immediate.
+ Imm = SCEVAddExpr::get(Imm, SubImm);
+
+ // Update what is left of 'Val'.
+ Val = SCEVMulExpr::get(SME->getOperand(0), NewOp);
+ return;
+ }
+ }
+ }
}
// Loop-variant expressions must stay in the immediate field of the
More information about the llvm-commits
mailing list