This is the mail archive of the gcc@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: User directed Function Multiversioning (MV) via Function Overloading


On Wed, Mar 7, 2012 at 1:42 AM, Sriraman Tallam <tmsriram@google.com> wrote:
> Hi,
>
> User directed Function Multiversioning (MV) via Function Overloading
> ===================================================
>
> I have created a set of patches to add support for user directed
> function MV via function overloading. This was discussed in this
> thread previously:
> http://gcc.gnu.org/ml/gcc-patches/2011-04/msg02285.html
>
> Two patches have been created now to support this:
> * The patch with the front-end changes to support versioned functions is:
> ?http://codereview.appspot.com/5752064/
>
> * The patch to add runtime CPU type detection support is here:
> ?http://codereview.appspot.com/5754058/

Please post the patches to gcc-patches.

> With this support, here is an example of writing a program with
> function versions:
>
> int foo (); ?/* Default version */
> int foo () __attribute__ ((targetv("arch=corei7"))); /*Specialized for corei7 */
> int foo () __attribute__ ((targetv("arch=amdfam10"))); /*Specialized
> for amdfam10 */

I don't like specifying 'arch' at all.  Instead you _always_ want architecture
feature tests, not architecture tests.  Because, does amdfam10 also cover
bdver1?  [it can't! bdver1 does no longer have 3dnow! but that's entirely
surprising for a user]

Thus, only allow feature specifications.  [Why not re-use the existing
'target' attribute?]

I'll have a look at the patches once posted.

Richard.

>
> int main ()
> {
> ?int (*p)() = &foo;
> ?return foo () + (*p)();
> }
>
> int foo ()
> {
> ?return 0;
> }
>
> int __attribute__ ((targetv("arch=corei7")))
> foo ()
> {
> ?...
> ?return 0;
> }
>
> int __attribute__ ((targetv("arch=amdfam10")))
> foo ()
> {
> ?...
> ?return 0;
> }
>
> The above example has foo defined 3 times, but all 3 definitions of
> foo are different versions of the same function. The call to foo in
> main, directly and via a pointer, are calls to the multi-versioned
> function foo which is dispatched to the right foo at run-time.
>
> Function versions must have the same signature but must differ in the
> specifier string provided to a new attribute called "targetv", which
> is nothing but the target attribute with an extra specification to
> indicate a version. Any number of versions can be created using the
> targetv attribute but it is mandatory to have one function without the
> attribute, which is treated as the default version. The front-end
> support is available in this patch:
> ?http://codereview.appspot.com/5752064/
>
> The front-end treats multiple definitions of foo with the same
> signature but with different targetv attributes as legitimate
> candidates for overloading. Also, all the function versions of one
> function are grouped together. Then, calls to foo and pointer access
> of foo will be replaced by an IFUNC function (foo.ifunc) which will
> call the dispatcher code at run-time to figure out the right version
> to execute. For the above example, the following functions will be
> created :
>
> * _Z3foov.ifunc : ifunc dispatcher for multi-versioned function foo and
> ?aliases to _Z3foov.resolver. All calls and pointer accesses to foo are
> ?replaced by an call or pointer access to this function.
> * _Z3foov.resolver : The code to determine which version to execute at
> ?run-time.
> * _Z3foov : The default version of foo.
> * _Z3foov.arch_corei7 : The corei7 version of foo.
> * _Z3foov.arch_amdfam10 : The amdfam10 version of foo.
>
> Note that using IFUNC ?blocks inlining of versioned functions. I had
> implemented an optimization earlier to do hot path cloning to allow
> versioned functions to be inlined. Please see :
> http://gcc.gnu.org/ml/gcc-patches/2011-04/msg02285.html
> In the next iteration, I plan to merge these two. With that, hot code
> paths with versioned functions will be cloned so that versioned
> functions can be inlined.
>
> The version dispatch itself happens in a newly created pass added to
> be one of the initial lowering passes. The pass communicates with the
> target to determine the appropriate predicates to use to figure out
> which version to dispatch at run-time. The predicates are target
> builtins which determine the platform type at run-time and are added
> in this patch :
> http://codereview.appspot.com/5754058/
>
> The following features are being developed for the next iteration:
>
> 1) Support for hot path cloning to inline versioned functions.
> 2) Specifying multiple versions in a single function definition.
>
> This will be done using the following syntax:
> int foo ()
> __attribute__ ((targetv (("arch=corei7"),("arch=amdfam10"), ("arch=core2"))));
>
> which means the same body of foo must be cloned for corei7, amdfam10, and core2.
>
> 3) Specifying ISA types in the attribute. Only "arch=" is supported now.
>
> For example,
> int foo ()
> __attribute__ ((targetv ("popcnt,ssse3")));
>
> means the version is only to be executed when popcount and ssse3
> instructions are available.
>
> 4) Other dispatching mechanism.
>
> IFUNC is used for dispatch, but then the target does not support this
> dispatching by directly calling the appropriate function version after
> checking the platform type will be supported.
>
> 5) Virtual function versioning.
>
> Thoughts?
>
> Thanks,
> -Sri.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]