[PATCH 1/2] Add cumulative_args_t variants of TARGET_FUNCTION_ROUND_BOUNDARY and friends

Richard Biener richard.guenther@gmail.com
Mon Nov 15 07:11:30 GMT 2021


On Sat, Nov 13, 2021 at 10:43 AM Maxim Blinov <maxim.blinov@embecosm.com> wrote:
>
> 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.

Just two quick comments without looking at the patch.

Please do not introduce options in the user namespace -f... which are
for debugging only.  I think you should go without this part instead.

Second, you fail to motivate the change.  I cannot make sense of
"This enables the backend to make alignment decisions based on the
context of the whole function rather than individual parameters."

Richard.

>
> 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.
> ---
>  gcc/calls.c           |  3 +++
>  gcc/common.opt        |  4 ++++
>  gcc/config.gcc        |  7 +++++++
>  gcc/cumulative-args.h | 20 ++++++++++++++++++++
>  gcc/doc/invoke.texi   | 12 ++++++++++++
>  gcc/doc/tm.texi       | 20 ++++++++++++++++++++
>  gcc/doc/tm.texi.in    |  4 ++++
>  gcc/function.c        | 25 +++++++++++++++++++++----
>  gcc/function.h        |  2 ++
>  gcc/target.def        | 24 ++++++++++++++++++++++++
>  gcc/target.h          | 17 +----------------
>  gcc/targhooks.c       | 16 ++++++++++++++++
>  gcc/targhooks.h       |  6 ++++++
>  13 files changed, 140 insertions(+), 20 deletions(-)
>  create mode 100644 gcc/cumulative-args.h
>
> diff --git a/gcc/calls.c b/gcc/calls.c
> index 27b59f26ad3..cef612a6ef4 100644
> --- a/gcc/calls.c
> +++ b/gcc/calls.c
> @@ -1527,6 +1527,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
> @@ -4205,6 +4206,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
> @@ -4296,6 +4298,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);
> diff --git a/gcc/common.opt b/gcc/common.opt
> index de9b848eda5..982417c1e39 100644
> --- a/gcc/common.opt
> +++ b/gcc/common.opt
> @@ -2705,6 +2705,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.
> diff --git a/gcc/config.gcc b/gcc/config.gcc
> index edd12655c4a..046d691af56 100644
> --- a/gcc/config.gcc
> +++ b/gcc/config.gcc
> @@ -1070,6 +1070,13 @@ case ${target} in
>    ;;
>  esac
>
> +# Figure out if we need to enable -foff-stack-trampolines by default.
> +case ${target} in
> +*)
> +  tm_defines="$tm_defines STACK_USE_CUMULATIVE_ARGS_INIT=0"
> +  ;;
> +esac
> +
>  case ${target} in
>  aarch64*-*-elf | aarch64*-*-fuchsia* | aarch64*-*-rtems*)
>         tm_file="${tm_file} dbxelf.h elfos.h newlib-stdint.h"
> diff --git a/gcc/cumulative-args.h b/gcc/cumulative-args.h
> new file mode 100644
> index 00000000000..b60928e37f9
> --- /dev/null
> +++ b/gcc/cumulative-args.h
> @@ -0,0 +1,20 @@
> +#ifndef GCC_CUMULATIVE_ARGS_H
> +#define GCC_CUMULATIVE_ARGS_H
> +
> +#if CHECKING_P
> +
> +struct cumulative_args_t { void *magic; void *p; };
> +
> +#else /* !CHECKING_P */
> +
> +/* When using a GCC build compiler, we could use
> +   __attribute__((transparent_union)) to get cumulative_args_t function
> +   arguments passed like scalars where the ABI would mandate a less
> +   efficient way of argument passing otherwise.  However, that would come
> +   at the cost of less type-safe !CHECKING_P compilation.  */
> +
> +union cumulative_args_t { void *p; };
> +
> +#endif /* !CHECKING_P */
> +
> +#endif /* GCC_CUMULATIVE_ARGS_H */
> diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
> index 2aba4c70b44..7ffb2997c69 100644
> --- a/gcc/doc/invoke.texi
> +++ b/gcc/doc/invoke.texi
> @@ -670,6 +670,7 @@ Objective-C and Objective-C++ Dialects}.
>  -fverbose-asm  -fpack-struct[=@var{n}]  @gol
>  -fleading-underscore  -ftls-model=@var{model} @gol
>  -fstack-reuse=@var{reuse_level} @gol
> +-fstack-use-cumulative-args @gol
>  -ftrampolines  -ftrapv  -fwrapv @gol
>  -fvisibility=@r{[}default@r{|}internal@r{|}hidden@r{|}protected@r{]} @gol
>  -fstrict-volatile-bitfields  -fsync-libcalls}
> @@ -16625,6 +16626,17 @@ the behavior of older compilers in which temporaries' stack space is
>  not reused, the aggressive stack reuse can lead to runtime errors. This
>  option is used to control the temporary stack reuse optimization.
>
> +@item -fstack-use-cumulative-args
> +@opindex fstack_use_cumulative_args
> +This option instructs the compiler to use the
> +@code{cumulative_args_t}-based stack layout target hooks,
> +@code{TARGET_FUNCTION_ARG_BOUNDARY_CA} and
> +@code{TARGET_FUNCTION_ARG_ROUND_BOUNDARY_CA}. If a given target does
> +not define these hooks, the default behaviour is to fallback to using
> +the standard non-@code{_CA} variants instead. Certain targets (such as
> +AArch64 Darwin) require using the more advanced @code{_CA}-based
> +hooks: For these targets this option should be enabled by default.
> +
>  @item -ftrapv
>  @opindex ftrapv
>  This option generates traps for signed overflow on addition, subtraction,
> diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi
> index 78a1af1ad4d..261eaf46ef5 100644
> --- a/gcc/doc/tm.texi
> +++ b/gcc/doc/tm.texi
> @@ -4322,6 +4322,16 @@ with the specified mode and type.  The default hook returns
>  @code{PARM_BOUNDARY} for all arguments.
>  @end deftypefn
>
> +@deftypefn {Target Hook} {unsigned int} TARGET_FUNCTION_ARG_BOUNDARY_CA (machine_mode @var{mode}, const_tree @var{type}, cumulative_args_t @var{ca})
> +This is the @code{cumulative_args_t}-based version of
> +@code{TARGET_FUNCTION_ARG_BOUNDARY}. Define this hook if you need more
> +fine-grained control over argument alignment, e.g. depending on whether
> +it is a named argument or not, or any other criteria that you choose to
> +place in the @var{ca} structure.
> +
> +The default hook will call @code{TARGET_FUNCTION_ARG_BOUNDARY}.
> +@end deftypefn
> +
>  @deftypefn {Target Hook} {unsigned int} TARGET_FUNCTION_ARG_ROUND_BOUNDARY (machine_mode @var{mode}, const_tree @var{type})
>  Normally, the size of an argument is rounded up to @code{PARM_BOUNDARY},
>  which is the default value for this hook.  You can define this hook to
> @@ -4329,6 +4339,16 @@ return a different value if an argument size must be rounded to a larger
>  value.
>  @end deftypefn
>
> +@deftypefn {Target Hook} {unsigned int} TARGET_FUNCTION_ARG_ROUND_BOUNDARY_CA (machine_mode @var{mode}, const_tree @var{type}, cumulative_args_t @var{ca})
> +This is the @code{cumulative_args_t}-based version of
> +@code{TARGET_FUNCTION_ARG_ROUND_BOUNDARY}. Define this hook if you need more
> +fine-grained control over argument size rounding, e.g. depending on whether
> +it is a named argument or not, or any other criteria that you choose to
> +place in the @var{ca} structure.
> +
> +The default hook will call @code{TARGET_FUNCTION_ARG_ROUND_BOUNDARY}.
> +@end deftypefn
> +
>  @defmac FUNCTION_ARG_REGNO_P (@var{regno})
>  A C expression that is nonzero if @var{regno} is the number of a hard
>  register in which function arguments are sometimes passed.  This does
> diff --git a/gcc/doc/tm.texi.in b/gcc/doc/tm.texi.in
> index 4401550989e..933644dfa86 100644
> --- a/gcc/doc/tm.texi.in
> +++ b/gcc/doc/tm.texi.in
> @@ -3330,8 +3330,12 @@ required.
>
>  @hook TARGET_FUNCTION_ARG_BOUNDARY
>
> +@hook TARGET_FUNCTION_ARG_BOUNDARY_CA
> +
>  @hook TARGET_FUNCTION_ARG_ROUND_BOUNDARY
>
> +@hook TARGET_FUNCTION_ARG_ROUND_BOUNDARY_CA
> +
>  @defmac FUNCTION_ARG_REGNO_P (@var{regno})
>  A C expression that is nonzero if @var{regno} is the number of a hard
>  register in which function arguments are sometimes passed.  This does
> diff --git a/gcc/function.c b/gcc/function.c
> index 61b3bd036b8..1ebf3e0ffe5 100644
> --- a/gcc/function.c
> +++ b/gcc/function.c
> @@ -2610,7 +2610,9 @@ assign_parm_find_entry_rtl (struct assign_parm_data_all *all,
>
>    locate_and_pad_parm (data->arg.mode, data->arg.type, in_regs,
>                        all->reg_parm_stack_space,
> -                      entry_parm ? data->partial : 0, current_function_decl,
> +                      entry_parm ? data->partial : 0,
> +                      all->args_so_far,
> +                      current_function_decl,
>                        &all->stack_args_size, &data->locate);
>
>    /* Update parm_stack_boundary if this parameter is passed in the
> @@ -4027,6 +4029,7 @@ gimplify_parameters (gimple_seq *cleanup)
>  void
>  locate_and_pad_parm (machine_mode passed_mode, tree type, int in_regs,
>                      int reg_parm_stack_space, int partial,
> +                    cumulative_args_t ca,
>                      tree fndecl ATTRIBUTE_UNUSED,
>                      struct args_size *initial_offset_ptr,
>                      struct locate_and_pad_arg_data *locate)
> @@ -4064,9 +4067,23 @@ locate_and_pad_parm (machine_mode passed_mode, tree type, int in_regs,
>               ? arg_size_in_bytes (type)
>               : size_int (GET_MODE_SIZE (passed_mode)));
>    where_pad = targetm.calls.function_arg_padding (passed_mode, type);
> -  boundary = targetm.calls.function_arg_boundary (passed_mode, type);
> -  round_boundary = targetm.calls.function_arg_round_boundary (passed_mode,
> -                                                             type);
> +
> +  if (flag_stack_use_cumulative_args)
> +    {
> +      boundary = targetm.calls.function_arg_boundary_ca (passed_mode,
> +                                                        type,
> +                                                        ca);
> +      round_boundary = targetm.calls.function_arg_round_boundary_ca
> +       (passed_mode, type, ca);
> +    }
> +  else
> +    {
> +      boundary = targetm.calls.function_arg_boundary (passed_mode,
> +                                                     type);
> +      round_boundary = targetm.calls.function_arg_round_boundary
> +       (passed_mode, type);
> +    }
> +
>    locate->where_pad = where_pad;
>
>    /* Alignment can't exceed MAX_SUPPORTED_STACK_ALIGNMENT.  */
> diff --git a/gcc/function.h b/gcc/function.h
> index 899430833ce..26f342caba3 100644
> --- a/gcc/function.h
> +++ b/gcc/function.h
> @@ -20,6 +20,7 @@ along with GCC; see the file COPYING3.  If not see
>  #ifndef GCC_FUNCTION_H
>  #define GCC_FUNCTION_H
>
> +#include "cumulative-args.h"
>
>  /* Stack of pending (incomplete) sequences saved by `start_sequence'.
>     Each element describes one pending sequence.
> @@ -661,6 +662,7 @@ extern int aggregate_value_p (const_tree, const_tree);
>  extern bool use_register_for_decl (const_tree);
>  extern gimple_seq gimplify_parameters (gimple_seq *);
>  extern void locate_and_pad_parm (machine_mode, tree, int, int, int,
> +                                cumulative_args_t,
>                                  tree, struct args_size *,
>                                  struct locate_and_pad_arg_data *);
>  extern void generate_setjmp_warnings (void);
> diff --git a/gcc/target.def b/gcc/target.def
> index 51ea167172b..bb56afab539 100644
> --- a/gcc/target.def
> +++ b/gcc/target.def
> @@ -4959,6 +4959,18 @@ with the specified mode and type.  The default hook returns\n\
>   unsigned int, (machine_mode mode, const_tree type),
>   default_function_arg_boundary)
>
> +DEFHOOK
> +(function_arg_boundary_ca,
> + "This is the @code{cumulative_args_t}-based version of\n\
> +@code{TARGET_FUNCTION_ARG_BOUNDARY}. Define this hook if you need more\n\
> +fine-grained control over argument alignment, e.g. depending on whether\n\
> +it is a named argument or not, or any other criteria that you choose to\n\
> +place in the @var{ca} structure.\n\
> +\n\
> +The default hook will call @code{TARGET_FUNCTION_ARG_BOUNDARY}.",
> + unsigned int, (machine_mode mode, const_tree type, cumulative_args_t ca),
> + default_function_arg_boundary_ca)
> +
>  DEFHOOK
>  (function_arg_round_boundary,
>   "Normally, the size of an argument is rounded up to @code{PARM_BOUNDARY},\n\
> @@ -4968,6 +4980,18 @@ value.",
>   unsigned int, (machine_mode mode, const_tree type),
>   default_function_arg_round_boundary)
>
> +DEFHOOK
> +(function_arg_round_boundary_ca,
> + "This is the @code{cumulative_args_t}-based version of\n\
> +@code{TARGET_FUNCTION_ARG_ROUND_BOUNDARY}. Define this hook if you need more\n\
> +fine-grained control over argument size rounding, e.g. depending on whether\n\
> +it is a named argument or not, or any other criteria that you choose to\n\
> +place in the @var{ca} structure.\n\
> +\n\
> +The default hook will call @code{TARGET_FUNCTION_ARG_ROUND_BOUNDARY}.",
> + unsigned int, (machine_mode mode, const_tree type, cumulative_args_t ca),
> + default_function_arg_round_boundary_ca)
> +
>  /* Return the diagnostic message string if function without a prototype
>     is not allowed for this 'val' argument; NULL otherwise. */
>  DEFHOOK
> diff --git a/gcc/target.h b/gcc/target.h
> index d8f45fb99c3..5b28ece7e1c 100644
> --- a/gcc/target.h
> +++ b/gcc/target.h
> @@ -51,22 +51,7 @@
>  #include "insn-codes.h"
>  #include "tm.h"
>  #include "hard-reg-set.h"
> -
> -#if CHECKING_P
> -
> -struct cumulative_args_t { void *magic; void *p; };
> -
> -#else /* !CHECKING_P */
> -
> -/* When using a GCC build compiler, we could use
> -   __attribute__((transparent_union)) to get cumulative_args_t function
> -   arguments passed like scalars where the ABI would mandate a less
> -   efficient way of argument passing otherwise.  However, that would come
> -   at the cost of less type-safe !CHECKING_P compilation.  */
> -
> -union cumulative_args_t { void *p; };
> -
> -#endif /* !CHECKING_P */
> +#include "cumulative-args.h"
>
>  /* Types of memory operation understood by the "by_pieces" infrastructure.
>     Used by the TARGET_USE_BY_PIECES_INFRASTRUCTURE_P target hook and
> diff --git a/gcc/targhooks.c b/gcc/targhooks.c
> index 6f071f80231..d83f362a5ae 100644
> --- a/gcc/targhooks.c
> +++ b/gcc/targhooks.c
> @@ -850,6 +850,14 @@ default_function_arg_boundary (machine_mode mode ATTRIBUTE_UNUSED,
>    return PARM_BOUNDARY;
>  }
>
> +unsigned int
> +default_function_arg_boundary_ca (machine_mode mode ATTRIBUTE_UNUSED,
> +                                 const_tree type ATTRIBUTE_UNUSED,
> +                                 cumulative_args_t ca ATTRIBUTE_UNUSED)
> +{
> +  return default_function_arg_boundary (mode, type);
> +}
> +
>  unsigned int
>  default_function_arg_round_boundary (machine_mode mode ATTRIBUTE_UNUSED,
>                                      const_tree type ATTRIBUTE_UNUSED)
> @@ -857,6 +865,14 @@ default_function_arg_round_boundary (machine_mode mode ATTRIBUTE_UNUSED,
>    return PARM_BOUNDARY;
>  }
>
> +unsigned int
> +default_function_arg_round_boundary_ca (machine_mode mode ATTRIBUTE_UNUSED,
> +                                       const_tree type ATTRIBUTE_UNUSED,
> +                                       cumulative_args_t ca ATTRIBUTE_UNUSED)
> +{
> +  return default_function_arg_round_boundary (mode, type);
> +}
> +
>  void
>  hook_void_bitmap (bitmap regs ATTRIBUTE_UNUSED)
>  {
> diff --git a/gcc/targhooks.h b/gcc/targhooks.h
> index 11e9d7dd1a8..f33374ef073 100644
> --- a/gcc/targhooks.h
> +++ b/gcc/targhooks.h
> @@ -154,6 +154,12 @@ extern unsigned int default_function_arg_boundary (machine_mode,
>                                                    const_tree);
>  extern unsigned int default_function_arg_round_boundary (machine_mode,
>                                                          const_tree);
> +extern unsigned int default_function_arg_boundary_ca (machine_mode,
> +                                                     const_tree,
> +                                                     cumulative_args_t ca);
> +extern unsigned int default_function_arg_round_boundary_ca (machine_mode,
> +                                                           const_tree,
> +                                                           cumulative_args_t ca);
>  extern bool hook_bool_const_rtx_commutative_p (const_rtx, int);
>  extern rtx default_function_value (const_tree, const_tree, bool);
>  extern HARD_REG_SET default_zero_call_used_regs (HARD_REG_SET);
> --
> 2.30.1 (Apple Git-130)
>


More information about the Gcc-patches mailing list