Re: [PATCH] Multiversioning fixes (PR c++/55742, take 2)
On Wed, Feb 13, 2013 at 12:14 PM, Jakub Jelinek 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 >> >> * 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 * 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
Re: [PATCH] Multiversioning fixes (PR c++/55742, take 2)
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 > > * 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
Re: [PATCH] Multiversioning fixes (PR c++/55742, take 2)
On Wed, Feb 13, 2013 at 7:46 AM, Sriraman Tallam wrote: > > On Feb 13, 2013 1:21 AM, "Andreas Schwab" wrote: >> >> Sriraman Tallam 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 * 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, sch...@suse.de >> GPG Key fingerprint = 0196 BAD8 1CE9 1970 F4BE 1748 E4D4 88E3 0EEA B9D7 >> "And now for something completely different."
Re: [PATCH] Multiversioning fixes (PR c++/55742, take 2)
Sriraman Tallam 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, sch...@suse.de GPG Key fingerprint = 0196 BAD8 1CE9 1970 F4BE 1748 E4D4 88E3 0EEA B9D7 "And now for something completely different."
Re: [PATCH] Multiversioning fixes (PR c++/55742, take 2)
OK, thanks. Jason
Re: [PATCH] Multiversioning fixes (PR c++/55742, take 2)
Hi, Is this alright to commit? Thanks Sri On Thu, Feb 7, 2013 at 4:10 PM, Sriraman Tallam wrote: > On Thu, Feb 7, 2013 at 6:29 AM, Jason Merrill 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 >>
Re: [PATCH] Multiversioning fixes (PR c++/55742, take 2)
On Thu, Feb 7, 2013 at 6:29 AM, Jason Merrill 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 > * 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 =
Re: [PATCH] Multiversioning fixes (PR c++/55742, take 2)
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
Re: [PATCH] Multiversioning fixes (PR c++/55742, take 2)
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 wrote: > OK. Sriraman, are you working on documentation and more tests? > > Jason * 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-e
Re: [PATCH] Multiversioning fixes (PR c++/55742, take 2)
OK. Sriraman, are you working on documentation and more tests? Jason
[PATCH] Multiversioning fixes (PR c++/55742, take 2)
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 % 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 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 % 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_POI