aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/llvm/Target/TargetLowering.h10
-rw-r--r--lib/CodeGen/SelectionDAG/TargetLowering.cpp16
-rw-r--r--lib/Target/ARM/ARMISelLowering.cpp18
-rw-r--r--lib/Target/ARM/ARMISelLowering.h11
-rw-r--r--lib/Transforms/Scalar/LoopStrengthReduce.cpp44
5 files changed, 81 insertions, 18 deletions
diff --git a/include/llvm/Target/TargetLowering.h b/include/llvm/Target/TargetLowering.h
index dc023c8c1f..e0d6740907 100644
--- a/include/llvm/Target/TargetLowering.h
+++ b/include/llvm/Target/TargetLowering.h
@@ -875,6 +875,16 @@ public:
/// scale of the target addressing mode for load / store of the given type.
virtual bool isLegalAddressScale(int64_t S, const Type *Ty) const;
+ /// isLegalAddressScaleAndImm - Return true if S works for IsLegalAddressScale
+ /// and V works for isLegalAddressImmediate _and_ both can be applied
+ /// simultaneously to the same instruction.
+ virtual bool isLegalAddressScaleAndImm(int64_t S, int64_t V,
+ const Type* Ty) const;
+ /// isLegalAddressScaleAndImm - Return true if S works for IsLegalAddressScale
+ /// and GV works for isLegalAddressImmediate _and_ both can be applied
+ /// simultaneously to the same instruction.
+ virtual bool isLegalAddressScaleAndImm(int64_t S, GlobalValue *GV) const;
+
//===--------------------------------------------------------------------===//
// Div utility functions
//
diff --git a/lib/CodeGen/SelectionDAG/TargetLowering.cpp b/lib/CodeGen/SelectionDAG/TargetLowering.cpp
index 8df7d8da39..83bca7570f 100644
--- a/lib/CodeGen/SelectionDAG/TargetLowering.cpp
+++ b/lib/CodeGen/SelectionDAG/TargetLowering.cpp
@@ -1958,6 +1958,22 @@ bool TargetLowering::isLegalAddressScale(int64_t S, const Type *Ty) const {
return false;
}
+/// isLegalAddressScaleAndImm - Return true if S works for IsLegalAddressScale
+/// and V works for isLegalAddressImmediate _and_ both can be applied
+/// simultaneously to the same instruction.
+bool TargetLowering::isLegalAddressScaleAndImm(int64_t S, int64_t V,
+ const Type* Ty) const {
+ return false;
+}
+
+/// isLegalAddressScaleAndImm - Return true if S works for IsLegalAddressScale
+/// and GV works for isLegalAddressImmediate _and_ both can be applied
+/// simultaneously to the same instruction.
+bool TargetLowering::isLegalAddressScaleAndImm(int64_t S,
+ GlobalValue *GV) const {
+
+ return false;
+}
// Magic for divide replacement
diff --git a/lib/Target/ARM/ARMISelLowering.cpp b/lib/Target/ARM/ARMISelLowering.cpp
index bd7fa5cf6c..17a41c5aaa 100644
--- a/lib/Target/ARM/ARMISelLowering.cpp
+++ b/lib/Target/ARM/ARMISelLowering.cpp
@@ -1379,6 +1379,24 @@ bool ARMTargetLowering::isLegalAddressScale(int64_t S, const Type *Ty) const {
}
}
+/// isLegalAddressScaleAndImm - Return true if S works for IsLegalAddressScale
+/// and V works for isLegalAddressImmediate _and_ both can be applied
+/// simultaneously to the same instruction.
+bool ARMTargetLowering::isLegalAddressScaleAndImm(int64_t S, int64_t V,
+ const Type* Ty) const {
+ if (V == 0)
+ return isLegalAddressScale(S, Ty);
+ return false;
+}
+
+/// isLegalAddressScaleAndImm - Return true if S works for IsLegalAddressScale
+/// and GV works for isLegalAddressImmediate _and_ both can be applied
+/// simultaneously to the same instruction.
+bool ARMTargetLowering::isLegalAddressScaleAndImm(int64_t S,
+ GlobalValue *GV) const {
+ return false;
+}
+
static bool getIndexedAddressParts(SDNode *Ptr, MVT::ValueType VT,
bool isSEXTLoad, SDOperand &Base,
SDOperand &Offset, bool &isInc,
diff --git a/lib/Target/ARM/ARMISelLowering.h b/lib/Target/ARM/ARMISelLowering.h
index dc146ba0d5..1675e9cffe 100644
--- a/lib/Target/ARM/ARMISelLowering.h
+++ b/lib/Target/ARM/ARMISelLowering.h
@@ -100,6 +100,17 @@ namespace llvm {
/// type.
virtual bool isLegalAddressScale(int64_t S, const Type *Ty) const;
+ /// isLegalAddressScaleAndImm - Return true if S works for
+ /// IsLegalAddressScale and V works for isLegalAddressImmediate _and_
+ /// both can be applied simultaneously to the same instruction.
+ virtual bool isLegalAddressScaleAndImm(int64_t S, int64_t V,
+ const Type *Ty) const;
+
+ /// isLegalAddressScaleAndImm - Return true if S works for
+ /// IsLegalAddressScale and GV works for isLegalAddressImmediate _and_
+ /// both can be applied simultaneously to the same instruction.
+ virtual bool isLegalAddressScaleAndImm(int64_t S, GlobalValue *GV) const;
+
/// getPreIndexedAddressParts - returns true by value, base pointer and
/// offset pointer and addressing mode by reference if the node's address
/// can be legally represented as pre-indexed load / store address.
diff --git a/lib/Transforms/Scalar/LoopStrengthReduce.cpp b/lib/Transforms/Scalar/LoopStrengthReduce.cpp
index 4353134093..4ace17f7a4 100644
--- a/lib/Transforms/Scalar/LoopStrengthReduce.cpp
+++ b/lib/Transforms/Scalar/LoopStrengthReduce.cpp
@@ -883,9 +883,16 @@ static bool isZero(SCEVHandle &V) {
///
bool LoopStrengthReduce::ValidStride(int64_t Scale,
const std::vector<BasedUser>& UsersToProcess) {
- for (unsigned i=0, e = UsersToProcess.size(); i!=e; ++i)
- if (!TLI->isLegalAddressScale(Scale, UsersToProcess[i].Inst->getType()))
+ int64_t Imm;
+ for (unsigned i=0, e = UsersToProcess.size(); i!=e; ++i) {
+ if (SCEVConstant *SC = dyn_cast<SCEVConstant>(UsersToProcess[i].Imm))
+ Imm = SC->getValue()->getSExtValue();
+ else
+ Imm = 0;
+ if (!TLI->isLegalAddressScaleAndImm(Scale, Imm,
+ UsersToProcess[i].Inst->getType()))
return false;
+ }
return true;
}
@@ -968,22 +975,6 @@ void LoopStrengthReduce::StrengthReduceStridedIVUsers(const SCEVHandle &Stride,
SCEVHandle CommonExprs =
RemoveCommonExpressionsFromUseBases(UsersToProcess);
- // Check if it is possible to reuse a IV with stride that is factor of this
- // stride. And the multiple is a number that can be encoded in the scale
- // field of the target addressing mode.
- PHINode *NewPHI = NULL;
- Value *IncV = NULL;
- IVExpr ReuseIV;
- unsigned RewriteFactor = CheckForIVReuse(Stride, ReuseIV,
- CommonExprs->getType(),
- UsersToProcess);
- if (RewriteFactor != 0) {
- DOUT << "BASED ON IV of STRIDE " << *ReuseIV.Stride
- << " and BASE " << *ReuseIV.Base << " :\n";
- NewPHI = ReuseIV.PHI;
- IncV = ReuseIV.IncV;
- }
-
// 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. We do this so that it increases the commonality
@@ -1011,6 +1002,23 @@ void LoopStrengthReduce::StrengthReduceStridedIVUsers(const SCEVHandle &Stride,
}
}
+ // Check if it is possible to reuse a IV with stride that is factor of this
+ // stride. And the multiple is a number that can be encoded in the scale
+ // field of the target addressing mode. And we will have a valid
+ // instruction after this substition, including the immediate field, if any.
+ PHINode *NewPHI = NULL;
+ Value *IncV = NULL;
+ IVExpr ReuseIV;
+ unsigned RewriteFactor = CheckForIVReuse(Stride, ReuseIV,
+ CommonExprs->getType(),
+ UsersToProcess);
+ if (RewriteFactor != 0) {
+ DOUT << "BASED ON IV of STRIDE " << *ReuseIV.Stride
+ << " and BASE " << *ReuseIV.Base << " :\n";
+ NewPHI = ReuseIV.PHI;
+ IncV = ReuseIV.IncV;
+ }
+
// Now that we know what we need to do, insert the PHI node itself.
//
DOUT << "INSERTING IV of STRIDE " << *Stride << " and BASE "