aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Jambor <mjambor@suse.cz>2009-09-04 13:08:12 +0200
committerMartin Jambor <jamborm@gcc.gnu.org>2009-09-04 13:08:12 +0200
commit22fc64b4d9a300216a82f2160ffbac6fec872f16 (patch)
treebea51968c32cbdd16ec16f2806c946162b2b9d90
parent2cdece442dfe6cb678193e67b395ad4e7b2942c5 (diff)
downloadgcc-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
-rw-r--r--gcc/ChangeLog8
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gnat.dg/array8.adb34
-rw-r--r--gcc/tree-sra.c30
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)