[llvm-commits] CVS: llvm/lib/Analysis/ScalarEvolution.cpp

Chris Lattner sabre at nondot.org
Mon Dec 11 18:26:24 PST 2006



Changes in directory llvm/lib/Analysis:

ScalarEvolution.cpp updated: 1.68 -> 1.69
---
Log message:

teach scev to analyze X*4|1 like X*4+c.  This allows us to produce:

LBB1_1: #bb
        movdqa (%esi), %xmm2
        movaps %xmm2, %xmm3
        punpcklbw %xmm0, %xmm3
        movaps %xmm3, %xmm4
        punpcklwd %xmm0, %xmm4
        cvtdq2ps %xmm4, %xmm4
        mulps %xmm1, %xmm4
        movaps %xmm4, (%edi)
        leal 1(,%eax,4), %ebx
        shll $4, %ebx
        punpckhwd %xmm0, %xmm3
        cvtdq2ps %xmm3, %xmm3
        mulps %xmm1, %xmm3
        movaps %xmm3, (%edx,%ebx)
        leal 2(,%eax,4), %ebx
        shll $4, %ebx
        punpckhbw %xmm0, %xmm2
        movaps %xmm2, %xmm3
        punpcklwd %xmm0, %xmm3
        cvtdq2ps %xmm3, %xmm3
        mulps %xmm1, %xmm3
        movaps %xmm3, (%edx,%ebx)
        leal 3(,%eax,4), %ebx
        shll $4, %ebx
        punpckhwd %xmm0, %xmm2
        cvtdq2ps %xmm2, %xmm2
        mulps %xmm1, %xmm2
        movaps %xmm2, (%edx,%ebx)
        addl $64, %edi
        incl %eax
        addl $16, %esi
        cmpl %ecx, %eax
        jne LBB1_1      #bb

instead of:

LBB1_1: #bb
        movdqa (%esi), %xmm2
        movaps %xmm2, %xmm3
        punpcklbw %xmm0, %xmm3
        movaps %xmm3, %xmm4
        punpcklwd %xmm0, %xmm4
        cvtdq2ps %xmm4, %xmm4
        mulps %xmm1, %xmm4
        movaps %xmm4, (%edi)
        leal 1(,%eax,4), %ebx
        shll $4, %ebx
        punpckhwd %xmm0, %xmm3
        cvtdq2ps %xmm3, %xmm3
        mulps %xmm1, %xmm3
        movaps %xmm3, (%edx,%ebx)
        leal 2(,%eax,4), %ebx
        shll $4, %ebx
        punpckhbw %xmm0, %xmm2
        movaps %xmm2, %xmm3
        punpcklwd %xmm0, %xmm3
        cvtdq2ps %xmm3, %xmm3
        mulps %xmm1, %xmm3
        movaps %xmm3, (%edx,%ebx)
        leal 3(,%eax,4), %ebx
        shll $4, %ebx
        punpckhwd %xmm0, %xmm2
        cvtdq2ps %xmm2, %xmm2
        mulps %xmm1, %xmm2
        movaps %xmm2, (%edx,%ebx)
        addl $64, %edi
        incl %eax
        addl $16, %esi
        cmpl %ecx, %eax
        jne LBB1_1      #bb

for a testcase.



---
Diffs of the changes:  (+59 -1)

 ScalarEvolution.cpp |   60 +++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 59 insertions(+), 1 deletion(-)


Index: llvm/lib/Analysis/ScalarEvolution.cpp
diff -u llvm/lib/Analysis/ScalarEvolution.cpp:1.68 llvm/lib/Analysis/ScalarEvolution.cpp:1.69
--- llvm/lib/Analysis/ScalarEvolution.cpp:1.68	Sun Dec 10 18:12:31 2006
+++ llvm/lib/Analysis/ScalarEvolution.cpp	Mon Dec 11 20:26:09 2006
@@ -1339,6 +1339,49 @@
   return SCEVUnknown::get(PN);
 }
 
+/// GetConstantFactor - Determine the largest constant factor that S has.  For
+/// example, turn {4,+,8} -> 4.    (S umod result) should always equal zero.
+static uint64_t GetConstantFactor(SCEVHandle S) {
+  if (SCEVConstant *C = dyn_cast<SCEVConstant>(S)) {
+    if (uint64_t V = C->getValue()->getZExtValue())
+      return V;
+    else   // Zero is a multiple of everything.
+      return 1ULL << (S->getType()->getPrimitiveSizeInBits()-1);
+  }
+
+  if (SCEVTruncateExpr *T = dyn_cast<SCEVTruncateExpr>(S))
+    return GetConstantFactor(T->getOperand()) &
+           T->getType()->getIntegralTypeMask();
+  if (SCEVZeroExtendExpr *E = dyn_cast<SCEVZeroExtendExpr>(S))
+    return GetConstantFactor(E->getOperand());
+  
+  if (SCEVAddExpr *A = dyn_cast<SCEVAddExpr>(S)) {
+    // The result is the min of all operands.
+    uint64_t Res = GetConstantFactor(A->getOperand(0));
+    for (unsigned i = 1, e = A->getNumOperands(); i != e && Res > 1; ++i)
+      Res = std::min(Res, GetConstantFactor(A->getOperand(i)));
+    return Res;
+  }
+
+  if (SCEVMulExpr *M = dyn_cast<SCEVMulExpr>(S)) {
+    // The result is the product of all the operands.
+    uint64_t Res = GetConstantFactor(M->getOperand(0));
+    for (unsigned i = 1, e = M->getNumOperands(); i != e; ++i)
+      Res *= GetConstantFactor(M->getOperand(i));
+    return Res;
+  }
+    
+  if (SCEVAddRecExpr *A = dyn_cast<SCEVAddRecExpr>(S)) {
+    // FIXME: Generalize.
+    if (A->getNumOperands() == 2)
+      return std::min(GetConstantFactor(A->getOperand(0)),
+                      GetConstantFactor(A->getOperand(1)));
+    // ?
+  }
+  
+  // SCEVSDivExpr, SCEVUnknown.
+  return 1;
+}
 
 /// createSCEV - We know that there is no SCEV for the specified value.
 /// Analyze the expression.
@@ -1360,7 +1403,22 @@
     case Instruction::Sub:
       return SCEV::getMinusSCEV(getSCEV(I->getOperand(0)),
                                 getSCEV(I->getOperand(1)));
-
+    case Instruction::Or:
+      // If the RHS of the Or is a constant, we may have something like:
+      // X*4+1 which got turned into X*4|1.  Handle this as an add so loop
+      // optimizations will transparently handle this case.
+      if (ConstantInt *CI = dyn_cast<ConstantInt>(I->getOperand(1))) {
+        SCEVHandle LHS = getSCEV(I->getOperand(0));
+        uint64_t CommonFact = GetConstantFactor(LHS);
+        assert(CommonFact && "Common factor should at least be 1!");
+        if (CommonFact > CI->getZExtValue()) {
+          // If the LHS is a multiple that is larger than the RHS, use +.
+          return SCEVAddExpr::get(LHS,
+                                  getSCEV(I->getOperand(1)));
+        }
+      }
+      break;
+      
     case Instruction::Shl:
       // Turn shift left of a constant amount into a multiply.
       if (ConstantInt *SA = dyn_cast<ConstantInt>(I->getOperand(1))) {






More information about the llvm-commits mailing list