Commit 3fb30019 by Richard Sandiford Committed by Richard Sandiford

calls.c (avoid_likely_spilled_reg): New function.

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

From-SVN: r127360
parent 4d8a9bfe
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.
......
...@@ -1856,6 +1856,31 @@ shift_return_value (enum machine_mode mode, bool left_p, rtx value) ...@@ -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) ...@@ -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) ...@@ -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))
{ {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment