This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH/RFC] PR target/15130 SH: A tail call optimization problem
- From: Kaz Kojima <kkojima at rr dot iij4u dot or dot jp>
- To: gcc-patches at gcc dot gnu dot org
- Cc: joern dot rennecke at superh dot com, aoliva at redhat dot com
- Date: Fri, 30 Apr 2004 20:20:37 +0900 (JST)
- Subject: [PATCH/RFC] PR target/15130 SH: A tail call optimization problem
Hi,
I've taken a look at PR 15130 which seems to be a target specific
problem about the tail call optimization. In the test case attached
with the PR, a function with 4 arguments is called at the end of
another function which has an epilogue using r7 as a temporary
register and a tail call optimization occurs.
thread_prologue_and_epilogue_insns inserts the epilogue sequence
just before the call instruction of which the 4-th argument is
passed with r7. Then the tail call is done with a bad 4-th argument
clobbered by the epilogue sequence.
The appended patch is to take account of this case. It always
scans registers to get an available register in epilogue case.
The patch is tested for 3.4.0 with bootstrapping and regtesting
on sh4-unknown-linux-gnu. At the moment, mainline fails on this
target with an ICE when building java library even for x86 cross,
though there are no new failures with this patch for mainline on
i686-linux cross to sh4-/sh64-unknown-linux-gnu. So it seems
that saving the register by using MACL suggested in the comment
of sh.c:output_stack_adjust is unnecessary yet.
Thoughts?
Regards,
kaz
--
* config/sh/sh.c (output_stack_adjust): Get a temporary register
by scan for epilogue. Take account of parmeter registers and
static-chain register always.
--- 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-04-29 09:14:12.000000000 +0900
@@ -4565,13 +4565,14 @@ output_stack_adjust (int size, rtx reg,
{
rtx const_reg;
rtx insn;
- int temp = epilogue_p ? 7 : (TARGET_SH5 ? 0 : 1);
+ int temp = (TARGET_SH5 ? 0 : 1);
int i;
/* 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
+ || current_function_interrupt
|| ! call_used_regs[temp] || fixed_regs[temp])
temp = -1;
if (temp < 0 && ! current_function_interrupt)
@@ -4590,14 +4591,11 @@ output_stack_adjust (int size, rtx reg,
CLEAR_HARD_REG_BIT (temps, EH_RETURN_DATA_REGNO (i));
}
}
- else
- {
- for (i = FIRST_PARM_REG;
- i < FIRST_PARM_REG + NPARM_REGS (SImode); i++)
- CLEAR_HARD_REG_BIT (temps, i);
- if (current_function_needs_context)
- CLEAR_HARD_REG_BIT (temps, STATIC_CHAIN_REGNUM);
- }
+ for (i = FIRST_PARM_REG;
+ i < FIRST_PARM_REG + NPARM_REGS (SImode); i++)
+ CLEAR_HARD_REG_BIT (temps, i);
+ if (current_function_needs_context)
+ CLEAR_HARD_REG_BIT (temps, STATIC_CHAIN_REGNUM);
temp = scavenge_reg (&temps);
}
if (temp < 0 && live_regs_mask)