[llvm-commits] CVS: llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp
Chris Lattner
lattner at cs.uiuc.edu
Mon Aug 8 15:32:45 PDT 2005
Changes in directory llvm/lib/Transforms/Scalar:
LoopStrengthReduce.cpp updated: 1.40 -> 1.41
---
Log message:
Split MoveLoopVariantsToImediateField out from MoveImmediateValues. The
first is a correctness thing, and the later is an optzn thing. This also
is needed to support a future change.
---
Diffs of the changes: (+65 -23)
LoopStrengthReduce.cpp | 88 ++++++++++++++++++++++++++++++++++++-------------
1 files changed, 65 insertions(+), 23 deletions(-)
Index: llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp
diff -u llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp:1.40 llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp:1.41
--- llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp:1.40 Mon Aug 8 01:25:50 2005
+++ llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp Mon Aug 8 17:32:34 2005
@@ -454,6 +454,45 @@
return false;
}
+/// MoveLoopVariantsToImediateField - Move any subexpressions from Val that are
+/// loop varying to the Imm operand.
+static void MoveLoopVariantsToImediateField(SCEVHandle &Val, SCEVHandle &Imm,
+ Loop *L) {
+ if (Val->isLoopInvariant(L)) return; // Nothing to do.
+
+ if (SCEVAddExpr *SAE = dyn_cast<SCEVAddExpr>(Val)) {
+ std::vector<SCEVHandle> NewOps;
+ NewOps.reserve(SAE->getNumOperands());
+
+ for (unsigned i = 0; i != SAE->getNumOperands(); ++i)
+ if (!SAE->getOperand(i)->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));
+ } else {
+ NewOps.push_back(SAE->getOperand(i));
+ }
+
+ if (NewOps.empty())
+ Val = SCEVUnknown::getIntegerSCEV(0, Val->getType());
+ else
+ Val = SCEVAddExpr::get(NewOps);
+ } else if (SCEVAddRecExpr *SARE = dyn_cast<SCEVAddRecExpr>(Val)) {
+ // Try to pull immediates out of the start value of nested addrec's.
+ SCEVHandle Start = SARE->getStart();
+ MoveLoopVariantsToImediateField(Start, Imm, L);
+
+ std::vector<SCEVHandle> Ops(SARE->op_begin(), SARE->op_end());
+ Ops[0] = Start;
+ Val = SCEVAddRecExpr::get(Ops, SARE->getLoop());
+ } else {
+ // Otherwise, all of Val is variant, move the whole thing over.
+ Imm = SCEVAddExpr::get(Imm, Val);
+ Val = SCEVUnknown::getIntegerSCEV(0, Val->getType());
+ }
+}
+
+
/// MoveImmediateValues - Look at Val, and pull out any additions of constants
/// that can fit into the immediate field of instructions in the target.
/// Accumulate these immediate values into the Imm value.
@@ -504,6 +543,7 @@
// Otherwise, no immediates to move.
}
+
/// StrengthReduceStridedIVUsers - Strength reduce all of the users of a single
/// stride of IV. All of the users may have different starting values, and this
/// may not be the only stride (we know it is if isOnlyStride is true).
@@ -528,25 +568,17 @@
Uses.Users[i].OperandValToReplace,
ZeroBase,
Uses.Users[i].isUseOfPostIncrementedValue)));
-
- // First pass, figure out what we can represent in the immediate fields of
- // instructions. If we can represent anything there, move it to the imm
- // fields of the BasedUsers.
+
+ // Move any loop invariant operands from the offset field to the immediate
+ // field of the use, so that we don't try to use something before it is
+ // computed.
for (unsigned i = 0, e = UsersToProcess.size(); i != e; ++i) {
- // Addressing modes can be folded into loads and stores. Be careful that
- // the store is through the expression, not of the expression though.
- bool isAddress = isa<LoadInst>(UsersToProcess[i].second.Inst);
- if (StoreInst *SI = dyn_cast<StoreInst>(UsersToProcess[i].second.Inst))
- if (SI->getOperand(1) == UsersToProcess[i].second.OperandValToReplace)
- isAddress = true;
-
- MoveImmediateValues(UsersToProcess[i].first, UsersToProcess[i].second.Imm,
- isAddress, L);
-
+ MoveLoopVariantsToImediateField(UsersToProcess[i].first,
+ UsersToProcess[i].second.Imm, L);
assert(UsersToProcess[i].first->isLoopInvariant(L) &&
"Base value is not loop invariant!");
}
-
+
SCEVExpander Rewriter(*SE, *LI);
SCEVExpander PreheaderRewriter(*SE, *LI);
@@ -561,16 +593,26 @@
"This loop isn't canonicalized right");
BasicBlock *LatchBlock =
SomeLoopPHI->getIncomingBlock(SomeLoopPHI->getIncomingBlock(0) == Preheader);
-
+
+ // Next, figure out what we can represent in the immediate fields of
+ // instructions. If we can represent anything there, move it to the imm
+ // fields of the BasedUsers.
+ for (unsigned i = 0, e = UsersToProcess.size(); i != e; ++i) {
+ // Addressing modes can be folded into loads and stores. Be careful that
+ // the store is through the expression, not of the expression though.
+ bool isAddress = isa<LoadInst>(UsersToProcess[i].second.Inst);
+ if (StoreInst *SI = dyn_cast<StoreInst>(UsersToProcess[i].second.Inst))
+ if (SI->getOperand(1) == UsersToProcess[i].second.OperandValToReplace)
+ isAddress = true;
+
+ MoveImmediateValues(UsersToProcess[i].first, UsersToProcess[i].second.Imm,
+ isAddress, L);
+ }
+
+
+
DEBUG(std::cerr << "INSERTING IVs of STRIDE " << *Stride << ":\n");
- // FIXME: This loop needs increasing levels of intelligence.
- // 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. <-- We are here
- // STAGE 2: factor out large constants to try and make more constants
- // acceptable for target loads and stores.
-
// Sort by the base value, so that all IVs with identical bases are next to
// each other.
std::sort(UsersToProcess.begin(), UsersToProcess.end());
More information about the llvm-commits
mailing list