Hi. I'm sending V3 which we did with Honza. It's similar to V2, but properly makes FUNCTION_DECL local for default implementation.
Patch can bootstrap on x86_64-linux-gnu and survives regression tests. Tests on ppc64le are running. Ready to be installed? Martin
>From 77b48cfad59dd24a5c068bfb32b1059535ae1f75 Mon Sep 17 00:00:00 2001 From: marxin <mli...@suse.cz> Date: Sat, 14 Apr 2018 09:55:35 +0200 Subject: [PATCH] Make redirection only for target_clones: V3 (PR ipa/85329). 2018-04-16 Martin Liska <mli...@suse.cz> * 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 emptry string. (expand_target_clones): Handle it. (ipa_target_clone): Make redirection just for target_clones functions. gcc/testsuite/ChangeLog: 2018-04-16 Martin Liska <mli...@suse.cz> * g++.dg/ext/pr85329-2.C: New test. * g++.dg/ext/pr85329.C: New test. * gcc.target/i386/mvc12.c: New test. --- gcc/multiple_target.c | 55 ++++++++++++++++++++++++++--------- gcc/testsuite/g++.dg/ext/pr85329-2.C | 22 ++++++++++++++ gcc/testsuite/g++.dg/ext/pr85329.C | 19 ++++++++++++ gcc/testsuite/gcc.target/i386/mvc12.c | 11 +++++++ 4 files changed, 93 insertions(+), 14 deletions(-) create mode 100644 gcc/testsuite/g++.dg/ext/pr85329-2.C create mode 100644 gcc/testsuite/g++.dg/ext/pr85329.C create mode 100644 gcc/testsuite/gcc.target/i386/mvc12.c 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; } diff --git a/gcc/testsuite/g++.dg/ext/pr85329-2.C b/gcc/testsuite/g++.dg/ext/pr85329-2.C new file mode 100644 index 00000000000..24622d404f7 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/pr85329-2.C @@ -0,0 +1,22 @@ +/* { dg-do compile { target i?86-*-* x86_64-*-* } } */ +/* { dg-require-ifunc "" } */ + +class b +{ +public: + __attribute__ ((target ("aes"))) b () {} + __attribute__ ((target ("default"))) b () {} +}; +class c +{ + b d; +}; +void +fn1 () +{ + c a; +} +__attribute__ ((target_clones ("sse", "default"))) void +e () +{ +} diff --git a/gcc/testsuite/g++.dg/ext/pr85329.C b/gcc/testsuite/g++.dg/ext/pr85329.C new file mode 100644 index 00000000000..fb77e42cd78 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/pr85329.C @@ -0,0 +1,19 @@ +/* { dg-do compile { target i?86-*-* x86_64-*-* } } */ +/* { dg-require-ifunc "" } */ + +struct a +{ + __attribute__((target_clones("sse", "default"))) void operator^=(a) {} +} * b; + +class c { +public: + a *d(); +}; + +class f { + void g(); + c e; +}; + +void f::g() { *e.d() ^= b[0]; } diff --git a/gcc/testsuite/gcc.target/i386/mvc12.c b/gcc/testsuite/gcc.target/i386/mvc12.c new file mode 100644 index 00000000000..f42ae8080e6 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/mvc12.c @@ -0,0 +1,11 @@ +/* { dg-do compile } */ +/* { dg-require-ifunc "" } */ + +__attribute__((target_clones("","arch=slm","arch=core-avx2", "default"))) +int foo (); /* { dg-error "an empty string cannot be in .target_clones. attribute" } */ + +int +bar () +{ + return foo(); +} -- 2.16.3