diff --git a/include/llvm/Target/TargetLowering.h b/include/llvm/Target/TargetLowering.h index 29c7fb2c10f..0ec98a26c81 100644 --- a/include/llvm/Target/TargetLowering.h +++ b/include/llvm/Target/TargetLowering.h @@ -349,7 +349,7 @@ public: uint64_t &KnownZero, uint64_t &KnownOne, unsigned Depth = 0) const; - + struct DAGCombinerInfo { void *DC; // The DAG Combiner object. bool BeforeLegalize; @@ -559,6 +559,15 @@ public: /// valid for the specified target constraint letter. virtual bool isOperandValidForConstraint(SDOperand Op, char ConstraintLetter); + //===--------------------------------------------------------------------===// + // Loop Strength Reduction hooks + // + + /// isLegalAddressImmediate - Return true if the integer value or GlobalValue + /// can be used as the offset of the target addressing mode. + virtual bool isLegalAddressImmediate(int64_t V) const; + virtual bool isLegalAddressImmediate(GlobalValue *GV) const; + //===--------------------------------------------------------------------===// // Scheduler hooks // diff --git a/lib/CodeGen/SelectionDAG/TargetLowering.cpp b/lib/CodeGen/SelectionDAG/TargetLowering.cpp index bceca139b7b..d068fec40c9 100644 --- a/lib/CodeGen/SelectionDAG/TargetLowering.cpp +++ b/lib/CodeGen/SelectionDAG/TargetLowering.cpp @@ -976,3 +976,16 @@ getRegForInlineAsmConstraint(const std::string &Constraint, return std::pair(0, 0); } + +//===----------------------------------------------------------------------===// +// Loop Strength Reduction hooks +//===----------------------------------------------------------------------===// + +/// isLegalAddressImmediate - Return true if the integer value or +/// GlobalValue can be used as the offset of the target addressing mode. +bool TargetLowering::isLegalAddressImmediate(int64_t V) const { + return false; +} +bool TargetLowering::isLegalAddressImmediate(GlobalValue *GV) const { + return false; +} diff --git a/lib/Target/X86/X86ISelLowering.cpp b/lib/Target/X86/X86ISelLowering.cpp index b2f3f18ec2f..bf0d6d8e56d 100644 --- a/lib/Target/X86/X86ISelLowering.cpp +++ b/lib/Target/X86/X86ISelLowering.cpp @@ -19,6 +19,8 @@ #include "llvm/CallingConv.h" #include "llvm/Constants.h" #include "llvm/Function.h" +#include "llvm/ADT/VectorExtras.h" +#include "llvm/Analysis/ScalarEvolutionExpressions.h" #include "llvm/CodeGen/MachineFrameInfo.h" #include "llvm/CodeGen/MachineFunction.h" #include "llvm/CodeGen/MachineInstrBuilder.h" @@ -26,7 +28,6 @@ #include "llvm/CodeGen/SSARegMap.h" #include "llvm/Support/MathExtras.h" #include "llvm/Target/TargetOptions.h" -#include "llvm/ADT/VectorExtras.h" using namespace llvm; // FIXME: temporary. @@ -1317,6 +1318,16 @@ X86TargetLowering::InsertAtEndOfBasicBlock(MachineInstr *MI, // X86 Custom Lowering Hooks //===----------------------------------------------------------------------===// +/// DarwinGVRequiresExtraLoad - true if accessing the GV requires an extra +/// load. For Darwin, external and weak symbols are indirect, loading the value +/// at address GV rather then the value of GV itself. This means that the +/// GlobalAddress must be in the base or index register of the address, not the +/// GV offset field. +static bool DarwinGVRequiresExtraLoad(GlobalValue *GV) { + return (GV->hasWeakLinkage() || GV->hasLinkOnceLinkage() || + (GV->isExternal() && !GV->hasNotBeenReadFromBytecode())); +} + /// LowerOperation - Provide custom lowering hooks for some operations. /// SDOperand X86TargetLowering::LowerOperation(SDOperand Op, SelectionDAG &DAG) { @@ -1986,12 +1997,11 @@ SDOperand X86TargetLowering::LowerOperation(SDOperand Op, SelectionDAG &DAG) { DAG.getNode(X86ISD::GlobalBaseReg, getPointerTy()), Result); // For Darwin, external and weak symbols are indirect, so we want to load - // the value at address GV, not the value of GV itself. This means that + // the value at address GV, not the value of GV itself. This means that // the GlobalAddress must be in the base or index register of the address, // not the GV offset field. if (getTargetMachine().getRelocationModel() != Reloc::Static && - (GV->hasWeakLinkage() || GV->hasLinkOnceLinkage() || - (GV->isExternal() && !GV->hasNotBeenReadFromBytecode()))) + DarwinGVRequiresExtraLoad(GV)) Result = DAG.getLoad(MVT::i32, DAG.getEntryNode(), Result, DAG.getSrcValue(NULL)); } @@ -2179,3 +2189,24 @@ getRegClassForInlineAsmConstraint(const std::string &Constraint, return std::vector(); } + +/// isLegalAddressImmediate - Return true if the integer value or +/// GlobalValue can be used as the offset of the target addressing mode. +bool X86TargetLowering::isLegalAddressImmediate(int64_t V) const { + // X86 allows a sign-extended 32-bit immediate field. + return (V > -(1LL << 32) && V < (1LL << 32)-1); +} + +bool X86TargetLowering::isLegalAddressImmediate(GlobalValue *GV) const { + if (getTargetMachine(). + getSubtarget().isTargetDarwin()) { + Reloc::Model RModel = getTargetMachine().getRelocationModel(); + if (RModel == Reloc::Static) + return true; + else if (RModel == Reloc::DynamicNoPIC) + return DarwinGVRequiresExtraLoad(GV); + else + return false; + } else + return true; +}