diff options
author | Evan Cheng <evan.cheng@apple.com> | 2006-03-13 23:14:23 +0000 |
---|---|---|
committer | Evan Cheng <evan.cheng@apple.com> | 2006-03-13 23:14:23 +0000 |
commit | d277f2c66914aecb619c12855f6afae4c7ef883b (patch) | |
tree | 8b295f06b51efbea22834b5be9261d36862d926f | |
parent | 872421553e3187717b6c29784e2009ce5cc6811c (diff) | |
download | external_llvm-d277f2c66914aecb619c12855f6afae4c7ef883b.zip external_llvm-d277f2c66914aecb619c12855f6afae4c7ef883b.tar.gz external_llvm-d277f2c66914aecb619c12855f6afae4c7ef883b.tar.bz2 |
Added target lowering hooks which LSR consults to make more intelligent
transformation decisions.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@26738 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | include/llvm/Transforms/Scalar.h | 10 | ||||
-rw-r--r-- | lib/Transforms/Scalar/LoopStrengthReduce.cpp | 58 |
2 files changed, 41 insertions, 27 deletions
diff --git a/include/llvm/Transforms/Scalar.h b/include/llvm/Transforms/Scalar.h index eb2f896..701460d 100644 --- a/include/llvm/Transforms/Scalar.h +++ b/include/llvm/Transforms/Scalar.h @@ -15,6 +15,8 @@ #ifndef LLVM_TRANSFORMS_SCALAR_H #define LLVM_TRANSFORMS_SCALAR_H +#include <cstdlib> + namespace llvm { class ModulePass; @@ -22,6 +24,7 @@ class FunctionPass; class GetElementPtrInst; class PassInfo; class TerminatorInst; +class TargetLowering; //===----------------------------------------------------------------------===// // @@ -132,9 +135,12 @@ FunctionPass *createLICMPass(); // a loop's canonical induction variable as one of their indices. The // MaxTargetAMSize is the largest element size that the target architecture // can handle in its addressing modes. Power of two multipliers less than or -// equal to this value are not reduced. +// equal to this value are not reduced. It also takes an optional second +// parameter used to consult the target machine whether certain transformations +// are profitable. // -FunctionPass *createLoopStrengthReducePass(unsigned MaxTargetAMSize = 1); +FunctionPass *createLoopStrengthReducePass(unsigned MaxTargetAMSize = 1, + const TargetLowering *TLI = NULL); //===----------------------------------------------------------------------===// // diff --git a/lib/Transforms/Scalar/LoopStrengthReduce.cpp b/lib/Transforms/Scalar/LoopStrengthReduce.cpp index 45a79d7..2723176 100644 --- a/lib/Transforms/Scalar/LoopStrengthReduce.cpp +++ b/lib/Transforms/Scalar/LoopStrengthReduce.cpp @@ -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 @@ namespace { /// 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 @@ private: "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 @@ void BasedUser::RewriteInstructionToUseNewBase(const SCEVHandle &NewBase, /// 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 @@ static void MoveLoopVariantsToImediateField(SCEVHandle &Val, SCEVHandle &Imm, /// 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 @@ static void MoveImmediateValues(SCEVHandle &Val, SCEVHandle &Imm, 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 @@ static void MoveImmediateValues(SCEVHandle &Val, SCEVHandle &Imm, } 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 @@ static void MoveImmediateValues(SCEVHandle &Val, SCEVHandle &Imm, 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 @@ static void MoveImmediateValues(SCEVHandle &Val, SCEVHandle &Imm, // 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 @@ static void MoveImmediateValues(SCEVHandle &Val, SCEVHandle &Imm, // 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 @@ void LoopStrengthReduce::StrengthReduceStridedIVUsers(const SCEVHandle &Stride, 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 @@ void LoopStrengthReduce::StrengthReduceStridedIVUsers(const SCEVHandle &Stride, // 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); |