diff options
author | Jakub Jelinek <jakub@redhat.com> | 2007-11-20 11:36:03 +0100 |
---|---|---|
committer | Jakub Jelinek <jakub@gcc.gnu.org> | 2007-11-20 11:36:03 +0100 |
commit | 7ef249e59f5763183e110ad98531645f3030a82c (patch) | |
tree | 0c4dfd8db5db25e7f3e83f89dc36db48d511e3fa /gcc/c-gimplify.c | |
parent | cae85ca91aadc601f13f814bbc6527f54293d843 (diff) | |
download | gcc-7ef249e59f5763183e110ad98531645f3030a82c.zip gcc-7ef249e59f5763183e110ad98531645f3030a82c.tar.gz gcc-7ef249e59f5763183e110ad98531645f3030a82c.tar.bz2 |
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
Diffstat (limited to 'gcc/c-gimplify.c')
-rw-r--r-- | gcc/c-gimplify.c | 53 |
1 files changed, 53 insertions, 0 deletions
diff --git a/gcc/c-gimplify.c b/gcc/c-gimplify.c index a1ee27b..12292a7 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: |