[llvm-commits] CVS: llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp
Evan Cheng
evan.cheng at apple.com
Mon Mar 13 15:14:34 PST 2006
Changes in directory llvm/lib/Transforms/Scalar:
LoopStrengthReduce.cpp updated: 1.75 -> 1.76
---
Log message:
Added target lowering hooks which LSR consults to make more intelligent
transformation decisions.
---
Diffs of the changes: (+33 -25)
LoopStrengthReduce.cpp | 58 +++++++++++++++++++++++++++----------------------
1 files changed, 33 insertions(+), 25 deletions(-)
Index: llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp
diff -u llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp:1.75 llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp:1.76
--- llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp:1.75 Sat Feb 4 03:52:43 2006
+++ llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp Mon Mar 13 17:14:23 2006
@@ -31,6 +31,7 @@
#include "llvm/Target/TargetData.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/Support/Debug.h"
+#include "llvm/Target/TargetLowering.h"
#include <algorithm>
#include <iostream>
#include <set>
@@ -105,9 +106,14 @@
/// DeadInsts - Keep track of instructions we may have made dead, so that
/// we can remove them after we are done working.
std::set<Instruction*> DeadInsts;
+
+ /// TLI - Keep a pointer of a TargetLowering to consult for determining
+ /// transformation profitability.
+ const TargetLowering *TLI;
+
public:
- LoopStrengthReduce(unsigned MTAMS = 1)
- : MaxTargetAMSize(MTAMS) {
+ LoopStrengthReduce(unsigned MTAMS = 1, const TargetLowering *tli = NULL)
+ : MaxTargetAMSize(MTAMS), TLI(tli) {
}
virtual bool runOnFunction(Function &) {
@@ -162,8 +168,9 @@
"Loop Strength Reduction");
}
-FunctionPass *llvm::createLoopStrengthReducePass(unsigned MaxTargetAMSize) {
- return new LoopStrengthReduce(MaxTargetAMSize);
+FunctionPass *llvm::createLoopStrengthReducePass(unsigned MaxTargetAMSize,
+ const TargetLowering *TLI) {
+ return new LoopStrengthReduce(MaxTargetAMSize, TLI);
}
/// getCastedVersionOf - Return the specified value casted to uintptr_t.
@@ -574,25 +581,25 @@
/// isTargetConstant - Return true if the following can be referenced by the
/// immediate field of a target instruction.
-static bool isTargetConstant(const SCEVHandle &V) {
-
- // FIXME: Look at the target to decide if &GV is a legal constant immediate.
+static bool isTargetConstant(const SCEVHandle &V, const TargetLowering *TLI) {
if (SCEVConstant *SC = dyn_cast<SCEVConstant>(V)) {
- // PPC allows a sign-extended 16-bit immediate field.
int64_t V = SC->getValue()->getSExtValue();
- if (V > -(1 << 16) && V < (1 << 16)-1)
- return true;
- return false;
+ if (TLI)
+ return TLI->isLegalAddressImmediate(V);
+ else
+ // Defaults to PPC. PPC allows a sign-extended 16-bit immediate field.
+ return (V > -(1 << 16) && V < (1 << 16)-1);
}
- return false; // ENABLE this for x86
-
if (SCEVUnknown *SU = dyn_cast<SCEVUnknown>(V))
if (ConstantExpr *CE = dyn_cast<ConstantExpr>(SU->getValue()))
- if (CE->getOpcode() == Instruction::Cast)
- if (isa<GlobalValue>(CE->getOperand(0)))
- // FIXME: should check to see that the dest is uintptr_t!
+ if (CE->getOpcode() == Instruction::Cast) {
+ Constant *Op0 = CE->getOperand(0);
+ if (isa<GlobalValue>(Op0) &&
+ TLI &&
+ TLI->isLegalAddressImmediate(cast<GlobalValue>(Op0)))
return true;
+ }
return false;
}
@@ -638,7 +645,8 @@
/// 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.
-static void MoveImmediateValues(SCEVHandle &Val, SCEVHandle &Imm,
+static void MoveImmediateValues(const TargetLowering *TLI,
+ SCEVHandle &Val, SCEVHandle &Imm,
bool isAddress, Loop *L) {
if (SCEVAddExpr *SAE = dyn_cast<SCEVAddExpr>(Val)) {
std::vector<SCEVHandle> NewOps;
@@ -646,7 +654,7 @@
for (unsigned i = 0; i != SAE->getNumOperands(); ++i) {
SCEVHandle NewOp = SAE->getOperand(i);
- MoveImmediateValues(NewOp, Imm, isAddress, L);
+ MoveImmediateValues(TLI, NewOp, Imm, isAddress, L);
if (!NewOp->isLoopInvariant(L)) {
// If this is a loop-variant expression, it must stay in the immediate
@@ -665,7 +673,7 @@
} 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();
- MoveImmediateValues(Start, Imm, isAddress, L);
+ MoveImmediateValues(TLI, Start, Imm, isAddress, L);
if (Start != SARE->getStart()) {
std::vector<SCEVHandle> Ops(SARE->op_begin(), SARE->op_end());
@@ -675,12 +683,12 @@
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)) &&
+ if (isAddress && isTargetConstant(SME->getOperand(0), TLI) &&
SME->getNumOperands() == 2 && SME->isLoopInvariant(L)) {
SCEVHandle SubImm = SCEVUnknown::getIntegerSCEV(0, Val->getType());
SCEVHandle NewOp = SME->getOperand(1);
- MoveImmediateValues(NewOp, SubImm, isAddress, L);
+ MoveImmediateValues(TLI, NewOp, SubImm, isAddress, L);
// If we extracted something out of the subexpressions, see if we can
// simplify this!
@@ -688,7 +696,7 @@
// 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)) {
+ if (isTargetConstant(SubImm, TLI)) {
// Accumulate the immediate.
Imm = SCEVAddExpr::get(Imm, SubImm);
@@ -702,7 +710,7 @@
// Loop-variant expressions must stay in the immediate field of the
// expression.
- if ((isAddress && isTargetConstant(Val)) ||
+ if ((isAddress && isTargetConstant(Val, TLI)) ||
!Val->isLoopInvariant(L)) {
Imm = SCEVAddExpr::get(Imm, Val);
Val = SCEVUnknown::getIntegerSCEV(0, Val->getType());
@@ -879,7 +887,7 @@
if (SI->getOperand(1) == UsersToProcess[i].OperandValToReplace)
isAddress = true;
- MoveImmediateValues(UsersToProcess[i].Base, UsersToProcess[i].Imm,
+ MoveImmediateValues(TLI, UsersToProcess[i].Base, UsersToProcess[i].Imm,
isAddress, L);
}
}
@@ -941,7 +949,7 @@
// this by forcing a noop cast to be inserted into the preheader in this
// case.
if (Constant *C = dyn_cast<Constant>(BaseV))
- if (!C->isNullValue() && !isTargetConstant(Base)) {
+ if (!C->isNullValue() && !isTargetConstant(Base, TLI)) {
// We want this constant emitted into the preheader!
BaseV = new CastInst(BaseV, BaseV->getType(), "preheaderinsert",
PreInsertPt);
More information about the llvm-commits
mailing list