From 39fcde8ff2ba378999f0466b8d65c233042c51b6 Mon Sep 17 00:00:00 2001 From: Eric Botcazou Date: Mon, 7 Apr 2008 09:47:43 +0000 Subject: [PATCH] fold-const.c (fold): New case. * fold-const.c (fold) : 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 --- gcc/ChangeLog | 5 +++ gcc/ada/ChangeLog | 4 ++ gcc/ada/utils2.c | 4 +- gcc/fold-const.c | 39 +++++++++++++++++++ gcc/testsuite/ChangeLog | 5 +++ gcc/testsuite/gnat.dg/array4.adb | 37 ++++++++++++++++++ .../gnat.dg/specs/static_initializer2.ads | 22 +++++++++++ 7 files changed, 114 insertions(+), 2 deletions(-) create mode 100644 gcc/testsuite/gnat.dg/array4.adb create mode 100644 gcc/testsuite/gnat.dg/specs/static_initializer2.ads diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 3e158244c68..b4e1c51dabb 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,8 @@ +2008-04-07 Eric Botcazou + + * fold-const.c (fold) : New case. Try to fold constant + reference in constructor with non self-referential type. + 2008-04-07 Eric Botcazou Removal of Return with Depressed Stack Pointer support diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog index 44c64cecc1f..826cd0dfa99 100644 --- a/gcc/ada/ChangeLog +++ b/gcc/ada/ChangeLog @@ -1,3 +1,7 @@ +2008-04-07 Eric Botcazou + + * utils2.c (build_binary_op): Fold ARRAY_REF and ARRAY_RANGE_REF too. + 2008-04-07 Eric Botcazou * gigi.h (create_subprog_type): Remove returns_with_dsp parameter. diff --git a/gcc/ada/utils2.c b/gcc/ada/utils2.c index e9908676b44..8eddde2fb37 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 ef95ae3d4a5..5a101f27451 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 beac0eb46d6..d4e38e8dae5 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2008-04-07 Eric Botcazou + + * gnat.dg/array4.adb: New test. + * gnat.dg/specs/static_initializer2.ads: Likewise. + 2008-04-06 Richard Guenther 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 00000000000..048698a54e1 --- /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 00000000000..3b27f26bde7 --- /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" } } -- 2.30.2