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

Piotr Padlewski via llvm-dev llvm-dev at lists.llvm.org
Tue Jan 24 11:39:49 PST 2017


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.
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20170124/8a380aa0/attachment-0001.html>


More information about the llvm-dev mailing list