Andrew Carlotti <[email protected]> writes:
> Move SVE extension checking functionality to aarch64-builtins.cc, so
> that it can be shared by non-SVE intrinsics.
>
> gcc/ChangeLog:
>
> * config/aarch64/aarch64-sve-builtins.cc (check_builtin_call)
> (expand_builtin): Update calls to the below.
> (report_missing_extension, check_required_registers)
> (check_required_extensions): Move out of aarch64_sve namespace,
> rename, and move into...
> * config/aarch64/aarch64-builtins.cc (aarch64_report_missing_extension)
> (aarch64_check_non_general_registers)
> (aarch64_check_required_extensions) ...here.
> * config/aarch64/aarch64-protos.h (aarch64_check_required_extensions):
> Add prototype.
>
>
> diff --git a/gcc/config/aarch64/aarch64-builtins.cc
> b/gcc/config/aarch64/aarch64-builtins.cc
> index
> 30669f8aa1823b64689c67e306d38e234bd31698..d0fb8bc1d1fedb382cba1a1f09a9c3ce6757ee22
> 100644
> --- a/gcc/config/aarch64/aarch64-builtins.cc
> +++ b/gcc/config/aarch64/aarch64-builtins.cc
> @@ -2180,6 +2180,110 @@ aarch64_general_builtin_decl (unsigned code, bool)
> return aarch64_builtin_decls[code];
> }
>
> +/* True if we've already complained about attempts to use functions
> + when the required extension is disabled. */
> +static bool reported_missing_extension_p;
> +
> +/* True if we've already complained about attempts to use functions
> + which require registers that are missing. */
> +static bool reported_missing_registers_p;
> +
> +/* Report an error against LOCATION that the user has tried to use
> + function FNDECL when extension EXTENSION is disabled. */
> +static void
> +aarch64_report_missing_extension (location_t location, tree fndecl,
> + const char *extension)
> +{
> + /* Avoid reporting a slew of messages for a single oversight. */
> + if (reported_missing_extension_p)
> + return;
> +
> + error_at (location, "ACLE function %qD requires ISA extension %qs",
> + fndecl, extension);
> + inform (location, "you can enable %qs using the command-line"
> + " option %<-march%>, or by using the %<target%>"
> + " attribute or pragma", extension);
> + reported_missing_extension_p = true;
> +}
> +
> +/* Check whether non-general registers required by ACLE function fndecl are
> + * available. Report an error against LOCATION and return false if not. */
Nit: should be no leading "*" on this line.
> +static bool
> +aarch64_check_non_general_registers (location_t location, tree fndecl)
> +{
> + /* Avoid reporting a slew of messages for a single oversight. */
> + if (reported_missing_registers_p)
> + return false;
> +
> + if (TARGET_GENERAL_REGS_ONLY)
> + {
> + /* FP/SIMD/SVE registers are not usable when -mgeneral-regs-only option
> + is specified. */
> + error_at (location,
> + "ACLE function %qD is incompatible with the use of %qs",
> + fndecl, "-mgeneral-regs-only");
> + reported_missing_registers_p = true;
> + return false;
> + }
> +
> + return true;
> +}
> +
> +/* Check whether all the AARCH64_FL_* values in REQUIRED_EXTENSIONS are
> + enabled, given that those extensions are required for function FNDECL.
> + Report an error against LOCATION if not.
> + If REQUIRES_NON_GENERAL_REGISTERS is true, then also check whether
> + non-general registers are available. */
> +bool
> +aarch64_check_required_extensions (location_t location, tree fndecl,
> + aarch64_feature_flags required_extensions,
> + bool requires_non_general_registers)
Rather than pass requires_non_general_registers, could we just test
whether:
(get_flags_off (AARCH64_FL_FP) & required_extensions)
? (The call is a constexpr.) So:
> +{
> + auto missing_extensions = required_extensions & ~aarch64_asm_isa_flags;
> + if (missing_extensions == 0)
> + return requires_non_general_registers
> + ? aarch64_check_non_general_registers (location, fndecl)
> + : true;
return (!(get_flags_off (AARCH64_FL_FP) & required_extensions)
|| aarch64_check_non_general_registers (location, fndecl));
LGTM otherwise, but please give 24 hours for others to comment.
Thanks,
Richard
> +
> + if (missing_extensions & AARCH64_FL_SM_OFF)
> + {
> + error_at (location, "ACLE function %qD cannot be called when"
> + " SME streaming mode is enabled", fndecl);
> + return false;
> + }
> +
> + if (missing_extensions & AARCH64_FL_SM_ON)
> + {
> + error_at (location, "ACLE function %qD can only be called when"
> + " SME streaming mode is enabled", fndecl);
> + return false;
> + }
> +
> + if (missing_extensions & AARCH64_FL_ZA_ON)
> + {
> + error_at (location, "ACLE function %qD can only be called from"
> + " a function that has %qs state", fndecl, "za");
> + return false;
> + }
> +
> + static const struct {
> + aarch64_feature_flags flag;
> + const char *name;
> + } extensions[] = {
> +#define AARCH64_OPT_EXTENSION(EXT_NAME, IDENT, C, D, E, F) \
> + { AARCH64_FL_##IDENT, EXT_NAME },
> +#include "aarch64-option-extensions.def"
> + };
> +
> + for (unsigned int i = 0; i < ARRAY_SIZE (extensions); ++i)
> + if (missing_extensions & extensions[i].flag)
> + {
> + aarch64_report_missing_extension (location, fndecl, extensions[i].name);
> + return false;
> + }
> + gcc_unreachable ();
> +}
> +
> bool
> aarch64_general_check_builtin_call (location_t location, vec<location_t>,
> unsigned int code, tree fndecl,
> diff --git a/gcc/config/aarch64/aarch64-protos.h
> b/gcc/config/aarch64/aarch64-protos.h
> index
> f64afe2889018e1c4735a1677e6bf5febc4a7665..1a1057639b09daab6cb326490bbce1822ff0328f
> 100644
> --- a/gcc/config/aarch64/aarch64-protos.h
> +++ b/gcc/config/aarch64/aarch64-protos.h
> @@ -1008,6 +1008,8 @@ tree aarch64_general_builtin_rsqrt (unsigned int);
> void handle_arm_acle_h (void);
> void handle_arm_neon_h (void);
>
> +bool aarch64_check_required_extensions (location_t, tree,
> + aarch64_feature_flags, bool = true);
> bool aarch64_general_check_builtin_call (location_t, vec<location_t>,
> unsigned int, tree, unsigned int,
> tree *);
> diff --git a/gcc/config/aarch64/aarch64-sve-builtins.cc
> b/gcc/config/aarch64/aarch64-sve-builtins.cc
> index
> 0a560eaedca14832bfacef3225bd467691e16e99..5ca9ec32b691fd53733b01c52ad7a25cc5de9b93
> 100644
> --- a/gcc/config/aarch64/aarch64-sve-builtins.cc
> +++ b/gcc/config/aarch64/aarch64-sve-builtins.cc
> @@ -947,14 +947,6 @@ static hash_table<registered_function_hasher>
> *function_table;
> are IDENTIFIER_NODEs. */
> static GTY(()) hash_map<tree, registered_function *> *overload_names[2];
>
> -/* True if we've already complained about attempts to use functions
> - when the required extension is disabled. */
> -static bool reported_missing_extension_p;
> -
> -/* True if we've already complained about attempts to use functions
> - which require registers that are missing. */
> -static bool reported_missing_registers_p;
> -
> /* Record that TYPE is an ABI-defined SVE type that contains NUM_ZR SVE
> vectors
> and NUM_PR SVE predicates. MANGLED_NAME, if nonnull, is the ABI-defined
> mangling of the type. ACLE_NAME is the <arm_sve.h> name of the type. */
> @@ -1076,96 +1068,6 @@ lookup_fndecl (tree fndecl)
> return &(*registered_functions)[subcode]->instance;
> }
>
> -/* Report an error against LOCATION that the user has tried to use
> - function FNDECL when extension EXTENSION is disabled. */
> -static void
> -report_missing_extension (location_t location, tree fndecl,
> - const char *extension)
> -{
> - /* Avoid reporting a slew of messages for a single oversight. */
> - if (reported_missing_extension_p)
> - return;
> -
> - error_at (location, "ACLE function %qD requires ISA extension %qs",
> - fndecl, extension);
> - inform (location, "you can enable %qs using the command-line"
> - " option %<-march%>, or by using the %<target%>"
> - " attribute or pragma", extension);
> - reported_missing_extension_p = true;
> -}
> -
> -/* Check whether the registers required by SVE function fndecl are available.
> - Report an error against LOCATION and return false if not. */
> -static bool
> -check_required_registers (location_t location, tree fndecl)
> -{
> - /* Avoid reporting a slew of messages for a single oversight. */
> - if (reported_missing_registers_p)
> - return false;
> -
> - if (TARGET_GENERAL_REGS_ONLY)
> - {
> - /* SVE registers are not usable when -mgeneral-regs-only option
> - is specified. */
> - error_at (location,
> - "ACLE function %qD is incompatible with the use of %qs",
> - fndecl, "-mgeneral-regs-only");
> - reported_missing_registers_p = true;
> - return false;
> - }
> -
> - return true;
> -}
> -
> -/* Check whether all the AARCH64_FL_* values in REQUIRED_EXTENSIONS are
> - enabled, given that those extensions are required for function FNDECL.
> - Report an error against LOCATION if not. */
> -static bool
> -check_required_extensions (location_t location, tree fndecl,
> - aarch64_feature_flags required_extensions)
> -{
> - auto missing_extensions = required_extensions & ~aarch64_asm_isa_flags;
> - if (missing_extensions == 0)
> - return check_required_registers (location, fndecl);
> -
> - if (missing_extensions & AARCH64_FL_SM_OFF)
> - {
> - error_at (location, "ACLE function %qD cannot be called when"
> - " SME streaming mode is enabled", fndecl);
> - return false;
> - }
> -
> - if (missing_extensions & AARCH64_FL_SM_ON)
> - {
> - error_at (location, "ACLE function %qD can only be called when"
> - " SME streaming mode is enabled", fndecl);
> - return false;
> - }
> -
> - if (missing_extensions & AARCH64_FL_ZA_ON)
> - {
> - error_at (location, "ACLE function %qD can only be called from"
> - " a function that has %qs state", fndecl, "za");
> - return false;
> - }
> -
> - static const struct {
> - aarch64_feature_flags flag;
> - const char *name;
> - } extensions[] = {
> -#define AARCH64_OPT_EXTENSION(EXT_NAME, IDENT, C, D, E, F) \
> - { AARCH64_FL_##IDENT, EXT_NAME },
> -#include "aarch64-option-extensions.def"
> - };
> -
> - for (unsigned int i = 0; i < ARRAY_SIZE (extensions); ++i)
> - if (missing_extensions & extensions[i].flag)
> - {
> - report_missing_extension (location, fndecl, extensions[i].name);
> - return false;
> - }
> - gcc_unreachable ();
> -}
>
> /* Report that LOCATION has a call to FNDECL in which argument ARGNO
> was not an integer constant expression. ARGNO counts from zero. */
> @@ -4761,7 +4663,8 @@ check_builtin_call (location_t location,
> vec<location_t>, unsigned int code,
> tree fndecl, unsigned int nargs, tree *args)
> {
> const registered_function &rfn = *(*registered_functions)[code];
> - if (!check_required_extensions (location, rfn.decl,
> rfn.required_extensions))
> + if (!aarch64_check_required_extensions (location, rfn.decl,
> + rfn.required_extensions))
> return false;
> return function_checker (location, rfn.instance, fndecl,
> TREE_TYPE (rfn.decl), nargs, args).check ();
> @@ -4784,8 +4687,8 @@ rtx
> expand_builtin (unsigned int code, tree exp, rtx target)
> {
> registered_function &rfn = *(*registered_functions)[code];
> - if (!check_required_extensions (EXPR_LOCATION (exp), rfn.decl,
> - rfn.required_extensions))
> + if (!aarch64_check_required_extensions (EXPR_LOCATION (exp), rfn.decl,
> + rfn.required_extensions))
> return target;
> return function_expander (rfn.instance, rfn.decl, exp, target).expand ();
> }