Use function_arg_info for TARGET_SETUP_INCOMING_ARGS. The hook is passed the promoted mode instead of the original type mode.
2019-08-19 Richard Sandiford <richard.sandif...@arm.com> gcc/ * target.def (setup_incoming_varargs): Take a function_arg_info instead of a mode and tree. * doc/tm.texi: Regenerate. * targhooks.h (default_setup_incoming_varargs): Take a function_arg_info instead of a mode and tree. * targhooks.c (default_setup_incoming_varargs): Likewise. * config/aarch64/aarch64.c (aarch64_setup_incoming_varargs): Likewise. * config/alpha/alpha.c (alpha_setup_incoming_varargs): Likewise. * config/arc/arc.c (arc_setup_incoming_varargs): Likewise. * config/arm/arm.c (arm_setup_incoming_varargs): Likewise. * config/bfin/bfin.c (setup_incoming_varargs): Likewise. * config/cris/cris.c (cris_setup_incoming_varargs): Likewise. * config/csky/csky.c (csky_setup_incoming_varargs): Likewise. * config/epiphany/epiphany.c (epiphany_setup_incoming_varargs): Likewise. * config/fr30/fr30.c (fr30_setup_incoming_varargs): Likewise. * config/frv/frv.c (frv_setup_incoming_varargs): Likewise. * config/ft32/ft32.c (ft32_setup_incoming_varargs): Likewise. * config/i386/i386.c (ix86_setup_incoming_varargs): Likewise. * config/ia64/ia64.c (ia64_setup_incoming_varargs): Likewise. * config/iq2000/iq2000.c (iq2000_setup_incoming_varargs): Likewise. * config/lm32/lm32.c (lm32_setup_incoming_varargs): Likewise. * config/m32r/m32r.c (m32r_setup_incoming_varargs): Likewise. * config/mcore/mcore.c (mcore_setup_incoming_varargs): Likewise. * config/mips/mips.c (mips_setup_incoming_varargs): Likewise. * config/mmix/mmix.c (mmix_setup_incoming_varargs): Likewise. * config/moxie/moxie.c (moxie_setup_incoming_varargs): Likewise. * config/nds32/nds32.c (nds32_setup_incoming_varargs): Likewise. * config/nios2/nios2.c (nios2_setup_incoming_varargs): Likewise. * config/riscv/riscv.c (riscv_setup_incoming_varargs): Likewise. * config/rs6000/rs6000-internal.h (setup_incoming_varargs): Likewise. * config/rs6000/rs6000-call.c (setup_incoming_varargs): Likewise. * config/sh/sh.c (sh_setup_incoming_varargs): Likewise. * config/spu/spu.c (spu_setup_incoming_varargs): Likewise. * config/tilegx/tilegx.c (tilegx_setup_incoming_varargs): Likewise. * config/tilepro/tilepro.c (tilepro_setup_incoming_varargs): Likewise. * config/visium/visium.c (visium_setup_incoming_varargs): Likewise. * function.c (assign_parms_setup_varargs): Update call to targetm.calls.setup_incoming_varargs. Index: gcc/target.def =================================================================== --- gcc/target.def 2019-08-19 15:58:28.450077433 +0100 +++ gcc/target.def 2019-08-19 15:58:34.850031127 +0100 @@ -4486,8 +4486,8 @@ pass all their arguments on the stack.\n \n\ The argument @var{args_so_far} points to the @code{CUMULATIVE_ARGS} data\n\ structure, containing the values that are obtained after processing the\n\ -named arguments. The arguments @var{mode} and @var{type} describe the\n\ -last named argument---its machine mode and its data type as a tree node.\n\ +named arguments. The argument @var{arg} describes the last of these named\n\ +arguments.\n\ \n\ The target hook should do two things: first, push onto the stack all the\n\ argument registers @emph{not} used for the named arguments, and second,\n\ @@ -4507,7 +4507,7 @@ arguments of the function are being anal happens for an inline function, which is not actually compiled until the\n\ end of the source file. The hook @code{TARGET_SETUP_INCOMING_VARARGS} should\n\ not generate any instructions in this case.", - void, (cumulative_args_t args_so_far, machine_mode mode, tree type, + void, (cumulative_args_t args_so_far, const function_arg_info &arg, int *pretend_args_size, int second_time), default_setup_incoming_varargs) Index: gcc/doc/tm.texi =================================================================== --- gcc/doc/tm.texi 2019-08-19 15:58:28.450077433 +0100 +++ gcc/doc/tm.texi 2019-08-19 15:58:34.850031127 +0100 @@ -5202,7 +5202,7 @@ return value of this function should be to use as the return of @code{__builtin_saveregs}. @end deftypefn -@deftypefn {Target Hook} void TARGET_SETUP_INCOMING_VARARGS (cumulative_args_t @var{args_so_far}, machine_mode @var{mode}, tree @var{type}, int *@var{pretend_args_size}, int @var{second_time}) +@deftypefn {Target Hook} void TARGET_SETUP_INCOMING_VARARGS (cumulative_args_t @var{args_so_far}, const function_arg_info @var{&arg}, int *@var{pretend_args_size}, int @var{second_time}) This target hook offers an alternative to using @code{__builtin_saveregs} and defining the hook @code{TARGET_EXPAND_BUILTIN_SAVEREGS}. Use it to store the anonymous @@ -5213,8 +5213,8 @@ pass all their arguments on the stack. The argument @var{args_so_far} points to the @code{CUMULATIVE_ARGS} data structure, containing the values that are obtained after processing the -named arguments. The arguments @var{mode} and @var{type} describe the -last named argument---its machine mode and its data type as a tree node. +named arguments. The argument @var{arg} describes the last of these named +arguments. The target hook should do two things: first, push onto the stack all the argument registers @emph{not} used for the named arguments, and second, Index: gcc/targhooks.h =================================================================== --- gcc/targhooks.h 2019-08-19 15:58:28.450077433 +0100 +++ gcc/targhooks.h 2019-08-19 15:58:34.850031127 +0100 @@ -40,7 +40,9 @@ extern machine_mode default_cc_modes_com extern bool default_return_in_memory (const_tree, const_tree); extern rtx default_expand_builtin_saveregs (void); -extern void default_setup_incoming_varargs (cumulative_args_t, machine_mode, tree, int *, int); +extern void default_setup_incoming_varargs (cumulative_args_t, + const function_arg_info &, + int *, int); extern rtx default_builtin_setjmp_frame_value (void); extern bool default_pretend_outgoing_varargs_named (cumulative_args_t); Index: gcc/targhooks.c =================================================================== --- gcc/targhooks.c 2019-08-19 15:58:28.450077433 +0100 +++ gcc/targhooks.c 2019-08-19 15:58:34.850031127 +0100 @@ -193,11 +193,8 @@ default_expand_builtin_saveregs (void) } void -default_setup_incoming_varargs (cumulative_args_t ca ATTRIBUTE_UNUSED, - machine_mode mode ATTRIBUTE_UNUSED, - tree type ATTRIBUTE_UNUSED, - int *pretend_arg_size ATTRIBUTE_UNUSED, - int second_time ATTRIBUTE_UNUSED) +default_setup_incoming_varargs (cumulative_args_t, + const function_arg_info &, int *, int) { } Index: gcc/config/aarch64/aarch64.c =================================================================== --- gcc/config/aarch64/aarch64.c 2019-08-19 15:58:28.422077636 +0100 +++ gcc/config/aarch64/aarch64.c 2019-08-19 15:58:34.822031327 +0100 @@ -14511,9 +14511,9 @@ aarch64_gimplify_va_arg_expr (tree valis /* Implement TARGET_SETUP_INCOMING_VARARGS. */ static void -aarch64_setup_incoming_varargs (cumulative_args_t cum_v, machine_mode mode, - tree type, int *pretend_size ATTRIBUTE_UNUSED, - int no_rtl) +aarch64_setup_incoming_varargs (cumulative_args_t cum_v, + const function_arg_info &arg, + int *pretend_size ATTRIBUTE_UNUSED, int no_rtl) { CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v); CUMULATIVE_ARGS local_cum; @@ -14524,7 +14524,8 @@ 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), mode, type, true); + aarch64_function_arg_advance (pack_cumulative_args(&local_cum), + arg.mode, arg.type, arg.named); /* 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:28.422077636 +0100 +++ gcc/config/alpha/alpha.c 2019-08-19 15:58:34.822031327 +0100 @@ -6090,14 +6090,15 @@ alpha_stdarg_optimize_hook (struct stdar variable number of arguments. */ static void -alpha_setup_incoming_varargs (cumulative_args_t pcum, machine_mode mode, - tree type, int *pretend_size, int no_rtl) +alpha_setup_incoming_varargs (cumulative_args_t pcum, + const function_arg_info &arg, + int *pretend_size, int no_rtl) { CUMULATIVE_ARGS cum = *get_cumulative_args (pcum); /* Skip the current argument. */ - targetm.calls.function_arg_advance (pack_cumulative_args (&cum), mode, type, - true); + targetm.calls.function_arg_advance (pack_cumulative_args (&cum), + arg.mode, arg.type, arg.named); #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:28.426077609 +0100 +++ gcc/config/arc/arc.c 2019-08-19 15:58:34.826031299 +0100 @@ -2415,12 +2415,12 @@ arc_double_limm_p (rtx value) create a register parameter block, and then copy any anonymous arguments in registers to memory. - CUM has not been updated for the last named argument which has type TYPE - and mode MODE, and we rely on this fact. */ + CUM has not been updated for the last named argument (which is given + by ARG), and we rely on this fact. */ static void arc_setup_incoming_varargs (cumulative_args_t args_so_far, - machine_mode mode, tree type, + const function_arg_info &arg, int *pretend_size, int no_rtl) { int first_anon_arg; @@ -2430,7 +2430,7 @@ arc_setup_incoming_varargs (cumulative_a next_cum = *get_cumulative_args (args_so_far); arc_function_arg_advance (pack_cumulative_args (&next_cum), - mode, type, true); + arg.mode, arg.type, arg.named); first_anon_arg = next_cum; if (FUNCTION_ARG_REGNO_P (first_anon_arg)) Index: gcc/config/arm/arm.c =================================================================== --- gcc/config/arm/arm.c 2019-08-19 15:58:28.430077578 +0100 +++ gcc/config/arm/arm.c 2019-08-19 15:58:34.830031272 +0100 @@ -212,8 +212,8 @@ static void arm_file_end (void); static void arm_file_start (void); static void arm_insert_attributes (tree, tree *); -static void arm_setup_incoming_varargs (cumulative_args_t, machine_mode, - tree, int *, int); +static void arm_setup_incoming_varargs (cumulative_args_t, + const function_arg_info &, int *, int); static bool arm_pass_by_reference (cumulative_args_t, const function_arg_info &); static bool arm_promote_prototypes (const_tree); @@ -27054,8 +27054,7 @@ arm_output_load_gr (rtx *operands) static void arm_setup_incoming_varargs (cumulative_args_t pcum_v, - machine_mode mode, - tree type, + const function_arg_info &arg, int *pretend_size, int second_time ATTRIBUTE_UNUSED) { @@ -27068,17 +27067,17 @@ arm_setup_incoming_varargs (cumulative_a nregs = pcum->aapcs_ncrn; if (nregs & 1) { - int res = arm_needs_doubleword_align (mode, type); + int res = arm_needs_doubleword_align (arg.mode, arg.type); if (res < 0 && warn_psabi) inform (input_location, "parameter passing for argument of " - "type %qT changed in GCC 7.1", type); + "type %qT changed in GCC 7.1", arg.type); else if (res > 0) { nregs++; if (res > 1 && warn_psabi) inform (input_location, "parameter passing for argument of type " - "%qT changed in GCC 9.1", type); + "%qT changed in GCC 9.1", arg.type); } } } Index: gcc/config/bfin/bfin.c =================================================================== --- gcc/config/bfin/bfin.c 2019-08-19 15:58:28.430077578 +0100 +++ gcc/config/bfin/bfin.c 2019-08-19 15:58:34.830031272 +0100 @@ -540,7 +540,7 @@ expand_epilogue_reg_restore (rtx spreg, CUM is as above. - MODE and TYPE are the mode and type of the current parameter. + ARG is the last named argument. PRETEND_SIZE is a variable that should be set to the amount of stack that must be pushed by the prolog to pretend that our caller pushed @@ -559,8 +559,7 @@ expand_epilogue_reg_restore (rtx spreg, static void setup_incoming_varargs (cumulative_args_t cum, - machine_mode mode ATTRIBUTE_UNUSED, - tree type ATTRIBUTE_UNUSED, int *pretend_size, + const function_arg_info &, int *pretend_size, int no_rtl) { rtx mem; Index: gcc/config/cris/cris.c =================================================================== --- gcc/config/cris/cris.c 2019-08-19 15:58:28.430077578 +0100 +++ gcc/config/cris/cris.c 2019-08-19 15:58:34.834031241 +0100 @@ -108,8 +108,9 @@ static struct machine_function * cris_in static rtx cris_struct_value_rtx (tree, int); -static void cris_setup_incoming_varargs (cumulative_args_t, machine_mode, - tree type, int *, int); +static void cris_setup_incoming_varargs (cumulative_args_t, + const function_arg_info &, + int *, int); static int cris_initial_frame_pointer_offset (void); @@ -4021,8 +4022,7 @@ cris_struct_value_rtx (tree fntype ATTRI static void cris_setup_incoming_varargs (cumulative_args_t ca_v, - machine_mode mode ATTRIBUTE_UNUSED, - tree type ATTRIBUTE_UNUSED, + const function_arg_info &, int *pretend_arg_size, int second_time) { Index: gcc/config/csky/csky.c =================================================================== --- gcc/config/csky/csky.c 2019-08-19 15:58:21.726126086 +0100 +++ gcc/config/csky/csky.c 2019-08-19 15:58:34.834031241 +0100 @@ -1937,8 +1937,7 @@ csky_arg_partial_bytes (cumulative_args_ static void csky_setup_incoming_varargs (cumulative_args_t pcum_v, - machine_mode mode, - tree type, + const function_arg_info &arg, int *pretend_size, int second_time ATTRIBUTE_UNUSED) { @@ -1949,7 +1948,7 @@ csky_setup_incoming_varargs (cumulative_ cfun->machine->uses_anonymous_args = 1; local_cum = *pcum; - csky_function_arg_advance (local_cum_v, mode, type, true); + csky_function_arg_advance (local_cum_v, arg.mode, arg.type, arg.named); 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:28.434077550 +0100 +++ gcc/config/epiphany/epiphany.c 2019-08-19 15:58:34.834031241 +0100 @@ -711,24 +711,25 @@ epiphany_function_arg_boundary (machine_ /* Do any needed setup for a variadic function. For the EPIPHANY, we actually emit the code in epiphany_expand_prologue. - CUM has not been updated for the last named argument which has type TYPE - and mode MODE, and we rely on this fact. */ + CUM has not been updated for the last named argument (which is given + by ARG), and we rely on this fact. */ static void -epiphany_setup_incoming_varargs (cumulative_args_t cum, machine_mode mode, - tree type, int *pretend_size, int no_rtl) +epiphany_setup_incoming_varargs (cumulative_args_t cum, + const function_arg_info &arg, + int *pretend_size, int no_rtl) { int first_anon_arg; CUMULATIVE_ARGS next_cum; machine_function_t *mf = MACHINE_FUNCTION (cfun); /* All BLKmode values are passed by reference. */ - gcc_assert (mode != BLKmode); + gcc_assert (arg.mode != BLKmode); next_cum = *get_cumulative_args (cum); - next_cum - = ROUND_ADVANCE_CUM (next_cum, mode, type) + ROUND_ADVANCE_ARG (mode, type); + next_cum = (ROUND_ADVANCE_CUM (next_cum, arg.mode, arg.type) + + ROUND_ADVANCE_ARG (arg.mode, arg.type)); first_anon_arg = next_cum; if (first_anon_arg < MAX_EPIPHANY_PARM_REGS && !no_rtl) Index: gcc/config/fr30/fr30.c =================================================================== --- gcc/config/fr30/fr30.c 2019-08-19 15:58:21.730126059 +0100 +++ gcc/config/fr30/fr30.c 2019-08-19 15:58:34.834031241 +0100 @@ -113,8 +113,9 @@ struct fr30_frame_info /* Zero structure to initialize current_frame_info. */ static struct fr30_frame_info zero_frame_info; -static void fr30_setup_incoming_varargs (cumulative_args_t, machine_mode, - tree, int *, int); +static void fr30_setup_incoming_varargs (cumulative_args_t, + const function_arg_info &, + int *, int); static bool fr30_must_pass_in_stack (machine_mode, const_tree); static int fr30_arg_partial_bytes (cumulative_args_t, const function_arg_info &); @@ -459,12 +460,11 @@ fr30_expand_epilogue (void) named argument, from registers into memory. * copying actually done in fr30_expand_prologue(). - ARG_REGS_USED_SO_FAR has *not* been updated for the last named argument - which has type TYPE and mode MODE, and we rely on this fact. */ + CUM has not been updated for the last named argument which has type TYPE + and mode MODE, and we rely on this fact. */ void fr30_setup_incoming_varargs (cumulative_args_t arg_regs_used_so_far_v, - machine_mode mode, - tree type ATTRIBUTE_UNUSED, + const function_arg_info &arg, int *pretend_size, int second_time ATTRIBUTE_UNUSED) { @@ -473,7 +473,7 @@ fr30_setup_incoming_varargs (cumulative_ int size; /* All BLKmode values are passed by reference. */ - gcc_assert (mode != BLKmode); + gcc_assert (arg.mode != BLKmode); /* ??? This run-time test as well as the code inside the if statement is probably unnecessary. */ @@ -481,7 +481,7 @@ fr30_setup_incoming_varargs (cumulative_ /* If TARGET_STRICT_ARGUMENT_NAMING returns true, then the last named arg must not be treated as an anonymous arg. */ /* ??? This is a pointer increment, which makes no sense. */ - arg_regs_used_so_far += fr30_num_arg_regs (mode, type); + arg_regs_used_so_far += fr30_num_arg_regs (arg.mode, arg.type); size = FR30_NUM_ARG_REGS - (* arg_regs_used_so_far); Index: gcc/config/frv/frv.c =================================================================== --- gcc/config/frv/frv.c 2019-08-19 15:58:21.730126059 +0100 +++ gcc/config/frv/frv.c 2019-08-19 15:58:34.834031241 +0100 @@ -359,8 +359,8 @@ static bool frv_in_small_data_p (const static void frv_asm_output_mi_thunk (FILE *, tree, HOST_WIDE_INT, HOST_WIDE_INT, tree); static void frv_setup_incoming_varargs (cumulative_args_t, - machine_mode, - tree, int *, int); + const function_arg_info &, + int *, int); static rtx frv_expand_builtin_saveregs (void); static void frv_expand_builtin_va_start (tree, rtx); static bool frv_rtx_costs (rtx, machine_mode, int, int, @@ -2109,17 +2109,16 @@ frv_initial_elimination_offset (int from static void frv_setup_incoming_varargs (cumulative_args_t cum_v, - machine_mode mode, - tree type ATTRIBUTE_UNUSED, - int *pretend_size, - int second_time) + const function_arg_info &arg, + int *pretend_size, + int second_time) { CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v); if (TARGET_DEBUG_ARG) fprintf (stderr, "setup_vararg: words = %2d, mode = %4s, pretend_size = %d, second_time = %d\n", - *cum, GET_MODE_NAME (mode), *pretend_size, second_time); + *cum, GET_MODE_NAME (arg.mode), *pretend_size, second_time); } Index: gcc/config/ft32/ft32.c =================================================================== --- gcc/config/ft32/ft32.c 2019-08-19 15:58:28.434077550 +0100 +++ gcc/config/ft32/ft32.c 2019-08-19 15:58:34.834031241 +0100 @@ -630,13 +630,12 @@ ft32_initial_elimination_offset (int fro static void ft32_setup_incoming_varargs (cumulative_args_t cum_v, - machine_mode mode, - tree type ATTRIBUTE_UNUSED, + const function_arg_info &arg, int *pretend_size, int no_rtl ATTRIBUTE_UNUSED) { CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v); int named_size = - GET_MODE_SIZE (SImode) * (*cum - FT32_R0) + GET_MODE_SIZE (mode); + GET_MODE_SIZE (SImode) * (*cum - FT32_R0) + GET_MODE_SIZE (arg.mode); if (named_size < 24) *pretend_size = 24 - named_size; Index: gcc/config/i386/i386.c =================================================================== --- gcc/config/i386/i386.c 2019-08-19 15:58:28.434077550 +0100 +++ gcc/config/i386/i386.c 2019-08-19 15:58:34.838031214 +0100 @@ -4096,8 +4096,9 @@ setup_incoming_varargs_ms_64 (CUMULATIVE } static void -ix86_setup_incoming_varargs (cumulative_args_t cum_v, machine_mode mode, - tree type, int *, int no_rtl) +ix86_setup_incoming_varargs (cumulative_args_t cum_v, + const function_arg_info &arg, + int *, int no_rtl) { CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v); CUMULATIVE_ARGS next_cum; @@ -4116,8 +4117,8 @@ 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), mode, type, - true); + ix86_function_arg_advance (pack_cumulative_args (&next_cum), + arg.mode, arg.type, arg.named); 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:21.734126028 +0100 +++ gcc/config/ia64/ia64.c 2019-08-19 15:58:34.838031214 +0100 @@ -199,8 +199,9 @@ static rtx gen_fr_restore_x (rtx, rtx, r static void ia64_option_override (void); static bool ia64_can_eliminate (const int, const int); static machine_mode hfa_element_mode (const_tree, bool); -static void ia64_setup_incoming_varargs (cumulative_args_t, machine_mode, - tree, int *, int); +static void ia64_setup_incoming_varargs (cumulative_args_t, + const function_arg_info &, + int *, int); static int ia64_arg_partial_bytes (cumulative_args_t, const function_arg_info &); static rtx ia64_function_arg_1 (cumulative_args_t, machine_mode, @@ -4585,19 +4586,21 @@ ia64_trampoline_init (rtx m_tramp, tree } /* Do any needed setup for a variadic function. CUM has not been updated - for the last named argument which has type TYPE and mode MODE. + for the last named argument, which is given by ARG. We generate the actual spill instructions during prologue generation. */ static void -ia64_setup_incoming_varargs (cumulative_args_t cum, machine_mode mode, - tree type, int * pretend_size, +ia64_setup_incoming_varargs (cumulative_args_t cum, + const function_arg_info &arg, + int *pretend_size, int second_time ATTRIBUTE_UNUSED) { CUMULATIVE_ARGS next_cum = *get_cumulative_args (cum); /* Skip the current argument. */ - ia64_function_arg_advance (pack_cumulative_args (&next_cum), mode, type, 1); + ia64_function_arg_advance (pack_cumulative_args (&next_cum), + arg.mode, arg.type, arg.named); if (next_cum.words < MAX_ARGUMENT_SLOTS) { Index: gcc/config/iq2000/iq2000.c =================================================================== --- gcc/config/iq2000/iq2000.c 2019-08-19 15:58:28.434077550 +0100 +++ gcc/config/iq2000/iq2000.c 2019-08-19 15:58:34.842031183 +0100 @@ -152,8 +152,8 @@ static void iq2000_init_builtins (v static rtx iq2000_expand_builtin (tree, rtx, rtx, machine_mode, int); static bool iq2000_return_in_memory (const_tree, const_tree); static void iq2000_setup_incoming_varargs (cumulative_args_t, - machine_mode, tree, int *, - int); + const function_arg_info &, + int *, int); static bool iq2000_rtx_costs (rtx, machine_mode, int, int, int *, bool); static int iq2000_address_cost (rtx, machine_mode, addr_space_t, bool); @@ -2894,9 +2894,8 @@ iq2000_return_in_memory (const_tree type static void iq2000_setup_incoming_varargs (cumulative_args_t cum_v, - machine_mode mode ATTRIBUTE_UNUSED, - tree type ATTRIBUTE_UNUSED, int * pretend_size, - int no_rtl) + const function_arg_info &, + int *pretend_size, int no_rtl) { CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v); unsigned int iq2000_off = ! cum->last_arg_fp; Index: gcc/config/lm32/lm32.c =================================================================== --- gcc/config/lm32/lm32.c 2019-03-08 18:15:37.796736185 +0000 +++ gcc/config/lm32/lm32.c 2019-08-19 15:58:34.842031183 +0100 @@ -64,7 +64,7 @@ static void expand_save_restore (struct static void stack_adjust (HOST_WIDE_INT amount); static bool lm32_in_small_data_p (const_tree); static void lm32_setup_incoming_varargs (cumulative_args_t cum, - machine_mode mode, tree type, + const function_arg_info &, int *pretend_size, int no_rtl); static bool lm32_rtx_costs (rtx x, machine_mode mode, int outer_code, int opno, int *total, bool speed); @@ -684,8 +684,9 @@ lm32_compute_initial_elimination_offset } static void -lm32_setup_incoming_varargs (cumulative_args_t cum_v, machine_mode mode, - tree type, int *pretend_size, int no_rtl) +lm32_setup_incoming_varargs (cumulative_args_t cum_v, + const function_arg_info &arg, + int *pretend_size, int no_rtl) { CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v); int first_anon_arg; @@ -702,12 +703,7 @@ lm32_setup_incoming_varargs (cumulative_ registers, if any used in passing this named paramter in order to determine which is the first registers used to pass anonymous arguments. */ - int size; - - if (mode == BLKmode) - size = int_size_in_bytes (type); - else - size = GET_MODE_SIZE (mode); + int size = arg.promoted_size_in_bytes (); first_anon_arg = *cum + LM32_FIRST_ARG_REG + Index: gcc/config/m32r/m32r.c =================================================================== --- gcc/config/m32r/m32r.c 2019-08-19 15:58:28.434077550 +0100 +++ gcc/config/m32r/m32r.c 2019-08-19 15:58:34.842031183 +0100 @@ -86,8 +86,9 @@ static bool m32r_return_in_memory (const static rtx m32r_function_value (const_tree, const_tree, bool); static rtx m32r_libcall_value (machine_mode, const_rtx); static bool m32r_function_value_regno_p (const unsigned int); -static void m32r_setup_incoming_varargs (cumulative_args_t, machine_mode, - tree, int *, int); +static void m32r_setup_incoming_varargs (cumulative_args_t, + const function_arg_info &, + int *, int); static void init_idents (void); static bool m32r_rtx_costs (rtx, machine_mode, int, int, int *, bool speed); static int m32r_memory_move_cost (machine_mode, reg_class_t, bool); @@ -1280,12 +1281,13 @@ m32r_function_value_regno_p (const unsig create a register parameter block, and then copy any anonymous arguments in registers to memory. - CUM has not been updated for the last named argument which has type TYPE - and mode MODE, and we rely on this fact. */ + CUM has not been updated for the last named argument (which is given + by ARG), and we rely on this fact. */ static void -m32r_setup_incoming_varargs (cumulative_args_t cum, machine_mode mode, - tree type, int *pretend_size, int no_rtl) +m32r_setup_incoming_varargs (cumulative_args_t cum, + const function_arg_info &arg, + int *pretend_size, int no_rtl) { int first_anon_arg; @@ -1293,10 +1295,11 @@ m32r_setup_incoming_varargs (cumulative_ return; /* All BLKmode values are passed by reference. */ - gcc_assert (mode != BLKmode); + gcc_assert (arg.mode != BLKmode); - first_anon_arg = (ROUND_ADVANCE_CUM (*get_cumulative_args (cum), mode, type) - + ROUND_ADVANCE_ARG (mode, type)); + first_anon_arg = (ROUND_ADVANCE_CUM (*get_cumulative_args (cum), + arg.mode, arg.type) + + ROUND_ADVANCE_ARG (arg.mode, arg.type)); if (first_anon_arg < M32R_MAX_PARM_REGS) { Index: gcc/config/mcore/mcore.c =================================================================== --- gcc/config/mcore/mcore.c 2019-08-19 15:58:21.734126028 +0100 +++ gcc/config/mcore/mcore.c 2019-08-19 15:58:34.842031183 +0100 @@ -99,7 +99,9 @@ static int calc_live_regs static int try_constant_tricks (HOST_WIDE_INT, HOST_WIDE_INT *, HOST_WIDE_INT *); static const char * output_inline_const (machine_mode, rtx *); static void layout_mcore_frame (struct mcore_frame *); -static void mcore_setup_incoming_varargs (cumulative_args_t, machine_mode, tree, int *, int); +static void mcore_setup_incoming_varargs (cumulative_args_t, + const function_arg_info &, + int *, int); static cond_type is_cond_candidate (rtx); static rtx_insn *emit_new_cond_insn (rtx_insn *, int); static rtx_insn *conditionalize_block (rtx_insn *); @@ -1942,7 +1944,7 @@ mcore_initial_elimination_offset (int fr static void mcore_setup_incoming_varargs (cumulative_args_t args_so_far_v, - machine_mode mode, tree type, + const function_arg_info &arg, int * ptr_pretend_size ATTRIBUTE_UNUSED, int second_time ATTRIBUTE_UNUSED) { @@ -1953,7 +1955,8 @@ mcore_setup_incoming_varargs (cumulative /* We need to know how many argument registers are used before the varargs start, so that we can push the remaining argument registers during the prologue. */ - number_of_regs_before_varargs = *args_so_far + mcore_num_arg_regs (mode, type); + number_of_regs_before_varargs + = *args_so_far + mcore_num_arg_regs (arg.mode, arg.type); /* There is a bug somewhere in the arg handling code. Until I can find it this workaround always pushes the Index: gcc/config/mips/mips.c =================================================================== --- gcc/config/mips/mips.c 2019-08-19 15:58:28.438077523 +0100 +++ gcc/config/mips/mips.c 2019-08-19 15:58:34.842031183 +0100 @@ -6544,9 +6544,9 @@ mips_return_in_memory (const_tree type, /* Implement TARGET_SETUP_INCOMING_VARARGS. */ static void -mips_setup_incoming_varargs (cumulative_args_t cum, machine_mode mode, - tree type, int *pretend_size ATTRIBUTE_UNUSED, - int no_rtl) +mips_setup_incoming_varargs (cumulative_args_t cum, + const function_arg_info &arg, + int *pretend_size ATTRIBUTE_UNUSED, int no_rtl) { CUMULATIVE_ARGS local_cum; int gp_saved, fp_saved; @@ -6555,8 +6555,8 @@ 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), mode, type, - true); + mips_function_arg_advance (pack_cumulative_args (&local_cum), + arg.mode, arg.type, arg.named); /* Found out how many registers we need to save. */ gp_saved = MAX_ARGS_IN_REGISTERS - local_cum.num_gprs; Index: gcc/config/mmix/mmix.c =================================================================== --- gcc/config/mmix/mmix.c 2019-08-19 15:58:28.438077523 +0100 +++ gcc/config/mmix/mmix.c 2019-08-19 15:58:34.842031183 +0100 @@ -138,7 +138,7 @@ static void mmix_reorg (void); static void mmix_asm_output_mi_thunk (FILE *, tree, HOST_WIDE_INT, HOST_WIDE_INT, tree); static void mmix_setup_incoming_varargs - (cumulative_args_t, machine_mode, tree, int *, int); + (cumulative_args_t, const function_arg_info &, int *, int); static void mmix_file_start (void); static void mmix_file_end (void); static void mmix_init_libfuncs (void); @@ -960,8 +960,7 @@ mmix_function_profiler (FILE *stream ATT static void mmix_setup_incoming_varargs (cumulative_args_t args_so_farp_v, - machine_mode mode, - tree vartype, + const function_arg_info &arg, int *pretend_sizep, int second_time ATTRIBUTE_UNUSED) { @@ -974,7 +973,7 @@ mmix_setup_incoming_varargs (cumulative_ /* We assume that one argument takes up one register here. That should be true until we start messing with multi-reg parameters. */ - if ((7 + (MMIX_FUNCTION_ARG_SIZE (mode, vartype))) / 8 != 1) + if ((7 + (MMIX_FUNCTION_ARG_SIZE (arg.mode, arg.type))) / 8 != 1) internal_error ("MMIX Internal: Last named vararg would not fit in a register"); } Index: gcc/config/moxie/moxie.c =================================================================== --- gcc/config/moxie/moxie.c 2019-08-19 15:58:28.438077523 +0100 +++ gcc/config/moxie/moxie.c 2019-08-19 15:58:34.842031183 +0100 @@ -385,8 +385,7 @@ moxie_initial_elimination_offset (int fr static void moxie_setup_incoming_varargs (cumulative_args_t cum_v, - machine_mode mode ATTRIBUTE_UNUSED, - tree type ATTRIBUTE_UNUSED, + const function_arg_info &, int *pretend_size, int no_rtl) { CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v); Index: gcc/config/nds32/nds32.c =================================================================== --- gcc/config/nds32/nds32.c 2019-08-19 15:58:21.738126000 +0100 +++ gcc/config/nds32/nds32.c 2019-08-19 15:58:34.846031154 +0100 @@ -2345,8 +2345,7 @@ nds32_warn_func_return (tree decl) static void nds32_setup_incoming_varargs (cumulative_args_t ca, - machine_mode mode, - tree type, + const function_arg_info &arg, int *pretend_args_size, int second_time ATTRIBUTE_UNUSED) { @@ -2370,14 +2369,14 @@ nds32_setup_incoming_varargs (cumulative cum = get_cumulative_args (ca); - /* The MODE and TYPE describe the last argument. + /* ARG describes the last argument. We need those information to determine the remaining registers for varargs. */ total_args_regs = NDS32_MAX_GPR_REGS_FOR_ARGS + NDS32_GPR_ARG_FIRST_REGNUM; num_of_used_regs - = NDS32_AVAILABLE_REGNUM_FOR_GPR_ARG (cum->gpr_offset, mode, type) - + NDS32_NEED_N_REGS_FOR_ARG (mode, type); + = NDS32_AVAILABLE_REGNUM_FOR_GPR_ARG (cum->gpr_offset, arg.mode, arg.type) + + NDS32_NEED_N_REGS_FOR_ARG (arg.mode, arg.type); remaining_reg_count = total_args_regs - num_of_used_regs; *pretend_args_size = remaining_reg_count * UNITS_PER_WORD; Index: gcc/config/nios2/nios2.c =================================================================== --- gcc/config/nios2/nios2.c 2019-08-19 15:58:21.738126000 +0100 +++ gcc/config/nios2/nios2.c 2019-08-19 15:58:34.846031154 +0100 @@ -3516,8 +3516,8 @@ nios2_return_in_memory (const_tree type, own va_arg type. */ static void nios2_setup_incoming_varargs (cumulative_args_t cum_v, - machine_mode mode, tree type, - int *pretend_size, int second_time) + const function_arg_info &arg, + int *pretend_size, int second_time) { CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v); CUMULATIVE_ARGS local_cum; @@ -3527,7 +3527,7 @@ nios2_setup_incoming_varargs (cumulative cfun->machine->uses_anonymous_args = 1; local_cum = *cum; - nios2_function_arg_advance (local_cum_v, mode, type, true); + nios2_function_arg_advance (local_cum_v, arg.mode, arg.type, arg.named); regs_to_push = NUM_ARG_REGS - local_cum.regs_used; Index: gcc/config/riscv/riscv.c =================================================================== --- gcc/config/riscv/riscv.c 2019-08-19 15:58:28.442077491 +0100 +++ gcc/config/riscv/riscv.c 2019-08-19 15:58:34.846031154 +0100 @@ -2854,9 +2854,9 @@ riscv_return_in_memory (const_tree type, /* Implement TARGET_SETUP_INCOMING_VARARGS. */ static void -riscv_setup_incoming_varargs (cumulative_args_t cum, machine_mode mode, - tree type, int *pretend_size ATTRIBUTE_UNUSED, - int no_rtl) +riscv_setup_incoming_varargs (cumulative_args_t cum, + const function_arg_info &arg, + int *pretend_size ATTRIBUTE_UNUSED, int no_rtl) { CUMULATIVE_ARGS local_cum; int gp_saved; @@ -2865,7 +2865,8 @@ 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), mode, type, 1); + riscv_function_arg_advance (pack_cumulative_args (&local_cum), + arg.mode, arg.type, arg.named); /* Found out how many registers we need to save. */ gp_saved = MAX_ARGS_IN_REGISTERS - local_cum.num_gprs; Index: gcc/config/rs6000/rs6000-internal.h =================================================================== --- gcc/config/rs6000/rs6000-internal.h 2019-08-19 15:58:28.442077491 +0100 +++ gcc/config/rs6000/rs6000-internal.h 2019-08-19 15:58:34.846031154 +0100 @@ -152,9 +152,8 @@ extern bool rs6000_return_in_memory (con extern bool rs6000_return_in_msb (const_tree valtype); extern bool rs6000_pass_by_reference (cumulative_args_t, const function_arg_info &); -extern void setup_incoming_varargs (cumulative_args_t cum, machine_mode mode, - tree type, int *pretend_size ATTRIBUTE_UNUSED, - int no_rtl); +extern void setup_incoming_varargs (cumulative_args_t, + const function_arg_info &, int *, int); extern unsigned int rs6000_function_arg_boundary (machine_mode mode, const_tree type); extern bool rs6000_must_pass_in_stack (machine_mode mode, const_tree type); Index: gcc/config/rs6000/rs6000-call.c =================================================================== --- gcc/config/rs6000/rs6000-call.c 2019-08-19 15:58:28.442077491 +0100 +++ gcc/config/rs6000/rs6000-call.c 2019-08-19 15:58:34.846031154 +0100 @@ -2365,7 +2365,7 @@ rs6000_move_block_from_reg (int regno, r CUM is as above. - MODE and TYPE are the mode and type of the current parameter. + ARG is the last named argument. PRETEND_SIZE is a variable that should be set to the amount of stack that must be pushed by the prolog to pretend that our caller pushed @@ -2375,9 +2375,9 @@ rs6000_move_block_from_reg (int regno, r stack and set PRETEND_SIZE to the length of the registers pushed. */ void -setup_incoming_varargs (cumulative_args_t cum, machine_mode mode, - tree type, int *pretend_size ATTRIBUTE_UNUSED, - int no_rtl) +setup_incoming_varargs (cumulative_args_t cum, + const function_arg_info &arg, + int *pretend_size ATTRIBUTE_UNUSED, int no_rtl) { CUMULATIVE_ARGS next_cum; int reg_size = TARGET_32BIT ? 4 : 8; @@ -2387,7 +2387,7 @@ setup_incoming_varargs (cumulative_args_ /* Skip the last named argument. */ next_cum = *get_cumulative_args (cum); - rs6000_function_arg_advance_1 (&next_cum, mode, type, true, 0); + rs6000_function_arg_advance_1 (&next_cum, arg.mode, arg.type, arg.named, 0); if (DEFAULT_ABI == ABI_V4) { @@ -2461,8 +2461,8 @@ setup_incoming_varargs (cumulative_args_ first_reg_offset = next_cum.words; save_area = crtl->args.internal_arg_pointer; - if (targetm.calls.must_pass_in_stack (mode, type)) - first_reg_offset += rs6000_arg_size (TYPE_MODE (type), type); + if (targetm.calls.must_pass_in_stack (arg.mode, arg.type)) + first_reg_offset += rs6000_arg_size (TYPE_MODE (arg.type), arg.type); } set = get_varargs_alias_set (); Index: gcc/config/sh/sh.c =================================================================== --- gcc/config/sh/sh.c 2019-08-19 15:58:28.446077464 +0100 +++ gcc/config/sh/sh.c 2019-08-19 15:58:34.846031154 +0100 @@ -280,8 +280,8 @@ static bool sh_function_value_regno_p (c static rtx sh_libcall_value (machine_mode, const_rtx); static bool sh_return_in_memory (const_tree, const_tree); static rtx sh_builtin_saveregs (void); -static void sh_setup_incoming_varargs (cumulative_args_t, machine_mode, - tree, int *, int); +static void sh_setup_incoming_varargs (cumulative_args_t, + const function_arg_info &, int *, int); static bool sh_strict_argument_naming (cumulative_args_t); static bool sh_pretend_outgoing_varargs_named (cumulative_args_t); static void sh_atomic_assign_expand_fenv (tree *, tree *, tree *); @@ -8184,8 +8184,7 @@ sh_return_in_memory (const_tree type, co function that tell if a function uses varargs or stdarg. */ static void sh_setup_incoming_varargs (cumulative_args_t ca, - machine_mode mode, - tree type, + const function_arg_info &arg, int *pretend_arg_size, int second_time ATTRIBUTE_UNUSED) { @@ -8194,10 +8193,9 @@ sh_setup_incoming_varargs (cumulative_ar { int named_parm_regs, anon_parm_regs; - named_parm_regs = (sh_round_reg (*get_cumulative_args (ca), mode) - + (mode == BLKmode - ? CEIL (int_size_in_bytes (type), UNITS_PER_WORD) - : CEIL (GET_MODE_SIZE (mode), UNITS_PER_WORD))); + named_parm_regs = (sh_round_reg (*get_cumulative_args (ca), arg.mode) + + CEIL (arg.promoted_size_in_bytes (), + UNITS_PER_WORD)); anon_parm_regs = NPARM_REGS (SImode) - named_parm_regs; if (anon_parm_regs > 0) *pretend_arg_size = anon_parm_regs * 4; Index: gcc/config/spu/spu.c =================================================================== --- gcc/config/spu/spu.c 2019-08-19 15:58:28.446077464 +0100 +++ gcc/config/spu/spu.c 2019-08-19 15:58:34.846031154 +0100 @@ -4089,8 +4089,9 @@ spu_gimplify_va_arg_expr (tree valist, t in the stack then save no registers. Set pretend_args_size to the amount of space needed to save the registers. */ static void -spu_setup_incoming_varargs (cumulative_args_t cum, machine_mode mode, - tree type, int *pretend_size, int no_rtl) +spu_setup_incoming_varargs (cumulative_args_t cum, + const function_arg_info &arg, + int *pretend_size, int no_rtl) { if (!no_rtl) { @@ -4101,7 +4102,8 @@ 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), mode, type, true); + spu_function_arg_advance (pack_cumulative_args (&ncum), + arg.mode, arg.type, arg.named); offset = -STACK_POINTER_OFFSET; for (regno = ncum; regno < MAX_REGISTER_ARGS; regno++) Index: gcc/config/tilegx/tilegx.c =================================================================== --- gcc/config/tilegx/tilegx.c 2019-08-19 15:58:28.446077464 +0100 +++ gcc/config/tilegx/tilegx.c 2019-08-19 15:58:34.850031127 +0100 @@ -390,8 +390,8 @@ tilegx_va_start (tree valist, rtx nextar /* Implement TARGET_SETUP_INCOMING_VARARGS. */ static void tilegx_setup_incoming_varargs (cumulative_args_t cum, - machine_mode mode, - tree type, int *pretend_args, int no_rtl) + const function_arg_info &arg, + int *pretend_args, int no_rtl) { CUMULATIVE_ARGS local_cum = *get_cumulative_args (cum); int first_reg; @@ -400,7 +400,7 @@ tilegx_setup_incoming_varargs (cumulativ 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), - mode, type, true); + arg.mode, arg.type, arg.named); 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:28.446077464 +0100 +++ gcc/config/tilepro/tilepro.c 2019-08-19 15:58:34.850031127 +0100 @@ -342,8 +342,8 @@ tilepro_va_start (tree valist, rtx nexta /* Implement TARGET_SETUP_INCOMING_VARARGS. */ static void tilepro_setup_incoming_varargs (cumulative_args_t cum, - machine_mode mode, - tree type, int *pretend_args, int no_rtl) + const function_arg_info &arg, + int *pretend_args, int no_rtl) { CUMULATIVE_ARGS local_cum = *get_cumulative_args (cum); int first_reg; @@ -352,7 +352,7 @@ tilepro_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. */ targetm.calls.function_arg_advance (pack_cumulative_args (&local_cum), - mode, type, true); + arg.mode, arg.type, arg.named); first_reg = local_cum; if (local_cum < TILEPRO_NUM_ARG_REGS) Index: gcc/config/visium/visium.c =================================================================== --- gcc/config/visium/visium.c 2019-08-19 15:58:28.446077464 +0100 +++ gcc/config/visium/visium.c 2019-08-19 15:58:34.850031127 +0100 @@ -175,8 +175,8 @@ static rtx visium_function_value (const_ static rtx visium_libcall_value (machine_mode, const_rtx); static void visium_setup_incoming_varargs (cumulative_args_t, - machine_mode, - tree, int *, int); + const function_arg_info &, + int *, int); static void visium_va_start (tree valist, rtx nextarg); @@ -1460,8 +1460,7 @@ visium_libcall_value (machine_mode mode, static void visium_setup_incoming_varargs (cumulative_args_t pcum_v, - machine_mode mode, - tree type, + const function_arg_info &arg, int *pretend_size ATTRIBUTE_UNUSED, int no_rtl) { @@ -1487,7 +1486,8 @@ 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, mode, type, 1); + TARGET_FUNCTION_ARG_ADVANCE (local_args_so_far, arg.mode, + arg.type, arg.named); /* Find how many registers we need to save. */ locargs = get_cumulative_args (local_args_so_far); Index: gcc/function.c =================================================================== --- gcc/function.c 2019-08-19 15:58:28.450077433 +0100 +++ gcc/function.c 2019-08-19 15:58:34.850031127 +0100 @@ -2485,9 +2485,9 @@ assign_parms_setup_varargs (struct assig { int varargs_pretend_bytes = 0; - targetm.calls.setup_incoming_varargs (all->args_so_far, - data->promoted_mode, - data->passed_type, + function_arg_info last_named_arg (data->passed_type, data->promoted_mode, + /*named=*/true); + targetm.calls.setup_incoming_varargs (all->args_so_far, last_named_arg, &varargs_pretend_bytes, no_rtl); /* If the back-end has requested extra stack space, record how much is