aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/llvm/Target/TargetLowering.h11
-rw-r--r--lib/CodeGen/SelectionDAG/TargetLowering.cpp13
-rw-r--r--lib/Target/X86/X86ISelLowering.cpp39
3 files changed, 58 insertions, 5 deletions
diff --git a/include/llvm/Target/TargetLowering.h b/include/llvm/Target/TargetLowering.h
index 29c7fb2c10..0ec98a26c8 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;
@@ -560,6 +560,15 @@ public:
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 bceca139b7..d068fec40c 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<unsigned, const TargetRegisterClass*>(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 b2f3f18ec2..bf0d6d8e56 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<unsigned>();
}
+
+/// 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<X86Subtarget>().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;
+}