Skip to content

Commit

Permalink
function call lowering, darwin, aarch64: Provide control over stack l…
Browse files Browse the repository at this point in the history
…ayout and packing.

1. Generic : Mega-hack to allow different passing organisation for variadic funcs.

Right now, the generic code assumes that it can determine the stack layout from
target callbacks that don't have complete information about the argument they
are processing (they only know the mode and the type - not it the argument is
named or not, for example).  This hack is not complete - but makes some
progress.

It looks like we really need the option for a target to override the layout
process - if it requires distinct stack layouts for different calling convs.

2. Add cumulative_args_t variants of TARGET_FUNCTION_ROUND_BOUNDARY and friends

The two target hooks responsible for informing GCC about stack
parameter alignment are `TARGET_FUNCTION_ARG_BOUNDARY` and
`TARGET_FUNCTION_ARG_ROUND_BOUNDARY`, which currently only consider
the tree and machine_mode of a specific given argument.

Create two new target hooks suffixed with '_CA', and pass in a third
`cumulative_args_t` parameter. This enables the backend to make
alignment decisions based on the context of the whole function rather
than individual parameters.

The orignal machine_mode/tree type macros are not removed - they are
called by the default implementations of `TARGET_...BOUNDARY_CA` and
`TARGET_...ROUND_BOUNDARY_CA`. This is done with the intetnion of
avoiding large mechanical modifications of nearly every backend in
GCC. There is also a new flag, -fstack-use-cumulative-args, which
provides a way to completely bypass the new `..._CA` macros. This
feature is intended for debugging GCC itself.

gcc/ChangeLog:

	* calls.c (initialize_argument_information): Pass `args_so_far`.
	* common.opt: New flag `-fstack-use-cumulative-args`.
	* config.gcc: No platforms currently use ..._CA-hooks: Set
	-fstack-use-cumulative-args to be off by default.
	* target.h (cumulative_args_t): Move declaration from here, to...
	* cumulative-args.h (cumulative_args_t): ...this new file. This is
	to permit backends to include the declaration of cumulative_args_t
	without dragging in circular dependencies.
	* function.c (assign_parm_find_entry_rtl): Provide
	cumulative_args_t to locate_and_pad_parm.
	(gimplify_parameters): Ditto.
	(locate_and_pad_parm): Conditionally call new hooks if we're
	invoked with -fstack-use-cumulative-args.
	* function.h: Include cumulative-args.h.
	(locate_and_pad_parm): Add cumulative_args_t parameter.
	* target.def (function_arg_boundary_ca): Add.
	(function_arg_round_boundary_ca): Ditto.
	* targhooks.c (default_function_arg_boundary_ca): Implement.
	(default_function_arg_round_boundary_ca): Ditto.
	* targhooks.h (default_function_arg_boundary_ca): Declare.
	(default_function_arg_round_boundary_ca): Ditto.
	* doc/invoke.texi (-fstack-use-cumulative-args): Document.
	* doc/tm.texi: Regenerate.
	* doc/tm.texi.in: Ditto.

3. Implement TARGET_..._CA target hooks for AArch64 Darwin

The AArch64 Darwin platform requires that named stack arguments are
passed naturally-aligned, while variadic stack arguments are passed on
word boundaries. Use the TARGET_FUNCTION_ARG_BOUNDARY_CA and
TARGET_FUNCTION_ARG_ROUND_BOUNDARY_CA target hooks to let the backend
correctly layout stack parameters.

gcc/ChangeLog:

	* config.gcc: Enable -fstack-use-cumulative-args by default if the
	host platform is MacOS 11.x or 12.x and we're on AArch64.

gcc/config/aarch64/ChangeLog:

	* aarch64-protos.h (aarch64_init_cumulative_incoming_args):
	Declare.
	* aarch64.c (aarch64_init_cumulative_args): Initialize
	`darwinpcs_n_named` (Total number of named parameters) and
	`darwinpcs_n_args_processed` (Total number of parameters we
	have processed, including variadic if any.)
	(aarch64_init_cumulative_incoming_args): Implement the
	INIT_CUMULATIVE_INCOMING_ARGS macro in order to capture
	information on the number of named parameters for the current
	function.
	(aarch64_function_arg_advance): Increment
	`darwinpcs_n_args_processed` each time we layout a function
	parameter.
	(aarch64_function_arg_boundary_ca): Implement
	TARGET_FUNCTION_ARG_BOUNDARY_CA and
	TARGET_FUNCTION_ARG_ROUND_BOUNDARY_CA to layout args based on
	whether we're a named parameter or not.
	(aarch64_function_arg_round_boundary_ca): Ditto.
	(TARGET_FUNCTION_ARG_BOUNDARY_CA): Define.
	(TARGET_FUNCTION_ARG_ROUND_BOUNDARY_CA): Ditto.
	* aarch64.h (CUMULATIVE_ARGS): Add `darwinpcs_n_named` and
	`darwinpcs_n_args_processed`.
	(INIT_CUMULATIVE_INCOMING_ARGS): Define.

3. aarch64, Darwin: Rework varargs handling to use cumulative args.

Maybe incomplete.
Currently this builds the information twice once during arg layout and once
during the value lookup - and checks we get the same result - looking for any
asserts before we enable the simplified version.

Signed-off-by: Iain Sandoe <iain@sandoe.co.uk>

gcc/ChangeLog:

	* config.gcc:
	* config/aarch64/aarch64.c (aarch64_layout_arg):
	(aarch64_init_cumulative_args):
	(aarch64_function_arg_boundary_ca):
	(aarch64_function_arg_round_boundary_ca):
	(aarch64_setup_incoming_varargs):
	* config/aarch64/aarch64.h:
  • Loading branch information
iains committed Dec 3, 2022
1 parent f34d994 commit f7ef1c2
Show file tree
Hide file tree
Showing 21 changed files with 651 additions and 76 deletions.
6 changes: 5 additions & 1 deletion gcc/calls.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1367,7 +1367,8 @@ initialize_argument_information (int num_actuals ATTRIBUTE_UNUSED,
with those made by function.cc. */

/* See if this argument should be passed by invisible reference. */
function_arg_info arg (type, argpos < n_named_args);
function_arg_info arg (type, argpos < n_named_args,
argpos == n_named_args - 1);
if (pass_by_reference (args_so_far_pnt, arg))
{
const bool callee_copies
Expand Down Expand Up @@ -1540,6 +1541,7 @@ initialize_argument_information (int num_actuals ATTRIBUTE_UNUSED,
#endif
reg_parm_stack_space,
args[i].pass_on_stack ? 0 : args[i].partial,
args_so_far,
fndecl, args_size, &args[i].locate);
#ifdef BLOCK_REG_PADDING
else
Expand Down Expand Up @@ -4256,6 +4258,7 @@ emit_library_call_value_1 (int retval, rtx orgfun, rtx value,
argvec[count].reg != 0,
#endif
reg_parm_stack_space, 0,
args_so_far,
NULL_TREE, &args_size, &argvec[count].locate);

if (argvec[count].reg == 0 || argvec[count].partial != 0
Expand Down Expand Up @@ -4347,6 +4350,7 @@ emit_library_call_value_1 (int retval, rtx orgfun, rtx value,
argvec[count].reg != 0,
#endif
reg_parm_stack_space, argvec[count].partial,
args_so_far,
NULL_TREE, &args_size, &argvec[count].locate);
args_size.constant += argvec[count].locate.size.constant;
gcc_assert (!argvec[count].locate.size.var);
Expand Down
30 changes: 26 additions & 4 deletions gcc/calls.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,24 +35,43 @@ class function_arg_info
{
public:
function_arg_info ()
: type (NULL_TREE), mode (VOIDmode), named (false),
: type (NULL_TREE), mode (VOIDmode), named (false), last_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), pass_by_reference (false)
: type (NULL_TREE), mode (mode), named (named), last_named (false),
pass_by_reference (false)
{}

function_arg_info (machine_mode mode, bool named, bool last_named)
: type (NULL_TREE), mode (mode), named (named), last_named (last_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), last_named (false),
pass_by_reference (false)
{}

/* Initialize an unpromoted argument of type TYPE. */
function_arg_info (tree type, bool named, bool last_named)
: type (type), mode (TYPE_MODE (type)), named (named),
last_named (last_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), pass_by_reference (false)
: type (type), mode (mode), named (named), last_named (false),
pass_by_reference (false)
{}

/* Initialize an argument with explicit properties. */
function_arg_info (tree type, machine_mode mode, bool named, bool last_named)
: type (type), mode (mode), named (named), last_named (last_named),
pass_by_reference (false)
{}

/* Return true if the gimple-level type is an aggregate. */
Expand Down Expand Up @@ -105,6 +124,9 @@ class function_arg_info
"..."). See also TARGET_STRICT_ARGUMENT_NAMING. */
unsigned int named : 1;

/* True if this is the last named argument. */
unsigned int last_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;
Expand Down
4 changes: 4 additions & 0 deletions gcc/common.opt
Original file line number Diff line number Diff line change
Expand Up @@ -2790,6 +2790,10 @@ fstack-usage
Common RejectNegative Var(flag_stack_usage)
Output stack usage information on a per-function basis.

fstack-use-cumulative-args
Common RejectNegative Var(flag_stack_use_cumulative_args) Init(STACK_USE_CUMULATIVE_ARGS_INIT)
Use cumulative args-based stack layout hooks.

fstrength-reduce
Common Ignore
Does nothing. Preserved for backward compatibility.
Expand Down
11 changes: 10 additions & 1 deletion gcc/config.gcc
Original file line number Diff line number Diff line change
Expand Up @@ -1112,13 +1112,22 @@ case ${target} in
;;
esac

# Defaults that need fixing.
# Figure out if we need to enable -foff-stack-trampolines by default
case ${target} in
aarch64*-*-darwin2*)
# This only applies to arm64 Darwin variadic funtions.
tm_defines="$tm_defines STACK_USE_CUMULATIVE_ARGS_INIT=1"
# This is required; executable stack is forbidden.
tm_defines="$tm_defines OFF_STACK_TRAMPOLINES_INIT=1"
;;
*-*-darwin2*)
tm_defines="$tm_defines STACK_USE_CUMULATIVE_ARGS_INIT=0"
# Currently, we do this for macOS 11 and above.
tm_defines="$tm_defines OFF_STACK_TRAMPOLINES_INIT=1"
;;
*)
tm_defines="$tm_defines STACK_USE_CUMULATIVE_ARGS_INIT=0"
tm_defines="$tm_defines OFF_STACK_TRAMPOLINES_INIT=0"
;;
esac
Expand Down Expand Up @@ -1161,7 +1170,7 @@ aarch64*-*-elf | aarch64*-*-fuchsia* | aarch64*-*-rtems*)
done
TM_MULTILIB_CONFIG=`echo $TM_MULTILIB_CONFIG | sed 's/^,//'`
;;
aarch64-*-darwin* | arm64-*-darwin*)
aarch64-*-darwin* )
tm_file="${tm_file} aarch64/aarch64-errata.h"
tmake_file="${tmake_file} aarch64/t-aarch64 aarch64/t-aarch64-darwin"
tm_defines="${tm_defines} TARGET_DEFAULT_ASYNC_UNWIND_TABLES=1"
Expand Down
1 change: 1 addition & 0 deletions gcc/config/aarch64/aarch64-protos.h
Original file line number Diff line number Diff line change
Expand Up @@ -916,6 +916,7 @@ void aarch64_expand_vector_init (rtx, rtx);
void aarch64_sve_expand_vector_init (rtx, rtx);
void aarch64_init_cumulative_args (CUMULATIVE_ARGS *, const_tree, rtx,
const_tree, unsigned, bool = false);
void aarch64_init_cumulative_incoming_args (CUMULATIVE_ARGS *, const_tree, rtx);
void aarch64_init_expanders (void);
void aarch64_emit_call_insn (rtx);
void aarch64_register_pragmas (void);
Expand Down
Loading

0 comments on commit f7ef1c2

Please sign in to comment.