aboutsummaryrefslogtreecommitdiff
path: root/gcc/function.c
diff options
context:
space:
mode:
authorRichard Henderson <rth@cygnus.com>1999-03-17 04:17:02 -0800
committerRichard Henderson <rth@gcc.gnu.org>1999-03-17 04:17:02 -0800
commit5f98f7c481fdaf3412295aebf770683171ab49e6 (patch)
tree3d75f1344d552a6d5963759dfe55d1037dea2a8c /gcc/function.c
parente75f4f152f98f31606a8211b21f63083778c28da (diff)
downloadgcc-5f98f7c481fdaf3412295aebf770683171ab49e6.zip
gcc-5f98f7c481fdaf3412295aebf770683171ab49e6.tar.gz
gcc-5f98f7c481fdaf3412295aebf770683171ab49e6.tar.bz2
function.c (fixup_var_refs_1): First try moving the expression directly into a register.
* function.c (fixup_var_refs_1): First try moving the expression directly into a register. Don't separate cc0 setter and user. From-SVN: r25821
Diffstat (limited to 'gcc/function.c')
-rw-r--r--gcc/function.c43
1 files changed, 35 insertions, 8 deletions
diff --git a/gcc/function.c b/gcc/function.c
index d6d5aa6..82ad012 100644
--- a/gcc/function.c
+++ b/gcc/function.c
@@ -1995,18 +1995,45 @@ fixup_var_refs_1 (var, promoted_mode, loc, insn, replacements)
/* Prevent sharing of rtl that might lose. */
rtx sub = copy_rtx (XEXP (var, 0));
- start_sequence ();
-
if (! validate_change (insn, loc, sub, 0))
{
- rtx y = force_operand (sub, NULL_RTX);
+ rtx y = gen_reg_rtx (GET_MODE (sub));
+ rtx seq, new_insn;
- if (! validate_change (insn, loc, y, 0))
- *loc = copy_to_reg (y);
- }
+ /* We should be able to replace with a register or all is lost.
+ Note that we can't use validate_change to verify this, since
+ we're not caring for replacing all dups simultaneously. */
+ if (! validate_replace_rtx (*loc, y, insn))
+ abort ();
- emit_insn_before (gen_sequence (), insn);
- end_sequence ();
+ /* Careful! First try to recognize a direct move of the
+ value, mimicking how things are done in gen_reload wrt
+ PLUS. Consider what happens when insn is a conditional
+ move instruction and addsi3 clobbers flags. */
+
+ start_sequence ();
+ new_insn = emit_insn (gen_rtx_SET (VOIDmode, y, sub));
+ seq = gen_sequence ();
+ end_sequence ();
+
+ if (recog_memoized (new_insn) < 0)
+ {
+ /* That failed. Fall back on force_operand and hope. */
+
+ start_sequence ();
+ force_operand (sub, y);
+ seq = gen_sequence ();
+ end_sequence ();
+ }
+
+#ifdef HAVE_cc0
+ /* Don't separate setter from user. */
+ if (PREV_INSN (insn) && sets_cc0_p (PREV_INSN (insn)))
+ insn = PREV_INSN (insn);
+#endif
+
+ emit_insn_before (seq, insn);
+ }
}
return;