diff options
author | Richard Sandiford <richard@codesourcery.com> | 2007-08-11 16:51:07 +0000 |
---|---|---|
committer | Richard Sandiford <rsandifo@gcc.gnu.org> | 2007-08-11 16:51:07 +0000 |
commit | 3fb300196dd0d2ff04eddf6c53f825699fd6720a (patch) | |
tree | 0fd74ebf1392d72c5584f02386c670bcd635c4e2 /gcc | |
parent | 4d8a9bfe2438189694ccb83cf02f49b5f1659ae6 (diff) | |
download | gcc-3fb300196dd0d2ff04eddf6c53f825699fd6720a.zip gcc-3fb300196dd0d2ff04eddf6c53f825699fd6720a.tar.gz gcc-3fb300196dd0d2ff04eddf6c53f825699fd6720a.tar.bz2 |
calls.c (avoid_likely_spilled_reg): New function.
gcc/
* calls.c (avoid_likely_spilled_reg): New function.
(expand_call): Use it.
From-SVN: r127360
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/calls.c | 34 |
2 files changed, 33 insertions, 6 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index d949292..906930e 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -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> * c-typeck.c (build_c_cast): Add OPT_Wcast_qual to warnings. diff --git a/gcc/calls.c b/gcc/calls.c index 98fc8f5..df9ef39 100644 --- a/gcc/calls.c +++ b/gcc/calls.c @@ -1856,6 +1856,31 @@ shift_return_value (enum machine_mode mode, bool left_p, rtx value) 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 and return an rtx for its value. 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 reg to a plain register. */ - if (REG_P (valreg) - && HARD_REGISTER_P (valreg) - && CLASS_LIKELY_SPILLED_P (REGNO_REG_CLASS (REGNO (valreg))) - && !(REG_P (target) && !HARD_REGISTER_P (target))) - valreg = copy_to_reg (valreg); + if (!REG_P (target) || HARD_REGISTER_P (target)) + valreg = avoid_likely_spilled_reg (valreg); /* If TARGET is a MEM in the argument area, and we have 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; } else - target = copy_to_reg (valreg); + target = copy_to_reg (avoid_likely_spilled_reg (valreg)); if (targetm.calls.promote_function_return(funtype)) { |