[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