[v1,08/16] Add get_clone_versions function.

Message ID 20250203130421.2192732-10-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
  This is a reimplementation of get_target_clone_attr_len,
get_attr_str, and separate_attrs using string_slice and auto_vec to make
memory management and use simpler.

gcc/c-family/ChangeLog:

	* c-attribs.cc (handle_target_clones_attribute): Change to use
	get_clone_versions.

gcc/ChangeLog:

	* tree.cc (get_clone_versions): New function.
	(get_clone_attr_versions): New function.
	* tree.h (get_clone_versions): New function.
	(get_clone_attr_versions): New function.
---
 gcc/c-family/c-attribs.cc |  2 +-
 gcc/tree.cc               | 40 +++++++++++++++++++++++++++++++++++++++
 gcc/tree.h                |  5 +++++
 3 files changed, 46 insertions(+), 1 deletion(-)
  

Comments

Richard Sandiford Feb. 3, 2025, 5:28 p.m. UTC | #1
Alfie Richards <alfie.richards@arm.com> writes:
> This is a reimplementation of get_target_clone_attr_len,
> get_attr_str, and separate_attrs using string_slice and auto_vec to make
> memory management and use simpler.
>
> gcc/c-family/ChangeLog:
>
> 	* c-attribs.cc (handle_target_clones_attribute): Change to use
> 	get_clone_versions.
>
> gcc/ChangeLog:
>
> 	* tree.cc (get_clone_versions): New function.
> 	(get_clone_attr_versions): New function.
> 	* tree.h (get_clone_versions): New function.
> 	(get_clone_attr_versions): New function.
> ---
>  gcc/c-family/c-attribs.cc |  2 +-
>  gcc/tree.cc               | 40 +++++++++++++++++++++++++++++++++++++++
>  gcc/tree.h                |  5 +++++
>  3 files changed, 46 insertions(+), 1 deletion(-)
>
> diff --git a/gcc/c-family/c-attribs.cc b/gcc/c-family/c-attribs.cc
> index f3181e7b57c..642d724f6c6 100644
> --- a/gcc/c-family/c-attribs.cc
> +++ b/gcc/c-family/c-attribs.cc
> @@ -6129,7 +6129,7 @@ handle_target_clones_attribute (tree *node, tree name, tree ARG_UNUSED (args),
>  	    }
>  	}
>  
> -      if (get_target_clone_attr_len (args) == -1)
> +      if (get_clone_attr_versions (args).length () == 1)
>  	{
>  	  warning (OPT_Wattributes,
>  		   "single %<target_clones%> attribute is ignored");
> diff --git a/gcc/tree.cc b/gcc/tree.cc
> index 05f679edc09..346522d01c0 100644
> --- a/gcc/tree.cc
> +++ b/gcc/tree.cc
> @@ -15299,6 +15299,46 @@ get_target_clone_attr_len (tree arglist)
>    return str_len_sum;
>  }
>  
> +/* Returns an auto_vec of string_slices containing the version strings from
> +   ARGLIST.  DEFAULT_COUNT is incremented for each default version found.  */
> +
> +auto_vec<string_slice>
> +get_clone_attr_versions (const tree arglist, int *default_count)
> +{
> +  gcc_assert (TREE_CODE (arglist) == TREE_LIST);
> +  auto_vec<string_slice> versions;
> +
> +  static const char separator_str[] = {TARGET_CLONES_ATTR_SEPARATOR, 0};
> +  string_slice separators = string_slice (separator_str);
> +
> +  for (tree arg = arglist; arg; arg = TREE_CHAIN (arg))
> +    {
> +      string_slice str = string_slice (TREE_STRING_POINTER (TREE_VALUE (arg)));
> +      for (string_slice attr = string_slice::strtok (&str, separators);
> +	   attr.is_valid (); attr = string_slice::strtok (&str, separators))
> +	{
> +	  attr = attr.strip ();
> +	  if (attr == string_slice ("default") && default_count)

Do we need the explicit constructor here?  It would be nice if
attr == "default" worked.

> +	    (*default_count)++;
> +	  versions.safe_push (attr);
> +	}
> +    }
> +  return versions;
> +}
> +
> +/* Returns an auto_vec of string_slices containing the version strings from
> +   the target_clone attribute from DECL.  DEFAULT_COUNT is incremented for each
> +   default version found.  */
> +auto_vec<string_slice>
> +get_clone_versions (const tree decl, int *default_count)
> +{
> +  tree attr = lookup_attribute ("target_clones", DECL_ATTRIBUTES (decl));
> +  if (!attr)
> +    return auto_vec<string_slice> ();
> +  tree arglist = TREE_VALUE (attr);
> +  return get_clone_attr_versions (arglist, default_count);
> +}
> +
>  void
>  tree_cc_finalize (void)
>  {
> diff --git a/gcc/tree.h b/gcc/tree.h
> index 21f3cd5525c..aea1cf078a0 100644
> --- a/gcc/tree.h
> +++ b/gcc/tree.h
> @@ -22,6 +22,7 @@ along with GCC; see the file COPYING3.  If not see
>  
>  #include "tree-core.h"
>  #include "options.h"
> +#include "vec.h"
>  
>  /* Convert a target-independent built-in function code to a combined_fn.  */
>  
> @@ -7035,5 +7036,9 @@ extern unsigned fndecl_dealloc_argno (tree);
>  extern tree get_attr_nonstring_decl (tree, tree * = NULL);
>  
>  extern int get_target_clone_attr_len (tree);
> +auto_vec<string_slice>
> +get_clone_versions (const tree, int * = NULL);
> +auto_vec<string_slice>
> +get_clone_attr_versions (const tree, int * = NULL);

Formatting nit, but: it's more usual to put declarations on a single line,
if they'd fit.

Otherwise it looks good, given that patch 13 removes the old functions.

Thanks,
Richard

>  
>  #endif  /* GCC_TREE_H  */
  

Patch

diff --git a/gcc/c-family/c-attribs.cc b/gcc/c-family/c-attribs.cc
index f3181e7b57c..642d724f6c6 100644
--- a/gcc/c-family/c-attribs.cc
+++ b/gcc/c-family/c-attribs.cc
@@ -6129,7 +6129,7 @@  handle_target_clones_attribute (tree *node, tree name, tree ARG_UNUSED (args),
 	    }
 	}
 
-      if (get_target_clone_attr_len (args) == -1)
+      if (get_clone_attr_versions (args).length () == 1)
 	{
 	  warning (OPT_Wattributes,
 		   "single %<target_clones%> attribute is ignored");
diff --git a/gcc/tree.cc b/gcc/tree.cc
index 05f679edc09..346522d01c0 100644
--- a/gcc/tree.cc
+++ b/gcc/tree.cc
@@ -15299,6 +15299,46 @@  get_target_clone_attr_len (tree arglist)
   return str_len_sum;
 }
 
+/* Returns an auto_vec of string_slices containing the version strings from
+   ARGLIST.  DEFAULT_COUNT is incremented for each default version found.  */
+
+auto_vec<string_slice>
+get_clone_attr_versions (const tree arglist, int *default_count)
+{
+  gcc_assert (TREE_CODE (arglist) == TREE_LIST);
+  auto_vec<string_slice> versions;
+
+  static const char separator_str[] = {TARGET_CLONES_ATTR_SEPARATOR, 0};
+  string_slice separators = string_slice (separator_str);
+
+  for (tree arg = arglist; arg; arg = TREE_CHAIN (arg))
+    {
+      string_slice str = string_slice (TREE_STRING_POINTER (TREE_VALUE (arg)));
+      for (string_slice attr = string_slice::strtok (&str, separators);
+	   attr.is_valid (); attr = string_slice::strtok (&str, separators))
+	{
+	  attr = attr.strip ();
+	  if (attr == string_slice ("default") && default_count)
+	    (*default_count)++;
+	  versions.safe_push (attr);
+	}
+    }
+  return versions;
+}
+
+/* Returns an auto_vec of string_slices containing the version strings from
+   the target_clone attribute from DECL.  DEFAULT_COUNT is incremented for each
+   default version found.  */
+auto_vec<string_slice>
+get_clone_versions (const tree decl, int *default_count)
+{
+  tree attr = lookup_attribute ("target_clones", DECL_ATTRIBUTES (decl));
+  if (!attr)
+    return auto_vec<string_slice> ();
+  tree arglist = TREE_VALUE (attr);
+  return get_clone_attr_versions (arglist, default_count);
+}
+
 void
 tree_cc_finalize (void)
 {
diff --git a/gcc/tree.h b/gcc/tree.h
index 21f3cd5525c..aea1cf078a0 100644
--- a/gcc/tree.h
+++ b/gcc/tree.h
@@ -22,6 +22,7 @@  along with GCC; see the file COPYING3.  If not see
 
 #include "tree-core.h"
 #include "options.h"
+#include "vec.h"
 
 /* Convert a target-independent built-in function code to a combined_fn.  */
 
@@ -7035,5 +7036,9 @@  extern unsigned fndecl_dealloc_argno (tree);
 extern tree get_attr_nonstring_decl (tree, tree * = NULL);
 
 extern int get_target_clone_attr_len (tree);
+auto_vec<string_slice>
+get_clone_versions (const tree, int * = NULL);
+auto_vec<string_slice>
+get_clone_attr_versions (const tree, int * = NULL);
 
 #endif  /* GCC_TREE_H  */