Infer types based on lb and ub.
authorSebastian Pop <sebastian.pop@amd.com>
Thu, 21 Jul 2011 22:57:59 +0000 (22:57 +0000)
committerSebastian Pop <spop@gcc.gnu.org>
Thu, 21 Jul 2011 22:57:59 +0000 (22:57 +0000)
2011-07-21  Sebastian Pop  <sebastian.pop@amd.com>

PR middle-end/47654
PR middle-end/49649
* graphite-clast-to-gimple.c (type_for_clast_term): Pass v1 and v2
in parameter.  Initialize v1 and v2 based on the values returned
by clast_name_to_lb_ub.
(type_for_clast_red): Pass v1 and v2 in parameter, and set their
values.
(type_for_clast_bin): Same.
(type_for_clast_expr): Same.
(type_for_clast_eq): Update calls to type_for_clast_expr.
(type_for_clast_for): Same.
(build_iv_mapping): Same.
* graphite-ppl.h (value_min): New.

* gcc.dg/graphite/run-id-pr47654.c: New.

From-SVN: r176605

gcc/ChangeLog
gcc/graphite-clast-to-gimple.c
gcc/graphite-ppl.h
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/graphite/run-id-pr47654.c [new file with mode: 0644]

index ea4db8c36c2cdb493bbbdc51e9038fb35e4eea88..9cfa21b5ef7639abc6d69cb96afedafbc22624d4 100644 (file)
@@ -1,3 +1,19 @@
+2011-07-21  Sebastian Pop  <sebastian.pop@amd.com>
+
+       PR middle-end/47654
+       PR middle-end/49649
+       * graphite-clast-to-gimple.c (type_for_clast_term): Pass v1 and v2
+       in parameter.  Initialize v1 and v2 based on the values returned
+       by clast_name_to_lb_ub.
+       (type_for_clast_red): Pass v1 and v2 in parameter, and set their
+       values.
+       (type_for_clast_bin): Same.
+       (type_for_clast_expr): Same.
+       (type_for_clast_eq): Update calls to type_for_clast_expr.
+       (type_for_clast_for): Same.
+       (build_iv_mapping): Same.
+       * graphite-ppl.h (value_min): New.
+
 2011-07-21  Sebastian Pop  <sebastian.pop@amd.com>
 
        * graphite-clast-to-gimple.c (type_for_interval): Generate signed
index 9cd27372bb65a3cef727388c6edf0155259fb2a8..ddf6d3d7d271b3a6fae047e3af97cb319106a43c 100644 (file)
@@ -488,79 +488,164 @@ type_for_value (mpz_t val)
   return type_for_interval (val, val);
 }
 
-/* Return the type for the clast_term T used in STMT.  */
+/* Return the type for the clast_term T.  Initializes V1 and V2 to the
+   bounds of the term.  */
 
 static tree
-type_for_clast_term (struct clast_term *t, ivs_params_p ip)
+type_for_clast_term (struct clast_term *t, ivs_params_p ip, mpz_t v1, mpz_t v2)
 {
+  clast_name_p name = t->var;
+  bool found = false;
+
   gcc_assert (t->expr.type == clast_expr_term);
 
-  if (!t->var)
-    return type_for_value (t->val);
+  if (!name)
+    {
+      mpz_set (v1, t->val);
+      mpz_set (v2, t->val);
+      return type_for_value (t->val);
+    }
+
+  if (ip->params && ip->params_index)
+    found = clast_name_to_lb_ub (name, ip->params_index, v1, v2);
 
-  return TREE_TYPE (clast_name_to_gcc (t->var, ip));
+  if (!found)
+    {
+      gcc_assert (*(ip->newivs) && ip->newivs_index);
+      found = clast_name_to_lb_ub (name, ip->newivs_index, v1, v2);
+      gcc_assert (found);
+    }
+
+  mpz_mul (v1, v1, t->val);
+  mpz_mul (v2, v2, t->val);
+
+  return TREE_TYPE (clast_name_to_gcc (name, ip));
 }
 
 static tree
-type_for_clast_expr (struct clast_expr *, ivs_params_p);
+type_for_clast_expr (struct clast_expr *, ivs_params_p, mpz_t, mpz_t);
 
-/* Return the type for the clast_reduction R used in STMT.  */
+/* Return the type for the clast_reduction R.  Initializes V1 and V2
+   to the bounds of the reduction expression.  */
 
 static tree
-type_for_clast_red (struct clast_reduction *r, ivs_params_p ip)
+type_for_clast_red (struct clast_reduction *r, ivs_params_p ip,
+                   mpz_t v1, mpz_t v2)
 {
   int i;
-  tree type = NULL_TREE;
+  tree type = type_for_clast_expr (r->elts[0], ip, v1, v2);
+  mpz_t b1, b2, m1, m2;
 
   if (r->n == 1)
-    return type_for_clast_expr (r->elts[0], ip);
-
-  switch (r->type)
-    {
-    case clast_red_sum:
-    case clast_red_min:
-    case clast_red_max:
-      type = type_for_clast_expr (r->elts[0], ip);
-      for (i = 1; i < r->n; i++)
-       type = max_precision_type
-         (type, type_for_clast_expr (r->elts[i], ip));
+    return type;
 
-      return type;
+  mpz_init (b1);
+  mpz_init (b2);
+  mpz_init (m1);
+  mpz_init (m2);
 
-    default:
-      break;
+  for (i = 1; i < r->n; i++)
+    {
+      tree t = type_for_clast_expr (r->elts[i], ip, b1, b2);
+      type = max_precision_type (type, t);
+
+      switch (r->type)
+       {
+       case clast_red_sum:
+         value_min (m1, v1, v2);
+         value_min (m2, b1, b2);
+         mpz_add (v1, m1, m2);
+
+         value_max (m1, v1, v2);
+         value_max (m2, b1, b2);
+         mpz_add (v2, m1, m2);
+         break;
+
+       case clast_red_min:
+         value_min (v1, v1, v2);
+         value_min (v2, b1, b2);
+         break;
+
+       case clast_red_max:
+         value_max (v1, v1, v2);
+         value_max (v2, b1, b2);
+         break;
+
+       default:
+         gcc_unreachable ();
+         break;
+       }
     }
 
-  gcc_unreachable ();
-  return NULL_TREE;
+  mpz_clear (b1);
+  mpz_clear (b2);
+  mpz_clear (m1);
+  mpz_clear (m2);
+
+  /* Return a type that can represent the result of the reduction.  */
+  return max_precision_type (type, type_for_interval (v1, v2));
 }
 
 /* Return the type for the clast_binary B used in STMT.  */
 
 static tree
-type_for_clast_bin (struct clast_binary *b, ivs_params_p ip)
+type_for_clast_bin (struct clast_binary *b, ivs_params_p ip, mpz_t v1, mpz_t v2)
 {
-  tree l = type_for_clast_expr ((struct clast_expr *) b->LHS, ip);
+  mpz_t one;
+  tree l = type_for_clast_expr ((struct clast_expr *) b->LHS, ip, v1, v2);
   tree r = type_for_value (b->RHS);
-  return max_precision_type (l, r);
+  tree type = max_precision_type (l, r);
+
+  switch (b->type)
+    {
+    case clast_bin_fdiv:
+      mpz_mdiv (v1, v1, b->RHS);
+      mpz_mdiv (v2, v2, b->RHS);
+      break;
+
+    case clast_bin_cdiv:
+      mpz_mdiv (v1, v1, b->RHS);
+      mpz_mdiv (v2, v2, b->RHS);
+      mpz_init (one);
+      mpz_add (v1, v1, one);
+      mpz_add (v2, v2, one);
+      mpz_clear (one);
+      break;
+
+    case clast_bin_div:
+      mpz_div (v1, v1, b->RHS);
+      mpz_div (v2, v2, b->RHS);
+      break;
+
+    case clast_bin_mod:
+      mpz_mod (v1, v1, b->RHS);
+      mpz_mod (v2, v2, b->RHS);
+      break;
+
+    default:
+      gcc_unreachable ();
+    }
+
+  /* Return a type that can represent the result of the reduction.  */
+  return max_precision_type (type, type_for_interval (v1, v2));
 }
 
 /* Returns the type for the CLAST expression E when used in statement
    STMT.  */
 
 static tree
-type_for_clast_expr (struct clast_expr *e, ivs_params_p ip)
+type_for_clast_expr (struct clast_expr *e, ivs_params_p ip, mpz_t v1, mpz_t v2)
 {
   switch (e->type)
     {
     case clast_expr_term:
-      return type_for_clast_term ((struct clast_term *) e, ip);
+      return type_for_clast_term ((struct clast_term *) e, ip, v1, v2);
 
     case clast_expr_red:
-      return type_for_clast_red ((struct clast_reduction *) e, ip);
+      return type_for_clast_red ((struct clast_reduction *) e, ip, v1, v2);
 
     case clast_expr_bin:
-      return type_for_clast_bin ((struct clast_binary *) e, ip);
+      return type_for_clast_bin ((struct clast_binary *) e, ip, v1, v2);
 
     default:
       gcc_unreachable ();
@@ -574,8 +659,17 @@ type_for_clast_expr (struct clast_expr *e, ivs_params_p ip)
 static tree
 type_for_clast_eq (struct clast_equation *cleq, ivs_params_p ip)
 {
-  tree l = type_for_clast_expr (cleq->LHS, ip);
-  tree r = type_for_clast_expr (cleq->RHS, ip);
+  mpz_t v1, v2;
+  tree l, r;
+
+  mpz_init (v1);
+  mpz_init (v2);
+
+  l = type_for_clast_expr (cleq->LHS, ip, v1, v2);
+  r = type_for_clast_expr (cleq->RHS, ip, v1, v2);
+
+  mpz_clear (v1);
+  mpz_clear (v2);
   return max_precision_type (l, r);
 }
 
@@ -727,8 +821,17 @@ clast_get_body_of_loop (struct clast_stmt *stmt)
 static tree
 type_for_clast_for (struct clast_for *stmt_for, ivs_params_p ip)
 {
-  tree lb_type = type_for_clast_expr (stmt_for->LB, ip);
-  tree ub_type = type_for_clast_expr (stmt_for->UB, ip);
+  mpz_t v1, v2;
+  tree lb_type, ub_type;
+
+  mpz_init (v1);
+  mpz_init (v2);
+
+  lb_type = type_for_clast_expr (stmt_for->LB, ip, v1, v2);
+  ub_type = type_for_clast_expr (stmt_for->UB, ip, v1, v2);
+
+  mpz_clear (v1);
+  mpz_clear (v2);
 
   return max_precision_type (lb_type, ub_type);
 }
@@ -784,17 +887,24 @@ build_iv_mapping (VEC (tree, heap) *iv_map, struct clast_user_stmt *user_stmt,
   CloogStatement *cs = user_stmt->statement;
   poly_bb_p pbb = (poly_bb_p) cloog_statement_usr (cs);
   gimple_bb_p gbb = PBB_BLACK_BOX (pbb);
+  mpz_t v1, v2;
+
+  mpz_init (v1);
+  mpz_init (v2);
 
   for (t = user_stmt->substitutions; t; t = t->next, depth++)
     {
       struct clast_expr *expr = (struct clast_expr *)
        ((struct clast_assignment *)t)->RHS;
-      tree type = type_for_clast_expr (expr, ip);
+      tree type = type_for_clast_expr (expr, ip, v1, v2);
       tree new_name = clast_to_gcc_expression (type, expr, ip);
       loop_p old_loop = gbb_loop_at_index (gbb, ip->region, depth);
 
       VEC_replace (tree, iv_map, old_loop->num, new_name);
     }
+
+  mpz_clear (v1);
+  mpz_clear (v2);
 }
 
 /* Construct bb_pbb_def with BB and PBB.  */
index 49bde618f47e72550604cb8e0f937332afaceb3d..5820e19927dc024b492eb10f08d49eccae61bdc0 100644 (file)
@@ -124,6 +124,17 @@ ppl_set_coef_tree (ppl_Linear_Expression_t e, ppl_dimension_type i, tree x)
   mpz_clear (v);
 }
 
+/* Sets RES to the min of V1 and V2.  */
+
+static inline void
+value_min (mpz_t res, mpz_t v1, mpz_t v2)
+{
+  if (mpz_cmp (v1, v2) < 0)
+    mpz_set (res, v1);
+  else
+    mpz_set (res, v2);
+}
+
 /* Sets RES to the max of V1 and V2.  */
 
 static inline void
index d28b4847483c0f99e0f2d227c496c68732d3d603..a63b6474cbb870eafe7732bf72f52071e483a90c 100644 (file)
@@ -1,3 +1,9 @@
+2011-07-21  Sebastian Pop  <sebastian.pop@amd.com>
+
+       PR middle-end/47654
+       PR middle-end/49649
+       * gcc.dg/graphite/run-id-pr47654.c: New.
+
 2011-07-21  Ian Lance Taylor  <iant@google.com>
 
        PR middle-end/49705
diff --git a/gcc/testsuite/gcc.dg/graphite/run-id-pr47654.c b/gcc/testsuite/gcc.dg/graphite/run-id-pr47654.c
new file mode 100644 (file)
index 0000000..85b6e8b
--- /dev/null
@@ -0,0 +1,24 @@
+/* { dg-options "-O -floop-strip-mine" } */
+
+int a[128][40];
+
+void __attribute__ ((noinline, noclone))
+foo (void)
+{
+  int i, j;
+  for (i = 0; i < 40; i++)
+    for (j = 0; j < 128; j++)
+      a[j][i] = 4;
+}
+
+int
+main ()
+{
+  int i, j;
+  foo ();
+  for (i = 0; i < 40; i++)
+    for (j = 0; j < 128; j++)
+      if (a[j][i] != 4)
+       __builtin_abort ();
+  return 0;
+}