diff options
author | jakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4> | 2016-11-18 22:21:31 +0000 |
---|---|---|
committer | jakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4> | 2016-11-18 22:21:31 +0000 |
commit | cb6c05f855c410696b3fdc075399b97534cc7c35 (patch) | |
tree | acf1794c26cb1e3b59a4151a8b8dcf6028251d3a | |
parent | e1c5261183f725d8ab3b0390110acc83f4e7231a (diff) | |
download | gcc-cb6c05f855c410696b3fdc075399b97534cc7c35.tar.gz |
PR middle-end/78419
* multiple_target.c (get_attr_len): Start with argnum and increment
argnum on every arg. Use strchr in a loop instead of counting commas
manually.
(get_attr_str): Increment argnum for every comma in the string.
(separate_attrs): Use for instead of while loop, simplify.
(expand_target_clones): Rename defenition argument to definition.
Free attrs and attr_str even when diagnosing errors. Temporarily
change input_location around targetm.target_option.valid_attribute_p
calls. Don't emit warning or errors if that function fails.
* gcc.target/i386/pr78419.c: New test.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@242608 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r-- | gcc/ChangeLog | 11 | ||||
-rw-r--r-- | gcc/multiple_target.c | 68 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 3 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/i386/pr78419.c | 23 |
4 files changed, 69 insertions, 36 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 9a793343da3..67938695608 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,16 @@ 2016-11-18 Jakub Jelinek <jakub@redhat.com> + PR middle-end/78419 + * multiple_target.c (get_attr_len): Start with argnum and increment + argnum on every arg. Use strchr in a loop instead of counting commas + manually. + (get_attr_str): Increment argnum for every comma in the string. + (separate_attrs): Use for instead of while loop, simplify. + (expand_target_clones): Rename defenition argument to definition. + Free attrs and attr_str even when diagnosing errors. Temporarily + change input_location around targetm.target_option.valid_attribute_p + calls. Don't emit warning or errors if that function fails. + * dwarf2out.c (size_of_discr_list): Fix typo in function comment. PR debug/78191 diff --git a/gcc/multiple_target.c b/gcc/multiple_target.c index 9848feaddb3..4ead0292138 100644 --- a/gcc/multiple_target.c +++ b/gcc/multiple_target.c @@ -101,22 +101,18 @@ get_attr_len (tree arglist) { tree arg; int str_len_sum = 0; - int argnum = 1; + int argnum = 0; for (arg = arglist; arg; arg = TREE_CHAIN (arg)) { - unsigned int i; const char *str = TREE_STRING_POINTER (TREE_VALUE (arg)); - int len = strlen (str); - + size_t len = strlen (str); str_len_sum += len + 1; - if (arg != arglist) + for (const char *p = strchr (str, ','); p; p = strchr (p + 1, ',')) argnum++; - for (i = 0; i < strlen (str); i++) - if (str[i] == ',') - argnum++; + argnum++; } - if (argnum == 1) + if (argnum <= 1) return -1; return str_len_sum; } @@ -134,8 +130,9 @@ get_attr_str (tree arglist, char *attr_str) for (arg = arglist; arg; arg = TREE_CHAIN (arg)) { 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, ',')) + argnum++; memcpy (attr_str + str_len_sum, str, len); attr_str[str_len_sum + len] = TREE_CHAIN (arg) ? ',' : '\0'; str_len_sum += len + 1; @@ -152,19 +149,16 @@ separate_attrs (char *attr_str, char **attrs) { int i = 0; bool has_default = false; - char *attr = strtok (attr_str, ","); - while (attr != NULL) + for (char *attr = strtok (attr_str, ","); + attr != NULL; attr = strtok (NULL, ",")) { if (strcmp (attr, "default") == 0) { has_default = true; - attr = strtok (NULL, ","); continue; } - attrs[i] = attr; - attr = strtok (NULL, ","); - i++; + attrs[i++] = attr; } if (!has_default) return -1; @@ -235,7 +229,7 @@ create_target_clone (cgraph_node *node, bool definition, char *name) create the appropriate clone for each valid target attribute. */ static bool -expand_target_clones (struct cgraph_node *node, bool defenition) +expand_target_clones (struct cgraph_node *node, bool definition) { int i; /* Parsing target attributes separated by comma. */ @@ -266,6 +260,8 @@ expand_target_clones (struct cgraph_node *node, bool defenition) { error_at (DECL_SOURCE_LOCATION (node->decl), "default target was not set"); + XDELETEVEC (attrs); + XDELETEVEC (attr_str); return false; } @@ -286,22 +282,24 @@ expand_target_clones (struct cgraph_node *node, bool defenition) create_new_asm_name (attr, suffix); /* Create new target clone. */ - cgraph_node *new_node = create_target_clone (node, defenition, suffix); + cgraph_node *new_node = create_target_clone (node, definition, suffix); XDELETEVEC (suffix); /* Set new attribute for the clone. */ tree attributes = make_attribute ("target", attr, DECL_ATTRIBUTES (new_node->decl)); DECL_ATTRIBUTES (new_node->decl) = attributes; + location_t saved_loc = input_location; + input_location = DECL_SOURCE_LOCATION (node->decl); if (!targetm.target_option.valid_attribute_p (new_node->decl, NULL, - TREE_VALUE (attributes), 0)) + TREE_VALUE (attributes), + 0)) { - warning_at (DECL_SOURCE_LOCATION (node->decl), 0, - "attribute(target_clones(\"%s\")) is not " - "valid for current target", attr); + input_location = saved_loc; continue; } + input_location = saved_loc; decl2_v = new_node->function_version (); if (decl2_v != NULL) continue; @@ -320,22 +318,20 @@ expand_target_clones (struct cgraph_node *node, bool defenition) DECL_FUNCTION_VERSIONED (new_node->decl) = 1; } - /* Setting new attribute to initial function. */ - tree attributes = make_attribute ("target", "default", - DECL_ATTRIBUTES (node->decl)); - DECL_ATTRIBUTES (node->decl) = attributes; - if (!targetm.target_option.valid_attribute_p (node->decl, NULL, - TREE_VALUE (attributes), 0)) - { - error_at (DECL_SOURCE_LOCATION (node->decl), - "attribute(target_clones(\"default\")) is not " - "valid for current target"); - return false; - } - XDELETEVEC (attrs); XDELETEVEC (attr_str); - return true; + + /* Setting new attribute to initial function. */ + tree attributes = make_attribute ("target", "default", + DECL_ATTRIBUTES (node->decl)); + DECL_ATTRIBUTES (node->decl) = attributes; + location_t saved_loc = input_location; + input_location = DECL_SOURCE_LOCATION (node->decl); + bool ret + = targetm.target_option.valid_attribute_p (node->decl, NULL, + TREE_VALUE (attributes), 0); + input_location = saved_loc; + return ret; } static bool target_clone_pass; diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index c94d808a1de..85bed9e2f45 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,5 +1,8 @@ 2016-11-18 Jakub Jelinek <jakub@redhat.com> + PR middle-end/78419 + * gcc.target/i386/pr78419.c: New test. + PR c++/77285 * g++.dg/tls/pr77285-1.C: New test. * g++.dg/tls/pr77285-2.C: New test. diff --git a/gcc/testsuite/gcc.target/i386/pr78419.c b/gcc/testsuite/gcc.target/i386/pr78419.c new file mode 100644 index 00000000000..1109193f72a --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr78419.c @@ -0,0 +1,23 @@ +/* PR middle-end/78419 */ +/* { dg-do compile } */ + +static double bar (double *__restrict, double *__restrict, int) +__attribute__ ((target_clones("avx,foo,avx2,avx512f,default"))); + +double +foo (double *__restrict a, double *__restrict b, int n) +{ + return bar (a,b,n); +} + +double +bar (double *__restrict a, double *__restrict b, int n) /* { dg-error "attribute\[^\n\r]*foo\[^\n\r]* is unknown" } */ +{ + double s; + int i; + s = 0.0; + for (i=0; i<n; i++) + s += a[i] + b[i]; + + return s; +} |