This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [PATCH] Make redirection only for target_clones: V2 (PR ipa/85329).
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 <mliska@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 <mliska@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 <mliska@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