aboutsummaryrefslogtreecommitdiff
path: root/gcc/fold-const.c
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/fold-const.c
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/fold-const.c')
-rw-r--r--gcc/fold-const.c39
1 files changed, 39 insertions, 0 deletions
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));