Commit 0fab64a3 by Mark Mitchell Committed by Mark Mitchell

expr.h (expand_expr): Make it a macro, not a function.

	* expr.h (expand_expr): Make it a macro, not a function.
	(expand_expr_real): New function.
	* expr.c (store_expr): Adjust logic for deciding whether or not to
	copy the value returned by expand_expr.
	(expand_expr): Rename to ...
	(expand_expr_real): ... this.  Add alt_rtl parameter.  Adjust
	calls to language hooks.
	* c-common.h (c_expand_expr): Adjust prototype.
	* c-common.c (c_expand_expr): Add alt_rtl parameter.
	* langhooks-def.h (lhd_expand_expr): Change prototype.
	* langhooks.c (lhd_expand_expr): Add all_rtl parameter.
	* langhooks.h (lang_hooks): Change type of expand_expr.
	* stmt.c (stmt_status): Add x_last_expr_alt_rtl.
	(last_expr_alt_rtl): Likewise.
	(expand_expr_stmt_value): Set last_expr_alt_rtl.
	(clear_last_expr): Clear it.
	(expand_end_stmt_expr): Set RTL_EXPR_ATL_RTL.
	(expand_end_bindings): Save and restor last_expr_alt_rtl.
	* tree.def (RTL_EXPR): Give it an additional operand.
	* tree.h (RTL_EXPR_ALT_RTL): New macro.

	* misc.c (gnat_expand_expr): Add alt_rtl parameter.

	* cp-tree.h (cxx_expand_expr): Change prototype.
	* expr.c (cxx_expand_expr): Add alt_rtl parameter.

	* java-tree.h (java_expand_expr): Change prototype.
	* expr.c (java_expand_expr): Add alt_rtl parameter.

From-SVN: r75594
parent 2fca049f
2004-01-09 Mark Mitchell <mark@codesourcery.com>
* expr.h (expand_expr): Make it a macro, not a function.
(expand_expr_real): New function.
* expr.c (store_expr): Adjust logic for deciding whether or not to
copy the value returned by expand_expr.
(expand_expr): Rename to ...
(expand_expr_real): ... this. Add alt_rtl parameter. Adjust
calls to language hooks.
* c-common.h (c_expand_expr): Adjust prototype.
* c-common.c (c_expand_expr): Add alt_rtl parameter.
* langhooks-def.h (lhd_expand_expr): Change prototype.
* langhooks.c (lhd_expand_expr): Add all_rtl parameter.
* langhooks.h (lang_hooks): Change type of expand_expr.
* stmt.c (stmt_status): Add x_last_expr_alt_rtl.
(last_expr_alt_rtl): Likewise.
(expand_expr_stmt_value): Set last_expr_alt_rtl.
(clear_last_expr): Clear it.
(expand_end_stmt_expr): Set RTL_EXPR_ATL_RTL.
(expand_end_bindings): Save and restor last_expr_alt_rtl.
* tree.def (RTL_EXPR): Give it an additional operand.
* tree.h (RTL_EXPR_ALT_RTL): New macro.
2004-01-09 Kazuhiro Inaoka <inaoka.kazuhiro@renesas.com> 2004-01-09 Kazuhiro Inaoka <inaoka.kazuhiro@renesas.com>
* config/m32r/m32r.h (TARGET_CPU_CPP_BUILTINS): Add __m32r__. * config/m32r/m32r.h (TARGET_CPU_CPP_BUILTINS): Add __m32r__.
......
2004-01-09 Mark Mitchell <mark@codesourcery.com>
* misc.c (gnat_expand_expr): Add alt_rtl parameter.
2004-01-07 Rainer Orth <ro@TechFak.Uni-Bielefeld.DE> 2004-01-07 Rainer Orth <ro@TechFak.Uni-Bielefeld.DE>
* link.c [sgi] (shared_libgnat_default): Change to STATIC. * link.c [sgi] (shared_libgnat_default): Change to STATIC.
......
...@@ -96,7 +96,8 @@ static const char *gnat_printable_name (tree, int); ...@@ -96,7 +96,8 @@ static const char *gnat_printable_name (tree, int);
static tree gnat_eh_runtime_type (tree); static tree gnat_eh_runtime_type (tree);
static int gnat_eh_type_covers (tree, tree); static int gnat_eh_type_covers (tree, tree);
static void gnat_parse_file (int); static void gnat_parse_file (int);
static rtx gnat_expand_expr (tree, rtx, enum machine_mode, int); static rtx gnat_expand_expr (tree, rtx, enum machine_mode, int,
rtx *);
static void internal_error_function (const char *, va_list *); static void internal_error_function (const char *, va_list *);
static void gnat_adjust_rli (record_layout_info); static void gnat_adjust_rli (record_layout_info);
...@@ -550,7 +551,8 @@ gnat_printable_name (tree decl, int verbosity) ...@@ -550,7 +551,8 @@ gnat_printable_name (tree decl, int verbosity)
here are TRANSFORM_EXPR, ALLOCATE_EXPR, USE_EXPR and NULL_EXPR. */ here are TRANSFORM_EXPR, ALLOCATE_EXPR, USE_EXPR and NULL_EXPR. */
static rtx static rtx
gnat_expand_expr (tree exp, rtx target, enum machine_mode tmode, int modifier) gnat_expand_expr (tree exp, rtx target, enum machine_mode tmode,
int modifier, rtx *alt_rtl)
{ {
tree type = TREE_TYPE (exp); tree type = TREE_TYPE (exp);
tree new; tree new;
...@@ -606,8 +608,8 @@ gnat_expand_expr (tree exp, rtx target, enum machine_mode tmode, int modifier) ...@@ -606,8 +608,8 @@ gnat_expand_expr (tree exp, rtx target, enum machine_mode tmode, int modifier)
return target; return target;
case GNAT_NOP_EXPR: case GNAT_NOP_EXPR:
return expand_expr (build1 (NOP_EXPR, type, TREE_OPERAND (exp, 0)), return expand_expr_real (build1 (NOP_EXPR, type, TREE_OPERAND (exp, 0)),
target, tmode, modifier); target, tmode, modifier, alt_rtl);
case UNCONSTRAINED_ARRAY_REF: case UNCONSTRAINED_ARRAY_REF:
/* If we are evaluating just for side-effects, just evaluate our /* If we are evaluating just for side-effects, just evaluate our
...@@ -623,7 +625,7 @@ gnat_expand_expr (tree exp, rtx target, enum machine_mode tmode, int modifier) ...@@ -623,7 +625,7 @@ gnat_expand_expr (tree exp, rtx target, enum machine_mode tmode, int modifier)
gigi_abort (201); gigi_abort (201);
} }
return expand_expr (new, target, tmode, modifier); return expand_expr_real (new, target, tmode, modifier, alt_rtl);
} }
/* Adjusts the RLI used to layout a record after all the fields have been /* Adjusts the RLI used to layout a record after all the fields have been
......
...@@ -4054,8 +4054,9 @@ finish_label_address_expr (tree label) ...@@ -4054,8 +4054,9 @@ finish_label_address_expr (tree label)
/* Hook used by expand_expr to expand language-specific tree codes. */ /* Hook used by expand_expr to expand language-specific tree codes. */
rtx rtx
c_expand_expr (tree exp, rtx target, enum machine_mode tmode, int modifier) c_expand_expr (tree exp, rtx target, enum machine_mode tmode,
/* Actually enum_modifier. */ int modifier /* Actually enum_modifier. */,
rtx *alt_rtl)
{ {
switch (TREE_CODE (exp)) switch (TREE_CODE (exp))
{ {
...@@ -4147,7 +4148,7 @@ c_expand_expr (tree exp, rtx target, enum machine_mode tmode, int modifier) ...@@ -4147,7 +4148,7 @@ c_expand_expr (tree exp, rtx target, enum machine_mode tmode, int modifier)
literal, then return the variable. */ literal, then return the variable. */
tree decl = COMPOUND_LITERAL_EXPR_DECL (exp); tree decl = COMPOUND_LITERAL_EXPR_DECL (exp);
emit_local_var (decl); emit_local_var (decl);
return expand_expr (decl, target, tmode, modifier); return expand_expr_real (decl, target, tmode, modifier, alt_rtl);
} }
default: default:
......
...@@ -1279,7 +1279,7 @@ extern tree finish_label_address_expr (tree); ...@@ -1279,7 +1279,7 @@ extern tree finish_label_address_expr (tree);
different implementations. Used in c-common.c. */ different implementations. Used in c-common.c. */
extern tree lookup_label (tree); extern tree lookup_label (tree);
extern rtx c_expand_expr (tree, rtx, enum machine_mode, int); extern rtx c_expand_expr (tree, rtx, enum machine_mode, int, rtx *);
extern int c_safe_from_p (rtx, tree); extern int c_safe_from_p (rtx, tree);
......
2004-01-09 Mark Mitchell <mark@codesourcery.com>
* cp-tree.h (cxx_expand_expr): Change prototype.
* expr.c (cxx_expand_expr): Add alt_rtl parameter.
2004-01-08 Giovanni Bajo <giovannibajo@gcc.gnu.org> 2004-01-08 Giovanni Bajo <giovannibajo@gcc.gnu.org>
PR c++/12573 PR c++/12573
......
...@@ -3785,8 +3785,8 @@ extern tree eh_type_info (tree); ...@@ -3785,8 +3785,8 @@ extern tree eh_type_info (tree);
/* in expr.c */ /* in expr.c */
extern rtx cxx_expand_expr (tree, rtx, extern rtx cxx_expand_expr (tree, rtx,
enum machine_mode, enum machine_mode,
int); int, rtx *);
extern tree cplus_expand_constant (tree); extern tree cplus_expand_constant (tree);
/* friend.c */ /* friend.c */
......
...@@ -75,7 +75,8 @@ cplus_expand_constant (tree cst) ...@@ -75,7 +75,8 @@ cplus_expand_constant (tree cst)
/* Hook used by expand_expr to expand language-specific tree codes. */ /* Hook used by expand_expr to expand language-specific tree codes. */
rtx rtx
cxx_expand_expr (tree exp, rtx target, enum machine_mode tmode, int modifier) cxx_expand_expr (tree exp, rtx target, enum machine_mode tmode, int modifier,
rtx *alt_rtl)
{ {
tree type = TREE_TYPE (exp); tree type = TREE_TYPE (exp);
enum machine_mode mode = TYPE_MODE (type); enum machine_mode mode = TYPE_MODE (type);
...@@ -119,7 +120,7 @@ cxx_expand_expr (tree exp, rtx target, enum machine_mode tmode, int modifier) ...@@ -119,7 +120,7 @@ cxx_expand_expr (tree exp, rtx target, enum machine_mode tmode, int modifier)
modifier); modifier);
default: default:
return c_expand_expr (exp, target, tmode, modifier); return c_expand_expr (exp, target, tmode, modifier, alt_rtl);
} }
abort (); abort ();
/* NOTREACHED */ /* NOTREACHED */
......
...@@ -4026,6 +4026,7 @@ rtx ...@@ -4026,6 +4026,7 @@ rtx
store_expr (tree exp, rtx target, int want_value) store_expr (tree exp, rtx target, int want_value)
{ {
rtx temp; rtx temp;
rtx alt_rtl = NULL_RTX;
int dont_return_target = 0; int dont_return_target = 0;
int dont_store_target = 0; int dont_store_target = 0;
...@@ -4207,8 +4208,10 @@ store_expr (tree exp, rtx target, int want_value) ...@@ -4207,8 +4208,10 @@ store_expr (tree exp, rtx target, int want_value)
} }
else else
{ {
temp = expand_expr (exp, target, GET_MODE (target), temp = expand_expr_real (exp, target, GET_MODE (target),
want_value & 2 ? EXPAND_STACK_PARM : EXPAND_NORMAL); (want_value & 2
? EXPAND_STACK_PARM : EXPAND_NORMAL),
&alt_rtl);
/* Return TARGET if it's a specified hardware register. /* Return TARGET if it's a specified hardware register.
If TARGET is a volatile mem ref, either return TARGET If TARGET is a volatile mem ref, either return TARGET
or return a reg copied *from* TARGET; ANSI requires this. or return a reg copied *from* TARGET; ANSI requires this.
...@@ -4256,10 +4259,7 @@ store_expr (tree exp, rtx target, int want_value) ...@@ -4256,10 +4259,7 @@ store_expr (tree exp, rtx target, int want_value)
/* If store_expr stores a DECL whose DECL_RTL(exp) == TARGET, /* If store_expr stores a DECL whose DECL_RTL(exp) == TARGET,
but TARGET is not valid memory reference, TEMP will differ but TARGET is not valid memory reference, TEMP will differ
from TARGET although it is really the same location. */ from TARGET although it is really the same location. */
&& !(GET_CODE (target) == MEM && !(alt_rtl && rtx_equal_p (alt_rtl, target))
&& GET_CODE (XEXP (target, 0)) != QUEUED
&& (!memory_address_p (GET_MODE (target), XEXP (target, 0))
|| (flag_force_addr && !REG_P (XEXP (target, 0)))))
/* If there's nothing to copy, don't bother. Don't call expr_size /* If there's nothing to copy, don't bother. Don't call expr_size
unless necessary, because some front-ends (C++) expr_size-hook unless necessary, because some front-ends (C++) expr_size-hook
aborts on objects that are not supposed to be bit-copied or aborts on objects that are not supposed to be bit-copied or
...@@ -6200,11 +6200,17 @@ expand_operands (tree exp0, tree exp1, rtx target, rtx *op0, rtx *op1, ...@@ -6200,11 +6200,17 @@ expand_operands (tree exp0, tree exp1, rtx target, rtx *op0, rtx *op1,
marked TARGET so that it's safe from being trashed by libcalls. We marked TARGET so that it's safe from being trashed by libcalls. We
don't want to use TARGET for anything but the final result; don't want to use TARGET for anything but the final result;
Intermediate values must go elsewhere. Additionally, calls to Intermediate values must go elsewhere. Additionally, calls to
emit_block_move will be flagged with BLOCK_OP_CALL_PARM. */ emit_block_move will be flagged with BLOCK_OP_CALL_PARM.
If EXP is a VAR_DECL whose DECL_RTL was a MEM with an invalid
address, and ALT_RTL is non-NULL, then *ALT_RTL is set to the
DECL_RTL of the VAR_DECL. *ALT_RTL is also set if EXP is a
COMPOUND_EXPR whose second argument is such a VAR_DECL, and so on
recursively. */
rtx rtx
expand_expr (tree exp, rtx target, enum machine_mode tmode, expand_expr_real (tree exp, rtx target, enum machine_mode tmode,
enum expand_modifier modifier) enum expand_modifier modifier, rtx *alt_rtl)
{ {
rtx op0, op1, temp; rtx op0, op1, temp;
tree type = TREE_TYPE (exp); tree type = TREE_TYPE (exp);
...@@ -6413,8 +6419,12 @@ expand_expr (tree exp, rtx target, enum machine_mode tmode, ...@@ -6413,8 +6419,12 @@ expand_expr (tree exp, rtx target, enum machine_mode tmode,
XEXP (DECL_RTL (exp), 0)) XEXP (DECL_RTL (exp), 0))
|| (flag_force_addr || (flag_force_addr
&& GET_CODE (XEXP (DECL_RTL (exp), 0)) != REG))) && GET_CODE (XEXP (DECL_RTL (exp), 0)) != REG)))
temp = replace_equiv_address (DECL_RTL (exp), {
copy_rtx (XEXP (DECL_RTL (exp), 0))); if (alt_rtl)
*alt_rtl = DECL_RTL (exp);
temp = replace_equiv_address (DECL_RTL (exp),
copy_rtx (XEXP (DECL_RTL (exp), 0)));
}
/* If we got something, return it. But first, set the alignment /* If we got something, return it. But first, set the alignment
if the address is a register. */ if the address is a register. */
...@@ -6741,6 +6751,8 @@ expand_expr (tree exp, rtx target, enum machine_mode tmode, ...@@ -6741,6 +6751,8 @@ expand_expr (tree exp, rtx target, enum machine_mode tmode,
} }
preserve_rtl_expr_result (RTL_EXPR_RTL (exp)); preserve_rtl_expr_result (RTL_EXPR_RTL (exp));
free_temps_for_rtl_expr (exp); free_temps_for_rtl_expr (exp);
if (alt_rtl)
*alt_rtl = RTL_EXPR_ALT_RTL (exp);
return RTL_EXPR_RTL (exp); return RTL_EXPR_RTL (exp);
case CONSTRUCTOR: case CONSTRUCTOR:
...@@ -7465,7 +7477,8 @@ expand_expr (tree exp, rtx target, enum machine_mode tmode, ...@@ -7465,7 +7477,8 @@ expand_expr (tree exp, rtx target, enum machine_mode tmode,
if (DECL_BUILT_IN_CLASS (TREE_OPERAND (TREE_OPERAND (exp, 0), 0)) if (DECL_BUILT_IN_CLASS (TREE_OPERAND (TREE_OPERAND (exp, 0), 0))
== BUILT_IN_FRONTEND) == BUILT_IN_FRONTEND)
return (*lang_hooks.expand_expr) (exp, original_target, return (*lang_hooks.expand_expr) (exp, original_target,
tmode, modifier); tmode, modifier,
alt_rtl);
else else
return expand_builtin (exp, target, subtarget, tmode, ignore); return expand_builtin (exp, target, subtarget, tmode, ignore);
} }
...@@ -8228,9 +8241,9 @@ expand_expr (tree exp, rtx target, enum machine_mode tmode, ...@@ -8228,9 +8241,9 @@ expand_expr (tree exp, rtx target, enum machine_mode tmode,
case COMPOUND_EXPR: case COMPOUND_EXPR:
expand_expr (TREE_OPERAND (exp, 0), const0_rtx, VOIDmode, 0); expand_expr (TREE_OPERAND (exp, 0), const0_rtx, VOIDmode, 0);
emit_queue (); emit_queue ();
return expand_expr (TREE_OPERAND (exp, 1), return expand_expr_real (TREE_OPERAND (exp, 1),
(ignore ? const0_rtx : target), (ignore ? const0_rtx : target),
VOIDmode, modifier); VOIDmode, modifier, alt_rtl);
case COND_EXPR: case COND_EXPR:
/* If we would have a "singleton" (see below) were it not for a /* If we would have a "singleton" (see below) were it not for a
...@@ -9043,7 +9056,8 @@ expand_expr (tree exp, rtx target, enum machine_mode tmode, ...@@ -9043,7 +9056,8 @@ expand_expr (tree exp, rtx target, enum machine_mode tmode,
abort (); abort ();
default: default:
return (*lang_hooks.expand_expr) (exp, original_target, tmode, modifier); return (*lang_hooks.expand_expr) (exp, original_target, tmode, modifier,
alt_rtl);
} }
/* Here to do an ordinary binary operator, generating an instruction /* Here to do an ordinary binary operator, generating an instruction
......
...@@ -498,7 +498,10 @@ extern tree find_placeholder (tree, tree *); ...@@ -498,7 +498,10 @@ extern tree find_placeholder (tree, tree *);
/* Generate code for computing expression EXP. /* Generate code for computing expression EXP.
An rtx for the computed value is returned. The value is never null. An rtx for the computed value is returned. The value is never null.
In the case of a void EXP, const0_rtx is returned. */ In the case of a void EXP, const0_rtx is returned. */
extern rtx expand_expr (tree, rtx, enum machine_mode, enum expand_modifier); #define expand_expr(EXP, TARGET, MODE, MODIFIER) \
expand_expr_real((EXP), (TARGET), (MODE), (MODIFIER), NULL)
extern rtx expand_expr_real (tree, rtx, enum machine_mode,
enum expand_modifier, rtx *);
/* At the start of a function, record that we have no previously-pushed /* At the start of a function, record that we have no previously-pushed
arguments waiting to be popped. */ arguments waiting to be popped. */
......
2004-01-09 Mark Mitchell <mark@codesourcery.com>
* java-tree.h (java_expand_expr): Change prototype.
* expr.c (java_expand_expr): Add alt_rtl parameter.
2004-01-09 Andrew Haley <aph@redhat.com> 2004-01-09 Andrew Haley <aph@redhat.com>
PR java/12755: PR java/12755:
......
...@@ -2448,7 +2448,8 @@ get_primitive_array_vtable (tree elt) ...@@ -2448,7 +2448,8 @@ get_primitive_array_vtable (tree elt)
struct rtx_def * struct rtx_def *
java_expand_expr (tree exp, rtx target, enum machine_mode tmode, java_expand_expr (tree exp, rtx target, enum machine_mode tmode,
int modifier /* Actually an enum expand_modifier. */) int modifier /* Actually an enum expand_modifier. */,
rtx *alt_rtl ATTRIBUTE_UNUSED)
{ {
tree current; tree current;
......
...@@ -1326,7 +1326,7 @@ extern tree decl_constant_value (tree); ...@@ -1326,7 +1326,7 @@ extern tree decl_constant_value (tree);
extern void java_mark_class_local (tree); extern void java_mark_class_local (tree);
#if defined(RTX_CODE) && defined (HAVE_MACHINE_MODES) #if defined(RTX_CODE) && defined (HAVE_MACHINE_MODES)
struct rtx_def * java_expand_expr (tree, rtx, enum machine_mode, int); struct rtx_def * java_expand_expr (tree, rtx, enum machine_mode, int, rtx *);
#endif #endif
extern void java_inlining_merge_static_initializers (tree, void *); extern void java_inlining_merge_static_initializers (tree, void *);
extern void java_inlining_map_static_initializers (tree, void *); extern void java_inlining_map_static_initializers (tree, void *);
......
...@@ -55,7 +55,7 @@ extern int lhd_unsafe_for_reeval (tree); ...@@ -55,7 +55,7 @@ extern int lhd_unsafe_for_reeval (tree);
extern void lhd_clear_binding_stack (void); extern void lhd_clear_binding_stack (void);
extern void lhd_print_tree_nothing (FILE *, tree, int); extern void lhd_print_tree_nothing (FILE *, tree, int);
extern const char *lhd_decl_printable_name (tree, int); extern const char *lhd_decl_printable_name (tree, int);
extern rtx lhd_expand_expr (tree, rtx, enum machine_mode, int); extern rtx lhd_expand_expr (tree, rtx, enum machine_mode, int, rtx *);
extern void lhd_print_error_function (struct diagnostic_context *, extern void lhd_print_error_function (struct diagnostic_context *,
const char *); const char *);
extern void lhd_set_decl_assembler_name (tree); extern void lhd_set_decl_assembler_name (tree);
......
...@@ -266,7 +266,8 @@ hook_get_alias_set_0 (tree t ATTRIBUTE_UNUSED) ...@@ -266,7 +266,8 @@ hook_get_alias_set_0 (tree t ATTRIBUTE_UNUSED)
rtx rtx
lhd_expand_expr (tree t ATTRIBUTE_UNUSED, rtx r ATTRIBUTE_UNUSED, lhd_expand_expr (tree t ATTRIBUTE_UNUSED, rtx r ATTRIBUTE_UNUSED,
enum machine_mode mm ATTRIBUTE_UNUSED, enum machine_mode mm ATTRIBUTE_UNUSED,
int em ATTRIBUTE_UNUSED) int em ATTRIBUTE_UNUSED,
rtx *a ATTRIBUTE_UNUSED)
{ {
abort (); abort ();
} }
......
...@@ -283,7 +283,7 @@ struct lang_hooks ...@@ -283,7 +283,7 @@ struct lang_hooks
/* Called by expand_expr for language-specific tree codes. /* Called by expand_expr for language-specific tree codes.
Fourth argument is actually an enum expand_modifier. */ Fourth argument is actually an enum expand_modifier. */
rtx (*expand_expr) (tree, rtx, enum machine_mode, int); rtx (*expand_expr) (tree, rtx, enum machine_mode, int, rtx *);
/* Prepare expr to be an argument of a TRUTH_NOT_EXPR or other logical /* Prepare expr to be an argument of a TRUTH_NOT_EXPR or other logical
operation. operation.
......
...@@ -361,6 +361,7 @@ struct stmt_status GTY(()) ...@@ -361,6 +361,7 @@ struct stmt_status GTY(())
record the expr's type and its RTL value here. */ record the expr's type and its RTL value here. */
tree x_last_expr_type; tree x_last_expr_type;
rtx x_last_expr_value; rtx x_last_expr_value;
rtx x_last_expr_alt_rtl;
/* Nonzero if within a ({...}) grouping, in which case we must /* Nonzero if within a ({...}) grouping, in which case we must
always compute a value for each expr-stmt in case it is the last one. */ always compute a value for each expr-stmt in case it is the last one. */
...@@ -383,6 +384,7 @@ struct stmt_status GTY(()) ...@@ -383,6 +384,7 @@ struct stmt_status GTY(())
#define current_block_start_count (cfun->stmt->x_block_start_count) #define current_block_start_count (cfun->stmt->x_block_start_count)
#define last_expr_type (cfun->stmt->x_last_expr_type) #define last_expr_type (cfun->stmt->x_last_expr_type)
#define last_expr_value (cfun->stmt->x_last_expr_value) #define last_expr_value (cfun->stmt->x_last_expr_value)
#define last_expr_alt_rtl (cfun->stmt->x_last_expr_alt_rtl)
#define expr_stmts_for_value (cfun->stmt->x_expr_stmts_for_value) #define expr_stmts_for_value (cfun->stmt->x_expr_stmts_for_value)
#define emit_locus (cfun->stmt->x_emit_locus) #define emit_locus (cfun->stmt->x_emit_locus)
#define goto_fixup_chain (cfun->stmt->x_goto_fixup_chain) #define goto_fixup_chain (cfun->stmt->x_goto_fixup_chain)
...@@ -2140,6 +2142,7 @@ expand_expr_stmt_value (tree exp, int want_value, int maybe_last) ...@@ -2140,6 +2142,7 @@ expand_expr_stmt_value (tree exp, int want_value, int maybe_last)
{ {
rtx value; rtx value;
tree type; tree type;
rtx alt_rtl = NULL;
if (want_value == -1) if (want_value == -1)
want_value = expr_stmts_for_value != 0; want_value = expr_stmts_for_value != 0;
...@@ -2166,8 +2169,8 @@ expand_expr_stmt_value (tree exp, int want_value, int maybe_last) ...@@ -2166,8 +2169,8 @@ expand_expr_stmt_value (tree exp, int want_value, int maybe_last)
/* The call to `expand_expr' could cause last_expr_type and /* The call to `expand_expr' could cause last_expr_type and
last_expr_value to get reset. Therefore, we set last_expr_value last_expr_value to get reset. Therefore, we set last_expr_value
and last_expr_type *after* calling expand_expr. */ and last_expr_type *after* calling expand_expr. */
value = expand_expr (exp, want_value ? NULL_RTX : const0_rtx, value = expand_expr_real (exp, want_value ? NULL_RTX : const0_rtx,
VOIDmode, 0); VOIDmode, 0, &alt_rtl);
type = TREE_TYPE (exp); type = TREE_TYPE (exp);
/* If all we do is reference a volatile value in memory, /* If all we do is reference a volatile value in memory,
...@@ -2203,6 +2206,7 @@ expand_expr_stmt_value (tree exp, int want_value, int maybe_last) ...@@ -2203,6 +2206,7 @@ expand_expr_stmt_value (tree exp, int want_value, int maybe_last)
if (want_value) if (want_value)
{ {
last_expr_value = value; last_expr_value = value;
last_expr_alt_rtl = alt_rtl;
last_expr_type = type; last_expr_type = type;
} }
...@@ -2322,6 +2326,7 @@ clear_last_expr (void) ...@@ -2322,6 +2326,7 @@ clear_last_expr (void)
{ {
last_expr_type = NULL_TREE; last_expr_type = NULL_TREE;
last_expr_value = NULL_RTX; last_expr_value = NULL_RTX;
last_expr_alt_rtl = NULL_RTX;
} }
/* Begin a statement-expression, i.e., a series of statements which /* Begin a statement-expression, i.e., a series of statements which
...@@ -2369,6 +2374,7 @@ expand_end_stmt_expr (tree t) ...@@ -2369,6 +2374,7 @@ expand_end_stmt_expr (tree t)
if (! last_expr_value || ! last_expr_type) if (! last_expr_value || ! last_expr_type)
{ {
last_expr_value = const0_rtx; last_expr_value = const0_rtx;
last_expr_alt_rtl = NULL_RTX;
last_expr_type = void_type_node; last_expr_type = void_type_node;
} }
else if (GET_CODE (last_expr_value) != REG && ! CONSTANT_P (last_expr_value)) else if (GET_CODE (last_expr_value) != REG && ! CONSTANT_P (last_expr_value))
...@@ -2379,6 +2385,7 @@ expand_end_stmt_expr (tree t) ...@@ -2379,6 +2385,7 @@ expand_end_stmt_expr (tree t)
TREE_TYPE (t) = last_expr_type; TREE_TYPE (t) = last_expr_type;
RTL_EXPR_RTL (t) = last_expr_value; RTL_EXPR_RTL (t) = last_expr_value;
RTL_EXPR_ALT_RTL (t) = last_expr_alt_rtl;
RTL_EXPR_SEQUENCE (t) = get_insns (); RTL_EXPR_SEQUENCE (t) = get_insns ();
rtl_expr_chain = tree_cons (NULL_TREE, t, rtl_expr_chain); rtl_expr_chain = tree_cons (NULL_TREE, t, rtl_expr_chain);
...@@ -3801,6 +3808,7 @@ expand_end_bindings (tree vars, int mark_ends, int dont_jump_in) ...@@ -3801,6 +3808,7 @@ expand_end_bindings (tree vars, int mark_ends, int dont_jump_in)
/* Don't let cleanups affect ({...}) constructs. */ /* Don't let cleanups affect ({...}) constructs. */
int old_expr_stmts_for_value = expr_stmts_for_value; int old_expr_stmts_for_value = expr_stmts_for_value;
rtx old_last_expr_value = last_expr_value; rtx old_last_expr_value = last_expr_value;
rtx old_last_expr_alt_rtl = last_expr_alt_rtl;
tree old_last_expr_type = last_expr_type; tree old_last_expr_type = last_expr_type;
expr_stmts_for_value = 0; expr_stmts_for_value = 0;
...@@ -3817,6 +3825,7 @@ expand_end_bindings (tree vars, int mark_ends, int dont_jump_in) ...@@ -3817,6 +3825,7 @@ expand_end_bindings (tree vars, int mark_ends, int dont_jump_in)
expr_stmts_for_value = old_expr_stmts_for_value; expr_stmts_for_value = old_expr_stmts_for_value;
last_expr_value = old_last_expr_value; last_expr_value = old_last_expr_value;
last_expr_alt_rtl = old_last_expr_alt_rtl;
last_expr_type = old_last_expr_type; last_expr_type = old_last_expr_type;
/* Restore the stack level. */ /* Restore the stack level. */
......
...@@ -730,11 +730,15 @@ DEFTREECODE (UNSAVE_EXPR, "unsave_expr", 'e', 1) ...@@ -730,11 +730,15 @@ DEFTREECODE (UNSAVE_EXPR, "unsave_expr", 'e', 1)
/* Represents something whose RTL has already been expanded as a /* Represents something whose RTL has already been expanded as a
sequence which should be emitted when this expression is expanded. sequence which should be emitted when this expression is expanded.
The first operand is the RTL to emit. It is the first of a chain The first operand is the RTL to emit. It is the first of a chain
of insns. The second is the RTL expression for the result. Any of insns. The second is the RTL expression for the result. The
temporaries created during the building of the RTL_EXPR can be third operand is the "alternate RTL expression" for the result, if
reused once the RTL_EXPR has been expanded, with the exception of any; if the second argument is the DECL_RTL for a VAR_DECL, but
the RTL_EXPR_RTL. */ with an invalid memory address replaced by a valid one, then the
DEFTREECODE (RTL_EXPR, "rtl_expr", 'e', 2) third operand will be the original DECL_RTL. Any temporaries
created during the building of the RTL_EXPR can be reused once the
RTL_EXPR has been expanded, with the exception of the
RTL_EXPR_RTL. */
DEFTREECODE (RTL_EXPR, "rtl_expr", 'e', 3)
/* & in C. Value is the address at which the operand's value resides. /* & in C. Value is the address at which the operand's value resides.
Operand may have any mode. Result mode is Pmode. */ Operand may have any mode. Result mode is Pmode. */
......
...@@ -794,6 +794,7 @@ struct tree_vec GTY(()) ...@@ -794,6 +794,7 @@ struct tree_vec GTY(())
/* In a RTL_EXPR node. */ /* In a RTL_EXPR node. */
#define RTL_EXPR_SEQUENCE(NODE) TREE_RTL_OPERAND_CHECK (NODE, RTL_EXPR, 0) #define RTL_EXPR_SEQUENCE(NODE) TREE_RTL_OPERAND_CHECK (NODE, RTL_EXPR, 0)
#define RTL_EXPR_RTL(NODE) TREE_RTL_OPERAND_CHECK (NODE, RTL_EXPR, 1) #define RTL_EXPR_RTL(NODE) TREE_RTL_OPERAND_CHECK (NODE, RTL_EXPR, 1)
#define RTL_EXPR_ALT_RTL(NODE) TREE_RTL_OPERAND_CHECK (NODE, RTL_EXPR, 2)
/* In a WITH_CLEANUP_EXPR node. */ /* In a WITH_CLEANUP_EXPR node. */
#define WITH_CLEANUP_EXPR_RTL(NODE) \ #define WITH_CLEANUP_EXPR_RTL(NODE) \
......
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