Commit f80e0faf by Sriraman Tallam Committed by Sriraman Tallam

extend.texi: Document Function Multiversioning and "default" parameter string to target...

	* 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.

From-SVN: r195967
parent 6e1d47c4
2013-02-11 Sriraman Tallam <tmsriramgoogle.com>
* doc/extend.texi: Document Function Multiversioning and "default"
parameter string to target attribute.
* 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.
2013-02-11 Iain Sandoe <iain@codesourcery.com> 2013-02-11 Iain Sandoe <iain@codesourcery.com>
Jack Howarth <howarth@bromo.med.uc.edu> Jack Howarth <howarth@bromo.med.uc.edu>
Patrick Marlier <patrick.marlier@gmail.com> Patrick Marlier <patrick.marlier@gmail.com>
......
...@@ -28696,6 +28696,9 @@ get_builtin_code_for_version (tree decl, tree *predicate_list) ...@@ -28696,6 +28696,9 @@ get_builtin_code_for_version (tree decl, tree *predicate_list)
gcc_assert (TREE_CODE (attrs) == STRING_CST); gcc_assert (TREE_CODE (attrs) == STRING_CST);
attrs_str = TREE_STRING_POINTER (attrs); 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 /* Handle arch= if specified. For priority, set it to be 1 more than
the best instruction set the processor can handle. For instance, if the best instruction set the processor can handle. For instance, if
...@@ -28828,14 +28831,8 @@ get_builtin_code_for_version (tree decl, tree *predicate_list) ...@@ -28828,14 +28831,8 @@ get_builtin_code_for_version (tree decl, tree *predicate_list)
static int static int
ix86_compare_version_priority (tree decl1, tree decl2) ix86_compare_version_priority (tree decl1, tree decl2)
{ {
unsigned int priority1 = 0; unsigned int priority1 = get_builtin_code_for_version (decl1, NULL);
unsigned int priority2 = 0; 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; return (int)priority1 - (int)priority2;
} }
...@@ -29065,14 +29062,12 @@ ix86_mangle_function_version_assembler_name (tree decl, tree id) ...@@ -29065,14 +29062,12 @@ ix86_mangle_function_version_assembler_name (tree decl, tree id)
if (DECL_VIRTUAL_P (decl) if (DECL_VIRTUAL_P (decl)
|| DECL_VINDEX (decl)) || DECL_VINDEX (decl))
error_at (DECL_SOURCE_LOCATION (decl), sorry ("Virtual function multiversioning not supported");
"Virtual function versioning not supported\n");
version_attr = lookup_attribute ("target", DECL_ATTRIBUTES (decl)); version_attr = lookup_attribute ("target", DECL_ATTRIBUTES (decl));
/* target attribute string is NULL for default functions. */ /* target attribute string cannot be NULL. */
if (version_attr == NULL_TREE) gcc_assert (version_attr != NULL_TREE);
return id;
orig_name = IDENTIFIER_POINTER (id); orig_name = IDENTIFIER_POINTER (id);
version_string version_string
...@@ -29512,8 +29507,8 @@ ix86_generate_version_dispatcher_body (void *node_p) ...@@ -29512,8 +29507,8 @@ ix86_generate_version_dispatcher_body (void *node_p)
virtual methods in base classes but are not explicitly marked as virtual methods in base classes but are not explicitly marked as
virtual. */ virtual. */
if (DECL_VINDEX (versn->symbol.decl)) if (DECL_VINDEX (versn->symbol.decl))
error_at (DECL_SOURCE_LOCATION (versn->symbol.decl), sorry ("Virtual function multiversioning not supported");
"Virtual function multiversioning not supported");
fn_ver_vec.safe_push (versn->symbol.decl); fn_ver_vec.safe_push (versn->symbol.decl);
} }
...@@ -3655,6 +3655,11 @@ Enable/disable the generation of the advanced bit instructions. ...@@ -3655,6 +3655,11 @@ Enable/disable the generation of the advanced bit instructions.
@cindex @code{target("aes")} attribute @cindex @code{target("aes")} attribute
Enable/disable the generation of the AES instructions. 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 @item mmx
@itemx no-mmx @itemx no-mmx
@cindex @code{target("mmx")} attribute @cindex @code{target("mmx")} attribute
...@@ -15215,6 +15220,7 @@ Predefined Macros,cpp,The GNU C Preprocessor}). ...@@ -15215,6 +15220,7 @@ Predefined Macros,cpp,The GNU C Preprocessor}).
* Bound member functions:: You can extract a function pointer to the * Bound member functions:: You can extract a function pointer to the
method denoted by a @samp{->*} or @samp{.*} expression. method denoted by a @samp{->*} or @samp{.*} expression.
* C++ Attributes:: Variable, function, and type attributes for C++ only. * C++ Attributes:: Variable, function, and type attributes for C++ only.
* Function Multiversioning:: Declaring multiple function versions.
* Namespace Association:: Strong using-directives for namespace association. * Namespace Association:: Strong using-directives for namespace association.
* Type Traits:: Compiler support for type traits * Type Traits:: Compiler support for type traits
* Java Exceptions:: Tweaking exception handling to work with Java. * Java Exceptions:: Tweaking exception handling to work with Java.
...@@ -15744,6 +15750,64 @@ interface table mechanism, instead of regular virtual table dispatch. ...@@ -15744,6 +15750,64 @@ interface table mechanism, instead of regular virtual table dispatch.
See also @ref{Namespace Association}. 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 @node Namespace Association
@section Namespace Association @section Namespace Association
......
2013-02-11 Sriraman Tallam <tmsriramgoogle.com>
* 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.
2013-02-11 Sebastian Huber <sebastian.huber@embedded-brains.de> 2013-02-11 Sebastian Huber <sebastian.huber@embedded-brains.de>
* lib/target-supports.exp * lib/target-supports.exp
......
// 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;
}
// 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;
}
// 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")));
// 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;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment