Skip to content

Commit

Permalink
Introduce TARGET_CLONES_ATTR_SEPARATOR for RISC-V
Browse files Browse the repository at this point in the history
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

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.
	* 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.
  • Loading branch information
cyyself committed Oct 30, 2024
1 parent a2cd5d1 commit a9dbca3
Show file tree
Hide file tree
Showing 5 changed files with 34 additions and 15 deletions.
17 changes: 10 additions & 7 deletions gcc/attribs.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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))
{
Expand All @@ -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++;
}

Expand All @@ -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;
}

Expand All @@ -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);
Expand Down
5 changes: 5 additions & 0 deletions gcc/config/riscv/riscv.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
4 changes: 4 additions & 0 deletions gcc/defaults.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
19 changes: 12 additions & 7 deletions gcc/multiple_target.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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.
Expand All @@ -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)
{
Expand Down Expand Up @@ -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. */
Expand Down
4 changes: 3 additions & 1 deletion gcc/tree.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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++;
}
Expand Down

0 comments on commit a9dbca3

Please sign in to comment.