diff mbox

Avoid duplicate calls to REG_PARM_STACK_SPACE

Message ID 201311111433.rABEXTs3017904@d06av02.portsmouth.uk.ibm.com
State New
Headers show

Commit Message

Ulrich Weigand Nov. 11, 2013, 2:33 p.m. UTC
Hello,

this is another tweak to the middle-end to help support the new
powerpc64le-linux ABI.

In the new ABI, we make a distinction between functions that pass
all arguments solely in registers, and those that do not.  Only when
calling one the latter type (or a varags routine) does the caller
need to provide REG_PARM_STACK_SPACE; in the former case, this can
be omitted to save stack space.

This leads to a definition of REG_PARM_STACK_SPACE that is a lot
more complex than usual, which means it would be helpful if the
middle-end were to evaluate it sparingly (e.g. once per function
definition / call).

The middle-end already does cache REG_PARM_STACK_SPACE results,
however, this cache it not consistently used.  In particular,
the locate_and_pad_parm routine will re-evaluate the macro
every time it is called, even though all callers of the routine
already have a cached copy.

This patch adds a new argument to locate_and_pad_parm which is
used instead of evaluating REG_PARM_STACK_SPACE, and updates
the callers to pass in the correct value.

There should be no change in generated code on any platform.

Tested on powerpc64-linux and powerpc64le-linux.

OK for mainline?

Bye,
Ulrich

2013-11-11  Ulrich Weigand  <Ulrich.Weigand@de.ibm.com>
	    Alan Modra  <amodra@gmail.com>

ChangeLog:

	* function.c (assign_parms): Use all.reg_parm_stack_space instead
	of re-evaluating REG_PARM_STACK_SPACE target macro.
	(locate_and_pad_parm): New parameter REG_PARM_STACK_SPACE.  Use it
	instead of evaluating target macro REG_PARM_STACK_SPACE every time.
	(assign_parm_find_entry_rtl): Update call.
	* calls.c (initialize_argument_information): Update call.
	(emit_library_call_value_1): Likewise.
	* expr.h (locate_and_pad_parm): Update prototype.

Comments

Jeff Law Nov. 14, 2013, 6:44 a.m. UTC | #1
On 11/11/13 07:33, Ulrich Weigand wrote:
> Hello,
>
> this is another tweak to the middle-end to help support the new
> powerpc64le-linux ABI.
>
> In the new ABI, we make a distinction between functions that pass
> all arguments solely in registers, and those that do not.  Only when
> calling one the latter type (or a varags routine) does the caller
> need to provide REG_PARM_STACK_SPACE; in the former case, this can
> be omitted to save stack space.
>
> This leads to a definition of REG_PARM_STACK_SPACE that is a lot
> more complex than usual, which means it would be helpful if the
> middle-end were to evaluate it sparingly (e.g. once per function
> definition / call).
>
> The middle-end already does cache REG_PARM_STACK_SPACE results,
> however, this cache it not consistently used.  In particular,
> the locate_and_pad_parm routine will re-evaluate the macro
> every time it is called, even though all callers of the routine
> already have a cached copy.
>
> This patch adds a new argument to locate_and_pad_parm which is
> used instead of evaluating REG_PARM_STACK_SPACE, and updates
> the callers to pass in the correct value.
>
> There should be no change in generated code on any platform.
>
> Tested on powerpc64-linux and powerpc64le-linux.
>
> OK for mainline?
>
> Bye,
> Ulrich
>
> 2013-11-11  Ulrich Weigand  <Ulrich.Weigand@de.ibm.com>
> 	    Alan Modra  <amodra@gmail.com>
>
> ChangeLog:
>
> 	* function.c (assign_parms): Use all.reg_parm_stack_space instead
> 	of re-evaluating REG_PARM_STACK_SPACE target macro.
> 	(locate_and_pad_parm): New parameter REG_PARM_STACK_SPACE.  Use it
> 	instead of evaluating target macro REG_PARM_STACK_SPACE every time.
> 	(assign_parm_find_entry_rtl): Update call.
> 	* calls.c (initialize_argument_information): Update call.
> 	(emit_library_call_value_1): Likewise.
> 	* expr.h (locate_and_pad_parm): Update prototype.
This is fine for the trunk.  Please go ahead and install.

Thanks,
Jeff
diff mbox

Patch

Index: gcc/gcc/expr.h
===================================================================
--- gcc.orig/gcc/expr.h
+++ gcc/gcc/expr.h
@@ -521,8 +521,8 @@  extern rtx expand_divmod (int, enum tree
 			  rtx, int);
 #endif
 
-extern void locate_and_pad_parm (enum machine_mode, tree, int, int, tree,
-				 struct args_size *,
+extern void locate_and_pad_parm (enum machine_mode, tree, int, int, int,
+				 tree, struct args_size *,
 				 struct locate_and_pad_arg_data *);
 
 /* Return the CODE_LABEL rtx for a LABEL_DECL, creating it if necessary.  */
Index: gcc/gcc/calls.c
===================================================================
--- gcc.orig/gcc/calls.c
+++ gcc/gcc/calls.c
@@ -1326,6 +1326,7 @@  initialize_argument_information (int num
 #else
 			     args[i].reg != 0,
 #endif
+			     reg_parm_stack_space,
 			     args[i].pass_on_stack ? 0 : args[i].partial,
 			     fndecl, args_size, &args[i].locate);
 #ifdef BLOCK_REG_PADDING
@@ -3736,7 +3737,8 @@  emit_library_call_value_1 (int retval, r
 #else
 			   argvec[count].reg != 0,
 #endif
-			   0, NULL_TREE, &args_size, &argvec[count].locate);
+			   reg_parm_stack_space, 0,
+			   NULL_TREE, &args_size, &argvec[count].locate);
 
       if (argvec[count].reg == 0 || argvec[count].partial != 0
 	  || reg_parm_stack_space > 0)
@@ -3823,7 +3825,7 @@  emit_library_call_value_1 (int retval, r
 #else
 			       argvec[count].reg != 0,
 #endif
-			       argvec[count].partial,
+			       reg_parm_stack_space, argvec[count].partial,
 			       NULL_TREE, &args_size, &argvec[count].locate);
 	  args_size.constant += argvec[count].locate.size.constant;
 	  gcc_assert (!argvec[count].locate.size.var);
Index: gcc/gcc/function.c
===================================================================
--- gcc.orig/gcc/function.c
+++ gcc/gcc/function.c
@@ -2523,6 +2523,7 @@  assign_parm_find_entry_rtl (struct assig
     }
 
   locate_and_pad_parm (data->promoted_mode, data->passed_type, in_regs,
+		       all->reg_parm_stack_space,
 		       entry_parm ? data->partial : 0, current_function_decl,
 		       &all->stack_args_size, &data->locate);
 
@@ -3511,11 +3512,7 @@  assign_parms (tree fndecl)
   /* Adjust function incoming argument size for alignment and
      minimum length.  */
 
-#ifdef REG_PARM_STACK_SPACE
-  crtl->args.size = MAX (crtl->args.size,
-				    REG_PARM_STACK_SPACE (fndecl));
-#endif
-
+  crtl->args.size = MAX (crtl->args.size, all.reg_parm_stack_space);
   crtl->args.size = CEIL_ROUND (crtl->args.size,
 					   PARM_BOUNDARY / BITS_PER_UNIT);
 
@@ -3719,6 +3716,9 @@  gimplify_parameters (void)
    IN_REGS is nonzero if the argument will be passed in registers.  It will
    never be set if REG_PARM_STACK_SPACE is not defined.
 
+   REG_PARM_STACK_SPACE is the number of bytes of stack space reserved
+   for arguments which are passed in registers.
+
    FNDECL is the function in which the argument was defined.
 
    There are two types of rounding that are done.  The first, controlled by
@@ -3739,19 +3739,16 @@  gimplify_parameters (void)
 
 void
 locate_and_pad_parm (enum machine_mode passed_mode, tree type, int in_regs,
-		     int partial, tree fndecl ATTRIBUTE_UNUSED,
+		     int reg_parm_stack_space, int partial,
+		     tree fndecl ATTRIBUTE_UNUSED,
 		     struct args_size *initial_offset_ptr,
 		     struct locate_and_pad_arg_data *locate)
 {
   tree sizetree;
   enum direction where_pad;
   unsigned int boundary, round_boundary;
-  int reg_parm_stack_space = 0;
   int part_size_in_regs;
 
-#ifdef REG_PARM_STACK_SPACE
-  reg_parm_stack_space = REG_PARM_STACK_SPACE (fndecl);
-
   /* If we have found a stack parm before we reach the end of the
      area reserved for registers, skip that area.  */
   if (! in_regs)
@@ -3769,7 +3766,6 @@  locate_and_pad_parm (enum machine_mode p
 	    initial_offset_ptr->constant = reg_parm_stack_space;
 	}
     }
-#endif /* REG_PARM_STACK_SPACE */
 
   part_size_in_regs = (reg_parm_stack_space == 0 ? partial : 0);
 
@@ -3832,11 +3828,7 @@  locate_and_pad_parm (enum machine_mode p
 
   locate->slot_offset.constant += part_size_in_regs;
 
-  if (!in_regs
-#ifdef REG_PARM_STACK_SPACE
-      || REG_PARM_STACK_SPACE (fndecl) > 0
-#endif
-     )
+  if (!in_regs || reg_parm_stack_space > 0)
     pad_to_arg_alignment (&locate->slot_offset, boundary,
 			  &locate->alignment_pad);
 
@@ -3856,11 +3848,7 @@  locate_and_pad_parm (enum machine_mode p
     pad_below (&locate->offset, passed_mode, sizetree);
 
 #else /* !ARGS_GROW_DOWNWARD */
-  if (!in_regs
-#ifdef REG_PARM_STACK_SPACE
-      || REG_PARM_STACK_SPACE (fndecl) > 0
-#endif
-      )
+  if (!in_regs || reg_parm_stack_space > 0)
     pad_to_arg_alignment (initial_offset_ptr, boundary,
 			  &locate->alignment_pad);
   locate->slot_offset = *initial_offset_ptr;