[llvm-commits] [llvm] r61109 - /llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp

Dale Johannesen dalej at apple.com
Tue Dec 16 14:16:29 PST 2008


Author: johannes
Date: Tue Dec 16 16:16:28 2008
New Revision: 61109

URL: http://llvm.org/viewvc/llvm-project?rev=61109&view=rev
Log:
Clarify that the scale factor from CheckForIVReuse
can be negative.  Keep track of whether all uses of
an IV are outside the loop.  Some cosmetics; no
functional change.


Modified:
    llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp

Modified: llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp?rev=61109&r1=61108&r2=61109&view=diff

==============================================================================
--- llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp (original)
+++ llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp Tue Dec 16 16:16:28 2008
@@ -191,7 +191,7 @@
     bool FindIVUserForCond(ICmpInst *Cond, IVStrideUse *&CondUse,
                            const SCEVHandle *&CondStride);
     bool RequiresTypeConversion(const Type *Ty, const Type *NewTy);
-    unsigned CheckForIVReuse(bool, bool, const SCEVHandle&,
+    int64_t CheckForIVReuse(bool, bool, bool, const SCEVHandle&,
                              IVExpr&, const Type*,
                              const std::vector<BasedUser>& UsersToProcess);
     bool ValidStride(bool, int64_t,
@@ -200,6 +200,7 @@
                               IVUsersOfOneStride &Uses,
                               Loop *L,
                               bool &AllUsesAreAddresses,
+                              bool &AllUsesAreOutsideLoop,
                               std::vector<BasedUser> &UsersToProcess);
     void StrengthReduceStridedIVUsers(const SCEVHandle &Stride,
                                       IVUsersOfOneStride &Uses,
@@ -522,7 +523,7 @@
 
     if (AddUserToIVUsers) {
       IVUsersOfOneStride &StrideUses = IVUsesByStride[Stride];
-      if (StrideUses.Users.empty())     // First occurance of this stride?
+      if (StrideUses.Users.empty())     // First occurrence of this stride?
         StrideOrder.push_back(Stride);
       
       // Okay, we found a user that we cannot reduce.  Analyze the instruction
@@ -1060,7 +1061,7 @@
         UseTy = SI->getOperand(0)->getType();
       if (!fitsInAddressMode(FreeResult, UseTy, TLI, Result!=Zero)) {
         // FIXME:  could split up FreeResult into pieces here, some hoisted
-        // and some not.  Doesn't seem worth it for now.
+        // and some not.  There is no obvious advantage to this.
         Result = SE->getAddExpr(Result, FreeResult);
         FreeResult = Zero;
         break;
@@ -1166,9 +1167,10 @@
 /// of a previous stride and it is a legal value for the target addressing
 /// mode scale component and optional base reg. This allows the users of
 /// this stride to be rewritten as prev iv * factor. It returns 0 if no
-/// reuse is possible.
-unsigned LoopStrengthReduce::CheckForIVReuse(bool HasBaseReg,
+/// reuse is possible.  Factors can be negative on same targets, e.g. ARM.
+int64_t LoopStrengthReduce::CheckForIVReuse(bool HasBaseReg,
                                 bool AllUsesAreAddresses,
+                                bool AllUsesAreOutsideLoop,
                                 const SCEVHandle &Stride, 
                                 IVExpr &IV, const Type *Ty,
                                 const std::vector<BasedUser>& UsersToProcess) {
@@ -1236,6 +1238,7 @@
                                               IVUsersOfOneStride &Uses,
                                               Loop *L,
                                               bool &AllUsesAreAddresses,
+                                              bool &AllUsesAreOutsideLoop,
                                        std::vector<BasedUser> &UsersToProcess) {
   UsersToProcess.reserve(Uses.Users.size());
   for (unsigned i = 0, e = Uses.Users.size(); i != e; ++i) {
@@ -1275,7 +1278,7 @@
       UsersToProcess[i].Base = 
         SE->getIntegerSCEV(0, UsersToProcess[i].Base->getType());
     } else {
-      
+
       // Addressing modes can be folded into loads and stores.  Be careful that
       // the store is through the expression, not of the expression though.
       bool isPHI = false;
@@ -1286,6 +1289,9 @@
         ++NumPHI;
       }
 
+      // Not all uses are outside the loop.
+      AllUsesAreOutsideLoop = false; 
+     
       // If this use isn't an address, then not all uses are addresses.
       if (!isAddress && !isPHI)
         AllUsesAreAddresses = false;
@@ -1320,6 +1326,11 @@
   // smaller-stride IV.
   bool AllUsesAreAddresses = true;
 
+  // Keep track if every use of a single stride is outside the loop.  If so,
+  // we want to be more aggressive about reusing a smaller-stride IV; a
+  // multiply outside the loop is better than another IV inside.  Well, usually.
+  bool AllUsesAreOutsideLoop = true;
+
   // Transform our list of users and offsets to a bit more complex table.  In
   // this new vector, each 'BasedUser' contains 'Base' the base of the
   // strided accessas well as the old information from Uses.  We progressively
@@ -1327,6 +1338,7 @@
   // have the full access expression to rewrite the use.
   std::vector<BasedUser> UsersToProcess;
   SCEVHandle CommonExprs = CollectIVUsers(Stride, Uses, L, AllUsesAreAddresses,
+                                          AllUsesAreOutsideLoop,
                                           UsersToProcess);
 
   // If we managed to find some expressions in common, we'll need to carry
@@ -1345,8 +1357,9 @@
   IVExpr   ReuseIV(SE->getIntegerSCEV(0, Type::Int32Ty),
                    SE->getIntegerSCEV(0, Type::Int32Ty),
                    0, 0);
-  unsigned RewriteFactor = 0;
+  int64_t RewriteFactor = 0;
   RewriteFactor = CheckForIVReuse(HaveCommonExprs, AllUsesAreAddresses,
+                                  AllUsesAreOutsideLoop,
                                   Stride, ReuseIV, CommonExprs->getType(),
                                   UsersToProcess);
   if (RewriteFactor != 0) {
@@ -1445,7 +1458,7 @@
     // Get a base value.
     SCEVHandle Base = UsersToProcess[i].Base;
     
-    // Compact everything with this base to be consequtive with this one.
+    // Compact everything with this base to be consecutive with this one.
     for (unsigned j = i+1; j != e; ++j) {
       if (UsersToProcess[j].Base == Base) {
         std::swap(UsersToProcess[i+1], UsersToProcess[j]);
@@ -1508,7 +1521,7 @@
 
       SCEVHandle RewriteExpr = SE->getUnknown(RewriteOp);
 
-      // If we had to insert new instrutions for RewriteOp, we have to
+      // If we had to insert new instructions for RewriteOp, we have to
       // consider that they may not have been able to end up immediately
       // next to RewriteOp, because non-PHI instructions may never precede
       // PHI instructions in a block. In this case, remember where the last
@@ -1535,7 +1548,7 @@
         if (!isa<ConstantInt>(CommonBaseV) ||
             !cast<ConstantInt>(CommonBaseV)->isZero())
           RewriteExpr = SE->getAddExpr(RewriteExpr,
-                                      SE->getUnknown(CommonBaseV));
+                                       SE->getUnknown(CommonBaseV));
       }
 
       // Now that we know what we need to do, insert code before User for the
@@ -1729,9 +1742,11 @@
       }
 
       bool AllUsesAreAddresses = true;
+      bool AllUsesAreOutsideLoop = true;
       std::vector<BasedUser> UsersToProcess;
       SCEVHandle CommonExprs = CollectIVUsers(SI->first, SI->second, L,
                                               AllUsesAreAddresses,
+                                              AllUsesAreOutsideLoop,
                                               UsersToProcess);
       // Avoid rewriting the compare instruction with an iv of new stride
       // if it's likely the new stride uses will be rewritten using the
@@ -2103,7 +2118,7 @@
   UIntPtrTy = TD->getIntPtrType();
   Changed = false;
 
-  // Find all uses of induction variables in this loop, and catagorize
+  // Find all uses of induction variables in this loop, and categorize
   // them by stride.  Start by finding all of the PHI nodes in the header for
   // this loop.  If they are induction variables, inspect their uses.
   SmallPtrSet<Instruction*,16> Processed;   // Don't reprocess instructions.





More information about the llvm-commits mailing list