From 7ef249e59f5763183e110ad98531645f3030a82c Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Tue, 20 Nov 2007 11:36:03 +0100 Subject: [PATCH] re PR c/34146 (Inefficient code with compound literals inside a CONSTRUCTO) PR c/34146 * 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. From-SVN: r130311 --- gcc/ChangeLog | 6 +++ gcc/c-gimplify.c | 53 +++++++++++++++++++++++++ gcc/testsuite/ChangeLog | 7 ++++ gcc/testsuite/gcc.dg/tree-ssa/pr33723.c | 4 +- gcc/testsuite/gcc.dg/tree-ssa/pr34146.c | 53 +++++++++++++++++++++++++ 5 files changed, 120 insertions(+), 3 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/pr34146.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 7b39d8b2ab4..5625617b9c2 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2007-11-20 Jakub Jelinek + + PR c/34146 + * c-gimplify.c (optimize_compound_literals_in_ctor): New function. + (c_gimplify_expr): Use it. + 2007-11-20 Ben Elliston * config/spu/spu_mfcio.h: Fix typo. diff --git a/gcc/c-gimplify.c b/gcc/c-gimplify.c index a1ee27bfb70..12292a7e591 100644 --- a/gcc/c-gimplify.c +++ b/gcc/c-gimplify.c @@ -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: diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index cd4b067eaa3..c01f3aefe28 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,5 +1,12 @@ 2007-11-20 Jakub Jelinek + 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. diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr33723.c b/gcc/testsuite/gcc.dg/tree-ssa/pr33723.c index 6c07682ba6b..32a3aad9c1c 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/pr33723.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/pr33723.c @@ -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 index 00000000000..99fdeb5edfe --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/pr34146.c @@ -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" } } */ -- 2.30.2