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. From-SVN: r157286
This commit is contained in:
parent
e3f81db10f
commit
68d3ff9044
6 changed files with 137 additions and 9 deletions
|
@ -282,14 +282,24 @@ clast_to_gcc_expression (tree type, struct clast_expr *e,
|
||||||
{
|
{
|
||||||
tree name = clast_name_to_gcc (t->var, region, newivs,
|
tree name = clast_name_to_gcc (t->var, region, newivs,
|
||||||
newivs_index, params_index);
|
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))
|
else if (value_mone_p (t->val))
|
||||||
{
|
{
|
||||||
tree name = clast_name_to_gcc (t->var, region, newivs,
|
tree name = clast_name_to_gcc (t->var, region, newivs,
|
||||||
newivs_index, params_index);
|
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);
|
name = fold_convert (type, name);
|
||||||
|
|
||||||
return fold_build1 (NEGATE_EXPR, type, name);
|
return fold_build1 (NEGATE_EXPR, type, name);
|
||||||
}
|
}
|
||||||
else
|
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,
|
tree name = clast_name_to_gcc (t->var, region, newivs,
|
||||||
newivs_index, params_index);
|
newivs_index, params_index);
|
||||||
tree cst = gmp_cst_to_tree (type, t->val);
|
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);
|
name = fold_convert (type, name);
|
||||||
|
|
||||||
if (!POINTER_TYPE_P (type))
|
if (!POINTER_TYPE_P (type))
|
||||||
return fold_build2 (MULT_EXPR, type, cst, name);
|
return fold_build2 (MULT_EXPR, type, cst, name);
|
||||||
|
|
||||||
|
@ -532,9 +547,16 @@ clast_get_body_of_loop (struct clast_stmt *stmt)
|
||||||
gcc_unreachable ();
|
gcc_unreachable ();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Given a CLOOG_IV, returns the type that it should have in GCC land.
|
/* Given a CLOOG_IV, return the type that CLOOG_IV should have in GCC
|
||||||
If the information is not available, i.e. in the case one of the
|
land. The selected type is big enough to include the original loop
|
||||||
transforms created the loop, just return integer_type_node. */
|
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
|
static tree
|
||||||
gcc_type_for_cloog_iv (const char *cloog_iv, gimple_bb_p gbb)
|
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);
|
slot = htab_find_slot (GBB_CLOOG_IV_TYPES (gbb), &tmp, NO_INSERT);
|
||||||
|
|
||||||
if (slot && *slot)
|
if (slot && *slot)
|
||||||
return ((ivtype_map_elt) *slot)->type;
|
{
|
||||||
|
tree type = ((ivtype_map_elt) *slot)->type;
|
||||||
|
int type_precision = TYPE_PRECISION (type);
|
||||||
|
|
||||||
return integer_type_node;
|
/* 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 long_long_integer_type_node;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Returns the induction variable for the loop that gets translated to
|
/* 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)
|
if (slot && !*slot)
|
||||||
{
|
{
|
||||||
tree oldiv = pbb_to_depth_to_oldiv (pbb, index);
|
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);
|
*slot = new_ivtype_map_elt (tmp.cloog_iv, type);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2893,6 +2893,38 @@ scop_canonicalize_loops (scop_p scop)
|
||||||
graphite_loop_normal_form (loop);
|
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. */
|
/* Builds the polyhedral representation for a SESE region. */
|
||||||
|
|
||||||
bool
|
bool
|
||||||
|
@ -2915,6 +2947,10 @@ build_poly_scop (scop_p scop)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
scop_canonicalize_loops (scop);
|
scop_canonicalize_loops (scop);
|
||||||
|
|
||||||
|
if (!scop_ivs_can_be_represented (scop))
|
||||||
|
return false;
|
||||||
|
|
||||||
build_sese_loop_nests (region);
|
build_sese_loop_nests (region);
|
||||||
build_sese_conditions (region);
|
build_sese_conditions (region);
|
||||||
find_scop_parameters (scop);
|
find_scop_parameters (scop);
|
||||||
|
|
7
gcc/testsuite/gcc.dg/graphite/id-18.c
Normal file
7
gcc/testsuite/gcc.dg/graphite/id-18.c
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
long do_hash (const char * lo, const char * hi)
|
||||||
|
{
|
||||||
|
int val = 0;
|
||||||
|
for (; lo < hi; ++lo)
|
||||||
|
val = *lo;
|
||||||
|
return val;
|
||||||
|
}
|
32
gcc/testsuite/gcc.dg/graphite/run-id-pr42644.c
Normal file
32
gcc/testsuite/gcc.dg/graphite/run-id-pr42644.c
Normal file
|
@ -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;
|
||||||
|
}
|
|
@ -23,7 +23,7 @@ int main(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check that parallel code generation part make the right answer. */
|
/* 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 { cleanup-tree-dump "graphite" } } */
|
||||||
/* { dg-final { scan-tree-dump-times "loopfn" 5 "optimized" } } */
|
/* { dg-final { scan-tree-dump-times "loopfn" 5 "optimized" } } */
|
||||||
/* { dg-final { cleanup-tree-dump "parloops" } } */
|
/* { dg-final { cleanup-tree-dump "parloops" } } */
|
||||||
|
|
|
@ -23,7 +23,7 @@ int main(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check that parallel code generation part make the right answer. */
|
/* 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 { cleanup-tree-dump "graphite" } } */
|
||||||
/* { dg-final { scan-tree-dump-times "loopfn" 5 "optimized" } } */
|
/* { dg-final { scan-tree-dump-times "loopfn" 5 "optimized" } } */
|
||||||
/* { dg-final { cleanup-tree-dump "parloops" } } */
|
/* { dg-final { cleanup-tree-dump "parloops" } } */
|
||||||
|
|
Loading…
Add table
Reference in a new issue