This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [PATCH/RFC] PR target/15130 SH: A tail call optimization
- From: Kaz Kojima <kkojima at rr dot iij4u dot or dot jp>
- To: joern dot rennecke at superh dot com
- Cc: gcc-patches at gcc dot gnu dot org, aoliva at redhat dot com
- Date: Sat, 01 May 2004 10:26:38 +0900 (JST)
- Subject: Re: [PATCH/RFC] PR target/15130 SH: A tail call optimization
- References: <20040430.222417.123989709.kkojima@rr.iij4u.or.jp><200404301459.i3UExC605451@linsvr1.uk.superh.com>
Joern Rennecke <joern.rennecke@superh.com> wrote:
> The patch as such look OK, however, as a re-read the code that you are
> patching, it appears to me that we have a latent bug here, which will
> be made worse by your patch.
> We are testing only for the general purpose registers used up by DImode
> values (or smaller). This seems to always give you r2.
> If the function returns a 128 bit value in general purpose registers,
> e.g. CDImode, TImode, or DCmode (the latter for soft floating point),
> then r2 is live.
Sure. The appended patch is revised one. Does it looks ok?
Regards,
kaz
--
* config/sh/sh.c (output_stack_adjust): Get a temporary register
by scan for epilogue when sibling call optimization is enabled.
Take account of parmeter registers and static-chain register
for that case. Compute the correct number of general registers
for the return value.
--- ORIG/gcc-3.4.0/gcc/config/sh/sh.c 2004-03-09 12:00:12.000000000 +0900
+++ LOCAL/gcc-3.4.0/gcc/config/sh/sh.c 2004-05-01 09:10:06.000000000 +0900
@@ -4571,7 +4571,8 @@ output_stack_adjust (int size, rtx reg,
/* If TEMP is invalid, we could temporarily save a general
register to MACL. However, there is currently no need
to handle this case, so just abort when we see it. */
- if (current_function_interrupt
+ if ((epilogue_p && flag_optimize_sibling_calls)
+ || current_function_interrupt
|| ! call_used_regs[temp] || fixed_regs[temp])
temp = -1;
if (temp < 0 && ! current_function_interrupt)
@@ -4581,7 +4582,15 @@ output_stack_adjust (int size, rtx reg,
AND_COMPL_HARD_REG_SET (temps, call_fixed_reg_set);
if (epilogue_p)
{
- for (i = 0; i < HARD_REGNO_NREGS (FIRST_RET_REG, DImode); i++)
+ int nreg = 0;
+ if (current_function_return_rtx)
+ {
+ enum machine_mode mode;
+ mode = GET_MODE (current_function_return_rtx);
+ if (BASE_RETURN_VALUE_REG (mode) == FIRST_RET_REG)
+ nreg = HARD_REGNO_NREGS (FIRST_RET_REG, mode);
+ }
+ for (i = 0; i < nreg; i++)
CLEAR_HARD_REG_BIT (temps, FIRST_RET_REG + i);
if (current_function_calls_eh_return)
{
@@ -4590,7 +4599,7 @@ output_stack_adjust (int size, rtx reg,
CLEAR_HARD_REG_BIT (temps, EH_RETURN_DATA_REGNO (i));
}
}
- else
+ if (! epilogue_p || flag_optimize_sibling_calls)
{
for (i = FIRST_PARM_REG;
i < FIRST_PARM_REG + NPARM_REGS (SImode); i++)