Commit cf0d189e by Richard Sandiford Committed by Richard Sandiford

Make calls.c use function_arg_info internally

This patch makes the two main calls.c argument-processing
routines track the state of the argument in a function_arg_info
instead of using separate mode variables.

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

gcc/
	* calls.c (emit_library_call_value_1): Merge arg and orig_arg
	into a single function_arg_info, updating its fields when we
	apply pass-by-reference and promotion semantics.  Use the
	function_arg_info to track the mode rather than keeping it in
	a separate local variable.
	(initialize_argument_information): Likewise.  Base the final
	arg_to_skip on this new function_arg_info rather than creating
	a new one from scratch.

From-SVN: r274706
parent 634afa05
2019-08-20 Richard Sandiford <richard.sandiford@arm.com> 2019-08-20 Richard Sandiford <richard.sandiford@arm.com>
* calls.c (emit_library_call_value_1): Merge arg and orig_arg
into a single function_arg_info, updating its fields when we
apply pass-by-reference and promotion semantics. Use the
function_arg_info to track the mode rather than keeping it in
a separate local variable.
(initialize_argument_information): Likewise. Base the final
arg_to_skip on this new function_arg_info rather than creating
a new one from scratch.
2019-08-20 Richard Sandiford <richard.sandiford@arm.com>
* function.c (assign_parm_data_one): Replace passed_type, * function.c (assign_parm_data_one): Replace passed_type,
promoted_mode and named_arg with a function_arg_info field. promoted_mode and named_arg with a function_arg_info field.
(assign_parm_find_data_types): Remove local variables and (assign_parm_find_data_types): Remove local variables and
......
...@@ -1982,7 +1982,6 @@ initialize_argument_information (int num_actuals ATTRIBUTE_UNUSED, ...@@ -1982,7 +1982,6 @@ initialize_argument_information (int num_actuals ATTRIBUTE_UNUSED,
{ {
tree type = TREE_TYPE (args[i].tree_value); tree type = TREE_TYPE (args[i].tree_value);
int unsignedp; int unsignedp;
machine_mode mode;
/* Replace erroneous argument with constant zero. */ /* Replace erroneous argument with constant zero. */
if (type == error_mark_node || !COMPLETE_TYPE_P (type)) if (type == error_mark_node || !COMPLETE_TYPE_P (type))
...@@ -2010,13 +2009,13 @@ initialize_argument_information (int num_actuals ATTRIBUTE_UNUSED, ...@@ -2010,13 +2009,13 @@ 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. */
function_arg_info orig_arg (type, argpos < n_named_args); function_arg_info arg (type, argpos < n_named_args);
if (pass_by_reference (args_so_far_pnt, orig_arg)) if (pass_by_reference (args_so_far_pnt, arg))
{ {
bool callee_copies; bool callee_copies;
tree base = NULL_TREE; tree base = NULL_TREE;
callee_copies = reference_callee_copied (args_so_far_pnt, orig_arg); callee_copies = reference_callee_copied (args_so_far_pnt, arg);
/* If we're compiling a thunk, pass through invisible references /* If we're compiling a thunk, pass through invisible references
instead of making a copy. */ instead of making a copy. */
...@@ -2129,15 +2128,16 @@ initialize_argument_information (int num_actuals ATTRIBUTE_UNUSED, ...@@ -2129,15 +2128,16 @@ initialize_argument_information (int num_actuals ATTRIBUTE_UNUSED,
} }
unsignedp = TYPE_UNSIGNED (type); unsignedp = TYPE_UNSIGNED (type);
mode = promote_function_mode (type, TYPE_MODE (type), &unsignedp, arg.type = type;
fndecl ? TREE_TYPE (fndecl) : fntype, 0); arg.mode
= promote_function_mode (type, TYPE_MODE (type), &unsignedp,
fndecl ? TREE_TYPE (fndecl) : fntype, 0);
args[i].unsignedp = unsignedp; args[i].unsignedp = unsignedp;
args[i].mode = mode; args[i].mode = arg.mode;
targetm.calls.warn_parameter_passing_abi (args_so_far, type); targetm.calls.warn_parameter_passing_abi (args_so_far, type);
function_arg_info arg (type, mode, argpos < n_named_args);
args[i].reg = targetm.calls.function_arg (args_so_far, arg); args[i].reg = targetm.calls.function_arg (args_so_far, arg);
if (args[i].reg && CONST_INT_P (args[i].reg)) if (args[i].reg && CONST_INT_P (args[i].reg))
...@@ -2177,7 +2177,7 @@ initialize_argument_information (int num_actuals ATTRIBUTE_UNUSED, ...@@ -2177,7 +2177,7 @@ initialize_argument_information (int num_actuals ATTRIBUTE_UNUSED,
if (args[i].reg == 0 || args[i].partial != 0 if (args[i].reg == 0 || args[i].partial != 0
|| reg_parm_stack_space > 0 || reg_parm_stack_space > 0
|| args[i].pass_on_stack) || args[i].pass_on_stack)
locate_and_pad_parm (mode, type, locate_and_pad_parm (arg.mode, type,
#ifdef STACK_PARMS_IN_REG_PARM_AREA #ifdef STACK_PARMS_IN_REG_PARM_AREA
1, 1,
#else #else
...@@ -2191,7 +2191,7 @@ initialize_argument_information (int num_actuals ATTRIBUTE_UNUSED, ...@@ -2191,7 +2191,7 @@ initialize_argument_information (int num_actuals ATTRIBUTE_UNUSED,
/* The argument is passed entirely in registers. See at which /* The argument is passed entirely in registers. See at which
end it should be padded. */ end it should be padded. */
args[i].locate.where_pad = args[i].locate.where_pad =
BLOCK_REG_PADDING (mode, type, BLOCK_REG_PADDING (arg.mode, type,
int_size_in_bytes (type) <= UNITS_PER_WORD); int_size_in_bytes (type) <= UNITS_PER_WORD);
#endif #endif
...@@ -2208,9 +2208,8 @@ initialize_argument_information (int num_actuals ATTRIBUTE_UNUSED, ...@@ -2208,9 +2208,8 @@ initialize_argument_information (int num_actuals ATTRIBUTE_UNUSED,
promoted_mode used for function_arg above. However, the promoted_mode used for function_arg above. However, the
corresponding handling of incoming arguments in function.c corresponding handling of incoming arguments in function.c
does pass the promoted mode. */ does pass the promoted mode. */
function_arg_info arg_to_skip (type, TYPE_MODE (type), arg.mode = TYPE_MODE (type);
argpos < n_named_args); targetm.calls.function_arg_advance (args_so_far, arg);
targetm.calls.function_arg_advance (args_so_far, arg_to_skip);
/* Store argument values for functions decorated with attribute /* Store argument values for functions decorated with attribute
alloc_size. */ alloc_size. */
...@@ -4906,24 +4905,25 @@ emit_library_call_value_1 (int retval, rtx orgfun, rtx value, ...@@ -4906,24 +4905,25 @@ emit_library_call_value_1 (int retval, rtx orgfun, rtx value,
for (unsigned int i = 0; count < nargs; i++, count++) for (unsigned int i = 0; count < nargs; i++, count++)
{ {
rtx val = args[i].first; rtx val = args[i].first;
machine_mode mode = args[i].second; function_arg_info arg (args[i].second, /*named=*/true);
int unsigned_p = 0; int unsigned_p = 0;
/* We cannot convert the arg value to the mode the library wants here; /* We cannot convert the arg value to the mode the library wants here;
must do it earlier where we know the signedness of the arg. */ must do it earlier where we know the signedness of the arg. */
gcc_assert (mode != BLKmode gcc_assert (arg.mode != BLKmode
&& (GET_MODE (val) == mode || GET_MODE (val) == VOIDmode)); && (GET_MODE (val) == arg.mode
|| GET_MODE (val) == VOIDmode));
/* Make sure it is a reasonable operand for a move or push insn. */ /* Make sure it is a reasonable operand for a move or push insn. */
if (!REG_P (val) && !MEM_P (val) if (!REG_P (val) && !MEM_P (val)
&& !(CONSTANT_P (val) && targetm.legitimate_constant_p (mode, val))) && !(CONSTANT_P (val)
&& targetm.legitimate_constant_p (arg.mode, val)))
val = force_operand (val, NULL_RTX); val = force_operand (val, NULL_RTX);
function_arg_info orig_arg (mode, /*named=*/true); if (pass_by_reference (&args_so_far_v, arg))
if (pass_by_reference (&args_so_far_v, orig_arg))
{ {
rtx slot; rtx slot;
int must_copy = !reference_callee_copied (&args_so_far_v, orig_arg); int must_copy = !reference_callee_copied (&args_so_far_v, arg);
/* If this was a CONST function, it is now PURE since it now /* If this was a CONST function, it is now PURE since it now
reads memory. */ reads memory. */
...@@ -4942,7 +4942,7 @@ emit_library_call_value_1 (int retval, rtx orgfun, rtx value, ...@@ -4942,7 +4942,7 @@ emit_library_call_value_1 (int retval, rtx orgfun, rtx value,
} }
else else
{ {
slot = assign_temp (lang_hooks.types.type_for_mode (mode, 0), slot = assign_temp (lang_hooks.types.type_for_mode (arg.mode, 0),
1, 1); 1, 1);
emit_move_insn (slot, val); emit_move_insn (slot, val);
} }
...@@ -4956,14 +4956,15 @@ emit_library_call_value_1 (int retval, rtx orgfun, rtx value, ...@@ -4956,14 +4956,15 @@ emit_library_call_value_1 (int retval, rtx orgfun, rtx value,
slot), slot),
call_fusage); call_fusage);
mode = Pmode; arg.mode = Pmode;
val = force_operand (XEXP (slot, 0), NULL_RTX); val = force_operand (XEXP (slot, 0), NULL_RTX);
} }
mode = promote_function_mode (NULL_TREE, mode, &unsigned_p, NULL_TREE, 0); arg.mode = promote_function_mode (NULL_TREE, arg.mode, &unsigned_p,
function_arg_info arg (mode, /*named=*/true); NULL_TREE, 0);
argvec[count].mode = mode; argvec[count].mode = arg.mode;
argvec[count].value = convert_modes (mode, GET_MODE (val), val, unsigned_p); argvec[count].value = convert_modes (arg.mode, GET_MODE (val), val,
unsigned_p);
argvec[count].reg = targetm.calls.function_arg (args_so_far, arg); argvec[count].reg = targetm.calls.function_arg (args_so_far, arg);
argvec[count].partial argvec[count].partial
...@@ -4973,7 +4974,7 @@ emit_library_call_value_1 (int retval, rtx orgfun, rtx value, ...@@ -4973,7 +4974,7 @@ emit_library_call_value_1 (int retval, rtx orgfun, rtx value,
|| argvec[count].partial != 0 || argvec[count].partial != 0
|| reg_parm_stack_space > 0) || reg_parm_stack_space > 0)
{ {
locate_and_pad_parm (mode, NULL_TREE, locate_and_pad_parm (arg.mode, NULL_TREE,
#ifdef STACK_PARMS_IN_REG_PARM_AREA #ifdef STACK_PARMS_IN_REG_PARM_AREA
1, 1,
#else #else
...@@ -4989,8 +4990,9 @@ emit_library_call_value_1 (int retval, rtx orgfun, rtx value, ...@@ -4989,8 +4990,9 @@ emit_library_call_value_1 (int retval, rtx orgfun, rtx value,
/* The argument is passed entirely in registers. See at which /* The argument is passed entirely in registers. See at which
end it should be padded. */ end it should be padded. */
argvec[count].locate.where_pad = argvec[count].locate.where_pad =
BLOCK_REG_PADDING (mode, NULL_TREE, BLOCK_REG_PADDING (arg.mode, NULL_TREE,
known_le (GET_MODE_SIZE (mode), UNITS_PER_WORD)); known_le (GET_MODE_SIZE (arg.mode),
UNITS_PER_WORD));
#endif #endif
targetm.calls.function_arg_advance (args_so_far, arg); targetm.calls.function_arg_advance (args_so_far, arg);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment