diff options
author | Martin Liska <mliska@suse.cz> | 2018-04-17 07:40:39 +0200 |
---|---|---|
committer | Martin Liska <marxin@gcc.gnu.org> | 2018-04-17 05:40:39 +0000 |
commit | 646cf2527541fb8928deee0d7eda9ca75a591328 (patch) | |
tree | 90085775e60ac8e9e866e3202e20f96c3a272e8a /gcc/multiple_target.c | |
parent | 42c884b130825022f3ff3621b6393eefa4cf36f6 (diff) |
Make redirection only for target_clones: V3 (PR ipa/85329).
2018-04-17 Martin Liska <mliska@suse.cz>
PR ipa/85329
* multiple_target.c (create_dispatcher_calls): Set apostrophes
for target_clone error message. Make default implementation
clone to be a local declaration.
(separate_attrs): Add new argument and check for an empty
string.
(expand_target_clones): Handle it.
(ipa_target_clone): Make redirection just for target_clones
functions.
2018-04-17 Martin Liska <mliska@suse.cz>
PR ipa/85329
* g++.dg/ext/pr85329-2.C: New test.
* g++.dg/ext/pr85329.C: New test.
* gcc.target/i386/mvc12.c: New test.
From-SVN: r259428
Diffstat (limited to 'gcc/multiple_target.c')
-rw-r--r-- | gcc/multiple_target.c | 55 |
1 files changed, 41 insertions, 14 deletions
diff --git a/gcc/multiple_target.c b/gcc/multiple_target.c index b006a5ab6ec..a1fe09a5983 100644 --- a/gcc/multiple_target.c +++ b/gcc/multiple_target.c @@ -88,7 +88,7 @@ create_dispatcher_calls (struct cgraph_node *node) if (!idecl) { error_at (DECL_SOURCE_LOCATION (node->decl), - "default target_clones attribute was not set"); + "default %<target_clones%> attribute was not set"); return; } @@ -161,10 +161,25 @@ create_dispatcher_calls (struct cgraph_node *node) } } - TREE_PUBLIC (node->decl) = 0; symtab->change_decl_assembler_name (node->decl, clone_function_name (node->decl, "default")); + + /* FIXME: copy of cgraph_node::make_local that should be cleaned up + in next stage1. */ + node->make_decl_local (); + node->set_section (NULL); + node->set_comdat_group (NULL); + node->externally_visible = false; + node->forced_by_abi = false; + node->set_section (NULL); + node->unique_name = ((node->resolution == LDPR_PREVAILING_DEF_IRONLY + || node->resolution == LDPR_PREVAILING_DEF_IRONLY_EXP) + && !flag_incremental_link); + node->resolution = LDPR_PREVAILING_DEF_IRONLY; + + DECL_ARTIFICIAL (node->decl) = 1; + node->force_output = true; } /* Return length of attribute names string, @@ -216,26 +231,30 @@ get_attr_str (tree arglist, char *attr_str) } /* Return number of attributes separated by comma and put them into ARGS. - If there is no DEFAULT attribute return -1. */ + If there is no DEFAULT attribute return -1. If there is an empty + string in attribute return -2. */ static int -separate_attrs (char *attr_str, char **attrs) +separate_attrs (char *attr_str, char **attrs, int attrnum) { int i = 0; - bool has_default = false; + int default_count = 0; for (char *attr = strtok (attr_str, ","); attr != NULL; attr = strtok (NULL, ",")) { if (strcmp (attr, "default") == 0) { - has_default = true; + default_count++; continue; } attrs[i++] = attr; } - if (!has_default) + if (default_count == 0) return -1; + else if (i + default_count < attrnum) + return -2; + return i; } @@ -321,7 +340,7 @@ expand_target_clones (struct cgraph_node *node, bool definition) { warning_at (DECL_SOURCE_LOCATION (node->decl), 0, - "single target_clones attribute is ignored"); + "single %<target_clones%> attribute is ignored"); return false; } @@ -345,7 +364,7 @@ expand_target_clones (struct cgraph_node *node, bool definition) int attrnum = get_attr_str (arglist, attr_str); char **attrs = XNEWVEC (char *, attrnum); - attrnum = separate_attrs (attr_str, attrs); + attrnum = separate_attrs (attr_str, attrs, attrnum); if (attrnum == -1) { error_at (DECL_SOURCE_LOCATION (node->decl), @@ -354,6 +373,14 @@ expand_target_clones (struct cgraph_node *node, bool definition) XDELETEVEC (attr_str); return false; } + else if (attrnum == -2) + { + error_at (DECL_SOURCE_LOCATION (node->decl), + "an empty string cannot be in %<target_clones%> attribute"); + XDELETEVEC (attrs); + XDELETEVEC (attr_str); + return false; + } cgraph_function_version_info *decl1_v = NULL; cgraph_function_version_info *decl2_v = NULL; @@ -427,14 +454,14 @@ static unsigned int ipa_target_clone (void) { struct cgraph_node *node; + auto_vec<cgraph_node *> to_dispatch; - bool target_clone_pass = false; FOR_EACH_FUNCTION (node) - target_clone_pass |= expand_target_clones (node, node->definition); + if (expand_target_clones (node, node->definition)) + to_dispatch.safe_push (node); - if (target_clone_pass) - FOR_EACH_FUNCTION (node) - create_dispatcher_calls (node); + for (unsigned i = 0; i < to_dispatch.length (); i++) + create_dispatcher_calls (to_dispatch[i]); return 0; } |