From: rsandifo Date: Sat, 11 Aug 2007 16:51:07 +0000 (+0000) Subject: gcc/ X-Git-Tag: upstream/4.9.2~47014 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=90af1361e9fa1a9d6c2353d2e5d8c4a33e05e2bf;p=platform%2Fupstream%2Flinaro-gcc.git gcc/ * calls.c (avoid_likely_spilled_reg): New function. (expand_call): Use it. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@127360 138bc75d-0d04-0410-961f-82ee72b054a4 --- 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 + + * calls.c (avoid_likely_spilled_reg): New function. + (expand_call): Use it. + 2007-08-11 Kaveh R. Ghazi * 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)) {