[cfe-dev] [llvm-dev] RFC: Emitting empty invariant group for vtable loads
Hal Finkel via cfe-dev
cfe-dev at lists.llvm.org
Wed Jan 25 15:03:54 PST 2017
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
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
> http://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/cfe-dev/attachments/20170125/7a93830a/attachment.html>
More information about the cfe-dev
mailing list