[llvm-dev] RFC: Emitting empty invariant group for vtable loads

Hal Finkel via llvm-dev llvm-dev at lists.llvm.org
Wed Jan 25 16:11:02 PST 2017


On 01/25/2017 06:05 PM, Piotr Padlewski wrote:
>
>
> 2017-01-26 0:03 GMT+01:00 Hal Finkel <hfinkel at anl.gov 
> <mailto:hfinkel at anl.gov>>:
>
>     Hi Piotr,
>
>     I think makes sense. Modulo bitcasts, the invariant is identified
>     by a particular pointer SSA value. Given that you can't sensibly
>     have two nonequivalent invariants associated with the same pointer
>     SSA value simultaneously, there's no need to also identify the
>     invariant with a metadata string as well. When we need a new
>     "identifier" for the pointed-to value, we get one using
>     invariant.group.barrier.
>
>      -Hal
>
> What is your opinion about changing invariant.group to just invariant?

You mean changing !invariant.group -> !invariant and changing 
@llvm.invariant.group.barrier to @llvm.invariant.barrier? I don't have a 
strong opinion, but I'm inclined to leave it as-is (saying "group" 
implies that there might be things outside the group, which is true in 
this case).

  -Hal

>
> Piotr
>
>     On 01/24/2017 01:39 PM, Piotr Padlewski via llvm-dev wrote:
>>     Hi,
>>     I would really like to hear some feedback about this.
>>
>>     Piotr
>>
>>     2017-01-20 17:07 GMT+01:00 Piotr Padlewski
>>     <piotr.padlewski at gmail.com <mailto:piotr.padlewski at gmail.com>>:
>>
>>         Hi all,
>>
>>         I would like to propose a new way clang would decorate vtable
>>         loads in order to handle devirtualization better.
>>
>>         I've added *llvm-dev* also, because this can start a
>>         discussion about changing invariant.group to just invariant.
>>
>>         PDF version of this RFC can be found here:
>>
>>         https://drive.google.com/file/d/0B72TmzNsY6Z8ZmpOUnB5dDZfSFU/view?usp=sharing
>>         <https://drive.google.com/file/d/0B72TmzNsY6Z8ZmpOUnB5dDZfSFU/view?usp=sharing>
>>
>>
>>             Background:
>>
>>         Initial old design:
>>
>>         http://lists.llvm.org/pipermail/cfe-dev/2015-July/044227.html
>>         <http://lists.llvm.org/pipermail/cfe-dev/2015-July/044227.html>
>>
>>         My talk from LLVM Dev Meeting
>>
>>         http://llvm.org/devmtg/2016-11/#talk6
>>         <http://llvm.org/devmtg/2016-11/#talk6>
>>
>>
>>             The problem
>>
>>         Clang with -fstrict-vtable-pointers decorates vtable loads
>>         with metadata corresponding to mangled pointer type name like:
>>
>>         voidg(A& a){   a.foo();}
>>
>>         define void at _Z1gR1A(%struct.A* dereferenceable(8) %a)
>>         local_unnamed_addr #0{entry: %0= bitcast %struct.A* %a to
>>         void(%struct.A*)*** %vtable = load void(%struct.A*)**,
>>         void(%struct.A*)*** %0, !invariant.group !7 %1= load
>>         void(%struct.A*)*, void(%struct.A*)** %vtable tail call
>>         void%1(%struct.A* nonnull %a) ret void}!7= !{!"_ZTS1A"}
>>
>>         This works well if the pointer type doesn’t change, but when
>>         it does, devirtualization might not happen like here:
>>
>>         structA {   A();virtualvoidfoo();};structB :
>>         A{   B();virtualvoidfoo();};voidg(A&
>>         a){   a.foo();   a.foo();}voidclobber(A&);voidf() {     B
>>         b;     clobber(b);     g(b);}
>>
>>         The other problem is that when we combine 2 instructions with
>>         different invariant.group metadata, then we pick one of them,
>>         because for now we can have only single !invariant.group
>>         metadata.
>>
>>
>>           The solution
>>
>>         I had some initial ideas how it can be solved, like
>>
>>         1.
>>
>>             introducing multi invariant groups
>>
>>         2.
>>
>>             having sub invariant groups - like inheritance, so we
>>             could figure out that one group is subgroup of another
>>
>>         3.
>>
>>             decorating all loads with base pointer MD (doesn’t work
>>             with multiple inheritance)
>>
>>         I consulted my ideas with Krzysztof Pszeniczny, and he
>>         proposed something much simpler: we can decorate every
>>         invariant.group md with empty metadata.
>>
>>         This should work because the lifetime of the object is
>>         strictly defined by invariant.group.barrier.
>>
>>         If this holds, we can start discussion about if it makes
>>         sense to keep invariant groups, and instead have just
>>         “invariant”, that would be equivalent to having
>>         invariant.group with the same metadata.
>>
>>         Do you have some thoughts about this approach? I don’t have a
>>         mathematical proof, but I am confident that it should be valid.
>>
>>     _______________________________________________
>>     LLVM Developers mailing list
>>     llvm-dev at lists.llvm.org <mailto:llvm-dev at lists.llvm.org>
>>     http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev
>>     <http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev>
>
>     -- 
>     Hal Finkel
>     Lead, Compiler Technology and Programming Languages
>     Leadership Computing Facility
>     Argonne National Laboratory
>
-- 
Hal Finkel
Lead, Compiler Technology and Programming Languages
Leadership Computing Facility
Argonne National Laboratory
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20170125/fa1526c4/attachment.html>


More information about the llvm-dev mailing list