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
This commit is contained in:
Martin Liska 2018-04-17 07:40:39 +02:00 committed by Martin Liska
parent 42c884b130
commit 646cf25275
6 changed files with 112 additions and 14 deletions

View File

@ -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>

View File

@ -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;
}

View File

@ -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

View File

@ -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 ()
{
}

View File

@ -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]; }

View File

@ -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();
}