diff mbox series

[v2,1/4] aarch64: Refactor check_required_extensions

Message ID 6ba68e24-eb1f-a6cc-094f-2dbd24474818@e124511.cambridge.arm.com
State New
Headers show
Series aarch64: Fix intrinsic availability [PR112108] | expand

Commit Message

Andrew Carlotti Aug. 8, 2024, 2:29 p.m. UTC
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.

Comments

Richard Sandiford Aug. 8, 2024, 3:43 p.m. UTC | #1
Andrew Carlotti <andrew.carlotti@arm.com> 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 ();
>  }
diff mbox series

Patch

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.  */
+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)
+{
+  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;
+
+  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 ();
 }