aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorMark Mitchell <mark@codesourcery.com>2004-01-09 19:55:13 +0000
committerMark Mitchell <mmitchel@gcc.gnu.org>2004-01-09 19:55:13 +0000
commit0fab64a344486770d0acc827ab6b670543d58a15 (patch)
treee2935a8f65ac880227cefaf160bb48b5a018326f /gcc
parent2fca049fe8aada42f982aff9498eb45d3a2db302 (diff)
downloadgcc-0fab64a344486770d0acc827ab6b670543d58a15.zip
gcc-0fab64a344486770d0acc827ab6b670543d58a15.tar.gz
gcc-0fab64a344486770d0acc827ab6b670543d58a15.tar.bz2
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
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog23
-rw-r--r--gcc/ada/ChangeLog4
-rw-r--r--gcc/ada/misc.c12
-rw-r--r--gcc/c-common.c7
-rw-r--r--gcc/c-common.h2
-rw-r--r--gcc/cp/ChangeLog5
-rw-r--r--gcc/cp/cp-tree.h4
-rw-r--r--gcc/cp/expr.c5
-rw-r--r--gcc/expr.c46
-rw-r--r--gcc/expr.h5
-rw-r--r--gcc/java/ChangeLog5
-rw-r--r--gcc/java/expr.c3
-rw-r--r--gcc/java/java-tree.h2
-rw-r--r--gcc/langhooks-def.h2
-rw-r--r--gcc/langhooks.c3
-rw-r--r--gcc/langhooks.h2
-rw-r--r--gcc/stmt.c13
-rw-r--r--gcc/tree.def14
-rw-r--r--gcc/tree.h1
19 files changed, 116 insertions, 42 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 02f11ac..95c1eaa 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,26 @@
+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>
* config/m32r/m32r.h (TARGET_CPU_CPP_BUILTINS): Add __m32r__.
diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog
index c69f3ca..d2796d7 100644
--- a/gcc/ada/ChangeLog
+++ b/gcc/ada/ChangeLog
@@ -1,3 +1,7 @@
+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>
* link.c [sgi] (shared_libgnat_default): Change to STATIC.
diff --git a/gcc/ada/misc.c b/gcc/ada/misc.c
index e9f2690..43a63de 100644
--- a/gcc/ada/misc.c
+++ b/gcc/ada/misc.c
@@ -96,7 +96,8 @@ static const char *gnat_printable_name (tree, int);
static tree gnat_eh_runtime_type (tree);
static int gnat_eh_type_covers (tree, tree);
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 gnat_adjust_rli (record_layout_info);
@@ -550,7 +551,8 @@ gnat_printable_name (tree decl, int verbosity)
here are TRANSFORM_EXPR, ALLOCATE_EXPR, USE_EXPR and NULL_EXPR. */
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 new;
@@ -606,8 +608,8 @@ gnat_expand_expr (tree exp, rtx target, enum machine_mode tmode, int modifier)
return target;
case GNAT_NOP_EXPR:
- return expand_expr (build1 (NOP_EXPR, type, TREE_OPERAND (exp, 0)),
- target, tmode, modifier);
+ return expand_expr_real (build1 (NOP_EXPR, type, TREE_OPERAND (exp, 0)),
+ target, tmode, modifier, alt_rtl);
case UNCONSTRAINED_ARRAY_REF:
/* 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)
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
diff --git a/gcc/c-common.c b/gcc/c-common.c
index 327a4dc..e12a9c0 100644
--- a/gcc/c-common.c
+++ b/gcc/c-common.c
@@ -4054,8 +4054,9 @@ finish_label_address_expr (tree label)
/* Hook used by expand_expr to expand language-specific tree codes. */
rtx
-c_expand_expr (tree exp, rtx target, enum machine_mode tmode, int modifier)
- /* Actually enum_modifier. */
+c_expand_expr (tree exp, rtx target, enum machine_mode tmode,
+ int modifier /* Actually enum_modifier. */,
+ rtx *alt_rtl)
{
switch (TREE_CODE (exp))
{
@@ -4147,7 +4148,7 @@ c_expand_expr (tree exp, rtx target, enum machine_mode tmode, int modifier)
literal, then return the variable. */
tree decl = COMPOUND_LITERAL_EXPR_DECL (exp);
emit_local_var (decl);
- return expand_expr (decl, target, tmode, modifier);
+ return expand_expr_real (decl, target, tmode, modifier, alt_rtl);
}
default:
diff --git a/gcc/c-common.h b/gcc/c-common.h
index e3ae91f..b87209e 100644
--- a/gcc/c-common.h
+++ b/gcc/c-common.h
@@ -1279,7 +1279,7 @@ extern tree finish_label_address_expr (tree);
different implementations. Used in c-common.c. */
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);
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index ef16d19..0c4ab8c 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,8 @@
+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>
PR c++/12573
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index fb04af3..ac6ecdf 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -3785,8 +3785,8 @@ extern tree eh_type_info (tree);
/* in expr.c */
extern rtx cxx_expand_expr (tree, rtx,
- enum machine_mode,
- int);
+ enum machine_mode,
+ int, rtx *);
extern tree cplus_expand_constant (tree);
/* friend.c */
diff --git a/gcc/cp/expr.c b/gcc/cp/expr.c
index 06a2e0c..14453bf 100644
--- a/gcc/cp/expr.c
+++ b/gcc/cp/expr.c
@@ -75,7 +75,8 @@ cplus_expand_constant (tree cst)
/* Hook used by expand_expr to expand language-specific tree codes. */
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);
enum machine_mode mode = TYPE_MODE (type);
@@ -119,7 +120,7 @@ cxx_expand_expr (tree exp, rtx target, enum machine_mode tmode, int modifier)
modifier);
default:
- return c_expand_expr (exp, target, tmode, modifier);
+ return c_expand_expr (exp, target, tmode, modifier, alt_rtl);
}
abort ();
/* NOTREACHED */
diff --git a/gcc/expr.c b/gcc/expr.c
index b593a51..6442b3d 100644
--- a/gcc/expr.c
+++ b/gcc/expr.c
@@ -4026,6 +4026,7 @@ rtx
store_expr (tree exp, rtx target, int want_value)
{
rtx temp;
+ rtx alt_rtl = NULL_RTX;
int dont_return_target = 0;
int dont_store_target = 0;
@@ -4207,8 +4208,10 @@ store_expr (tree exp, rtx target, int want_value)
}
else
{
- temp = expand_expr (exp, target, GET_MODE (target),
- want_value & 2 ? EXPAND_STACK_PARM : EXPAND_NORMAL);
+ temp = expand_expr_real (exp, target, GET_MODE (target),
+ (want_value & 2
+ ? EXPAND_STACK_PARM : EXPAND_NORMAL),
+ &alt_rtl);
/* Return TARGET if it's a specified hardware register.
If TARGET is a volatile mem ref, either return TARGET
or return a reg copied *from* TARGET; ANSI requires this.
@@ -4256,10 +4259,7 @@ store_expr (tree exp, rtx target, int want_value)
/* If store_expr stores a DECL whose DECL_RTL(exp) == TARGET,
but TARGET is not valid memory reference, TEMP will differ
from TARGET although it is really the same location. */
- && !(GET_CODE (target) == MEM
- && GET_CODE (XEXP (target, 0)) != QUEUED
- && (!memory_address_p (GET_MODE (target), XEXP (target, 0))
- || (flag_force_addr && !REG_P (XEXP (target, 0)))))
+ && !(alt_rtl && rtx_equal_p (alt_rtl, target))
/* If there's nothing to copy, don't bother. Don't call expr_size
unless necessary, because some front-ends (C++) expr_size-hook
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,
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;
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
-expand_expr (tree exp, rtx target, enum machine_mode tmode,
- enum expand_modifier modifier)
+expand_expr_real (tree exp, rtx target, enum machine_mode tmode,
+ enum expand_modifier modifier, rtx *alt_rtl)
{
rtx op0, op1, temp;
tree type = TREE_TYPE (exp);
@@ -6413,8 +6419,12 @@ expand_expr (tree exp, rtx target, enum machine_mode tmode,
XEXP (DECL_RTL (exp), 0))
|| (flag_force_addr
&& 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 the address is a register. */
@@ -6741,6 +6751,8 @@ expand_expr (tree exp, rtx target, enum machine_mode tmode,
}
preserve_rtl_expr_result (RTL_EXPR_RTL (exp));
free_temps_for_rtl_expr (exp);
+ if (alt_rtl)
+ *alt_rtl = RTL_EXPR_ALT_RTL (exp);
return RTL_EXPR_RTL (exp);
case CONSTRUCTOR:
@@ -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))
== BUILT_IN_FRONTEND)
return (*lang_hooks.expand_expr) (exp, original_target,
- tmode, modifier);
+ tmode, modifier,
+ alt_rtl);
else
return expand_builtin (exp, target, subtarget, tmode, ignore);
}
@@ -8228,9 +8241,9 @@ expand_expr (tree exp, rtx target, enum machine_mode tmode,
case COMPOUND_EXPR:
expand_expr (TREE_OPERAND (exp, 0), const0_rtx, VOIDmode, 0);
emit_queue ();
- return expand_expr (TREE_OPERAND (exp, 1),
- (ignore ? const0_rtx : target),
- VOIDmode, modifier);
+ return expand_expr_real (TREE_OPERAND (exp, 1),
+ (ignore ? const0_rtx : target),
+ VOIDmode, modifier, alt_rtl);
case COND_EXPR:
/* 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,
abort ();
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
diff --git a/gcc/expr.h b/gcc/expr.h
index abd7f5b..bdfd490 100644
--- a/gcc/expr.h
+++ b/gcc/expr.h
@@ -498,7 +498,10 @@ extern tree find_placeholder (tree, tree *);
/* Generate code for computing expression EXP.
An rtx for the computed value is returned. The value is never null.
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
arguments waiting to be popped. */
diff --git a/gcc/java/ChangeLog b/gcc/java/ChangeLog
index a0cee42..2a8bd6e 100644
--- a/gcc/java/ChangeLog
+++ b/gcc/java/ChangeLog
@@ -1,3 +1,8 @@
+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>
PR java/12755:
diff --git a/gcc/java/expr.c b/gcc/java/expr.c
index 82c110b..6b1c032 100644
--- a/gcc/java/expr.c
+++ b/gcc/java/expr.c
@@ -2448,7 +2448,8 @@ get_primitive_array_vtable (tree elt)
struct rtx_def *
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;
diff --git a/gcc/java/java-tree.h b/gcc/java/java-tree.h
index 7da5055..9d4fcdd 100644
--- a/gcc/java/java-tree.h
+++ b/gcc/java/java-tree.h
@@ -1326,7 +1326,7 @@ extern tree decl_constant_value (tree);
extern void java_mark_class_local (tree);
#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
extern void java_inlining_merge_static_initializers (tree, void *);
extern void java_inlining_map_static_initializers (tree, void *);
diff --git a/gcc/langhooks-def.h b/gcc/langhooks-def.h
index 6a9f68c..c9ba042 100644
--- a/gcc/langhooks-def.h
+++ b/gcc/langhooks-def.h
@@ -55,7 +55,7 @@ extern int lhd_unsafe_for_reeval (tree);
extern void lhd_clear_binding_stack (void);
extern void lhd_print_tree_nothing (FILE *, 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 *,
const char *);
extern void lhd_set_decl_assembler_name (tree);
diff --git a/gcc/langhooks.c b/gcc/langhooks.c
index e31c1fb..5bce710 100644
--- a/gcc/langhooks.c
+++ b/gcc/langhooks.c
@@ -266,7 +266,8 @@ hook_get_alias_set_0 (tree t ATTRIBUTE_UNUSED)
rtx
lhd_expand_expr (tree t ATTRIBUTE_UNUSED, rtx r ATTRIBUTE_UNUSED,
enum machine_mode mm ATTRIBUTE_UNUSED,
- int em ATTRIBUTE_UNUSED)
+ int em ATTRIBUTE_UNUSED,
+ rtx *a ATTRIBUTE_UNUSED)
{
abort ();
}
diff --git a/gcc/langhooks.h b/gcc/langhooks.h
index ce6b7a6..fcc078c 100644
--- a/gcc/langhooks.h
+++ b/gcc/langhooks.h
@@ -283,7 +283,7 @@ struct lang_hooks
/* 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 (*expand_expr) (tree, rtx, enum machine_mode, int, rtx *);
/* Prepare expr to be an argument of a TRUTH_NOT_EXPR or other logical
operation.
diff --git a/gcc/stmt.c b/gcc/stmt.c
index 7b388dd..1a3d918 100644
--- a/gcc/stmt.c
+++ b/gcc/stmt.c
@@ -361,6 +361,7 @@ struct stmt_status GTY(())
record the expr's type and its RTL value here. */
tree x_last_expr_type;
rtx x_last_expr_value;
+ rtx x_last_expr_alt_rtl;
/* 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. */
@@ -383,6 +384,7 @@ struct stmt_status GTY(())
#define current_block_start_count (cfun->stmt->x_block_start_count)
#define last_expr_type (cfun->stmt->x_last_expr_type)
#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 emit_locus (cfun->stmt->x_emit_locus)
#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)
{
rtx value;
tree type;
+ rtx alt_rtl = NULL;
if (want_value == -1)
want_value = expr_stmts_for_value != 0;
@@ -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
last_expr_value to get reset. Therefore, we set last_expr_value
and last_expr_type *after* calling expand_expr. */
- value = expand_expr (exp, want_value ? NULL_RTX : const0_rtx,
- VOIDmode, 0);
+ value = expand_expr_real (exp, want_value ? NULL_RTX : const0_rtx,
+ VOIDmode, 0, &alt_rtl);
type = TREE_TYPE (exp);
/* 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)
if (want_value)
{
last_expr_value = value;
+ last_expr_alt_rtl = alt_rtl;
last_expr_type = type;
}
@@ -2322,6 +2326,7 @@ clear_last_expr (void)
{
last_expr_type = NULL_TREE;
last_expr_value = NULL_RTX;
+ last_expr_alt_rtl = NULL_RTX;
}
/* Begin a statement-expression, i.e., a series of statements which
@@ -2369,6 +2374,7 @@ expand_end_stmt_expr (tree t)
if (! last_expr_value || ! last_expr_type)
{
last_expr_value = const0_rtx;
+ last_expr_alt_rtl = NULL_RTX;
last_expr_type = void_type_node;
}
else if (GET_CODE (last_expr_value) != REG && ! CONSTANT_P (last_expr_value))
@@ -2379,6 +2385,7 @@ expand_end_stmt_expr (tree t)
TREE_TYPE (t) = last_expr_type;
RTL_EXPR_RTL (t) = last_expr_value;
+ RTL_EXPR_ALT_RTL (t) = last_expr_alt_rtl;
RTL_EXPR_SEQUENCE (t) = get_insns ();
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)
/* Don't let cleanups affect ({...}) constructs. */
int old_expr_stmts_for_value = expr_stmts_for_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;
expr_stmts_for_value = 0;
@@ -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;
last_expr_value = old_last_expr_value;
+ last_expr_alt_rtl = old_last_expr_alt_rtl;
last_expr_type = old_last_expr_type;
/* Restore the stack level. */
diff --git a/gcc/tree.def b/gcc/tree.def
index 79bb63e..0419fae 100644
--- a/gcc/tree.def
+++ b/gcc/tree.def
@@ -730,11 +730,15 @@ DEFTREECODE (UNSAVE_EXPR, "unsave_expr", 'e', 1)
/* Represents something whose RTL has already been expanded as a
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
- of insns. The second is the RTL expression for the result. 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', 2)
+ of insns. The second is the RTL expression for the result. The
+ third operand is the "alternate RTL expression" for the result, if
+ any; if the second argument is the DECL_RTL for a VAR_DECL, but
+ with an invalid memory address replaced by a valid one, then the
+ 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.
Operand may have any mode. Result mode is Pmode. */
diff --git a/gcc/tree.h b/gcc/tree.h
index 04ac0b8..aa967d9 100644
--- a/gcc/tree.h
+++ b/gcc/tree.h
@@ -794,6 +794,7 @@ struct tree_vec GTY(())
/* In a RTL_EXPR node. */
#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_ALT_RTL(NODE) TREE_RTL_OPERAND_CHECK (NODE, RTL_EXPR, 2)
/* In a WITH_CLEANUP_EXPR node. */
#define WITH_CLEANUP_EXPR_RTL(NODE) \