calls.c (avoid_likely_spilled_reg): New function.

gcc/
	* calls.c (avoid_likely_spilled_reg): New function.
	(expand_call): Use it.

From-SVN: r127360
This commit is contained in:
Richard Sandiford 2007-08-11 16:51:07 +00:00 committed by Richard Sandiford
parent 4d8a9bfe24
commit 3fb300196d
2 changed files with 33 additions and 6 deletions

View File

@ -1,3 +1,8 @@
2007-08-11 Richard Sandiford <richard@codesourcery.com>
* calls.c (avoid_likely_spilled_reg): New function.
(expand_call): Use it.
2007-08-11 Kaveh R. Ghazi <ghazi@caip.rutgers.edu> 2007-08-11 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
* c-typeck.c (build_c_cast): Add OPT_Wcast_qual to warnings. * c-typeck.c (build_c_cast): Add OPT_Wcast_qual to warnings.

View File

@ -1856,6 +1856,31 @@ shift_return_value (enum machine_mode mode, bool left_p, rtx value)
return true; return true;
} }
/* If X is a likely-spilled register value, copy it to a pseudo
register and return that register. Return X otherwise. */
static rtx
avoid_likely_spilled_reg (rtx x)
{
rtx new;
if (REG_P (x)
&& HARD_REGISTER_P (x)
&& CLASS_LIKELY_SPILLED_P (REGNO_REG_CLASS (REGNO (x))))
{
/* Make sure that we generate a REG rather than a CONCAT.
Moves into CONCATs can need nontrivial instructions,
and the whole point of this function is to avoid
using the hard register directly in such a situation. */
generating_concat_p = 0;
new = gen_reg_rtx (GET_MODE (x));
generating_concat_p = 1;
emit_move_insn (new, x);
return new;
}
return x;
}
/* Generate all the code for a CALL_EXPR exp /* Generate all the code for a CALL_EXPR exp
and return an rtx for its value. and return an rtx for its value.
Store the value in TARGET (specified as an rtx) if convenient. Store the value in TARGET (specified as an rtx) if convenient.
@ -2953,11 +2978,8 @@ expand_call (tree exp, rtx target, int ignore)
/* We have to copy a return value in a CLASS_LIKELY_SPILLED hard /* We have to copy a return value in a CLASS_LIKELY_SPILLED hard
reg to a plain register. */ reg to a plain register. */
if (REG_P (valreg) if (!REG_P (target) || HARD_REGISTER_P (target))
&& HARD_REGISTER_P (valreg) valreg = avoid_likely_spilled_reg (valreg);
&& CLASS_LIKELY_SPILLED_P (REGNO_REG_CLASS (REGNO (valreg)))
&& !(REG_P (target) && !HARD_REGISTER_P (target)))
valreg = copy_to_reg (valreg);
/* If TARGET is a MEM in the argument area, and we have /* If TARGET is a MEM in the argument area, and we have
saved part of the argument area, then we can't store saved part of the argument area, then we can't store
@ -3002,7 +3024,7 @@ expand_call (tree exp, rtx target, int ignore)
sibcall_failure = 1; sibcall_failure = 1;
} }
else else
target = copy_to_reg (valreg); target = copy_to_reg (avoid_likely_spilled_reg (valreg));
if (targetm.calls.promote_function_return(funtype)) if (targetm.calls.promote_function_return(funtype))
{ {