OSDN Git Service

PR c/34146
authorjakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 20 Nov 2007 10:36:03 +0000 (10:36 +0000)
committerjakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 20 Nov 2007 10:36:03 +0000 (10:36 +0000)
* c-gimplify.c (optimize_compound_literals_in_ctor): New function.
(c_gimplify_expr): Use it.

PR c/34146
* gcc.dg/tree-ssa/pr34146.c: New test.

PR testsuite/33978
* gcc.dg/tree-ssa/pr33723.c: Adjust scan pattern to make it less
dependent on target settings like move_by_pieces etc.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@130311 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/c-gimplify.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/tree-ssa/pr33723.c
gcc/testsuite/gcc.dg/tree-ssa/pr34146.c [new file with mode: 0644]

index 7b39d8b..5625617 100644 (file)
@@ -1,3 +1,9 @@
+2007-11-20  Jakub Jelinek  <jakub@redhat.com>
+
+       PR c/34146
+       * c-gimplify.c (optimize_compound_literals_in_ctor): New function.
+       (c_gimplify_expr): Use it.
+
 2007-11-20  Ben Elliston  <bje@au.ibm.com>
 
        * config/spu/spu_mfcio.h: Fix typo.
index a1ee27b..12292a7 100644 (file)
@@ -208,6 +208,47 @@ gimplify_compound_literal_expr (tree *expr_p, tree *pre_p)
   return GS_OK;
 }
 
+/* Optimize embedded COMPOUND_LITERAL_EXPRs within a CONSTRUCTOR,
+   return a new CONSTRUCTOR if something changed.  */
+
+static tree
+optimize_compound_literals_in_ctor (tree orig_ctor)
+{
+  tree ctor = orig_ctor;
+  VEC(constructor_elt,gc) *elts = CONSTRUCTOR_ELTS (ctor);
+  unsigned int idx, num = VEC_length (constructor_elt, elts);
+
+  for (idx = 0; idx < num; idx++)
+    {
+      tree value = VEC_index (constructor_elt, elts, idx)->value;
+      tree newval = value;
+      if (TREE_CODE (value) == CONSTRUCTOR)
+       newval = optimize_compound_literals_in_ctor (value);
+      else if (TREE_CODE (value) == COMPOUND_LITERAL_EXPR)
+       {
+         tree decl_s = COMPOUND_LITERAL_EXPR_DECL_STMT (value);
+         tree decl = DECL_EXPR_DECL (decl_s);
+         tree init = DECL_INITIAL (decl);
+
+         if (!TREE_ADDRESSABLE (value)
+             && !TREE_ADDRESSABLE (decl)
+             && init)
+           newval = init;
+       }
+      if (newval == value)
+       continue;
+
+      if (ctor == orig_ctor)
+       {
+         ctor = copy_node (orig_ctor);
+         CONSTRUCTOR_ELTS (ctor) = VEC_copy (constructor_elt, gc, elts);
+         elts = CONSTRUCTOR_ELTS (ctor);
+       }
+      VEC_index (constructor_elt, elts, idx)->value = newval;
+    }
+  return ctor;
+}
+
 /* Do C-specific gimplification.  Args are as for gimplify_expr.  */
 
 int
@@ -254,6 +295,18 @@ c_gimplify_expr (tree *expr_p, tree *pre_p, tree *post_p ATTRIBUTE_UNUSED)
              return GS_OK;
            }
        }
+      else if (TREE_CODE (TREE_OPERAND (*expr_p, 1)) == CONSTRUCTOR)
+       {
+         tree ctor
+           = optimize_compound_literals_in_ctor (TREE_OPERAND (*expr_p, 1));
+
+         if (ctor != TREE_OPERAND (*expr_p, 1))
+           {
+             *expr_p = copy_node (*expr_p);
+             TREE_OPERAND (*expr_p, 1) = ctor;
+             return GS_OK;
+           }
+       }
       return GS_UNHANDLED;
 
     default:
index cd4b067..c01f3ae 100644 (file)
@@ -1,5 +1,12 @@
 2007-11-20  Jakub Jelinek  <jakub@redhat.com>
 
+       PR c/34146
+       * gcc.dg/tree-ssa/pr34146.c: New test.
+
+       PR testsuite/33978
+       * gcc.dg/tree-ssa/pr33723.c: Adjust scan pattern to make it less
+       dependent on target settings like move_by_pieces etc.
+
        PR c++/28879
        * g++.dg/template/vla2.C: New test.
 
index 6c07682..32a3aad 100644 (file)
@@ -68,7 +68,5 @@ baz3 (void)
   test (&t);
 }
 
-/* { dg-final { scan-tree-dump-times "t = {}" 3 "gimple"} } */
-/* { dg-final { scan-tree-dump-times "t.f.f1 = 1" 4 "gimple"} } */
-/* { dg-final { scan-tree-dump-times "t.f.f8 = 8" 4 "gimple"} } */
+/* { dg-final { scan-tree-dump-not "t = D" "gimple"} } */
 /* { dg-final { cleanup-tree-dump "gimple" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr34146.c b/gcc/testsuite/gcc.dg/tree-ssa/pr34146.c
new file mode 100644 (file)
index 0000000..99fdeb5
--- /dev/null
@@ -0,0 +1,53 @@
+/* PR c/34146 */
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-gimple" } */
+
+struct A
+{
+  int f1, f2, f3;
+};
+
+struct B
+{
+  struct A g1, g2;
+};
+
+struct C
+{
+  struct B h1, h2;
+};
+
+typedef union
+{
+  struct C c;
+  char s[4];
+  long int a;
+} T;
+
+void
+foo (void)
+{
+  T t = { { { { 0, 0, 0 }, { 0, 0, 0 } }, { { 0, 0, 0 }, { 0, 0, 0 } } } };
+  test (&t);
+}
+
+void
+bar (void)
+{
+  T t = { { { { 0, 0, 0 }, (struct A) { 0, 0, 0 } },
+           (struct B) { (struct A) { 0, 0, 0 }, { 0, 0, 0 } } } };
+  test (&t);
+}
+
+void
+baz (void)
+{
+  T t = { { { { 0, 0, 0 }, (struct A) { 1, 1, 1 } },
+           (struct B) { (struct A) { 0, 0, 0 }, { 1, 1, 1 } } } };
+  test (&t);
+}
+
+/* { dg-final { scan-tree-dump-not "t = D" "gimple"} } */
+/* { dg-final { scan-tree-dump-not "t\.c\.h\[12\] = D" "gimple"} } */
+/* { dg-final { scan-tree-dump-not "\.g\[12\] = D" "gimple"} } */
+/* { dg-final { cleanup-tree-dump "gimple" } } */