aboutsummaryrefslogtreecommitdiff
path: root/gcc/expr.c
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/expr.c
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/expr.c')
-rw-r--r--gcc/expr.c46
1 files changed, 30 insertions, 16 deletions
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