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.