X-Git-Url: http://git.sourceforge.jp/view?a=blobdiff_plain;f=gcc%2Fc-gimplify.c;h=12292a7e591acf45b1671e9d8da8c156897d7de9;hb=9fed75026cca1c2bf8cbf67920c15fe52489d1c9;hp=7ddc88cf4ea939e2731195e10bd422942f31d27c;hpb=e6b3b120a11d5e06cd7e1dc9dfd26a956af8e9f8;p=pf3gnuchains%2Fgcc-fork.git diff --git a/gcc/c-gimplify.c b/gcc/c-gimplify.c index 7ddc88cf4ea..12292a7e591 100644 --- a/gcc/c-gimplify.c +++ b/gcc/c-gimplify.c @@ -2,7 +2,7 @@ by the C-based front ends. The structure of gimplified, or language-independent, trees is dictated by the grammar described in this file. - Copyright (C) 2002, 2003, 2004, 2005 Free Software Foundation, Inc. + Copyright (C) 2002, 2003, 2004, 2005, 2007 Free Software Foundation, Inc. Lowering of expressions contributed by Sebastian Pop Re-written to support lowering of whole function trees, documentation and miscellaneous cleanups by Diego Novillo @@ -11,7 +11,7 @@ This file is part of GCC. GCC is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free -Software Foundation; either version 2, or (at your option) any later +Software Foundation; either version 3, or (at your option) any later version. GCC is distributed in the hope that it will be useful, but WITHOUT ANY @@ -20,9 +20,8 @@ FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License -along with GCC; see the file COPYING. If not, write to the Free -Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA -02110-1301, USA. */ +along with GCC; see the file COPYING3. If not see +. */ #include "config.h" #include "system.h" @@ -183,6 +182,20 @@ gimplify_compound_literal_expr (tree *expr_p, tree *pre_p) { tree decl_s = COMPOUND_LITERAL_EXPR_DECL_STMT (*expr_p); tree decl = DECL_EXPR_DECL (decl_s); + /* Mark the decl as addressable if the compound literal + expression is addressable now, otherwise it is marked too late + after we gimplify the initialization expression. */ + if (TREE_ADDRESSABLE (*expr_p)) + TREE_ADDRESSABLE (decl) = 1; + + /* Preliminarily mark non-addressed complex variables as eligible + for promotion to gimple registers. We'll transform their uses + as we find them. */ + if ((TREE_CODE (TREE_TYPE (decl)) == COMPLEX_TYPE + || TREE_CODE (TREE_TYPE (decl)) == VECTOR_TYPE) + && !TREE_THIS_VOLATILE (decl) + && !needs_to_live_in_memory (decl)) + DECL_GIMPLE_REG_P (decl) = 1; /* This decl isn't mentioned in the enclosing block, so add it to the list of temps. FIXME it seems a bit of a kludge to say that @@ -195,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 @@ -220,6 +274,41 @@ c_gimplify_expr (tree *expr_p, tree *pre_p, tree *post_p ATTRIBUTE_UNUSED) case COMPOUND_LITERAL_EXPR: return gimplify_compound_literal_expr (expr_p, pre_p); + case INIT_EXPR: + case MODIFY_EXPR: + if (TREE_CODE (TREE_OPERAND (*expr_p, 1)) == COMPOUND_LITERAL_EXPR) + { + tree complit = TREE_OPERAND (*expr_p, 1); + tree decl_s = COMPOUND_LITERAL_EXPR_DECL_STMT (complit); + tree decl = DECL_EXPR_DECL (decl_s); + tree init = DECL_INITIAL (decl); + + /* struct T x = (struct T) { 0, 1, 2 } can be optimized + into struct T x = { 0, 1, 2 } if the address of the + compound literal has never been taken. */ + if (!TREE_ADDRESSABLE (complit) + && !TREE_ADDRESSABLE (decl) + && init) + { + *expr_p = copy_node (*expr_p); + TREE_OPERAND (*expr_p, 1) = init; + 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: return GS_UNHANDLED; }