This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] Plug optimization hole in constant folder
- From: Eric Botcazou <ebotcazou at adacore dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: Mon, 17 Sep 2007 16:46:03 +0200
- Subject: [PATCH] Plug optimization hole in constant folder
Hi,
This is end-of-stage-2 material but plugs an obvious hole in the constant
folder. In fold_ternary:
case COMPONENT_REF:
if (TREE_CODE (arg0) == CONSTRUCTOR
&& ! type_contains_placeholder_p (TREE_TYPE (arg0)))
{
unsigned HOST_WIDE_INT idx;
tree field, value;
FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (arg0), idx, field, value)
if (field == arg1)
return value;
}
return NULL_TREE;
but the couterpart for ARRAY_REF is nowhere to be found. As a result:
package P is
type R is record
I : Integer;
end record;
f1 : constant R := (I=>1);
f2 : integer renames f1.I;
b : boolean := f2 = 1;
end P;
is entirely optimized at compile time
p__b:
.byte 1
while
package P is
type A is array (1..1) of Integer;
f1 : constant A := (1=>1);
f2 : integer renames f1(1);
b : boolean := f2 = 1;
end P;
is not.
Bootstrapped/regtested on i586-suse-linux, OK for mainline?
2007-09-17 Eric Botcazou <ebotcazou@adacore.com>
* fold-const.c (fold) <ARRAY_REF>: New case. Try to fold
reference in constructor with non self-referential type.
ada/
* utils2.c (build_binary_op): Fold ARRAY_REF and ARRAY_RANGE_REF too.
2007-09-17 Eric Botcazou <ebotcazou@adacore.com>
* gnat.dg/specs/static_initializer2.ads: New testcase.
--
Eric Botcazou
Index: fold-const.c
===================================================================
--- fold-const.c (revision 128432)
+++ fold-const.c (working copy)
@@ -13138,6 +13141,22 @@ fold (tree expr)
switch (code)
{
+ case ARRAY_REF:
+ {
+ tree op0 = TREE_OPERAND (t, 0);
+ tree op1 = TREE_OPERAND (t, 1);
+ if (TREE_CODE (op0) == CONSTRUCTOR
+ && ! type_contains_placeholder_p (TREE_TYPE (op0)))
+ {
+ unsigned HOST_WIDE_INT i;
+ tree index, value;
+ FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (op0), i, index, value)
+ if (operand_equal_p (index, op1, 0))
+ return value;
+ }
+ return t;
+ }
+
case CONST_DECL:
return fold (DECL_INITIAL (t));
Index: ada/utils2.c
===================================================================
--- ada/utils2.c (revision 128432)
+++ ada/utils2.c (working copy)
@@ -1001,8 +1001,8 @@ build_binary_op (enum tree_code op_code,
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);
-- { dg-do compile }
package Static_Initializer2 is
type A is array (1..1) of Integer;
f1 : constant A := (1=>1);
f2 : integer renames f1(1);
b : boolean := f2 = 1;
end Static_Initializer2;
-- { dg-final { scan-assembler-not "elabs" } }