* [PATCH] Multiversioning fixes (PR c++/55742)
@ 2013-01-18 20:22 Jakub Jelinek
2013-01-19 16:19 ` Jason Merrill
0 siblings, 1 reply; 13+ messages in thread
From: Jakub Jelinek @ 2013-01-18 20:22 UTC (permalink / raw)
To: Jason Merrill, Richard Henderson, Sriraman Tallam; +Cc: gcc-patches
Hi!
As discussed in the PR, this patch attempts to change multiversioning
so that backwards compatibility with the previous target attribute behavior
is preserved. In particular, e.g. for
void foo () __attribute__((target ("avx")));
void foo ()
{
}
the foo definition was just merged with the previous declaration and
used the avx target attribute. The patch introduces
target ("default")
which should be used if a default multiversion variant is desirable.
Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?
I've mentioned a bunch of other issues with multiversioning in the PR
(including missing documentation for the feature), hope those can be
resolved incrementally.
2013-01-18 Jakub Jelinek <jakub@redhat.com>
PR c++/55742
* config/i386/i386.c (ix86_valid_target_attribute_inner_p): Diagnose
invalid args instead of ICEing on it.
(ix86_valid_target_attribute_p): Allow target("default") attribute.
(sorted_attr_string): Formatting fix.
(ix86_mangle_function_version_assembler_n): Mangle target("default")
as if no target attribute is present.
(ix86_function_versions): Don't return true if one of the decls
doesn't have target attribute. If they don't and one of the decls
is DECL_FUNCTION_VERSIONED, report an error.
(is_function_default_version): Return true if there is
target("default") attribute rather than no target attribute at all.
* g++.dg/mv1.C: Adjust test.
* g++.dg/mv2.C: Likewise.
* g++.dg/mv5.C: Likewise.
* g++.dg/mv6.C: Likewise.
--- gcc/config/i386/i386.c.jj 2013-01-18 17:59:41.692943971 +0100
+++ gcc/config/i386/i386.c 2013-01-18 18:43:21.105326012 +0100
@@ -4223,7 +4223,10 @@ ix86_valid_target_attribute_inner_p (tre
}
else if (TREE_CODE (args) != STRING_CST)
- gcc_unreachable ();
+ {
+ error ("invalid %<target%> attribute value");
+ return false;
+ }
/* Handle multiple arguments separated by commas. */
next_optstr = ASTRDUP (TREE_STRING_POINTER (args));
@@ -4433,6 +4436,15 @@ ix86_valid_target_attribute_p (tree fnde
{
struct cl_target_option cur_target;
bool ret = true;
+
+ /* attribute((target("default"))) does nothing, beyond
+ affecting multi-versioning. */
+ if (TREE_VALUE (args)
+ && TREE_CODE (TREE_VALUE (args)) == STRING_CST
+ && TREE_CHAIN (args) == NULL_TREE
+ && strcmp (TREE_STRING_POINTER (TREE_VALUE (args)), "default") == 0)
+ return true;
+
tree old_optimize = build_optimization_node ();
tree new_target, new_optimize;
tree func_optimize = DECL_FUNCTION_SPECIFIC_OPTIMIZATION (fndecl);
@@ -28964,7 +28976,7 @@ sorted_attr_string (const char *str)
if (str[i] == ',')
argnum++;
- attr_str = (char *)xmalloc (strlen (str) + 1);
+ attr_str = (char *) xmalloc (strlen (str) + 1);
strcpy (attr_str, str);
/* Replace "=,-" with "_". */
@@ -29034,6 +29046,9 @@ ix86_mangle_function_version_assembler_n
version_string
= TREE_STRING_POINTER (TREE_VALUE (TREE_VALUE (version_attr)));
+ if (strcmp (version_string, "default") == 0)
+ return id;
+
attr_str = sorted_attr_string (version_string);
assembler_name = (char *) xmalloc (strlen (orig_name)
+ strlen (attr_str) + 2);
@@ -29058,7 +29073,7 @@ ix86_function_versions (tree fn1, tree f
const char *attr_str1, *attr_str2;
char *target1, *target2;
bool result;
-
+
if (TREE_CODE (fn1) != FUNCTION_DECL
|| TREE_CODE (fn2) != FUNCTION_DECL)
return false;
@@ -29070,12 +29085,35 @@ ix86_function_versions (tree fn1, tree f
if (attr1 == NULL_TREE && attr2 == NULL_TREE)
return false;
- /* If one function does not have a target attribute, these are versions. */
+ /* Diagnose missing target attribute if one of the decls is already
+ multi-versioned. */
if (attr1 == NULL_TREE || attr2 == NULL_TREE)
- return true;
+ {
+ if (DECL_FUNCTION_VERSIONED (fn1) || DECL_FUNCTION_VERSIONED (fn2))
+ {
+ if (attr2 != NULL_TREE)
+ {
+ tree tem = fn1;
+ fn1 = fn2;
+ fn2 = tem;
+ attr1 = attr2;
+ }
+ error_at (DECL_SOURCE_LOCATION (fn2),
+ "missing %<target%> attribute for multi-versioned %D",
+ fn2);
+ error_at (DECL_SOURCE_LOCATION (fn1),
+ "previous declaration of %D", fn1);
+ /* Prevent diagnosing of the same error multiple times. */
+ DECL_ATTRIBUTES (fn2)
+ = tree_cons (get_identifier ("target"),
+ copy_node (TREE_VALUE (attr1)),
+ DECL_ATTRIBUTES (fn2));
+ }
+ return false;
+ }
- attr_str1 = TREE_STRING_POINTER (TREE_VALUE (TREE_VALUE (attr1)));
- attr_str2 = TREE_STRING_POINTER (TREE_VALUE (TREE_VALUE (attr2)));
+ attr_str1 = TREE_STRING_POINTER (TREE_VALUE (TREE_VALUE (attr1)));
+ attr_str2 = TREE_STRING_POINTER (TREE_VALUE (TREE_VALUE (attr2)));
target1 = sorted_attr_string (attr_str1);
target2 = sorted_attr_string (attr_str2);
@@ -29196,9 +29234,14 @@ make_dispatcher_decl (const tree decl)
static bool
is_function_default_version (const tree decl)
{
- return (TREE_CODE (decl) == FUNCTION_DECL
- && DECL_FUNCTION_VERSIONED (decl)
- && lookup_attribute ("target", DECL_ATTRIBUTES (decl)) == NULL_TREE);
+ if (TREE_CODE (decl) != FUNCTION_DECL
+ || !DECL_FUNCTION_VERSIONED (decl))
+ return false;
+ tree attr = lookup_attribute ("target", DECL_ATTRIBUTES (decl));
+ gcc_assert (attr);
+ attr = TREE_VALUE (TREE_VALUE (attr));
+ return (TREE_CODE (attr) == STRING_CST
+ && strcmp (TREE_STRING_POINTER (attr), "default") == 0);
}
/* Make a dispatcher declaration for the multi-versioned function DECL.
--- gcc/testsuite/g++.dg/mv1.C.jj 2013-01-18 17:59:41.567944606 +0100
+++ gcc/testsuite/g++.dg/mv1.C 2013-01-18 18:31:36.223533556 +0100
@@ -6,7 +6,7 @@
#include <assert.h>
/* Default version. */
-int foo ();
+int foo () __attribute__ ((target("default")));
/* The other versions of foo. Mix up the ordering and
check if the dispatching does it in the order of priority. */
/* Check combination of target attributes. */
@@ -65,7 +65,8 @@ int main ()
return 0;
}
-int foo ()
+int __attribute__ ((target("default")))
+foo ()
{
return 0;
}
--- gcc/testsuite/g++.dg/mv2.C.jj 2013-01-18 17:59:41.456945279 +0100
+++ gcc/testsuite/g++.dg/mv2.C 2013-01-18 18:31:36.224533535 +0100
@@ -7,7 +7,7 @@
#include <assert.h>
/* Default version. */
-int foo ();
+int foo () __attribute__ ((target ("default")));
/* The dispatch checks should be in the exact reverse order of the
declarations below. */
int foo () __attribute__ ((target ("mmx")));
@@ -51,7 +51,7 @@ int main ()
return 0;
}
-int
+int __attribute__ ((target("default")))
foo ()
{
return 0;
--- gcc/testsuite/g++.dg/mv5.C.jj 2013-01-18 17:59:41.587944512 +0100
+++ gcc/testsuite/g++.dg/mv5.C 2013-01-18 18:31:36.224533535 +0100
@@ -7,7 +7,7 @@
/* Default version. */
-inline int
+inline int __attribute__ ((target ("default")))
foo ()
{
return 0;
--- gcc/testsuite/g++.dg/mv6.C.jj 2013-01-18 17:59:41.507944953 +0100
+++ gcc/testsuite/g++.dg/mv6.C 2013-01-18 18:31:36.224533535 +0100
@@ -8,6 +8,7 @@ class Foo
{
public:
/* Default version of foo. */
+ __attribute__ ((target("default")))
int foo ()
{
return 0;
Jakub
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH] Multiversioning fixes (PR c++/55742)
2013-01-18 20:22 [PATCH] Multiversioning fixes (PR c++/55742) Jakub Jelinek
@ 2013-01-19 16:19 ` Jason Merrill
2013-01-21 14:33 ` [PATCH] Multiversioning fixes (PR c++/55742, take 2) Jakub Jelinek
0 siblings, 1 reply; 13+ messages in thread
From: Jason Merrill @ 2013-01-19 16:19 UTC (permalink / raw)
To: Jakub Jelinek; +Cc: Richard Henderson, Sriraman Tallam, gcc-patches
On 01/18/2013 03:22 PM, Jakub Jelinek wrote:
> else if (TREE_CODE (args) != STRING_CST)
> - gcc_unreachable ();
> + {
> + error ("invalid %<target%> attribute value");
> + return false;
> + }
Maybe say that it needs to be a string?
We also need more tests, both for the example in the PR (and your
introductory text) and for error cases.
Thanks,
Jason
^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH] Multiversioning fixes (PR c++/55742, take 2)
2013-01-19 16:19 ` Jason Merrill
@ 2013-01-21 14:33 ` Jakub Jelinek
2013-01-30 13:55 ` Jason Merrill
0 siblings, 1 reply; 13+ messages in thread
From: Jakub Jelinek @ 2013-01-21 14:33 UTC (permalink / raw)
To: Jason Merrill, Richard Henderson; +Cc: Sriraman Tallam, gcc-patches
On Sat, Jan 19, 2013 at 11:19:04AM -0500, Jason Merrill wrote:
> On 01/18/2013 03:22 PM, Jakub Jelinek wrote:
> > else if (TREE_CODE (args) != STRING_CST)
> >- gcc_unreachable ();
> >+ {
> >+ error ("invalid %<target%> attribute value");
> >+ return false;
> >+ }
>
> Maybe say that it needs to be a string?
Fixed, using the wording of another attribute handler in c-common.c.
> We also need more tests, both for the example in the PR (and your
> introductory text) and for error cases.
Added a few ones, merged the patch with the incremental one, fixed handling
of target ("popcnt", "avx") as opposed to target ("popcnt,avx") that was
the only thing handled before by mv, fixed a bunch of memory leaks and
formatting issues, moved tests to g++.dg/ext/ and added a couple of new
ones.
Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?
I hope documentation (which is for multiversioning missing completely right
now) and further testcases can be added incrementally.
2013-01-21 Jakub Jelinek <jakub@redhat.com>
PR c++/55742
* config/i386/i386.c (ix86_valid_target_attribute_inner_p): Diagnose
invalid args instead of ICEing on it.
(ix86_valid_target_attribute_tree): Return error_mark_node if
ix86_valid_target_attribute_inner_p failed.
(ix86_valid_target_attribute_p): Return false only if
ix86_valid_target_attribute_tree returned error_mark_node. Allow
target("default") attribute.
(sorted_attr_string): Change argument from const char * to tree,
merge in all target attribute arguments rather than just one.
Formatting fix. Use XNEWVEC instead of xmalloc and XDELETEVEC
instead of free. Avoid using strcat.
(ix86_mangle_function_version_assembler_name): Mangle
target("default") as if no target attribute is present. Adjust
sorted_attr_string caller. Avoid leaking memory. Use XNEWVEC
instead of xmalloc and XDELETEVEC instead of free.
(ix86_function_versions): Don't return true if one of the decls
doesn't have target attribute. If they don't and one of the decls
is DECL_FUNCTION_VERSIONED, report an error. Adjust
sorted_attr_string caller. Use XDELETEVEC instead of free.
(ix86_supports_function_versions): Remove.
(make_name): Fix up formatting.
(make_dispatcher_decl): Remove resolver_name and its initialization.
Avoid leaking memory.
(is_function_default_version): Return true if there is
target("default") attribute rather than no target attribute at all.
(make_resolver_func): Avoid leaking memory.
(ix86_generate_version_dispatcher_body): Likewise.
(TARGET_OPTION_SUPPORTS_FUNCTION_VERSIONS): Remove.
* target.def (supports_function_versions): Remove.
* doc/tm.texi.in (SUPPORTS_FUNCTION_VERSIONS): Remove.
* doc/tm.texi: Regenerated.
* c-common.c (handle_target_attribute): Revert 2012-12-26 change.
* g++.dg/mv1.C: Moved to...
* g++.dg/ext/mv1.C: ... here. Adjust test.
* g++.dg/mv2.C: Moved to...
* g++.dg/ext/mv2.C: ... here. Adjust test.
* g++.dg/mv3.C: Moved to...
* g++.dg/ext/mv3.C: ... here.
* g++.dg/mv4.C: Moved to...
* g++.dg/ext/mv4.C: ... here.
* g++.dg/mv5.C: Moved to...
* g++.dg/ext/mv5.C: ... here. Adjust test.
* g++.dg/mv6.C: Moved to...
* g++.dg/ext/mv6.C: ... here. Adjust test.
* g++.dg/ext/mv7.C: New test.
* g++.dg/ext/mv8.C: New test.
* g++.dg/ext/mv9.C: New test.
* g++.dg/ext/mv10.C: New test.
* g++.dg/ext/mv11.C: New test.
--- gcc/config/i386/i386.c.jj 2013-01-21 10:57:08.325945469 +0100
+++ gcc/config/i386/i386.c 2013-01-21 12:02:59.384701394 +0100
@@ -4223,7 +4223,10 @@ ix86_valid_target_attribute_inner_p (tre
}
else if (TREE_CODE (args) != STRING_CST)
- gcc_unreachable ();
+ {
+ error ("attribute %<target%> argument not a string");
+ return false;
+ }
/* Handle multiple arguments separated by commas. */
next_optstr = ASTRDUP (TREE_STRING_POINTER (args));
@@ -4368,7 +4371,7 @@ ix86_valid_target_attribute_tree (tree a
/* Process each of the options on the chain. */
if (! ix86_valid_target_attribute_inner_p (args, option_strings,
&enum_opts_set))
- return NULL_TREE;
+ return error_mark_node;
/* If the changed options are different from the default, rerun
ix86_option_override_internal, and then save the options away.
@@ -4433,6 +4436,15 @@ ix86_valid_target_attribute_p (tree fnde
{
struct cl_target_option cur_target;
bool ret = true;
+
+ /* attribute((target("default"))) does nothing, beyond
+ affecting multi-versioning. */
+ if (TREE_VALUE (args)
+ && TREE_CODE (TREE_VALUE (args)) == STRING_CST
+ && TREE_CHAIN (args) == NULL_TREE
+ && strcmp (TREE_STRING_POINTER (TREE_VALUE (args)), "default") == 0)
+ return true;
+
tree old_optimize = build_optimization_node ();
tree new_target, new_optimize;
tree func_optimize = DECL_FUNCTION_SPECIFIC_OPTIMIZATION (fndecl);
@@ -4449,10 +4461,10 @@ ix86_valid_target_attribute_p (tree fnde
new_target = ix86_valid_target_attribute_tree (args);
new_optimize = build_optimization_node ();
- if (!new_target)
+ if (new_target == error_mark_node)
ret = false;
- else if (fndecl)
+ else if (fndecl && new_target)
{
DECL_FUNCTION_SPECIFIC_TARGET (fndecl) = new_target;
@@ -28946,26 +28958,44 @@ attr_strcmp (const void *v1, const void
return strcmp (c1, c2);
}
-/* STR is the argument to target attribute. This function tokenizes
+/* ARGLIST is the argument to target attribute. This function tokenizes
the comma separated arguments, sorts them and returns a string which
is a unique identifier for the comma separated arguments. It also
replaces non-identifier characters "=,-" with "_". */
static char *
-sorted_attr_string (const char *str)
+sorted_attr_string (tree arglist)
{
+ tree arg;
+ size_t str_len_sum = 0;
char **args = NULL;
char *attr_str, *ret_str;
char *attr = NULL;
unsigned int argnum = 1;
unsigned int i;
- for (i = 0; i < strlen (str); i++)
- if (str[i] == ',')
- argnum++;
-
- attr_str = (char *)xmalloc (strlen (str) + 1);
- strcpy (attr_str, str);
+ for (arg = arglist; arg; arg = TREE_CHAIN (arg))
+ {
+ const char *str = TREE_STRING_POINTER (TREE_VALUE (arg));
+ size_t len = strlen (str);
+ str_len_sum += len + 1;
+ if (arg != arglist)
+ argnum++;
+ for (i = 0; i < strlen (str); i++)
+ if (str[i] == ',')
+ argnum++;
+ }
+
+ attr_str = XNEWVEC (char, str_len_sum);
+ str_len_sum = 0;
+ for (arg = arglist; arg; arg = TREE_CHAIN (arg))
+ {
+ const char *str = TREE_STRING_POINTER (TREE_VALUE (arg));
+ size_t len = strlen (str);
+ memcpy (attr_str + str_len_sum, str, len);
+ attr_str[str_len_sum + len] = TREE_CHAIN (arg) ? ',' : '\0';
+ str_len_sum += len + 1;
+ }
/* Replace "=,-" with "_". */
for (i = 0; i < strlen (attr_str); i++)
@@ -28986,18 +29016,20 @@ sorted_attr_string (const char *str)
attr = strtok (NULL, ",");
}
- qsort (args, argnum, sizeof (char*), attr_strcmp);
+ qsort (args, argnum, sizeof (char *), attr_strcmp);
- ret_str = (char *)xmalloc (strlen (str) + 1);
- strcpy (ret_str, args[0]);
- for (i = 1; i < argnum; i++)
+ ret_str = XNEWVEC (char, str_len_sum);
+ str_len_sum = 0;
+ for (i = 0; i < argnum; i++)
{
- strcat (ret_str, "_");
- strcat (ret_str, args[i]);
+ size_t len = strlen (args[i]);
+ memcpy (ret_str + str_len_sum, args[i], len);
+ ret_str[str_len_sum + len] = i < argnum - 1 ? '_' : '\0';
+ str_len_sum += len + 1;
}
- free (args);
- free (attr_str);
+ XDELETEVEC (args);
+ XDELETEVEC (attr_str);
return ret_str;
}
@@ -29009,8 +29041,8 @@ static tree
ix86_mangle_function_version_assembler_name (tree decl, tree id)
{
tree version_attr;
- const char *orig_name, *version_string, *attr_str;
- char *assembler_name;
+ const char *orig_name, *version_string;
+ char *attr_str, *assembler_name;
if (DECL_DECLARED_INLINE_P (decl)
&& lookup_attribute ("gnu_inline",
@@ -29034,9 +29066,11 @@ ix86_mangle_function_version_assembler_n
version_string
= TREE_STRING_POINTER (TREE_VALUE (TREE_VALUE (version_attr)));
- attr_str = sorted_attr_string (version_string);
- assembler_name = (char *) xmalloc (strlen (orig_name)
- + strlen (attr_str) + 2);
+ if (strcmp (version_string, "default") == 0)
+ return id;
+
+ attr_str = sorted_attr_string (TREE_VALUE (version_attr));
+ assembler_name = XNEWVEC (char, strlen (orig_name) + strlen (attr_str) + 2);
sprintf (assembler_name, "%s.%s", orig_name, attr_str);
@@ -29044,7 +29078,10 @@ ix86_mangle_function_version_assembler_n
if (DECL_ASSEMBLER_NAME_SET_P (decl))
SET_DECL_RTL (decl, NULL);
- return get_identifier (assembler_name);
+ tree ret = get_identifier (assembler_name);
+ XDELETEVEC (attr_str);
+ XDELETEVEC (assembler_name);
+ return ret;
}
/* This function returns true if FN1 and FN2 are versions of the same function,
@@ -29055,10 +29092,9 @@ static bool
ix86_function_versions (tree fn1, tree fn2)
{
tree attr1, attr2;
- const char *attr_str1, *attr_str2;
char *target1, *target2;
bool result;
-
+
if (TREE_CODE (fn1) != FUNCTION_DECL
|| TREE_CODE (fn2) != FUNCTION_DECL)
return false;
@@ -29070,15 +29106,35 @@ ix86_function_versions (tree fn1, tree f
if (attr1 == NULL_TREE && attr2 == NULL_TREE)
return false;
- /* If one function does not have a target attribute, these are versions. */
+ /* Diagnose missing target attribute if one of the decls is already
+ multi-versioned. */
if (attr1 == NULL_TREE || attr2 == NULL_TREE)
- return true;
-
- attr_str1 = TREE_STRING_POINTER (TREE_VALUE (TREE_VALUE (attr1)));
- attr_str2 = TREE_STRING_POINTER (TREE_VALUE (TREE_VALUE (attr2)));
+ {
+ if (DECL_FUNCTION_VERSIONED (fn1) || DECL_FUNCTION_VERSIONED (fn2))
+ {
+ if (attr2 != NULL_TREE)
+ {
+ tree tem = fn1;
+ fn1 = fn2;
+ fn2 = tem;
+ attr1 = attr2;
+ }
+ error_at (DECL_SOURCE_LOCATION (fn2),
+ "missing %<target%> attribute for multi-versioned %D",
+ fn2);
+ error_at (DECL_SOURCE_LOCATION (fn1),
+ "previous declaration of %D", fn1);
+ /* Prevent diagnosing of the same error multiple times. */
+ DECL_ATTRIBUTES (fn2)
+ = tree_cons (get_identifier ("target"),
+ copy_node (TREE_VALUE (attr1)),
+ DECL_ATTRIBUTES (fn2));
+ }
+ return false;
+ }
- target1 = sorted_attr_string (attr_str1);
- target2 = sorted_attr_string (attr_str2);
+ target1 = sorted_attr_string (TREE_VALUE (attr1));
+ target2 = sorted_attr_string (TREE_VALUE (attr2));
/* The sorted target strings must be different for fn1 and fn2
to be versions. */
@@ -29087,20 +29143,12 @@ ix86_function_versions (tree fn1, tree f
else
result = true;
- free (target1);
- free (target2);
+ XDELETEVEC (target1);
+ XDELETEVEC (target2);
return result;
}
-/* This target supports function multiversioning. */
-
-static bool
-ix86_supports_function_versions (void)
-{
- return true;
-}
-
static tree
ix86_mangle_decl_assembler_name (tree decl, tree id)
{
@@ -29141,10 +29189,10 @@ make_name (tree decl, const char *suffix
/* Use '.' to concatenate names as it is demangler friendly. */
if (make_unique)
- snprintf (global_var_name, name_len, "%s.%s.%s", name,
- unique_name, suffix);
+ snprintf (global_var_name, name_len, "%s.%s.%s", name, unique_name,
+ suffix);
else
- snprintf (global_var_name, name_len, "%s.%s", name, suffix);
+ snprintf (global_var_name, name_len, "%s.%s", name, suffix);
return global_var_name;
}
@@ -29159,7 +29207,7 @@ static tree
make_dispatcher_decl (const tree decl)
{
tree func_decl;
- char *func_name, *resolver_name;
+ char *func_name;
tree fn_type, func_type;
bool is_uniq = false;
@@ -29167,14 +29215,13 @@ make_dispatcher_decl (const tree decl)
is_uniq = true;
func_name = make_name (decl, "ifunc", is_uniq);
- resolver_name = make_name (decl, "resolver", is_uniq);
- gcc_assert (resolver_name);
fn_type = TREE_TYPE (decl);
func_type = build_function_type (TREE_TYPE (fn_type),
TYPE_ARG_TYPES (fn_type));
func_decl = build_fn_decl (func_name, func_type);
+ XDELETEVEC (func_name);
TREE_USED (func_decl) = 1;
DECL_CONTEXT (func_decl) = NULL_TREE;
DECL_INITIAL (func_decl) = error_mark_node;
@@ -29196,9 +29243,14 @@ make_dispatcher_decl (const tree decl)
static bool
is_function_default_version (const tree decl)
{
- return (TREE_CODE (decl) == FUNCTION_DECL
- && DECL_FUNCTION_VERSIONED (decl)
- && lookup_attribute ("target", DECL_ATTRIBUTES (decl)) == NULL_TREE);
+ if (TREE_CODE (decl) != FUNCTION_DECL
+ || !DECL_FUNCTION_VERSIONED (decl))
+ return false;
+ tree attr = lookup_attribute ("target", DECL_ATTRIBUTES (decl));
+ gcc_assert (attr);
+ attr = TREE_VALUE (TREE_VALUE (attr));
+ return (TREE_CODE (attr) == STRING_CST
+ && strcmp (TREE_STRING_POINTER (attr), "default") == 0);
}
/* Make a dispatcher declaration for the multi-versioned function DECL.
@@ -29392,6 +29444,7 @@ make_resolver_func (const tree default_d
/* Create the alias for dispatch to resolver here. */
/*cgraph_create_function_alias (dispatch_decl, decl);*/
cgraph_same_body_alias (NULL, dispatch_decl, decl);
+ XDELETEVEC (resolver_name);
return decl;
}
@@ -29453,7 +29506,7 @@ ix86_generate_version_dispatcher_body (v
}
dispatch_function_versions (resolver_decl, &fn_ver_vec, &empty_bb);
-
+ fn_ver_vec.release ();
rebuild_cgraph_edges ();
pop_cfun ();
return resolver_decl;
@@ -42441,10 +42494,6 @@ ix86_memmodel_check (unsigned HOST_WIDE_
#undef TARGET_OPTION_FUNCTION_VERSIONS
#define TARGET_OPTION_FUNCTION_VERSIONS ix86_function_versions
-#undef TARGET_OPTION_SUPPORTS_FUNCTION_VERSIONS
-#define TARGET_OPTION_SUPPORTS_FUNCTION_VERSIONS \
- ix86_supports_function_versions
-
#undef TARGET_CAN_INLINE_P
#define TARGET_CAN_INLINE_P ix86_can_inline_p
--- gcc/target.def.jj 2013-01-11 09:02:32.000000000 +0100
+++ gcc/target.def 2013-01-21 11:25:29.145124702 +0100
@@ -2831,14 +2831,6 @@ DEFHOOK
bool, (tree decl1, tree decl2),
hook_bool_tree_tree_false)
-/* This function returns true if the target supports function
- multiversioning. */
-DEFHOOK
-(supports_function_versions,
- "",
- bool, (void),
- hook_bool_void_false)
-
/* Function to determine if one function can inline another function. */
#undef HOOK_PREFIX
#define HOOK_PREFIX "TARGET_"
--- gcc/doc/tm.texi.in.jj 2013-01-11 09:02:26.000000000 +0100
+++ gcc/doc/tm.texi.in 2013-01-21 11:25:57.789962584 +0100
@@ -9768,11 +9768,6 @@ different target specific attributes, th
different target machines.
@end deftypefn
-@hook TARGET_OPTION_SUPPORTS_FUNCTION_VERSIONS
-This target hook returns @code{true} if the target supports function
-multiversioning.
-@end deftypefn
-
@hook TARGET_CAN_INLINE_P
This target hook returns @code{false} if the @var{caller} function
cannot inline @var{callee}, based on target specific information. By
--- gcc/doc/tm.texi.jj 2013-01-11 09:02:26.000000000 +0100
+++ gcc/doc/tm.texi 2013-01-21 11:26:08.647897014 +0100
@@ -9907,11 +9907,6 @@ different target specific attributes, th
different target machines.
@end deftypefn
-@deftypefn {Target Hook} bool TARGET_OPTION_SUPPORTS_FUNCTION_VERSIONS (void)
-This target hook returns @code{true} if the target supports function
-multiversioning.
-@end deftypefn
-
@deftypefn {Target Hook} bool TARGET_CAN_INLINE_P (tree @var{caller}, tree @var{callee})
This target hook returns @code{false} if the @var{caller} function
cannot inline @var{callee}, based on target specific information. By
--- gcc/c-family/c-common.c.jj 2013-01-21 10:56:55.165014693 +0100
+++ gcc/c-family/c-common.c 2013-01-21 10:59:04.305285038 +0100
@@ -8759,12 +8759,8 @@ handle_target_attribute (tree *node, tre
warning (OPT_Wattributes, "%qE attribute ignored", name);
*no_add_attrs = true;
}
- /* Do not strip invalid target attributes for targets which support function
- multiversioning as the target string is used to determine versioned
- functions. */
else if (! targetm.target_option.valid_attribute_p (*node, name, args,
- flags)
- && ! targetm.target_option.supports_function_versions ())
+ flags))
*no_add_attrs = true;
return NULL_TREE;
--- gcc/testsuite/g++.dg/mv1.C.jj 2013-01-21 10:56:54.564017815 +0100
+++ gcc/testsuite/g++.dg/mv1.C 2013-01-21 11:35:42.260684508 +0100
@@ -1,130 +0,0 @@
-/* Test case to check if Multiversioning works. */
-/* { dg-do run { target i?86-*-* x86_64-*-* } } */
-/* { dg-require-ifunc "" } */
-/* { dg-options "-O2 -fPIC" } */
-
-#include <assert.h>
-
-/* Default version. */
-int foo ();
-/* The other versions of foo. Mix up the ordering and
- check if the dispatching does it in the order of priority. */
-/* Check combination of target attributes. */
-int foo () __attribute__ ((target("arch=corei7,popcnt")));
-/* The target operands in this declaration and the definition are re-ordered.
- This should still work. */
-int foo () __attribute__ ((target("ssse3,avx2")));
-
-/* Check for all target attributes for which dispatchers are available. */
-/* Check arch= */
-int foo () __attribute__((target("arch=core2")));
-int foo () __attribute__((target("arch=corei7")));
-int foo () __attribute__((target("arch=atom")));
-/* Check ISAs */
-int foo () __attribute__((target("avx")));
-int foo () __attribute__ ((target("arch=core2,sse4.2")));
-/* Check more arch=. */
-int foo () __attribute__((target("arch=amdfam10")));
-int foo () __attribute__((target("arch=bdver1")));
-int foo () __attribute__((target("arch=bdver2")));
-
-int (*p)() = &foo;
-int main ()
-{
- int val = foo ();
- assert (val == (*p)());
-
- /* Check in the exact same order in which the dispatching
- is expected to happen. */
- if (__builtin_cpu_is ("bdver1"))
- assert (val == 1);
- else if (__builtin_cpu_is ("bdver2"))
- assert (val == 2);
- else if (__builtin_cpu_supports ("avx2")
- && __builtin_cpu_supports ("ssse3"))
- assert (val == 3);
- else if (__builtin_cpu_supports ("avx"))
- assert (val == 4);
- else if (__builtin_cpu_is ("corei7")
- && __builtin_cpu_supports ("popcnt"))
- assert (val == 5);
- else if (__builtin_cpu_is ("corei7"))
- assert (val == 6);
- else if (__builtin_cpu_is ("amdfam10h"))
- assert (val == 7);
- else if (__builtin_cpu_is ("core2")
- && __builtin_cpu_supports ("sse4.2"))
- assert (val == 8);
- else if (__builtin_cpu_is ("core2"))
- assert (val == 9);
- else if (__builtin_cpu_is ("atom"))
- assert (val == 10);
- else
- assert (val == 0);
-
- return 0;
-}
-
-int foo ()
-{
- return 0;
-}
-
-int __attribute__ ((target("arch=corei7,popcnt")))
-foo ()
-{
- return 5;
-}
-int __attribute__ ((target("avx2,ssse3")))
-foo ()
-{
- return 3;
-}
-
-int __attribute__ ((target("arch=core2")))
-foo ()
-{
- return 9;
-}
-
-int __attribute__ ((target("arch=corei7")))
-foo ()
-{
- return 6;
-}
-
-int __attribute__ ((target("arch=atom")))
-foo ()
-{
- return 10;
-}
-
-int __attribute__ ((target("avx")))
-foo ()
-{
- return 4;
-}
-
-int __attribute__ ((target("arch=core2,sse4.2")))
-foo ()
-{
- return 8;
-}
-
-int __attribute__ ((target("arch=amdfam10")))
-foo ()
-{
- return 7;
-}
-
-int __attribute__ ((target("arch=bdver1")))
-foo ()
-{
- return 1;
-}
-
-int __attribute__ ((target("arch=bdver2")))
-foo ()
-{
- return 2;
-}
--- gcc/testsuite/g++.dg/ext/mv1.C.jj 2013-01-21 11:36:16.084491175 +0100
+++ gcc/testsuite/g++.dg/ext/mv1.C 2013-01-21 11:42:52.975315718 +0100
@@ -0,0 +1,132 @@
+/* Test case to check if Multiversioning works. */
+/* { dg-do run { target i?86-*-* x86_64-*-* } } */
+/* { dg-require-ifunc "" } */
+/* { dg-options "-O2 -fPIC" } */
+
+#include <assert.h>
+
+/* Default version. */
+int foo (); // Extra declaration that is merged with the second one.
+int foo () __attribute__ ((target("default")));
+/* The other versions of foo. Mix up the ordering and
+ check if the dispatching does it in the order of priority. */
+/* Check combination of target attributes. */
+int foo () __attribute__ ((target("arch=corei7,popcnt")));
+/* The target operands in this declaration and the definition are re-ordered.
+ This should still work. */
+int foo () __attribute__ ((target("ssse3,avx2")));
+
+/* Check for all target attributes for which dispatchers are available. */
+/* Check arch= */
+int foo () __attribute__((target("arch=core2")));
+int foo () __attribute__((target("arch=corei7")));
+int foo () __attribute__((target("arch=atom")));
+/* Check ISAs */
+int foo () __attribute__((target("avx")));
+int foo () __attribute__ ((target("arch=core2,sse4.2")));
+/* Check more arch=. */
+int foo () __attribute__((target("arch=amdfam10")));
+int foo () __attribute__((target("arch=bdver1")));
+int foo () __attribute__((target("arch=bdver2")));
+
+int (*p)() = &foo;
+int main ()
+{
+ int val = foo ();
+ assert (val == (*p)());
+
+ /* Check in the exact same order in which the dispatching
+ is expected to happen. */
+ if (__builtin_cpu_is ("bdver1"))
+ assert (val == 1);
+ else if (__builtin_cpu_is ("bdver2"))
+ assert (val == 2);
+ else if (__builtin_cpu_supports ("avx2")
+ && __builtin_cpu_supports ("ssse3"))
+ assert (val == 3);
+ else if (__builtin_cpu_supports ("avx"))
+ assert (val == 4);
+ else if (__builtin_cpu_is ("corei7")
+ && __builtin_cpu_supports ("popcnt"))
+ assert (val == 5);
+ else if (__builtin_cpu_is ("corei7"))
+ assert (val == 6);
+ else if (__builtin_cpu_is ("amdfam10h"))
+ assert (val == 7);
+ else if (__builtin_cpu_is ("core2")
+ && __builtin_cpu_supports ("sse4.2"))
+ assert (val == 8);
+ else if (__builtin_cpu_is ("core2"))
+ assert (val == 9);
+ else if (__builtin_cpu_is ("atom"))
+ assert (val == 10);
+ else
+ assert (val == 0);
+
+ return 0;
+}
+
+int __attribute__ ((target("default")))
+foo ()
+{
+ return 0;
+}
+
+int __attribute__ ((target("arch=corei7,popcnt")))
+foo ()
+{
+ return 5;
+}
+int __attribute__ ((target("avx2,ssse3")))
+foo ()
+{
+ return 3;
+}
+
+int __attribute__ ((target("arch=core2")))
+foo ()
+{
+ return 9;
+}
+
+int __attribute__ ((target("arch=corei7")))
+foo ()
+{
+ return 6;
+}
+
+int __attribute__ ((target("arch=atom")))
+foo ()
+{
+ return 10;
+}
+
+int __attribute__ ((target("avx")))
+foo ()
+{
+ return 4;
+}
+
+int __attribute__ ((target("arch=core2,sse4.2")))
+foo ()
+{
+ return 8;
+}
+
+int __attribute__ ((target("arch=amdfam10")))
+foo ()
+{
+ return 7;
+}
+
+int __attribute__ ((target("arch=bdver1")))
+foo ()
+{
+ return 1;
+}
+
+int __attribute__ ((target("arch=bdver2")))
+foo ()
+{
+ return 2;
+}
--- gcc/testsuite/g++.dg/mv2.C.jj 2013-01-21 10:56:54.465018354 +0100
+++ gcc/testsuite/g++.dg/mv2.C 2013-01-21 11:35:45.088666745 +0100
@@ -1,118 +0,0 @@
-/* Test case to check if Multiversioning chooses the correct
- dispatching order when versions are for various ISAs. */
-/* { dg-do run { target i?86-*-* x86_64-*-* } } */
-/* { dg-require-ifunc "" } */
-/* { dg-options "-O2" } */
-
-#include <assert.h>
-
-/* Default version. */
-int foo ();
-/* The dispatch checks should be in the exact reverse order of the
- declarations below. */
-int foo () __attribute__ ((target ("mmx")));
-int foo () __attribute__ ((target ("sse")));
-int foo () __attribute__ ((target ("sse2")));
-int foo () __attribute__ ((target ("sse3")));
-int foo () __attribute__ ((target ("ssse3")));
-int foo () __attribute__ ((target ("sse4.1")));
-int foo () __attribute__ ((target ("sse4.2")));
-int foo () __attribute__ ((target ("popcnt")));
-int foo () __attribute__ ((target ("avx")));
-int foo () __attribute__ ((target ("avx2")));
-
-int main ()
-{
- int val = foo ();
-
- if (__builtin_cpu_supports ("avx2"))
- assert (val == 1);
- else if (__builtin_cpu_supports ("avx"))
- assert (val == 2);
- else if (__builtin_cpu_supports ("popcnt"))
- assert (val == 3);
- else if (__builtin_cpu_supports ("sse4.2"))
- assert (val == 4);
- else if (__builtin_cpu_supports ("sse4.1"))
- assert (val == 5);
- else if (__builtin_cpu_supports ("ssse3"))
- assert (val == 6);
- else if (__builtin_cpu_supports ("sse3"))
- assert (val == 7);
- else if (__builtin_cpu_supports ("sse2"))
- assert (val == 8);
- else if (__builtin_cpu_supports ("sse"))
- assert (val == 9);
- else if (__builtin_cpu_supports ("mmx"))
- assert (val == 10);
- else
- assert (val == 0);
-
- return 0;
-}
-
-int
-foo ()
-{
- return 0;
-}
-
-int __attribute__ ((target("mmx")))
-foo ()
-{
- return 10;
-}
-
-int __attribute__ ((target("sse")))
-foo ()
-{
- return 9;
-}
-
-int __attribute__ ((target("sse2")))
-foo ()
-{
- return 8;
-}
-
-int __attribute__ ((target("sse3")))
-foo ()
-{
- return 7;
-}
-
-int __attribute__ ((target("ssse3")))
-foo ()
-{
- return 6;
-}
-
-int __attribute__ ((target("sse4.1")))
-foo ()
-{
- return 5;
-}
-
-int __attribute__ ((target("sse4.2")))
-foo ()
-{
- return 4;
-}
-
-int __attribute__ ((target("popcnt")))
-foo ()
-{
- return 3;
-}
-
-int __attribute__ ((target("avx")))
-foo ()
-{
- return 2;
-}
-
-int __attribute__ ((target("avx2")))
-foo ()
-{
- return 1;
-}
--- gcc/testsuite/g++.dg/ext/mv2.C.jj 2013-01-21 11:36:16.085491165 +0100
+++ gcc/testsuite/g++.dg/ext/mv2.C 2013-01-21 10:58:57.000000000 +0100
@@ -0,0 +1,118 @@
+/* Test case to check if Multiversioning chooses the correct
+ dispatching order when versions are for various ISAs. */
+/* { dg-do run { target i?86-*-* x86_64-*-* } } */
+/* { dg-require-ifunc "" } */
+/* { dg-options "-O2" } */
+
+#include <assert.h>
+
+/* Default version. */
+int foo () __attribute__ ((target ("default")));
+/* The dispatch checks should be in the exact reverse order of the
+ declarations below. */
+int foo () __attribute__ ((target ("mmx")));
+int foo () __attribute__ ((target ("sse")));
+int foo () __attribute__ ((target ("sse2")));
+int foo () __attribute__ ((target ("sse3")));
+int foo () __attribute__ ((target ("ssse3")));
+int foo () __attribute__ ((target ("sse4.1")));
+int foo () __attribute__ ((target ("sse4.2")));
+int foo () __attribute__ ((target ("popcnt")));
+int foo () __attribute__ ((target ("avx")));
+int foo () __attribute__ ((target ("avx2")));
+
+int main ()
+{
+ int val = foo ();
+
+ if (__builtin_cpu_supports ("avx2"))
+ assert (val == 1);
+ else if (__builtin_cpu_supports ("avx"))
+ assert (val == 2);
+ else if (__builtin_cpu_supports ("popcnt"))
+ assert (val == 3);
+ else if (__builtin_cpu_supports ("sse4.2"))
+ assert (val == 4);
+ else if (__builtin_cpu_supports ("sse4.1"))
+ assert (val == 5);
+ else if (__builtin_cpu_supports ("ssse3"))
+ assert (val == 6);
+ else if (__builtin_cpu_supports ("sse3"))
+ assert (val == 7);
+ else if (__builtin_cpu_supports ("sse2"))
+ assert (val == 8);
+ else if (__builtin_cpu_supports ("sse"))
+ assert (val == 9);
+ else if (__builtin_cpu_supports ("mmx"))
+ assert (val == 10);
+ else
+ assert (val == 0);
+
+ return 0;
+}
+
+int __attribute__ ((target("default")))
+foo ()
+{
+ return 0;
+}
+
+int __attribute__ ((target("mmx")))
+foo ()
+{
+ return 10;
+}
+
+int __attribute__ ((target("sse")))
+foo ()
+{
+ return 9;
+}
+
+int __attribute__ ((target("sse2")))
+foo ()
+{
+ return 8;
+}
+
+int __attribute__ ((target("sse3")))
+foo ()
+{
+ return 7;
+}
+
+int __attribute__ ((target("ssse3")))
+foo ()
+{
+ return 6;
+}
+
+int __attribute__ ((target("sse4.1")))
+foo ()
+{
+ return 5;
+}
+
+int __attribute__ ((target("sse4.2")))
+foo ()
+{
+ return 4;
+}
+
+int __attribute__ ((target("popcnt")))
+foo ()
+{
+ return 3;
+}
+
+int __attribute__ ((target("avx")))
+foo ()
+{
+ return 2;
+}
+
+int __attribute__ ((target("avx2")))
+foo ()
+{
+ return 1;
+}
--- gcc/testsuite/g++.dg/mv3.C.jj 2013-01-18 21:23:45.000000000 +0100
+++ gcc/testsuite/g++.dg/mv3.C 2013-01-21 11:35:52.400626435 +0100
@@ -1,36 +0,0 @@
-/* Test case to check if a call to a multiversioned function
- is replaced with a direct call to the particular version when
- the most specialized version's target attributes match the
- caller.
-
- In this program, foo is multiversioned but there is no default
- function. This is an error if the call has to go through a
- dispatcher. However, the call to foo in bar can be replaced
- with a direct call to the popcnt version of foo. Hence, this
- test should pass. */
-
-/* { dg-do run { target i?86-*-* x86_64-*-* } } */
-/* { dg-options "-O2" } */
-
-
-int __attribute__ ((target ("sse")))
-foo ()
-{
- return 1;
-}
-int __attribute__ ((target ("popcnt")))
-foo ()
-{
- return 0;
-}
-
-int __attribute__ ((target ("popcnt")))
-bar ()
-{
- return foo ();
-}
-
-int main ()
-{
- return bar ();
-}
--- gcc/testsuite/g++.dg/ext/mv3.C.jj 2013-01-21 11:36:16.086491156 +0100
+++ gcc/testsuite/g++.dg/ext/mv3.C 2013-01-18 21:23:45.000000000 +0100
@@ -0,0 +1,36 @@
+/* Test case to check if a call to a multiversioned function
+ is replaced with a direct call to the particular version when
+ the most specialized version's target attributes match the
+ caller.
+
+ In this program, foo is multiversioned but there is no default
+ function. This is an error if the call has to go through a
+ dispatcher. However, the call to foo in bar can be replaced
+ with a direct call to the popcnt version of foo. Hence, this
+ test should pass. */
+
+/* { dg-do run { target i?86-*-* x86_64-*-* } } */
+/* { dg-options "-O2" } */
+
+
+int __attribute__ ((target ("sse")))
+foo ()
+{
+ return 1;
+}
+int __attribute__ ((target ("popcnt")))
+foo ()
+{
+ return 0;
+}
+
+int __attribute__ ((target ("popcnt")))
+bar ()
+{
+ return foo ();
+}
+
+int main ()
+{
+ return bar ();
+}
--- gcc/testsuite/g++.dg/mv4.C.jj 2013-01-18 21:23:45.000000000 +0100
+++ gcc/testsuite/g++.dg/mv4.C 2013-01-21 11:35:54.308616223 +0100
@@ -1,24 +0,0 @@
-/* Test case to check if the compiler generates an error message
- when the default version of a multiversioned function is absent
- and its pointer is taken. */
-
-/* { dg-do compile { target i?86-*-* x86_64-*-* } } */
-/* { dg-require-ifunc "" } */
-/* { dg-options "-O2" } */
-
-int __attribute__ ((target ("sse")))
-foo ()
-{
- return 1;
-}
-int __attribute__ ((target ("popcnt")))
-foo ()
-{
- return 0;
-}
-
-int main ()
-{
- int (*p)() = &foo; /* { dg-error "use of multiversioned function without a default" {} } */
- return (*p)();
-}
--- gcc/testsuite/g++.dg/ext/mv4.C.jj 2013-01-21 11:36:16.088491133 +0100
+++ gcc/testsuite/g++.dg/ext/mv4.C 2013-01-18 21:23:45.000000000 +0100
@@ -0,0 +1,24 @@
+/* Test case to check if the compiler generates an error message
+ when the default version of a multiversioned function is absent
+ and its pointer is taken. */
+
+/* { dg-do compile { target i?86-*-* x86_64-*-* } } */
+/* { dg-require-ifunc "" } */
+/* { dg-options "-O2" } */
+
+int __attribute__ ((target ("sse")))
+foo ()
+{
+ return 1;
+}
+int __attribute__ ((target ("popcnt")))
+foo ()
+{
+ return 0;
+}
+
+int main ()
+{
+ int (*p)() = &foo; /* { dg-error "use of multiversioned function without a default" {} } */
+ return (*p)();
+}
--- gcc/testsuite/g++.dg/mv5.C.jj 2013-01-21 10:56:54.582017723 +0100
+++ gcc/testsuite/g++.dg/mv5.C 2013-01-21 11:35:56.027606185 +0100
@@ -1,25 +0,0 @@
-/* Test case to check if multiversioned functions are still generated if they are
- marked comdat with inline keyword. */
-
-/* { dg-do run { target i?86-*-* x86_64-*-* } } */
-/* { dg-require-ifunc "" } */
-/* { dg-options "-O2" } */
-
-
-/* Default version. */
-inline int
-foo ()
-{
- return 0;
-}
-
-inline int __attribute__ ((target ("popcnt")))
-foo ()
-{
- return 0;
-}
-
-int main ()
-{
- return foo ();
-}
--- gcc/testsuite/g++.dg/ext/mv5.C.jj 2013-01-21 11:36:16.089491123 +0100
+++ gcc/testsuite/g++.dg/ext/mv5.C 2013-01-21 10:58:57.000000000 +0100
@@ -0,0 +1,25 @@
+/* Test case to check if multiversioned functions are still generated if they are
+ marked comdat with inline keyword. */
+
+/* { dg-do run { target i?86-*-* x86_64-*-* } } */
+/* { dg-require-ifunc "" } */
+/* { dg-options "-O2" } */
+
+
+/* Default version. */
+inline int __attribute__ ((target ("default")))
+foo ()
+{
+ return 0;
+}
+
+inline int __attribute__ ((target ("popcnt")))
+foo ()
+{
+ return 0;
+}
+
+int main ()
+{
+ return foo ();
+}
--- gcc/testsuite/g++.dg/mv6.C.jj 2013-01-21 10:56:54.504018081 +0100
+++ gcc/testsuite/g++.dg/mv6.C 2013-01-21 11:35:57.514597697 +0100
@@ -1,27 +0,0 @@
-/* Test to check if member version multiversioning works correctly. */
-
-/* { dg-do run { target i?86-*-* x86_64-*-* } } */
-/* { dg-require-ifunc "" } */
-/* { dg-options "-march=x86-64" } */
-
-class Foo
-{
- public:
- /* Default version of foo. */
- int foo ()
- {
- return 0;
- }
- /* corei7 version of foo. */
- __attribute__ ((target("arch=corei7")))
- int foo ()
- {
- return 0;
- }
-};
-
-int main ()
-{
- Foo f;
- return f.foo ();
-}
--- gcc/testsuite/g++.dg/ext/mv6.C.jj 2013-01-21 11:36:16.090491117 +0100
+++ gcc/testsuite/g++.dg/ext/mv6.C 2013-01-21 10:58:57.000000000 +0100
@@ -0,0 +1,28 @@
+/* Test to check if member version multiversioning works correctly. */
+
+/* { dg-do run { target i?86-*-* x86_64-*-* } } */
+/* { dg-require-ifunc "" } */
+/* { dg-options "-march=x86-64" } */
+
+class Foo
+{
+ public:
+ /* Default version of foo. */
+ __attribute__ ((target("default")))
+ int foo ()
+ {
+ return 0;
+ }
+ /* corei7 version of foo. */
+ __attribute__ ((target("arch=corei7")))
+ int foo ()
+ {
+ return 0;
+ }
+};
+
+int main ()
+{
+ Foo f;
+ return f.foo ();
+}
--- gcc/testsuite/g++.dg/ext/mv7.C.jj 2013-01-21 11:39:21.789460493 +0100
+++ gcc/testsuite/g++.dg/ext/mv7.C 2013-01-21 11:45:05.098589632 +0100
@@ -0,0 +1,12 @@
+// { dg-do compile { target i?86-*-* x86_64-*-* } }
+// { dg-options "" }
+
+__attribute__((target ("default")))
+void foo (void) // { dg-error "previously defined here" }
+{
+}
+
+__attribute__((target (128)))
+void foo (void) // { dg-error "(not a string|redefinition)" }
+{
+}
--- gcc/testsuite/g++.dg/ext/mv8.C.jj 2013-01-21 11:41:17.147836101 +0100
+++ gcc/testsuite/g++.dg/ext/mv8.C 2013-01-21 11:45:13.493544256 +0100
@@ -0,0 +1,7 @@
+// { dg-do compile { target i?86-*-* x86_64-*-* } }
+// { dg-options "" }
+
+__attribute__((target (11,12)))
+void foo (void) // { dg-error "not a string" }
+{
+}
--- gcc/testsuite/g++.dg/ext/mv9.C.jj 2013-01-21 11:44:31.634774921 +0100
+++ gcc/testsuite/g++.dg/ext/mv9.C 2013-01-21 11:45:18.275516266 +0100
@@ -0,0 +1,9 @@
+// { dg-do compile { target i?86-*-* x86_64-*-* } }
+// { dg-options "" }
+
+void foo ();
+void foo () __attribute__((target ("sse4")));
+void foo () __attribute__((target ("default"))); // { dg-error "previous declaration" }
+void foo () // { dg-error "attribute for multi-versioned" }
+{
+}
--- gcc/testsuite/g++.dg/ext/mv10.C.jj 2013-01-21 12:12:29.354541630 +0100
+++ gcc/testsuite/g++.dg/ext/mv10.C 2013-01-21 12:12:56.207392886 +0100
@@ -0,0 +1,12 @@
+// { dg-do assemble { target i?86-*-* x86_64-*-* } }
+// { dg-options "" }
+
+__attribute__((target ("popcnt"), used))
+void foo (void)
+{
+}
+
+__attribute__((target ("popcnt","avx"), used))
+void foo (void)
+{
+}
--- gcc/testsuite/g++.dg/ext/mv11.C.jj 2013-01-21 12:16:26.381285535 +0100
+++ gcc/testsuite/g++.dg/ext/mv11.C 2013-01-21 12:17:33.380918996 +0100
@@ -0,0 +1,23 @@
+// { dg-do compile { target i?86-*-* x86_64-*-* } }
+// { dg-options "-msse2" }
+
+int foo () __attribute__ ((target("default")));
+int foo () __attribute__ ((target("sse2")));
+
+int
+main ()
+{
+ return foo ();
+}
+
+int __attribute__ ((target("default")))
+foo ()
+{
+ return 0;
+}
+
+int __attribute__ ((target("sse2")))
+foo ()
+{
+ return 0;
+}
Jakub
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH] Multiversioning fixes (PR c++/55742, take 2)
2013-01-21 14:33 ` [PATCH] Multiversioning fixes (PR c++/55742, take 2) Jakub Jelinek
@ 2013-01-30 13:55 ` Jason Merrill
2013-02-07 1:39 ` Sriraman Tallam
0 siblings, 1 reply; 13+ messages in thread
From: Jason Merrill @ 2013-01-30 13:55 UTC (permalink / raw)
To: Jakub Jelinek; +Cc: Richard Henderson, Sriraman Tallam, gcc-patches
OK. Sriraman, are you working on documentation and more tests?
Jason
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH] Multiversioning fixes (PR c++/55742, take 2)
2013-01-30 13:55 ` Jason Merrill
@ 2013-02-07 1:39 ` Sriraman Tallam
2013-02-07 14:30 ` Jason Merrill
0 siblings, 1 reply; 13+ messages in thread
From: Sriraman Tallam @ 2013-02-07 1:39 UTC (permalink / raw)
To: Jason Merrill; +Cc: Jakub Jelinek, Richard Henderson, GCC Patches
[-- Attachment #1: Type: text/plain, Size: 424 bytes --]
Hi,
I have attached a patch documenting Function Multiversioning and
added a few more tests. I have also updated the wiki
http://gcc.gnu.org/wiki/FunctionMultiVersioning. Please let me know if
there are any more tests you specifically want.
Please review.
Thanks
Sri
On Wed, Jan 30, 2013 at 5:55 AM, Jason Merrill <jason@redhat.com> wrote:
> OK. Sriraman, are you working on documentation and more tests?
>
> Jason
[-- Attachment #2: mv.txt --]
[-- Type: text/plain, Size: 6900 bytes --]
* doc/extend.texi: Document Function Multiversioning and "default"
parameter string to target attribute.
* g++.dg/ext/mv12.C: New test.
* g++.dg/ext/mv13.C: New test.
* g++.dg/ext/mv13.h: New file.
* g++.dg/ext/mv13-aux.C: New file.
* config/i386/i386.c (ix86_mangle_function_version_assembler_name): Change
comment.
Index: gcc/doc/extend.texi
===================================================================
--- gcc/doc/extend.texi (revision 195818)
+++ gcc/doc/extend.texi (working copy)
@@ -3655,6 +3655,11 @@ Enable/disable the generation of the advanced bit
@cindex @code{target("aes")} attribute
Enable/disable the generation of the AES instructions.
+@item default
+@cindex @code{target("default")} attribute
+@xref{Function Multiversioning}, where it is used to specify the
+default function version.
+
@item mmx
@itemx no-mmx
@cindex @code{target("mmx")} attribute
@@ -15215,6 +15220,7 @@ Predefined Macros,cpp,The GNU C Preprocessor}).
* Bound member functions:: You can extract a function pointer to the
method denoted by a @samp{->*} or @samp{.*} expression.
* C++ Attributes:: Variable, function, and type attributes for C++ only.
+* Function Multiversioning:: Declaring multiple function versions.
* Namespace Association:: Strong using-directives for namespace association.
* Type Traits:: Compiler support for type traits
* Java Exceptions:: Tweaking exception handling to work with Java.
@@ -15744,6 +15750,64 @@ interface table mechanism, instead of regular virt
See also @ref{Namespace Association}.
+@node Function Multiversioning
+@section Function Multiversioning
+@cindex function versions
+
+With the GNU C++ front end, for target i386, you may specify multiple
+versions of a function, where each function is specialized for a
+specific target feature. At runtime, the appropriate version of the
+function is automatically executed depending on the characteristics of
+the execution platform. Here is an example.
+
+@smallexample
+__attribute__ ((target ("default")))
+int foo ()
+@{
+ // The default version of foo.
+ return 0;
+@}
+
+__attribute__ ((target ("sse4.2")))
+int foo ()
+@{
+ // foo version for SSE4.2
+ return 1;
+@}
+
+__attribute__ ((target ("arch=atom")))
+int foo ()
+@{
+ // foo version for the Intel ATOM processor
+ return 2;
+@}
+
+__attribute__ ((target ("arch=amdfam10")))
+int foo ()
+@{
+ // foo version for the AMD Family 0x10 processors.
+ return 3;
+@}
+
+int main ()
+@{
+ int (*p)() = &foo;
+ assert ((*p) () == foo ());
+ return 0;
+@}
+@end smallexample
+
+In the above example, four versions of function foo are created. The
+first version of foo with the target attribute "default" is the default
+version. This version gets executed when no other target specific
+version qualifies for execution on a particular platform. A new version
+of foo is created by using the same function signature but with a
+different target string. Function foo is called or a pointer to it is
+taken just like a regular function. GCC takes care of doing the
+dispatching to call the right version at runtime. Refer to the
+@uref{http://gcc.gnu.org/wiki/FunctionMultiVersioning, GCC wiki on
+Function Multiversioning} for more details.
+
@node Namespace Association
@section Namespace Association
Index: gcc/testsuite/g++.dg/ext/mv13-aux.C
===================================================================
--- gcc/testsuite/g++.dg/ext/mv13-aux.C (revision 0)
+++ gcc/testsuite/g++.dg/ext/mv13-aux.C (revision 0)
@@ -0,0 +1,11 @@
+// Test case to check if multiversioning works as expected when the versions
+// are defined in different files. Auxiliary file for mv13.C.
+// { dg-do compile }
+
+#include "mv13.h"
+
+__attribute__ ((target ("sse4.2")))
+int foo ()
+{
+ return 1;
+}
Index: gcc/testsuite/g++.dg/ext/mv12.C
===================================================================
--- gcc/testsuite/g++.dg/ext/mv12.C (revision 0)
+++ gcc/testsuite/g++.dg/ext/mv12.C (revision 0)
@@ -0,0 +1,21 @@
+// Test to check if an error is generated when virtual functions
+// are multiversioned.
+
+// { dg-do compile { target i?86-*-* x86_64-*-* } }
+// { dg-options "" }
+class Foo
+{
+ public:
+ /* Default version of foo. */
+ __attribute__ ((target("default")))
+ virtual int foo () // { dg-error "Virtual function multiversioning not supported" }
+ {
+ return 0;
+ }
+ /* corei7 version of foo. */
+ __attribute__ ((target("arch=corei7")))
+ virtual int foo () // { dg-error "Virtual function multiversioning not supported" }
+ {
+ return 0;
+ }
+};
Index: gcc/testsuite/g++.dg/ext/mv13.C
===================================================================
--- gcc/testsuite/g++.dg/ext/mv13.C (revision 0)
+++ gcc/testsuite/g++.dg/ext/mv13.C (revision 0)
@@ -0,0 +1,22 @@
+// Test case to check if multiversioning works as expected when the versions
+// are defined in different files.
+
+// { dg-do run { target i?86-*-* x86_64-*-* } }
+// { dg-require-ifunc "" }
+// { dg-options "-O2" }
+// { dg-additional-sources "mv13-aux.C" }
+
+#include "mv13.h"
+
+int main ()
+{
+ if (__builtin_cpu_supports ("sse4.2"))
+ return foo () - 1;
+ return foo ();
+}
+
+__attribute__ ((target ("default")))
+int foo ()
+{
+ return 0;
+}
Index: gcc/testsuite/g++.dg/ext/mv13.h
===================================================================
--- gcc/testsuite/g++.dg/ext/mv13.h (revision 0)
+++ gcc/testsuite/g++.dg/ext/mv13.h (revision 0)
@@ -0,0 +1,6 @@
+// Header file used by mv13.C and mv13-aux.C.
+// { dg-do compile { target i?86-*-* x86_64-*-* } }
+// { dg-options "" }
+
+int foo () __attribute__ ((target ("default")));
+int foo () __attribute__ ((target ("sse4.2")));
Index: gcc/testsuite/g++.dg/ext/mv14.C
===================================================================
--- gcc/testsuite/g++.dg/ext/mv14.C (revision 0)
+++ gcc/testsuite/g++.dg/ext/mv14.C (revision 0)
@@ -0,0 +1,18 @@
+// Test case to check if multiversioning functions that are extern "C"
+// generates errors.
+
+// { dg-do compile { target i?86-*-* x86_64-*-* } }
+
+extern "C"
+__attribute__ ((target ("default")))
+int foo () // { dg-error "previously defined here" }
+{
+ return 0;
+}
+
+extern "C"
+__attribute__ ((target ("sse4.2")))
+int foo () // { dg-error "redefinition" }
+{
+ return 1;
+}
Index: gcc/config/i386/i386.c
===================================================================
--- gcc/config/i386/i386.c (revision 195818)
+++ gcc/config/i386/i386.c (working copy)
@@ -29065,7 +29065,7 @@ ix86_mangle_function_version_assembler_name (tree
if (DECL_VIRTUAL_P (decl)
|| DECL_VINDEX (decl))
error_at (DECL_SOURCE_LOCATION (decl),
- "Virtual function versioning not supported\n");
+ "Virtual function multiversioning not supported\n");
version_attr = lookup_attribute ("target", DECL_ATTRIBUTES (decl));
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH] Multiversioning fixes (PR c++/55742, take 2)
2013-02-07 1:39 ` Sriraman Tallam
@ 2013-02-07 14:30 ` Jason Merrill
2013-02-08 0:10 ` Sriraman Tallam
0 siblings, 1 reply; 13+ messages in thread
From: Jason Merrill @ 2013-02-07 14:30 UTC (permalink / raw)
To: Sriraman Tallam; +Cc: Jakub Jelinek, Richard Henderson, GCC Patches
On 02/06/2013 08:39 PM, Sriraman Tallam wrote:
> +// Test to check if an error is generated when virtual functions
> +// are multiversioned.
This seems like a TODO, rather than something to test for. I don't see
any reason why we couldn't support multiversioned virtual functions.
> error_at (DECL_SOURCE_LOCATION (decl),
> - "Virtual function versioning not supported\n");
> + "Virtual function multiversioning not supported\n");
And so this should be a sorry rather than an error.
Jason
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH] Multiversioning fixes (PR c++/55742, take 2)
2013-02-07 14:30 ` Jason Merrill
@ 2013-02-08 0:10 ` Sriraman Tallam
2013-02-11 18:35 ` Sriraman Tallam
2013-02-13 9:22 ` Andreas Schwab
0 siblings, 2 replies; 13+ messages in thread
From: Sriraman Tallam @ 2013-02-08 0:10 UTC (permalink / raw)
To: Jason Merrill; +Cc: Jakub Jelinek, Richard Henderson, GCC Patches
[-- Attachment #1: Type: text/plain, Size: 730 bytes --]
On Thu, Feb 7, 2013 at 6:29 AM, Jason Merrill <jason@redhat.com> wrote:
> On 02/06/2013 08:39 PM, Sriraman Tallam wrote:
>>
>> +// Test to check if an error is generated when virtual functions
>> +// are multiversioned.
>
>
> This seems like a TODO, rather than something to test for. I don't see any
> reason why we couldn't support multiversioned virtual functions.
>
>> error_at (DECL_SOURCE_LOCATION (decl),
>> - "Virtual function versioning not supported\n");
>> + "Virtual function multiversioning not supported\n");
>
>
> And so this should be a sorry rather than an error.
Attached a new patch with these changes. Also made more minor changes
to config/i386/i386.c.
Thanks
Sri
>
> Jason
>
[-- Attachment #2: mv.txt --]
[-- Type: text/plain, Size: 8214 bytes --]
* doc/extend.texi: Document Function Multiversioning and "default"
parameter string to target attribute.
* g++.dg/ext/mv12.C: New test.
* g++.dg/ext/mv12.h: New file.
* g++.dg/ext/mv12-aux.C: New file.
* g++.dg/ext/mv13.C: New test.
* config/i386/i386.c (get_builtin_code_for_version): Return 0 if
target attribute parameter is "default".
(ix86_compare_version_priority): Remove checks for target attribute.
(ix86_mangle_function_version_assembler_name): Change error to sorry.
Remove check for target attribute equal to NULL. Add assert.
(ix86_generate_version_dispatcher_body): Change error to sorry.
Index: gcc/doc/extend.texi
===================================================================
--- gcc/doc/extend.texi (revision 195818)
+++ gcc/doc/extend.texi (working copy)
@@ -3655,6 +3655,11 @@ Enable/disable the generation of the advanced bit
@cindex @code{target("aes")} attribute
Enable/disable the generation of the AES instructions.
+@item default
+@cindex @code{target("default")} attribute
+@xref{Function Multiversioning}, where it is used to specify the
+default function version.
+
@item mmx
@itemx no-mmx
@cindex @code{target("mmx")} attribute
@@ -15215,6 +15220,7 @@ Predefined Macros,cpp,The GNU C Preprocessor}).
* Bound member functions:: You can extract a function pointer to the
method denoted by a @samp{->*} or @samp{.*} expression.
* C++ Attributes:: Variable, function, and type attributes for C++ only.
+* Function Multiversioning:: Declaring multiple function versions.
* Namespace Association:: Strong using-directives for namespace association.
* Type Traits:: Compiler support for type traits
* Java Exceptions:: Tweaking exception handling to work with Java.
@@ -15744,6 +15750,64 @@ interface table mechanism, instead of regular virt
See also @ref{Namespace Association}.
+@node Function Multiversioning
+@section Function Multiversioning
+@cindex function versions
+
+With the GNU C++ front end, for target i386, you may specify multiple
+versions of a function, where each function is specialized for a
+specific target feature. At runtime, the appropriate version of the
+function is automatically executed depending on the characteristics of
+the execution platform. Here is an example.
+
+@smallexample
+__attribute__ ((target ("default")))
+int foo ()
+@{
+ // The default version of foo.
+ return 0;
+@}
+
+__attribute__ ((target ("sse4.2")))
+int foo ()
+@{
+ // foo version for SSE4.2
+ return 1;
+@}
+
+__attribute__ ((target ("arch=atom")))
+int foo ()
+@{
+ // foo version for the Intel ATOM processor
+ return 2;
+@}
+
+__attribute__ ((target ("arch=amdfam10")))
+int foo ()
+@{
+ // foo version for the AMD Family 0x10 processors.
+ return 3;
+@}
+
+int main ()
+@{
+ int (*p)() = &foo;
+ assert ((*p) () == foo ());
+ return 0;
+@}
+@end smallexample
+
+In the above example, four versions of function foo are created. The
+first version of foo with the target attribute "default" is the default
+version. This version gets executed when no other target specific
+version qualifies for execution on a particular platform. A new version
+of foo is created by using the same function signature but with a
+different target string. Function foo is called or a pointer to it is
+taken just like a regular function. GCC takes care of doing the
+dispatching to call the right version at runtime. Refer to the
+@uref{http://gcc.gnu.org/wiki/FunctionMultiVersioning, GCC wiki on
+Function Multiversioning} for more details.
+
@node Namespace Association
@section Namespace Association
Index: gcc/testsuite/g++.dg/ext/mv12-aux.C
===================================================================
--- gcc/testsuite/g++.dg/ext/mv12-aux.C (revision 0)
+++ gcc/testsuite/g++.dg/ext/mv12-aux.C (revision 0)
@@ -0,0 +1,11 @@
+// Test case to check if multiversioning works as expected when the versions
+// are defined in different files. Auxiliary file for mv12.C.
+// { dg-do compile }
+
+#include "mv12.h"
+
+__attribute__ ((target ("sse4.2")))
+int foo ()
+{
+ return 1;
+}
Index: gcc/testsuite/g++.dg/ext/mv12.C
===================================================================
--- gcc/testsuite/g++.dg/ext/mv12.C (revision 0)
+++ gcc/testsuite/g++.dg/ext/mv12.C (revision 0)
@@ -0,0 +1,22 @@
+// Test case to check if multiversioning works as expected when the versions
+// are defined in different files.
+
+// { dg-do run { target i?86-*-* x86_64-*-* } }
+// { dg-require-ifunc "" }
+// { dg-options "-O2" }
+// { dg-additional-sources "mv12-aux.C" }
+
+#include "mv12.h"
+
+int main ()
+{
+ if (__builtin_cpu_supports ("sse4.2"))
+ return foo () - 1;
+ return foo ();
+}
+
+__attribute__ ((target ("default")))
+int foo ()
+{
+ return 0;
+}
Index: gcc/testsuite/g++.dg/ext/mv12.h
===================================================================
--- gcc/testsuite/g++.dg/ext/mv12.h (revision 0)
+++ gcc/testsuite/g++.dg/ext/mv12.h (revision 0)
@@ -0,0 +1,6 @@
+// Header file used by mv12.C and mv12-aux.C.
+// { dg-do compile { target i?86-*-* x86_64-*-* } }
+// { dg-options "" }
+
+int foo () __attribute__ ((target ("default")));
+int foo () __attribute__ ((target ("sse4.2")));
Index: gcc/testsuite/g++.dg/ext/mv13.C
===================================================================
--- gcc/testsuite/g++.dg/ext/mv13.C (revision 0)
+++ gcc/testsuite/g++.dg/ext/mv13.C (revision 0)
@@ -0,0 +1,18 @@
+// Test case to check if multiversioning functions that are extern "C"
+// generates errors.
+
+// { dg-do compile { target i?86-*-* x86_64-*-* } }
+
+extern "C"
+__attribute__ ((target ("default")))
+int foo () // { dg-error "previously defined here" }
+{
+ return 0;
+}
+
+extern "C"
+__attribute__ ((target ("sse4.2")))
+int foo () // { dg-error "redefinition" }
+{
+ return 1;
+}
Index: gcc/config/i386/i386.c
===================================================================
--- gcc/config/i386/i386.c (revision 195818)
+++ gcc/config/i386/i386.c (working copy)
@@ -28695,6 +28695,9 @@ get_builtin_code_for_version (tree decl, tree *pre
gcc_assert (TREE_CODE (attrs) == STRING_CST);
attrs_str = TREE_STRING_POINTER (attrs);
+ /* Return priority zero for default function. */
+ if (strcmp (attrs_str, "default") == 0)
+ return 0;
/* Handle arch= if specified. For priority, set it to be 1 more than
the best instruction set the processor can handle. For instance, if
@@ -28827,15 +28830,9 @@ get_builtin_code_for_version (tree decl, tree *pre
static int
ix86_compare_version_priority (tree decl1, tree decl2)
{
- unsigned int priority1 = 0;
- unsigned int priority2 = 0;
+ unsigned int priority1 = get_builtin_code_for_version (decl1, NULL);
+ unsigned int priority2 = get_builtin_code_for_version (decl2, NULL);
- if (lookup_attribute ("target", DECL_ATTRIBUTES (decl1)) != NULL)
- priority1 = get_builtin_code_for_version (decl1, NULL);
-
- if (lookup_attribute ("target", DECL_ATTRIBUTES (decl2)) != NULL)
- priority2 = get_builtin_code_for_version (decl2, NULL);
-
return (int)priority1 - (int)priority2;
}
@@ -29064,14 +29061,12 @@ ix86_mangle_function_version_assembler_name (tree
if (DECL_VIRTUAL_P (decl)
|| DECL_VINDEX (decl))
- error_at (DECL_SOURCE_LOCATION (decl),
- "Virtual function versioning not supported\n");
+ sorry ("Virtual function multiversioning not supported");
version_attr = lookup_attribute ("target", DECL_ATTRIBUTES (decl));
- /* target attribute string is NULL for default functions. */
- if (version_attr == NULL_TREE)
- return id;
+ /* target attribute string cannot be NULL. */
+ gcc_assert (version_attr != NULL_TREE);
orig_name = IDENTIFIER_POINTER (id);
version_string
@@ -29511,8 +29506,8 @@ ix86_generate_version_dispatcher_body (void *node_
virtual methods in base classes but are not explicitly marked as
virtual. */
if (DECL_VINDEX (versn->symbol.decl))
- error_at (DECL_SOURCE_LOCATION (versn->symbol.decl),
- "Virtual function multiversioning not supported");
+ sorry ("Virtual function multiversioning not supported");
+
fn_ver_vec.safe_push (versn->symbol.decl);
}
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH] Multiversioning fixes (PR c++/55742, take 2)
2013-02-08 0:10 ` Sriraman Tallam
@ 2013-02-11 18:35 ` Sriraman Tallam
2013-02-12 3:01 ` Jason Merrill
2013-02-13 9:22 ` Andreas Schwab
1 sibling, 1 reply; 13+ messages in thread
From: Sriraman Tallam @ 2013-02-11 18:35 UTC (permalink / raw)
To: Jason Merrill; +Cc: Jakub Jelinek, Richard Henderson, GCC Patches
Hi,
Is this alright to commit?
Thanks
Sri
On Thu, Feb 7, 2013 at 4:10 PM, Sriraman Tallam <tmsriram@google.com> wrote:
> On Thu, Feb 7, 2013 at 6:29 AM, Jason Merrill <jason@redhat.com> wrote:
>> On 02/06/2013 08:39 PM, Sriraman Tallam wrote:
>>>
>>> +// Test to check if an error is generated when virtual functions
>>> +// are multiversioned.
>>
>>
>> This seems like a TODO, rather than something to test for. I don't see any
>> reason why we couldn't support multiversioned virtual functions.
>>
>>> error_at (DECL_SOURCE_LOCATION (decl),
>>> - "Virtual function versioning not supported\n");
>>> + "Virtual function multiversioning not supported\n");
>>
>>
>> And so this should be a sorry rather than an error.
>
> Attached a new patch with these changes. Also made more minor changes
> to config/i386/i386.c.
>
> Thanks
> Sri
>
>>
>> Jason
>>
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH] Multiversioning fixes (PR c++/55742, take 2)
2013-02-11 18:35 ` Sriraman Tallam
@ 2013-02-12 3:01 ` Jason Merrill
0 siblings, 0 replies; 13+ messages in thread
From: Jason Merrill @ 2013-02-12 3:01 UTC (permalink / raw)
To: Sriraman Tallam; +Cc: Jakub Jelinek, Richard Henderson, GCC Patches
OK, thanks.
Jason
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH] Multiversioning fixes (PR c++/55742, take 2)
2013-02-08 0:10 ` Sriraman Tallam
2013-02-11 18:35 ` Sriraman Tallam
@ 2013-02-13 9:22 ` Andreas Schwab
[not found] ` <CAAs8HmyKtXHzTA+93PF5e+Ggd=zWDbO_s_ujdq92guPd4T+Zww@mail.gmail.com>
1 sibling, 1 reply; 13+ messages in thread
From: Andreas Schwab @ 2013-02-13 9:22 UTC (permalink / raw)
To: Sriraman Tallam
Cc: Jason Merrill, Jakub Jelinek, Richard Henderson, GCC Patches
Sriraman Tallam <tmsriram@google.com> writes:
> Index: gcc/testsuite/g++.dg/ext/mv12-aux.C
> ===================================================================
> --- gcc/testsuite/g++.dg/ext/mv12-aux.C (revision 0)
> +++ gcc/testsuite/g++.dg/ext/mv12-aux.C (revision 0)
> @@ -0,0 +1,11 @@
> +// Test case to check if multiversioning works as expected when the versions
> +// are defined in different files. Auxiliary file for mv12.C.
> +// { dg-do compile }
> +
> +#include "mv12.h"
> +
> +__attribute__ ((target ("sse4.2")))
> +int foo ()
FAIL: g++.dg/ext/mv12-aux.C -std=c++11 (test for excess errors)
Excess errors:
/daten/aranym/gcc/gcc-20130213/gcc/testsuite/g++.dg/ext/mv12.h:5:47: warning: target attribute is not supported on this machine [-Wattributes]
/daten/aranym/gcc/gcc-20130213/gcc/testsuite/g++.dg/ext/mv12.h:6:46: warning: target attribute is not supported on this machine [-Wattributes]
/daten/aranym/gcc/gcc-20130213/gcc/testsuite/g++.dg/ext/mv12-aux.C:8:10: warning: target attribute is not supported on this machine [-Wattributes]
Andreas.
--
Andreas Schwab, SUSE Labs, schwab@suse.de
GPG Key fingerprint = 0196 BAD8 1CE9 1970 F4BE 1748 E4D4 88E3 0EEA B9D7
"And now for something completely different."
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH] Multiversioning fixes (PR c++/55742, take 2)
[not found] ` <CAAs8HmyKtXHzTA+93PF5e+Ggd=zWDbO_s_ujdq92guPd4T+Zww@mail.gmail.com>
@ 2013-02-13 18:57 ` Sriraman Tallam
2013-02-13 20:14 ` Jakub Jelinek
0 siblings, 1 reply; 13+ messages in thread
From: Sriraman Tallam @ 2013-02-13 18:57 UTC (permalink / raw)
To: Andreas Schwab
Cc: Jason Merrill, GCC Patches, Richard Henderson, Jakub Jelinek
On Wed, Feb 13, 2013 at 7:46 AM, Sriraman Tallam <tmsriram@google.com> wrote:
>
> On Feb 13, 2013 1:21 AM, "Andreas Schwab" <schwab@suse.de> wrote:
>>
>> Sriraman Tallam <tmsriram@google.com> writes:
>>
>> > Index: gcc/testsuite/g++.dg/ext/mv12-aux.C
>> > ===================================================================
>> > --- gcc/testsuite/g++.dg/ext/mv12-aux.C (revision 0)
>> > +++ gcc/testsuite/g++.dg/ext/mv12-aux.C (revision 0)
>> > @@ -0,0 +1,11 @@
>> > +// Test case to check if multiversioning works as expected when the
>> > versions
>> > +// are defined in different files. Auxiliary file for mv12.C.
>> > +// { dg-do compile }
>> > +
>> > +#include "mv12.h"
>> > +
>> > +__attribute__ ((target ("sse4.2")))
>> > +int foo ()
>>
>> FAIL: g++.dg/ext/mv12-aux.C -std=c++11 (test for excess errors)
>> Excess errors:
>> /daten/aranym/gcc/gcc-20130213/gcc/testsuite/g++.dg/ext/mv12.h:5:47:
>> warning: target attribute is not supported on this machine [-Wattributes]
>> /daten/aranym/gcc/gcc-20130213/gcc/testsuite/g++.dg/ext/mv12.h:6:46:
>> warning: target attribute is not supported on this machine [-Wattributes]
>> /daten/aranym/gcc/gcc-20130213/gcc/testsuite/g++.dg/ext/mv12-aux.C:8:10:
>> warning: target attribute is not supported on this machine [-Wattributes]
>
> I will fix this asap. Sorry about this.
I committed a trivial patch to fix this problem. mv12-aux.C is
auxiliary to mv12.C and should have the same test directives as
mv12.C.
2013-02-13 Sriraman Tallam <tmsriram@google.com>
* g++.dg/ext/mv12-aux.C: Add directives to match mv12.C.
Index: g++.dg/ext/mv12-aux.C
===================================================================
--- g++.dg/ext/mv12-aux.C (revision 196025)
+++ g++.dg/ext/mv12-aux.C (working copy)
@@ -1,7 +1,10 @@
// Test case to check if multiversioning works as expected when the versions
// are defined in different files. Auxiliary file for mv12.C.
-// { dg-do compile }
+// { dg-do compile { target i?86-*-* x86_64-*-* } }
+// { dg-require-ifunc "" }
+// { dg-options "-O2" }
+
#include "mv12.h"
This should fix the problem.
Thanks
Sri
>
> Sri
>
>>
>> Andreas.
>>
>> --
>> Andreas Schwab, SUSE Labs, schwab@suse.de
>> GPG Key fingerprint = 0196 BAD8 1CE9 1970 F4BE 1748 E4D4 88E3 0EEA B9D7
>> "And now for something completely different."
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH] Multiversioning fixes (PR c++/55742, take 2)
2013-02-13 18:57 ` Sriraman Tallam
@ 2013-02-13 20:14 ` Jakub Jelinek
2013-02-13 21:53 ` Sriraman Tallam
0 siblings, 1 reply; 13+ messages in thread
From: Jakub Jelinek @ 2013-02-13 20:14 UTC (permalink / raw)
To: Sriraman Tallam
Cc: Andreas Schwab, Jason Merrill, GCC Patches, Richard Henderson
On Wed, Feb 13, 2013 at 10:57:42AM -0800, Sriraman Tallam wrote:
> I committed a trivial patch to fix this problem. mv12-aux.C is
> auxiliary to mv12.C and should have the same test directives as
> mv12.C.
>
> 2013-02-13 Sriraman Tallam <tmsriram@google.com>
>
> * g++.dg/ext/mv12-aux.C: Add directives to match mv12.C.
Better would be to rename
g++.dg/ext/mv12-aux.C to g++.dg/ext/mv12-aux.cc and remove all dg-*
directives from it, plus adjust dg-additional-sources in mv12.C.
The dg.exp driver is only looking for *.C testcases, so it will skip
*.cc, which is what you want.
> --- g++.dg/ext/mv12-aux.C (revision 196025)
> +++ g++.dg/ext/mv12-aux.C (working copy)
> @@ -1,7 +1,10 @@
> // Test case to check if multiversioning works as expected when the versions
> // are defined in different files. Auxiliary file for mv12.C.
> -// { dg-do compile }
>
> +// { dg-do compile { target i?86-*-* x86_64-*-* } }
> +// { dg-require-ifunc "" }
> +// { dg-options "-O2" }
> +
> #include "mv12.h"
>
> This should fix the problem.
Jakub
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH] Multiversioning fixes (PR c++/55742, take 2)
2013-02-13 20:14 ` Jakub Jelinek
@ 2013-02-13 21:53 ` Sriraman Tallam
0 siblings, 0 replies; 13+ messages in thread
From: Sriraman Tallam @ 2013-02-13 21:53 UTC (permalink / raw)
To: Jakub Jelinek
Cc: Andreas Schwab, Jason Merrill, GCC Patches, Richard Henderson
On Wed, Feb 13, 2013 at 12:14 PM, Jakub Jelinek <jakub@redhat.com> wrote:
> On Wed, Feb 13, 2013 at 10:57:42AM -0800, Sriraman Tallam wrote:
>> I committed a trivial patch to fix this problem. mv12-aux.C is
>> auxiliary to mv12.C and should have the same test directives as
>> mv12.C.
>>
>> 2013-02-13 Sriraman Tallam <tmsriram@google.com>
>>
>> * g++.dg/ext/mv12-aux.C: Add directives to match mv12.C.
>
> Better would be to rename
> g++.dg/ext/mv12-aux.C to g++.dg/ext/mv12-aux.cc and remove all dg-*
> directives from it, plus adjust dg-additional-sources in mv12.C.
> The dg.exp driver is only looking for *.C testcases, so it will skip
> *.cc, which is what you want.
Committed patch which does exactly this.
2013-02-13 Sriraman Tallam <tmsriram@google.com>
* g++.dg/ext/mv12-aux.C: Delete, move to mv12-aux.cc.
* g++.dg/ext/mv12-aux.cc: New file.
* g++.dg/ext/mv12.h: Remove directives. Fix comment.
* g++.dg/ext/mv12.C: Fix file name.
Index: mv12-aux.cc
===================================================================
--- mv12-aux.cc (revision 0)
+++ mv12-aux.cc (revision 0)
@@ -0,0 +1,10 @@
+// Test case to check if multiversioning works as expected when the versions
+// are defined in different files. Auxiliary file for mv12.C.
+
+#include "mv12.h"
+
+__attribute__ ((target ("sse4.2")))
+int foo ()
+{
+ return 1;
+}
Index: mv12.C
===================================================================
--- mv12.C (revision 196025)
+++ mv12.C (working copy)
@@ -4,7 +4,7 @@
// { dg-do run { target i?86-*-* x86_64-*-* } }
// { dg-require-ifunc "" }
// { dg-options "-O2" }
-// { dg-additional-sources "mv12-aux.C" }
+// { dg-additional-sources "mv12-aux.cc" }
#include "mv12.h"
Index: mv12.h
===================================================================
--- mv12.h (revision 196025)
+++ mv12.h (working copy)
@@ -1,6 +1,4 @@
-// Header file used by mv12.C and mv12-aux.C.
-// { dg-do compile { target i?86-*-* x86_64-*-* } }
-// { dg-options "" }
+// Header file used by mv12.C and mv12-aux.cc.
int foo () __attribute__ ((target ("default")));
int foo () __attribute__ ((target ("sse4.2")));
Index: mv12-aux.C
===================================================================
--- mv12-aux.C (revision 196025)
+++ mv12-aux.C (working copy)
@@ -1,14 +0,0 @@
-// Test case to check if multiversioning works as expected when the versions
-// are defined in different files. Auxiliary file for mv12.C.
-
-// { dg-do compile { target i?86-*-* x86_64-*-* } }
-// { dg-require-ifunc "" }
-// { dg-options "-O2" }
-
-#include "mv12.h"
-
-__attribute__ ((target ("sse4.2")))
-int foo ()
-{
- return 1;
-}
Thanks
Sri
>
>> --- g++.dg/ext/mv12-aux.C (revision 196025)
>> +++ g++.dg/ext/mv12-aux.C (working copy)
>> @@ -1,7 +1,10 @@
>> // Test case to check if multiversioning works as expected when the versions
>> // are defined in different files. Auxiliary file for mv12.C.
>> -// { dg-do compile }
>>
>> +// { dg-do compile { target i?86-*-* x86_64-*-* } }
>> +// { dg-require-ifunc "" }
>> +// { dg-options "-O2" }
>> +
>> #include "mv12.h"
>>
>> This should fix the problem.
>
> Jakub
^ permalink raw reply [flat|nested] 13+ messages in thread
end of thread, other threads:[~2013-02-13 21:53 UTC | newest]
Thread overview: 13+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-01-18 20:22 [PATCH] Multiversioning fixes (PR c++/55742) Jakub Jelinek
2013-01-19 16:19 ` Jason Merrill
2013-01-21 14:33 ` [PATCH] Multiversioning fixes (PR c++/55742, take 2) Jakub Jelinek
2013-01-30 13:55 ` Jason Merrill
2013-02-07 1:39 ` Sriraman Tallam
2013-02-07 14:30 ` Jason Merrill
2013-02-08 0:10 ` Sriraman Tallam
2013-02-11 18:35 ` Sriraman Tallam
2013-02-12 3:01 ` Jason Merrill
2013-02-13 9:22 ` Andreas Schwab
[not found] ` <CAAs8HmyKtXHzTA+93PF5e+Ggd=zWDbO_s_ujdq92guPd4T+Zww@mail.gmail.com>
2013-02-13 18:57 ` Sriraman Tallam
2013-02-13 20:14 ` Jakub Jelinek
2013-02-13 21:53 ` Sriraman Tallam
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).