Hi,

  I am working on supporting function multi-versioning in GCC and here
is a write-up on its usability.

Multiversioning Usability
====================

For a simple motivating example,

int
find_popcount(unsigned int i)
{
  return __builtin_popcount(i);
}

Currently, compiling this with -mpopcnt will result in the “popcnt”
instruction being used and otherwise call a built-in generic
implementation. It is desirable to have two versions of this function
so that it can be run both on targets that support the popcnt insn and
those that do not.


* Case I - User Guided Versioning where only one function body is
provided by the user.

This case addresses a use where the user wants multi-versioning but
provides only one function body.  I want to add a new attribute called
“mversion” which will be used like this:

int __attribute__(mversion(“popcnt”))
find_popcount(unsigned int i)
{
  return __builtin_popcount(i);
}

With the attribute, the compiler should understand that it should
generate two versions for this function. The user makes a call to this
function like a regular call but the code generated would call the
appropriate function at run-time based on a check to determine if that
instruction is supported or not.

The attribute can be scaled to support many versions but allowing a
comma separated list of values for the mversion attribute. For
instance, “__attribute__(mversion(“sse3”, “sse4”, ...)) will provide a
version for each. For N attributes, N clones plus one clone for the
default case will have to be generated by the compiler. The arguments
to the "mversion" attribute will be similar to the arguments supported
by the "target" attribute.

This attribute is useful if the same source is going to be used to
generate the different versions. If this has to be done manually, the
user has to duplicate the body of the function and specify a target
attribute of “popcnt” on one clone. Then, the user has to use
something like IFUNC support or manually write code to call the
appropriate version. All of this will be done automatically by the
compiler with this new attribute.

* Case II - User Guided Versioning where the function bodies for each
version differ and is provided by the user.

This case pertains to multi-versioning when the source bodies of the
two or more versions are different and are provided by the user. Here
too, I want to use a new attribute, “version”. Now, the user can
specify versioning intent like this:

int __attribute__((version(“popcnt”))
find_popcnt(unsigned int i)
{
   // inline assembly of the popcnt instruction, specialized version.
  asm(“popcnt ….”);
}

int
find_popcnt(unsigned int i)
{
  //generic code for doing this
  ...
}

This uses function overloading to specify versions.  The compiler will
understand that versioning is requested, since the functions have
different attributes with "version", and will generate the code to
execute the right function at run-time.  The compiler should check for
the existence of one body without the attribute which will be the
default version.

* Case III - Versioning is done automatically by the compiler.

I want to add a new compiler flag “-mversion” along the lines of “-m”.
If the user specifies “-mversion=popcnt” then the compiler will
automatically create two versions of any function that is impacted by
the new instruction. The difference between “-m” and “-mversion” will
be that while “-m” generates only the specialized version, “-mversion”
will generate both the specialized and the generic versions.  There is
no need to explicity mark any function for versioning, no source
changes.

The compiler will decide if it is beneficial to multi-version a
function based on heuristics using hotness information, code size
growth, etc.


Runtime support
===============

In order for the compiler to generate multi-versioned code, it needs
to call functions that would test if a particular feature exists or
not at run-time. For example, IsPopcntSupported() would be one such
function. I have prepared a patch to do this which adds the runtime
support in libgcc and supports new builtins to test the various
features. I will send the patch separately to keep the dicussions
focused.


Thoughts?

Thanks,
-Sri.

Reply via email to