[07/13] Use function_arg_info for TARGET_FUNCTION_ARG_ADVANCE
diff mbox series

Message ID mpt36hxchfy.fsf@arm.com
State New
Headers show
Series
  • Pass an argument descriptor to target hooks
Related show

Commit Message

Richard Sandiford Aug. 19, 2019, 3:18 p.m. UTC
Use function_arg_info for TARGET_FUNCTION_ARG_ADVANCE.

There seems to be a bit of confusion around this one.  Almost all
callers pass the same arguments as TARGET_FUNCTION_ARG, meaning
that the mode is the promoted mode rather than the type mode.
But the calls.c handling for normal typed arguments instead passes
the unpromoted TYPE_MODE (despite passing the promoted mode to
TARGET_FUNCTION_ARG).  I've kept this behaviour with a ??? comment.

(The calls.c handling of libgcc functions does pass the promoted
mode though, as does the function.c handling of incoming arguments.)

Also, a couple of the arm callers don't seem to be using the hook
correctly.  Again I kept the current choices and added a ??? comment.


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

gcc/
	* target.def (function_arg_advance): Take a function_arg_info instead
	of a mode, type and named flag.
	* doc/tm.texi: Regenerate.
	* targhooks.h (default_function_arg_advance): Take a function_arg_info
	instead of a mode, type and named flag.
	* targhooks.c (default_function_arg_advance): Likewise.
	* calls.c (initialize_argument_information): Update call to
	targetm.calls.function_arg_advance.
	(emit_library_call_value_1): Likewise.
	* dse.c (get_call_args): Likewise.
	* expr.c (block_move_libcall_safe_for_call_parm): Likewise.
	* function.c (assign_parms, gimplify_parameters): Likewise.
	* var-tracking.c (prepare_call_arguments): Likewise.
	* config/aarch64/aarch64.c (aarch64_function_arg_advance): Take a
	function_arg_info instead of a mode, type and named flag.
	(aarch64_setup_incoming_varargs): Update call accordingly.
	* config/alpha/alpha.c (alpha_function_arg_advance): Take a
	function_arg_info instead of a mode, type and named flag.
	(alpha_setup_incoming_varargs): Update call accordingly.
	* config/arc/arc.c (arc_function_arg_advance): Take a
	function_arg_info instead of a mode, type and named flag.
	(arc_setup_incoming_varargs): Update call accordingly.
	* config/arm/arm.c (arm_function_arg_advance): Take a
	function_arg_info instead of a mode, type and named flag.
	(cmse_func_args_or_return_in_stack): Update call accordingly.
	(arm_function_ok_for_sibcall): Likewise.
	(cmse_nonsecure_call_clear_caller_saved): Likewise.
	* config/avr/avr.c (avr_function_arg_advance): Take a
	function_arg_info instead of a mode, type and named flag.
	* config/bfin/bfin.c (bfin_function_arg_advance): Likewise.
	* config/c6x/c6x.c (c6x_function_arg_advance): Likewise.
	(c6x_call_saved_register_used): Update call accordingly.
	* config/cr16/cr16.c (cr16_function_arg_advance): Take a
	function_arg_info instead of a mode, type and named flag.
	* config/cris/cris.c (cris_function_arg_advance): Likewise.
	* config/csky/csky.c (csky_function_arg_advance): Likewise.
	(csky_setup_incoming_varargs): Update call accordingly.
	* config/epiphany/epiphany.c (epiphany_function_arg_advance): Take a
	function_arg_info instead of a mode, type and named flag.
	* config/fr30/fr30.c (fr30_function_arg_advance): Likewise.
	* config/frv/frv.c (frv_function_arg_advance): Likewise.
	* config/ft32/ft32.c (ft32_function_arg_advance): Likewise.
	* config/gcn/gcn.c (gcn_function_arg_advance): Likewise.
	* config/h8300/h8300.c (h8300_function_arg_advance): Likewise.
	* config/i386/i386.c (ix86_function_arg_advance): Likewise.
	(ix86_setup_incoming_varargs): Update call accordingly.
	* config/ia64/ia64.c (ia64_function_arg_advance): Take a
	function_arg_info instead of a mode, type and named flag.
	(ia64_setup_incoming_varargs): Update call accordingly.
	* config/iq2000/iq2000.c (iq2000_function_arg_advance): Take a
	function_arg_info instead of a mode, type and named flag.
	(iq2000_expand_prologue): Update call accordingly.
	* config/lm32/lm32.c (lm32_function_arg_advance): Take a
	function_arg_info instead of a mode, type and named flag.
	* config/m32c/m32c.c (m32c_function_arg_advance): Likewise.
	* config/m32r/m32r.c (m32r_function_arg_advance): Likewise.
	* config/m68k/m68k.c (m68k_function_arg_advance): Likewise.
	* config/mcore/mcore.c (mcore_function_arg_advance): Likewise.
	* config/microblaze/microblaze.c (microblaze_function_arg_advance):
	Likewise.
	(microblaze_expand_prologue): Update call accordingly.
	* config/mips/mips.c (mips_function_arg_advance): Take a
	function_arg_info instead of a mode, type and named flag.
	(mips_setup_incoming_varargs): Update call accordingly.
	(mips_output_args_xfer): Likewise.
	* config/mmix/mmix.c (mmix_function_arg_advance): Take a
	function_arg_info instead of a mode, type and named flag.
	* config/mn10300/mn10300.c (mn10300_function_arg_advance): Likewise.
	* config/moxie/moxie.c (moxie_function_arg_advance): Likewise.
	* config/msp430/msp430.c (msp430_function_arg_advance): Likewise.
	* config/nds32/nds32.c (nds32_function_arg_advance): Likewise.
	* config/nios2/nios2.c (nios2_function_arg_advance): Likewise.
	(nios2_setup_incoming_varargs): Update call accordingly.
	* config/nvptx/nvptx.c (nvptx_function_arg_advance): Take a
	function_arg_info instead of a mode, type and named flag.
	* config/or1k/or1k.c (or1k_function_arg_advance): Likewise.
	* config/pa/pa.c (pa_function_arg_advance): Likewise.
	* config/pdp11/pdp11.c (pdp11_function_arg_advance): Likewise.
	* config/pru/pru.c (pru_function_arg_advance): Likewise.
	* config/riscv/riscv.c (riscv_function_arg_advance): Likewise.
	(riscv_setup_incoming_varargs): Update call accordingly.
	* config/rl78/rl78.c (rl78_function_arg_advance): Take a
	function_arg_info instead of a mode, type and named flag.
	* config/rs6000/rs6000-internal.h (rs6000_function_arg_advance):
	Likewise.
	* config/rs6000/rs6000-call.c (rs6000_function_arg_advance): Likewise.
	(rs6000_parm_needs_stack): Update call accordingly.
	* config/rx/rx.c (rx_function_arg_advance): Take a function_arg_info
	instead of a mode, type and named flag.
	* config/s390/s390.c (s390_function_arg_advance): Likewise.
	(s390_call_saved_register_used): Update call accordingly.
	* config/sh/sh.c (sh_function_arg_advance): Take a function_arg_info
	instead of a mode, type and named flag.
	(sh_output_mi_thunk): Update call accordingly.
	* config/sparc/sparc.c (sparc_function_arg_advance): Take a
	function_arg_info instead of a mode, type and named flag.
	* config/spu/spu.c (spu_function_arg_advance): Likewise.
	(spu_setup_incoming_varargs): Update call accordingly.
	* config/stormy16/stormy16.c (xstormy16_function_arg_advance): Take a
	function_arg_info instead of a mode, type and named flag.
	* config/tilegx/tilegx.c (tilegx_function_arg_advance): Likewise.
	(tilegx_setup_incoming_varargs): Update call accordingly.
	* config/tilepro/tilepro.c (tilepro_function_arg_advance): Take a
	function_arg_info instead of a mode, type and named flag.
	(tilegx_setup_incoming_varargs): Update call accordingly.
	* config/v850/v850.c (v850_function_arg_advance): Take a
	function_arg_info instead of a mode, type and named flag.
	* config/vax/vax.c (vax_function_arg_advance): Likewise.
	* config/visium/visium.c (visium_function_arg_advance): Likewise.
	(visium_setup_incoming_varargs): Update call accordingly.
	* config/xtensa/xtensa.c (xtensa_function_arg_advance): Take a
	function_arg_info instead of a mode, type and named flag.

Comments

Jeff Law Aug. 19, 2019, 8:42 p.m. UTC | #1
On 8/19/19 9:18 AM, Richard Sandiford wrote:
> Use function_arg_info for TARGET_FUNCTION_ARG_ADVANCE.
> 
> There seems to be a bit of confusion around this one.  Almost all
> callers pass the same arguments as TARGET_FUNCTION_ARG, meaning
> that the mode is the promoted mode rather than the type mode.
> But the calls.c handling for normal typed arguments instead passes
> the unpromoted TYPE_MODE (despite passing the promoted mode to
> TARGET_FUNCTION_ARG).  I've kept this behaviour with a ??? comment.
> 
> (The calls.c handling of libgcc functions does pass the promoted
> mode though, as does the function.c handling of incoming arguments.)
> 
> Also, a couple of the arm callers don't seem to be using the hook
> correctly.  Again I kept the current choices and added a ??? comment.
Keeping current behavior seems reasonable as does marking the
inconsistent bits.


> 
> 
> 2019-08-19  Richard Sandiford  <richard.sandiford@arm.com>
> 
> gcc/
> 	* target.def (function_arg_advance): Take a function_arg_info instead
> 	of a mode, type and named flag.
> 	* doc/tm.texi: Regenerate.
> 	* targhooks.h (default_function_arg_advance): Take a function_arg_info
> 	instead of a mode, type and named flag.
> 	* targhooks.c (default_function_arg_advance): Likewise.
> 	* calls.c (initialize_argument_information): Update call to
> 	targetm.calls.function_arg_advance.
> 	(emit_library_call_value_1): Likewise.
> 	* dse.c (get_call_args): Likewise.
> 	* expr.c (block_move_libcall_safe_for_call_parm): Likewise.
> 	* function.c (assign_parms, gimplify_parameters): Likewise.
> 	* var-tracking.c (prepare_call_arguments): Likewise.
> 	* config/aarch64/aarch64.c (aarch64_function_arg_advance): Take a
> 	function_arg_info instead of a mode, type and named flag.
> 	(aarch64_setup_incoming_varargs): Update call accordingly.
> 	* config/alpha/alpha.c (alpha_function_arg_advance): Take a
> 	function_arg_info instead of a mode, type and named flag.
> 	(alpha_setup_incoming_varargs): Update call accordingly.
> 	* config/arc/arc.c (arc_function_arg_advance): Take a
> 	function_arg_info instead of a mode, type and named flag.
> 	(arc_setup_incoming_varargs): Update call accordingly.
> 	* config/arm/arm.c (arm_function_arg_advance): Take a
> 	function_arg_info instead of a mode, type and named flag.
> 	(cmse_func_args_or_return_in_stack): Update call accordingly.
> 	(arm_function_ok_for_sibcall): Likewise.
> 	(cmse_nonsecure_call_clear_caller_saved): Likewise.
> 	* config/avr/avr.c (avr_function_arg_advance): Take a
> 	function_arg_info instead of a mode, type and named flag.
> 	* config/bfin/bfin.c (bfin_function_arg_advance): Likewise.
> 	* config/c6x/c6x.c (c6x_function_arg_advance): Likewise.
> 	(c6x_call_saved_register_used): Update call accordingly.
> 	* config/cr16/cr16.c (cr16_function_arg_advance): Take a
> 	function_arg_info instead of a mode, type and named flag.
> 	* config/cris/cris.c (cris_function_arg_advance): Likewise.
> 	* config/csky/csky.c (csky_function_arg_advance): Likewise.
> 	(csky_setup_incoming_varargs): Update call accordingly.
> 	* config/epiphany/epiphany.c (epiphany_function_arg_advance): Take a
> 	function_arg_info instead of a mode, type and named flag.
> 	* config/fr30/fr30.c (fr30_function_arg_advance): Likewise.
> 	* config/frv/frv.c (frv_function_arg_advance): Likewise.
> 	* config/ft32/ft32.c (ft32_function_arg_advance): Likewise.
> 	* config/gcn/gcn.c (gcn_function_arg_advance): Likewise.
> 	* config/h8300/h8300.c (h8300_function_arg_advance): Likewise.
> 	* config/i386/i386.c (ix86_function_arg_advance): Likewise.
> 	(ix86_setup_incoming_varargs): Update call accordingly.
> 	* config/ia64/ia64.c (ia64_function_arg_advance): Take a
> 	function_arg_info instead of a mode, type and named flag.
> 	(ia64_setup_incoming_varargs): Update call accordingly.
> 	* config/iq2000/iq2000.c (iq2000_function_arg_advance): Take a
> 	function_arg_info instead of a mode, type and named flag.
> 	(iq2000_expand_prologue): Update call accordingly.
> 	* config/lm32/lm32.c (lm32_function_arg_advance): Take a
> 	function_arg_info instead of a mode, type and named flag.
> 	* config/m32c/m32c.c (m32c_function_arg_advance): Likewise.
> 	* config/m32r/m32r.c (m32r_function_arg_advance): Likewise.
> 	* config/m68k/m68k.c (m68k_function_arg_advance): Likewise.
> 	* config/mcore/mcore.c (mcore_function_arg_advance): Likewise.
> 	* config/microblaze/microblaze.c (microblaze_function_arg_advance):
> 	Likewise.
> 	(microblaze_expand_prologue): Update call accordingly.
> 	* config/mips/mips.c (mips_function_arg_advance): Take a
> 	function_arg_info instead of a mode, type and named flag.
> 	(mips_setup_incoming_varargs): Update call accordingly.
> 	(mips_output_args_xfer): Likewise.
> 	* config/mmix/mmix.c (mmix_function_arg_advance): Take a
> 	function_arg_info instead of a mode, type and named flag.
> 	* config/mn10300/mn10300.c (mn10300_function_arg_advance): Likewise.
> 	* config/moxie/moxie.c (moxie_function_arg_advance): Likewise.
> 	* config/msp430/msp430.c (msp430_function_arg_advance): Likewise.
> 	* config/nds32/nds32.c (nds32_function_arg_advance): Likewise.
> 	* config/nios2/nios2.c (nios2_function_arg_advance): Likewise.
> 	(nios2_setup_incoming_varargs): Update call accordingly.
> 	* config/nvptx/nvptx.c (nvptx_function_arg_advance): Take a
> 	function_arg_info instead of a mode, type and named flag.
> 	* config/or1k/or1k.c (or1k_function_arg_advance): Likewise.
> 	* config/pa/pa.c (pa_function_arg_advance): Likewise.
> 	* config/pdp11/pdp11.c (pdp11_function_arg_advance): Likewise.
> 	* config/pru/pru.c (pru_function_arg_advance): Likewise.
> 	* config/riscv/riscv.c (riscv_function_arg_advance): Likewise.
> 	(riscv_setup_incoming_varargs): Update call accordingly.
> 	* config/rl78/rl78.c (rl78_function_arg_advance): Take a
> 	function_arg_info instead of a mode, type and named flag.
> 	* config/rs6000/rs6000-internal.h (rs6000_function_arg_advance):
> 	Likewise.
> 	* config/rs6000/rs6000-call.c (rs6000_function_arg_advance): Likewise.
> 	(rs6000_parm_needs_stack): Update call accordingly.
> 	* config/rx/rx.c (rx_function_arg_advance): Take a function_arg_info
> 	instead of a mode, type and named flag.
> 	* config/s390/s390.c (s390_function_arg_advance): Likewise.
> 	(s390_call_saved_register_used): Update call accordingly.
> 	* config/sh/sh.c (sh_function_arg_advance): Take a function_arg_info
> 	instead of a mode, type and named flag.
> 	(sh_output_mi_thunk): Update call accordingly.
> 	* config/sparc/sparc.c (sparc_function_arg_advance): Take a
> 	function_arg_info instead of a mode, type and named flag.
> 	* config/spu/spu.c (spu_function_arg_advance): Likewise.
> 	(spu_setup_incoming_varargs): Update call accordingly.
> 	* config/stormy16/stormy16.c (xstormy16_function_arg_advance): Take a
> 	function_arg_info instead of a mode, type and named flag.
> 	* config/tilegx/tilegx.c (tilegx_function_arg_advance): Likewise.
> 	(tilegx_setup_incoming_varargs): Update call accordingly.
> 	* config/tilepro/tilepro.c (tilepro_function_arg_advance): Take a
> 	function_arg_info instead of a mode, type and named flag.
> 	(tilegx_setup_incoming_varargs): Update call accordingly.
> 	* config/v850/v850.c (v850_function_arg_advance): Take a
> 	function_arg_info instead of a mode, type and named flag.
> 	* config/vax/vax.c (vax_function_arg_advance): Likewise.
> 	* config/visium/visium.c (visium_function_arg_advance): Likewise.
> 	(visium_setup_incoming_varargs): Update call accordingly.
> 	* config/xtensa/xtensa.c (xtensa_function_arg_advance): Take a
> 	function_arg_info instead of a mode, type and named flag.
> 

OK
jeff

Patch
diff mbox series

Index: gcc/target.def
===================================================================
--- gcc/target.def	2019-08-19 15:58:42.425976307 +0100
+++ gcc/target.def	2019-08-19 15:58:50.345918999 +0100
@@ -4686,8 +4686,7 @@  register to be used by the caller for th
 DEFHOOK
 (function_arg_advance,
  "This hook updates the summarizer variable pointed to by @var{ca} to\n\
-advance past an argument in the argument list.  The values @var{mode},\n\
-@var{type} and @var{named} describe that argument.  Once this is done,\n\
+advance past argument @var{arg} in the argument list.  Once this is done,\n\
 the variable @var{cum} is suitable for analyzing the @emph{following}\n\
 argument with @code{TARGET_FUNCTION_ARG}, etc.\n\
 \n\
@@ -4695,7 +4694,7 @@  This hook need not do anything if the ar
 on the stack.  The compiler knows how to track the amount of stack space\n\
 used for arguments without any special help.",
  void,
- (cumulative_args_t ca, machine_mode mode, const_tree type, bool named),
+ (cumulative_args_t ca, const function_arg_info &arg),
  default_function_arg_advance)
 
 DEFHOOK
Index: gcc/doc/tm.texi
===================================================================
--- gcc/doc/tm.texi	2019-08-19 15:58:42.421976335 +0100
+++ gcc/doc/tm.texi	2019-08-19 15:58:50.341919030 +0100
@@ -4159,10 +4159,9 @@  argument @var{libname} exists for symmet
 @c --mew 5feb93   i switched the order of the sentences.  --mew 10feb93
 @end defmac
 
-@deftypefn {Target Hook} void TARGET_FUNCTION_ARG_ADVANCE (cumulative_args_t @var{ca}, machine_mode @var{mode}, const_tree @var{type}, bool @var{named})
+@deftypefn {Target Hook} void TARGET_FUNCTION_ARG_ADVANCE (cumulative_args_t @var{ca}, const function_arg_info @var{&arg})
 This hook updates the summarizer variable pointed to by @var{ca} to
-advance past an argument in the argument list.  The values @var{mode},
-@var{type} and @var{named} describe that argument.  Once this is done,
+advance past argument @var{arg} in the argument list.  Once this is done,
 the variable @var{cum} is suitable for analyzing the @emph{following}
 argument with @code{TARGET_FUNCTION_ARG}, etc.
 
Index: gcc/targhooks.h
===================================================================
--- gcc/targhooks.h	2019-08-19 15:58:42.425976307 +0100
+++ gcc/targhooks.h	2019-08-19 15:58:50.345918999 +0100
@@ -148,7 +148,7 @@  extern bool hook_bool_CUMULATIVE_ARGS_tr
 extern const char *hook_invalid_arg_for_unprototyped_fn
   (const_tree, const_tree, const_tree);
 extern void default_function_arg_advance
-  (cumulative_args_t, machine_mode, const_tree, bool);
+  (cumulative_args_t, const function_arg_info &);
 extern HOST_WIDE_INT default_function_arg_offset (machine_mode, const_tree);
 extern pad_direction default_function_arg_padding (machine_mode, const_tree);
 extern rtx default_function_arg (cumulative_args_t, const function_arg_info &);
Index: gcc/targhooks.c
===================================================================
--- gcc/targhooks.c	2019-08-19 15:58:42.425976307 +0100
+++ gcc/targhooks.c	2019-08-19 15:58:50.345918999 +0100
@@ -784,10 +784,7 @@  hook_void_CUMULATIVE_ARGS_tree (cumulati
 }
 
 void
-default_function_arg_advance (cumulative_args_t ca ATTRIBUTE_UNUSED,
-			      machine_mode mode ATTRIBUTE_UNUSED,
-			      const_tree type ATTRIBUTE_UNUSED,
-			      bool named ATTRIBUTE_UNUSED)
+default_function_arg_advance (cumulative_args_t, const function_arg_info &)
 {
   gcc_unreachable ();
 }
Index: gcc/calls.c
===================================================================
--- gcc/calls.c	2019-08-19 15:58:42.381976625 +0100
+++ gcc/calls.c	2019-08-19 15:58:50.301919320 +0100
@@ -2192,8 +2192,13 @@  initialize_argument_information (int num
       /* Increment ARGS_SO_FAR, which has info about which arg-registers
 	 have been used, etc.  */
 
-      targetm.calls.function_arg_advance (args_so_far, TYPE_MODE (type),
-					  type, argpos < n_named_args);
+      /* ??? Traditionally we've passed TYPE_MODE here, instead of the
+	 promoted_mode used for function_arg above.  However, the
+	 corresponding handling of incoming arguments in function.c
+	 does pass the promoted mode.  */
+      function_arg_info arg_to_skip (type, TYPE_MODE (type),
+				     argpos < n_named_args);
+      targetm.calls.function_arg_advance (args_so_far, arg_to_skip);
 
       /* Store argument values for functions decorated with attribute
 	 alloc_size.  */
@@ -4881,7 +4886,7 @@  emit_library_call_value_1 (int retval, r
 	  || reg_parm_stack_space > 0)
 	args_size.constant += argvec[count].locate.size.constant;
 
-      targetm.calls.function_arg_advance (args_so_far, Pmode, (tree) 0, true);
+      targetm.calls.function_arg_advance (args_so_far, ptr_arg);
 
       count++;
     }
@@ -4977,7 +4982,7 @@  emit_library_call_value_1 (int retval, r
 			     known_le (GET_MODE_SIZE (mode), UNITS_PER_WORD));
 #endif
 
-      targetm.calls.function_arg_advance (args_so_far, mode, (tree) 0, true);
+      targetm.calls.function_arg_advance (args_so_far, arg);
     }
 
   for (int i = 0; i < nargs; i++)
Index: gcc/dse.c
===================================================================
--- gcc/dse.c	2019-08-19 15:58:42.421976335 +0100
+++ gcc/dse.c	2019-08-19 15:58:50.345918999 +0100
@@ -2377,7 +2377,7 @@  get_call_args (rtx call_insn, tree fn, r
       if (tmp)
 	args[idx] = tmp;
 
-      targetm.calls.function_arg_advance (args_so_far, mode, NULL_TREE, true);
+      targetm.calls.function_arg_advance (args_so_far, arg);
     }
   if (arg != void_list_node || idx != nargs)
     return false;
Index: gcc/expr.c
===================================================================
--- gcc/expr.c	2019-08-19 15:58:42.425976307 +0100
+++ gcc/expr.c	2019-08-19 15:58:50.345918999 +0100
@@ -1715,8 +1715,7 @@  block_move_libcall_safe_for_call_parm (v
 	  return false;
 	if (targetm.calls.arg_partial_bytes (args_so_far, arg_info))
 	  return false;
-	targetm.calls.function_arg_advance (args_so_far, mode,
-					    NULL_TREE, true);
+	targetm.calls.function_arg_advance (args_so_far, arg_info);
       }
   }
   return true;
Index: gcc/function.c
===================================================================
--- gcc/function.c	2019-08-19 15:58:42.425976307 +0100
+++ gcc/function.c	2019-08-19 15:58:50.345918999 +0100
@@ -3657,8 +3657,9 @@  assign_parms (tree fndecl)
 	assign_parms_setup_varargs (&all, &data, false);
 
       /* Update info on where next arg arrives in registers.  */
-      targetm.calls.function_arg_advance (all.args_so_far, data.promoted_mode,
-					  data.passed_type, data.named_arg);
+      function_arg_info arg (data.passed_type, data.promoted_mode,
+			     data.named_arg);
+      targetm.calls.function_arg_advance (all.args_so_far, arg);
     }
 
   if (targetm.calls.split_complex_arg)
@@ -3845,8 +3846,9 @@  gimplify_parameters (gimple_seq *cleanup
 	continue;
 
       /* Update info on where next arg arrives in registers.  */
-      targetm.calls.function_arg_advance (all.args_so_far, data.promoted_mode,
-					  data.passed_type, data.named_arg);
+      function_arg_info arg (data.passed_type, data.promoted_mode,
+			     data.named_arg);
+      targetm.calls.function_arg_advance (all.args_so_far, arg);
 
       /* ??? Once upon a time variable_size stuffed parameter list
 	 SAVE_EXPRs (amongst others) onto a pending sizes list.  This
Index: gcc/var-tracking.c
===================================================================
--- gcc/var-tracking.c	2019-08-19 15:58:42.425976307 +0100
+++ gcc/var-tracking.c	2019-08-19 15:58:50.345918999 +0100
@@ -6293,14 +6293,12 @@  prepare_call_arguments (basic_block bb,
 		  && targetm.calls.struct_value_rtx (type, 0) == 0)
 		{
 		  tree struct_addr = build_pointer_type (TREE_TYPE (type));
-		  machine_mode mode = TYPE_MODE (struct_addr);
 		  function_arg_info arg (struct_addr, /*named=*/true);
 		  rtx reg;
 		  INIT_CUMULATIVE_ARGS (args_so_far_v, type, NULL_RTX, fndecl,
 					nargs + 1);
 		  reg = targetm.calls.function_arg (args_so_far, arg);
-		  targetm.calls.function_arg_advance (args_so_far, mode,
-						      struct_addr, true);
+		  targetm.calls.function_arg_advance (args_so_far, arg);
 		  if (reg == NULL_RTX)
 		    {
 		      for (; link; link = XEXP (link, 1))
@@ -6489,8 +6487,7 @@  prepare_call_arguments (basic_block bb,
 			}
 		  }
 	      }
-	    targetm.calls.function_arg_advance (args_so_far, mode,
-						argtype, true);
+	    targetm.calls.function_arg_advance (args_so_far, arg);
 	    t = TREE_CHAIN (t);
 	  }
       }
Index: gcc/config/aarch64/aarch64.c
===================================================================
--- gcc/config/aarch64/aarch64.c	2019-08-19 15:58:42.385976597 +0100
+++ gcc/config/aarch64/aarch64.c	2019-08-19 15:58:50.305919288 +0100
@@ -4846,14 +4846,12 @@  aarch64_init_cumulative_args (CUMULATIVE
 
 static void
 aarch64_function_arg_advance (cumulative_args_t pcum_v,
-			      machine_mode mode,
-			      const_tree type,
-			      bool named)
+			      const function_arg_info &arg)
 {
   CUMULATIVE_ARGS *pcum = get_cumulative_args (pcum_v);
   if (pcum->pcs_variant == ARM_PCS_AAPCS64)
     {
-      aarch64_layout_arg (pcum_v, mode, type, named);
+      aarch64_layout_arg (pcum_v, arg.mode, arg.type, arg.named);
       gcc_assert ((pcum->aapcs_reg != NULL_RTX)
 		  != (pcum->aapcs_stack_words != 0));
       pcum->aapcs_arg_processed = false;
@@ -14523,8 +14521,7 @@  aarch64_setup_incoming_varargs (cumulati
      argument.  Advance a local copy of CUM past the last "real" named
      argument, to find out how many registers are left over.  */
   local_cum = *cum;
-  aarch64_function_arg_advance (pack_cumulative_args(&local_cum),
-				arg.mode, arg.type, arg.named);
+  aarch64_function_arg_advance (pack_cumulative_args(&local_cum), arg);
 
   /* Found out how many registers we need to save.
      Honor tree-stdvar analysis results.  */
Index: gcc/config/alpha/alpha.c
===================================================================
--- gcc/config/alpha/alpha.c	2019-08-19 15:58:42.385976597 +0100
+++ gcc/config/alpha/alpha.c	2019-08-19 15:58:50.309919261 +0100
@@ -5606,23 +5606,21 @@  alpha_function_arg (cumulative_args_t cu
   return gen_rtx_REG (arg.mode, num_args + basereg);
 }
 
-/* Update the data in CUM to advance over an argument
-   of mode MODE and data type TYPE.
-   (TYPE is null for libcalls where that information may not be available.)  */
+/* Update the data in CUM to advance over argument ARG.  */
 
 static void
-alpha_function_arg_advance (cumulative_args_t cum_v, machine_mode mode,
-			    const_tree type, bool named ATTRIBUTE_UNUSED)
+alpha_function_arg_advance (cumulative_args_t cum_v,
+			    const function_arg_info &arg)
 {
   CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
-  bool onstack = targetm.calls.must_pass_in_stack (mode, type);
-  int increment = onstack ? 6 : ALPHA_ARG_SIZE (mode, type);
+  bool onstack = targetm.calls.must_pass_in_stack (arg.mode, arg.type);
+  int increment = onstack ? 6 : ALPHA_ARG_SIZE (arg.mode, arg.type);
 
 #if TARGET_ABI_OSF
   *cum += increment;
 #else
   if (!onstack && cum->num_args < 6)
-    cum->atypes[cum->num_args] = alpha_arg_type (mode);
+    cum->atypes[cum->num_args] = alpha_arg_type (arg.mode);
   cum->num_args += increment;
 #endif
 }
@@ -6090,8 +6088,7 @@  alpha_setup_incoming_varargs (cumulative
   CUMULATIVE_ARGS cum = *get_cumulative_args (pcum);
 
   /* Skip the current argument.  */
-  targetm.calls.function_arg_advance (pack_cumulative_args (&cum),
-				      arg.mode, arg.type, arg.named);
+  targetm.calls.function_arg_advance (pack_cumulative_args (&cum), arg);
 
 #if TARGET_ABI_OPEN_VMS
   /* For VMS, we allocate space for all 6 arg registers plus a count.
Index: gcc/config/arc/arc.c
===================================================================
--- gcc/config/arc/arc.c	2019-08-19 15:58:42.389976569 +0100
+++ gcc/config/arc/arc.c	2019-08-19 15:58:50.309919261 +0100
@@ -642,8 +642,8 @@  static bool arc_can_follow_jump (const r
 				 const rtx_insn *followee);
 
 static rtx frame_insn (rtx);
-static void arc_function_arg_advance (cumulative_args_t, machine_mode,
-				      const_tree, bool);
+static void arc_function_arg_advance (cumulative_args_t,
+				      const function_arg_info &);
 static rtx arc_legitimize_address_0 (rtx, rtx, machine_mode mode);
 
 /* initialize the GCC target structure.  */
@@ -2429,8 +2429,7 @@  arc_setup_incoming_varargs (cumulative_a
   /* We must treat `__builtin_va_alist' as an anonymous arg.  */
 
   next_cum = *get_cumulative_args (args_so_far);
-  arc_function_arg_advance (pack_cumulative_args (&next_cum),
-			    arg.mode, arg.type, arg.named);
+  arc_function_arg_advance (pack_cumulative_args (&next_cum), arg);
   first_anon_arg = next_cum;
 
   if (FUNCTION_ARG_REGNO_P (first_anon_arg))
@@ -6480,17 +6479,7 @@  arc_function_arg (cumulative_args_t cum_
   return ret;
 }
 
-/* The function to update the summarizer variable *CUM to advance past
-   an argument in the argument list.  The values MODE, TYPE and NAMED
-   describe that argument.  Once this is done, the variable *CUM is
-   suitable for analyzing the *following* argument with
-   `FUNCTION_ARG', etc.
-
-   This function need not do anything if the argument in question was
-   passed on the stack.  The compiler knows how to track the amount of
-   stack space used for arguments without any special help.
-
-   The function is used to implement macro FUNCTION_ARG_ADVANCE.  */
+/* Implement TARGET_FUNCTION_ARG_ADVANCE.  */
 /* For the ARC: the cum set here is passed on to function_arg where we
    look at its value and say which reg to use. Strategy: advance the
    regnumber here till we run out of arg regs, then set *cum to last
@@ -6500,18 +6489,15 @@  arc_function_arg (cumulative_args_t cum_
 
 static void
 arc_function_arg_advance (cumulative_args_t cum_v,
-			  machine_mode mode,
-			  const_tree type,
-			  bool named ATTRIBUTE_UNUSED)
+			  const function_arg_info &arg)
 {
   CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
-  int bytes = (mode == BLKmode
-	       ? int_size_in_bytes (type) : (int) GET_MODE_SIZE (mode));
+  int bytes = arg.promoted_size_in_bytes ();
   int words = (bytes + UNITS_PER_WORD  - 1) / UNITS_PER_WORD;
   int i;
 
   if (words)
-    *cum = ROUND_ADVANCE_CUM (*cum, mode, type);
+    *cum = ROUND_ADVANCE_CUM (*cum, arg.mode, arg.type);
   for (i = 0; i < words; i++)
     *cum = ARC_NEXT_ARG_REG (*cum);
 
Index: gcc/config/arm/arm.c
===================================================================
--- gcc/config/arm/arm.c	2019-08-19 15:58:42.393976538 +0100
+++ gcc/config/arm/arm.c	2019-08-19 15:58:50.317919202 +0100
@@ -190,8 +190,8 @@  static rtx emit_multi_reg_push (unsigned
 static int arm_arg_partial_bytes (cumulative_args_t,
 				  const function_arg_info &);
 static rtx arm_function_arg (cumulative_args_t, const function_arg_info &);
-static void arm_function_arg_advance (cumulative_args_t, machine_mode,
-				      const_tree, bool);
+static void arm_function_arg_advance (cumulative_args_t,
+				      const function_arg_info &);
 static pad_direction arm_function_arg_padding (machine_mode, const_tree);
 static unsigned int arm_function_arg_boundary (machine_mode, const_tree);
 static rtx aapcs_allocate_return_reg (machine_mode, const_tree,
@@ -6770,24 +6770,22 @@  arm_arg_partial_bytes (cumulative_args_t
   return 0;
 }
 
-/* Update the data in PCUM to advance over an argument
-   of mode MODE and data type TYPE.
-   (TYPE is null for libcalls where that information may not be available.)  */
+/* Update the data in PCUM to advance over argument ARG.  */
 
 static void
-arm_function_arg_advance (cumulative_args_t pcum_v, machine_mode mode,
-			  const_tree type, bool named)
+arm_function_arg_advance (cumulative_args_t pcum_v,
+			  const function_arg_info &arg)
 {
   CUMULATIVE_ARGS *pcum = get_cumulative_args (pcum_v);
 
   if (pcum->pcs_variant <= ARM_PCS_AAPCS_LOCAL)
     {
-      aapcs_layout_arg (pcum, mode, type, named);
+      aapcs_layout_arg (pcum, arg.mode, arg.type, arg.named);
 
       if (pcum->aapcs_cprc_slot >= 0)
 	{
-	  aapcs_cp_arg_layout[pcum->aapcs_cprc_slot].advance (pcum, mode,
-							      type);
+	  aapcs_cp_arg_layout[pcum->aapcs_cprc_slot].advance (pcum, arg.mode,
+							      arg.type);
 	  pcum->aapcs_cprc_slot = -1;
 	}
 
@@ -6800,12 +6798,12 @@  arm_function_arg_advance (cumulative_arg
   else
     {
       pcum->nargs += 1;
-      if (arm_vector_mode_supported_p (mode)
+      if (arm_vector_mode_supported_p (arg.mode)
 	  && pcum->named_count > pcum->nargs
 	  && TARGET_IWMMXT_ABI)
 	pcum->iwmmxt_nregs += 1;
       else
-	pcum->nregs += ARM_NUM_REGS2 (mode, type);
+	pcum->nregs += ARM_NUM_REGS2 (arg.mode, arg.type);
     }
 }
 
@@ -6984,7 +6982,6 @@  cmse_func_args_or_return_in_stack (tree
   FOREACH_FUNCTION_ARGS (fntype, arg_type, args_iter)
     {
       rtx arg_rtx;
-      machine_mode arg_mode = TYPE_MODE (arg_type);
 
       prev_arg_type = arg_type;
       if (VOID_TYPE_P (arg_type))
@@ -6992,7 +6989,9 @@  cmse_func_args_or_return_in_stack (tree
 
       function_arg_info arg (arg_type, /*named=*/true);
       if (!first_param)
-	arm_function_arg_advance (args_so_far, arg_mode, arg_type, true);
+	/* ??? We should advance after processing the argument and pass
+	   the argument we're advancing past.  */
+	arm_function_arg_advance (args_so_far, arg);
       arg_rtx = arm_function_arg (args_so_far, arg);
       if (!arg_rtx || arm_arg_partial_bytes (args_so_far, arg))
 	{
@@ -7378,7 +7377,10 @@  arm_function_ok_for_sibcall (tree decl,
 	{
 	  tree type = TREE_VALUE (t);
 	  if (!VOID_TYPE_P (type))
-	    arm_function_arg_advance (cum_v, TYPE_MODE (type), type, true);
+	    {
+	      function_arg_info arg (type, /*named=*/true);
+	      arm_function_arg_advance (cum_v, arg);
+	    }
 	}
 
       function_arg_info arg (integer_type_node, /*named=*/true);
@@ -17441,15 +17443,15 @@  cmse_nonsecure_call_clear_caller_saved (
 	    {
 	      rtx arg_rtx;
 	      uint64_t to_clear_args_mask;
-	      machine_mode arg_mode = TYPE_MODE (arg_type);
 
 	      if (VOID_TYPE_P (arg_type))
 		continue;
 
 	      function_arg_info arg (arg_type, /*named=*/true);
 	      if (!first_param)
-		arm_function_arg_advance (args_so_far, arg_mode, arg_type,
-					  true);
+		/* ??? We should advance after processing the argument and pass
+		   the argument we're advancing past.  */
+		arm_function_arg_advance (args_so_far, arg);
 
 	      arg_rtx = arm_function_arg (args_so_far, arg);
 	      gcc_assert (REG_P (arg_rtx));
Index: gcc/config/avr/avr.c
===================================================================
--- gcc/config/avr/avr.c	2019-08-19 15:58:42.397976511 +0100
+++ gcc/config/avr/avr.c	2019-08-19 15:58:50.317919202 +0100
@@ -3405,11 +3405,11 @@  avr_function_arg (cumulative_args_t cum_
    in the argument list.  */
 
 static void
-avr_function_arg_advance (cumulative_args_t cum_v, machine_mode mode,
-                          const_tree type, bool named ATTRIBUTE_UNUSED)
+avr_function_arg_advance (cumulative_args_t cum_v,
+			  const function_arg_info &arg)
 {
   CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
-  int bytes = avr_num_arg_regs (mode, type);
+  int bytes = avr_num_arg_regs (arg.mode, arg.type);
 
   cum->nregs -= bytes;
   cum->regno -= bytes;
Index: gcc/config/bfin/bfin.c
===================================================================
--- gcc/config/bfin/bfin.c	2019-08-19 15:58:42.397976511 +0100
+++ gcc/config/bfin/bfin.c	2019-08-19 15:58:50.317919202 +0100
@@ -1647,18 +1647,16 @@  init_cumulative_args (CUMULATIVE_ARGS *c
   return;
 }
 
-/* Update the data in CUM to advance over an argument
-   of mode MODE and data type TYPE.
-   (TYPE is null for libcalls where that information may not be available.)  */
+/* Update the data in CUM to advance over argument ARG.  */
 
 static void
-bfin_function_arg_advance (cumulative_args_t cum_v, machine_mode mode,
-			   const_tree type, bool named ATTRIBUTE_UNUSED)
+bfin_function_arg_advance (cumulative_args_t cum_v,
+			   const function_arg_info &arg)
 {
   CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
   int count, bytes, words;
 
-  bytes = (mode == BLKmode) ? int_size_in_bytes (type) : GET_MODE_SIZE (mode);
+  bytes = arg.promoted_size_in_bytes ();
   words = (bytes + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
 
   cum->words += words;
Index: gcc/config/c6x/c6x.c
===================================================================
--- gcc/config/c6x/c6x.c	2019-08-19 15:58:42.397976511 +0100
+++ gcc/config/c6x/c6x.c	2019-08-19 15:58:50.317919202 +0100
@@ -526,10 +526,7 @@  c6x_function_arg (cumulative_args_t cum_
 }
 
 static void
-c6x_function_arg_advance (cumulative_args_t cum_v,
-			  machine_mode mode ATTRIBUTE_UNUSED,
-			  const_tree type ATTRIBUTE_UNUSED,
-			  bool named ATTRIBUTE_UNUSED)
+c6x_function_arg_advance (cumulative_args_t cum_v, const function_arg_info &)
 {
   CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
   cum->count++;
@@ -1136,7 +1133,7 @@  c6x_call_saved_register_used (tree call_
        function_arg_info arg (type, mode, /*named=*/false);
        parm_rtx = c6x_function_arg (cum, arg);
 
-       c6x_function_arg_advance (cum, mode, type, 0);
+       c6x_function_arg_advance (cum, arg);
 
        if (!parm_rtx)
 	 continue;
Index: gcc/config/cr16/cr16.c
===================================================================
--- gcc/config/cr16/cr16.c	2019-08-19 15:58:42.397976511 +0100
+++ gcc/config/cr16/cr16.c	2019-08-19 15:58:50.317919202 +0100
@@ -660,34 +660,34 @@  cr16_init_cumulative_args (CUMULATIVE_AR
 
 /* Implements the macro FUNCTION_ARG_ADVANCE defined in cr16.h.  */
 static void
-cr16_function_arg_advance (cumulative_args_t cum_v, machine_mode mode,
-			   const_tree type, bool named ATTRIBUTE_UNUSED)
+cr16_function_arg_advance (cumulative_args_t cum_v,
+			   const function_arg_info &arg)
 {
   CUMULATIVE_ARGS * cum = get_cumulative_args (cum_v);
 
   /* l holds the number of registers required.  */
-  int l = GET_MODE_BITSIZE (mode) / BITS_PER_WORD;
+  int l = GET_MODE_BITSIZE (arg.mode) / BITS_PER_WORD;
 
   /* If the parameter isn't passed on a register don't advance cum.  */
   if (!cum->last_parm_in_reg)
     return;
 
-  if (targetm.calls.must_pass_in_stack (mode, type) || (cum->ints < 0))
+  if (targetm.calls.must_pass_in_stack (arg.mode, arg.type) || (cum->ints < 0))
     return;
 
-  if ((mode == SImode) || (mode == HImode)
-      || (mode == QImode) || (mode == DImode))
+  if ((arg.mode == SImode) || (arg.mode == HImode)
+      || (arg.mode == QImode) || (arg.mode == DImode))
     {
       if (l <= 1)
 	cum->ints += 1;
       else
 	cum->ints += l;
     }
-  else if ((mode == SFmode) || (mode == DFmode))
+  else if ((arg.mode == SFmode) || (arg.mode == DFmode))
     cum->ints += l;
-  else if ((mode) == BLKmode)
+  else if (arg.mode == BLKmode)
     {
-      if ((l = enough_regs_for_param (cum, type, mode)) != 0)
+      if ((l = enough_regs_for_param (cum, arg.type, arg.mode)) != 0)
 	cum->ints += l;
     }
   return;
Index: gcc/config/cris/cris.c
===================================================================
--- gcc/config/cris/cris.c	2019-08-19 15:58:42.397976511 +0100
+++ gcc/config/cris/cris.c	2019-08-19 15:58:50.321919175 +0100
@@ -147,8 +147,8 @@  static int cris_arg_partial_bytes (cumul
 static rtx cris_function_arg (cumulative_args_t, const function_arg_info &);
 static rtx cris_function_incoming_arg (cumulative_args_t,
 				       const function_arg_info &);
-static void cris_function_arg_advance (cumulative_args_t, machine_mode,
-				       const_tree, bool);
+static void cris_function_arg_advance (cumulative_args_t,
+				       const function_arg_info &);
 static rtx_insn *cris_md_asm_adjust (vec<rtx> &, vec<rtx> &,
 				     vec<const char *> &,
 				     vec<rtx> &, HARD_REG_SET &);
@@ -4156,12 +4156,12 @@  cris_function_incoming_arg (cumulative_a
 /* Worker function for TARGET_FUNCTION_ARG_ADVANCE.  */
 
 static void
-cris_function_arg_advance (cumulative_args_t ca_v, machine_mode mode,
-			   const_tree type, bool named ATTRIBUTE_UNUSED)
+cris_function_arg_advance (cumulative_args_t ca_v,
+			   const function_arg_info &arg)
 {
   CUMULATIVE_ARGS *ca = get_cumulative_args (ca_v);
 
-  ca->regs += (3 + CRIS_FUNCTION_ARG_SIZE (mode, type)) / 4;
+  ca->regs += (3 + CRIS_FUNCTION_ARG_SIZE (arg.mode, arg.type)) / 4;
 }
 
 /* Worker function for TARGET_MD_ASM_ADJUST.  */
Index: gcc/config/csky/csky.c
===================================================================
--- gcc/config/csky/csky.c	2019-08-19 15:58:42.401976480 +0100
+++ gcc/config/csky/csky.c	2019-08-19 15:58:50.321919175 +0100
@@ -1819,11 +1819,11 @@  csky_num_arg_regs (machine_mode mode, co
 /* Implement TARGET_FUNCTION_ARG_ADVANCE.  */
 
 static void
-csky_function_arg_advance (cumulative_args_t pcum_v, machine_mode mode,
-			   const_tree type, bool named ATTRIBUTE_UNUSED)
+csky_function_arg_advance (cumulative_args_t pcum_v,
+			   const function_arg_info &arg)
 {
   CUMULATIVE_ARGS *pcum = get_cumulative_args (pcum_v);
-  int param_size = csky_num_arg_regs (mode, type);
+  int param_size = csky_num_arg_regs (arg.mode, arg.type);
 
   if (*pcum + param_size > CSKY_NPARM_REGS)
     *pcum = CSKY_NPARM_REGS;
@@ -1941,7 +1941,7 @@  csky_setup_incoming_varargs (cumulative_
 
   cfun->machine->uses_anonymous_args = 1;
   local_cum = *pcum;
-  csky_function_arg_advance (local_cum_v, arg.mode, arg.type, arg.named);
+  csky_function_arg_advance (local_cum_v, arg);
   regs_to_push = CSKY_NPARM_REGS - local_cum;
   if (regs_to_push)
     *pretend_size  = regs_to_push * UNITS_PER_WORD;
Index: gcc/config/epiphany/epiphany.c
===================================================================
--- gcc/config/epiphany/epiphany.c	2019-08-19 15:58:42.401976480 +0100
+++ gcc/config/epiphany/epiphany.c	2019-08-19 15:58:50.321919175 +0100
@@ -2269,16 +2269,15 @@  epiphany_function_arg (cumulative_args_t
   return 0;
 }
 
-/* Update the data in CUM to advance over an argument
-   of mode MODE and data type TYPE.
-   (TYPE is null for libcalls where that information may not be available.)  */
+/* Update the data in CUM to advance over argument ARG.  */
 static void
-epiphany_function_arg_advance (cumulative_args_t cum_v, machine_mode mode,
-			       const_tree type, bool named ATTRIBUTE_UNUSED)
+epiphany_function_arg_advance (cumulative_args_t cum_v,
+			       const function_arg_info &arg)
 {
   CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
 
-  *cum = ROUND_ADVANCE_CUM (*cum, mode, type) + ROUND_ADVANCE_ARG (mode, type);
+  *cum = (ROUND_ADVANCE_CUM (*cum, arg.mode, arg.type)
+	  + ROUND_ADVANCE_ARG (arg.mode, arg.type));
 }
 
 /* Nested function support.
Index: gcc/config/fr30/fr30.c
===================================================================
--- gcc/config/fr30/fr30.c	2019-08-19 15:58:42.401976480 +0100
+++ gcc/config/fr30/fr30.c	2019-08-19 15:58:50.321919175 +0100
@@ -120,8 +120,8 @@  static bool fr30_must_pass_in_stack (mac
 static int fr30_arg_partial_bytes (cumulative_args_t,
 				   const function_arg_info &);
 static rtx fr30_function_arg (cumulative_args_t, const function_arg_info &);
-static void fr30_function_arg_advance (cumulative_args_t, machine_mode,
-				       const_tree, bool);
+static void fr30_function_arg_advance (cumulative_args_t,
+				       const function_arg_info &);
 static bool fr30_frame_pointer_required (void);
 static rtx fr30_function_value (const_tree, const_tree, bool);
 static rtx fr30_libcall_value (machine_mode, const_rtx);
@@ -811,19 +811,13 @@  fr30_function_arg (cumulative_args_t cum
     return gen_rtx_REG (arg.mode, *cum + FIRST_ARG_REGNUM);
 }
 
-/* A C statement (sans semicolon) to update the summarizer variable CUM to
-   advance past an argument in the argument list.  The values MODE, TYPE and
-   NAMED describe that argument.  Once this is done, the variable CUM is
-   suitable for analyzing the *following* argument with `FUNCTION_ARG', etc.
-
-   This macro need not do anything if the argument in question was passed on
-   the stack.  The compiler knows how to track the amount of stack space used
-   for arguments without any special help.  */
+/* Implement TARGET_FUNCTION_ARG_ADVANCE.  */
 static void
-fr30_function_arg_advance (cumulative_args_t cum, machine_mode mode,
-			   const_tree type, bool named)
+fr30_function_arg_advance (cumulative_args_t cum,
+			   const function_arg_info &arg)
 {
-  *get_cumulative_args (cum) += named * fr30_num_arg_regs (mode, type);
+  if (arg.named)
+    *get_cumulative_args (cum) += fr30_num_arg_regs (arg.mode, arg.type);
 }
 
 /*}}}*/
Index: gcc/config/frv/frv.c
===================================================================
--- gcc/config/frv/frv.c	2019-08-19 15:58:42.401976480 +0100
+++ gcc/config/frv/frv.c	2019-08-19 15:58:50.321919175 +0100
@@ -385,8 +385,8 @@  static int frv_arg_partial_bytes (cumula
 static rtx frv_function_arg (cumulative_args_t, const function_arg_info &);
 static rtx frv_function_incoming_arg (cumulative_args_t,
 				      const function_arg_info &);
-static void frv_function_arg_advance (cumulative_args_t, machine_mode,
-				       const_tree, bool);
+static void frv_function_arg_advance (cumulative_args_t,
+				      const function_arg_info &);
 static unsigned int frv_function_arg_boundary	(machine_mode,
 						 const_tree);
 static void frv_output_dwarf_dtprel		(FILE *, int, rtx)
@@ -3149,24 +3149,15 @@  frv_function_incoming_arg (cumulative_ar
 }
 
 
-/* A C statement (sans semicolon) to update the summarizer variable CUM to
-   advance past an argument in the argument list.  The values MODE, TYPE and
-   NAMED describe that argument.  Once this is done, the variable CUM is
-   suitable for analyzing the *following* argument with `FUNCTION_ARG', etc.
-
-   This macro need not do anything if the argument in question was passed on
-   the stack.  The compiler knows how to track the amount of stack space used
-   for arguments without any special help.  */
+/* Implement TARGET_FUNCTION_ARG_ADVANCE.  */
 
 static void
 frv_function_arg_advance (cumulative_args_t cum_v,
-                          machine_mode mode,
-                          const_tree type ATTRIBUTE_UNUSED,
-                          bool named)
+			  const function_arg_info &arg)
 {
   CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
 
-  machine_mode xmode = (mode == BLKmode) ? SImode : mode;
+  machine_mode xmode = (arg.mode == BLKmode) ? SImode : arg.mode;
   int bytes = GET_MODE_SIZE (xmode);
   int words = (bytes + UNITS_PER_WORD  - 1) / UNITS_PER_WORD;
   int arg_num = *cum;
@@ -3176,7 +3167,8 @@  frv_function_arg_advance (cumulative_arg
   if (TARGET_DEBUG_ARG)
     fprintf (stderr,
 	     "function_adv: words = %2d, mode = %4s, named = %d, size = %3d\n",
-	     arg_num, GET_MODE_NAME (mode), named, words * UNITS_PER_WORD);
+	     arg_num, GET_MODE_NAME (arg.mode), arg.named,
+	     words * UNITS_PER_WORD);
 }
 
 
Index: gcc/config/ft32/ft32.c
===================================================================
--- gcc/config/ft32/ft32.c	2019-08-19 15:58:42.401976480 +0100
+++ gcc/config/ft32/ft32.c	2019-08-19 15:58:50.321919175 +0100
@@ -672,13 +672,14 @@  #define FT32_FUNCTION_ARG_SIZE(MODE, TYP
    : (unsigned) int_size_in_bytes (TYPE))
 
 static void
-ft32_function_arg_advance (cumulative_args_t cum_v, machine_mode mode,
-                           const_tree type, bool named ATTRIBUTE_UNUSED)
+ft32_function_arg_advance (cumulative_args_t cum_v,
+			   const function_arg_info &arg)
 {
   CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
 
   *cum = (*cum < FT32_R6
-          ? *cum + ((3 + FT32_FUNCTION_ARG_SIZE (mode, type)) / 4) : *cum);
+	  ? *cum + ((3 + FT32_FUNCTION_ARG_SIZE (arg.mode, arg.type)) / 4)
+	  : *cum);
 }
 
 /* Return non-zero if the function argument described by ARG is to be
Index: gcc/config/gcn/gcn.c
===================================================================
--- gcc/config/gcn/gcn.c	2019-08-19 15:58:42.401976480 +0100
+++ gcc/config/gcn/gcn.c	2019-08-19 15:58:50.321919175 +0100
@@ -2313,17 +2313,17 @@  gcn_function_arg (cumulative_args_t cum_
    argument in the argument list.  */
 
 static void
-gcn_function_arg_advance (cumulative_args_t cum_v, machine_mode mode,
-			  const_tree type, bool named)
+gcn_function_arg_advance (cumulative_args_t cum_v,
+			  const function_arg_info &arg)
 {
   CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
 
   if (cum->normal_function)
     {
-      if (!named)
+      if (!arg.named)
 	return;
 
-      int num_regs = num_arg_regs (mode, type);
+      int num_regs = num_arg_regs (arg.mode, arg.type);
       if (num_regs > 0)
 	while ((FIRST_PARM_REG + cum->num) % num_regs != 0)
 	  cum->num++;
@@ -2335,7 +2335,7 @@  gcn_function_arg_advance (cumulative_arg
 	cum->num++;
       else
 	{
-	  cum->offset += tree_to_uhwi (TYPE_SIZE_UNIT (type));
+	  cum->offset += tree_to_uhwi (TYPE_SIZE_UNIT (arg.type));
 	  cfun->machine->kernarg_segment_byte_size = cum->offset;
 	}
     }
Index: gcc/config/h8300/h8300.c
===================================================================
--- gcc/config/h8300/h8300.c	2019-08-19 15:58:42.405976452 +0100
+++ gcc/config/h8300/h8300.c	2019-08-19 15:58:50.325919144 +0100
@@ -1151,19 +1151,16 @@  h8300_function_arg (cumulative_args_t cu
   return result;
 }
 
-/* Update the data in CUM to advance over an argument
-   of mode MODE and data type TYPE.
-   (TYPE is null for libcalls where that information may not be available.)  */
+/* Update the data in CUM to advance over argument ARG.  */
 
 static void
-h8300_function_arg_advance (cumulative_args_t cum_v, machine_mode mode,
-			    const_tree type, bool named ATTRIBUTE_UNUSED)
+h8300_function_arg_advance (cumulative_args_t cum_v,
+			    const function_arg_info &arg)
 {
   CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
 
-  cum->nbytes += (mode != BLKmode
-		  ? (GET_MODE_SIZE (mode) + UNITS_PER_WORD - 1) & -UNITS_PER_WORD
-		  : (int_size_in_bytes (type) + UNITS_PER_WORD - 1) & -UNITS_PER_WORD);
+  cum->nbytes += ((arg.promoted_size_in_bytes () + UNITS_PER_WORD - 1)
+		  & -UNITS_PER_WORD);
 }
 
 
Index: gcc/config/i386/i386.c
===================================================================
--- gcc/config/i386/i386.c	2019-08-19 15:58:42.405976452 +0100
+++ gcc/config/i386/i386.c	2019-08-19 15:58:50.325919144 +0100
@@ -2919,15 +2919,14 @@  function_arg_advance_ms_64 (CUMULATIVE_A
   return 0;
 }
 
-/* Update the data in CUM to advance over an argument of mode MODE and
-   data type TYPE.  (TYPE is null for libcalls where that information
-   may not be available.)  */
+/* Update the data in CUM to advance over argument ARG.  */
 
 static void
-ix86_function_arg_advance (cumulative_args_t cum_v, machine_mode mode,
-			   const_tree type, bool named)
+ix86_function_arg_advance (cumulative_args_t cum_v,
+			   const function_arg_info &arg)
 {
   CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
+  machine_mode mode = arg.mode;
   HOST_WIDE_INT bytes, words;
   int nregs;
 
@@ -2936,14 +2935,11 @@  ix86_function_arg_advance (cumulative_ar
   if (!cum->caller && cfun->machine->func_type != TYPE_NORMAL)
     return;
 
-  if (mode == BLKmode)
-    bytes = int_size_in_bytes (type);
-  else
-    bytes = GET_MODE_SIZE (mode);
+  bytes = arg.promoted_size_in_bytes ();
   words = CEIL (bytes, UNITS_PER_WORD);
 
-  if (type)
-    mode = type_natural_mode (type, NULL, false);
+  if (arg.type)
+    mode = type_natural_mode (arg.type, NULL, false);
 
   if (TARGET_64BIT)
     {
@@ -2952,10 +2948,11 @@  ix86_function_arg_advance (cumulative_ar
       if (call_abi == MS_ABI)
 	nregs = function_arg_advance_ms_64 (cum, bytes, words);
       else
-	nregs = function_arg_advance_64 (cum, mode, type, words, named);
+	nregs = function_arg_advance_64 (cum, mode, arg.type, words,
+					 arg.named);
     }
   else
-    nregs = function_arg_advance_32 (cum, mode, type, bytes, words);
+    nregs = function_arg_advance_32 (cum, mode, arg.type, bytes, words);
 
   if (!nregs)
     {
@@ -4109,8 +4106,7 @@  ix86_setup_incoming_varargs (cumulative_
      For stdargs, we do want to skip the last named argument.  */
   next_cum = *cum;
   if (stdarg_p (fntype))
-    ix86_function_arg_advance (pack_cumulative_args (&next_cum),
-			       arg.mode, arg.type, arg.named);
+    ix86_function_arg_advance (pack_cumulative_args (&next_cum), arg);
 
   if (cum->call_abi == MS_ABI)
     setup_incoming_varargs_ms_64 (&next_cum);
Index: gcc/config/ia64/ia64.c
===================================================================
--- gcc/config/ia64/ia64.c	2019-08-19 15:58:42.405976452 +0100
+++ gcc/config/ia64/ia64.c	2019-08-19 15:58:50.329919117 +0100
@@ -207,8 +207,8 @@  static int ia64_arg_partial_bytes (cumul
 static rtx ia64_function_arg (cumulative_args_t, const function_arg_info &);
 static rtx ia64_function_incoming_arg (cumulative_args_t,
 				       const function_arg_info &);
-static void ia64_function_arg_advance (cumulative_args_t, machine_mode,
-				       const_tree, bool);
+static void ia64_function_arg_advance (cumulative_args_t,
+				       const function_arg_info &);
 static pad_direction ia64_function_arg_padding (machine_mode, const_tree);
 static unsigned int ia64_function_arg_boundary (machine_mode,
 						const_tree);
@@ -4596,8 +4596,7 @@  ia64_setup_incoming_varargs (cumulative_
   CUMULATIVE_ARGS next_cum = *get_cumulative_args (cum);
 
   /* Skip the current argument.  */
-  ia64_function_arg_advance (pack_cumulative_args (&next_cum),
-			     arg.mode, arg.type, arg.named);
+  ia64_function_arg_advance (pack_cumulative_args (&next_cum), arg);
 
   if (next_cum.words < MAX_ARGUMENT_SLOTS)
     {
@@ -4999,12 +4998,12 @@  ia64_arg_type (machine_mode mode)
    ia64_function_arg.  */
 
 static void
-ia64_function_arg_advance (cumulative_args_t cum_v, machine_mode mode,
-			   const_tree type, bool named)
+ia64_function_arg_advance (cumulative_args_t cum_v,
+			   const function_arg_info &arg)
 {
   CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
-  int words = ia64_function_arg_words (type, mode);
-  int offset = ia64_function_arg_offset (cum, type, words);
+  int words = ia64_function_arg_words (arg.type, arg.mode);
+  int offset = ia64_function_arg_offset (cum, arg.type, words);
   machine_mode hfa_mode = VOIDmode;
 
   /* If all arg slots are already full, then there is nothing to do.  */
@@ -5014,7 +5013,7 @@  ia64_function_arg_advance (cumulative_ar
       return;
     }
 
-  cum->atypes[cum->words] = ia64_arg_type (mode);
+  cum->atypes[cum->words] = ia64_arg_type (arg.mode);
   cum->words += words + offset;
 
   /* On OpenVMS argument is either in Rn or Fn.  */
@@ -5026,12 +5025,12 @@  ia64_function_arg_advance (cumulative_ar
     }
 
   /* Check for and handle homogeneous FP aggregates.  */
-  if (type)
-    hfa_mode = hfa_element_mode (type, 0);
+  if (arg.type)
+    hfa_mode = hfa_element_mode (arg.type, 0);
 
   /* Unnamed prototyped hfas are passed as usual.  Named prototyped hfas
      and unprototyped hfas are passed specially.  */
-  if (hfa_mode != VOIDmode && (! cum->prototype || named))
+  if (hfa_mode != VOIDmode && (! cum->prototype || arg.named))
     {
       int fp_regs = cum->fp_regs;
       /* This is the original value of cum->words + offset.  */
@@ -5050,8 +5049,7 @@  ia64_function_arg_advance (cumulative_ar
       /* Fill the FP regs.  We do this always.  We stop if we reach the end
 	 of the argument, the last FP register, or the last argument slot.  */
 
-      byte_size = ((mode == BLKmode)
-		   ? int_size_in_bytes (type) : GET_MODE_SIZE (mode));
+      byte_size = arg.promoted_size_in_bytes ();
       args_byte_size = int_regs * UNITS_PER_WORD;
       offset = 0;
       for (; (offset < byte_size && fp_regs < MAX_ARGUMENT_SLOTS
@@ -5068,26 +5066,29 @@  ia64_function_arg_advance (cumulative_ar
   /* Integral and aggregates go in general registers.  So do TFmode FP values.
      If we have run out of FR registers, then other FP values must also go in
      general registers.  This can happen when we have a SFmode HFA.  */
-  else if (mode == TFmode || mode == TCmode
-           || (! FLOAT_MODE_P (mode) || cum->fp_regs == MAX_ARGUMENT_SLOTS))
+  else if (arg.mode == TFmode || arg.mode == TCmode
+           || !FLOAT_MODE_P (arg.mode)
+	   || cum->fp_regs == MAX_ARGUMENT_SLOTS)
     cum->int_regs = cum->words;
 
   /* If there is a prototype, then FP values go in a FR register when
      named, and in a GR register when unnamed.  */
   else if (cum->prototype)
     {
-      if (! named)
+      if (! arg.named)
 	cum->int_regs = cum->words;
       else
 	/* ??? Complex types should not reach here.  */
-	cum->fp_regs += (GET_MODE_CLASS (mode) == MODE_COMPLEX_FLOAT ? 2 : 1);
+	cum->fp_regs
+	  += (GET_MODE_CLASS (arg.mode) == MODE_COMPLEX_FLOAT ? 2 : 1);
     }
   /* If there is no prototype, then FP values go in both FR and GR
      registers.  */
   else
     {
       /* ??? Complex types should not reach here.  */
-      cum->fp_regs += (GET_MODE_CLASS (mode) == MODE_COMPLEX_FLOAT ? 2 : 1);
+      cum->fp_regs
+	+= (GET_MODE_CLASS (arg.mode) == MODE_COMPLEX_FLOAT ? 2 : 1);
       cum->int_regs = cum->words;
     }
 }
Index: gcc/config/iq2000/iq2000.c
===================================================================
--- gcc/config/iq2000/iq2000.c	2019-08-19 15:58:42.405976452 +0100
+++ gcc/config/iq2000/iq2000.c	2019-08-19 15:58:50.329919117 +0100
@@ -166,7 +166,7 @@  static int  iq2000_arg_partial_bytes  (c
 static rtx iq2000_function_arg	      (cumulative_args_t,
 				       const function_arg_info &);
 static void iq2000_function_arg_advance (cumulative_args_t,
-					 machine_mode, const_tree, bool);
+					 const function_arg_info &);
 static pad_direction iq2000_function_arg_padding (machine_mode, const_tree);
 static unsigned int iq2000_function_arg_boundary (machine_mode,
 						  const_tree);
@@ -1153,12 +1153,11 @@  init_cumulative_args (CUMULATIVE_ARGS *c
     }
 }
 
-/* Advance the argument of type TYPE and mode MODE to the next argument
-   position in CUM.  */
+/* Implement TARGET_FUNCTION_ARG_ADVANCE.  */
 
 static void
-iq2000_function_arg_advance (cumulative_args_t cum_v, machine_mode mode,
-			     const_tree type, bool named)
+iq2000_function_arg_advance (cumulative_args_t cum_v,
+			     const function_arg_info &arg)
 {
   CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
 
@@ -1167,29 +1166,29 @@  iq2000_function_arg_advance (cumulative_
       fprintf (stderr,
 	       "function_adv({gp reg found = %d, arg # = %2d, words = %2d}, %4s, ",
 	       cum->gp_reg_found, cum->arg_number, cum->arg_words,
-	       GET_MODE_NAME (mode));
-      fprintf (stderr, "%p", (const void *) type);
-      fprintf (stderr, ", %d )\n\n", named);
+	       GET_MODE_NAME (arg.mode));
+      fprintf (stderr, "%p", (const void *) arg.type);
+      fprintf (stderr, ", %d )\n\n", arg.named);
     }
 
   cum->arg_number++;
-  switch (mode)
+  switch (arg.mode)
     {
     case E_VOIDmode:
       break;
 
     default:
-      gcc_assert (GET_MODE_CLASS (mode) == MODE_COMPLEX_INT
-		  || GET_MODE_CLASS (mode) == MODE_COMPLEX_FLOAT);
+      gcc_assert (GET_MODE_CLASS (arg.mode) == MODE_COMPLEX_INT
+		  || GET_MODE_CLASS (arg.mode) == MODE_COMPLEX_FLOAT);
 
       cum->gp_reg_found = 1;
-      cum->arg_words += ((GET_MODE_SIZE (mode) + UNITS_PER_WORD - 1)
+      cum->arg_words += ((GET_MODE_SIZE (arg.mode) + UNITS_PER_WORD - 1)
 			 / UNITS_PER_WORD);
       break;
 
     case E_BLKmode:
       cum->gp_reg_found = 1;
-      cum->arg_words += ((int_size_in_bytes (type) + UNITS_PER_WORD - 1)
+      cum->arg_words += ((int_size_in_bytes (arg.type) + UNITS_PER_WORD - 1)
 			 / UNITS_PER_WORD);
       break;
 
@@ -1971,8 +1970,7 @@  iq2000_expand_prologue (void)
       function_arg_info arg (passed_type, passed_mode, /*named=*/true);
       entry_parm = iq2000_function_arg (args_so_far, arg);
 
-      iq2000_function_arg_advance (args_so_far, passed_mode,
-				   passed_type, true);
+      iq2000_function_arg_advance (args_so_far, arg);
       next_arg = DECL_CHAIN (cur_arg);
 
       if (entry_parm && store_args_on_stack)
Index: gcc/config/lm32/lm32.c
===================================================================
--- gcc/config/lm32/lm32.c	2019-08-19 15:58:42.405976452 +0100
+++ gcc/config/lm32/lm32.c	2019-08-19 15:58:50.329919117 +0100
@@ -75,8 +75,7 @@  static HOST_WIDE_INT lm32_compute_frame_
 static void lm32_option_override (void);
 static rtx lm32_function_arg (cumulative_args_t, const function_arg_info &);
 static void lm32_function_arg_advance (cumulative_args_t cum,
-				       machine_mode mode,
-				       const_tree type, bool named);
+				       const function_arg_info &);
 static bool lm32_hard_regno_mode_ok (unsigned int, machine_mode);
 static bool lm32_modes_tieable_p (machine_mode, machine_mode);
 static HOST_WIDE_INT lm32_starting_frame_offset (void);
@@ -641,10 +640,10 @@  lm32_function_arg (cumulative_args_t cum
 }
 
 static void
-lm32_function_arg_advance (cumulative_args_t cum, machine_mode mode,
-			   const_tree type, bool named ATTRIBUTE_UNUSED)
+lm32_function_arg_advance (cumulative_args_t cum,
+			   const function_arg_info &arg)
 {
-  *get_cumulative_args (cum) += LM32_NUM_REGS2 (mode, type);
+  *get_cumulative_args (cum) += LM32_NUM_REGS2 (arg.mode, arg.type);
 }
 
 HOST_WIDE_INT
Index: gcc/config/m32c/m32c.c
===================================================================
--- gcc/config/m32c/m32c.c	2019-08-19 15:58:42.409976425 +0100
+++ gcc/config/m32c/m32c.c	2019-08-19 15:58:50.329919117 +0100
@@ -79,8 +79,8 @@  static bool m32c_addr_space_legitimate_a
 static rtx m32c_function_arg (cumulative_args_t, const function_arg_info &);
 static bool m32c_pass_by_reference (cumulative_args_t,
 				    const function_arg_info &);
-static void m32c_function_arg_advance (cumulative_args_t, machine_mode,
-				       const_tree, bool);
+static void m32c_function_arg_advance (cumulative_args_t,
+				       const function_arg_info &);
 static unsigned int m32c_function_arg_boundary (machine_mode, const_tree);
 static int m32c_pushm_popm (Push_Pop_Type);
 static bool m32c_strict_argument_naming (cumulative_args_t);
@@ -1399,9 +1399,7 @@  m32c_init_cumulative_args (CUMULATIVE_AR
 #define TARGET_FUNCTION_ARG_ADVANCE m32c_function_arg_advance
 static void
 m32c_function_arg_advance (cumulative_args_t ca_v,
-			   machine_mode mode ATTRIBUTE_UNUSED,
-			   const_tree type ATTRIBUTE_UNUSED,
-			   bool named ATTRIBUTE_UNUSED)
+			   const function_arg_info &)
 {
   CUMULATIVE_ARGS *ca = get_cumulative_args (ca_v);
 
Index: gcc/config/m32r/m32r.c
===================================================================
--- gcc/config/m32r/m32r.c	2019-08-19 15:58:42.409976425 +0100
+++ gcc/config/m32r/m32r.c	2019-08-19 15:58:50.329919117 +0100
@@ -97,8 +97,8 @@  static bool m32r_pass_by_reference (cumu
 static int m32r_arg_partial_bytes (cumulative_args_t,
 				   const function_arg_info &);
 static rtx m32r_function_arg (cumulative_args_t, const function_arg_info &);
-static void m32r_function_arg_advance (cumulative_args_t, machine_mode,
-				       const_tree, bool);
+static void m32r_function_arg_advance (cumulative_args_t,
+				       const function_arg_info &);
 static bool m32r_can_eliminate (const int, const int);
 static void m32r_conditional_register_usage (void);
 static void m32r_trampoline_init (rtx, tree, rtx);
@@ -1217,18 +1217,16 @@  m32r_function_arg (cumulative_args_t cum
 	  : NULL_RTX);
 }
 
-/* Update the data in CUM to advance over an argument
-   of mode MODE and data type TYPE.
-   (TYPE is null for libcalls where that information may not be available.)  */
+/* Update the data in CUM to advance over argument ARG.  */
 
 static void
-m32r_function_arg_advance (cumulative_args_t cum_v, machine_mode mode,
-			   const_tree type, bool named ATTRIBUTE_UNUSED)
+m32r_function_arg_advance (cumulative_args_t cum_v,
+			   const function_arg_info &arg)
 {
   CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
 
-  *cum = (ROUND_ADVANCE_CUM (*cum, mode, type)
-	  + ROUND_ADVANCE_ARG (mode, type));
+  *cum = (ROUND_ADVANCE_CUM (*cum, arg.mode, arg.type)
+	  + ROUND_ADVANCE_ARG (arg.mode, arg.type));
 }
 
 /* Worker function for TARGET_RETURN_IN_MEMORY.  */
Index: gcc/config/m68k/m68k.c
===================================================================
--- gcc/config/m68k/m68k.c	2019-08-19 15:58:42.409976425 +0100
+++ gcc/config/m68k/m68k.c	2019-08-19 15:58:50.329919117 +0100
@@ -181,8 +181,8 @@  static void m68k_output_dwarf_dtprel (FI
 static void m68k_trampoline_init (rtx, tree, rtx);
 static poly_int64 m68k_return_pops_args (tree, tree, poly_int64);
 static rtx m68k_delegitimize_address (rtx);
-static void m68k_function_arg_advance (cumulative_args_t, machine_mode,
-				       const_tree, bool);
+static void m68k_function_arg_advance (cumulative_args_t,
+				       const function_arg_info &);
 static rtx m68k_function_arg (cumulative_args_t, const function_arg_info &);
 static bool m68k_cannot_force_const_mem (machine_mode mode, rtx x);
 static bool m68k_output_addr_const_extra (FILE *, rtx);
@@ -1469,14 +1469,12 @@  m68k_function_arg (cumulative_args_t, co
 }
 
 static void
-m68k_function_arg_advance (cumulative_args_t cum_v, machine_mode mode,
-			   const_tree type, bool named ATTRIBUTE_UNUSED)
+m68k_function_arg_advance (cumulative_args_t cum_v,
+			   const function_arg_info &arg)
 {
   CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
 
-  *cum += (mode != BLKmode
-	   ? (GET_MODE_SIZE (mode) + 3) & ~3
-	   : (int_size_in_bytes (type) + 3) & ~3);
+  *cum += (arg.promoted_size_in_bytes () + 3) & ~3;
 }
 
 /* Convert X to a legitimate function call memory reference and return the
Index: gcc/config/mcore/mcore.c
===================================================================
--- gcc/config/mcore/mcore.c	2019-08-19 15:58:42.409976425 +0100
+++ gcc/config/mcore/mcore.c	2019-08-19 15:58:50.329919117 +0100
@@ -135,8 +135,7 @@  static int        mcore_arg_partial_byte
 static rtx        mcore_function_arg            (cumulative_args_t,
 						 const function_arg_info &);
 static void       mcore_function_arg_advance    (cumulative_args_t,
-						 machine_mode,
-						 const_tree, bool);
+						 const function_arg_info &);
 static unsigned int mcore_function_arg_boundary (machine_mode,
 						 const_tree);
 static void       mcore_asm_trampoline_template (FILE *);
@@ -2817,13 +2816,13 @@  mcore_function_arg (cumulative_args_t cu
 }
 
 static void
-mcore_function_arg_advance (cumulative_args_t cum_v, machine_mode mode,
-			    const_tree type, bool named ATTRIBUTE_UNUSED)
+mcore_function_arg_advance (cumulative_args_t cum_v,
+			    const function_arg_info &arg)
 {
   CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
 
-  *cum = (ROUND_REG (*cum, mode)
-	  + (int)named * mcore_num_arg_regs (mode, type));
+  *cum = (ROUND_REG (*cum, arg.mode)
+	  + (int) arg.named * mcore_num_arg_regs (arg.mode, arg.type));
 }
 
 static unsigned int
Index: gcc/config/microblaze/microblaze.c
===================================================================
--- gcc/config/microblaze/microblaze.c	2019-08-19 15:58:42.409976425 +0100
+++ gcc/config/microblaze/microblaze.c	2019-08-19 15:58:50.329919117 +0100
@@ -1543,29 +1543,28 @@  init_cumulative_args (CUMULATIVE_ARGS *
 
 static void
 microblaze_function_arg_advance (cumulative_args_t cum_v,
-				 machine_mode mode,
-				 const_tree type, bool named ATTRIBUTE_UNUSED)
+				 const function_arg_info &arg)
 {
   CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
 
   cum->arg_number++;
-  switch (mode)
+  switch (arg.mode)
     {
     case E_VOIDmode:
       break;
 
     default:
-      gcc_assert (GET_MODE_CLASS (mode) == MODE_COMPLEX_INT
-	  || GET_MODE_CLASS (mode) == MODE_COMPLEX_FLOAT);
+      gcc_assert (GET_MODE_CLASS (arg.mode) == MODE_COMPLEX_INT
+		  || GET_MODE_CLASS (arg.mode) == MODE_COMPLEX_FLOAT);
 
       cum->gp_reg_found = 1;
-      cum->arg_words += ((GET_MODE_SIZE (mode) + UNITS_PER_WORD - 1)
+      cum->arg_words += ((GET_MODE_SIZE (arg.mode) + UNITS_PER_WORD - 1)
 			 / UNITS_PER_WORD);
       break;
 
     case E_BLKmode:
       cum->gp_reg_found = 1;
-      cum->arg_words += ((int_size_in_bytes (type) + UNITS_PER_WORD - 1)
+      cum->arg_words += ((int_size_in_bytes (arg.type) + UNITS_PER_WORD - 1)
 			 / UNITS_PER_WORD);
       break;
 
@@ -2935,8 +2934,7 @@  microblaze_expand_prologue (void)
 	  break;
 	}
 
-      targetm.calls.function_arg_advance (args_so_far, passed_mode,
-					  passed_type, true);
+      targetm.calls.function_arg_advance (args_so_far, arg);
 
       next_arg = TREE_CHAIN (cur_arg);
       if (next_arg == 0)
Index: gcc/config/mips/mips.c
===================================================================
--- gcc/config/mips/mips.c	2019-08-19 15:58:42.409976425 +0100
+++ gcc/config/mips/mips.c	2019-08-19 15:58:50.333919085 +0100
@@ -6102,13 +6102,13 @@  mips_function_arg (cumulative_args_t cum
 /* Implement TARGET_FUNCTION_ARG_ADVANCE.  */
 
 static void
-mips_function_arg_advance (cumulative_args_t cum_v, machine_mode mode,
-			   const_tree type, bool named)
+mips_function_arg_advance (cumulative_args_t cum_v,
+			   const function_arg_info &arg)
 {
   CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
   struct mips_arg_info info;
 
-  mips_get_arg_info (&info, cum, mode, type, named);
+  mips_get_arg_info (&info, cum, arg.mode, arg.type, arg.named);
 
   if (!info.fpr_p)
     cum->gp_reg_found = true;
@@ -6118,7 +6118,7 @@  mips_function_arg_advance (cumulative_ar
      either the o32 or the o64 ABI, both of which pass at most 2 arguments
      in FPRs.  */
   if (cum->arg_number < 2 && info.fpr_p)
-    cum->fp_code += (mode == SFmode ? 1 : 2) << (cum->arg_number * 2);
+    cum->fp_code += (arg.mode == SFmode ? 1 : 2) << (cum->arg_number * 2);
 
   /* Advance the register count.  This has the effect of setting
      num_gprs to MAX_ARGS_IN_REGISTERS if a doubleword-aligned
@@ -6554,8 +6554,7 @@  mips_setup_incoming_varargs (cumulative_
      argument.  Advance a local copy of CUM past the last "real" named
      argument, to find out how many registers are left over.  */
   local_cum = *get_cumulative_args (cum);
-  mips_function_arg_advance (pack_cumulative_args (&local_cum),
-			     arg.mode, arg.type, arg.named);
+  mips_function_arg_advance (pack_cumulative_args (&local_cum), arg);
 
   /* Found out how many registers we need to save.  */
   gp_saved = MAX_ARGS_IN_REGISTERS - local_cum.num_gprs;
@@ -7305,7 +7304,8 @@  mips_output_args_xfer (int fp_code, char
       else
 	mips_output_64bit_xfer (direction, gparg, fparg);
 
-      mips_function_arg_advance (pack_cumulative_args (&cum), mode, NULL, true);
+      function_arg_info arg (mode, /*named=*/true);
+      mips_function_arg_advance (pack_cumulative_args (&cum), arg);
     }
 }
 
Index: gcc/config/mmix/mmix.c
===================================================================
--- gcc/config/mmix/mmix.c	2019-08-19 15:58:42.413976394 +0100
+++ gcc/config/mmix/mmix.c	2019-08-19 15:58:50.333919085 +0100
@@ -149,8 +149,8 @@  static rtx mmix_struct_value_rtx (tree,
 static machine_mode mmix_promote_function_mode (const_tree,
 						     machine_mode,
 	                                             int *, const_tree, int);
-static void mmix_function_arg_advance (cumulative_args_t, machine_mode,
-				       const_tree, bool);
+static void mmix_function_arg_advance (cumulative_args_t,
+				       const function_arg_info &);
 static rtx mmix_function_incoming_arg (cumulative_args_t,
 				       const function_arg_info &);
 static rtx mmix_function_arg (cumulative_args_t, const function_arg_info &);
@@ -615,13 +615,13 @@  mmix_initial_elimination_offset (int fro
 }
 
 static void
-mmix_function_arg_advance (cumulative_args_t argsp_v, machine_mode mode,
-			   const_tree type, bool named ATTRIBUTE_UNUSED)
+mmix_function_arg_advance (cumulative_args_t argsp_v,
+			   const function_arg_info &arg)
 {
   CUMULATIVE_ARGS *argsp = get_cumulative_args (argsp_v);
-  int arg_size = MMIX_FUNCTION_ARG_SIZE (mode, type);
+  int arg_size = MMIX_FUNCTION_ARG_SIZE (arg.mode, arg.type);
 
-  argsp->regs = ((targetm.calls.must_pass_in_stack (mode, type)
+  argsp->regs = ((targetm.calls.must_pass_in_stack (arg.mode, arg.type)
 		  || (arg_size > 8
 		      && !TARGET_LIBFUNC
 		      && !argsp->lib))
Index: gcc/config/mn10300/mn10300.c
===================================================================
--- gcc/config/mn10300/mn10300.c	2019-08-19 15:58:42.413976394 +0100
+++ gcc/config/mn10300/mn10300.c	2019-08-19 15:58:50.333919085 +0100
@@ -1575,19 +1575,15 @@  mn10300_function_arg (cumulative_args_t
   return result;
 }
 
-/* Update the data in CUM to advance over an argument
-   of mode MODE and data type TYPE.
-   (TYPE is null for libcalls where that information may not be available.)  */
+/* Update the data in CUM to advance over argument ARG.  */
 
 static void
-mn10300_function_arg_advance (cumulative_args_t cum_v, machine_mode mode,
-			      const_tree type, bool named ATTRIBUTE_UNUSED)
+mn10300_function_arg_advance (cumulative_args_t cum_v,
+			      const function_arg_info &arg)
 {
   CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
 
-  cum->nbytes += (mode != BLKmode
-		  ? (GET_MODE_SIZE (mode) + 3) & ~3
-		  : (int_size_in_bytes (type) + 3) & ~3);
+  cum->nbytes += (arg.promoted_size_in_bytes () + 3) & ~3;
 }
 
 /* Return the number of bytes of registers to use for an argument passed
Index: gcc/config/moxie/moxie.c
===================================================================
--- gcc/config/moxie/moxie.c	2019-08-19 15:58:42.413976394 +0100
+++ gcc/config/moxie/moxie.c	2019-08-19 15:58:50.333919085 +0100
@@ -438,13 +438,13 @@  #define MOXIE_FUNCTION_ARG_SIZE(MODE, TY
    : (unsigned) int_size_in_bytes (TYPE))
 
 static void
-moxie_function_arg_advance (cumulative_args_t cum_v, machine_mode mode,
-			    const_tree type, bool named ATTRIBUTE_UNUSED)
+moxie_function_arg_advance (cumulative_args_t cum_v,
+			    const function_arg_info &arg)
 {
   CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
 
   *cum = (*cum < MOXIE_R6
-	  ? *cum + ((3 + MOXIE_FUNCTION_ARG_SIZE (mode, type)) / 4)
+	  ? *cum + ((3 + MOXIE_FUNCTION_ARG_SIZE (arg.mode, arg.type)) / 4)
 	  : *cum);
 }
 
Index: gcc/config/msp430/msp430.c
===================================================================
--- gcc/config/msp430/msp430.c	2019-08-19 15:58:42.413976394 +0100
+++ gcc/config/msp430/msp430.c	2019-08-19 15:58:50.333919085 +0100
@@ -766,14 +766,12 @@  #define TARGET_FUNCTION_ARG_ADVANCE msp4
 
 void
 msp430_function_arg_advance (cumulative_args_t cap,
-			     machine_mode mode,
-			     const_tree type,
-			     bool named)
+			     const function_arg_info &arg)
 {
   CUMULATIVE_ARGS *ca = get_cumulative_args (cap);
   int i;
 
-  msp430_evaluate_arg (cap, mode, type, named);
+  msp430_evaluate_arg (cap, arg.mode, arg.type, arg.named);
 
   if (ca->start_reg >= CA_FIRST_REG)
     for (i = 0; i < ca->reg_count; i ++)
Index: gcc/config/nds32/nds32.c
===================================================================
--- gcc/config/nds32/nds32.c	2019-08-19 15:58:42.413976394 +0100
+++ gcc/config/nds32/nds32.c	2019-08-19 15:58:50.333919085 +0100
@@ -2008,12 +2008,14 @@  nds32_arg_partial_bytes (cumulative_args
 }
 
 static void
-nds32_function_arg_advance (cumulative_args_t ca, machine_mode mode,
-			    const_tree type, bool named)
+nds32_function_arg_advance (cumulative_args_t ca,
+			    const function_arg_info &arg)
 {
   CUMULATIVE_ARGS *cum = get_cumulative_args (ca);
+  tree type = arg.type;
+  machine_mode mode = arg.mode;
 
-  if (named)
+  if (arg.named)
     {
       /* We need to further check TYPE and MODE so that we can determine
 	 which kind of register we shall advance.  */
Index: gcc/config/nios2/nios2.c
===================================================================
--- gcc/config/nios2/nios2.c	2019-08-19 15:58:42.413976394 +0100
+++ gcc/config/nios2/nios2.c	2019-08-19 15:58:50.333919085 +0100
@@ -3399,25 +3399,15 @@  nios2_arg_partial_bytes (cumulative_args
   return 0;
 }
 
-/* Update the data in CUM to advance over an argument of mode MODE
-   and data type TYPE; TYPE is null for libcalls where that information
-   may not be available.  */
+/* Update the data in CUM to advance over argument ARG.  */
 
 static void
-nios2_function_arg_advance (cumulative_args_t cum_v, machine_mode mode,
-			    const_tree type ATTRIBUTE_UNUSED,
-			    bool named ATTRIBUTE_UNUSED)
+nios2_function_arg_advance (cumulative_args_t cum_v,
+			    const function_arg_info &arg)
 {
   CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v); 
-  HOST_WIDE_INT param_size;
-
-  if (mode == BLKmode)
-    {
-      param_size = int_size_in_bytes (type);
-      gcc_assert (param_size >= 0);
-    }
-  else
-    param_size = GET_MODE_SIZE (mode);
+  HOST_WIDE_INT param_size = arg.promoted_size_in_bytes ();
+  gcc_assert (param_size >= 0);
 
   /* Convert to words (round up).  */
   param_size = (UNITS_PER_WORD - 1 + param_size) / UNITS_PER_WORD;
@@ -3520,7 +3510,7 @@  nios2_setup_incoming_varargs (cumulative
 
   cfun->machine->uses_anonymous_args = 1;
   local_cum = *cum;
-  nios2_function_arg_advance (local_cum_v, arg.mode, arg.type, arg.named);
+  nios2_function_arg_advance (local_cum_v, arg);
 
   regs_to_push = NUM_ARG_REGS - local_cum.regs_used;
 
Index: gcc/config/nvptx/nvptx.c
===================================================================
--- gcc/config/nvptx/nvptx.c	2019-08-19 15:58:42.413976394 +0100
+++ gcc/config/nvptx/nvptx.c	2019-08-19 15:58:50.333919085 +0100
@@ -550,10 +550,7 @@  nvptx_function_incoming_arg (cumulative_
 /* Implement TARGET_FUNCTION_ARG_ADVANCE.  */
 
 static void
-nvptx_function_arg_advance (cumulative_args_t cum_v,
-			    machine_mode ARG_UNUSED (mode),
-			    const_tree ARG_UNUSED (type),
-			    bool ARG_UNUSED (named))
+nvptx_function_arg_advance (cumulative_args_t cum_v, const function_arg_info &)
 {
   CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
 
Index: gcc/config/or1k/or1k.c
===================================================================
--- gcc/config/or1k/or1k.c	2019-08-19 15:58:42.413976394 +0100
+++ gcc/config/or1k/or1k.c	2019-08-19 15:58:50.333919085 +0100
@@ -1019,15 +1019,15 @@  or1k_function_arg (cumulative_args_t cum
    argument.  Note, this is not called for arguments passed on the stack.  */
 
 static void
-or1k_function_arg_advance (cumulative_args_t cum_v, machine_mode mode,
-			   const_tree /* type */, bool named)
+or1k_function_arg_advance (cumulative_args_t cum_v,
+			   const function_arg_info &arg)
 {
   CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
-  int nreg = CEIL (GET_MODE_SIZE (mode), UNITS_PER_WORD);
+  int nreg = CEIL (GET_MODE_SIZE (arg.mode), UNITS_PER_WORD);
 
   /* Note that all large arguments are passed by reference.  */
   gcc_assert (nreg <= 2);
-  if (named)
+  if (arg.named)
     *cum += nreg;
 }
 
Index: gcc/config/pa/pa.c
===================================================================
--- gcc/config/pa/pa.c	2019-08-19 15:58:42.413976394 +0100
+++ gcc/config/pa/pa.c	2019-08-19 15:58:50.337919057 +0100
@@ -167,8 +167,8 @@  static rtx pa_struct_value_rtx (tree, in
 static bool pa_pass_by_reference (cumulative_args_t,
 				  const function_arg_info &);
 static int pa_arg_partial_bytes (cumulative_args_t, const function_arg_info &);
-static void pa_function_arg_advance (cumulative_args_t, machine_mode,
-				     const_tree, bool);
+static void pa_function_arg_advance (cumulative_args_t,
+				     const function_arg_info &);
 static rtx pa_function_arg (cumulative_args_t, const function_arg_info &);
 static pad_direction pa_function_arg_padding (machine_mode, const_tree);
 static unsigned int pa_function_arg_boundary (machine_mode, const_tree);
@@ -9437,21 +9437,19 @@  pa_function_value_regno_p (const unsigne
   return false;
 }
 
-/* Update the data in CUM to advance over an argument
-   of mode MODE and data type TYPE.
-   (TYPE is null for libcalls where that information may not be available.)  */
+/* Update the data in CUM to advance over argument ARG.  */
 
 static void
-pa_function_arg_advance (cumulative_args_t cum_v, machine_mode mode,
-			 const_tree type, bool named ATTRIBUTE_UNUSED)
+pa_function_arg_advance (cumulative_args_t cum_v,
+			 const function_arg_info &arg)
 {
   CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
-  int arg_size = pa_function_arg_size (mode, type);
+  int arg_size = pa_function_arg_size (arg.mode, arg.type);
 
   cum->nargs_prototype--;
   cum->words += (arg_size
 		 + ((cum->words & 01)
-		    && type != NULL_TREE
+		    && arg.type != NULL_TREE
 		    && arg_size > 1));
 }
 
Index: gcc/config/pdp11/pdp11.c
===================================================================
--- gcc/config/pdp11/pdp11.c	2019-08-19 15:58:42.413976394 +0100
+++ gcc/config/pdp11/pdp11.c	2019-08-19 15:58:50.337919057 +0100
@@ -164,7 +164,7 @@  static bool pdp11_function_value_regno_p
 static void pdp11_trampoline_init (rtx, tree, rtx);
 static rtx pdp11_function_arg (cumulative_args_t, const function_arg_info &);
 static void pdp11_function_arg_advance (cumulative_args_t,
-					machine_mode, const_tree, bool);
+					const function_arg_info &);
 static void pdp11_conditional_register_usage (void);
 static bool pdp11_legitimate_constant_p (machine_mode, rtx);
 
@@ -2189,19 +2189,15 @@  pdp11_function_arg (cumulative_args_t, c
 
 /* Worker function for TARGET_FUNCTION_ARG_ADVANCE.
 
-   Update the data in CUM to advance over an argument of mode MODE and
-   data type TYPE.  (TYPE is null for libcalls where that information
-   may not be available.)  */
+   Update the data in CUM to advance over argument ARG.  */
 
 static void
-pdp11_function_arg_advance (cumulative_args_t cum_v, machine_mode mode,
-			    const_tree type, bool named ATTRIBUTE_UNUSED)
+pdp11_function_arg_advance (cumulative_args_t cum_v,
+			    const function_arg_info &arg)
 {
   CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
 
-  *cum += (mode != BLKmode
-	   ? GET_MODE_SIZE (mode)
-	   : int_size_in_bytes (type));
+  *cum += arg.promoted_size_in_bytes ();
 }
 
 /* Make sure everything's fine if we *don't* have an FPU.
Index: gcc/config/pru/pru.c
===================================================================
--- gcc/config/pru/pru.c	2019-08-19 15:58:42.413976394 +0100
+++ gcc/config/pru/pru.c	2019-08-19 15:58:50.337919057 +0100
@@ -2177,19 +2177,17 @@  pru_arg_partial_bytes (cumulative_args_t
   return 0;
 }
 
-/* Update the data in CUM to advance over an argument of mode MODE
-   and data type TYPE; TYPE is null for libcalls where that information
-   may not be available.  */
+/* Update the data in CUM to advance over argument ARG.  */
 
 static void
-pru_function_arg_advance (cumulative_args_t cum_v, machine_mode mode,
-			    const_tree type,
-			    bool named)
+pru_function_arg_advance (cumulative_args_t cum_v,
+			  const function_arg_info &arg)
 {
-  int regi = pru_function_arg_regi (cum_v, mode, type, named);
+  int regi = pru_function_arg_regi (cum_v, arg.mode, arg.type, arg.named);
 
   if (regi >= 0)
-    pru_function_arg_regi_mark_slot (regi, cum_v, mode, type, named);
+    pru_function_arg_regi_mark_slot (regi, cum_v, arg.mode,
+				     arg.type, arg.named);
 }
 
 /* Implement TARGET_FUNCTION_VALUE.  */
Index: gcc/config/riscv/riscv.c
===================================================================
--- gcc/config/riscv/riscv.c	2019-08-19 15:58:42.417976367 +0100
+++ gcc/config/riscv/riscv.c	2019-08-19 15:58:50.337919057 +0100
@@ -2757,13 +2757,13 @@  riscv_function_arg (cumulative_args_t cu
 /* Implement TARGET_FUNCTION_ARG_ADVANCE.  */
 
 static void
-riscv_function_arg_advance (cumulative_args_t cum_v, machine_mode mode,
-			    const_tree type, bool named)
+riscv_function_arg_advance (cumulative_args_t cum_v,
+			    const function_arg_info &arg)
 {
   CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
   struct riscv_arg_info info;
 
-  riscv_get_arg_info (&info, cum, mode, type, named, false);
+  riscv_get_arg_info (&info, cum, arg.mode, arg.type, arg.named, false);
 
   /* Advance the register count.  This has the effect of setting
      num_gprs to MAX_ARGS_IN_REGISTERS if a doubleword-aligned
@@ -2864,8 +2864,7 @@  riscv_setup_incoming_varargs (cumulative
      argument.  Advance a local copy of CUM past the last "real" named
      argument, to find out how many registers are left over.  */
   local_cum = *get_cumulative_args (cum);
-  riscv_function_arg_advance (pack_cumulative_args (&local_cum),
-			      arg.mode, arg.type, arg.named);
+  riscv_function_arg_advance (pack_cumulative_args (&local_cum), arg);
 
   /* Found out how many registers we need to save.  */
   gp_saved = MAX_ARGS_IN_REGISTERS - local_cum.num_gprs;
Index: gcc/config/rl78/rl78.c
===================================================================
--- gcc/config/rl78/rl78.c	2019-08-19 15:58:42.417976367 +0100
+++ gcc/config/rl78/rl78.c	2019-08-19 15:58:50.337919057 +0100
@@ -1750,14 +1750,13 @@  rl78_function_arg (cumulative_args_t, co
 #define TARGET_FUNCTION_ARG_ADVANCE     rl78_function_arg_advance
 
 static void
-rl78_function_arg_advance (cumulative_args_t cum_v, machine_mode mode, const_tree type,
-			   bool named ATTRIBUTE_UNUSED)
+rl78_function_arg_advance (cumulative_args_t cum_v,
+			   const function_arg_info &arg)
 {
   int rounded_size;
   CUMULATIVE_ARGS * cum = get_cumulative_args (cum_v);
 
-  rounded_size = ((mode == BLKmode)
-		  ? int_size_in_bytes (type) : GET_MODE_SIZE (mode));
+  rounded_size = arg.promoted_size_in_bytes ();
   if (rounded_size & 1)
     rounded_size ++;
   (*cum) += rounded_size;
Index: gcc/config/rs6000/rs6000-internal.h
===================================================================
--- gcc/config/rs6000/rs6000-internal.h	2019-08-19 15:58:42.417976367 +0100
+++ gcc/config/rs6000/rs6000-internal.h	2019-08-19 15:58:50.337919057 +0100
@@ -159,9 +159,8 @@  extern unsigned int rs6000_function_arg_
 extern bool rs6000_must_pass_in_stack (machine_mode mode, const_tree type);
 extern int rs6000_arg_partial_bytes (cumulative_args_t,
 				     const function_arg_info &);
-extern void rs6000_function_arg_advance (cumulative_args_t cum,
-					 machine_mode mode,
-					 const_tree type, bool named);
+extern void rs6000_function_arg_advance (cumulative_args_t,
+					 const function_arg_info &);
 extern pad_direction rs6000_function_arg_padding (machine_mode mode,
 						  const_tree type);
 extern rtx rs6000_function_arg (cumulative_args_t, const function_arg_info &);
Index: gcc/config/rs6000/rs6000-call.c
===================================================================
--- gcc/config/rs6000/rs6000-call.c	2019-08-19 15:58:42.417976367 +0100
+++ gcc/config/rs6000/rs6000-call.c	2019-08-19 15:58:50.337919057 +0100
@@ -1400,11 +1400,11 @@  rs6000_function_arg_advance_1 (CUMULATIV
 }
 
 void
-rs6000_function_arg_advance (cumulative_args_t cum, machine_mode mode,
-			     const_tree type, bool named)
+rs6000_function_arg_advance (cumulative_args_t cum,
+			     const function_arg_info &arg)
 {
-  rs6000_function_arg_advance_1 (get_cumulative_args (cum), mode, type, named,
-				 0);
+  rs6000_function_arg_advance_1 (get_cumulative_args (cum),
+				 arg.mode, arg.type, arg.named, 0);
 }
 
 /* A subroutine of rs6000_darwin64_record_arg.  Assign the bits of the
@@ -2221,7 +2221,7 @@  rs6000_parm_needs_stack (cumulative_args
     return true;
 
   /* Update info on where next arg arrives in registers.  */
-  rs6000_function_arg_advance (args_so_far, mode, type, true);
+  rs6000_function_arg_advance (args_so_far, arg);
   return false;
 }
 
Index: gcc/config/rx/rx.c
===================================================================
--- gcc/config/rx/rx.c	2019-08-19 15:58:42.417976367 +0100
+++ gcc/config/rx/rx.c	2019-08-19 15:58:50.337919057 +0100
@@ -1105,10 +1105,10 @@  rx_function_arg (cumulative_args_t cum,
 }
 
 static void
-rx_function_arg_advance (cumulative_args_t cum, machine_mode mode,
-			 const_tree type, bool named ATTRIBUTE_UNUSED)
+rx_function_arg_advance (cumulative_args_t cum,
+			 const function_arg_info &arg)
 {
-  *get_cumulative_args (cum) += rx_function_arg_size (mode, type);
+  *get_cumulative_args (cum) += rx_function_arg_size (arg.mode, arg.type);
 }
 
 static unsigned int
Index: gcc/config/s390/s390.c
===================================================================
--- gcc/config/s390/s390.c	2019-08-19 15:58:42.417976367 +0100
+++ gcc/config/s390/s390.c	2019-08-19 15:58:50.337919057 +0100
@@ -11982,35 +11982,31 @@  s390_pass_by_reference (cumulative_args_
   return false;
 }
 
-/* Update the data in CUM to advance over an argument of mode MODE and
-   data type TYPE.  (TYPE is null for libcalls where that information
-   may not be available.).  The boolean NAMED specifies whether the
-   argument is a named argument (as opposed to an unnamed argument
-   matching an ellipsis).  */
+/* Update the data in CUM to advance over argument ARG.  */
 
 static void
-s390_function_arg_advance (cumulative_args_t cum_v, machine_mode mode,
-			   const_tree type, bool named)
+s390_function_arg_advance (cumulative_args_t cum_v,
+			   const function_arg_info &arg)
 {
   CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
 
-  if (s390_function_arg_vector (mode, type))
+  if (s390_function_arg_vector (arg.mode, arg.type))
     {
       /* We are called for unnamed vector stdarg arguments which are
 	 passed on the stack.  In this case this hook does not have to
 	 do anything since stack arguments are tracked by common
 	 code.  */
-      if (!named)
+      if (!arg.named)
 	return;
       cum->vrs += 1;
     }
-  else if (s390_function_arg_float (mode, type))
+  else if (s390_function_arg_float (arg.mode, arg.type))
     {
       cum->fprs += 1;
     }
-  else if (s390_function_arg_integer (mode, type))
+  else if (s390_function_arg_integer (arg.mode, arg.type))
     {
-      int size = s390_function_arg_size (mode, type);
+      int size = s390_function_arg_size (arg.mode, arg.type);
       cum->gprs += ((size + UNITS_PER_LONG - 1) / UNITS_PER_LONG);
     }
   else
@@ -13349,7 +13345,7 @@  s390_call_saved_register_used (tree call
        function_arg_info arg (type, mode, /*named=*/true);
        parm_rtx = s390_function_arg (cum, arg);
 
-       s390_function_arg_advance (cum, mode, type, true);
+       s390_function_arg_advance (cum, arg);
 
        if (!parm_rtx)
 	 continue;
Index: gcc/config/sh/sh.c
===================================================================
--- gcc/config/sh/sh.c	2019-08-19 15:58:42.417976367 +0100
+++ gcc/config/sh/sh.c	2019-08-19 15:58:50.337919057 +0100
@@ -299,8 +299,8 @@  static bool sh_pass_by_reference (cumula
 static bool sh_callee_copies (cumulative_args_t, machine_mode,
 			      const_tree, bool);
 static int sh_arg_partial_bytes (cumulative_args_t, const function_arg_info &);
-static void sh_function_arg_advance (cumulative_args_t, machine_mode,
-				     const_tree, bool);
+static void sh_function_arg_advance (cumulative_args_t,
+				     const function_arg_info &);
 static rtx sh_function_arg (cumulative_args_t, const function_arg_info &);
 static int sh_dwarf_calling_convention (const_tree);
 static void sh_encode_section_info (tree, rtx, int);
@@ -8066,13 +8066,10 @@  sh_function_arg (cumulative_args_t ca_v,
   return NULL_RTX;
 }
 
-/* Update the data in CUM to advance over an argument
-   of mode MODE and data type TYPE.
-   (TYPE is null for libcalls where that information may not be
-   available.)  */
+/* Update the data in CUM to advance over argument ARG.  */
 static void
-sh_function_arg_advance (cumulative_args_t ca_v, machine_mode mode,
-			 const_tree type, bool named ATTRIBUTE_UNUSED)
+sh_function_arg_advance (cumulative_args_t ca_v,
+			 const function_arg_info &arg)
 {
   CUMULATIVE_ARGS *ca = get_cumulative_args (ca_v);
 
@@ -8082,7 +8079,7 @@  sh_function_arg_advance (cumulative_args
   if ((TARGET_HITACHI || ca->renesas_abi) && TARGET_FPU_DOUBLE)
     {
       /* Note that we've used the skipped register.  */
-      if (mode == SFmode && ca->free_single_fp_reg)
+      if (arg.mode == SFmode && ca->free_single_fp_reg)
 	{
 	  ca->free_single_fp_reg = 0;
 	  return;
@@ -8091,21 +8088,19 @@  sh_function_arg_advance (cumulative_args
 	 skipped in order to align the DF value.  We note this skipped
 	 register, because the next SF value will use it, and not the
 	 SF that follows the DF.  */
-      if (mode == DFmode
+      if (arg.mode == DFmode
 	  && sh_round_reg (*ca, DFmode) != sh_round_reg (*ca, SFmode))
 	{
 	  ca->free_single_fp_reg = (sh_round_reg (*ca, SFmode)
-				    + BASE_ARG_REG (mode));
+				    + BASE_ARG_REG (arg.mode));
 	}
     }
 
   if (! ((TARGET_SH4 || TARGET_SH2A) || ca->renesas_abi)
-      || sh_pass_in_reg_p (*ca, mode, type))
-    (ca->arg_count[(int) get_sh_arg_class (mode)]
-     = (sh_round_reg (*ca, mode)
-	+ (mode == BLKmode
-	   ? CEIL (int_size_in_bytes (type), UNITS_PER_WORD)
-	   : CEIL (GET_MODE_SIZE (mode), UNITS_PER_WORD))));
+      || sh_pass_in_reg_p (*ca, arg.mode, arg.type))
+    (ca->arg_count[(int) get_sh_arg_class (arg.mode)]
+     = (sh_round_reg (*ca, arg.mode)
+	+ CEIL (arg.promoted_size_in_bytes (), UNITS_PER_WORD)));
 }
 
 /* The Renesas calling convention doesn't quite fit into this scheme since
@@ -10811,7 +10806,8 @@  sh_output_mi_thunk (FILE *file, tree thu
     {
       tree ptype = build_pointer_type (TREE_TYPE (funtype));
 
-      sh_function_arg_advance (pack_cumulative_args (&cum), Pmode, ptype, true);
+      function_arg_info ptr_arg (ptype, Pmode, /*named=*/true);
+      sh_function_arg_advance (pack_cumulative_args (&cum), ptr_arg);
     }
   function_arg_info ptr_arg (ptr_type_node, Pmode, /*named=*/true);
   this_rtx = sh_function_arg (pack_cumulative_args (&cum), ptr_arg);
Index: gcc/config/sparc/sparc.c
===================================================================
--- gcc/config/sparc/sparc.c	2019-08-19 15:58:42.417976367 +0100
+++ gcc/config/sparc/sparc.c	2019-08-19 15:58:50.341919030 +0100
@@ -657,7 +657,7 @@  static bool sparc_mode_dependent_address
 static bool sparc_pass_by_reference (cumulative_args_t,
 				     const function_arg_info &);
 static void sparc_function_arg_advance (cumulative_args_t,
-					machine_mode, const_tree, bool);
+					const function_arg_info &);
 static rtx sparc_function_arg (cumulative_args_t, const function_arg_info &);
 static rtx sparc_function_incoming_arg (cumulative_args_t,
 					const function_arg_info &);
@@ -7590,19 +7590,19 @@  sparc_arg_partial_bytes (cumulative_args
 }
 
 /* Handle the TARGET_FUNCTION_ARG_ADVANCE hook.
-   Update the data in CUM to advance over an argument
-   of mode MODE and data type TYPE.
-   TYPE is null for libcalls where that information may not be available.  */
+   Update the data in CUM to advance over argument ARG.  */
 
 static void
-sparc_function_arg_advance (cumulative_args_t cum_v, machine_mode mode,
-			    const_tree type, bool named)
+sparc_function_arg_advance (cumulative_args_t cum_v,
+			    const function_arg_info &arg)
 {
   CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
+  tree type = arg.type;
+  machine_mode mode = arg.mode;
   int regno, padding;
 
   /* We pass false for incoming here, it doesn't matter.  */
-  function_arg_slotno (cum, mode, type, named, false, &regno, &padding);
+  function_arg_slotno (cum, mode, type, arg.named, false, &regno, &padding);
 
   /* If argument requires leading padding, add it.  */
   cum->words += padding;
Index: gcc/config/spu/spu.c
===================================================================
--- gcc/config/spu/spu.c	2019-08-19 15:58:42.421976335 +0100
+++ gcc/config/spu/spu.c	2019-08-19 15:58:50.341919030 +0100
@@ -3863,18 +3863,18 @@  spu_function_arg (cumulative_args_t cum_
 }
 
 static void
-spu_function_arg_advance (cumulative_args_t cum_v, machine_mode mode,
-			  const_tree type, bool named ATTRIBUTE_UNUSED)
+spu_function_arg_advance (cumulative_args_t cum_v,
+			  const function_arg_info &arg)
 {
   CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
 
-  *cum += (type && TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST
+  *cum += (arg.type && TREE_CODE (TYPE_SIZE (arg.type)) != INTEGER_CST
 	   ? 1
-	   : mode == BLKmode
-	   ? ((int_size_in_bytes (type) + 15) / 16)
-	   : mode == VOIDmode
+	   : arg.mode == BLKmode
+	   ? ((int_size_in_bytes (arg.type) + 15) / 16)
+	   : arg.mode == VOIDmode
 	   ? 1
-	   : spu_hard_regno_nregs (FIRST_ARG_REGNUM, mode));
+	   : spu_hard_regno_nregs (FIRST_ARG_REGNUM, arg.mode));
 }
 
 /* Implement TARGET_FUNCTION_ARG_OFFSET.  The SPU ABI wants 32/64-bit
@@ -4099,8 +4099,7 @@  spu_setup_incoming_varargs (cumulative_a
 
       /* cum currently points to the last named argument, we want to
          start at the next argument. */
-      spu_function_arg_advance (pack_cumulative_args (&ncum),
-				arg.mode, arg.type, arg.named);
+      spu_function_arg_advance (pack_cumulative_args (&ncum), arg);
 
       offset = -STACK_POINTER_OFFSET;
       for (regno = ncum; regno < MAX_REGISTER_ARGS; regno++)
Index: gcc/config/stormy16/stormy16.c
===================================================================
--- gcc/config/stormy16/stormy16.c	2019-08-19 15:58:42.421976335 +0100
+++ gcc/config/stormy16/stormy16.c	2019-08-19 15:58:50.341919030 +0100
@@ -1205,9 +1205,8 @@  xstormy16_function_profiler (void)
   sorry ("function_profiler support");
 }
 
-/* Update CUM to advance past an argument in the argument list.  The
-   values MODE, TYPE and NAMED describe that argument.  Once this is
-   done, the variable CUM is suitable for analyzing the *following*
+/* Update CUM to advance past argument ARG.  Once this is done,
+   the variable CUM is suitable for analyzing the *following*
    argument with `TARGET_FUNCTION_ARG', etc.
 
    This function need not do anything if the argument in question was
@@ -1217,8 +1216,8 @@  xstormy16_function_profiler (void)
    the word count.  */
 
 static void
-xstormy16_function_arg_advance (cumulative_args_t cum_v, machine_mode mode,
-				const_tree type, bool named ATTRIBUTE_UNUSED)
+xstormy16_function_arg_advance (cumulative_args_t cum_v,
+				const function_arg_info &arg)
 {
   CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
 
@@ -1226,10 +1225,11 @@  xstormy16_function_arg_advance (cumulati
      and partially on the stack, the whole of it is passed on the
      stack.  */
   if (*cum < NUM_ARGUMENT_REGISTERS
-      && *cum + XSTORMY16_WORD_SIZE (type, mode) > NUM_ARGUMENT_REGISTERS)
+      && (*cum + XSTORMY16_WORD_SIZE (arg.type, arg.mode)
+	  > NUM_ARGUMENT_REGISTERS))
     *cum = NUM_ARGUMENT_REGISTERS;
 
-  *cum += XSTORMY16_WORD_SIZE (type, mode);
+  *cum += XSTORMY16_WORD_SIZE (arg.type, arg.mode);
 }
 
 static rtx
Index: gcc/config/tilegx/tilegx.c
===================================================================
--- gcc/config/tilegx/tilegx.c	2019-08-19 15:58:42.421976335 +0100
+++ gcc/config/tilegx/tilegx.c	2019-08-19 15:58:50.341919030 +0100
@@ -245,19 +245,17 @@  tilegx_function_arg (cumulative_args_t c
 /* Implement TARGET_FUNCTION_ARG_ADVANCE.  */
 static void
 tilegx_function_arg_advance (cumulative_args_t cum_v,
-			     machine_mode mode,
-			     const_tree type, bool named ATTRIBUTE_UNUSED)
+			     const function_arg_info &arg)
 {
   CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
 
-  int byte_size = ((mode == BLKmode)
-		   ? int_size_in_bytes (type) : GET_MODE_SIZE (mode));
+  int byte_size = arg.promoted_size_in_bytes ();
   int word_size = (byte_size + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
   bool doubleword_aligned_p;
 
   /* See whether the argument has doubleword alignment.  */
   doubleword_aligned_p =
-    tilegx_function_arg_boundary (mode, type) > BITS_PER_WORD;
+    tilegx_function_arg_boundary (arg.mode, arg.type) > BITS_PER_WORD;
 
   if (doubleword_aligned_p)
     *cum += *cum & 1;
@@ -396,8 +394,7 @@  tilegx_setup_incoming_varargs (cumulativ
   /* The caller has advanced CUM up to, but not beyond, the last named
      argument.  Advance a local copy of CUM past the last "real" named
      argument, to find out how many registers are left over.  */
-  targetm.calls.function_arg_advance (pack_cumulative_args (&local_cum),
-				      arg.mode, arg.type, arg.named);
+  targetm.calls.function_arg_advance (pack_cumulative_args (&local_cum), arg);
   first_reg = local_cum;
 
   if (local_cum < TILEGX_NUM_ARG_REGS)
Index: gcc/config/tilepro/tilepro.c
===================================================================
--- gcc/config/tilepro/tilepro.c	2019-08-19 15:58:42.421976335 +0100
+++ gcc/config/tilepro/tilepro.c	2019-08-19 15:58:50.341919030 +0100
@@ -197,19 +197,17 @@  tilepro_function_arg (cumulative_args_t
 /* Implement TARGET_FUNCTION_ARG_ADVANCE.  */
 static void
 tilepro_function_arg_advance (cumulative_args_t cum_v,
-			      machine_mode mode,
-			      const_tree type, bool named ATTRIBUTE_UNUSED)
+			      const function_arg_info &arg)
 {
   CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
 
-  int byte_size = ((mode == BLKmode)
-		   ? int_size_in_bytes (type) : GET_MODE_SIZE (mode));
+  int byte_size = arg.promoted_size_in_bytes ();
   int word_size = (byte_size + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
   bool doubleword_aligned_p;
 
   /* See whether the argument has doubleword alignment.  */
   doubleword_aligned_p =
-    tilepro_function_arg_boundary (mode, type) > BITS_PER_WORD;
+    tilepro_function_arg_boundary (arg.mode, arg.type) > BITS_PER_WORD;
 
   if (doubleword_aligned_p)
     *cum += *cum & 1;
@@ -348,8 +346,7 @@  tilepro_setup_incoming_varargs (cumulati
   /* The caller has advanced CUM up to, but not beyond, the last named
      argument.  Advance a local copy of CUM past the last "real" named
      argument, to find out how many registers are left over.  */
-  targetm.calls.function_arg_advance (pack_cumulative_args (&local_cum),
-				      arg.mode, arg.type, arg.named);
+  targetm.calls.function_arg_advance (pack_cumulative_args (&local_cum), arg);
   first_reg = local_cum;
 
   if (local_cum < TILEPRO_NUM_ARG_REGS)
Index: gcc/config/v850/v850.c
===================================================================
--- gcc/config/v850/v850.c	2019-08-19 15:58:42.421976335 +0100
+++ gcc/config/v850/v850.c	2019-08-19 15:58:50.341919030 +0100
@@ -216,27 +216,22 @@  v850_arg_partial_bytes (cumulative_args_
   return 4 * UNITS_PER_WORD - cum->nbytes;
 }
 
-/* Update the data in CUM to advance over an argument
-   of mode MODE and data type TYPE.
-   (TYPE is null for libcalls where that information may not be available.)  */
+/* Update the data in CUM to advance over argument ARG.  */
 
 static void
-v850_function_arg_advance (cumulative_args_t cum_v, machine_mode mode,
-			   const_tree type, bool named ATTRIBUTE_UNUSED)
+v850_function_arg_advance (cumulative_args_t cum_v,
+			   const function_arg_info &arg)
 {
   CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
 
   if (!TARGET_GCC_ABI)
-    cum->nbytes += (((mode != BLKmode
-		      ? GET_MODE_SIZE (mode)
-		      : int_size_in_bytes (type)) + UNITS_PER_WORD - 1)
+    cum->nbytes += ((arg.promoted_size_in_bytes () + UNITS_PER_WORD - 1)
 		    & -UNITS_PER_WORD);
   else
-    cum->nbytes += (((type && int_size_in_bytes (type) > 8
+    cum->nbytes += (((arg.type && int_size_in_bytes (arg.type) > 8
 		      ? GET_MODE_SIZE (Pmode)
-		      : (mode != BLKmode
-			 ? GET_MODE_SIZE (mode)
-			 : int_size_in_bytes (type))) + UNITS_PER_WORD - 1)
+		      : (HOST_WIDE_INT) arg.promoted_size_in_bytes ())
+		     + UNITS_PER_WORD - 1)
 		    & -UNITS_PER_WORD);
 }
 
Index: gcc/config/vax/vax.c
===================================================================
--- gcc/config/vax/vax.c	2019-08-19 15:58:42.421976335 +0100
+++ gcc/config/vax/vax.c	2019-08-19 15:58:50.341919030 +0100
@@ -55,8 +55,8 @@  static int vax_address_cost_1 (rtx);
 static int vax_address_cost (rtx, machine_mode, addr_space_t, bool);
 static bool vax_rtx_costs (rtx, machine_mode, int, int, int *, bool);
 static rtx vax_function_arg (cumulative_args_t, const function_arg_info &);
-static void vax_function_arg_advance (cumulative_args_t, machine_mode,
-				      const_tree, bool);
+static void vax_function_arg_advance (cumulative_args_t,
+				      const function_arg_info &);
 static rtx vax_struct_value_rtx (tree, int);
 static void vax_asm_trampoline_template (FILE *);
 static void vax_trampoline_init (rtx, tree, rtx);
@@ -2148,19 +2148,15 @@  vax_function_arg (cumulative_args_t, con
   return NULL_RTX;
 }
 
-/* Update the data in CUM to advance over an argument of mode MODE and
-   data type TYPE.  (TYPE is null for libcalls where that information
-   may not be available.)  */
+/* Update the data in CUM to advance over argument ARG.  */
 
 static void
-vax_function_arg_advance (cumulative_args_t cum_v, machine_mode mode,
-			  const_tree type, bool named ATTRIBUTE_UNUSED)
+vax_function_arg_advance (cumulative_args_t cum_v,
+			  const function_arg_info &arg)
 {
   CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
 
-  *cum += (mode != BLKmode
-	   ? (GET_MODE_SIZE (mode) + 3) & ~3
-	   : (int_size_in_bytes (type) + 3) & ~3);
+  *cum += (arg.promoted_size_in_bytes () + 3) & ~3;
 }
 
 static HOST_WIDE_INT
Index: gcc/config/visium/visium.c
===================================================================
--- gcc/config/visium/visium.c	2019-08-19 15:58:42.421976335 +0100
+++ gcc/config/visium/visium.c	2019-08-19 15:58:50.341919030 +0100
@@ -163,8 +163,8 @@  static bool visium_pass_by_reference (cu
 
 static rtx visium_function_arg (cumulative_args_t, const function_arg_info &);
 
-static void visium_function_arg_advance (cumulative_args_t, machine_mode,
-					 const_tree, bool);
+static void visium_function_arg_advance (cumulative_args_t,
+					 const function_arg_info &);
 
 static bool visium_return_in_memory (const_tree, const_tree fntype);
 
@@ -1358,28 +1358,25 @@  visium_function_arg (cumulative_args_t p
   return NULL_RTX;
 }
 
-/* Update the summarizer variable pointed to by PCUM_V to advance past an
-   argument in the argument list.  The values MODE, TYPE and NAMED describe
-   that argument.  Once this is done, the variable CUM is suitable for
+/* Update the summarizer variable pointed to by PCUM_V to advance past
+   argument ARG.  Once this is done, the variable CUM is suitable for
    analyzing the _following_ argument with visium_function_arg.  */
 
 static void
 visium_function_arg_advance (cumulative_args_t pcum_v,
-			     machine_mode mode,
-			     const_tree type ATTRIBUTE_UNUSED,
-			     bool named)
+			     const function_arg_info &arg)
 {
-  int size = (GET_MODE_SIZE (mode) + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
+  int size = (GET_MODE_SIZE (arg.mode) + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
   int stack_size = 0;
   CUMULATIVE_ARGS *ca = get_cumulative_args (pcum_v);
 
   /* Scalar or complex single precision floating point arguments are returned
      in floating registers.  */
   if (TARGET_FPU
-      && ((GET_MODE_CLASS (mode) == MODE_FLOAT
-	   && GET_MODE_SIZE (mode) <= UNITS_PER_HWFPVALUE)
-	  || (GET_MODE_CLASS (mode) == MODE_COMPLEX_FLOAT
-	      && GET_MODE_SIZE (mode) <= UNITS_PER_HWFPVALUE * 2)))
+      && ((GET_MODE_CLASS (arg.mode) == MODE_FLOAT
+	   && GET_MODE_SIZE (arg.mode) <= UNITS_PER_HWFPVALUE)
+	  || (GET_MODE_CLASS (arg.mode) == MODE_COMPLEX_FLOAT
+	      && GET_MODE_SIZE (arg.mode) <= UNITS_PER_HWFPVALUE * 2)))
     {
       if (ca->frcount + size <= MAX_ARGS_IN_FP_REGISTERS)
 	ca->frcount += size;
@@ -1402,7 +1399,7 @@  visium_function_arg_advance (cumulative_
 	}
     }
 
-  if (named)
+  if (arg.named)
     ca->stack_words += stack_size;
 }
 
@@ -1483,8 +1480,7 @@  visium_setup_incoming_varargs (cumulativ
   /* The caller has advanced ARGS_SO_FAR up to, but not beyond, the last named
      argument.  Advance a local copy of ARGS_SO_FAR past the last "real" named
      argument, to find out how many registers are left over.  */
-  TARGET_FUNCTION_ARG_ADVANCE (local_args_so_far, arg.mode,
-			       arg.type, arg.named);
+  TARGET_FUNCTION_ARG_ADVANCE (local_args_so_far, arg);
 
   /* Find how many registers we need to save.  */
   locargs = get_cumulative_args (local_args_so_far);
Index: gcc/config/xtensa/xtensa.c
===================================================================
--- gcc/config/xtensa/xtensa.c	2019-08-19 15:58:42.421976335 +0100
+++ gcc/config/xtensa/xtensa.c	2019-08-19 15:58:50.341919030 +0100
@@ -141,8 +141,8 @@  static tree xtensa_build_builtin_va_list
 static bool xtensa_return_in_memory (const_tree, const_tree);
 static tree xtensa_gimplify_va_arg_expr (tree, tree, gimple_seq *,
 					 gimple_seq *);
-static void xtensa_function_arg_advance (cumulative_args_t, machine_mode,
-					 const_tree, bool);
+static void xtensa_function_arg_advance (cumulative_args_t,
+					 const function_arg_info &);
 static rtx xtensa_function_arg (cumulative_args_t, const function_arg_info &);
 static rtx xtensa_function_incoming_arg (cumulative_args_t,
 					 const function_arg_info &);
@@ -2105,8 +2105,8 @@  init_cumulative_args (CUMULATIVE_ARGS *c
 /* Advance the argument to the next argument position.  */
 
 static void
-xtensa_function_arg_advance (cumulative_args_t cum, machine_mode mode,
-			     const_tree type, bool named ATTRIBUTE_UNUSED)
+xtensa_function_arg_advance (cumulative_args_t cum,
+			     const function_arg_info &arg)
 {
   int words, max;
   int *arg_words;
@@ -2114,12 +2114,11 @@  xtensa_function_arg_advance (cumulative_
   arg_words = &get_cumulative_args (cum)->arg_words;
   max = MAX_ARGS_IN_REGISTERS;
 
-  words = (((mode != BLKmode)
-	    ? (int) GET_MODE_SIZE (mode)
-	    : int_size_in_bytes (type)) + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
+  words = ((arg.promoted_size_in_bytes () + UNITS_PER_WORD - 1)
+	   / UNITS_PER_WORD);
 
   if (*arg_words < max
-      && (targetm.calls.must_pass_in_stack (mode, type)
+      && (targetm.calls.must_pass_in_stack (arg.mode, arg.type)
 	  || *arg_words + words > max))
     *arg_words = max;