[PATCH/RFC] PR target/15130 SH: A tail call optimization

Kaz Kojima kkojima@rr.iij4u.or.jp
Sat May 1 01:28:00 GMT 2004


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++)



More information about the Gcc-patches mailing list