This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[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" } }

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]