+2019-08-20 Richard Sandiford <richard.sandiford@arm.com>
+
+ * calls.h (function_arg_info): Add a pass_by_reference field,
+ defaulting to false.
+ * calls.c (apply_pass_by_reference_rules): Set pass_by_reference
+ when applying pass-by-reference semantics.
+ (initialize_argument_information): Likewise.
+ (emit_library_call_value_1): Likewise.
+ * function.c (assign_parm_data_one): Remove passed_pointer field.
+ (assign_parm_find_data_types): Don't set it.
+ (assign_parm_find_stack_rtl, assign_parm_adjust_stack_rtl)
+ (assign_parm_setup_reg, assign_parms, gimplify_parameters): Use
+ arg.pass_by_reference instead of passed_pointer.
+
2019-08-20 Richard Sandiford <richard.sandiford@arm.com>
* calls.c (emit_library_call_value_1): Merge arg and orig_arg
{
arg.type = build_pointer_type (arg.type);
arg.mode = TYPE_MODE (arg.type);
+ arg.pass_by_reference = true;
return true;
}
return false;
"argument must be passed"
" by copying");
}
+ arg.pass_by_reference = true;
}
unsignedp = TYPE_UNSIGNED (type);
call_fusage);
arg.mode = Pmode;
+ arg.pass_by_reference = true;
val = force_operand (XEXP (slot, 0), NULL_RTX);
}
class function_arg_info
{
public:
- function_arg_info () : type (NULL_TREE), mode (VOIDmode), named (false) {}
+ function_arg_info ()
+ : type (NULL_TREE), mode (VOIDmode), named (false),
+ pass_by_reference (false)
+ {}
/* Initialize an argument of mode MODE, either before or after promotion. */
function_arg_info (machine_mode mode, bool named)
- : type (NULL_TREE), mode (mode), named (named)
+ : type (NULL_TREE), mode (mode), named (named), pass_by_reference (false)
{}
/* Initialize an unpromoted argument of type TYPE. */
function_arg_info (tree type, bool named)
- : type (type), mode (TYPE_MODE (type)), named (named)
+ : type (type), mode (TYPE_MODE (type)), named (named),
+ pass_by_reference (false)
{}
/* Initialize an argument with explicit properties. */
function_arg_info (tree type, machine_mode mode, bool named)
- : type (type), mode (mode), named (named)
+ : type (type), mode (mode), named (named), pass_by_reference (false)
{}
/* Return true if the gimple-level type is an aggregate. */
treated as an unnamed variadic argument (i.e. one passed through
"..."). See also TARGET_STRICT_ARGUMENT_NAMING. */
unsigned int named : 1;
+
+ /* True if we have decided to pass the argument by reference, in which case
+ the function_arg_info describes a pointer to the original argument. */
+ unsigned int pass_by_reference : 1;
};
extern int flags_from_decl_or_type (const_tree);
machine_mode passed_mode;
struct locate_and_pad_arg_data locate;
int partial;
- BOOL_BITFIELD passed_pointer : 1;
};
/* A subroutine of assign_parms. Initialize ALL. */
if (apply_pass_by_reference_rules (&all->args_so_far_v, data->arg))
{
data->nominal_type = data->arg.type;
- data->passed_pointer = true;
data->passed_mode = data->nominal_mode = data->arg.mode;
}
stack_parm = gen_rtx_PLUS (Pmode, stack_parm, offset_rtx);
stack_parm = gen_rtx_MEM (data->arg.mode, stack_parm);
- if (!data->passed_pointer)
+ if (!data->arg.pass_by_reference)
{
set_mem_attributes (stack_parm, parm, 1);
/* set_mem_attributes could set MEM_SIZE to the passed mode's size,
pointers in their passed stack slots. */
else if (crtl->stack_protect_guard
&& (flag_stack_protect == 2
- || data->passed_pointer
+ || data->arg.pass_by_reference
|| POINTER_TYPE_P (data->nominal_type)))
stack_parm = NULL;
/* If this was an item that we received a pointer to,
set rtl appropriately. */
- if (data->passed_pointer)
+ if (data->arg.pass_by_reference)
{
rtl = gen_rtx_MEM (TYPE_MODE (TREE_TYPE (data->arg.type)), parmreg);
set_mem_attributes (rtl, parm, 1);
/* If we were passed a pointer but the actual value can safely live
in a register, retrieve it and use it directly. */
- if (data->passed_pointer && TYPE_MODE (TREE_TYPE (parm)) != BLKmode)
+ if (data->arg.pass_by_reference && TYPE_MODE (TREE_TYPE (parm)) != BLKmode)
{
/* We can't use nominal_mode, because it will have been set to
Pmode above. We must use the actual mode of the parm. */
assign_parm_adjust_entry_rtl (&data);
}
/* Record permanently how this parm was passed. */
- if (data.passed_pointer)
+ if (data.arg.pass_by_reference)
{
rtx incoming_rtl
= gen_rtx_MEM (TYPE_MODE (TREE_TYPE (data.arg.type)),
if (assign_parm_setup_block_p (&data))
assign_parm_setup_block (&all, parm, &data);
- else if (data.passed_pointer || use_register_for_decl (parm))
+ else if (data.arg.pass_by_reference || use_register_for_decl (parm))
assign_parm_setup_reg (&all, parm, &data);
else
assign_parm_setup_stack (&all, parm, &data);
gimplify_one_sizepos (&DECL_SIZE_UNIT (parm), &stmts);
}
- if (data.passed_pointer)
+ if (data.arg.pass_by_reference)
{
tree type = TREE_TYPE (data.arg.type);
function_arg_info orig_arg (type, data.arg.named);