aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorMartin Liska <mliska@suse.cz>2018-04-17 07:40:39 +0200
committerMartin Liska <marxin@gcc.gnu.org>2018-04-17 05:40:39 +0000
commit646cf2527541fb8928deee0d7eda9ca75a591328 (patch)
tree90085775e60ac8e9e866e3202e20f96c3a272e8a /gcc
parent42c884b130825022f3ff3621b6393eefa4cf36f6 (diff)
downloadgcc-646cf2527541fb8928deee0d7eda9ca75a591328.zip
gcc-646cf2527541fb8928deee0d7eda9ca75a591328.tar.gz
gcc-646cf2527541fb8928deee0d7eda9ca75a591328.tar.bz2
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')
-rw-r--r--gcc/ChangeLog12
-rw-r--r--gcc/multiple_target.c55
-rw-r--r--gcc/testsuite/ChangeLog7
-rw-r--r--gcc/testsuite/g++.dg/ext/pr85329-2.C22
-rw-r--r--gcc/testsuite/g++.dg/ext/pr85329.C19
-rw-r--r--gcc/testsuite/gcc.target/i386/mvc12.c11
6 files changed, 112 insertions, 14 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index caef305..a96c8de 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,15 @@
+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-16 Cesar Philippidis <cesar@codesourcery.com>
Tom de Vries <tom@codesourcery.com>
diff --git a/gcc/multiple_target.c b/gcc/multiple_target.c
index b006a5a..a1fe09a 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/ChangeLog b/gcc/testsuite/ChangeLog
index 33258e6..a7dd355 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,10 @@
+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.
+
2018-04-16 Alexandre Oliva <aoliva@redhat.com>
PR c++/85039
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 0000000..24622d4
--- /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 0000000..fb77e42
--- /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 0000000..f42ae80
--- /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();
+}