[11/13] Make function.c use function_arg_info internally

Richard Sandiford richard.sandiford@arm.com
Mon Aug 19 15:51:00 GMT 2019


This patch adds a function_arg_info field to assign_parm_data_one,
so that:

  - passed_type -> arg.type
  - promoted_mode -> arg.mode
  - named_arg -> arg.named

We can then pass this function_arg_info directly to the converted
hooks.

Between the initialisation of the assign_parm_data_one and the
application of promotion rules (which is a state internal to
assign_parm_find_data_types), arg.mode is equivalent to passed_mode
(i.e. to TYPE_MODE).


2019-08-19  Richard Sandiford  <richard.sandiford@arm.com>

gcc/
	* function.c (assign_parm_data_one): Replace passed_type,
	promoted_mode and named_arg with a function_arg_info field.
	(assign_parm_find_data_types): Remove local variables and
	assign directly to "data".  Make data->passed_mode shadow
	data->arg.mode until promotion, then assign the promoted
	mode to data->arg.mode.
	(assign_parms_setup_varargs, assign_parm_find_entry_rtl)
	(assign_parm_find_stack_rtl, assign_parm_adjust_entry_rtl)
	(assign_parm_remove_parallels, assign_parm_setup_block_p)
	(assign_parm_setup_block, assign_parm_setup_reg)
	(assign_parm_setup_stack, assign_parms, gimplify_parameters): Use
	arg.mode instead of promoted_mode, arg.type instead of passed_type
	and arg.named instead of named_arg.  Use data->arg for
	function_arg_info structures that had the field values passed_type,
	promoted_mode and named_arg.  Base other function_arg_infos on
	data->arg, changing the necessary properties.

Index: gcc/function.c
===================================================================
--- gcc/function.c	2019-08-19 15:59:09.809778162 +0100
+++ gcc/function.c	2019-08-19 15:59:14.297745685 +0100
@@ -2264,15 +2264,13 @@ struct assign_parm_data_all
 struct assign_parm_data_one
 {
   tree nominal_type;
-  tree passed_type;
+  function_arg_info arg;
   rtx entry_parm;
   rtx stack_parm;
   machine_mode nominal_mode;
   machine_mode passed_mode;
-  machine_mode promoted_mode;
   struct locate_and_pad_arg_data locate;
   int partial;
-  BOOL_BITFIELD named_arg : 1;
   BOOL_BITFIELD passed_pointer : 1;
 };
 
@@ -2407,24 +2405,22 @@ assign_parms_augmented_arg_list (struct
 assign_parm_find_data_types (struct assign_parm_data_all *all, tree parm,
 			     struct assign_parm_data_one *data)
 {
-  tree nominal_type, passed_type;
-  machine_mode nominal_mode, passed_mode, promoted_mode;
   int unsignedp;
 
-  memset (data, 0, sizeof (*data));
+  *data = assign_parm_data_one ();
 
   /* NAMED_ARG is a misnomer.  We really mean 'non-variadic'. */
   if (!cfun->stdarg)
-    data->named_arg = 1;  /* No variadic parms.  */
+    data->arg.named = 1;  /* No variadic parms.  */
   else if (DECL_CHAIN (parm))
-    data->named_arg = 1;  /* Not the last non-variadic parm. */
+    data->arg.named = 1;  /* Not the last non-variadic parm. */
   else if (targetm.calls.strict_argument_naming (all->args_so_far))
-    data->named_arg = 1;  /* Only variadic ones are unnamed.  */
+    data->arg.named = 1;  /* Only variadic ones are unnamed.  */
   else
-    data->named_arg = 0;  /* Treat as variadic.  */
+    data->arg.named = 0;  /* Treat as variadic.  */
 
-  nominal_type = TREE_TYPE (parm);
-  passed_type = DECL_ARG_TYPE (parm);
+  data->nominal_type = TREE_TYPE (parm);
+  data->arg.type = DECL_ARG_TYPE (parm);
 
   /* Look out for errors propagating this far.  Also, if the parameter's
      type is void then its value doesn't matter.  */
@@ -2432,49 +2428,40 @@ assign_parm_find_data_types (struct assi
       /* This can happen after weird syntax errors
 	 or if an enum type is defined among the parms.  */
       || TREE_CODE (parm) != PARM_DECL
-      || passed_type == NULL
-      || VOID_TYPE_P (nominal_type))
+      || data->arg.type == NULL
+      || VOID_TYPE_P (data->nominal_type))
     {
-      nominal_type = passed_type = void_type_node;
-      nominal_mode = passed_mode = promoted_mode = VOIDmode;
-      goto egress;
+      data->nominal_type = data->arg.type = void_type_node;
+      data->nominal_mode = data->passed_mode = data->arg.mode = VOIDmode;
+      return;
     }
 
   /* Find mode of arg as it is passed, and mode of arg as it should be
      during execution of this function.  */
-  passed_mode = TYPE_MODE (passed_type);
-  nominal_mode = TYPE_MODE (nominal_type);
+  data->passed_mode = data->arg.mode = TYPE_MODE (data->arg.type);
+  data->nominal_mode = TYPE_MODE (data->nominal_type);
 
   /* If the parm is to be passed as a transparent union or record, use the
      type of the first field for the tests below.  We have already verified
      that the modes are the same.  */
-  if ((TREE_CODE (passed_type) == UNION_TYPE
-       || TREE_CODE (passed_type) == RECORD_TYPE)
-      && TYPE_TRANSPARENT_AGGR (passed_type))
-    passed_type = TREE_TYPE (first_field (passed_type));
+  if ((TREE_CODE (data->arg.type) == UNION_TYPE
+       || TREE_CODE (data->arg.type) == RECORD_TYPE)
+      && TYPE_TRANSPARENT_AGGR (data->arg.type))
+    data->arg.type = TREE_TYPE (first_field (data->arg.type));
 
   /* See if this arg was passed by invisible reference.  */
-  {
-    function_arg_info arg (passed_type, passed_mode, data->named_arg);
-    if (apply_pass_by_reference_rules (&all->args_so_far_v, arg))
-      {
-	passed_type = nominal_type = arg.type;
-	data->passed_pointer = true;
-	passed_mode = nominal_mode = arg.mode;
-      }
-  }
+  if (apply_pass_by_reference_rules (&all->args_so_far_v, data->arg))
+    {
+      data->nominal_type = data->arg.type;
+      data->passed_pointer = true;
+      data->passed_mode = data->nominal_mode = data->arg.mode;
+    }
 
   /* Find mode as it is passed by the ABI.  */
-  unsignedp = TYPE_UNSIGNED (passed_type);
-  promoted_mode = promote_function_mode (passed_type, passed_mode, &unsignedp,
-				         TREE_TYPE (current_function_decl), 0);
-
- egress:
-  data->nominal_type = nominal_type;
-  data->passed_type = passed_type;
-  data->nominal_mode = nominal_mode;
-  data->passed_mode = passed_mode;
-  data->promoted_mode = promoted_mode;
+  unsignedp = TYPE_UNSIGNED (data->arg.type);
+  data->arg.mode
+    = promote_function_mode (data->arg.type, data->arg.mode, &unsignedp,
+			     TREE_TYPE (current_function_decl), 0);
 }
 
 /* A subroutine of assign_parms.  Invoke setup_incoming_varargs.  */
@@ -2485,8 +2472,8 @@ assign_parms_setup_varargs (struct assig
 {
   int varargs_pretend_bytes = 0;
 
-  function_arg_info last_named_arg (data->passed_type, data->promoted_mode,
-				    /*named=*/true);
+  function_arg_info last_named_arg = data->arg;
+  last_named_arg.named = true;
   targetm.calls.setup_incoming_varargs (all->args_so_far, last_named_arg,
 					&varargs_pretend_bytes, no_rtl);
 
@@ -2508,20 +2495,19 @@ assign_parm_find_entry_rtl (struct assig
   rtx entry_parm;
   bool in_regs;
 
-  if (data->promoted_mode == VOIDmode)
+  if (data->arg.mode == VOIDmode)
     {
       data->entry_parm = data->stack_parm = const0_rtx;
       return;
     }
 
   targetm.calls.warn_parameter_passing_abi (all->args_so_far,
-					    data->passed_type);
+					    data->arg.type);
 
-  function_arg_info arg (data->passed_type, data->promoted_mode,
-			 data->named_arg);
-  entry_parm = targetm.calls.function_incoming_arg (all->args_so_far, arg);
+  entry_parm = targetm.calls.function_incoming_arg (all->args_so_far,
+						    data->arg);
   if (entry_parm == 0)
-    data->promoted_mode = data->passed_mode;
+    data->arg.mode = data->passed_mode;
 
   /* Determine parm's home in the stack, in case it arrives in the stack
      or we should pretend it did.  Compute the stack position and rtx where
@@ -2537,13 +2523,13 @@ assign_parm_find_entry_rtl (struct assig
 #ifdef STACK_PARMS_IN_REG_PARM_AREA
   in_regs = true;
 #endif
-  if (!in_regs && !data->named_arg)
+  if (!in_regs && !data->arg.named)
     {
       if (targetm.calls.pretend_outgoing_varargs_named (all->args_so_far))
 	{
 	  rtx tem;
-	  function_arg_info named_arg (data->passed_type, data->promoted_mode,
-				       /*named=*/true);
+	  function_arg_info named_arg = data->arg;
+	  named_arg.named = true;
 	  tem = targetm.calls.function_incoming_arg (all->args_so_far,
 						     named_arg);
 	  in_regs = tem != NULL;
@@ -2552,16 +2538,14 @@ assign_parm_find_entry_rtl (struct assig
 
   /* If this parameter was passed both in registers and in the stack, use
      the copy on the stack.  */
-  if (targetm.calls.must_pass_in_stack (arg))
+  if (targetm.calls.must_pass_in_stack (data->arg))
     entry_parm = 0;
 
   if (entry_parm)
     {
       int partial;
 
-      function_arg_info arg (data->passed_type, data->promoted_mode,
-			     data->named_arg);
-      partial = targetm.calls.arg_partial_bytes (all->args_so_far, arg);
+      partial = targetm.calls.arg_partial_bytes (all->args_so_far, data->arg);
       data->partial = partial;
 
       /* The caller might already have allocated stack space for the
@@ -2596,7 +2580,7 @@ assign_parm_find_entry_rtl (struct assig
 	}
     }
 
-  locate_and_pad_parm (data->promoted_mode, data->passed_type, in_regs,
+  locate_and_pad_parm (data->arg.mode, data->arg.type, in_regs,
 		       all->reg_parm_stack_space,
 		       entry_parm ? data->partial : 0, current_function_decl,
 		       &all->stack_args_size, &data->locate);
@@ -2667,21 +2651,21 @@ assign_parm_find_stack_rtl (tree parm, s
   stack_parm = crtl->args.internal_arg_pointer;
   if (offset_rtx != const0_rtx)
     stack_parm = gen_rtx_PLUS (Pmode, stack_parm, offset_rtx);
-  stack_parm = gen_rtx_MEM (data->promoted_mode, stack_parm);
+  stack_parm = gen_rtx_MEM (data->arg.mode, stack_parm);
 
   if (!data->passed_pointer)
     {
       set_mem_attributes (stack_parm, parm, 1);
       /* set_mem_attributes could set MEM_SIZE to the passed mode's size,
 	 while promoted mode's size is needed.  */
-      if (data->promoted_mode != BLKmode
-	  && data->promoted_mode != DECL_MODE (parm))
+      if (data->arg.mode != BLKmode
+	  && data->arg.mode != DECL_MODE (parm))
 	{
-	  set_mem_size (stack_parm, GET_MODE_SIZE (data->promoted_mode));
+	  set_mem_size (stack_parm, GET_MODE_SIZE (data->arg.mode));
 	  if (MEM_EXPR (stack_parm) && MEM_OFFSET_KNOWN_P (stack_parm))
 	    {
 	      poly_int64 offset = subreg_lowpart_offset (DECL_MODE (parm),
-							 data->promoted_mode);
+							 data->arg.mode);
 	      if (maybe_ne (offset, 0))
 		set_mem_offset (stack_parm, MEM_OFFSET (stack_parm) - offset);
 	    }
@@ -2733,8 +2717,7 @@ assign_parm_adjust_entry_rtl (struct ass
 	 locations.  The Irix 6 ABI has examples of this.  */
       if (GET_CODE (entry_parm) == PARALLEL)
 	emit_group_store (validize_mem (copy_rtx (stack_parm)), entry_parm,
-			  data->passed_type,
-			  int_size_in_bytes (data->passed_type));
+			  data->arg.type, int_size_in_bytes (data->arg.type));
       else
 	{
 	  gcc_assert (data->partial % UNITS_PER_WORD == 0);
@@ -2790,7 +2773,7 @@ assign_parm_remove_parallels (struct ass
   if (GET_CODE (entry_parm) == PARALLEL && GET_MODE (entry_parm) != BLKmode)
     {
       rtx parmreg = gen_reg_rtx (GET_MODE (entry_parm));
-      emit_group_store (parmreg, entry_parm, data->passed_type,
+      emit_group_store (parmreg, entry_parm, data->arg.type,
 			GET_MODE_SIZE (GET_MODE (entry_parm)));
       entry_parm = parmreg;
     }
@@ -2851,8 +2834,8 @@ assign_parm_setup_block_p (struct assign
   /* Only assign_parm_setup_block knows how to deal with register arguments
      that are padded at the least significant end.  */
   if (REG_P (data->entry_parm)
-      && known_lt (GET_MODE_SIZE (data->promoted_mode), UNITS_PER_WORD)
-      && (BLOCK_REG_PADDING (data->passed_mode, data->passed_type, 1)
+      && known_lt (GET_MODE_SIZE (data->arg.mode), UNITS_PER_WORD)
+      && (BLOCK_REG_PADDING (data->passed_mode, data->arg.type, 1)
 	  == (BYTES_BIG_ENDIAN ? PAD_UPWARD : PAD_DOWNWARD)))
     return true;
 #endif
@@ -2907,7 +2890,7 @@ assign_parm_setup_block (struct assign_p
       data->stack_parm = NULL;
     }
 
-  size = int_size_in_bytes (data->passed_type);
+  size = int_size_in_bytes (data->arg.type);
   size_stored = CEIL_ROUND (size, UNITS_PER_WORD);
   if (stack_parm == 0)
     {
@@ -2962,12 +2945,12 @@ assign_parm_setup_block (struct assign_p
 
       /* Handle values in multiple non-contiguous locations.  */
       if (GET_CODE (entry_parm) == PARALLEL && !MEM_P (mem))
-	emit_group_store (mem, entry_parm, data->passed_type, size);
+	emit_group_store (mem, entry_parm, data->arg.type, size);
       else if (GET_CODE (entry_parm) == PARALLEL)
 	{
 	  push_to_sequence2 (all->first_conversion_insn,
 			     all->last_conversion_insn);
-	  emit_group_store (mem, entry_parm, data->passed_type, size);
+	  emit_group_store (mem, entry_parm, data->arg.type, size);
 	  all->first_conversion_insn = get_insns ();
 	  all->last_conversion_insn = get_last_insn ();
 	  end_sequence ();
@@ -2987,7 +2970,7 @@ assign_parm_setup_block (struct assign_p
 	  if (mode != BLKmode
 #ifdef BLOCK_REG_PADDING
 	      && (size == UNITS_PER_WORD
-		  || (BLOCK_REG_PADDING (mode, data->passed_type, 1)
+		  || (BLOCK_REG_PADDING (mode, data->arg.type, 1)
 		      != (BYTES_BIG_ENDIAN ? PAD_UPWARD : PAD_DOWNWARD)))
 #endif
 	      )
@@ -3028,7 +3011,7 @@ assign_parm_setup_block (struct assign_p
 		 additional changes to work correctly.  */
 	      gcc_checking_assert (BYTES_BIG_ENDIAN
 				   && (BLOCK_REG_PADDING (mode,
-							  data->passed_type, 1)
+							  data->arg.type, 1)
 				       == PAD_UPWARD));
 
 	      int by = (UNITS_PER_WORD - size) * BITS_PER_UNIT;
@@ -3049,7 +3032,7 @@ assign_parm_setup_block (struct assign_p
 	     handle all cases (e.g. SIZE == 3).  */
 	  else if (size != UNITS_PER_WORD
 #ifdef BLOCK_REG_PADDING
-		   && (BLOCK_REG_PADDING (mode, data->passed_type, 1)
+		   && (BLOCK_REG_PADDING (mode, data->arg.type, 1)
 		       == PAD_DOWNWARD)
 #else
 		   && BYTES_BIG_ENDIAN
@@ -3073,7 +3056,7 @@ assign_parm_setup_block (struct assign_p
 	  gcc_checking_assert (size > UNITS_PER_WORD);
 #ifdef BLOCK_REG_PADDING
 	  gcc_checking_assert (BLOCK_REG_PADDING (GET_MODE (mem),
-						  data->passed_type, 0)
+						  data->arg.type, 0)
 			       == PAD_UPWARD);
 #endif
 	  emit_move_insn (mem, entry_parm);
@@ -3144,7 +3127,7 @@ assign_parm_setup_reg (struct assign_par
      set rtl appropriately.  */
   if (data->passed_pointer)
     {
-      rtl = gen_rtx_MEM (TYPE_MODE (TREE_TYPE (data->passed_type)), parmreg);
+      rtl = gen_rtx_MEM (TYPE_MODE (TREE_TYPE (data->arg.type)), parmreg);
       set_mem_attributes (rtl, parm, 1);
     }
   else
@@ -3159,7 +3142,7 @@ assign_parm_setup_reg (struct assign_par
   validated_mem = validize_mem (copy_rtx (data->entry_parm));
 
   need_conversion = (data->nominal_mode != data->passed_mode
-		     || promoted_nominal_mode != data->promoted_mode);
+		     || promoted_nominal_mode != data->arg.mode);
   moved = false;
 
   if (need_conversion
@@ -3429,7 +3412,7 @@ assign_parm_setup_stack (struct assign_p
 
   assign_parm_remove_parallels (data);
 
-  if (data->promoted_mode != data->nominal_mode)
+  if (data->arg.mode != data->nominal_mode)
     {
       /* Conversion is required.  */
       rtx tempreg = gen_reg_rtx (GET_MODE (data->entry_parm));
@@ -3462,9 +3445,9 @@ assign_parm_setup_stack (struct assign_p
 
       if (data->stack_parm == 0)
 	{
-	  int align = STACK_SLOT_ALIGNMENT (data->passed_type,
+	  int align = STACK_SLOT_ALIGNMENT (data->arg.type,
 					    GET_MODE (data->entry_parm),
-					    TYPE_ALIGN (data->passed_type));
+					    TYPE_ALIGN (data->arg.type));
 	  data->stack_parm
 	    = assign_stack_local (GET_MODE (data->entry_parm),
 				  GET_MODE_SIZE (GET_MODE (data->entry_parm)),
@@ -3484,7 +3467,7 @@ assign_parm_setup_stack (struct assign_p
 	  to_conversion = true;
 
 	  emit_block_move (dest, src,
-			   GEN_INT (int_size_in_bytes (data->passed_type)),
+			   GEN_INT (int_size_in_bytes (data->arg.type)),
 			   BLOCK_OP_NORMAL);
 	}
       else
@@ -3608,10 +3591,9 @@ assign_parms (tree fndecl)
       if (SUPPORTS_STACK_ALIGNMENT)
         {
           unsigned int align
-	    = targetm.calls.function_arg_boundary (data.promoted_mode,
-						   data.passed_type);
-	  align = MINIMUM_ALIGNMENT (data.passed_type, data.promoted_mode,
-				     align);
+	    = targetm.calls.function_arg_boundary (data.arg.mode,
+						   data.arg.type);
+	  align = MINIMUM_ALIGNMENT (data.arg.type, data.arg.mode, align);
 	  if (TYPE_ALIGN (data.nominal_type) > align)
 	    align = MINIMUM_ALIGNMENT (data.nominal_type,
 				       TYPE_MODE (data.nominal_type),
@@ -3636,7 +3618,7 @@ assign_parms (tree fndecl)
       if (data.passed_pointer)
 	{
 	  rtx incoming_rtl
-	    = gen_rtx_MEM (TYPE_MODE (TREE_TYPE (data.passed_type)),
+	    = gen_rtx_MEM (TYPE_MODE (TREE_TYPE (data.arg.type)),
 			   data.entry_parm);
 	  set_decl_incoming_rtl (parm, incoming_rtl, true);
 	}
@@ -3656,9 +3638,7 @@ assign_parms (tree fndecl)
 	assign_parms_setup_varargs (&all, &data, false);
 
       /* Update info on where next arg arrives in registers.  */
-      function_arg_info arg (data.passed_type, data.promoted_mode,
-			     data.named_arg);
-      targetm.calls.function_arg_advance (all.args_so_far, arg);
+      targetm.calls.function_arg_advance (all.args_so_far, data.arg);
     }
 
   if (targetm.calls.split_complex_arg)
@@ -3845,15 +3825,13 @@ gimplify_parameters (gimple_seq *cleanup
 	continue;
 
       /* Update info on where next arg arrives in registers.  */
-      function_arg_info arg (data.passed_type, data.promoted_mode,
-			     data.named_arg);
-      targetm.calls.function_arg_advance (all.args_so_far, arg);
+      targetm.calls.function_arg_advance (all.args_so_far, data.arg);
 
       /* ??? Once upon a time variable_size stuffed parameter list
 	 SAVE_EXPRs (amongst others) onto a pending sizes list.  This
 	 turned out to be less than manageable in the gimple world.
 	 Now we have to hunt them down ourselves.  */
-      walk_tree_without_duplicates (&data.passed_type,
+      walk_tree_without_duplicates (&data.arg.type,
 				    gimplify_parm_type, &stmts);
 
       if (TREE_CODE (DECL_SIZE_UNIT (parm)) != INTEGER_CST)
@@ -3864,8 +3842,8 @@ gimplify_parameters (gimple_seq *cleanup
 
       if (data.passed_pointer)
 	{
-          tree type = TREE_TYPE (data.passed_type);
-	  function_arg_info orig_arg (type, data.named_arg);
+	  tree type = TREE_TYPE (data.arg.type);
+	  function_arg_info orig_arg (type, data.arg.named);
 	  if (reference_callee_copied (&all.args_so_far_v, orig_arg))
 	    {
 	      tree local, t;



More information about the Gcc-patches mailing list