Use function_arg_info for TARGET_PASS_BY_REFERENCE

The hook is passed the unpromoted type mode instead of the promoted mode.

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

gcc/
	* target.def (pass_by_reference): Take a function_arg_info instead
	of a mode, type and named flag.
	* doc/tm.texi: Regenerate.
	* targhooks.h (hook_pass_by_reference_must_pass_in_stack): Update
	accordingly.
	(hook_bool_CUMULATIVE_ARGS_arg_info_false): Declare.
	* targhooks.c (hook_pass_by_reference_must_pass_in_stack): Take a
	function_arg_info instead of a mode, type and named flag.
	(hook_bool_CUMULATIVE_ARGS_arg_info_false): New function.
	* calls.h (pass_by_reference): Take a function_arg_info instead of a
	mode, type and named flag.
	* calls.c (pass_by_reference): Likewise.
	(pass_va_arg_by_reference): Update call accordingly.
	(initialize_argument_information): Likewise.
	(emit_library_call_value_1): Likewise.
	* function.c (assign_parm_find_data_types): Likewise.
	* var-tracking.c (prepare_call_arguments): Likewise.
	* stor-layout.c: Include calls.h.
	(compute_record_mode): Update call to targetm.calls.pass_by_reference.
	* config/aarch64/aarch64.c (aarch64_pass_by_reference): Take a
	function_arg_info instead of a mode, type and named flag.
	* config/alpha/alpha.c (alpha_pass_by_reference): Likewise.
	* config/arc/arc.c (arc_pass_by_reference): Likewise.
	* config/arm/arm.c (arm_pass_by_reference): Likewise.
	* config/bfin/bfin.c (bfin_pass_by_reference): Likewise.
	* config/c6x/c6x.c (c6x_pass_by_reference): Likewise.
	(c6x_call_saved_register_used): Update call to pass_by_reference.
	* config/cris/cris.c (cris_pass_by_reference): Take a
	function_arg_info instead of a mode, type and named flag.
	* config/epiphany/epiphany.c (epiphany_pass_by_reference): Take a
	function_arg_info instead of a mode, type and named flag.
	(epiphany_arg_partial_bytes): Update call accordingly.
	* config/ft32/ft32.c (ft32_pass_by_reference): Take a
	function_arg_info instead of a mode, type and named flag.
	(ft32_arg_partial_bytes): Update call accordingly.
	* config/i386/i386.c (ix86_pass_by_reference): Take a
	function_arg_info instead of a mode, type and named flag.
	* config/iq2000/iq2000.c (iq2000_pass_by_reference): Likewise.
	* config/m32c/m32c.c (m32c_pass_by_reference): Likewise.
	* config/m32r/m32r.c (m32r_pass_by_reference): Likewise.
	(m32r_return_in_memory): Update call accordingly.
	* config/mips/mips.c (mips_pass_by_reference): Take a
	function_arg_info instead of a mode, type and named flag.
	* config/mmix/mmix.c (mmix_pass_by_reference): Likewise.
	* config/mn10300/mn10300.c (mn10300_pass_by_reference): Likewise.
	* config/moxie/moxie.c (moxie_pass_by_reference): Likewise.
	(moxie_arg_partial_bytes): Update call accordingly.
	* config/msp430/msp430.c (msp430_pass_by_reference): Take a
	function_arg_info instead of a mode, type and named flag.
	* config/nvptx/nvptx.c (nvptx_pass_by_reference): Likewise.
	* config/or1k/or1k.c (or1k_pass_by_reference): Likewise.
	* config/pa/pa.c (pa_pass_by_reference): Likewise.
	* config/riscv/riscv.c (riscv_pass_by_reference): Likewise.
	(riscv_return_in_memory): Update call accordingly.
	* config/rs6000/rs6000-internal.h (rs6000_pass_by_reference): Take a
	function_arg_info instead of a mode, type and named flag.
	* config/rs6000/rs6000-call.c (rs6000_pass_by_reference): Likewise.
	(rs6000_parm_needs_stack): Update call to pass_by_reference.
	* config/s390/s390.c (s390_pass_by_reference): Take a
	function_arg_info instead of a mode, type and named flag.
	(s390_call_saved_register_used): Update call accordingly.
	* config/sh/sh.c (sh_pass_by_reference): Take a function_arg_info
	instead of a mode, type and named flag.
	* config/sparc/sparc.c (sparc_pass_by_reference): Likewise.
	* config/spu/spu.c (spu_pass_by_reference): Likewise.
	* config/tilegx/tilegx.c (tilegx_pass_by_reference): Likewise.
	* config/tilepro/tilepro.c (tilepro_pass_by_reference): Likewise.
	* config/v850/v850.c (v850_pass_by_reference): Likewise.
	* config/visium/visium.c (visium_pass_by_reference): Likewise.

gcc/ada/
	* gcc-interface/misc.c (default_pass_by_ref): Update call to
	pass_by_reference.

From-SVN: r274698
This commit is contained in:
Richard Sandiford 2019-08-20 08:52:40 +00:00 committed by Richard Sandiford
parent a7c81bc1fb
commit 52090e4dbd
44 changed files with 279 additions and 299 deletions

View File

@ -1,3 +1,75 @@
2019-08-20 Richard Sandiford <richard.sandiford@arm.com>
* target.def (pass_by_reference): Take a function_arg_info instead
of a mode, type and named flag.
* doc/tm.texi: Regenerate.
* targhooks.h (hook_pass_by_reference_must_pass_in_stack): Update
accordingly.
(hook_bool_CUMULATIVE_ARGS_arg_info_false): Declare.
* targhooks.c (hook_pass_by_reference_must_pass_in_stack): Take a
function_arg_info instead of a mode, type and named flag.
(hook_bool_CUMULATIVE_ARGS_arg_info_false): New function.
* calls.h (pass_by_reference): Take a function_arg_info instead of a
mode, type and named flag.
* calls.c (pass_by_reference): Likewise.
(pass_va_arg_by_reference): Update call accordingly.
(initialize_argument_information): Likewise.
(emit_library_call_value_1): Likewise.
* function.c (assign_parm_find_data_types): Likewise.
* var-tracking.c (prepare_call_arguments): Likewise.
* stor-layout.c: Include calls.h.
(compute_record_mode): Update call to targetm.calls.pass_by_reference.
* config/aarch64/aarch64.c (aarch64_pass_by_reference): Take a
function_arg_info instead of a mode, type and named flag.
* config/alpha/alpha.c (alpha_pass_by_reference): Likewise.
* config/arc/arc.c (arc_pass_by_reference): Likewise.
* config/arm/arm.c (arm_pass_by_reference): Likewise.
* config/bfin/bfin.c (bfin_pass_by_reference): Likewise.
* config/c6x/c6x.c (c6x_pass_by_reference): Likewise.
(c6x_call_saved_register_used): Update call to pass_by_reference.
* config/cris/cris.c (cris_pass_by_reference): Take a
function_arg_info instead of a mode, type and named flag.
* config/epiphany/epiphany.c (epiphany_pass_by_reference): Take a
function_arg_info instead of a mode, type and named flag.
(epiphany_arg_partial_bytes): Update call accordingly.
* config/ft32/ft32.c (ft32_pass_by_reference): Take a
function_arg_info instead of a mode, type and named flag.
(ft32_arg_partial_bytes): Update call accordingly.
* config/i386/i386.c (ix86_pass_by_reference): Take a
function_arg_info instead of a mode, type and named flag.
* config/iq2000/iq2000.c (iq2000_pass_by_reference): Likewise.
* config/m32c/m32c.c (m32c_pass_by_reference): Likewise.
* config/m32r/m32r.c (m32r_pass_by_reference): Likewise.
(m32r_return_in_memory): Update call accordingly.
* config/mips/mips.c (mips_pass_by_reference): Take a
function_arg_info instead of a mode, type and named flag.
* config/mmix/mmix.c (mmix_pass_by_reference): Likewise.
* config/mn10300/mn10300.c (mn10300_pass_by_reference): Likewise.
* config/moxie/moxie.c (moxie_pass_by_reference): Likewise.
(moxie_arg_partial_bytes): Update call accordingly.
* config/msp430/msp430.c (msp430_pass_by_reference): Take a
function_arg_info instead of a mode, type and named flag.
* config/nvptx/nvptx.c (nvptx_pass_by_reference): Likewise.
* config/or1k/or1k.c (or1k_pass_by_reference): Likewise.
* config/pa/pa.c (pa_pass_by_reference): Likewise.
* config/riscv/riscv.c (riscv_pass_by_reference): Likewise.
(riscv_return_in_memory): Update call accordingly.
* config/rs6000/rs6000-internal.h (rs6000_pass_by_reference): Take a
function_arg_info instead of a mode, type and named flag.
* config/rs6000/rs6000-call.c (rs6000_pass_by_reference): Likewise.
(rs6000_parm_needs_stack): Update call to pass_by_reference.
* config/s390/s390.c (s390_pass_by_reference): Take a
function_arg_info instead of a mode, type and named flag.
(s390_call_saved_register_used): Update call accordingly.
* config/sh/sh.c (sh_pass_by_reference): Take a function_arg_info
instead of a mode, type and named flag.
* config/sparc/sparc.c (sparc_pass_by_reference): Likewise.
* config/spu/spu.c (spu_pass_by_reference): Likewise.
* config/tilegx/tilegx.c (tilegx_pass_by_reference): Likewise.
* config/tilepro/tilepro.c (tilepro_pass_by_reference): Likewise.
* config/v850/v850.c (v850_pass_by_reference): Likewise.
* config/visium/visium.c (visium_pass_by_reference): Likewise.
2019-08-20 Richard Sandiford <richard.sandiford@arm.com> 2019-08-20 Richard Sandiford <richard.sandiford@arm.com>
* target.def (arg_partial_bytes): Take a function_arg_info instead * target.def (arg_partial_bytes): Take a function_arg_info instead

View File

@ -1,3 +1,8 @@
2019-08-20 Richard Sandiford <richard.sandiford@arm.com>
* gcc-interface/misc.c (default_pass_by_ref): Update call to
pass_by_reference.
2019-08-19 Bob Duff <duff@adacore.com> 2019-08-19 Bob Duff <duff@adacore.com>
* doc/gnat_rm/implementation_advice.rst: Fix documentation for * doc/gnat_rm/implementation_advice.rst: Fix documentation for

View File

@ -1136,7 +1136,7 @@ default_pass_by_ref (tree gnu_type)
TYPE_ALIGN (gnu_type)) > 0)) TYPE_ALIGN (gnu_type)) > 0))
return true; return true;
if (pass_by_reference (NULL, TYPE_MODE (gnu_type), gnu_type, true)) if (pass_by_reference (NULL, function_arg_info (gnu_type, /*named=*/true)))
return true; return true;
if (targetm.calls.return_in_memory (gnu_type, NULL_TREE)) if (targetm.calls.return_in_memory (gnu_type, NULL_TREE))

View File

@ -897,13 +897,12 @@ call_expr_flags (const_tree t)
return flags; return flags;
} }
/* Return true if TYPE should be passed by invisible reference. */ /* Return true if ARG should be passed by invisible reference. */
bool bool
pass_by_reference (CUMULATIVE_ARGS *ca, machine_mode mode, pass_by_reference (CUMULATIVE_ARGS *ca, function_arg_info arg)
tree type, bool named_arg)
{ {
if (type) if (tree type = arg.type)
{ {
/* If this type contains non-trivial constructors, then it is /* If this type contains non-trivial constructors, then it is
forbidden for the middle-end to create any new copies. */ forbidden for the middle-end to create any new copies. */
@ -918,13 +917,12 @@ pass_by_reference (CUMULATIVE_ARGS *ca, machine_mode mode,
member, use the type and mode of that member. */ member, use the type and mode of that member. */
if (TREE_CODE (type) == RECORD_TYPE && TYPE_TRANSPARENT_AGGR (type)) if (TREE_CODE (type) == RECORD_TYPE && TYPE_TRANSPARENT_AGGR (type))
{ {
type = TREE_TYPE (first_field (type)); arg.type = TREE_TYPE (first_field (type));
mode = TYPE_MODE (type); arg.mode = TYPE_MODE (arg.type);
} }
} }
return targetm.calls.pass_by_reference (pack_cumulative_args (ca), mode, return targetm.calls.pass_by_reference (pack_cumulative_args (ca), arg);
type, named_arg);
} }
/* Return true if TYPE should be passed by reference when passed to /* Return true if TYPE should be passed by reference when passed to
@ -933,7 +931,7 @@ pass_by_reference (CUMULATIVE_ARGS *ca, machine_mode mode,
bool bool
pass_va_arg_by_reference (tree type) pass_va_arg_by_reference (tree type)
{ {
return pass_by_reference (NULL, TYPE_MODE (type), type, false); return pass_by_reference (NULL, function_arg_info (type, /*named=*/false));
} }
/* Return true if TYPE, which is passed by reference, should be callee /* Return true if TYPE, which is passed by reference, should be callee
@ -1997,8 +1995,8 @@ initialize_argument_information (int num_actuals ATTRIBUTE_UNUSED,
with those made by function.c. */ with those made by function.c. */
/* See if this argument should be passed by invisible reference. */ /* See if this argument should be passed by invisible reference. */
if (pass_by_reference (args_so_far_pnt, TYPE_MODE (type), function_arg_info orig_arg (type, argpos < n_named_args);
type, argpos < n_named_args)) if (pass_by_reference (args_so_far_pnt, orig_arg))
{ {
bool callee_copies; bool callee_copies;
tree base = NULL_TREE; tree base = NULL_TREE;
@ -4909,7 +4907,8 @@ emit_library_call_value_1 (int retval, rtx orgfun, rtx value,
&& !(CONSTANT_P (val) && targetm.legitimate_constant_p (mode, val))) && !(CONSTANT_P (val) && targetm.legitimate_constant_p (mode, val)))
val = force_operand (val, NULL_RTX); val = force_operand (val, NULL_RTX);
if (pass_by_reference (&args_so_far_v, mode, NULL_TREE, 1)) function_arg_info orig_arg (mode, /*named=*/true);
if (pass_by_reference (&args_so_far_v, orig_arg))
{ {
rtx slot; rtx slot;
int must_copy int must_copy

View File

@ -105,8 +105,7 @@ extern bool shift_return_value (machine_mode, bool, rtx);
extern rtx expand_call (tree, rtx, int); extern rtx expand_call (tree, rtx, int);
extern void fixup_tail_calls (void); extern void fixup_tail_calls (void);
extern bool pass_by_reference (CUMULATIVE_ARGS *, machine_mode, extern bool pass_by_reference (CUMULATIVE_ARGS *, function_arg_info);
tree, bool);
extern bool pass_va_arg_by_reference (tree); extern bool pass_va_arg_by_reference (tree);
extern bool reference_callee_copied (CUMULATIVE_ARGS *, machine_mode, extern bool reference_callee_copied (CUMULATIVE_ARGS *, machine_mode,
tree, bool); tree, bool);

View File

@ -4409,35 +4409,30 @@ aarch64_function_ok_for_sibcall (tree decl ATTRIBUTE_UNUSED,
/* Implement TARGET_PASS_BY_REFERENCE. */ /* Implement TARGET_PASS_BY_REFERENCE. */
static bool static bool
aarch64_pass_by_reference (cumulative_args_t pcum ATTRIBUTE_UNUSED, aarch64_pass_by_reference (cumulative_args_t, const function_arg_info &arg)
machine_mode mode,
const_tree type,
bool named ATTRIBUTE_UNUSED)
{ {
HOST_WIDE_INT size; HOST_WIDE_INT size;
machine_mode dummymode; machine_mode dummymode;
int nregs; int nregs;
/* GET_MODE_SIZE (BLKmode) is useless since it is 0. */ /* GET_MODE_SIZE (BLKmode) is useless since it is 0. */
if (mode == BLKmode && type) if (arg.mode == BLKmode && arg.type)
size = int_size_in_bytes (type); size = int_size_in_bytes (arg.type);
else else
/* No frontends can create types with variable-sized modes, so we /* No frontends can create types with variable-sized modes, so we
shouldn't be asked to pass or return them. */ shouldn't be asked to pass or return them. */
size = GET_MODE_SIZE (mode).to_constant (); size = GET_MODE_SIZE (arg.mode).to_constant ();
/* Aggregates are passed by reference based on their size. */ /* Aggregates are passed by reference based on their size. */
if (type && AGGREGATE_TYPE_P (type)) if (arg.aggregate_type_p ())
{ size = int_size_in_bytes (arg.type);
size = int_size_in_bytes (type);
}
/* Variable sized arguments are always returned by reference. */ /* Variable sized arguments are always returned by reference. */
if (size < 0) if (size < 0)
return true; return true;
/* Can this be a candidate to be passed in fp/simd register(s)? */ /* Can this be a candidate to be passed in fp/simd register(s)? */
if (aarch64_vfp_is_call_or_return_candidate (mode, type, if (aarch64_vfp_is_call_or_return_candidate (arg.mode, arg.type,
&dummymode, &nregs, &dummymode, &nregs,
NULL)) NULL))
return false; return false;

View File

@ -5710,13 +5710,10 @@ alpha_return_in_memory (const_tree type, const_tree fndecl ATTRIBUTE_UNUSED)
return size > UNITS_PER_WORD; return size > UNITS_PER_WORD;
} }
/* Return true if TYPE should be passed by invisible reference. */ /* Return true if ARG should be passed by invisible reference. */
static bool static bool
alpha_pass_by_reference (cumulative_args_t ca ATTRIBUTE_UNUSED, alpha_pass_by_reference (cumulative_args_t, const function_arg_info &arg)
machine_mode mode,
const_tree type ATTRIBUTE_UNUSED,
bool named)
{ {
/* Pass float and _Complex float variable arguments by reference. /* Pass float and _Complex float variable arguments by reference.
This avoids 64-bit store from a FP register to a pretend args save area This avoids 64-bit store from a FP register to a pretend args save area
@ -5736,10 +5733,10 @@ alpha_pass_by_reference (cumulative_args_t ca ATTRIBUTE_UNUSED,
to worry about, and passing unpromoted _Float32 and _Complex float to worry about, and passing unpromoted _Float32 and _Complex float
as a variable argument will actually work in the future. */ as a variable argument will actually work in the future. */
if (mode == SFmode || mode == SCmode) if (arg.mode == SFmode || arg.mode == SCmode)
return !named; return !arg.named;
return mode == TFmode || mode == TCmode; return arg.mode == TFmode || arg.mode == TCmode;
} }
/* Define how to find the value returned by a function. VALTYPE is the /* Define how to find the value returned by a function. VALTYPE is the

View File

@ -7566,14 +7566,11 @@ arc_return_in_memory (const_tree type, const_tree fntype ATTRIBUTE_UNUSED)
} }
static bool static bool
arc_pass_by_reference (cumulative_args_t ca_v ATTRIBUTE_UNUSED, arc_pass_by_reference (cumulative_args_t, const function_arg_info &arg)
machine_mode mode ATTRIBUTE_UNUSED,
const_tree type,
bool named ATTRIBUTE_UNUSED)
{ {
return (type != 0 return (arg.type != 0
&& (TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST && (TREE_CODE (TYPE_SIZE (arg.type)) != INTEGER_CST
|| TREE_ADDRESSABLE (type))); || TREE_ADDRESSABLE (arg.type)));
} }
/* Implement TARGET_CAN_USE_DOLOOP_P. */ /* Implement TARGET_CAN_USE_DOLOOP_P. */

View File

@ -215,7 +215,7 @@ static void arm_insert_attributes (tree, tree *);
static void arm_setup_incoming_varargs (cumulative_args_t, machine_mode, static void arm_setup_incoming_varargs (cumulative_args_t, machine_mode,
tree, int *, int); tree, int *, int);
static bool arm_pass_by_reference (cumulative_args_t, static bool arm_pass_by_reference (cumulative_args_t,
machine_mode, const_tree, bool); const function_arg_info &);
static bool arm_promote_prototypes (const_tree); static bool arm_promote_prototypes (const_tree);
static bool arm_default_short_enums (void); static bool arm_default_short_enums (void);
static bool arm_align_anon_bitfield (void); static bool arm_align_anon_bitfield (void);
@ -6819,11 +6819,9 @@ arm_function_arg_advance (cumulative_args_t pcum_v, machine_mode mode,
extension to the ARM ABI. */ extension to the ARM ABI. */
static bool static bool
arm_pass_by_reference (cumulative_args_t cum ATTRIBUTE_UNUSED, arm_pass_by_reference (cumulative_args_t, const function_arg_info &arg)
machine_mode mode ATTRIBUTE_UNUSED,
const_tree type, bool named ATTRIBUTE_UNUSED)
{ {
return type && TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST; return arg.type && TREE_CODE (TYPE_SIZE (arg.type)) != INTEGER_CST;
} }
/* Encode the current state of the #pragma [no_]long_calls. */ /* Encode the current state of the #pragma [no_]long_calls. */

View File

@ -1741,11 +1741,9 @@ bfin_arg_partial_bytes (cumulative_args_t cum, const function_arg_info &arg)
/* Variable sized types are passed by reference. */ /* Variable sized types are passed by reference. */
static bool static bool
bfin_pass_by_reference (cumulative_args_t cum ATTRIBUTE_UNUSED, bfin_pass_by_reference (cumulative_args_t, const function_arg_info &arg)
machine_mode mode ATTRIBUTE_UNUSED,
const_tree type, bool named ATTRIBUTE_UNUSED)
{ {
return type && TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST; return arg.type && TREE_CODE (TYPE_SIZE (arg.type)) != INTEGER_CST;
} }
/* Decide whether a type should be returned in memory (true) /* Decide whether a type should be returned in memory (true)

View File

@ -642,15 +642,13 @@ c6x_function_value_regno_p (const unsigned int regno)
reference. The callee must copy them; see c6x_callee_copies. */ reference. The callee must copy them; see c6x_callee_copies. */
static bool static bool
c6x_pass_by_reference (cumulative_args_t cum_v ATTRIBUTE_UNUSED, c6x_pass_by_reference (cumulative_args_t, const function_arg_info &arg)
machine_mode mode, const_tree type,
bool named ATTRIBUTE_UNUSED)
{ {
int size = -1; int size = -1;
if (type) if (arg.type)
size = int_size_in_bytes (type); size = int_size_in_bytes (arg.type);
else if (mode != VOIDmode) else if (arg.mode != VOIDmode)
size = GET_MODE_SIZE (mode); size = GET_MODE_SIZE (arg.mode);
return size > 2 * UNITS_PER_WORD || size == -1; return size > 2 * UNITS_PER_WORD || size == -1;
} }
@ -1130,7 +1128,7 @@ c6x_call_saved_register_used (tree call_expr)
mode = TYPE_MODE (type); mode = TYPE_MODE (type);
gcc_assert (mode); gcc_assert (mode);
if (pass_by_reference (&cum_v, mode, type, true)) if (pass_by_reference (&cum_v, function_arg_info (type, /*named=*/true)))
{ {
mode = Pmode; mode = Pmode;
type = build_pointer_type (type); type = build_pointer_type (type);

View File

@ -139,8 +139,8 @@ static int cris_register_move_cost (machine_mode, reg_class_t, reg_class_t);
static int cris_memory_move_cost (machine_mode, reg_class_t, bool); static int cris_memory_move_cost (machine_mode, reg_class_t, bool);
static bool cris_rtx_costs (rtx, machine_mode, int, int, int *, bool); static bool cris_rtx_costs (rtx, machine_mode, int, int, int *, bool);
static int cris_address_cost (rtx, machine_mode, addr_space_t, bool); static int cris_address_cost (rtx, machine_mode, addr_space_t, bool);
static bool cris_pass_by_reference (cumulative_args_t, machine_mode, static bool cris_pass_by_reference (cumulative_args_t,
const_tree, bool); const function_arg_info &);
static int cris_arg_partial_bytes (cumulative_args_t, static int cris_arg_partial_bytes (cumulative_args_t,
const function_arg_info &); const function_arg_info &);
static rtx cris_function_arg (cumulative_args_t, machine_mode, static rtx cris_function_arg (cumulative_args_t, machine_mode,
@ -4041,16 +4041,14 @@ cris_setup_incoming_varargs (cumulative_args_t ca_v,
ca->regs, *pretend_arg_size, second_time); ca->regs, *pretend_arg_size, second_time);
} }
/* Return true if TYPE must be passed by invisible reference. /* Return true if ARG must be passed by invisible reference.
For cris, we pass <= 8 bytes by value, others by reference. */ For cris, we pass <= 8 bytes by value, others by reference. */
static bool static bool
cris_pass_by_reference (cumulative_args_t ca ATTRIBUTE_UNUSED, cris_pass_by_reference (cumulative_args_t, const function_arg_info &arg)
machine_mode mode, const_tree type,
bool named ATTRIBUTE_UNUSED)
{ {
return (targetm.calls.must_pass_in_stack (mode, type) return (targetm.calls.must_pass_in_stack (arg.mode, arg.type)
|| CRIS_FUNCTION_ARG_SIZE (mode, type) > 8); || CRIS_FUNCTION_ARG_SIZE (arg.mode, arg.type) > 8);
} }
/* A combination of defining TARGET_PROMOTE_FUNCTION_MODE, promoting arguments /* A combination of defining TARGET_PROMOTE_FUNCTION_MODE, promoting arguments

View File

@ -71,8 +71,8 @@ static int get_epiphany_condition_code (rtx);
static tree epiphany_handle_interrupt_attribute (tree *, tree, tree, int, bool *); static tree epiphany_handle_interrupt_attribute (tree *, tree, tree, int, bool *);
static tree epiphany_handle_forwarder_attribute (tree *, tree, tree, int, static tree epiphany_handle_forwarder_attribute (tree *, tree, tree, int,
bool *); bool *);
static bool epiphany_pass_by_reference (cumulative_args_t, machine_mode, static bool epiphany_pass_by_reference (cumulative_args_t,
const_tree, bool); const function_arg_info &);
static rtx_insn *frame_insn (rtx); static rtx_insn *frame_insn (rtx);
/* defines for the initialization of the GCC target structure. */ /* defines for the initialization of the GCC target structure. */
@ -749,8 +749,7 @@ epiphany_arg_partial_bytes (cumulative_args_t cum,
{ {
int words = 0, rounded_cum; int words = 0, rounded_cum;
gcc_assert (!epiphany_pass_by_reference (cum, arg.mode, arg.type, gcc_assert (!epiphany_pass_by_reference (cum, arg));
arg.named));
rounded_cum = ROUND_ADVANCE_CUM (*get_cumulative_args (cum), rounded_cum = ROUND_ADVANCE_CUM (*get_cumulative_args (cum),
arg.mode, arg.type); arg.mode, arg.type);
@ -1487,14 +1486,12 @@ epiphany_return_in_memory (const_tree type, const_tree fntype ATTRIBUTE_UNUSED)
passed by reference. */ passed by reference. */
static bool static bool
epiphany_pass_by_reference (cumulative_args_t ca ATTRIBUTE_UNUSED, epiphany_pass_by_reference (cumulative_args_t, const function_arg_info &arg)
machine_mode mode, const_tree type,
bool named ATTRIBUTE_UNUSED)
{ {
if (type) if (tree type = arg.type)
{ {
if (AGGREGATE_TYPE_P (type) if (AGGREGATE_TYPE_P (type)
&& (mode == BLKmode || TYPE_NEEDS_CONSTRUCTING (type))) && (arg.mode == BLKmode || TYPE_NEEDS_CONSTRUCTING (type)))
return true; return true;
} }
return false; return false;

View File

@ -684,25 +684,15 @@ ft32_function_arg_advance (cumulative_args_t cum_v, machine_mode mode,
? *cum + ((3 + FT32_FUNCTION_ARG_SIZE (mode, type)) / 4) : *cum); ? *cum + ((3 + FT32_FUNCTION_ARG_SIZE (mode, type)) / 4) : *cum);
} }
/* Return non-zero if the function argument described by TYPE is to be /* Return non-zero if the function argument described by ARG is to be
passed by reference. */ passed by reference. */
static bool static bool
ft32_pass_by_reference (cumulative_args_t cum ATTRIBUTE_UNUSED, ft32_pass_by_reference (cumulative_args_t, const function_arg_info &arg)
machine_mode mode, const_tree type,
bool named ATTRIBUTE_UNUSED)
{ {
unsigned HOST_WIDE_INT size; if (arg.aggregate_type_p ())
return true;
if (type) unsigned HOST_WIDE_INT size = arg.type_size_in_bytes ();
{
if (AGGREGATE_TYPE_P (type))
return true;
size = int_size_in_bytes (type);
}
else
size = GET_MODE_SIZE (mode);
return size > 4 * 6; return size > 4 * 6;
} }
@ -719,7 +709,7 @@ ft32_arg_partial_bytes (cumulative_args_t cum_v, const function_arg_info &arg)
if (*cum >= 8) if (*cum >= 8)
return 0; return 0;
if (ft32_pass_by_reference (cum_v, arg.mode, arg.type, arg.named)) if (ft32_pass_by_reference (cum_v, arg))
size = 4; size = 4;
else if (arg.type) else if (arg.type)
{ {

View File

@ -3286,8 +3286,7 @@ ix86_function_arg (cumulative_args_t cum_v, machine_mode omode,
appropriate for passing a pointer to that type. */ appropriate for passing a pointer to that type. */
static bool static bool
ix86_pass_by_reference (cumulative_args_t cum_v, machine_mode mode, ix86_pass_by_reference (cumulative_args_t cum_v, const function_arg_info &arg)
const_tree type, bool)
{ {
CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v); CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
@ -3298,9 +3297,9 @@ ix86_pass_by_reference (cumulative_args_t cum_v, machine_mode mode,
/* See Windows x64 Software Convention. */ /* See Windows x64 Software Convention. */
if (call_abi == MS_ABI) if (call_abi == MS_ABI)
{ {
HOST_WIDE_INT msize = GET_MODE_SIZE (mode); HOST_WIDE_INT msize = GET_MODE_SIZE (arg.mode);
if (type) if (tree type = arg.type)
{ {
/* Arrays are passed by reference. */ /* Arrays are passed by reference. */
if (TREE_CODE (type) == ARRAY_TYPE) if (TREE_CODE (type) == ARRAY_TYPE)
@ -3317,7 +3316,7 @@ ix86_pass_by_reference (cumulative_args_t cum_v, machine_mode mode,
/* __m128 is passed by reference. */ /* __m128 is passed by reference. */
return msize != 1 && msize != 2 && msize != 4 && msize != 8; return msize != 1 && msize != 2 && msize != 4 && msize != 8;
} }
else if (type && int_size_in_bytes (type) == -1) else if (arg.type && int_size_in_bytes (arg.type) == -1)
return true; return true;
} }

View File

@ -159,8 +159,8 @@ static int iq2000_address_cost (rtx, machine_mode, addr_space_t,
bool); bool);
static section *iq2000_select_section (tree, int, unsigned HOST_WIDE_INT); static section *iq2000_select_section (tree, int, unsigned HOST_WIDE_INT);
static rtx iq2000_legitimize_address (rtx, rtx, machine_mode); static rtx iq2000_legitimize_address (rtx, rtx, machine_mode);
static bool iq2000_pass_by_reference (cumulative_args_t, machine_mode, static bool iq2000_pass_by_reference (cumulative_args_t,
const_tree, bool); const function_arg_info &);
static int iq2000_arg_partial_bytes (cumulative_args_t, static int iq2000_arg_partial_bytes (cumulative_args_t,
const function_arg_info &arg); const function_arg_info &arg);
static rtx iq2000_function_arg (cumulative_args_t, static rtx iq2000_function_arg (cumulative_args_t,
@ -2292,8 +2292,8 @@ iq2000_function_value_regno_p (const unsigned int regno)
/* Return true when an argument must be passed by reference. */ /* Return true when an argument must be passed by reference. */
static bool static bool
iq2000_pass_by_reference (cumulative_args_t cum_v, machine_mode mode, iq2000_pass_by_reference (cumulative_args_t cum_v,
const_tree type, bool named ATTRIBUTE_UNUSED) const function_arg_info &arg)
{ {
CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v); CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
int size; int size;
@ -2301,7 +2301,7 @@ iq2000_pass_by_reference (cumulative_args_t cum_v, machine_mode mode,
/* We must pass by reference if we would be both passing in registers /* We must pass by reference if we would be both passing in registers
and the stack. This is because any subsequent partial arg would be and the stack. This is because any subsequent partial arg would be
handled incorrectly in this case. */ handled incorrectly in this case. */
if (cum && targetm.calls.must_pass_in_stack (mode, type)) if (cum && targetm.calls.must_pass_in_stack (arg.mode, arg.type))
{ {
/* Don't pass the actual CUM to FUNCTION_ARG, because we would /* Don't pass the actual CUM to FUNCTION_ARG, because we would
get double copies of any offsets generated for small structs get double copies of any offsets generated for small structs
@ -2309,15 +2309,15 @@ iq2000_pass_by_reference (cumulative_args_t cum_v, machine_mode mode,
CUMULATIVE_ARGS temp; CUMULATIVE_ARGS temp;
temp = *cum; temp = *cum;
if (iq2000_function_arg (pack_cumulative_args (&temp), mode, type, named) if (iq2000_function_arg (pack_cumulative_args (&temp), arg.mode,
!= 0) arg.type, arg.named) != 0)
return 1; return 1;
} }
if (type == NULL_TREE || mode == DImode || mode == DFmode) if (arg.type == NULL_TREE || arg.mode == DImode || arg.mode == DFmode)
return 0; return 0;
size = int_size_in_bytes (type); size = int_size_in_bytes (arg.type);
return size == -1 || size > UNITS_PER_WORD; return size == -1 || size > UNITS_PER_WORD;
} }

View File

@ -78,8 +78,8 @@ static bool m32c_legitimate_address_p (machine_mode, rtx, bool);
static bool m32c_addr_space_legitimate_address_p (machine_mode, rtx, bool, addr_space_t); static bool m32c_addr_space_legitimate_address_p (machine_mode, rtx, bool, addr_space_t);
static rtx m32c_function_arg (cumulative_args_t, machine_mode, static rtx m32c_function_arg (cumulative_args_t, machine_mode,
const_tree, bool); const_tree, bool);
static bool m32c_pass_by_reference (cumulative_args_t, machine_mode, static bool m32c_pass_by_reference (cumulative_args_t,
const_tree, bool); const function_arg_info &);
static void m32c_function_arg_advance (cumulative_args_t, machine_mode, static void m32c_function_arg_advance (cumulative_args_t, machine_mode,
const_tree, bool); const_tree, bool);
static unsigned int m32c_function_arg_boundary (machine_mode, const_tree); static unsigned int m32c_function_arg_boundary (machine_mode, const_tree);
@ -1373,10 +1373,7 @@ m32c_function_arg (cumulative_args_t ca_v,
#undef TARGET_PASS_BY_REFERENCE #undef TARGET_PASS_BY_REFERENCE
#define TARGET_PASS_BY_REFERENCE m32c_pass_by_reference #define TARGET_PASS_BY_REFERENCE m32c_pass_by_reference
static bool static bool
m32c_pass_by_reference (cumulative_args_t ca ATTRIBUTE_UNUSED, m32c_pass_by_reference (cumulative_args_t, const function_arg_info &)
machine_mode mode ATTRIBUTE_UNUSED,
const_tree type ATTRIBUTE_UNUSED,
bool named ATTRIBUTE_UNUSED)
{ {
return 0; return 0;
} }

View File

@ -91,8 +91,8 @@ static void m32r_setup_incoming_varargs (cumulative_args_t, machine_mode,
static void init_idents (void); static void init_idents (void);
static bool m32r_rtx_costs (rtx, machine_mode, int, int, int *, bool speed); 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); static int m32r_memory_move_cost (machine_mode, reg_class_t, bool);
static bool m32r_pass_by_reference (cumulative_args_t, machine_mode, static bool m32r_pass_by_reference (cumulative_args_t,
const_tree, bool); const function_arg_info &arg);
static int m32r_arg_partial_bytes (cumulative_args_t, static int m32r_arg_partial_bytes (cumulative_args_t,
const function_arg_info &); const function_arg_info &);
static rtx m32r_function_arg (cumulative_args_t, machine_mode, static rtx m32r_function_arg (cumulative_args_t, machine_mode,
@ -680,20 +680,12 @@ memreg_operand (rtx op, machine_mode mode ATTRIBUTE_UNUSED)
return MEM_P (op) && REG_P (XEXP (op, 0)); return MEM_P (op) && REG_P (XEXP (op, 0));
} }
/* Return nonzero if TYPE must be passed by indirect reference. */ /* Return nonzero if ARG must be passed by indirect reference. */
static bool static bool
m32r_pass_by_reference (cumulative_args_t ca ATTRIBUTE_UNUSED, m32r_pass_by_reference (cumulative_args_t, const function_arg_info &arg)
machine_mode mode, const_tree type,
bool named ATTRIBUTE_UNUSED)
{ {
int size; int size = arg.type_size_in_bytes ();
if (type)
size = int_size_in_bytes (type);
else
size = GET_MODE_SIZE (mode);
return (size < 0 || size > 8); return (size < 0 || size > 8);
} }
@ -1251,8 +1243,8 @@ static bool
m32r_return_in_memory (const_tree type, const_tree fntype ATTRIBUTE_UNUSED) m32r_return_in_memory (const_tree type, const_tree fntype ATTRIBUTE_UNUSED)
{ {
cumulative_args_t dummy = pack_cumulative_args (NULL); cumulative_args_t dummy = pack_cumulative_args (NULL);
function_arg_info arg (const_cast<tree> (type), /*named=*/false);
return m32r_pass_by_reference (dummy, TYPE_MODE (type), type, false); return m32r_pass_by_reference (dummy, arg);
} }
/* Worker function for TARGET_FUNCTION_VALUE. */ /* Worker function for TARGET_FUNCTION_VALUE. */

View File

@ -6235,27 +6235,25 @@ mips_pad_reg_upward (machine_mode mode, tree type)
/* Return nonzero when an argument must be passed by reference. */ /* Return nonzero when an argument must be passed by reference. */
static bool static bool
mips_pass_by_reference (cumulative_args_t cum ATTRIBUTE_UNUSED, mips_pass_by_reference (cumulative_args_t, const function_arg_info &arg)
machine_mode mode, const_tree type,
bool named ATTRIBUTE_UNUSED)
{ {
if (mips_abi == ABI_EABI) if (mips_abi == ABI_EABI)
{ {
int size; int size;
/* ??? How should SCmode be handled? */ /* ??? How should SCmode be handled? */
if (mode == DImode || mode == DFmode if (arg.mode == DImode || arg.mode == DFmode
|| mode == DQmode || mode == UDQmode || arg.mode == DQmode || arg.mode == UDQmode
|| mode == DAmode || mode == UDAmode) || arg.mode == DAmode || arg.mode == UDAmode)
return 0; return 0;
size = type ? int_size_in_bytes (type) : GET_MODE_SIZE (mode); size = arg.type_size_in_bytes ();
return size == -1 || size > UNITS_PER_WORD; return size == -1 || size > UNITS_PER_WORD;
} }
else else
{ {
/* If we have a variable-sized parameter, we have no choice. */ /* If we have a variable-sized parameter, we have no choice. */
return targetm.calls.must_pass_in_stack (mode, type); return targetm.calls.must_pass_in_stack (arg.mode, arg.type);
} }
} }

View File

@ -161,7 +161,7 @@ static rtx mmix_function_value (const_tree, const_tree, bool);
static rtx mmix_libcall_value (machine_mode, const_rtx); static rtx mmix_libcall_value (machine_mode, const_rtx);
static bool mmix_function_value_regno_p (const unsigned int); static bool mmix_function_value_regno_p (const unsigned int);
static bool mmix_pass_by_reference (cumulative_args_t, static bool mmix_pass_by_reference (cumulative_args_t,
machine_mode, const_tree, bool); const function_arg_info &);
static bool mmix_frame_pointer_required (void); static bool mmix_frame_pointer_required (void);
static void mmix_asm_trampoline_template (FILE *); static void mmix_asm_trampoline_template (FILE *);
static void mmix_trampoline_init (rtx, tree, rtx); static void mmix_trampoline_init (rtx, tree, rtx);
@ -690,17 +690,17 @@ mmix_function_incoming_arg (cumulative_args_t argsp,
everything that goes by value. */ everything that goes by value. */
static bool static bool
mmix_pass_by_reference (cumulative_args_t argsp_v, machine_mode mode, mmix_pass_by_reference (cumulative_args_t argsp_v,
const_tree type, bool named ATTRIBUTE_UNUSED) const function_arg_info &arg)
{ {
CUMULATIVE_ARGS *argsp = get_cumulative_args (argsp_v); CUMULATIVE_ARGS *argsp = get_cumulative_args (argsp_v);
/* FIXME: Check: I'm not sure the must_pass_in_stack check is /* FIXME: Check: I'm not sure the must_pass_in_stack check is
necessary. */ necessary. */
if (targetm.calls.must_pass_in_stack (mode, type)) if (targetm.calls.must_pass_in_stack (arg.mode, arg.type))
return true; return true;
if (MMIX_FUNCTION_ARG_SIZE (mode, type) > 8 if (MMIX_FUNCTION_ARG_SIZE (arg.mode, arg.type) > 8
&& !TARGET_LIBFUNC && !TARGET_LIBFUNC
&& (!argsp || !argsp->lib)) && (!argsp || !argsp->lib))
return true; return true;

View File

@ -1526,17 +1526,9 @@ mn10300_va_start (tree valist, rtx nextarg)
/* Return true when a parameter should be passed by reference. */ /* Return true when a parameter should be passed by reference. */
static bool static bool
mn10300_pass_by_reference (cumulative_args_t cum ATTRIBUTE_UNUSED, mn10300_pass_by_reference (cumulative_args_t, const function_arg_info &arg)
machine_mode mode, const_tree type,
bool named ATTRIBUTE_UNUSED)
{ {
unsigned HOST_WIDE_INT size; unsigned HOST_WIDE_INT size = arg.type_size_in_bytes ();
if (type)
size = int_size_in_bytes (type);
else
size = GET_MODE_SIZE (mode);
return (size > 8 || size == 0); return (size > 8 || size == 0);
} }

View File

@ -451,25 +451,15 @@ moxie_function_arg_advance (cumulative_args_t cum_v, machine_mode mode,
: *cum); : *cum);
} }
/* Return non-zero if the function argument described by TYPE is to be /* Return non-zero if the function argument described by ARG is to be
passed by reference. */ passed by reference. */
static bool static bool
moxie_pass_by_reference (cumulative_args_t cum ATTRIBUTE_UNUSED, moxie_pass_by_reference (cumulative_args_t, const function_arg_info &arg)
machine_mode mode, const_tree type,
bool named ATTRIBUTE_UNUSED)
{ {
unsigned HOST_WIDE_INT size; if (arg.aggregate_type_p ())
return true;
if (type) unsigned HOST_WIDE_INT size = arg.type_size_in_bytes ();
{
if (AGGREGATE_TYPE_P (type))
return true;
size = int_size_in_bytes (type);
}
else
size = GET_MODE_SIZE (mode);
return size > 4*6; return size > 4*6;
} }
@ -486,7 +476,7 @@ moxie_arg_partial_bytes (cumulative_args_t cum_v, const function_arg_info &arg)
if (*cum >= 8) if (*cum >= 8)
return 0; return 0;
if (moxie_pass_by_reference (cum_v, arg.mode, arg.type, arg.named)) if (moxie_pass_by_reference (cum_v, arg))
size = 4; size = 4;
else if (arg.type) else if (arg.type)
{ {

View File

@ -744,14 +744,11 @@ msp430_arg_partial_bytes (cumulative_args_t cap, const function_arg_info &arg)
#define TARGET_PASS_BY_REFERENCE msp430_pass_by_reference #define TARGET_PASS_BY_REFERENCE msp430_pass_by_reference
static bool static bool
msp430_pass_by_reference (cumulative_args_t cap ATTRIBUTE_UNUSED, msp430_pass_by_reference (cumulative_args_t, const function_arg_info &arg)
machine_mode mode,
const_tree type,
bool named ATTRIBUTE_UNUSED)
{ {
return (mode == BLKmode return (arg.mode == BLKmode
|| (type && TREE_CODE (type) == RECORD_TYPE) || (arg.type && TREE_CODE (arg.type) == RECORD_TYPE)
|| (type && TREE_CODE (type) == UNION_TYPE)); || (arg.type && TREE_CODE (arg.type) == UNION_TYPE));
} }
#undef TARGET_CALLEE_COPIES #undef TARGET_CALLEE_COPIES

View File

@ -633,11 +633,9 @@ nvptx_function_value_regno_p (const unsigned int regno)
reference in memory. */ reference in memory. */
static bool static bool
nvptx_pass_by_reference (cumulative_args_t ARG_UNUSED (cum), nvptx_pass_by_reference (cumulative_args_t, const function_arg_info &arg)
machine_mode mode, const_tree type,
bool ARG_UNUSED (named))
{ {
return pass_in_memory (mode, type, false); return pass_in_memory (arg.mode, arg.type, false);
} }
/* Implement TARGET_RETURN_IN_MEMORY. */ /* Implement TARGET_RETURN_IN_MEMORY. */

View File

@ -928,23 +928,16 @@ or1k_legitimate_constant_p (machine_mode, rtx x)
#define TARGET_LEGITIMATE_CONSTANT_P or1k_legitimate_constant_p #define TARGET_LEGITIMATE_CONSTANT_P or1k_legitimate_constant_p
/* Worker for TARGET_PASS_BY_REFERENCE. /* Worker for TARGET_PASS_BY_REFERENCE.
Returns true if an argument of TYPE in MODE should be passed by reference Returns true if an argument ARG should be passed by reference as
as required by the OpenRISC ABI. On OpenRISC structures, unions and required by the OpenRISC ABI. On OpenRISC structures, unions and
arguments larger than 64-bits are passed by reference. */ arguments larger than 64-bits are passed by reference. */
static bool static bool
or1k_pass_by_reference (cumulative_args_t, machine_mode mode, or1k_pass_by_reference (cumulative_args_t, const function_arg_info &arg)
const_tree type, bool)
{ {
HOST_WIDE_INT size; if (arg.aggregate_type_p ())
if (type) return true;
{ HOST_WIDE_INT size = arg.type_size_in_bytes ();
if (AGGREGATE_TYPE_P (type))
return true;
size = int_size_in_bytes (type);
}
else
size = GET_MODE_SIZE (mode);
return size < 0 || size > 8; return size < 0 || size > 8;
} }

View File

@ -164,8 +164,8 @@ static void output_deferred_profile_counters (void) ATTRIBUTE_UNUSED;
static void pa_file_end (void); static void pa_file_end (void);
static void pa_init_libfuncs (void); static void pa_init_libfuncs (void);
static rtx pa_struct_value_rtx (tree, int); static rtx pa_struct_value_rtx (tree, int);
static bool pa_pass_by_reference (cumulative_args_t, machine_mode, static bool pa_pass_by_reference (cumulative_args_t,
const_tree, bool); const function_arg_info &);
static int pa_arg_partial_bytes (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, static void pa_function_arg_advance (cumulative_args_t, machine_mode,
const_tree, bool); const_tree, bool);
@ -6222,17 +6222,9 @@ pa_eh_return_handler_rtx (void)
or updates the ABI. */ or updates the ABI. */
static bool static bool
pa_pass_by_reference (cumulative_args_t ca ATTRIBUTE_UNUSED, pa_pass_by_reference (cumulative_args_t, const function_arg_info &arg)
machine_mode mode, const_tree type,
bool named ATTRIBUTE_UNUSED)
{ {
HOST_WIDE_INT size; HOST_WIDE_INT size = arg.type_size_in_bytes ();
if (type)
size = int_size_in_bytes (type);
else
size = GET_MODE_SIZE (mode);
if (TARGET_64BIT) if (TARGET_64BIT)
return size <= 0; return size <= 0;
else else

View File

@ -2815,10 +2815,9 @@ riscv_function_value (const_tree type, const_tree func, machine_mode mode)
/* Implement TARGET_PASS_BY_REFERENCE. */ /* Implement TARGET_PASS_BY_REFERENCE. */
static bool static bool
riscv_pass_by_reference (cumulative_args_t cum_v, machine_mode mode, riscv_pass_by_reference (cumulative_args_t cum_v, const function_arg_info &arg)
const_tree type, bool named)
{ {
HOST_WIDE_INT size = type ? int_size_in_bytes (type) : GET_MODE_SIZE (mode); HOST_WIDE_INT size = arg.type_size_in_bytes ();
struct riscv_arg_info info; struct riscv_arg_info info;
CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v); CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
@ -2828,7 +2827,7 @@ riscv_pass_by_reference (cumulative_args_t cum_v, machine_mode mode,
if (cum != NULL) if (cum != NULL)
{ {
/* Don't pass by reference if we can use a floating-point register. */ /* Don't pass by reference if we can use a floating-point register. */
riscv_get_arg_info (&info, cum, mode, type, named, false); riscv_get_arg_info (&info, cum, arg.mode, arg.type, arg.named, false);
if (info.num_fprs) if (info.num_fprs)
return false; return false;
} }
@ -2848,7 +2847,8 @@ riscv_return_in_memory (const_tree type, const_tree fndecl ATTRIBUTE_UNUSED)
/* The rules for returning in memory are the same as for passing the /* The rules for returning in memory are the same as for passing the
first named argument by reference. */ first named argument by reference. */
memset (&args, 0, sizeof args); memset (&args, 0, sizeof args);
return riscv_pass_by_reference (cum, TYPE_MODE (type), type, true); function_arg_info arg (const_cast<tree> (type), /*named=*/true);
return riscv_pass_by_reference (cum, arg);
} }
/* Implement TARGET_SETUP_INCOMING_VARARGS. */ /* Implement TARGET_SETUP_INCOMING_VARARGS. */

View File

@ -2111,29 +2111,27 @@ rs6000_arg_partial_bytes (cumulative_args_t cum_v,
reference. */ reference. */
bool bool
rs6000_pass_by_reference (cumulative_args_t cum ATTRIBUTE_UNUSED, rs6000_pass_by_reference (cumulative_args_t, const function_arg_info &arg)
machine_mode mode, const_tree type,
bool named ATTRIBUTE_UNUSED)
{ {
if (!type) if (!arg.type)
return 0; return 0;
if (DEFAULT_ABI == ABI_V4 && TARGET_IEEEQUAD if (DEFAULT_ABI == ABI_V4 && TARGET_IEEEQUAD
&& FLOAT128_IEEE_P (TYPE_MODE (type))) && FLOAT128_IEEE_P (TYPE_MODE (arg.type)))
{ {
if (TARGET_DEBUG_ARG) if (TARGET_DEBUG_ARG)
fprintf (stderr, "function_arg_pass_by_reference: V4 IEEE 128-bit\n"); fprintf (stderr, "function_arg_pass_by_reference: V4 IEEE 128-bit\n");
return 1; return 1;
} }
if (DEFAULT_ABI == ABI_V4 && AGGREGATE_TYPE_P (type)) if (DEFAULT_ABI == ABI_V4 && AGGREGATE_TYPE_P (arg.type))
{ {
if (TARGET_DEBUG_ARG) if (TARGET_DEBUG_ARG)
fprintf (stderr, "function_arg_pass_by_reference: V4 aggregate\n"); fprintf (stderr, "function_arg_pass_by_reference: V4 aggregate\n");
return 1; return 1;
} }
if (int_size_in_bytes (type) < 0) if (int_size_in_bytes (arg.type) < 0)
{ {
if (TARGET_DEBUG_ARG) if (TARGET_DEBUG_ARG)
fprintf (stderr, "function_arg_pass_by_reference: variable size\n"); fprintf (stderr, "function_arg_pass_by_reference: variable size\n");
@ -2142,7 +2140,7 @@ rs6000_pass_by_reference (cumulative_args_t cum ATTRIBUTE_UNUSED,
/* Allow -maltivec -mabi=no-altivec without warning. Altivec vector /* Allow -maltivec -mabi=no-altivec without warning. Altivec vector
modes only exist for GCC vector types if -maltivec. */ modes only exist for GCC vector types if -maltivec. */
if (TARGET_32BIT && !TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (mode)) if (TARGET_32BIT && !TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (arg.mode))
{ {
if (TARGET_DEBUG_ARG) if (TARGET_DEBUG_ARG)
fprintf (stderr, "function_arg_pass_by_reference: AltiVec\n"); fprintf (stderr, "function_arg_pass_by_reference: AltiVec\n");
@ -2150,8 +2148,8 @@ rs6000_pass_by_reference (cumulative_args_t cum ATTRIBUTE_UNUSED,
} }
/* Pass synthetic vectors in memory. */ /* Pass synthetic vectors in memory. */
if (TREE_CODE (type) == VECTOR_TYPE if (TREE_CODE (arg.type) == VECTOR_TYPE
&& int_size_in_bytes (type) > (TARGET_ALTIVEC_ABI ? 16 : 8)) && int_size_in_bytes (arg.type) > (TARGET_ALTIVEC_ABI ? 16 : 8))
{ {
static bool warned_for_pass_big_vectors = false; static bool warned_for_pass_big_vectors = false;
if (TARGET_DEBUG_ARG) if (TARGET_DEBUG_ARG)
@ -2200,7 +2198,7 @@ rs6000_parm_needs_stack (cumulative_args_t args_so_far, tree type)
/* See if this arg was passed by invisible reference. */ /* See if this arg was passed by invisible reference. */
if (pass_by_reference (get_cumulative_args (args_so_far), if (pass_by_reference (get_cumulative_args (args_so_far),
TYPE_MODE (type), type, true)) function_arg_info (type, /*named=*/true)))
type = build_pointer_type (type); type = build_pointer_type (type);
/* Find mode as it is passed by the ABI. */ /* Find mode as it is passed by the ABI. */

View File

@ -150,9 +150,8 @@ extern machine_mode rs6000_promote_function_mode (const_tree type ATTRIBUTE_UNUS
extern bool rs6000_return_in_memory (const_tree type, extern bool rs6000_return_in_memory (const_tree type,
const_tree fntype ATTRIBUTE_UNUSED); const_tree fntype ATTRIBUTE_UNUSED);
extern bool rs6000_return_in_msb (const_tree valtype); extern bool rs6000_return_in_msb (const_tree valtype);
extern bool rs6000_pass_by_reference (cumulative_args_t cum ATTRIBUTE_UNUSED, extern bool rs6000_pass_by_reference (cumulative_args_t,
machine_mode mode, const_tree type, const function_arg_info &);
bool named ATTRIBUTE_UNUSED);
extern void setup_incoming_varargs (cumulative_args_t cum, machine_mode mode, extern void setup_incoming_varargs (cumulative_args_t cum, machine_mode mode,
tree type, int *pretend_size ATTRIBUTE_UNUSED, tree type, int *pretend_size ATTRIBUTE_UNUSED,
int no_rtl); int no_rtl);

View File

@ -11953,26 +11953,23 @@ s390_function_arg_integer (machine_mode mode, const_tree type)
return false; return false;
} }
/* Return 1 if a function argument of type TYPE and mode MODE /* Return 1 if a function argument ARG is to be passed by reference.
is to be passed by reference. The ABI specifies that only The ABI specifies that only structures of size 1, 2, 4, or 8 bytes
structures of size 1, 2, 4, or 8 bytes are passed by value, are passed by value, all other structures (and complex numbers) are
all other structures (and complex numbers) are passed by passed by reference. */
reference. */
static bool static bool
s390_pass_by_reference (cumulative_args_t ca ATTRIBUTE_UNUSED, s390_pass_by_reference (cumulative_args_t, const function_arg_info &arg)
machine_mode mode, const_tree type,
bool named ATTRIBUTE_UNUSED)
{ {
int size = s390_function_arg_size (mode, type); int size = s390_function_arg_size (arg.mode, arg.type);
if (s390_function_arg_vector (mode, type)) if (s390_function_arg_vector (arg.mode, arg.type))
return false; return false;
if (size > 8) if (size > 8)
return true; return true;
if (type) if (tree type = arg.type)
{ {
if (AGGREGATE_TYPE_P (type) && exact_log2 (size) < 0) if (AGGREGATE_TYPE_P (type) && exact_log2 (size) < 0)
return true; return true;
@ -13349,7 +13346,7 @@ s390_call_saved_register_used (tree call_expr)
/* We assume that in the target function all parameters are /* We assume that in the target function all parameters are
named. This only has an impact on vector argument register named. This only has an impact on vector argument register
usage none of which is call-saved. */ usage none of which is call-saved. */
if (pass_by_reference (&cum_v, mode, type, true)) if (pass_by_reference (&cum_v, function_arg_info (type, /*named=*/true)))
{ {
mode = Pmode; mode = Pmode;
type = build_pointer_type (type); type = build_pointer_type (type);

View File

@ -294,8 +294,8 @@ static machine_mode sh_promote_function_mode (const_tree type,
int *punsignedp, int *punsignedp,
const_tree funtype, const_tree funtype,
int for_return); int for_return);
static bool sh_pass_by_reference (cumulative_args_t, machine_mode, static bool sh_pass_by_reference (cumulative_args_t,
const_tree, bool); const function_arg_info &);
static bool sh_callee_copies (cumulative_args_t, machine_mode, static bool sh_callee_copies (cumulative_args_t, machine_mode,
const_tree, bool); const_tree, bool);
static int sh_arg_partial_bytes (cumulative_args_t, const function_arg_info &); static int sh_arg_partial_bytes (cumulative_args_t, const function_arg_info &);
@ -7899,12 +7899,11 @@ sh_promote_prototypes (const_tree type)
} }
static bool static bool
sh_pass_by_reference (cumulative_args_t cum_v, machine_mode mode, sh_pass_by_reference (cumulative_args_t cum_v, const function_arg_info &arg)
const_tree type, bool named ATTRIBUTE_UNUSED)
{ {
CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v); CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
if (targetm.calls.must_pass_in_stack (mode, type)) if (targetm.calls.must_pass_in_stack (arg.mode, arg.type))
return true; return true;
/* ??? std_gimplify_va_arg_expr passes NULL for cum. That function /* ??? std_gimplify_va_arg_expr passes NULL for cum. That function

View File

@ -655,7 +655,7 @@ static rtx sparc_legitimize_address (rtx, rtx, machine_mode);
static rtx sparc_delegitimize_address (rtx); static rtx sparc_delegitimize_address (rtx);
static bool sparc_mode_dependent_address_p (const_rtx, addr_space_t); static bool sparc_mode_dependent_address_p (const_rtx, addr_space_t);
static bool sparc_pass_by_reference (cumulative_args_t, static bool sparc_pass_by_reference (cumulative_args_t,
machine_mode, const_tree, bool); const function_arg_info &);
static void sparc_function_arg_advance (cumulative_args_t, static void sparc_function_arg_advance (cumulative_args_t,
machine_mode, const_tree, bool); machine_mode, const_tree, bool);
static rtx sparc_function_arg_1 (cumulative_args_t, static rtx sparc_function_arg_1 (cumulative_args_t,
@ -6743,10 +6743,10 @@ sparc_strict_argument_naming (cumulative_args_t ca ATTRIBUTE_UNUSED)
Specify whether to pass the argument by reference. */ Specify whether to pass the argument by reference. */
static bool static bool
sparc_pass_by_reference (cumulative_args_t cum ATTRIBUTE_UNUSED, sparc_pass_by_reference (cumulative_args_t, const function_arg_info &arg)
machine_mode mode, const_tree type,
bool named ATTRIBUTE_UNUSED)
{ {
tree type = arg.type;
machine_mode mode = arg.mode;
if (TARGET_ARCH32) if (TARGET_ARCH32)
/* Original SPARC 32-bit ABI says that structures and unions, /* Original SPARC 32-bit ABI says that structures and unions,
and quad-precision floats are passed by reference. and quad-precision floats are passed by reference.

View File

@ -3902,11 +3902,9 @@ spu_function_arg_padding (machine_mode, const_tree)
/* Variable sized types are passed by reference. */ /* Variable sized types are passed by reference. */
static bool static bool
spu_pass_by_reference (cumulative_args_t cum ATTRIBUTE_UNUSED, spu_pass_by_reference (cumulative_args_t, const function_arg_info &arg)
machine_mode mode ATTRIBUTE_UNUSED,
const_tree type, bool named ATTRIBUTE_UNUSED)
{ {
return type && TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST; return arg.type && TREE_CODE (TYPE_SIZE (arg.type)) != INTEGER_CST;
} }

View File

@ -159,12 +159,11 @@ tilegx_function_ok_for_sibcall (tree decl, tree exp ATTRIBUTE_UNUSED)
/* Implement TARGET_PASS_BY_REFERENCE. Variable sized types are /* Implement TARGET_PASS_BY_REFERENCE. Variable sized types are
passed by reference. */ passed by reference. */
static bool static bool
tilegx_pass_by_reference (cumulative_args_t cum ATTRIBUTE_UNUSED, tilegx_pass_by_reference (cumulative_args_t, const function_arg_info &arg)
machine_mode mode ATTRIBUTE_UNUSED,
const_tree type, bool named ATTRIBUTE_UNUSED)
{ {
return (type && TYPE_SIZE (type) return (arg.type
&& TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST); && TYPE_SIZE (arg.type)
&& TREE_CODE (TYPE_SIZE (arg.type)) != INTEGER_CST);
} }

View File

@ -134,12 +134,11 @@ tilepro_function_ok_for_sibcall (tree decl, tree exp ATTRIBUTE_UNUSED)
/* Implement TARGET_PASS_BY_REFERENCE. Variable sized types are /* Implement TARGET_PASS_BY_REFERENCE. Variable sized types are
passed by reference. */ passed by reference. */
static bool static bool
tilepro_pass_by_reference (cumulative_args_t cum ATTRIBUTE_UNUSED, tilepro_pass_by_reference (cumulative_args_t, const function_arg_info &arg)
machine_mode mode ATTRIBUTE_UNUSED,
const_tree type, bool named ATTRIBUTE_UNUSED)
{ {
return (type && TYPE_SIZE (type) return (arg.type
&& TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST); && TYPE_SIZE (arg.type)
&& TREE_CODE (TYPE_SIZE (arg.type)) != INTEGER_CST);
} }

View File

@ -110,20 +110,12 @@ v850_all_frame_related (rtx par)
Specify whether to pass the argument by reference. */ Specify whether to pass the argument by reference. */
static bool static bool
v850_pass_by_reference (cumulative_args_t cum ATTRIBUTE_UNUSED, v850_pass_by_reference (cumulative_args_t, const function_arg_info &arg)
machine_mode mode, const_tree type,
bool named ATTRIBUTE_UNUSED)
{ {
unsigned HOST_WIDE_INT size;
if (!TARGET_GCC_ABI) if (!TARGET_GCC_ABI)
return 0; return 0;
if (type) unsigned HOST_WIDE_INT size = arg.type_size_in_bytes ();
size = int_size_in_bytes (type);
else
size = GET_MODE_SIZE (mode);
return size > 8; return size > 8;
} }

View File

@ -158,8 +158,8 @@ static struct machine_function *visium_init_machine_status (void);
/* Target hooks and TARGET_INITIALIZER */ /* Target hooks and TARGET_INITIALIZER */
static bool visium_pass_by_reference (cumulative_args_t, machine_mode, static bool visium_pass_by_reference (cumulative_args_t,
const_tree, bool); const function_arg_info &);
static rtx visium_function_arg (cumulative_args_t, machine_mode, static rtx visium_function_arg (cumulative_args_t, machine_mode,
const_tree, bool); const_tree, bool);
@ -1310,11 +1310,9 @@ visium_reorg (void)
/* Return true if an argument must be passed by indirect reference. */ /* Return true if an argument must be passed by indirect reference. */
static bool static bool
visium_pass_by_reference (cumulative_args_t ca ATTRIBUTE_UNUSED, visium_pass_by_reference (cumulative_args_t, const function_arg_info &arg)
machine_mode mode ATTRIBUTE_UNUSED,
const_tree type,
bool named ATTRIBUTE_UNUSED)
{ {
tree type = arg.type;
return type && (AGGREGATE_TYPE_P (type) || TREE_CODE (type) == VECTOR_TYPE); return type && (AGGREGATE_TYPE_P (type) || TREE_CODE (type) == VECTOR_TYPE);
} }

View File

@ -4076,11 +4076,11 @@ register to be used by the caller for this argument; likewise
@code{TARGET_FUNCTION_INCOMING_ARG}, for the called function. @code{TARGET_FUNCTION_INCOMING_ARG}, for the called function.
@end deftypefn @end deftypefn
@deftypefn {Target Hook} bool TARGET_PASS_BY_REFERENCE (cumulative_args_t @var{cum}, machine_mode @var{mode}, const_tree @var{type}, bool @var{named}) @deftypefn {Target Hook} bool TARGET_PASS_BY_REFERENCE (cumulative_args_t @var{cum}, const function_arg_info @var{&arg})
This target hook should return @code{true} if an argument at the This target hook should return @code{true} if argument @var{arg} at the
position indicated by @var{cum} should be passed by reference. This position indicated by @var{cum} should be passed by reference. This
predicate is queried after target independent reasons for being predicate is queried after target independent reasons for being
passed by reference, such as @code{TREE_ADDRESSABLE (type)}. passed by reference, such as @code{TREE_ADDRESSABLE (@var{arg}.type)}.
If the hook returns true, a copy of that argument is made in memory and a If the hook returns true, a copy of that argument is made in memory and a
pointer to the argument is passed instead of the argument itself. pointer to the argument is passed instead of the argument itself.

View File

@ -2454,13 +2454,15 @@ assign_parm_find_data_types (struct assign_parm_data_all *all, tree parm,
passed_type = TREE_TYPE (first_field (passed_type)); passed_type = TREE_TYPE (first_field (passed_type));
/* See if this arg was passed by invisible reference. */ /* See if this arg was passed by invisible reference. */
if (pass_by_reference (&all->args_so_far_v, passed_mode, {
passed_type, data->named_arg)) function_arg_info arg (passed_type, passed_mode, data->named_arg);
{ if (pass_by_reference (&all->args_so_far_v, arg))
passed_type = nominal_type = build_pointer_type (passed_type); {
data->passed_pointer = true; passed_type = nominal_type = build_pointer_type (passed_type);
passed_mode = nominal_mode = TYPE_MODE (nominal_type); data->passed_pointer = true;
} passed_mode = nominal_mode = TYPE_MODE (nominal_type);
}
}
/* Find mode as it is passed by the ABI. */ /* Find mode as it is passed by the ABI. */
unsignedp = TYPE_UNSIGNED (passed_type); unsignedp = TYPE_UNSIGNED (passed_type);

View File

@ -42,6 +42,7 @@ along with GCC; see the file COPYING3. If not see
#include "gimplify.h" #include "gimplify.h"
#include "attribs.h" #include "attribs.h"
#include "debug.h" #include "debug.h"
#include "calls.h"
/* Data type for the expressions representing sizes of data types. /* Data type for the expressions representing sizes of data types.
It is the first integer type laid out. */ It is the first integer type laid out. */
@ -1859,8 +1860,9 @@ compute_record_mode (tree type)
|| (TREE_CODE (type) == UNION_TYPE || (TREE_CODE (type) == UNION_TYPE
&& (GET_MODE_CLASS (mode) == MODE_INT && (GET_MODE_CLASS (mode) == MODE_INT
|| (GET_MODE_CLASS (mode) == MODE_PARTIAL_INT || (GET_MODE_CLASS (mode) == MODE_PARTIAL_INT
&& targetm.calls.pass_by_reference (pack_cumulative_args (0), && (targetm.calls.pass_by_reference
mode, type, 0))))) (pack_cumulative_args (0),
function_arg_info (type, mode, /*named=*/false)))))))
&& mode != VOIDmode && mode != VOIDmode
&& poly_int_tree_p (TYPE_SIZE (type), &type_size) && poly_int_tree_p (TYPE_SIZE (type), &type_size)
&& known_eq (GET_MODE_BITSIZE (mode), type_size)) && known_eq (GET_MODE_BITSIZE (mode), type_size))

View File

@ -4450,18 +4450,18 @@ or 3-byte structure is returned at the most significant end of a\n\
from __builtin_va_arg. */ from __builtin_va_arg. */
DEFHOOK DEFHOOK
(pass_by_reference, (pass_by_reference,
"This target hook should return @code{true} if an argument at the\n\ "This target hook should return @code{true} if argument @var{arg} at the\n\
position indicated by @var{cum} should be passed by reference. This\n\ position indicated by @var{cum} should be passed by reference. This\n\
predicate is queried after target independent reasons for being\n\ predicate is queried after target independent reasons for being\n\
passed by reference, such as @code{TREE_ADDRESSABLE (type)}.\n\ passed by reference, such as @code{TREE_ADDRESSABLE (@var{arg}.type)}.\n\
\n\ \n\
If the hook returns true, a copy of that argument is made in memory and a\n\ If the hook returns true, a copy of that argument is made in memory and a\n\
pointer to the argument is passed instead of the argument itself.\n\ pointer to the argument is passed instead of the argument itself.\n\
The pointer is passed in whatever way is appropriate for passing a pointer\n\ The pointer is passed in whatever way is appropriate for passing a pointer\n\
to that type.", to that type.",
bool, bool,
(cumulative_args_t cum, machine_mode mode, const_tree type, bool named), (cumulative_args_t cum, const function_arg_info &arg),
hook_bool_CUMULATIVE_ARGS_mode_tree_bool_false) hook_bool_CUMULATIVE_ARGS_arg_info_false)
DEFHOOK DEFHOOK
(expand_builtin_saveregs, (expand_builtin_saveregs,

View File

@ -323,11 +323,10 @@ default_cxx_get_cookie_size (tree type)
of the TARGET_PASS_BY_REFERENCE hook uses just MUST_PASS_IN_STACK. */ of the TARGET_PASS_BY_REFERENCE hook uses just MUST_PASS_IN_STACK. */
bool bool
hook_pass_by_reference_must_pass_in_stack (cumulative_args_t c ATTRIBUTE_UNUSED, hook_pass_by_reference_must_pass_in_stack (cumulative_args_t,
machine_mode mode ATTRIBUTE_UNUSED, const_tree type ATTRIBUTE_UNUSED, const function_arg_info &arg)
bool named_arg ATTRIBUTE_UNUSED)
{ {
return targetm.calls.must_pass_in_stack (mode, type); return targetm.calls.must_pass_in_stack (arg.mode, arg.type);
} }
/* Return true if a parameter follows callee copies conventions. This /* Return true if a parameter follows callee copies conventions. This
@ -767,6 +766,13 @@ hook_bool_CUMULATIVE_ARGS_mode_tree_bool_true (
return true; return true;
} }
bool
hook_bool_CUMULATIVE_ARGS_arg_info_false (cumulative_args_t,
const function_arg_info &)
{
return false;
}
int int
hook_int_CUMULATIVE_ARGS_arg_info_0 (cumulative_args_t, hook_int_CUMULATIVE_ARGS_arg_info_0 (cumulative_args_t,
const function_arg_info &) const function_arg_info &)

View File

@ -63,7 +63,7 @@ extern tree default_cxx_guard_type (void);
extern tree default_cxx_get_cookie_size (tree); extern tree default_cxx_get_cookie_size (tree);
extern bool hook_pass_by_reference_must_pass_in_stack extern bool hook_pass_by_reference_must_pass_in_stack
(cumulative_args_t, machine_mode mode, const_tree, bool); (cumulative_args_t, const function_arg_info &);
extern bool hook_callee_copies_named extern bool hook_callee_copies_named
(cumulative_args_t ca, machine_mode, const_tree, bool); (cumulative_args_t ca, machine_mode, const_tree, bool);
@ -137,6 +137,8 @@ extern bool hook_bool_CUMULATIVE_ARGS_mode_tree_bool_false
(cumulative_args_t, machine_mode, const_tree, bool); (cumulative_args_t, machine_mode, const_tree, bool);
extern bool hook_bool_CUMULATIVE_ARGS_mode_tree_bool_true extern bool hook_bool_CUMULATIVE_ARGS_mode_tree_bool_true
(cumulative_args_t, machine_mode, const_tree, bool); (cumulative_args_t, machine_mode, const_tree, bool);
extern bool hook_bool_CUMULATIVE_ARGS_arg_info_false
(cumulative_args_t, const function_arg_info &);
extern int hook_int_CUMULATIVE_ARGS_arg_info_0 extern int hook_int_CUMULATIVE_ARGS_arg_info_0
(cumulative_args_t, const function_arg_info &); (cumulative_args_t, const function_arg_info &);
extern void hook_void_CUMULATIVE_ARGS_tree extern void hook_void_CUMULATIVE_ARGS_tree

View File

@ -6431,13 +6431,11 @@ prepare_call_arguments (basic_block bb, rtx_insn *insn)
if (t && t != void_list_node) if (t && t != void_list_node)
{ {
tree argtype = TREE_VALUE (t); tree argtype = TREE_VALUE (t);
machine_mode mode = TYPE_MODE (argtype);
rtx reg; rtx reg;
if (pass_by_reference (&args_so_far_v, mode, argtype, true)) function_arg_info orig_arg (argtype, /*named=*/true);
{ if (pass_by_reference (&args_so_far_v, orig_arg))
argtype = build_pointer_type (argtype); argtype = build_pointer_type (argtype);
mode = TYPE_MODE (argtype); machine_mode mode = TYPE_MODE (argtype);
}
reg = targetm.calls.function_arg (args_so_far, mode, reg = targetm.calls.function_arg (args_so_far, mode,
argtype, true); argtype, true);
if (TREE_CODE (argtype) == REFERENCE_TYPE if (TREE_CODE (argtype) == REFERENCE_TYPE