@@ -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 */
@@ -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
@@ -180,7 +180,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
@@ -194,17 +194,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.
@@ -215,9 +219,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)
{
@@ -305,7 +310,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. */