summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorspop <spop@138bc75d-0d04-0410-961f-82ee72b054a4>2010-03-08 17:49:36 +0000
committerspop <spop@138bc75d-0d04-0410-961f-82ee72b054a4>2010-03-08 17:49:36 +0000
commitb43389bdff99f059d2f593c0b3b5b3332f8131f2 (patch)
tree6a1a47eb427ba78c11b008b0e38679bf05584a5c
parent2d0a2aaadcca869d985e2152914b82771207f754 (diff)
downloadgcc-b43389bdff99f059d2f593c0b3b5b3332f8131f2.tar.gz
Fix type problems in loop ivs.
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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@157286 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/graphite-clast-to-gimple.c67
-rw-r--r--gcc/graphite-sese-to-poly.c36
-rw-r--r--gcc/testsuite/gcc.dg/graphite/id-18.c7
-rw-r--r--gcc/testsuite/gcc.dg/graphite/run-id-pr42644.c32
-rw-r--r--libgomp/testsuite/libgomp.graphite/force-parallel-1.c2
-rw-r--r--libgomp/testsuite/libgomp.graphite/force-parallel-2.c2
6 files changed, 137 insertions, 9 deletions
diff --git a/gcc/graphite-clast-to-gimple.c b/gcc/graphite-clast-to-gimple.c
index fd631a4847e..64ddbb8ed91 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 3ee431fda6e..279a905764d 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 00000000000..77628fa8cb9
--- /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 00000000000..2e9006470c4
--- /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 7f043d83d8b..1ad4b4192d6 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 03d823653a7..1ce0feb2506 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" } } */