[llvm-commits] CVS: llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp

Chris Lattner lattner at cs.uiuc.edu
Sat Aug 13 00:27:30 PDT 2005



Changes in directory llvm/lib/Transforms/Scalar:

LoopStrengthReduce.cpp updated: 1.49 -> 1.50
---
Log message:

Recursively scan scev expressions for common subexpressions.  This allows us
to handle nested loops much better, for example, by being able to tell that 
these two expressions:

{( 8 + ( 16 * ( 1 +  %Tmp11 +  %Tmp12)) +  %c_),+,( 16 *  %Tmp 12)}<loopentry.1>

{(( 16 * ( 1 +  %Tmp11 +  %Tmp12)) +  %c_),+,( 16 *  %Tmp12)}<loopentry.1>

Have the following common part that can be shared:
{(( 16 * ( 1 +  %Tmp11 +  %Tmp12)) +  %c_),+,( 16 *  %Tmp12)}<loopentry.1>

This allows us to codegen an important inner loop in 168.wupwise as:

.LBB_foo_4:     ; no_exit.1
        lfd f2, 16(r9)
        fmul f3, f0, f2
        fmul f2, f1, f2
        fadd f4, f3, f2
        stfd f4, 8(r9)
        fsub f2, f3, f2
        stfd f2, 16(r9)
        addi r8, r8, 1
        addi r9, r9, 16
        cmpw cr0, r8, r4
        ble .LBB_foo_4  ; no_exit.1

instead of:

.LBB_foo_3:     ; no_exit.1
        lfdx f2, r6, r9
        add r10, r6, r9
        lfd f3, 8(r10)
        fmul f4, f1, f2
        fmadd f4, f0, f3, f4
        stfd f4, 8(r10)
        fmul f3, f1, f3
        fmsub f2, f0, f2, f3
        stfdx f2, r6, r9
        addi r9, r9, 16
        addi r8, r8, 1
        cmpw cr0, r8, r4
        ble .LBB_foo_3  ; no_exit.1




---
Diffs of the changes:  (+61 -28)

 LoopStrengthReduce.cpp |   89 +++++++++++++++++++++++++++++++++----------------
 1 files changed, 61 insertions(+), 28 deletions(-)


Index: llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp
diff -u llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp:1.49 llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp:1.50
--- llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp:1.49	Fri Aug 12 17:22:17 2005
+++ llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp	Sat Aug 13 02:27:18 2005
@@ -593,6 +593,36 @@
   // Otherwise, no immediates to move.
 }
 
+
+/// IncrementAddExprUses - Decompose the specified expression into its added
+/// subexpressions, and increment SubExpressionUseCounts for each of these
+/// decomposed parts.
+static void SeparateSubExprs(std::vector<SCEVHandle> &SubExprs,
+                             SCEVHandle Expr) {
+  if (SCEVAddExpr *AE = dyn_cast<SCEVAddExpr>(Expr)) {
+    for (unsigned j = 0, e = AE->getNumOperands(); j != e; ++j)
+      SeparateSubExprs(SubExprs, AE->getOperand(j));
+  } else if (SCEVAddRecExpr *SARE = dyn_cast<SCEVAddRecExpr>(Expr)) {
+    SCEVHandle Zero = SCEVUnknown::getIntegerSCEV(0, Expr->getType());
+    if (SARE->getOperand(0) == Zero) {
+      SubExprs.push_back(Expr);
+    } else {
+      // Compute the addrec with zero as its base.
+      std::vector<SCEVHandle> Ops(SARE->op_begin(), SARE->op_end());
+      Ops[0] = Zero;   // Start with zero base.
+      SubExprs.push_back(SCEVAddRecExpr::get(Ops, SARE->getLoop()));
+      
+
+      SeparateSubExprs(SubExprs, SARE->getOperand(0));
+    }
+  } else if (!isa<SCEVConstant>(Expr) ||
+             !cast<SCEVConstant>(Expr)->getValue()->isNullValue()) {
+    // Do not add zero.
+    SubExprs.push_back(Expr);
+  }
+}
+
+
 /// RemoveCommonExpressionsFromUseBases - Look through all of the uses in Bases,
 /// removing any common subexpressions from it.  Anything truly common is
 /// removed, accumulated, and returned.  This looks for things like (a+b+c) and
@@ -613,17 +643,21 @@
   // If any subexpressions are used Uses.size() times, they are common.
   std::map<SCEVHandle, unsigned> SubExpressionUseCounts;
   
-  for (unsigned i = 0; i != NumUses; ++i)
-    if (SCEVAddExpr *AE = dyn_cast<SCEVAddExpr>(Uses[i].Base)) {
-      for (unsigned j = 0, e = AE->getNumOperands(); j != e; ++j)
-        SubExpressionUseCounts[AE->getOperand(j)]++;
-    } else {
-      // If the base is zero (which is common), return zero now, there are no
-      // CSEs we can find.
-      if (Uses[i].Base == Zero) return Result;
-      SubExpressionUseCounts[Uses[i].Base]++;
-    }
-  
+  std::vector<SCEVHandle> SubExprs;
+  for (unsigned i = 0; i != NumUses; ++i) {
+    // If the base is zero (which is common), return zero now, there are no
+    // CSEs we can find.
+    if (Uses[i].Base == Zero) return Zero;
+
+    // Split the expression into subexprs.
+    SeparateSubExprs(SubExprs, Uses[i].Base);
+    // Add one to SubExpressionUseCounts for each subexpr present.
+    for (unsigned j = 0, e = SubExprs.size(); j != e; ++j)
+      SubExpressionUseCounts[SubExprs[j]]++;
+    SubExprs.clear();
+  }
+
+
   // Now that we know how many times each is used, build Result.
   for (std::map<SCEVHandle, unsigned>::iterator I =
        SubExpressionUseCounts.begin(), E = SubExpressionUseCounts.end();
@@ -640,24 +674,23 @@
   if (Result == Zero) return Result;
   
   // Otherwise, remove all of the CSE's we found from each of the base values.
-  for (unsigned i = 0; i != NumUses; ++i)
-    if (SCEVAddExpr *AE = dyn_cast<SCEVAddExpr>(Uses[i].Base)) {
-      std::vector<SCEVHandle> NewOps;
-      
-      // Remove all of the values that are now in SubExpressionUseCounts.
-      for (unsigned j = 0, e = AE->getNumOperands(); j != e; ++j)
-        if (!SubExpressionUseCounts.count(AE->getOperand(j)))
-          NewOps.push_back(AE->getOperand(j));
-      if (NewOps.empty())
-        Uses[i].Base = Zero;
-      else
-        Uses[i].Base = SCEVAddExpr::get(NewOps);
-    } else {
-      // If the base is zero (which is common), return zero now, there are no
-      // CSEs we can find.
-      assert(Uses[i].Base == Result);
+  for (unsigned i = 0; i != NumUses; ++i) {
+    // Split the expression into subexprs.
+    SeparateSubExprs(SubExprs, Uses[i].Base);
+
+    // Remove any common subexpressions.
+    for (unsigned j = 0, e = SubExprs.size(); j != e; ++j)
+      if (SubExpressionUseCounts.count(SubExprs[j])) {
+        SubExprs.erase(SubExprs.begin()+j);
+        --j; --e;
+      }
+    
+    // Finally, the non-shared expressions together.
+    if (SubExprs.empty())
       Uses[i].Base = Zero;
-    }
+    else
+      Uses[i].Base = SCEVAddExpr::get(SubExprs);
+  }
  
   return Result;
 }






More information about the llvm-commits mailing list