]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
Introduce TARGET_CLONES_ATTR_SEPARATOR for RISC-V
authorYangyu Chen <cyy@cyyself.name>
Tue, 5 Nov 2024 03:21:22 +0000 (11:21 +0800)
committerKito Cheng <kito.cheng@sifive.com>
Wed, 13 Nov 2024 09:01:41 +0000 (17:01 +0800)
Some architectures may use ',' in the attribute string, but it is not
used as the separator for different targets. To avoid conflict, we
introduce a new macro TARGET_CLONES_ATTR_SEPARATOR to separate different
clones.

As an example, according to RISC-V C-API Specification [1], RISC-V allows
',' in the attribute string in the "arch=" option to specify one more
ISA extensions in the same target function, which conflict with the
default separator to separate different clones. This patch introduces
TARGET_CLONES_ATTR_SEPARATOR for RISC-V and choose '#' as the separator,
since '#' is not allowed in the target_clones option string.

[1] https://github.com/riscv-non-isa/riscv-c-api-doc/blob/c6c5d6d9cf96b342293315a5dff3d25e96ef8191/src/c-api.adoc#__attribute__targetattr-string

Signed-off-by: Yangyu Chen <cyy@cyyself.name>
gcc/ChangeLog:

* defaults.h (TARGET_CLONES_ATTR_SEPARATOR): Define new macro.
* multiple_target.cc (get_attr_str): Use
TARGET_CLONES_ATTR_SEPARATOR to separate attributes.
(separate_attrs): Likewise.
(expand_target_clones): Likewise.
* attribs.cc (attr_strcmp): Likewise.
(sorted_attr_string): Likewise.
* tree.cc (get_target_clone_attr_len): Likewise.
* config/riscv/riscv.h (TARGET_CLONES_ATTR_SEPARATOR): Define
TARGET_CLONES_ATTR_SEPARATOR for RISC-V.
* doc/tm.texi: Document TARGET_CLONES_ATTR_SEPARATOR.
* doc/tm.texi.in: Likewise.

gcc/attribs.cc
gcc/config/riscv/riscv.h
gcc/defaults.h
gcc/doc/tm.texi
gcc/doc/tm.texi.in
gcc/multiple_target.cc
gcc/tree.cc

index a290015fb4778d5d98770ea69978f6aeb65a05bd..1d6589835a1626fd64e860e2a73272951e326808 100644 (file)
@@ -1103,9 +1103,10 @@ attr_strcmp (const void *v1, const void *v2)
 }
 
 /* ARGLIST is the argument to target attribute.  This function tokenizes
-   the comma separated arguments, sorts them and returns a string which
-   is a unique identifier for the comma separated arguments.   It also
-   replaces non-identifier characters "=,-" with "_".  */
+   the TARGET_CLONES_ATTR_SEPARATOR separated arguments, sorts them and
+   returns a string which is a unique identifier for the
+   TARGET_CLONES_ATTR_SEPARATOR separated arguments.  It also replaces
+   non-identifier characters "=,-" with "_".  */
 
 char *
 sorted_attr_string (tree arglist)
@@ -1117,6 +1118,7 @@ sorted_attr_string (tree arglist)
   char *attr = NULL;
   unsigned int argnum = 1;
   unsigned int i;
+  static const char separator_str[] = { TARGET_CLONES_ATTR_SEPARATOR, 0 };
 
   for (arg = arglist; arg; arg = TREE_CHAIN (arg))
     {
@@ -1126,7 +1128,7 @@ sorted_attr_string (tree arglist)
       if (arg != arglist)
        argnum++;
       for (i = 0; i < strlen (str); i++)
-       if (str[i] == ',')
+       if (str[i] == TARGET_CLONES_ATTR_SEPARATOR)
          argnum++;
     }
 
@@ -1137,7 +1139,8 @@ sorted_attr_string (tree arglist)
       const char *str = TREE_STRING_POINTER (TREE_VALUE (arg));
       size_t len = strlen (str);
       memcpy (attr_str + str_len_sum, str, len);
-      attr_str[str_len_sum + len] = TREE_CHAIN (arg) ? ',' : '\0';
+      attr_str[str_len_sum + len]
+       = TREE_CHAIN (arg) ? TARGET_CLONES_ATTR_SEPARATOR : '\0';
       str_len_sum += len + 1;
     }
 
@@ -1152,12 +1155,12 @@ sorted_attr_string (tree arglist)
   args = XNEWVEC (char *, argnum);
 
   i = 0;
-  attr = strtok (attr_str, ",");
+  attr = strtok (attr_str, separator_str);
   while (attr != NULL)
     {
       args[i] = attr;
       i++;
-      attr = strtok (NULL, ",");
+      attr = strtok (NULL, separator_str);
     }
 
   qsort (args, argnum, sizeof (char *), attr_strcmp);
index ca1b8329cdc9b19914375bc446b7c29e4aa4005f..2ff9c1024f3ca71287e1151d05a130cb63c43fa2 100644 (file)
@@ -1298,4 +1298,9 @@ extern void riscv_remove_unneeded_save_restore_calls (void);
                STACK_BOUNDARY / BITS_PER_UNIT)            \
     : (crtl->outgoing_args_size + STACK_POINTER_OFFSET))
 
+/* According to the RISC-V C API, the arch string may contains ','. To avoid
+   the conflict with the default separator, we choose '#' as the separator for
+   the target attribute.  */
+#define TARGET_CLONES_ATTR_SEPARATOR '#'
+
 #endif /* ! GCC_RISCV_H */
index ac2d25852abb504f3483eb041dc4714fc41dcf49..918e3ec2f2447e5293102925ffe6583c4e417229 100644 (file)
@@ -874,6 +874,10 @@ see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
 #define TARGET_HAS_FMV_TARGET_ATTRIBUTE 1
 #endif
 
+/* Select a attribute separator for function multiversioning.  */
+#ifndef TARGET_CLONES_ATTR_SEPARATOR
+#define TARGET_CLONES_ATTR_SEPARATOR ','
+#endif
 
 /* Select a format to encode pointers in exception handling data.  We
    prefer those that result in fewer dynamic relocations.  Assume no
index 4deb3d2c283a2964972b94f434370a6f57ea816a..109e40384b68a1c2da41ab8158d3343dd17ee521 100644 (file)
@@ -10822,6 +10822,13 @@ the function declaration to hold a pointer to a target-specific
 @code{struct cl_target_option} structure.
 @end deftypefn
 
+@defmac TARGET_CLONES_ATTR_SEPARATOR
+Define this char-typed macro to select a character that separates each
+target specific attributes from the @code{attribute(target_clones("..."))}
+attribute string.  This macro should be carefully chosen to avoid conflicts
+with the target specific attributes.  The default value is @code{','}.
+@end defmac
+
 @deftypefn {Target Hook} void TARGET_OPTION_SAVE (struct cl_target_option *@var{ptr}, struct gcc_options *@var{opts}, struct gcc_options *@var{opts_set})
 This hook is called to save any additional target-specific information
 in the @code{struct cl_target_option} structure for function-specific
index 9f147ccb95cc6d4e79cdf5b265666ad502492145..93bcd747e374cd26071d22a003871a8f8af32b23 100644 (file)
@@ -7101,6 +7101,13 @@ on this implementation detail.
 
 @hook TARGET_OPTION_VALID_VERSION_ATTRIBUTE_P
 
+@defmac TARGET_CLONES_ATTR_SEPARATOR
+Define this char-typed macro to select a character that separates each
+target specific attributes from the @code{attribute(target_clones("..."))}
+attribute string.  This macro should be carefully chosen to avoid conflicts
+with the target specific attributes.  The default value is @code{','}.
+@end defmac
+
 @hook TARGET_OPTION_SAVE
 
 @hook TARGET_OPTION_RESTORE
index d2c9671fc1bd4767e6c3d4006796b7a2e5ded164..0cceba68ce9ba88be29d66bc87484c253c92700a 100644 (file)
@@ -181,7 +181,7 @@ create_dispatcher_calls (struct cgraph_node *node)
     }
 }
 
-/* Create string with attributes separated by comma.
+/* Create string with attributes separated by TARGET_CLONES_ATTR_SEPARATOR.
    Return number of attributes.  */
 
 static int
@@ -195,17 +195,21 @@ get_attr_str (tree arglist, char *attr_str)
     {
       const char *str = TREE_STRING_POINTER (TREE_VALUE (arg));
       size_t len = strlen (str);
-      for (const char *p = strchr (str, ','); p; p = strchr (p + 1, ','))
+      for (const char *p = strchr (str, TARGET_CLONES_ATTR_SEPARATOR);
+          p;
+          p = strchr (p + 1, TARGET_CLONES_ATTR_SEPARATOR))
        argnum++;
       memcpy (attr_str + str_len_sum, str, len);
-      attr_str[str_len_sum + len] = TREE_CHAIN (arg) ? ',' : '\0';
+      attr_str[str_len_sum + len]
+       = TREE_CHAIN (arg) ? TARGET_CLONES_ATTR_SEPARATOR : '\0';
       str_len_sum += len + 1;
       argnum++;
     }
   return argnum;
 }
 
-/* Return number of attributes separated by comma and put them into ARGS.
+/* Return number of attributes separated by TARGET_CLONES_ATTR_SEPARATOR
+   and put them into ARGS.
    If there is no DEFAULT attribute return -1.
    If there is an empty string in attribute return -2.
    If there are multiple DEFAULT attributes return -3.
@@ -216,9 +220,10 @@ separate_attrs (char *attr_str, char **attrs, int attrnum)
 {
   int i = 0;
   int default_count = 0;
+  static const char separator_str[] = { TARGET_CLONES_ATTR_SEPARATOR, 0 };
 
-  for (char *attr = strtok (attr_str, ",");
-       attr != NULL; attr = strtok (NULL, ","))
+  for (char *attr = strtok (attr_str, separator_str);
+       attr != NULL; attr = strtok (NULL, separator_str))
     {
       if (strcmp (attr, "default") == 0)
        {
@@ -306,7 +311,7 @@ static bool
 expand_target_clones (struct cgraph_node *node, bool definition)
 {
   int i;
-  /* Parsing target attributes separated by comma.  */
+  /* Parsing target attributes separated by TARGET_CLONES_ATTR_SEPARATOR.  */
   tree attr_target = lookup_attribute ("target_clones",
                                       DECL_ATTRIBUTES (node->decl));
   /* No targets specified.  */
index b4c059d3b0dbf0a22c77153890e7a1fe1c55fec5..113a669128bb851abf8da19331736df73092a7bd 100644 (file)
@@ -15229,7 +15229,9 @@ get_target_clone_attr_len (tree arglist)
       const char *str = TREE_STRING_POINTER (TREE_VALUE (arg));
       size_t len = strlen (str);
       str_len_sum += len + 1;
-      for (const char *p = strchr (str, ','); p; p = strchr (p + 1, ','))
+      for (const char *p = strchr (str, TARGET_CLONES_ATTR_SEPARATOR);
+          p;
+          p = strchr (p + 1, TARGET_CLONES_ATTR_SEPARATOR))
        argnum++;
       argnum++;
     }