diff options
author | Eric Botcazou <ebotcazou@adacore.com> | 2008-04-07 09:47:43 +0000 |
---|---|---|
committer | Eric Botcazou <ebotcazou@gcc.gnu.org> | 2008-04-07 09:47:43 +0000 |
commit | 39fcde8ff2ba378999f0466b8d65c233042c51b6 (patch) | |
tree | 5f52e504245f353cbf4c7ab73aff6c9c36257959 /gcc/fold-const.c | |
parent | 9dd9bf80a87fdd119261f5efb8a9ceceffb12963 (diff) | |
download | gcc-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.c | 39 |
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)); |