[v1,05/16] Update is_function_default_version to work with target_version.

Message ID 20250203130421.2192732-7-alfie.richards@arm.com
State New
Headers
Series FMV refactor and ACLE compliance. |

Commit Message

Alfie Richards Feb. 3, 2025, 1:04 p.m. UTC
  Notably this respects target_version semantics where an unannotated
function can be the default version.

gcc/ChangeLog:

	* attribs.cc (is_function_default_version): Add target_version logic.
---
 gcc/attribs.cc | 28 ++++++++++++++++++++--------
 1 file changed, 20 insertions(+), 8 deletions(-)
  

Comments

Richard Sandiford Feb. 3, 2025, 4:36 p.m. UTC | #1
Alfie Richards <alfie.richards@arm.com> writes:
> Notably this respects target_version semantics where an unannotated
> function can be the default version.
>
> gcc/ChangeLog:
>
> 	* attribs.cc (is_function_default_version): Add target_version logic.

Generally looks good to me, but:

> ---
>  gcc/attribs.cc | 28 ++++++++++++++++++++--------
>  1 file changed, 20 insertions(+), 8 deletions(-)
>
> diff --git a/gcc/attribs.cc b/gcc/attribs.cc
> index 56dd18c2fa8..5cf45491ada 100644
> --- a/gcc/attribs.cc
> +++ b/gcc/attribs.cc
> @@ -1279,18 +1279,30 @@ make_dispatcher_decl (const tree decl)
>    return func_decl;
>  }
>  
> -/* Returns true if DECL is multi-versioned using the target attribute, and this
> -   is the default version.  This function can only be used for targets that do
> -   not support the "target_version" attribute.  */
> +/* Returns true if DECL a multiversioned default.
> +   With the target attribute semantics, returns true if the function is marked
> +   as default with the target version.
> +   With the target_version attribute semantics, returns true if the function
> +   is either not annotated, or annotated as default.  */
>  
>  bool
>  is_function_default_version (const tree decl)
>  {
> -  if (TREE_CODE (decl) != FUNCTION_DECL
> -      || !DECL_FUNCTION_VERSIONED (decl))
> -    return false;
> -  tree attr = lookup_attribute ("target", DECL_ATTRIBUTES (decl));
> -  gcc_assert (attr);

It might be worth either preserving the FUNCTION_DECL test or turning
it into an assert.  With that change...

> +  tree attr;
> +  if (TARGET_HAS_FMV_TARGET_ATTRIBUTE)
> +    {
> +      if (!DECL_FUNCTION_VERSIONED (decl))
> +	return false;
> +      attr = lookup_attribute ("target", DECL_ATTRIBUTES (decl));
> +      if (!attr)
> +	return false;

...I suppose we should also preserve the original assert here,
unless there's a specific reason not to.

Thanks,
Richard

> +    }
> +  else
> +    {
> +      attr = lookup_attribute ("target_version", DECL_ATTRIBUTES (decl));
> +      if (!attr)
> +	return true;
> +    }
>    attr = TREE_VALUE (TREE_VALUE (attr));
>    return (TREE_CODE (attr) == STRING_CST
>  	  && strcmp (TREE_STRING_POINTER (attr), "default") == 0);
  

Patch

diff --git a/gcc/attribs.cc b/gcc/attribs.cc
index 56dd18c2fa8..5cf45491ada 100644
--- a/gcc/attribs.cc
+++ b/gcc/attribs.cc
@@ -1279,18 +1279,30 @@  make_dispatcher_decl (const tree decl)
   return func_decl;
 }
 
-/* Returns true if DECL is multi-versioned using the target attribute, and this
-   is the default version.  This function can only be used for targets that do
-   not support the "target_version" attribute.  */
+/* Returns true if DECL a multiversioned default.
+   With the target attribute semantics, returns true if the function is marked
+   as default with the target version.
+   With the target_version attribute semantics, returns true if the function
+   is either not annotated, or annotated as default.  */
 
 bool
 is_function_default_version (const tree decl)
 {
-  if (TREE_CODE (decl) != FUNCTION_DECL
-      || !DECL_FUNCTION_VERSIONED (decl))
-    return false;
-  tree attr = lookup_attribute ("target", DECL_ATTRIBUTES (decl));
-  gcc_assert (attr);
+  tree attr;
+  if (TARGET_HAS_FMV_TARGET_ATTRIBUTE)
+    {
+      if (!DECL_FUNCTION_VERSIONED (decl))
+	return false;
+      attr = lookup_attribute ("target", DECL_ATTRIBUTES (decl));
+      if (!attr)
+	return false;
+    }
+  else
+    {
+      attr = lookup_attribute ("target_version", DECL_ATTRIBUTES (decl));
+      if (!attr)
+	return true;
+    }
   attr = TREE_VALUE (TREE_VALUE (attr));
   return (TREE_CODE (attr) == STRING_CST
 	  && strcmp (TREE_STRING_POINTER (attr), "default") == 0);