fold-const.c (fold): New case.
authorEric Botcazou <ebotcazou@adacore.com>
Mon, 7 Apr 2008 09:47:43 +0000 (09:47 +0000)
committerEric Botcazou <ebotcazou@gcc.gnu.org>
Mon, 7 Apr 2008 09:47:43 +0000 (09:47 +0000)
* 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

gcc/ChangeLog
gcc/ada/ChangeLog
gcc/ada/utils2.c
gcc/fold-const.c
gcc/testsuite/ChangeLog
gcc/testsuite/gnat.dg/array4.adb [new file with mode: 0644]
gcc/testsuite/gnat.dg/specs/static_initializer2.ads [new file with mode: 0644]

index 3e158244c682b943be995a66ad51c84930c27b7b..b4e1c51dabb40b2689b9add8618b659c2be4191f 100644 (file)
@@ -1,3 +1,8 @@
+2008-04-07  Eric Botcazou  <ebotcazou@adacore.com>
+
+       * fold-const.c (fold) <ARRAY_REF>: New case.  Try to fold constant
+       reference in constructor with non self-referential type.
+
 2008-04-07  Eric Botcazou  <ebotcazou@adacore.com>
 
        Removal of Return with Depressed Stack Pointer support
index 44c64cecc1f1925df91044cc48cbf0c78ebb65b2..826cd0dfa9987dd8e0d8c1fcfb717e929a6359d4 100644 (file)
@@ -1,3 +1,7 @@
+2008-04-07  Eric Botcazou  <ebotcazou@adacore.com>
+
+       * utils2.c (build_binary_op): Fold ARRAY_REF and ARRAY_RANGE_REF too.
+
 2008-04-07  Eric Botcazou  <ebotcazou@adacore.com>
 
        * gigi.h (create_subprog_type): Remove returns_with_dsp parameter.
index e9908676b441ce1594ca20f19448e44f51c250b6..8eddde2fb3737c66cce9190448b0f72359626097 100644 (file)
@@ -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);
index ef95ae3d4a54db07b1a0a709392acde0c257feab..5a101f27451359f5f172d483cf761fa7d9e77db2 100644 (file)
@@ -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));
 
index beac0eb46d6973a3173809870474837e6f2854cb..d4e38e8dae53f97a15af2aa60162812658194d84 100644 (file)
@@ -1,3 +1,8 @@
+2008-04-07  Eric Botcazou  <ebotcazou@adacore.com>
+
+       * gnat.dg/array4.adb: New test.
+       * gnat.dg/specs/static_initializer2.ads: Likewise.
+
 2008-04-06  Richard Guenther  <rguenther@suse.de>
 
        PR tree-optimization/35400
diff --git a/gcc/testsuite/gnat.dg/array4.adb b/gcc/testsuite/gnat.dg/array4.adb
new file mode 100644 (file)
index 0000000..048698a
--- /dev/null
@@ -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 (file)
index 0000000..3b27f26
--- /dev/null
@@ -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" } }