diff mbox

[10/10] Infer types based on lb and ub.

Message ID 1311273070-12128-11-git-send-email-sebpop@gmail.com
State New
Headers show

Commit Message

Sebastian Pop July 21, 2011, 6:31 p.m. UTC
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.
---
 gcc/ChangeLog                                  |   16 ++
 gcc/graphite-clast-to-gimple.c                 |  184 +++++++++++++++++++-----
 gcc/graphite-ppl.h                             |   11 ++
 gcc/testsuite/ChangeLog                        |    6 +
 gcc/testsuite/gcc.dg/graphite/run-id-pr47654.c |   24 +++
 5 files changed, 204 insertions(+), 37 deletions(-)
 create mode 100644 gcc/testsuite/gcc.dg/graphite/run-id-pr47654.c
diff mbox

Patch

diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index c79f0b4..394863d 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,5 +1,21 @@ 
 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
 	types whenever possible.
 
diff --git a/gcc/graphite-clast-to-gimple.c b/gcc/graphite-clast-to-gimple.c
index 9cd2737..ddf6d3d 100644
--- a/gcc/graphite-clast-to-gimple.c
+++ b/gcc/graphite-clast-to-gimple.c
@@ -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.  */
diff --git a/gcc/graphite-ppl.h b/gcc/graphite-ppl.h
index 49bde61..5820e19 100644
--- a/gcc/graphite-ppl.h
+++ b/gcc/graphite-ppl.h
@@ -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
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 7ccdad4..c9ae3cf 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -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-18  Martin Jambor  <mjambor@suse.cz>
 
 	* gcc.dg/ipa/ipa-1.c: Updated testcase dump scan.
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
index 0000000..85b6e8b
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/graphite/run-id-pr47654.c
@@ -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;
+}