From 5f98f7c481fdaf3412295aebf770683171ab49e6 Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Wed, 17 Mar 1999 04:17:02 -0800 Subject: 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 --- gcc/function.c | 43 +++++++++++++++++++++++++++++++++++-------- 1 file changed, 35 insertions(+), 8 deletions(-) (limited to 'gcc/function.c') 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; -- cgit v1.1