This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH , rs6000] Fix order of prologue instructions for varargs functions with -O0 and -m32


Hi,

Considering this little example using varargs for ppc:

void testvad32 (int n, ...)
{
  __builtin_va_list ap;
  __builtin_va_start (ap, n);
  __builtin_va_end (ap);
}

When built with -O0 and -m32, we get the following asm as output:

        stw 4,28(31)
        stw 5,32(31)
        stw 6,36(31)
        stw 7,40(31)
        stw 8,44(31)
        stw 9,48(31)
        stw 10,52(31)
>>>>> Debug info tells us r3 is already saved at this point
        bne 1,.L2
        stfd 1,56(31)
        stfd 2,64(31)
        stfd 3,72(31)
        stfd 4,80(31)
        stfd 5,88(31)
        stfd 6,96(31)
        stfd 7,104(31)
        stfd 8,112(31)
>>>>> End of prologue/Beginning of function
        stw 3,120(31)

As we can see, r3 isn't saved to the stack until later in the process,
but the debugging information tells us r3 should already be on slot 120
right before the branch instruction. This prevents GDB from getting the
correct value for the last named argument of a variadic function right
upon entering it.

The following patch reorders the statement responsible for generating
varargs-related RTL code. Basically, we'll only generate the RTL code
for unamed parameters after we have the RTL ready for the last named
parameter.

It also does some cleaning on "rs6000.c" since, with the reordering,
there's a variable there that is not relevant anymore.

Bootstrapped and regtested using the testsuite. The results looked OK,
with no changes.

Ok for mainline?

Luis


2009-02-26  Luis Machado  <luisgpm@br.ibm.com>

	* function.c (assign_parms): Delay generation of varargs-related
	RTL code.
	* config/rs6000/rs6000.c (setup_incoming_varargs): Remove NEXT_CUM
	variable and use CUM instead. Don't skip a parameter.

Index: gcc/function.c
===================================================================
--- gcc.orig/function.c	2009-02-20 11:54:18.000000000 -0600
+++ gcc/function.c	2009-02-25 18:32:09.000000000 -0600
@@ -3122,9 +3122,6 @@
 	    }
 	}
 	
-      if (cfun->stdarg && !TREE_CHAIN (parm))
-	assign_parms_setup_varargs (&all, &data, false);
-
       /* Find out where the parameter arrives in this function.  */
       assign_parm_find_entry_rtl (&all, &data);
 
@@ -3150,6 +3147,10 @@
 	assign_parm_setup_reg (&all, parm, &data);
       else
 	assign_parm_setup_stack (&all, parm, &data);
+
+      if (cfun->stdarg && !TREE_CHAIN (parm))
+	assign_parms_setup_varargs (&all, &data, false);
+
     }
 
   if (targetm.calls.split_complex_arg && fnargs != all.orig_fnargs)
Index: gcc/config/rs6000/rs6000.c
===================================================================
--- gcc.orig/config/rs6000/rs6000.c	2009-02-25 16:09:27.000000000 -0600
+++ gcc/config/rs6000/rs6000.c	2009-02-26 09:04:00.000000000 -0600
@@ -6663,19 +6663,14 @@
 			tree type, int *pretend_size ATTRIBUTE_UNUSED,
 			int no_rtl)
 {
-  CUMULATIVE_ARGS next_cum;
   int reg_size = TARGET_32BIT ? 4 : 8;
   rtx save_area = NULL_RTX, mem;
   int first_reg_offset;
   alias_set_type set;
 
-  /* Skip the last named argument.  */
-  next_cum = *cum;
-  function_arg_advance (&next_cum, mode, type, 1, 0);
-
   if (DEFAULT_ABI == ABI_V4)
     {
-      first_reg_offset = next_cum.sysv_gregno - GP_ARG_MIN_REG;
+      first_reg_offset = cum->sysv_gregno - GP_ARG_MIN_REG;
 
       if (! no_rtl)
 	{
@@ -6690,17 +6685,17 @@
 	  if (cfun->va_list_gpr_size && first_reg_offset < GP_ARG_NUM_REG)
 	    gpr_reg_num = GP_ARG_NUM_REG - first_reg_offset;
 	  if (TARGET_HARD_FLOAT && TARGET_FPRS
-	      && next_cum.fregno <= FP_ARG_V4_MAX_REG
+	      && cum->fregno <= FP_ARG_V4_MAX_REG
 	      && cfun->va_list_fpr_size)
 	    {
 	      if (gpr_reg_num)
-		fpr_size = (next_cum.fregno - FP_ARG_MIN_REG)
+		fpr_size = (cum->fregno - FP_ARG_MIN_REG)
 			   * UNITS_PER_FP_WORD;
 	      if (cfun->va_list_fpr_size
-		  < FP_ARG_V4_MAX_REG + 1 - next_cum.fregno)
+		  < FP_ARG_V4_MAX_REG + 1 - cum->fregno)
 		fpr_size += cfun->va_list_fpr_size * UNITS_PER_FP_WORD;
 	      else
-		fpr_size += (FP_ARG_V4_MAX_REG + 1 - next_cum.fregno)
+		fpr_size += (FP_ARG_V4_MAX_REG + 1 - cum->fregno)
 			    * UNITS_PER_FP_WORD;
 	    }
 	  if (gpr_reg_num)
@@ -6715,7 +6710,7 @@
 	      gpr_size = (gpr_reg_num * reg_size + 7) & ~7;
 	    }
 	  else if (fpr_size)
-	    offset = - (int) (next_cum.fregno - FP_ARG_MIN_REG)
+	    offset = - (int) (cum->fregno - FP_ARG_MIN_REG)
 		       * UNITS_PER_FP_WORD
 		     - (int) (GP_ARG_NUM_REG * reg_size);
 
@@ -6742,7 +6737,7 @@
     }
   else
     {
-      first_reg_offset = next_cum.words;
+      first_reg_offset = cum->words;
       save_area = virtual_incoming_args_rtx;
 
       if (targetm.calls.must_pass_in_stack (mode, type))
@@ -6783,10 +6778,10 @@
   if (DEFAULT_ABI == ABI_V4
       && TARGET_HARD_FLOAT && TARGET_FPRS
       && ! no_rtl
-      && next_cum.fregno <= FP_ARG_V4_MAX_REG
+      && cum->fregno <= FP_ARG_V4_MAX_REG
       && cfun->va_list_fpr_size)
     {
-      int fregno = next_cum.fregno, nregs;
+      int fregno = cum->fregno, nregs;
       rtx cr1 = gen_rtx_REG (CCmode, CR1_REGNO);
       rtx lab = gen_label_rtx ();
       int off = (GP_ARG_NUM_REG * reg_size) + ((fregno - FP_ARG_MIN_REG)



Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]