c-common.c (c_expand_expr, c_staticp): Remove.
2009-03-28 Paolo Bonzini <bonzini@gnu.org> * c-common.c (c_expand_expr, c_staticp): Remove. * c-common.def (COMPOUND_LITERAL_EXPR): Delete. * c-common.h (emit_local_var, c_staticp, COMPOUND_LITERAL_EXPR_DECL, COMPOUND_LITERAL_EXPR_DECL_EXPR): Remove. * c-gimplify.c (gimplify_compound_literal_expr, optimize_compound_literals_in_ctor): Remove. (c_gimplify_expr): Remove COMPOUND_LITERAL_EXPR handling. * c-objc-common.h (LANG_HOOKS_STATICP): Remove. * c-semantics.c (emit_local_var): Remove. * langhooks-def.h (lhd_expand_expr): Remove. * langhooks.c (lhd_expand_expr): Remove. * langhooks.h (LANG_HOOKS_DEF): Remove LANG_HOOKS_EXPAND_EXPR. * expr.c (expand_expr_real_1): Move COMPOUND_LITERAL_EXPR handling from c-semantics.c; don't call into langhook. (expand_expr_addr_expr_1): Check that we don't get non-GENERIC trees. * gimplify.c (gimplify_compound_literal_expr, optimize_compound_literals_in_ctor): Move from c-gimplify.c. (gimplify_init_constructor): Call optimize_compound_literals_in_ctor. (gimplify_modify_expr_rhs, gimplify_expr): Handle COMPOUND_LITERAL_EXPR as was done in c-gimplify.c. * tree.c (staticp): Move COMPOUND_LITERAL_EXPR handling from c_staticp. * tree.h (COMPOUND_LITERAL_EXPR_DECL, COMPOUND_LITERAL_EXPR_DECL_EXPR): Move from c-common.h. * tree.def (COMPOUND_LITERAL_EXPR): Move from c-common.def. * tree.c (staticp): Do not call langhook. * langhooks.c (lhd_staticp): Delete. * langhooks-def.h (lhd_staticp): Delete prototype. (LANG_HOOKS_STATICP): Delete. (LANG_HOOKS_INITIALIZER): Delete LANG_HOOKS_STATICP. * doc/c-tree.texi (Expression nodes): Refer to DECL_EXPRs instead of DECL_STMTs. cp: 2009-03-28 Paolo Bonzini <bonzini@gnu.org> * cp/cp-objcp-common.h (LANG_HOOKS_STATICP): Remove. * cp/cp-objcp-common.c (cxx_staticp): Remove. * cp/cp-tree.h (cxx_staticp): Remove. From-SVN: r145256
This commit is contained in:
parent
928c19bbb0
commit
2ec5deb5c3
21 changed files with 209 additions and 282 deletions
|
@ -1,3 +1,41 @@
|
|||
2009-03-28 Paolo Bonzini <bonzini@gnu.org>
|
||||
|
||||
* c-common.c (c_expand_expr, c_staticp): Remove.
|
||||
* c-common.def (COMPOUND_LITERAL_EXPR): Delete.
|
||||
* c-common.h (emit_local_var, c_staticp, COMPOUND_LITERAL_EXPR_DECL,
|
||||
COMPOUND_LITERAL_EXPR_DECL_EXPR): Remove.
|
||||
* c-gimplify.c (gimplify_compound_literal_expr,
|
||||
optimize_compound_literals_in_ctor): Remove.
|
||||
(c_gimplify_expr): Remove COMPOUND_LITERAL_EXPR handling.
|
||||
* c-objc-common.h (LANG_HOOKS_STATICP): Remove.
|
||||
* c-semantics.c (emit_local_var): Remove.
|
||||
|
||||
* langhooks-def.h (lhd_expand_expr): Remove.
|
||||
* langhooks.c (lhd_expand_expr): Remove.
|
||||
* langhooks.h (LANG_HOOKS_DEF): Remove LANG_HOOKS_EXPAND_EXPR.
|
||||
|
||||
* expr.c (expand_expr_real_1): Move COMPOUND_LITERAL_EXPR
|
||||
handling from c-semantics.c; don't call into langhook.
|
||||
(expand_expr_addr_expr_1): Check that we don't get non-GENERIC trees.
|
||||
* gimplify.c (gimplify_compound_literal_expr,
|
||||
optimize_compound_literals_in_ctor): Move from c-gimplify.c.
|
||||
(gimplify_init_constructor): Call optimize_compound_literals_in_ctor.
|
||||
(gimplify_modify_expr_rhs, gimplify_expr): Handle COMPOUND_LITERAL_EXPR
|
||||
as was done in c-gimplify.c.
|
||||
* tree.c (staticp): Move COMPOUND_LITERAL_EXPR handling from c_staticp.
|
||||
* tree.h (COMPOUND_LITERAL_EXPR_DECL, COMPOUND_LITERAL_EXPR_DECL_EXPR):
|
||||
Move from c-common.h.
|
||||
* tree.def (COMPOUND_LITERAL_EXPR): Move from c-common.def.
|
||||
|
||||
* tree.c (staticp): Do not call langhook.
|
||||
* langhooks.c (lhd_staticp): Delete.
|
||||
* langhooks-def.h (lhd_staticp): Delete prototype.
|
||||
(LANG_HOOKS_STATICP): Delete.
|
||||
(LANG_HOOKS_INITIALIZER): Delete LANG_HOOKS_STATICP.
|
||||
|
||||
* doc/c-tree.texi (Expression nodes): Refer to DECL_EXPRs
|
||||
instead of DECL_STMTs.
|
||||
|
||||
2009-03-29 Joseph Myers <joseph@codesourcery.com>
|
||||
|
||||
PR c/456
|
||||
|
|
|
@ -5444,43 +5444,6 @@ finish_label_address_expr (tree label, location_t loc)
|
|||
|
||||
return result;
|
||||
}
|
||||
|
||||
/* Hook used by expand_expr to expand language-specific tree codes. */
|
||||
/* The only things that should go here are bits needed to expand
|
||||
constant initializers. Everything else should be handled by the
|
||||
gimplification routines. */
|
||||
|
||||
rtx
|
||||
c_expand_expr (tree exp, rtx target, enum machine_mode tmode,
|
||||
int modifiera /* Actually enum expand_modifier. */,
|
||||
rtx *alt_rtl)
|
||||
{
|
||||
enum expand_modifier modifier = (enum expand_modifier) modifiera;
|
||||
switch (TREE_CODE (exp))
|
||||
{
|
||||
case COMPOUND_LITERAL_EXPR:
|
||||
{
|
||||
/* Initialize the anonymous variable declared in the compound
|
||||
literal, then return the variable. */
|
||||
tree decl = COMPOUND_LITERAL_EXPR_DECL (exp);
|
||||
emit_local_var (decl);
|
||||
return expand_expr_real (decl, target, tmode, modifier, alt_rtl);
|
||||
}
|
||||
|
||||
default:
|
||||
gcc_unreachable ();
|
||||
}
|
||||
}
|
||||
|
||||
/* Hook used by staticp to handle language-specific tree codes. */
|
||||
|
||||
tree
|
||||
c_staticp (tree exp)
|
||||
{
|
||||
return (TREE_CODE (exp) == COMPOUND_LITERAL_EXPR
|
||||
&& TREE_STATIC (COMPOUND_LITERAL_EXPR_DECL (exp))
|
||||
? exp : NULL);
|
||||
}
|
||||
|
||||
|
||||
/* Given a boolean expression ARG, return a tree representing an increment
|
||||
|
|
|
@ -24,13 +24,6 @@ along with GCC; see the file COPYING3. If not see
|
|||
/* Tree nodes used in the C frontend. These are also shared with the
|
||||
C++ and Objective C frontends. */
|
||||
|
||||
/* A COMPOUND_LITERAL_EXPR represents a C99 compound literal. The
|
||||
COMPOUND_LITERAL_EXPR_DECL_STMT is the a DECL_STMT containing the decl
|
||||
for the anonymous object represented by the COMPOUND_LITERAL;
|
||||
the DECL_INITIAL of that decl is the CONSTRUCTOR that initializes
|
||||
the compound literal. */
|
||||
DEFTREECODE (COMPOUND_LITERAL_EXPR, "compound_literal_expr", tcc_expression, 1)
|
||||
|
||||
/* A C_MAYBE_CONST_EXPR, currently only used for C and Objective C,
|
||||
tracks information about constancy of an expression and VLA type
|
||||
sizes or VM expressions from typeof that need to be evaluated
|
||||
|
|
|
@ -798,12 +798,6 @@ extern void finish_file (void);
|
|||
#define STATEMENT_LIST_HAS_LABEL(NODE) \
|
||||
TREE_LANG_FLAG_3 (STATEMENT_LIST_CHECK (NODE))
|
||||
|
||||
/* COMPOUND_LITERAL_EXPR accessors. */
|
||||
#define COMPOUND_LITERAL_EXPR_DECL_STMT(NODE) \
|
||||
TREE_OPERAND (COMPOUND_LITERAL_EXPR_CHECK (NODE), 0)
|
||||
#define COMPOUND_LITERAL_EXPR_DECL(NODE) \
|
||||
DECL_EXPR_DECL (COMPOUND_LITERAL_EXPR_DECL_STMT (NODE))
|
||||
|
||||
/* C_MAYBE_CONST_EXPR accessors. */
|
||||
#define C_MAYBE_CONST_EXPR_PRE(NODE) \
|
||||
TREE_OPERAND (C_MAYBE_CONST_EXPR_CHECK (NODE), 0)
|
||||
|
@ -827,7 +821,6 @@ extern void finish_file (void);
|
|||
#define CLEAR_DECL_C_BIT_FIELD(NODE) \
|
||||
(DECL_LANG_FLAG_4 (FIELD_DECL_CHECK (NODE)) = 0)
|
||||
|
||||
extern void emit_local_var (tree);
|
||||
extern tree do_case (tree, tree);
|
||||
extern tree build_stmt (enum tree_code, ...);
|
||||
extern tree build_case_label (tree, tree, tree);
|
||||
|
@ -876,8 +869,6 @@ extern bool vector_types_convertible_p (const_tree t1, const_tree t2, bool emit_
|
|||
|
||||
extern rtx c_expand_expr (tree, rtx, enum machine_mode, int, rtx *);
|
||||
|
||||
extern tree c_staticp (tree);
|
||||
|
||||
extern void init_c_lex (void);
|
||||
|
||||
extern void c_cpp_builtins (cpp_reader *);
|
||||
|
|
144
gcc/c-gimplify.c
144
gcc/c-gimplify.c
|
@ -176,145 +176,25 @@ c_build_bind_expr (tree block, tree body)
|
|||
|
||||
/* Gimplification of expression trees. */
|
||||
|
||||
/* Gimplify a C99 compound literal expression. This just means adding
|
||||
the DECL_EXPR before the current statement and using its anonymous
|
||||
decl instead. */
|
||||
|
||||
static enum gimplify_status
|
||||
gimplify_compound_literal_expr (tree *expr_p, gimple_seq *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
|
||||
anonymous artificial vars aren't pushed, but everything else is. */
|
||||
if (DECL_NAME (decl) == NULL_TREE && !DECL_SEEN_IN_BIND_EXPR_P (decl))
|
||||
gimple_add_tmp_var (decl);
|
||||
|
||||
gimplify_and_add (decl_s, pre_p);
|
||||
*expr_p = decl;
|
||||
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 on *EXPR_P. PRE_P and POST_P are as in
|
||||
gimplify_expr. */
|
||||
|
||||
int
|
||||
c_gimplify_expr (tree *expr_p, gimple_seq *pre_p,
|
||||
c_gimplify_expr (tree *expr_p, gimple_seq *pre_p ATTRIBUTE_UNUSED,
|
||||
gimple_seq *post_p ATTRIBUTE_UNUSED)
|
||||
{
|
||||
enum tree_code code = TREE_CODE (*expr_p);
|
||||
|
||||
switch (code)
|
||||
{
|
||||
case DECL_EXPR:
|
||||
/* This is handled mostly by gimplify.c, but we have to deal with
|
||||
not warning about int x = x; as it is a GCC extension to turn off
|
||||
this warning but only if warn_init_self is zero. */
|
||||
if (TREE_CODE (DECL_EXPR_DECL (*expr_p)) == VAR_DECL
|
||||
&& !DECL_EXTERNAL (DECL_EXPR_DECL (*expr_p))
|
||||
&& !TREE_STATIC (DECL_EXPR_DECL (*expr_p))
|
||||
&& (DECL_INITIAL (DECL_EXPR_DECL (*expr_p))
|
||||
== DECL_EXPR_DECL (*expr_p))
|
||||
&& !warn_init_self)
|
||||
TREE_NO_WARNING (DECL_EXPR_DECL (*expr_p)) = 1;
|
||||
return GS_UNHANDLED;
|
||||
/* This is handled mostly by gimplify.c, but we have to deal with
|
||||
not warning about int x = x; as it is a GCC extension to turn off
|
||||
this warning but only if warn_init_self is zero. */
|
||||
if (code == DECL_EXPR
|
||||
&& TREE_CODE (DECL_EXPR_DECL (*expr_p)) == VAR_DECL
|
||||
&& !DECL_EXTERNAL (DECL_EXPR_DECL (*expr_p))
|
||||
&& !TREE_STATIC (DECL_EXPR_DECL (*expr_p))
|
||||
&& (DECL_INITIAL (DECL_EXPR_DECL (*expr_p)) == DECL_EXPR_DECL (*expr_p))
|
||||
&& !warn_init_self)
|
||||
TREE_NO_WARNING (DECL_EXPR_DECL (*expr_p)) = 1;
|
||||
|
||||
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;
|
||||
}
|
||||
return GS_UNHANDLED;
|
||||
}
|
||||
|
|
|
@ -43,16 +43,12 @@ extern void c_initialize_diagnostics (diagnostic_context *);
|
|||
#define LANG_HOOKS_POST_OPTIONS c_common_post_options
|
||||
#undef LANG_HOOKS_GET_ALIAS_SET
|
||||
#define LANG_HOOKS_GET_ALIAS_SET c_common_get_alias_set
|
||||
#undef LANG_HOOKS_EXPAND_EXPR
|
||||
#define LANG_HOOKS_EXPAND_EXPR c_expand_expr
|
||||
#undef LANG_HOOKS_MARK_ADDRESSABLE
|
||||
#define LANG_HOOKS_MARK_ADDRESSABLE c_mark_addressable
|
||||
#undef LANG_HOOKS_PARSE_FILE
|
||||
#define LANG_HOOKS_PARSE_FILE c_common_parse_file
|
||||
#undef LANG_HOOKS_FINISH_INCOMPLETE_DECL
|
||||
#define LANG_HOOKS_FINISH_INCOMPLETE_DECL c_finish_incomplete_decl
|
||||
#undef LANG_HOOKS_STATICP
|
||||
#define LANG_HOOKS_STATICP c_staticp
|
||||
#undef LANG_HOOKS_WARN_UNUSED_GLOBAL_DECL
|
||||
#define LANG_HOOKS_WARN_UNUSED_GLOBAL_DECL c_warn_unused_global_decl
|
||||
#undef LANG_HOOKS_PRINT_IDENTIFIER
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
/* This file contains the definitions and documentation for the common
|
||||
tree codes used in the GNU C and C++ compilers (see c-common.def
|
||||
for the standard codes).
|
||||
/* This file contains subroutine used by the C front-end to construct GENERIC.
|
||||
Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2007, 2008
|
||||
Free Software Foundation, Inc.
|
||||
Written by Benjamin Chelf (chelf@codesourcery.com).
|
||||
|
@ -145,23 +143,6 @@ build_stmt (enum tree_code code, ...)
|
|||
return ret;
|
||||
}
|
||||
|
||||
/* Let the back-end know about DECL. */
|
||||
|
||||
void
|
||||
emit_local_var (tree decl)
|
||||
{
|
||||
/* Create RTL for this variable. */
|
||||
if (!DECL_RTL_SET_P (decl))
|
||||
{
|
||||
if (DECL_HARD_REGISTER (decl))
|
||||
/* The user specified an assembler name for this variable.
|
||||
Set that up now. */
|
||||
rest_of_decl_compilation (decl, 0, 0);
|
||||
else
|
||||
expand_decl (decl);
|
||||
}
|
||||
}
|
||||
|
||||
/* Create a CASE_LABEL_EXPR tree node and return it. */
|
||||
|
||||
tree
|
||||
|
|
|
@ -1,3 +1,9 @@
|
|||
2009-03-28 Paolo Bonzini <bonzini@gnu.org>
|
||||
|
||||
* cp/cp-objcp-common.h (LANG_HOOKS_STATICP): Remove.
|
||||
* cp/cp-objcp-common.c (cxx_staticp): Remove.
|
||||
* cp/cp-tree.h (cxx_staticp): Remove.
|
||||
|
||||
2009-03-28 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
PR c++/39554
|
||||
|
|
|
@ -188,21 +188,6 @@ cxx_types_compatible_p (tree x, tree y)
|
|||
return same_type_ignoring_top_level_qualifiers_p (x, y);
|
||||
}
|
||||
|
||||
tree
|
||||
cxx_staticp (tree arg)
|
||||
{
|
||||
switch (TREE_CODE (arg))
|
||||
{
|
||||
case BASELINK:
|
||||
return staticp (BASELINK_FUNCTIONS (arg));
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return NULL_TREE;
|
||||
}
|
||||
|
||||
/* Return true if DECL is explicit member function. */
|
||||
|
||||
bool
|
||||
|
|
|
@ -52,12 +52,8 @@ extern bool cp_function_decl_explicit_p (tree decl);
|
|||
#define LANG_HOOKS_POST_OPTIONS c_common_post_options
|
||||
#undef LANG_HOOKS_GET_ALIAS_SET
|
||||
#define LANG_HOOKS_GET_ALIAS_SET cxx_get_alias_set
|
||||
#undef LANG_HOOKS_EXPAND_EXPR
|
||||
#define LANG_HOOKS_EXPAND_EXPR c_expand_expr
|
||||
#undef LANG_HOOKS_PARSE_FILE
|
||||
#define LANG_HOOKS_PARSE_FILE c_common_parse_file
|
||||
#undef LANG_HOOKS_STATICP
|
||||
#define LANG_HOOKS_STATICP cxx_staticp
|
||||
#undef LANG_HOOKS_DUP_LANG_SPECIFIC_DECL
|
||||
#define LANG_HOOKS_DUP_LANG_SPECIFIC_DECL cxx_dup_lang_specific_decl
|
||||
#undef LANG_HOOKS_SET_DECL_ASSEMBLER_NAME
|
||||
|
|
|
@ -5053,7 +5053,6 @@ extern bool cp_var_mod_type_p (tree, tree);
|
|||
extern void cxx_initialize_diagnostics (struct diagnostic_context *);
|
||||
extern int cxx_types_compatible_p (tree, tree);
|
||||
extern void init_shadowed_var_for_decl (void);
|
||||
extern tree cxx_staticp (tree);
|
||||
|
||||
/* in cp-gimplify.c */
|
||||
extern int cp_gimplify_expr (tree *, gimple_seq *,
|
||||
|
|
|
@ -2636,10 +2636,10 @@ declaration order. You should not assume that all fields will be
|
|||
represented. Unrepresented fields will be set to zero.
|
||||
|
||||
@item COMPOUND_LITERAL_EXPR
|
||||
@findex COMPOUND_LITERAL_EXPR_DECL_STMT
|
||||
@findex COMPOUND_LITERAL_EXPR_DECL_EXPR
|
||||
@findex COMPOUND_LITERAL_EXPR_DECL
|
||||
These nodes represent ISO C99 compound literals. The
|
||||
@code{COMPOUND_LITERAL_EXPR_DECL_STMT} is a @code{DECL_STMT}
|
||||
@code{COMPOUND_LITERAL_EXPR_DECL_EXPR} is a @code{DECL_EXPR}
|
||||
containing an anonymous @code{VAR_DECL} for
|
||||
the unnamed object represented by the compound literal; the
|
||||
@code{DECL_INITIAL} of that @code{VAR_DECL} is a @code{CONSTRUCTOR}
|
||||
|
|
|
@ -248,7 +248,7 @@ expr_size (tree exp)
|
|||
{
|
||||
size = lang_hooks.expr_size (exp);
|
||||
gcc_assert (size);
|
||||
size = SUBSTITUTE_PLACEHOLDER_IN_EXPR (size, exp);
|
||||
gcc_assert (size == SUBSTITUTE_PLACEHOLDER_IN_EXPR (size, exp));
|
||||
}
|
||||
|
||||
return expand_expr (size, NULL_RTX, TYPE_MODE (sizetype), EXPAND_NORMAL);
|
||||
|
|
34
gcc/expr.c
34
gcc/expr.c
|
@ -6821,9 +6821,10 @@ expand_expr_addr_expr_1 (tree exp, rtx target, enum machine_mode tmode,
|
|||
CONSTRUCTORs too, which should yield a memory reference for the
|
||||
constructor's contents. Assume language specific tree nodes can
|
||||
be expanded in some interesting way. */
|
||||
gcc_assert (TREE_CODE (exp) < LAST_AND_UNUSED_TREE_CODE);
|
||||
if (DECL_P (exp)
|
||||
|| TREE_CODE (exp) == CONSTRUCTOR
|
||||
|| TREE_CODE (exp) >= LAST_AND_UNUSED_TREE_CODE)
|
||||
|| TREE_CODE (exp) == COMPOUND_LITERAL_EXPR)
|
||||
{
|
||||
result = expand_expr (exp, target, tmode,
|
||||
modifier == EXPAND_INITIALIZER
|
||||
|
@ -8069,11 +8070,8 @@ expand_expr_real_1 (tree exp, rtx target, enum machine_mode tmode,
|
|||
/* Check for a built-in function. */
|
||||
if (fndecl && DECL_BUILT_IN (fndecl))
|
||||
{
|
||||
if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_FRONTEND)
|
||||
return lang_hooks.expand_expr (exp, original_target,
|
||||
tmode, modifier, alt_rtl);
|
||||
else
|
||||
return expand_builtin (exp, target, subtarget, tmode, ignore);
|
||||
gcc_assert (DECL_BUILT_IN_CLASS (fndecl) != BUILT_IN_FRONTEND);
|
||||
return expand_builtin (exp, target, subtarget, tmode, ignore);
|
||||
}
|
||||
}
|
||||
return expand_call (exp, target, ignore);
|
||||
|
@ -9460,9 +9458,29 @@ expand_expr_real_1 (tree exp, rtx target, enum machine_mode tmode,
|
|||
mode = TYPE_MODE (TREE_TYPE (TREE_OPERAND (exp, 0)));
|
||||
goto binop;
|
||||
|
||||
case COMPOUND_LITERAL_EXPR:
|
||||
{
|
||||
/* Initialize the anonymous variable declared in the compound
|
||||
literal, then return the variable. */
|
||||
tree decl = COMPOUND_LITERAL_EXPR_DECL (exp);
|
||||
|
||||
/* Create RTL for this variable. */
|
||||
if (!DECL_RTL_SET_P (decl))
|
||||
{
|
||||
if (DECL_HARD_REGISTER (decl))
|
||||
/* The user specified an assembler name for this variable.
|
||||
Set that up now. */
|
||||
rest_of_decl_compilation (decl, 0, 0);
|
||||
else
|
||||
expand_decl (decl);
|
||||
}
|
||||
|
||||
return expand_expr_real (decl, original_target, tmode,
|
||||
modifier, alt_rtl);
|
||||
}
|
||||
|
||||
default:
|
||||
return lang_hooks.expand_expr (exp, original_target, tmode,
|
||||
modifier, alt_rtl);
|
||||
gcc_unreachable ();
|
||||
}
|
||||
|
||||
/* Here to do an ordinary binary operator. */
|
||||
|
|
106
gcc/gimplify.c
106
gcc/gimplify.c
|
@ -3456,6 +3456,83 @@ rhs_predicate_for (tree lhs)
|
|||
return is_gimple_mem_or_call_rhs;
|
||||
}
|
||||
|
||||
/* Gimplify a C99 compound literal expression. This just means adding
|
||||
the DECL_EXPR before the current statement and using its anonymous
|
||||
decl instead. */
|
||||
|
||||
static enum gimplify_status
|
||||
gimplify_compound_literal_expr (tree *expr_p, gimple_seq *pre_p)
|
||||
{
|
||||
tree decl_s = COMPOUND_LITERAL_EXPR_DECL_EXPR (*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
|
||||
anonymous artificial vars aren't pushed, but everything else is. */
|
||||
if (DECL_NAME (decl) == NULL_TREE && !DECL_SEEN_IN_BIND_EXPR_P (decl))
|
||||
gimple_add_tmp_var (decl);
|
||||
|
||||
gimplify_and_add (decl_s, pre_p);
|
||||
*expr_p = decl;
|
||||
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_EXPR (value);
|
||||
tree decl = DECL_EXPR_DECL (decl_s);
|
||||
tree init = DECL_INITIAL (decl);
|
||||
|
||||
if (!TREE_ADDRESSABLE (value)
|
||||
&& !TREE_ADDRESSABLE (decl)
|
||||
&& init)
|
||||
newval = optimize_compound_literals_in_ctor (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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* A subroutine of gimplify_modify_expr. Break out elements of a
|
||||
CONSTRUCTOR used as an initializer into separate MODIFY_EXPRs.
|
||||
|
@ -3474,7 +3551,7 @@ static enum gimplify_status
|
|||
gimplify_init_constructor (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
|
||||
bool want_value, bool notify_temp_creation)
|
||||
{
|
||||
tree object;
|
||||
tree object, new_ctor;
|
||||
tree ctor = TREE_OPERAND (*expr_p, 1);
|
||||
tree type = TREE_TYPE (ctor);
|
||||
enum gimplify_status ret;
|
||||
|
@ -3492,7 +3569,8 @@ gimplify_init_constructor (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
|
|||
}
|
||||
|
||||
object = TREE_OPERAND (*expr_p, 0);
|
||||
elts = CONSTRUCTOR_ELTS (ctor);
|
||||
new_ctor = optimize_compound_literals_in_ctor (ctor);
|
||||
elts = CONSTRUCTOR_ELTS (new_ctor);
|
||||
ret = GS_ALL_DONE;
|
||||
|
||||
switch (TREE_CODE (type))
|
||||
|
@ -4099,6 +4177,26 @@ gimplify_modify_expr_rhs (tree *expr_p, tree *from_p, tree *to_p,
|
|||
return GS_OK;
|
||||
}
|
||||
|
||||
case COMPOUND_LITERAL_EXPR:
|
||||
{
|
||||
tree complit = TREE_OPERAND (*expr_p, 1);
|
||||
tree decl_s = COMPOUND_LITERAL_EXPR_DECL_EXPR (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;
|
||||
}
|
||||
}
|
||||
|
||||
default:
|
||||
ret = GS_UNHANDLED;
|
||||
break;
|
||||
|
@ -6361,6 +6459,10 @@ gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
|
|||
ret = gimplify_compound_expr (expr_p, pre_p, fallback != fb_none);
|
||||
break;
|
||||
|
||||
case COMPOUND_LITERAL_EXPR:
|
||||
ret = gimplify_compound_literal_expr (expr_p, pre_p);
|
||||
break;
|
||||
|
||||
case MODIFY_EXPR:
|
||||
case INIT_EXPR:
|
||||
ret = gimplify_modify_expr (expr_p, pre_p, post_p,
|
||||
|
|
|
@ -46,12 +46,10 @@ extern tree lhd_return_null_tree_v (void);
|
|||
extern tree lhd_return_null_tree (tree);
|
||||
extern tree lhd_return_null_const_tree (const_tree);
|
||||
extern tree lhd_do_nothing_iii_return_null_tree (int, int, int);
|
||||
extern tree lhd_staticp (tree);
|
||||
extern void lhd_print_tree_nothing (FILE *, tree, int);
|
||||
extern const char *lhd_decl_printable_name (tree, int);
|
||||
extern const char *lhd_dwarf_name (tree, int);
|
||||
extern int lhd_types_compatible_p (tree, tree);
|
||||
extern rtx lhd_expand_expr (tree, rtx, enum machine_mode, int, rtx *);
|
||||
extern void lhd_print_error_function (struct diagnostic_context *,
|
||||
const char *, struct diagnostic_info *);
|
||||
extern void lhd_set_decl_assembler_name (tree);
|
||||
|
@ -92,9 +90,7 @@ extern void lhd_omp_firstprivatize_type_sizes (struct gimplify_omp_ctx *,
|
|||
#define LANG_HOOKS_POST_OPTIONS lhd_post_options
|
||||
#define LANG_HOOKS_MISSING_NORETURN_OK_P hook_bool_tree_true
|
||||
#define LANG_HOOKS_GET_ALIAS_SET lhd_get_alias_set
|
||||
#define LANG_HOOKS_EXPAND_EXPR lhd_expand_expr
|
||||
#define LANG_HOOKS_FINISH_INCOMPLETE_DECL lhd_do_nothing_t
|
||||
#define LANG_HOOKS_STATICP lhd_staticp
|
||||
#define LANG_HOOKS_DUP_LANG_SPECIFIC_DECL lhd_do_nothing_t
|
||||
#define LANG_HOOKS_SET_DECL_ASSEMBLER_NAME lhd_set_decl_assembler_name
|
||||
#define LANG_HOOKS_PRINT_STATISTICS lhd_do_nothing
|
||||
|
@ -241,10 +237,8 @@ extern tree lhd_make_node (enum tree_code);
|
|||
LANG_HOOKS_PARSE_FILE, \
|
||||
LANG_HOOKS_MISSING_NORETURN_OK_P, \
|
||||
LANG_HOOKS_GET_ALIAS_SET, \
|
||||
LANG_HOOKS_EXPAND_EXPR, \
|
||||
LANG_HOOKS_FINISH_INCOMPLETE_DECL, \
|
||||
LANG_HOOKS_MARK_ADDRESSABLE, \
|
||||
LANG_HOOKS_STATICP, \
|
||||
LANG_HOOKS_DUP_LANG_SPECIFIC_DECL, \
|
||||
LANG_HOOKS_SET_DECL_ASSEMBLER_NAME, \
|
||||
LANG_HOOKS_PRINT_STATISTICS, \
|
||||
|
|
|
@ -117,14 +117,6 @@ lhd_print_tree_nothing (FILE * ARG_UNUSED (file),
|
|||
{
|
||||
}
|
||||
|
||||
/* Called from staticp. */
|
||||
|
||||
tree
|
||||
lhd_staticp (tree ARG_UNUSED (exp))
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Called from check_global_declarations. */
|
||||
|
||||
bool
|
||||
|
@ -216,17 +208,6 @@ lhd_get_alias_set (tree ARG_UNUSED (t))
|
|||
return -1;
|
||||
}
|
||||
|
||||
/* This is the default expand_expr function. */
|
||||
|
||||
rtx
|
||||
lhd_expand_expr (tree ARG_UNUSED (t), rtx ARG_UNUSED (r),
|
||||
enum machine_mode ARG_UNUSED (mm),
|
||||
int ARG_UNUSED (em),
|
||||
rtx * ARG_UNUSED (a))
|
||||
{
|
||||
gcc_unreachable ();
|
||||
}
|
||||
|
||||
/* This is the default decl_printable_name function. */
|
||||
|
||||
const char *
|
||||
|
|
|
@ -293,10 +293,6 @@ struct lang_hooks
|
|||
Returns -1 if the language does nothing special for it. */
|
||||
alias_set_type (*get_alias_set) (tree);
|
||||
|
||||
/* Called by expand_expr for language-specific tree codes.
|
||||
Fourth argument is actually an enum expand_modifier. */
|
||||
rtx (*expand_expr) (tree, rtx, enum machine_mode, int, rtx *);
|
||||
|
||||
/* Function to finish handling an incomplete decl at the end of
|
||||
compilation. Default hook is does nothing. */
|
||||
void (*finish_incomplete_decl) (tree);
|
||||
|
@ -306,9 +302,6 @@ struct lang_hooks
|
|||
successful. */
|
||||
bool (*mark_addressable) (tree);
|
||||
|
||||
/* Hook called by staticp for language-specific tree codes. */
|
||||
tree (*staticp) (tree);
|
||||
|
||||
/* Replace the DECL_LANG_SPECIFIC data, which may be NULL, of the
|
||||
DECL_NODE with a newly GC-allocated copy. */
|
||||
void (*dup_lang_specific_decl) (tree);
|
||||
|
|
14
gcc/tree.c
14
gcc/tree.c
|
@ -2098,8 +2098,7 @@ staticp (tree arg)
|
|||
case COMPONENT_REF:
|
||||
/* If the thing being referenced is not a field, then it is
|
||||
something language specific. */
|
||||
if (TREE_CODE (TREE_OPERAND (arg, 1)) != FIELD_DECL)
|
||||
return (*lang_hooks.staticp) (arg);
|
||||
gcc_assert (TREE_CODE (TREE_OPERAND (arg, 1)) == FIELD_DECL);
|
||||
|
||||
/* If we are referencing a bitfield, we can't evaluate an
|
||||
ADDR_EXPR at compile time and so it isn't a constant. */
|
||||
|
@ -2122,14 +2121,13 @@ staticp (tree arg)
|
|||
&& TREE_CODE (TREE_OPERAND (arg, 1)) == INTEGER_CST)
|
||||
return staticp (TREE_OPERAND (arg, 0));
|
||||
else
|
||||
return false;
|
||||
return NULL;
|
||||
|
||||
case COMPOUND_LITERAL_EXPR:
|
||||
return TREE_STATIC (COMPOUND_LITERAL_EXPR_DECL (arg)) ? arg : NULL;
|
||||
|
||||
default:
|
||||
if ((unsigned int) TREE_CODE (arg)
|
||||
>= (unsigned int) LAST_AND_UNUSED_TREE_CODE)
|
||||
return lang_hooks.staticp (arg);
|
||||
else
|
||||
return NULL;
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -786,6 +786,13 @@ DEFTREECODE (NON_LVALUE_EXPR, "non_lvalue_expr", tcc_unary, 1)
|
|||
generating insns. */
|
||||
DEFTREECODE (VIEW_CONVERT_EXPR, "view_convert_expr", tcc_reference, 1)
|
||||
|
||||
/* A COMPOUND_LITERAL_EXPR represents a literal that is placed in a DECL. The
|
||||
COMPOUND_LITERAL_EXPR_DECL_EXPR is the a DECL_EXPR containing the decl
|
||||
for the anonymous object represented by the COMPOUND_LITERAL;
|
||||
the DECL_INITIAL of that decl is the CONSTRUCTOR that initializes
|
||||
the compound literal. */
|
||||
DEFTREECODE (COMPOUND_LITERAL_EXPR, "compound_literal_expr", tcc_expression, 1)
|
||||
|
||||
/* Represents something we computed once and will use multiple times.
|
||||
First operand is that expression. After it is evaluated once, it
|
||||
will be replaced by the temporary variable that holds the value. */
|
||||
|
|
|
@ -1590,6 +1590,12 @@ extern void protected_set_expr_location (tree, location_t);
|
|||
|
||||
#define EXIT_EXPR_COND(NODE) TREE_OPERAND (EXIT_EXPR_CHECK (NODE), 0)
|
||||
|
||||
/* COMPOUND_LITERAL_EXPR accessors. */
|
||||
#define COMPOUND_LITERAL_EXPR_DECL_EXPR(NODE) \
|
||||
TREE_OPERAND (COMPOUND_LITERAL_EXPR_CHECK (NODE), 0)
|
||||
#define COMPOUND_LITERAL_EXPR_DECL(NODE) \
|
||||
DECL_EXPR_DECL (COMPOUND_LITERAL_EXPR_DECL_EXPR (NODE))
|
||||
|
||||
/* SWITCH_EXPR accessors. These give access to the condition, body and
|
||||
original condition type (before any compiler conversions)
|
||||
of the switch statement, respectively. */
|
||||
|
|
Loading…
Add table
Reference in a new issue