This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[graphite] Fix pdr_add_data_dimensions for pointers
- From: Alexander Monakov <amonakov at ispras dot ru>
- To: gcc-patches at gcc dot gnu dot org
- Cc: Sebastian Pop <sebpop at gmail dot com>
- Date: Thu, 17 Sep 2009 15:02:23 +0400 (MSD)
- Subject: [graphite] Fix pdr_add_data_dimensions for pointers
Hi,
Graphite's function pdr_add_data_dimensions records constraints of the form
0 <= subscript <= array_size. This should only be done for array references
(we cannot assert anything about index bounds for p[i] where p is a pointer;
currently, Graphite would assume 0 <= i && 4 (or 8) * i <= 4), hence i <= 1,
and then Graphite would mark the loop in the attached testcase as parallel).
This patch fixes it and also converts the function to use
array_ref_{low,up}_bound functions (fixing off-by-one error for upper bound).
Ideally, this should also avoid adding 'subscript <= upper_bound' constraint
for 1-element arrays at end of structures, but such references are currently
not handled by Graphite anyway, so I have not implemented it.
Bootstrapped & regtested on trunk (all default languages) and on graphite
branch (c,c++,fortran), no new regressions (both on x86-64). Committed
earlier to graphite branch after Sebastian's approval, results from
SPEC'06 autotester seem fine.
OK for trunk?
--
Alexander Monakov
gcc/Changelog:
* graphite-sese-to-poly.c (pdr_add_data_dimensions): Add bounds only
for ARRAY_REFs. Use array_ref_{low,up}_bound to determine bounds.
libgomp/Changelog:
* testsuite/libgomp.graphite/bounds.c: New test.
diff --git a/gcc/graphite-sese-to-poly.c b/gcc/graphite-sese-to-poly.c
index ab80c6d..affd20a 100644
--- a/gcc/graphite-sese-to-poly.c
+++ b/gcc/graphite-sese-to-poly.c
@@ -1614,53 +1614,50 @@ pdr_add_data_dimensions (ppl_Polyhedron_t accesses, data_reference_p dr,
{
tree ref = DR_REF (dr);
int i, nb_subscripts = DR_NUM_DIMENSIONS (dr);
- tree array_size;
- HOST_WIDE_INT elt_size;
- array_size = TYPE_SIZE (TREE_TYPE (ref));
- if (array_size == NULL_TREE
- || TREE_CODE (array_size) != INTEGER_CST)
- return;
-
- elt_size = int_cst_value (array_size);
-
- for (i = nb_subscripts - 1; i >= 0; i--)
+ for (i = nb_subscripts - 1; i >= 0; i--, ref = TREE_OPERAND (ref, 0))
{
ppl_Linear_Expression_t expr;
ppl_Constraint_t cstr;
ppl_dimension_type subscript = dom_nb_dims + 1 + i;
- int size;
+ tree low, high;
- /* 0 <= subscript */
- ppl_new_Linear_Expression_with_dimension (&expr, accessp_nb_dims);
- ppl_set_coef (expr, subscript, 1);
- ppl_new_Constraint (&cstr, expr, PPL_CONSTRAINT_TYPE_GREATER_OR_EQUAL);
- ppl_Polyhedron_add_constraint (accesses, cstr);
- ppl_delete_Linear_Expression (expr);
- ppl_delete_Constraint (cstr);
-
- ref = TREE_OPERAND (ref, 0);
- array_size = TYPE_SIZE (TREE_TYPE (ref));
- if (array_size == NULL_TREE
- || TREE_CODE (array_size) != INTEGER_CST)
+ if (TREE_CODE (ref) != ARRAY_REF)
break;
- /* subscript <= array_size */
- size = elt_size ? int_cst_value (array_size) / elt_size : 0;
- if (size)
+ low = array_ref_low_bound (ref);
+
+ /* subscript - low >= 0 */
+ if (host_integerp (low, 0))
+ {
+ ppl_new_Linear_Expression_with_dimension (&expr, accessp_nb_dims);
+ ppl_set_coef (expr, subscript, 1);
+
+ ppl_set_inhomogeneous (expr, -int_cst_value (low));
+
+ ppl_new_Constraint (&cstr, expr, PPL_CONSTRAINT_TYPE_GREATER_OR_EQUAL);
+ ppl_Polyhedron_add_constraint (accesses, cstr);
+ ppl_delete_Linear_Expression (expr);
+ ppl_delete_Constraint (cstr);
+ }
+
+ high = array_ref_up_bound (ref);
+
+ /* high - subscript >= 0
+ XXX: 1-element arrays at end of structures may extend over their
+ declared size. */
+ if (high && host_integerp (high, 0))
{
ppl_new_Linear_Expression_with_dimension (&expr, accessp_nb_dims);
ppl_set_coef (expr, subscript, -1);
- ppl_set_inhomogeneous (expr, size);
+ ppl_set_inhomogeneous (expr, int_cst_value (high));
ppl_new_Constraint (&cstr, expr, PPL_CONSTRAINT_TYPE_GREATER_OR_EQUAL);
ppl_Polyhedron_add_constraint (accesses, cstr);
ppl_delete_Linear_Expression (expr);
ppl_delete_Constraint (cstr);
}
-
- elt_size = int_cst_value (array_size);
}
}
diff --git a/libgomp/testsuite/libgomp.graphite/bounds.c b/libgomp/testsuite/libgomp.graphite/bounds.c
new file mode 100644
index 0000000..7a6a244
--- /dev/null
+++ b/libgomp/testsuite/libgomp.graphite/bounds.c
@@ -0,0 +1,13 @@
+int foo(int *a, int n)
+{
+ int i;
+ for (i = 2; i < n; i++)
+ a[i] += a[i+1];
+}
+
+/* Check that Graphite dependency checking notes the dependency. */
+/* { dg-do compile } */
+/* { dg-final { scan-tree-dump-times "0 loops carried no dependency" 1 "graphite" } } */
+/* { dg-final { cleanup-tree-dump "graphite" } } */
+/* { dg-final { cleanup-tree-dump "parloops" } } */
+/* { dg-final { cleanup-tree-dump "optimized" } } */