public inbox for gcc@gcc.gnu.org
 help / color / mirror / Atom feed
From: Richard Guenther <richard.guenther@gmail.com>
To: Xinliang David Li <davidxl@google.com>
Cc: Sriraman Tallam <tmsriram@google.com>, gcc@gcc.gnu.org
Subject: Re: Function Multiversioning Usability.
Date: Wed, 17 Aug 2011 15:12:00 -0000	[thread overview]
Message-ID: <CAFiYyc2=GhrA+pE46ZTqkQkD+PqETM+1Ht5Aj3CVLzsqXm7uWA@mail.gmail.com> (raw)
In-Reply-To: <CAAkRFZLLaXgHs6LP3PfbN4KgT_spL3t4So8q9Yy_etELF=fF9w@mail.gmail.com>

On Wed, Aug 17, 2011 at 4:52 PM, Xinliang David Li <davidxl@google.com> wrote:
> The gist of previous discussion is to use function overloading instead
> of exposing underlying implementation such as builtin_dispatch to the
> user. This new refined proposal has not changed in that, but is more
> elaborate on various use cases which has been carefully thought out.
> Please be specific on which part needs to improvement.

See below ...

> Thanks,
>
> David
>
> On Wed, Aug 17, 2011 at 12:29 AM, Richard Guenther
> <richard.guenther@gmail.com> wrote:
>> On Tue, Aug 16, 2011 at 10:37 PM, Sriraman Tallam <tmsriram@google.com> wrote:
>>> 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 example seems to be particularly ill-suited.  Trying to 2nd guess you
here I think you want to direct the compiler to emit multiple versions
with different target capabilities enabled, probably for elaborate code that
_doesn't_ use any fancy builtins, right?  It seems this is a shortcut for

static inline __attribute__((always_iniline)) implementation () { ... }

symbol __attribute__((target("msse2"))) { implementation(); }
symbol __attribute__((target("msse3"))) { implementation(); }
...

and so should be fully handled by the frontend (if at all, it seems to
be purely syntactic sugar).

I'd like to see it omitted initially - we should get the core stuff right
and build "nice" stuff ontop of it later, if necessary.

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

Yep, we agreed that this is a good idea.  But we also agreed to
use either the target attribute (for compiler-generated tests) or
a single predicate attribute that takes a function which is const
with no arguments and returns whether the variant is selected or not.

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

How do you plan to detect "impacted by the new instruction?".  Again
popcnt seems to be a poor example - most use probably lies in
autovectorization (but then it's closely tied to active capabilites of the
backend and not really ready for auto-versioning).

This will be a lot of work if it shouldn't be very inefficient.

Richard.

>>> 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?
>>
>> Please focus on one mechanism and re-use existing facilities as much as
>> possible.  Thus, see the old discussion where we settled on overloading
>> with either using the existing target attribute or a selector function.
>> I don't see any benefit repeating the discussions here.
>>
>> Richard.
>>
>>> Thanks,
>>> -Sri.
>>>
>>
>

  reply	other threads:[~2011-08-17 15:12 UTC|newest]

Thread overview: 9+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2011-08-16 20:38 Sriraman Tallam
2011-08-16 21:06 ` Xinliang David Li
2011-08-16 21:24 ` Xinliang David Li
2011-08-17  7:29 ` Richard Guenther
2011-08-17 14:53   ` Xinliang David Li
2011-08-17 15:12     ` Richard Guenther [this message]
2011-08-17 16:38       ` Xinliang David Li
2011-08-18  7:51         ` Richard Guenther
2011-08-18  8:05           ` Xinliang David Li

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to='CAFiYyc2=GhrA+pE46ZTqkQkD+PqETM+1Ht5Aj3CVLzsqXm7uWA@mail.gmail.com' \
    --to=richard.guenther@gmail.com \
    --cc=davidxl@google.com \
    --cc=gcc@gcc.gnu.org \
    --cc=tmsriram@google.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).