gallivm: Updated lp_build_polynomial to compute odd and even terms separately to...
authorJames Benton <jbenton@vmware.com>
Thu, 5 Apr 2012 19:32:51 +0000 (20:32 +0100)
committerJosé Fonseca <jfonseca@vmware.com>
Thu, 5 Apr 2012 19:32:54 +0000 (20:32 +0100)
Signed-off-by: José Fonseca <jfonseca@vmware.com>
src/gallium/auxiliary/gallivm/lp_bld_arit.c

index 6b17fbd2d31043708ea860311d992ec591653b1c..d07cf689de36c99f32bbc497a198a91dfcf420c7 100644 (file)
@@ -2163,7 +2163,8 @@ lp_build_polynomial(struct lp_build_context *bld,
                     unsigned num_coeffs)
 {
    const struct lp_type type = bld->type;
-   LLVMValueRef res = NULL;
+   LLVMValueRef even = NULL, odd = NULL;
+   LLVMValueRef x2;
    unsigned i;
 
    assert(lp_check_value(bld->type, x));
@@ -2175,19 +2176,36 @@ lp_build_polynomial(struct lp_build_context *bld,
                    __FUNCTION__);
    }
 
+   /*
+    * Calculate odd and even terms seperately to decrease data dependency
+    * Ex:
+    *     c[0] + x^2 * c[2] + x^4 * c[4] ...
+    *     + x * (c[1] + x^2 * c[3] + x^4 * c[5]) ...
+    */
+   x2 = lp_build_mul(bld, x, x);
+
    for (i = num_coeffs; i--; ) {
       LLVMValueRef coeff;
 
       coeff = lp_build_const_vec(bld->gallivm, type, coeffs[i]);
 
-      if(res)
-         res = lp_build_add(bld, coeff, lp_build_mul(bld, x, res));
-      else
-         res = coeff;
+      if (i % 2 == 0) {
+         if (even)
+            even = lp_build_add(bld, coeff, lp_build_mul(bld, x2, even));
+         else
+            even = coeff;
+      } else {
+         if (odd)
+            odd = lp_build_add(bld, coeff, lp_build_mul(bld, x2, odd));
+         else
+            odd = coeff;
+      }
    }
 
-   if(res)
-      return res;
+   if (odd)
+      return lp_build_add(bld, lp_build_mul(bld, odd, x), even);
+   else if (even)
+      return even;
    else
       return bld->undef;
 }