[llvm-dev] RFC: Emitting empty invariant group for vtable loads
Piotr Padlewski via llvm-dev
llvm-dev at lists.llvm.org
Wed Jan 25 16:05:29 PST 2017
2017-01-26 0:03 GMT+01:00 Hal Finkel <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?
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>:
>
>> 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
>>
>> Background:
>>
>> Initial old design:
>>
>> http://lists.llvm.org/pipermail/cfe-dev/2015-July/044227.html
>>
>> My talk from LLVM Dev Meeting
>>
>> 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:
>>
>> void g(A& a){ a.foo(); }
>>
>> define void @_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:
>>
>> struct A { A(); virtual void foo(); }; struct B : A{ B();
>> virtual void foo(); }; void g(A& a){ a.foo(); a.foo(); } void
>> clobber(A&); void f() { 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 listllvm-dev at lists.llvm.orghttp://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev
>
> --
> 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/20170126/96c7e7ad/attachment-0001.html>
More information about the llvm-dev
mailing list