Commit 1574ef13 by Alexandre Oliva Committed by Alexandre Oliva

c-common.h (genrtl_expr_stmt_value): Declare.

* c-common.h (genrtl_expr_stmt_value): Declare.
* c-semantics.c (genrtl_goto_stmt): Redirect to...
(genrtl_goto_stmt_value): ... this new function.  Pass new
argument down to expand_expr_stmt_value, taking
TREE_ADDRESSABLE into account.
* c-common.c (c_expand_expr): Mark the last EXPR_STMT of a
STMT_EXPR as addressable, i.e., one whose result we want.
* expr.c (expand_expr): Don't save expression statement value
of labeled_blocks or loop_exprs.
* stmt.c (expand_expr_stmt): Redirect to...
(expand_expr_stmt_value): ... this new function.  Use new
argument to tell whether to save expression value.
(expand_end_stmt_expr): Reset last_expr_type and
last_expr_value if we don't have either.
* tree-inline.c (declare_return_variable): Mark its use
statement as addressable.
* tree.h: Document new use of TREE_ADDRESSABLE.
(expand_expr_stmt_value): Declare.

From-SVN: r48456
parent 6180abdb
2002-01-02 Alexandre Oliva <aoliva@redhat.com>
* c-common.h (genrtl_expr_stmt_value): Declare.
* c-semantics.c (genrtl_goto_stmt): Redirect to...
(genrtl_goto_stmt_value): ... this new function. Pass new
argument down to expand_expr_stmt_value, taking
TREE_ADDRESSABLE into account.
* c-common.c (c_expand_expr): Mark the last EXPR_STMT of a
STMT_EXPR as addressable, i.e., one whose result we want.
* expr.c (expand_expr): Don't save expression statement value
of labeled_blocks or loop_exprs.
* stmt.c (expand_expr_stmt): Redirect to...
(expand_expr_stmt_value): ... this new function. Use new
argument to tell whether to save expression value.
(expand_end_stmt_expr): Reset last_expr_type and
last_expr_value if we don't have either.
* tree-inline.c (declare_return_variable): Mark its use
statement as addressable.
* tree.h: Document new use of TREE_ADDRESSABLE.
(expand_expr_stmt_value): Declare.
2002-01-01 Joseph S. Myers <jsm28@cam.ac.uk>
* configure.in: Prepend ${srcdir}/config/${cpu_type}/ instead of
......
/* Subroutines shared by all languages that are variants of C.
Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001
Free Software Foundation, Inc.
Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
2001, 2002 Free Software Foundation, Inc.
This file is part of GCC.
......@@ -3418,6 +3418,27 @@ c_expand_expr (exp, target, tmode, modifier)
STMT_EXPR. */
push_temp_slots ();
rtl_expr = expand_start_stmt_expr ();
/* If we want the result of this expression, find the last
EXPR_STMT in the COMPOUND_STMT and mark it as addressable. */
if (target != const0_rtx
&& TREE_CODE (STMT_EXPR_STMT (exp)) == COMPOUND_STMT
&& TREE_CODE (COMPOUND_BODY (STMT_EXPR_STMT (exp))) == SCOPE_STMT)
{
tree expr = COMPOUND_BODY (STMT_EXPR_STMT (exp));
tree last = TREE_CHAIN (expr);
while (TREE_CHAIN (last))
{
expr = last;
last = TREE_CHAIN (last);
}
if (TREE_CODE (last) == SCOPE_STMT
&& TREE_CODE (expr) == EXPR_STMT)
TREE_ADDRESSABLE (expr) = 1;
}
expand_stmt (STMT_EXPR_STMT (exp));
expand_end_stmt_expr (rtl_expr);
result = expand_expr (rtl_expr, target, tmode, modifier);
......
/* Definitions for c-common.c.
Copyright (C) 1987, 1993, 1994, 1995, 1997, 1998,
1999, 2000, 2001 Free Software Foundation, Inc.
1999, 2000, 2001, 2002 Free Software Foundation, Inc.
This file is part of GCC.
......@@ -717,6 +717,7 @@ extern void add_c_tree_codes PARAMS ((void));
extern void genrtl_do_pushlevel PARAMS ((void));
extern void genrtl_goto_stmt PARAMS ((tree));
extern void genrtl_expr_stmt PARAMS ((tree));
extern void genrtl_expr_stmt_value PARAMS ((tree, int));
extern void genrtl_decl_stmt PARAMS ((tree));
extern void genrtl_if_stmt PARAMS ((tree));
extern void genrtl_while_stmt PARAMS ((tree));
......
/* 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).
Copyright (C) 2000, 2001 Free Software Foundation, Inc.
Copyright (C) 2000, 2001, 2002 Free Software Foundation, Inc.
Written by Benjamin Chelf (chelf@codesourcery.com).
This file is part of GCC.
......@@ -305,12 +305,27 @@ genrtl_goto_stmt (destination)
expand_computed_goto (destination);
}
/* Generate the RTL for EXPR, which is an EXPR_STMT. */
/* Generate the RTL for EXPR, which is an EXPR_STMT. Provided just
for backward compatibility. genrtl_expr_stmt_value() should be
used for new code. */
void
void
genrtl_expr_stmt (expr)
tree expr;
{
genrtl_expr_stmt_value (expr, -1);
}
/* Generate the RTL for EXPR, which is an EXPR_STMT. WANT_VALUE tells
whether to (1) save the value of the expression, (0) discard it or
(-1) use expr_stmts_for_value to tell. The use of -1 is
deprecated, and retained only for backward compatibility. */
void
genrtl_expr_stmt_value (expr, want_value)
tree expr;
int want_value;
{
if (expr != NULL_TREE)
{
emit_line_note (input_filename, lineno);
......@@ -319,7 +334,7 @@ genrtl_expr_stmt (expr)
expand_start_target_temps ();
if (expr != error_mark_node)
expand_expr_stmt (expr);
expand_expr_stmt_value (expr, want_value);
if (stmts_are_full_exprs_p ())
expand_end_target_temps ();
......@@ -748,7 +763,7 @@ expand_stmt (t)
break;
case EXPR_STMT:
genrtl_expr_stmt (EXPR_STMT_EXPR (t));
genrtl_expr_stmt_value (EXPR_STMT_EXPR (t), TREE_ADDRESSABLE (t));
break;
case DECL_STMT:
......
/* Convert tree expression to rtl instructions, for GNU compiler.
Copyright (C) 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
2000, 2001 Free Software Foundation, Inc.
2000, 2001, 2002 Free Software Foundation, Inc.
This file is part of GCC.
......@@ -6453,7 +6453,7 @@ expand_expr (exp, target, tmode, modifier)
case LABELED_BLOCK_EXPR:
if (LABELED_BLOCK_BODY (exp))
expand_expr_stmt (LABELED_BLOCK_BODY (exp));
expand_expr_stmt_value (LABELED_BLOCK_BODY (exp), 0);
/* Should perhaps use expand_label, but this is simpler and safer. */
do_pending_stack_adjust ();
emit_label (label_rtx (LABELED_BLOCK_LABEL (exp)));
......@@ -6468,7 +6468,7 @@ expand_expr (exp, target, tmode, modifier)
case LOOP_EXPR:
push_temp_slots ();
expand_start_loop (1);
expand_expr_stmt (TREE_OPERAND (exp, 0));
expand_expr_stmt_value (TREE_OPERAND (exp, 0), 0);
expand_end_loop ();
pop_temp_slots ();
......
/* Expands front end tree to back end RTL for GNU C-Compiler
Copyright (C) 1987, 1988, 1989, 1992, 1993, 1994, 1995, 1996, 1997,
1998, 1999, 2000, 2001 Free Software Foundation, Inc.
1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
This file is part of GCC.
......@@ -2182,16 +2182,37 @@ resolve_operand_name_1 (p, outputs, inputs)
}
/* Generate RTL to evaluate the expression EXP
and remember it in case this is the VALUE in a ({... VALUE; }) constr. */
and remember it in case this is the VALUE in a ({... VALUE; }) constr.
Provided just for backward-compatibility. expand_expr_stmt_value()
should be used for new code. */
void
expand_expr_stmt (exp)
tree exp;
{
expand_expr_stmt_value (exp, -1);
}
/* Generate RTL to evaluate the expression EXP. WANT_VALUE tells
whether to (1) save the value of the expression, (0) discard it or
(-1) use expr_stmts_for_value to tell. The use of -1 is
deprecated, and retained only for backward compatibility. */
void
expand_expr_stmt_value (exp, want_value)
tree exp;
int want_value;
{
rtx value;
tree type;
if (want_value == -1)
want_value = expr_stmts_for_value != 0;
/* If -W, warn about statements with no side effects,
except for an explicit cast to void (e.g. for assert()), and
except inside a ({...}) where they may be useful. */
if (expr_stmts_for_value == 0 && exp != error_mark_node)
if (! want_value && exp != error_mark_node)
{
if (! TREE_SIDE_EFFECTS (exp))
{
......@@ -2207,34 +2228,31 @@ expand_expr_stmt (exp)
/* If EXP is of function type and we are expanding statements for
value, convert it to pointer-to-function. */
if (expr_stmts_for_value && TREE_CODE (TREE_TYPE (exp)) == FUNCTION_TYPE)
if (want_value && TREE_CODE (TREE_TYPE (exp)) == FUNCTION_TYPE)
exp = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (exp)), exp);
/* The call to `expand_expr' could cause last_expr_type and
last_expr_value to get reset. Therefore, we set last_expr_value
and last_expr_type *after* calling expand_expr. */
last_expr_value = expand_expr (exp,
(expr_stmts_for_value
? NULL_RTX : const0_rtx),
VOIDmode, 0);
last_expr_type = TREE_TYPE (exp);
value = expand_expr (exp, want_value ? NULL_RTX : const0_rtx,
VOIDmode, 0);
type = TREE_TYPE (exp);
/* If all we do is reference a volatile value in memory,
copy it to a register to be sure it is actually touched. */
if (last_expr_value != 0 && GET_CODE (last_expr_value) == MEM
&& TREE_THIS_VOLATILE (exp))
if (value && GET_CODE (value) == MEM && TREE_THIS_VOLATILE (exp))
{
if (TYPE_MODE (TREE_TYPE (exp)) == VOIDmode)
if (TYPE_MODE (type) == VOIDmode)
;
else if (TYPE_MODE (TREE_TYPE (exp)) != BLKmode)
copy_to_reg (last_expr_value);
else if (TYPE_MODE (type) != BLKmode)
value = copy_to_reg (value);
else
{
rtx lab = gen_label_rtx ();
/* Compare the value with itself to reference it. */
emit_cmp_and_jump_insns (last_expr_value, last_expr_value, EQ,
expand_expr (TYPE_SIZE (last_expr_type),
emit_cmp_and_jump_insns (value, value, EQ,
expand_expr (TYPE_SIZE (type),
NULL_RTX, VOIDmode, 0),
BLKmode, 0, lab);
emit_label (lab);
......@@ -2243,13 +2261,19 @@ expand_expr_stmt (exp)
/* If this expression is part of a ({...}) and is in memory, we may have
to preserve temporaries. */
preserve_temp_slots (last_expr_value);
preserve_temp_slots (value);
/* Free any temporaries used to evaluate this expression. Any temporary
used as a result of this expression will already have been preserved
above. */
free_temp_slots ();
if (want_value)
{
last_expr_value = value;
last_expr_type = type;
}
emit_queue ();
}
......@@ -2386,6 +2410,7 @@ expand_start_stmt_expr ()
start_sequence_for_rtl_expr (t);
NO_DEFER_POP;
expr_stmts_for_value++;
last_expr_value = NULL_RTX;
return t;
}
......@@ -2407,15 +2432,11 @@ expand_end_stmt_expr (t)
{
OK_DEFER_POP;
if (last_expr_type == 0)
if (! last_expr_value || ! last_expr_type)
{
last_expr_type = void_type_node;
last_expr_value = const0_rtx;
last_expr_type = void_type_node;
}
else if (last_expr_value == 0)
/* There are some cases where this can happen, such as when the
statement is void type. */
last_expr_value = const0_rtx;
else if (GET_CODE (last_expr_value) != REG && ! CONSTANT_P (last_expr_value))
/* Remove any possible QUEUED. */
last_expr_value = protect_from_queue (last_expr_value, 0);
......
/* Control and data flow functions for trees.
Copyright 2001 Free Software Foundation, Inc.
Copyright 2001, 2002 Free Software Foundation, Inc.
Contributed by Alexandre Oliva <aoliva@redhat.com>
This file is part of GNU CC.
......@@ -624,7 +624,9 @@ declare_return_variable (id, use_stmt)
*use_stmt = build_stmt (EXPR_STMT,
build1 (NOP_EXPR, TREE_TYPE (TREE_TYPE (fn)),
var));
TREE_ADDRESSABLE (*use_stmt) = 1;
/* Build the declaration statement if FN does not return an
aggregate. */
if (need_return_decl)
......
/* Front-end tree definitions for GNU compiler.
Copyright (C) 1989, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001
Free Software Foundation, Inc.
Copyright (C) 1989, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
2001, 2002 Free Software Foundation, Inc.
This file is part of GCC.
......@@ -161,7 +161,9 @@ struct tree_common
TREE_ADDRESSABLE in
VAR_DECL, FUNCTION_DECL, FIELD_DECL, CONSTRUCTOR, LABEL_DECL,
..._TYPE, IDENTIFIER_NODE
..._TYPE, IDENTIFIER_NODE.
In a STMT_EXPR, it means we want the result of the enclosed
expression.
static_flag:
......@@ -258,8 +260,7 @@ struct tree_common
expressions, VAR_DECL, PARM_DECL, FIELD_DECL, FUNCTION_DECL,
IDENTIFIER_NODE
TYPE_BOUNDED in
..._TYPE
*/
..._TYPE */
/* Define accessors for the fields that all tree nodes have
(though some fields are not used for all kinds of nodes). */
......@@ -2719,6 +2720,7 @@ extern void expand_fixups PARAMS ((rtx));
extern tree expand_start_stmt_expr PARAMS ((void));
extern tree expand_end_stmt_expr PARAMS ((tree));
extern void expand_expr_stmt PARAMS ((tree));
extern void expand_expr_stmt_value PARAMS ((tree, int));
extern int warn_if_unused_value PARAMS ((tree));
extern void expand_decl_init PARAMS ((tree));
extern void clear_last_expr PARAMS ((void));
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment