public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [Graphite] Fix type problems in loop ivs.
@ 2010-03-05 14:22 Tobias Grosser
  2010-03-05 14:39 ` Richard Guenther
                   ` (3 more replies)
  0 siblings, 4 replies; 14+ messages in thread
From: Tobias Grosser @ 2010-03-05 14:22 UTC (permalink / raw)
  To: gcc-patches, gcc-graphite; +Cc: Tobias Grosser

Hi,

I would like to commit this patch that fixes the loop iv type problems in
graphite.

This resolves two P1 bug reports without any regressions in the graphite.exp
testsuite neither on 64 nor on 32 bit linux. Only two test cases in libgomp
changed, as autopar generates for these files an iv where we cannot yet
prove, that it can be handled safely in graphite. This can be enhanced later on.

The patch was bootstrapped on
Linux tobias 2.6.33 #4 SMP PREEMPT Mon Mar 1 12:59:44 CET 2010 x86_64 Intel(R)
Core(TM) i5 CPU M 520 @ 2.40GHz GenuineIntel GNU/Linux

Linux tobias 2.6.33 #4 SMP PREEMPT Mon Mar 1 12:59:44 CET 2010 i686 Intel(R)
Core(TM) i5 CPU M 520 @ 2.40GHz GenuineIntel GNU/Linux

Also tested dealII on 64bit with -O2, which failed before.

OK for trunk, if it passes the automatic spec 2006 tests on graphite branch?

Tobias

PS: Thanks Richi, for proposing "fold_convert (sizetype, name)" for the conversion
from pointers.

Fix pr42644.
Fix pr42130 (dealII).

2010-03-03  Tobias Grosser  <grosser@fim.uni-passau.de>

	* gcc/graphite-clast-to-gimple.c (clast_to_gcc_expression): Also
	handle conversions from pointer to integers.
	(gcc_type_for_cloog_iv): Choose the smalles signed integer as an
	induction variable, to be able to work with code generated by
	CLooG.
	* gcc/graphite-sese-to-poly.c (scop_ivs_can_be_represented): New.
	(build_poly_scop): Bail out if we cannot codegen a loop.
	* gcc/testsuite/gcc.dg/graphite/id-18.c: New.
	* gcc/testsuite/gcc.dg/graphite/run-id-pr42644.c: New.
	* libgomp/testsuite/libgomp.graphite/force-parallel-1.c: Adjust.
	* libgomp/testsuite/libgomp.graphite/force-parallel-2.c: Adjust.
---
 gcc/graphite-clast-to-gimple.c                     |   67 +++++++++++++++++--
 gcc/graphite-sese-to-poly.c                        |   36 +++++++++++
 gcc/testsuite/gcc.dg/graphite/id-18.c              |    7 ++
 gcc/testsuite/gcc.dg/graphite/run-id-pr42644.c     |   32 +++++++++
 .../testsuite/libgomp.graphite/force-parallel-1.c  |    2 +-
 .../testsuite/libgomp.graphite/force-parallel-2.c  |    2 +-
 6 files changed, 137 insertions(+), 9 deletions(-)
 create mode 100644 gcc/testsuite/gcc.dg/graphite/id-18.c
 create mode 100644 gcc/testsuite/gcc.dg/graphite/run-id-pr42644.c

diff --git a/gcc/graphite-clast-to-gimple.c b/gcc/graphite-clast-to-gimple.c
index 909392a..6ce01d5 100644
--- a/gcc/graphite-clast-to-gimple.c
+++ b/gcc/graphite-clast-to-gimple.c
@@ -282,14 +282,24 @@ clast_to_gcc_expression (tree type, struct clast_expr *e,
 	      {
 		tree name = clast_name_to_gcc (t->var, region, newivs,
 					       newivs_index, params_index);
-		return fold_convert (type, name);
+
+		if (POINTER_TYPE_P (TREE_TYPE (name)) != POINTER_TYPE_P (type))
+		  name = fold_convert (sizetype, name);
+
+		name = fold_convert (type, name);
+		return name;
 	      }
 
 	    else if (value_mone_p (t->val))
 	      {
 		tree name = clast_name_to_gcc (t->var, region, newivs,
 					       newivs_index, params_index);
+
+		if (POINTER_TYPE_P (TREE_TYPE (name)) != POINTER_TYPE_P (type))
+		  name = fold_convert (sizetype, name);
+
 		name = fold_convert (type, name);
+
 		return fold_build1 (NEGATE_EXPR, type, name);
 	      }
 	    else
@@ -297,7 +307,12 @@ clast_to_gcc_expression (tree type, struct clast_expr *e,
 		tree name = clast_name_to_gcc (t->var, region, newivs,
 					       newivs_index, params_index);
 		tree cst = gmp_cst_to_tree (type, t->val);
+
+		if (POINTER_TYPE_P (TREE_TYPE (name)) != POINTER_TYPE_P (type))
+		  name = fold_convert (sizetype, name);
+
 		name = fold_convert (type, name);
+
 		if (!POINTER_TYPE_P (type))
 		  return fold_build2 (MULT_EXPR, type, cst, name);
 
@@ -532,9 +547,16 @@ clast_get_body_of_loop (struct clast_stmt *stmt)
   gcc_unreachable ();
 }
 
-/* Given a CLOOG_IV, returns the type that it should have in GCC land.
-   If the information is not available, i.e. in the case one of the
-   transforms created the loop, just return integer_type_node.  */
+/* Given a CLOOG_IV, return the type that CLOOG_IV should have in GCC
+   land.  The selected type is big enough to include the original loop
+   iteration variable, but signed to work with the subtractions CLooG
+   may have introduced.  If such a type is not available, we fail.
+
+   TODO: Do not always return long_long, but the smallest possible
+   type, that still holds the original type.
+
+   TODO: Get the types using CLooG instead.  This enables further
+   optimizations, but needs CLooG support.  */
 
 static tree
 gcc_type_for_cloog_iv (const char *cloog_iv, gimple_bb_p gbb)
@@ -546,9 +568,40 @@ gcc_type_for_cloog_iv (const char *cloog_iv, gimple_bb_p gbb)
   slot = htab_find_slot (GBB_CLOOG_IV_TYPES (gbb), &tmp, NO_INSERT);
 
   if (slot && *slot)
-    return ((ivtype_map_elt) *slot)->type;
+    {
+      tree type = ((ivtype_map_elt) *slot)->type;
+      int type_precision = TYPE_PRECISION (type);
+
+      /* Find the smallest signed type possible.  */
+      if (!TYPE_UNSIGNED (type))
+	{
+	  if (type_precision <= TYPE_PRECISION (integer_type_node))
+	    return integer_type_node;
+
+	  if (type_precision <= TYPE_PRECISION (long_integer_type_node))
+	    return long_integer_type_node;
+
+	  if (type_precision <= TYPE_PRECISION (long_long_integer_type_node))
+	    return long_long_integer_type_node;
+
+	  gcc_unreachable ();
+	}
+
+      if (type_precision < TYPE_PRECISION (integer_type_node))
+	return integer_type_node;
+
+      if (type_precision < TYPE_PRECISION (long_integer_type_node))
+	return long_integer_type_node;
+
+      if (type_precision < TYPE_PRECISION (long_long_integer_type_node))
+	return long_long_integer_type_node;
+
+      /* There is no signed type available, that is large enough to hold the
+	 original value.  */
+      gcc_unreachable ();
+    }
 
-  return integer_type_node;
+  return long_long_integer_type_node;
 }
 
 /* Returns the induction variable for the loop that gets translated to
@@ -1046,7 +1099,7 @@ compute_cloog_iv_types_1 (poly_bb_p pbb, struct clast_user_stmt *user_stmt)
       if (slot && !*slot)
 	{
 	  tree oldiv = pbb_to_depth_to_oldiv (pbb, index);
-	  tree type = oldiv ? TREE_TYPE (oldiv) : integer_type_node;
+	  tree type = TREE_TYPE (oldiv);
 	  *slot = new_ivtype_map_elt (tmp.cloog_iv, type);
 	}
     }
diff --git a/gcc/graphite-sese-to-poly.c b/gcc/graphite-sese-to-poly.c
index 3ee431f..279a905 100644
--- a/gcc/graphite-sese-to-poly.c
+++ b/gcc/graphite-sese-to-poly.c
@@ -2893,6 +2893,38 @@ scop_canonicalize_loops (scop_p scop)
       graphite_loop_normal_form (loop);
 }
 
+/* Can all ivs be represented by a signed integer?
+   As CLooG might generate negative values in its expressions, signed loop ivs
+   are required in the backend. */
+static bool
+scop_ivs_can_be_represented (scop_p scop)
+{
+  loop_iterator li;
+  loop_p loop;
+
+  FOR_EACH_LOOP (li, loop, 0)
+    {
+      tree type;
+      int precision;
+
+      if (!loop_in_sese_p (loop, SCOP_REGION (scop)))
+	continue;
+
+      if (!loop->single_iv)
+	continue;
+
+      type = TREE_TYPE(loop->single_iv);
+      precision = TYPE_PRECISION (type);
+
+      if (TYPE_UNSIGNED (type)
+	  && precision >= TYPE_PRECISION (long_long_integer_type_node))
+	return false;
+    }
+
+  return true;
+}
+
+
 /* Builds the polyhedral representation for a SESE region.  */
 
 bool
@@ -2915,6 +2947,10 @@ build_poly_scop (scop_p scop)
     return false;
 
   scop_canonicalize_loops (scop);
+
+  if (!scop_ivs_can_be_represented (scop))
+    return false;
+
   build_sese_loop_nests (region);
   build_sese_conditions (region);
   find_scop_parameters (scop);
diff --git a/gcc/testsuite/gcc.dg/graphite/id-18.c b/gcc/testsuite/gcc.dg/graphite/id-18.c
new file mode 100644
index 0000000..77628fa
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/graphite/id-18.c
@@ -0,0 +1,7 @@
+long do_hash (const char * lo, const char * hi)
+{
+	int val = 0;
+	for (; lo < hi; ++lo)
+		val = *lo;
+	return val;
+}
diff --git a/gcc/testsuite/gcc.dg/graphite/run-id-pr42644.c b/gcc/testsuite/gcc.dg/graphite/run-id-pr42644.c
new file mode 100644
index 0000000..2e90064
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/graphite/run-id-pr42644.c
@@ -0,0 +1,32 @@
+/* Testcase extracted from test 183.equake in SPEC CPU2000.  */
+double Ke[2], ds[2];
+
+void foo(double Ke[2], int i, double ds[],  int column)
+{
+  double tt, ts;
+  int j;
+
+  for (j = 0; j < 2; j++)
+    {
+      ++column;
+      ts = ds[i];
+      if (i == j)
+	tt = 123;
+      else
+	tt = 0;
+      Ke[column] = Ke[column] + ts + tt;
+    }
+}
+
+int
+main ()
+{
+  int i, j;
+
+  ds[0] = 1.0;
+  ds[1] = 1.0;
+
+  foo(Ke, 0, ds, -1);
+
+  return (int) Ke[0] != 124;
+}
diff --git a/libgomp/testsuite/libgomp.graphite/force-parallel-1.c b/libgomp/testsuite/libgomp.graphite/force-parallel-1.c
index 7f043d8..1ad4b41 100644
--- a/libgomp/testsuite/libgomp.graphite/force-parallel-1.c
+++ b/libgomp/testsuite/libgomp.graphite/force-parallel-1.c
@@ -23,7 +23,7 @@ int main(void)
 }
 
 /* Check that parallel code generation part make the right answer.  */
-/* { dg-final { scan-tree-dump-times "1 loops carried no dependency" 2 "graphite" } } */
+/* { dg-final { scan-tree-dump-times "1 loops carried no dependency" 1 "graphite" } } */
 /* { dg-final { cleanup-tree-dump "graphite" } } */
 /* { dg-final { scan-tree-dump-times "loopfn" 5 "optimized" } } */
 /* { dg-final { cleanup-tree-dump "parloops" } } */
diff --git a/libgomp/testsuite/libgomp.graphite/force-parallel-2.c b/libgomp/testsuite/libgomp.graphite/force-parallel-2.c
index 03d8236..1ce0feb 100644
--- a/libgomp/testsuite/libgomp.graphite/force-parallel-2.c
+++ b/libgomp/testsuite/libgomp.graphite/force-parallel-2.c
@@ -23,7 +23,7 @@ int main(void)
 }
 
 /* Check that parallel code generation part make the right answer.  */
-/* { dg-final { scan-tree-dump-times "2 loops carried no dependency" 2 "graphite" } } */
+/* { dg-final { scan-tree-dump-times "2 loops carried no dependency" 1 "graphite" } } */
 /* { dg-final { cleanup-tree-dump "graphite" } } */
 /* { dg-final { scan-tree-dump-times "loopfn" 5 "optimized" } } */
 /* { dg-final { cleanup-tree-dump "parloops" } } */
-- 
1.6.4.4

^ permalink raw reply	[flat|nested] 14+ messages in thread

end of thread, other threads:[~2010-06-07 19:00 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2010-03-05 14:22 [Graphite] Fix type problems in loop ivs Tobias Grosser
2010-03-05 14:39 ` Richard Guenther
2010-03-05 20:49   ` Sebastian Pop
2010-03-05 14:40 ` Eric Botcazou
     [not found] ` <11654_1267799959_4B911797_11654_9062_1_201003051538.47829.ebotcazou@adacore.com>
2010-03-05 15:38   ` Tobias Grosser
2010-03-10 21:23 ` Sebastian Pop
2010-03-11 12:31   ` Richard Guenther
2010-03-11 13:56     ` Sebastian Pop
2010-03-11 14:20       ` Richard Guenther
2010-06-01 23:10         ` Sebastian Pop
2010-06-02  9:03           ` Richard Guenther
2010-06-07 16:36             ` NightStrike
2010-06-07 16:59               ` Sebastian Pop
2010-06-07 19:00                 ` NightStrike

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).