do not share old induction variables when this would result in invalid
authorDale Johannesen <dalej@apple.com>
Tue, 20 Mar 2007 21:54:54 +0000 (21:54 +0000)
committerDale Johannesen <dalej@apple.com>
Tue, 20 Mar 2007 21:54:54 +0000 (21:54 +0000)
instructions (that would have to be split later)

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@35227 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/Target/TargetLowering.h
lib/CodeGen/SelectionDAG/TargetLowering.cpp
lib/Target/ARM/ARMISelLowering.cpp
lib/Target/ARM/ARMISelLowering.h
lib/Transforms/Scalar/LoopStrengthReduce.cpp

index dc023c8c1f03f4f4cbaa70d31d783a9da680c301..e0d674090712ad369b70e90688c9df48775ce465 100644 (file)
@@ -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
   //
index 8df7d8da39968dbc516edbaea2e078aa13ab8a74..83bca7570f03eba1329b998629e58bb7f6b8b267 100644 (file)
@@ -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
 
index bd7fa5cf6c70af8932fbeba8ce31fa44813bf3c1..17a41c5aaaad221a48f0e890b6b5284c22433ac6 100644 (file)
@@ -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,
index dc146ba0d5b2490c5ba50fa7c8357bd2df072df8..1675e9cffefeb19ecf15a9ac95a4318813e0765f 100644 (file)
@@ -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.
index 4353134093867c2ad84a00b722751da0b135dc06..4ace17f7a4a0fa86a735732362b27b0b44f31184 100644 (file)
@@ -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 "