diff options
author | Martin Jambor <mjambor@suse.cz> | 2009-09-04 13:08:12 +0200 |
---|---|---|
committer | Martin Jambor <jamborm@gcc.gnu.org> | 2009-09-04 13:08:12 +0200 |
commit | 22fc64b4d9a300216a82f2160ffbac6fec872f16 (patch) | |
tree | bea51968c32cbdd16ec16f2806c946162b2b9d90 /gcc | |
parent | 2cdece442dfe6cb678193e67b395ad4e7b2942c5 (diff) | |
download | gcc-22fc64b4d9a300216a82f2160ffbac6fec872f16.zip gcc-22fc64b4d9a300216a82f2160ffbac6fec872f16.tar.gz gcc-22fc64b4d9a300216a82f2160ffbac6fec872f16.tar.bz2 |
re PR tree-optimization/41112 (ACATS c43205b fails at -O2 (tree-sra))
2009-09-04 Martin Jambor <mjambor@suse.cz>
PR tree-optimization/41112
* tree-sra.c (build_ref_for_offset_1): Signal that we cannot
handle variable-bounded arrays.
(expr_with_var_bounded_array_refs_p): New function.
(analyze_access_subtree): Call expr_with_var_bounded_array_refs_p.
* testsuite/gnat.dg/array8.adb: New test.
From-SVN: r151420
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 8 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/gnat.dg/array8.adb | 34 | ||||
-rw-r--r-- | gcc/tree-sra.c | 30 |
4 files changed, 72 insertions, 5 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 994c36a..0b160b4 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,11 @@ +2009-09-04 Martin Jambor <mjambor@suse.cz> + + PR tree-optimization/41112 + * tree-sra.c (build_ref_for_offset_1): Signal that we cannot + handle variable-bounded arrays. + (expr_with_var_bounded_array_refs_p): New function. + (analyze_access_subtree): Call expr_with_var_bounded_array_refs_p. + 2009-09-04 Wolfgang Gellerich <gellerich@de.ibm.com> * config/s390/2097.md: Removed two incorrect bypasses. diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index f9e2502..d51cc02 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2009-09-04 Martin Jambor <mjambor@suse.cz> + + PR tree-optimization/41112 + * gnat.dg/array8.adb: New test. + 2009-09-03 Jakub Jelinek <jakub@redhat.com> * gcc.dg/guality/guality.exp: Only run guality tests if a trivial diff --git a/gcc/testsuite/gnat.dg/array8.adb b/gcc/testsuite/gnat.dg/array8.adb new file mode 100644 index 0000000..6e18eca --- /dev/null +++ b/gcc/testsuite/gnat.dg/array8.adb @@ -0,0 +1,34 @@ +-- { dg-do compile } +-- { dg-options "-O2" } + +PROCEDURE Array8 IS + + function ID (I : Integer) return Integer is + begin + return I; + end; + + SUBTYPE STB IS INTEGER RANGE ID(-8) .. -5; + + TYPE TB IS ARRAY (STB RANGE <>) OF INTEGER; + + GENERIC + B1 : TB; + PROCEDURE PROC1; + + PROCEDURE PROC1 IS + BEGIN + IF B1'FIRST /= -8 THEN + raise Program_Error; + ELSIF B1'LAST /= ID(-5) THEN + raise Program_Error; + ELSIF B1 /= (7, 6, 5, 4) THEN + raise Program_Error; + END IF; + END; + + PROCEDURE PROC2 IS NEW PROC1 ((7, 6, ID(5), 4)); + +BEGIN + PROC2; +END; diff --git a/gcc/tree-sra.c b/gcc/tree-sra.c index aed2839..a801839 100644 --- a/gcc/tree-sra.c +++ b/gcc/tree-sra.c @@ -1039,7 +1039,7 @@ build_ref_for_offset_1 (tree *res, tree type, HOST_WIDE_INT offset, while (1) { tree fld; - tree tr_size, index; + tree tr_size, index, minidx; HOST_WIDE_INT el_size; if (offset == 0 && exp_type @@ -1090,13 +1090,14 @@ build_ref_for_offset_1 (tree *res, tree type, HOST_WIDE_INT offset, return false; el_size = tree_low_cst (tr_size, 1); + minidx = TYPE_MIN_VALUE (TYPE_DOMAIN (type)); + if (TREE_CODE (minidx) != INTEGER_CST) + return false; if (res) { index = build_int_cst (TYPE_DOMAIN (type), offset / el_size); - if (!integer_zerop (TYPE_MIN_VALUE (TYPE_DOMAIN (type)))) - index = int_const_binop (PLUS_EXPR, index, - TYPE_MIN_VALUE (TYPE_DOMAIN (type)), - 0); + if (!integer_zerop (minidx)) + index = int_const_binop (PLUS_EXPR, index, minidx, 0); *res = build4 (ARRAY_REF, TREE_TYPE (type), *res, index, NULL_TREE, NULL_TREE); } @@ -1378,6 +1379,22 @@ build_access_trees (struct access *access) } } +/* Return true if expr contains some ARRAY_REFs into a variable bounded + array. */ + +static bool +expr_with_var_bounded_array_refs_p (tree expr) +{ + while (handled_component_p (expr)) + { + if (TREE_CODE (expr) == ARRAY_REF + && !host_integerp (array_ref_low_bound (expr), 0)) + return true; + expr = TREE_OPERAND (expr, 0); + } + return false; +} + /* Analyze the subtree of accesses rooted in ROOT, scheduling replacements when both seeming beneficial and when ALLOW_REPLACEMENTS allows it. Also set all sorts of access flags appropriately along the way, notably always ser @@ -1407,6 +1424,9 @@ analyze_access_subtree (struct access *root, bool allow_replacements, if (root->grp_unscalarizable_region) allow_replacements = false; + if (allow_replacements && expr_with_var_bounded_array_refs_p (root->expr)) + allow_replacements = false; + for (child = root->first_child; child; child = child->next_sibling) { if (!hole && child->offset < covered_to) |