[Graphite] Fix type problems in loop ivs.
Richard Guenther
richard.guenther@gmail.com
Fri Mar 5 14:39:00 GMT 2010
On Fri, Mar 5, 2010 at 3:14 PM, Tobias Grosser
<grosser@fim.uni-passau.de> wrote:
> 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?
This variant looks reasonable. It's still ugly, but well - I hope
somebody is working on enhancing CLooG for a nicer fix.
The patch is ok if it passes testing.
Thanks,
Richard.
> 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
>
>
More information about the Gcc-patches
mailing list