[Graphite] Fix type problems in loop ivs.
Richard Guenther
richard.guenther@gmail.com
Thu Mar 11 12:31:00 GMT 2010
On Wed, Mar 10, 2010 at 9:33 PM, Sebastian Pop <sebpop@gmail.com> wrote:
> Hi,
>
> On Fri, Mar 5, 2010 at 08:14, 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?
>>
>> 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))
>
> This breaks Java when Graphite is enabled,
> as there is no long_long_integer_type_node defined there.
> The compiler stops on this line in the error from the Graphite
> auto tester:
> http://groups.google.com/group/gcc-graphite-test/browse_thread/thread/f348f4f4d50483
Java indeed fails to initialize most of the common trees.
I suggest to use ssizetype if long_long_type_node is NULL.
Richard.
> Sebastian
>
>> + 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