isl_ast_expr_from_constraint: split off constant term if it avoids operation
authorSven Verdoolaege <skimo@kotnet.org>
Sun, 19 May 2013 15:35:48 +0000 (17:35 +0200)
committerSven Verdoolaege <skimo@kotnet.org>
Thu, 23 May 2013 12:25:36 +0000 (14:25 +0200)
If one hand of the comparison operation that is constructed would be
exactly zero, then we put the constant term on that side.
This avoids the operation that adds the constant term to the other side,
resulting in slightly smaller expressions that are easier to read and
that may also reduce the risk of overflows.

Signed-off-by: Sven Verdoolaege <skimo@kotnet.org>
isl_ast_build_expr.c
test_inputs/codegen/cloog/reservoir-liu-zhuge1.c
test_inputs/codegen/cloog/unroll2.c
test_inputs/codegen/omega/ts1d-mp-i_ts-m_b-0.c
test_inputs/codegen/unroll6.c

index 86a9e6e..81d8fbf 100644 (file)
@@ -558,18 +558,31 @@ static __isl_give isl_ast_expr *add_signed_terms(__isl_take isl_ast_expr *expr,
                }
        }
 
-       isl_aff_get_constant(aff, &v);
-       if (sign * isl_int_sgn(v) > 0) {
-               isl_int_abs(v, v);
-               expr = isl_ast_expr_add_int(expr, v);
-       }
-
        isl_local_space_free(ls);
        isl_int_clear(v);
 
        return expr;
 }
 
+/* Should the constant term "v" be considered positive?
+ *
+ * A positive constant will be added to "pos" by the caller,
+ * while a negative constant will be added to "neg".
+ * If either "pos" or "neg" is exactly zero, then we prefer
+ * to add the constant "v" to that side, irrespective of the sign of "v".
+ * This results in slightly shorter expressions and may reduce the risk
+ * of overflows.
+ */
+static int constant_is_considered_positive(isl_int v,
+       __isl_keep isl_ast_expr *pos, __isl_keep isl_ast_expr *neg)
+{
+       if (ast_expr_is_zero(pos))
+               return 1;
+       if (ast_expr_is_zero(neg))
+               return 0;
+       return isl_int_is_pos(v);
+}
+
 /* Construct an isl_ast_expr that evaluates the condition "constraint",
  * The result is simplified in terms of build->domain.
  *
@@ -589,6 +602,10 @@ static __isl_give isl_ast_expr *add_signed_terms(__isl_take isl_ast_expr *expr,
  * However, if the first expression is an integer constant (and the second
  * is not), then we swap the two expressions.  This ensures that we construct,
  * e.g., "i <= 5" rather than "5 >= i".
+ *
+ * Furthermore, is there are no terms with positive coefficients (or no terms
+ * with negative coefficients), then the constant term is added to "pos"
+ * (or "neg"), ignoring the sign of the constant term.
  */
 static __isl_give isl_ast_expr *isl_ast_expr_from_constraint(
        __isl_take isl_constraint *constraint, __isl_keep isl_ast_build *build)
@@ -598,6 +615,7 @@ static __isl_give isl_ast_expr *isl_ast_expr_from_constraint(
        isl_ast_expr *expr_neg;
        isl_ast_expr *expr;
        isl_aff *aff;
+       isl_int v;
        int eq;
        enum isl_ast_op_type type;
 
@@ -615,6 +633,16 @@ static __isl_give isl_ast_expr *isl_ast_expr_from_constraint(
        expr_pos = add_signed_terms(expr_pos, aff, 1, build);
        expr_neg = add_signed_terms(expr_neg, aff, -1, build);
 
+       isl_int_init(v);
+       isl_aff_get_constant(aff, &v);
+       if (constant_is_considered_positive(v, expr_pos, expr_neg)) {
+               expr_pos = isl_ast_expr_add_int(expr_pos, v);
+       } else {
+               isl_int_neg(v, v);
+               expr_neg = isl_ast_expr_add_int(expr_neg, v);
+       }
+       isl_int_clear(v);
+
        eq = isl_constraint_is_equality(constraint);
 
        if (isl_ast_expr_get_type(expr_pos) == isl_ast_expr_int &&
index eb78c94..e6b49ea 100644 (file)
@@ -2,7 +2,7 @@ if (N >= 0 && M >= 0)
   for (int c1 = -4; c1 <= 3 * M + N; c1 += 1) {
     if (c1 >= 3 * M) {
       S2(M, -3 * M + c1);
-    } else if (3 * floord(c1 - 2, 3) + 2 == c1 && c1 + 1 >= 0 && 3 * M >= c1 + 4)
+    } else if (3 * floord(c1 - 2, 3) + 2 == c1 && c1 >= -1 && 3 * M >= c1 + 4)
       S1((c1 + 4) / 3, 0);
     for (int c3 = max(-3 * M + c1 + 3, c1 + 3 * floord(-c1 - 1, 3) + 3); c3 <= min(N - 1, c1); c3 += 3) {
       S2((c1 - c3) / 3, c3);
index 0a463c8..e7166b6 100644 (file)
@@ -1,6 +1,6 @@
 {
   if (n <= 9 && n >= 0)
     S1(n);
-  if (n <= 9 && n + 1 >= 0)
+  if (n <= 9 && n >= -1)
     S1(n + 1);
 }
index 809649f..ca44024 100644 (file)
@@ -5,7 +5,7 @@
         s0(1, c1, 0, 0, 0);
       } else if (c2 + 1 == N && T >= c1 + 1 && c1 >= 0) {
         s0(1, c1, N - 1, 0, 0);
-      } else if (c1 + 1 == 0 && c2 >= 0 && N >= c2 + 1)
+      } else if (c1 == -1 && c2 >= 0 && N >= c2 + 1)
         s0(1, -1, c2, 0, 0);
   for (int c1 = 0; c1 <= floord(T - 1, 500); c1 += 1) {
     for (int c3 = -((c1 + 9) / 8) + 2; c3 <= floord(N - 500 * c1 - 3, 4000) + 1; c3 += 1)
index f5e6982..1b78a17 100644 (file)
@@ -2,7 +2,7 @@
   if (((-t1 + 128) % 128) + nn >= 128 * g + 130 && 128 * g + 127 >= (-t1 + 128) % 128 && nn >= 128 * g + 6)
     for (int c1 = 393214; c1 < nn - 1; c1 += 393216)
       A(c1, ((t1 + 127) % 128) + 128 * g + 1, ((t1 + 127) % 128) + 1);
-  if (nn >= t1 + 128 * g + 130 && t1 + 128 * g + 127 >= 0 && t1 <= 2 && t1 >= 1)
+  if (nn >= t1 + 128 * g + 130 && t1 + 128 * g >= -127 && t1 <= 2 && t1 >= 1)
     for (int c1 = 393214; c1 < nn - 1; c1 += 393216)
       A(c1, t1 + 128 * g + 128, t1 + 128);
 }