aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorEric Botcazou <ebotcazou@adacore.com>2008-04-07 09:47:43 +0000
committerEric Botcazou <ebotcazou@gcc.gnu.org>2008-04-07 09:47:43 +0000
commit39fcde8ff2ba378999f0466b8d65c233042c51b6 (patch)
tree5f52e504245f353cbf4c7ab73aff6c9c36257959 /gcc
parent9dd9bf80a87fdd119261f5efb8a9ceceffb12963 (diff)
downloadgcc-39fcde8ff2ba378999f0466b8d65c233042c51b6.zip
gcc-39fcde8ff2ba378999f0466b8d65c233042c51b6.tar.gz
gcc-39fcde8ff2ba378999f0466b8d65c233042c51b6.tar.bz2
fold-const.c (fold): New case.
* fold-const.c (fold) <ARRAY_REF>: New case. Try to fold constant reference in constructor with non self-referential type. ada/ * utils2.c (build_binary_op): Fold ARRAY_REF and ARRAY_RANGE_REF too. From-SVN: r133977
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog5
-rw-r--r--gcc/ada/ChangeLog4
-rw-r--r--gcc/ada/utils2.c4
-rw-r--r--gcc/fold-const.c39
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gnat.dg/array4.adb37
-rw-r--r--gcc/testsuite/gnat.dg/specs/static_initializer2.ads22
7 files changed, 114 insertions, 2 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 3e15824..b4e1c51 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,5 +1,10 @@
2008-04-07 Eric Botcazou <ebotcazou@adacore.com>
+ * fold-const.c (fold) <ARRAY_REF>: New case. Try to fold constant
+ reference in constructor with non self-referential type.
+
+2008-04-07 Eric Botcazou <ebotcazou@adacore.com>
+
Removal of Return with Depressed Stack Pointer support
* tree.h (TYPE_RETURNS_STACK_DEPRESSED): Delete.
(ECF_SP_DEPRESSED): Likewise.
diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog
index 44c64ce..826cd0d 100644
--- a/gcc/ada/ChangeLog
+++ b/gcc/ada/ChangeLog
@@ -1,5 +1,9 @@
2008-04-07 Eric Botcazou <ebotcazou@adacore.com>
+ * utils2.c (build_binary_op): Fold ARRAY_REF and ARRAY_RANGE_REF too.
+
+2008-04-07 Eric Botcazou <ebotcazou@adacore.com>
+
* gigi.h (create_subprog_type): Remove returns_with_dsp parameter.
* decl.c (gnat_to_gnu_entity): Adjust for above new prototype.
* utils.c (create_subprog_type): Remove returns_with_dsp parameter.
diff --git a/gcc/ada/utils2.c b/gcc/ada/utils2.c
index e990867..8eddde2 100644
--- a/gcc/ada/utils2.c
+++ b/gcc/ada/utils2.c
@@ -1017,8 +1017,8 @@ build_binary_op (enum tree_code op_code, tree result_type,
else if (TREE_CODE (right_operand) == NULL_EXPR)
return build1 (NULL_EXPR, operation_type, TREE_OPERAND (right_operand, 0));
else if (op_code == ARRAY_REF || op_code == ARRAY_RANGE_REF)
- result = build4 (op_code, operation_type, left_operand,
- right_operand, NULL_TREE, NULL_TREE);
+ result = fold (build4 (op_code, operation_type, left_operand,
+ right_operand, NULL_TREE, NULL_TREE));
else
result
= fold_build2 (op_code, operation_type, left_operand, right_operand);
diff --git a/gcc/fold-const.c b/gcc/fold-const.c
index ef95ae3..5a101f2 100644
--- a/gcc/fold-const.c
+++ b/gcc/fold-const.c
@@ -13086,6 +13086,45 @@ fold (tree expr)
switch (code)
{
+ case ARRAY_REF:
+ {
+ tree op0 = TREE_OPERAND (t, 0);
+ tree op1 = TREE_OPERAND (t, 1);
+
+ if (TREE_CODE (op1) == INTEGER_CST
+ && TREE_CODE (op0) == CONSTRUCTOR
+ && ! type_contains_placeholder_p (TREE_TYPE (op0)))
+ {
+ VEC(constructor_elt,gc) *elts = CONSTRUCTOR_ELTS (op0);
+ unsigned HOST_WIDE_INT end = VEC_length (constructor_elt, elts);
+ unsigned HOST_WIDE_INT begin = 0;
+
+ /* Find a matching index by means of a binary search. */
+ while (begin != end)
+ {
+ unsigned HOST_WIDE_INT middle = (begin + end) / 2;
+ tree index = VEC_index (constructor_elt, elts, middle)->index;
+
+ if (TREE_CODE (index) == INTEGER_CST
+ && tree_int_cst_lt (index, op1))
+ begin = middle + 1;
+ else if (TREE_CODE (index) == INTEGER_CST
+ && tree_int_cst_lt (op1, index))
+ end = middle;
+ else if (TREE_CODE (index) == RANGE_EXPR
+ && tree_int_cst_lt (TREE_OPERAND (index, 1), op1))
+ begin = middle + 1;
+ else if (TREE_CODE (index) == RANGE_EXPR
+ && tree_int_cst_lt (op1, TREE_OPERAND (index, 0)))
+ end = middle;
+ else
+ return VEC_index (constructor_elt, elts, middle)->value;
+ }
+ }
+
+ return t;
+ }
+
case CONST_DECL:
return fold (DECL_INITIAL (t));
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index beac0eb..d4e38e8 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2008-04-07 Eric Botcazou <ebotcazou@adacore.com>
+
+ * gnat.dg/array4.adb: New test.
+ * gnat.dg/specs/static_initializer2.ads: Likewise.
+
2008-04-06 Richard Guenther <rguenther@suse.de>
PR tree-optimization/35400
diff --git a/gcc/testsuite/gnat.dg/array4.adb b/gcc/testsuite/gnat.dg/array4.adb
new file mode 100644
index 0000000..048698a
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/array4.adb
@@ -0,0 +1,37 @@
+-- { dg-do run }
+
+procedure Array4 is
+
+ type A is array (1..5) of Integer;
+ f : constant A := (1, 2, 3, 4, 5);
+
+ i1 : integer renames f(1);
+ i2 : integer renames f(2);
+ i3 : integer renames f(3);
+ i4 : integer renames f(4);
+ i5 : integer renames f(5);
+
+ procedure Link_Failure;
+ pragma Import (C, Link_Failure);
+
+begin
+ if i1 /= 1 then
+ Link_Failure;
+ end if;
+
+ if i2 /= 2 then
+ Link_Failure;
+ end if;
+
+ if i3 /= 3 then
+ Link_Failure;
+ end if;
+
+ if i4 /= 4 then
+ Link_Failure;
+ end if;
+
+ if i5 /= 5 then
+ Link_Failure;
+ end if;
+end;
diff --git a/gcc/testsuite/gnat.dg/specs/static_initializer2.ads b/gcc/testsuite/gnat.dg/specs/static_initializer2.ads
new file mode 100644
index 0000000..3b27f26
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/specs/static_initializer2.ads
@@ -0,0 +1,22 @@
+-- { dg-do compile }
+
+package Static_Initializer2 is
+
+ type A is array (1..5) of Integer;
+ f : constant A := (1, 2, 3, 4, 5);
+
+ i1 : integer renames f(1);
+ i2 : integer renames f(2);
+ i3 : integer renames f(3);
+ i4 : integer renames f(4);
+ i5 : integer renames f(5);
+
+ b1 : boolean := i1 = 1;
+ b2 : boolean := i2 = 2;
+ b3 : boolean := i3 = 3;
+ b4 : boolean := i4 = 4;
+ b5 : boolean := i5 = 5;
+
+end Static_Initializer2;
+
+-- { dg-final { scan-assembler-not "elabs" } }