[prev in list] [next in list] [prev in thread] [next in thread] 

List:       cfe-dev
Subject:    Re: [cfe-dev] C++11 and enhacned devirtualization
From:       Piotr Padlewski <prazek () google ! com>
Date:       2015-07-16 17:02:47
Message-ID: CABUQfFq1UDRfjM7kB7xTix9fTpXOrEAUv_pZLoErYPWSaMX52g () mail ! gmail ! com
[Download RAW message or body]

[Attachment #2 (multipart/alternative)]


The proposal of our solution will be published next week. Brief
introduction:

"Basic idea is to mark vtable loads with !invariant , and also put assume()
after calling constructor to show how vtable will look like. Function
@llvm.invariant.barrier that breaks the invariant will be needed to cope
with placement new and other cases where the vptr is legitimately permitted
to change."

We also want to make some improvements on generating vtables as
avaliable_externally - for example when there are no virtual inline
functions

Piotr

On Thu, Jul 16, 2015 at 9:11 AM, David Blaikie <dblaikie@gmail.com> wrote:

> I believe Piotr Prazek (cc'd) is working with Richard Smith on a
> proposal/plan for a general device for devirtualization (something like a
> restricted assume for pointer loads, if I understand it correctly - as we
> have nonnull and other attributes for other special cases of assume)
>
> On Thu, Jul 16, 2015 at 8:26 AM, Rafael Espíndola <
> rafael.espindola@gmail.com> wrote:
>
>> My preference for cases like PR16984 would be to change how clang
>> finds the vtable. Instead of doing a load from this, have clang
>> directly use the _ZTV variable when it is known at compile time.
>>
>>
>> On 15 July 2015 at 23:12, Hal Finkel <hfinkel@anl.gov> wrote:
>> > Hi Rafael,
>> >
>> > Thanks for the list of bug reports. The situations I've highlighted are
>> indeed PR16984 and PR13227. Do you have any thoughts on a design to fix
>> them? PR16984 mentions that it is likely best to put the necessary
>> information into the IR and let the optimizer take care of the constant
>> propagation to get rid of the indirect call. I agree, this sounds
>> appealing. The question then is what form should that information take. I
>> could do this with @llvm.assume, but I'm somewhat afraid of littering the
>> IR with them in response to a common core language property.
>> >
>> >  -Hal
>> >
>> > ----- Original Message -----
>> >> From: "Rafael Espíndola" <rafael.espindola@gmail.com>
>> >> To: "Hal Finkel" <hfinkel@anl.gov>
>> >> Cc: "cfe-dev@cs.uiuc.edu Developers" <cfe-dev@cs.uiuc.edu>, "Richard
>> Smith" <richard@metafoo.co.uk>
>> >> Sent: Thursday, July 16, 2015 12:48:05 AM
>> >> Subject: Re: [cfe-dev] C++11 and enhacned devirtualization
>> >>
>> >> There a quite a few open bugs about devirtualization. A quick search
>> >> finds
>> >>
>> >> pr18972, pr3100, pr13227, pr15961, pr15963, pr16984, pr17863,
>> >> pr19545, pr6747.
>> >>
>> >> A fairly important restriction to keep in mind is that the itanium
>> >> abi
>> >> requires some vtables to be exported from a given file (the one with
>> >> the key function), but the functions in those vtables don't have to
>> >> be
>> >> exported.
>> >>
>> >> That means that to devirtualize we have to produce a copy, which hits
>> >> issues with code that wants avoid #including definitions.
>> >>
>> >> See the commit message of r189852 for more details.
>> >>
>> >> Cheers,
>> >> Rafael
>> >>
>> >>
>> >> On 15 July 2015 at 22:11, Hal Finkel <hfinkel@anl.gov> wrote:
>> >> > Hi everyone,
>> >> >
>> >> > C++11 added features that allow for certain parts of the class
>> >> > hierarchy to be closed, specifically the 'final' keyword and the
>> >> > semantics of anonymous namespaces, and I think we take advantage
>> >> > of these to enhance our ability to perform devirtualization. For
>> >> > example, given this situation:
>> >> >
>> >> > struct Base {
>> >> >   virtual void foo() = 0;
>> >> > };
>> >> >
>> >> > void external();
>> >> > struct Final final : Base {
>> >> >   void foo() {
>> >> >     external();
>> >> >   }
>> >> > };
>> >> >
>> >> > void dispatch(Base *B) {
>> >> >   B->foo();
>> >> > }
>> >> >
>> >> > void opportunity(Final *F) {
>> >> >   dispatch(F);
>> >> > }
>> >> >
>> >> > When we optimize this code, we do the expected thing and inline
>> >> > 'dispatch' into 'opportunity' but we don't devirtualize the call
>> >> > to foo(). The fact that we know what the vtable of F is at that
>> >> > callsite is not exploited. To a lesser extent, we can do similar
>> >> > things for final virtual methods, and derived classes in anonymous
>> >> > namespaces (because Clang could determine whether or not a class
>> >> > (or method) there is effectively final).
>> >> >
>> >> > One possibility might be to @llvm.assume to say something about
>> >> > what the vtable ptr of F might be/contain should it be needed
>> >> > later when we emit the initial IR for 'opportunity' (and then
>> >> > teach the optimizer to use that information), but I'm not at all
>> >> > sure that's the best solution. Thoughts?
>> >> >
>> >> > Thanks again,
>> >> > Hal
>> >> >
>> >> > --
>> >> > Hal Finkel
>> >> > Assistant Computational Scientist
>> >> > Leadership Computing Facility
>> >> > Argonne National Laboratory
>> >> > _______________________________________________
>> >> > cfe-dev mailing list
>> >> > cfe-dev@cs.uiuc.edu
>> >> > http://lists.cs.uiuc.edu/mailman/listinfo/cfe-dev
>> >>
>> >
>> > --
>> > Hal Finkel
>> > Assistant Computational Scientist
>> > Leadership Computing Facility
>> > Argonne National Laboratory
>>
>> _______________________________________________
>> cfe-dev mailing list
>> cfe-dev@cs.uiuc.edu
>> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-dev
>>
>
>

[Attachment #5 (text/html)]

<div dir="ltr">The proposal of our solution will be published next week. Brief \
introduction:<div><br></div><div><span><span \
style="font-size:14.6666666666667px;font-family:Arial;color:rgb(0,0,0);vertical-align:baseline;white-space:pre-wrap;background-color:transparent">&quot;Basic \
idea is to mark vtable loads with </span><span \
style="font-size:14.6666666666667px;font-family:Arial;color:rgb(0,0,0);font-weight:bol \
d;vertical-align:baseline;white-space:pre-wrap;background-color:transparent">!invariant</span><span \
style="font-size:14.6666666666667px;font-family:Arial;color:rgb(0,0,0);vertical-align:baseline;white-space:pre-wrap;background-color:transparent"> \
, and also put </span><span \
style="font-size:14.6666666666667px;font-family:Arial;color:rgb(0,0,0);font-weight:bol \
d;vertical-align:baseline;white-space:pre-wrap;background-color:transparent">assume()</span><span \
style="font-size:14.6666666666667px;font-family:Arial;color:rgb(0,0,0);vertical-align:baseline;white-space:pre-wrap;background-color:transparent"> \
after calling constructor to show how vtable will look like. Function </span><span \
style="font-size:14.6666666666667px;font-family:Arial;color:rgb(0,0,0);font-weight:bol \
d;vertical-align:baseline;white-space:pre-wrap;background-color:transparent">@llvm.invariant.barrier</span><span \
style="font-size:14.6666666666667px;font-family:Arial;color:rgb(0,0,0);vertical-align:baseline;white-space:pre-wrap;background-color:transparent"> \
that breaks the invariant will be needed to cope with placement new and other cases \
where the vptr is legitimately permitted to \
change.&quot;</span></span><br></div><div><span><span \
style="font-size:14.6666666666667px;font-family:Arial;color:rgb(0,0,0);vertical-align: \
baseline;white-space:pre-wrap;background-color:transparent"><br></span></span></div><div><span><span \
style="font-size:14.6666666666667px;font-family:Arial;color:rgb(0,0,0);vertical-align:baseline;white-space:pre-wrap;background-color:transparent">We \
also want to make some improvements on generating vtables as avaliable_externally - \
for example when there are no virtual inline \
functions</span></span></div><div><span><span \
style="font-size:14.6666666666667px;font-family:Arial;color:rgb(0,0,0);vertical-align: \
baseline;white-space:pre-wrap;background-color:transparent"><br></span></span></div><div><span><span \
style="font-size:14.6666666666667px;font-family:Arial;color:rgb(0,0,0);vertical-align: \
baseline;white-space:pre-wrap;background-color:transparent">Piotr</span></span></div></div><div \
class="gmail_extra"><br><div class="gmail_quote">On Thu, Jul 16, 2015 at 9:11 AM, \
David Blaikie <span dir="ltr">&lt;<a href="mailto:dblaikie@gmail.com" \
target="_blank">dblaikie@gmail.com</a>&gt;</span> wrote:<br><blockquote \
class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc \
solid;padding-left:1ex"><div dir="ltr">I believe Piotr Prazek (cc&#39;d) is working \
with Richard Smith on a proposal/plan for a general device for devirtualization \
(something like a restricted assume for pointer loads, if I understand it correctly - \
as we have nonnull and other attributes for other special cases of \
assume)<br></div><div class="gmail_extra"><br><div class="gmail_quote">On Thu, Jul \
16, 2015 at 8:26 AM, Rafael Espíndola <span dir="ltr">&lt;<a \
href="mailto:rafael.espindola@gmail.com" \
target="_blank">rafael.espindola@gmail.com</a>&gt;</span> wrote:<br><blockquote \
class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc \
solid;padding-left:1ex">My preference for cases like PR16984 would be to change how \
clang<br> finds the vtable. Instead of doing a load from this, have clang<br>
directly use the _ZTV variable when it is known at compile time.<br>
<div><div><br>
<br>
On 15 July 2015 at 23:12, Hal Finkel &lt;<a href="mailto:hfinkel@anl.gov" \
target="_blank">hfinkel@anl.gov</a>&gt; wrote:<br> &gt; Hi Rafael,<br>
&gt;<br>
&gt; Thanks for the list of bug reports. The situations I&#39;ve highlighted are \
indeed PR16984 and PR13227. Do you have any thoughts on a design to fix them? PR16984 \
mentions that it is likely best to put the necessary information into the IR and let \
the optimizer take care of the constant propagation to get rid of the indirect call. \
I agree, this sounds appealing. The question then is what form should that \
information take. I could do this with @llvm.assume, but I&#39;m somewhat afraid of \
littering the IR with them in response to a common core language property.<br> \
&gt;<br> &gt;   -Hal<br>
&gt;<br>
&gt; ----- Original Message -----<br>
&gt;&gt; From: &quot;Rafael Espíndola&quot; &lt;<a \
href="mailto:rafael.espindola@gmail.com" \
target="_blank">rafael.espindola@gmail.com</a>&gt;<br> &gt;&gt; To: &quot;Hal \
Finkel&quot; &lt;<a href="mailto:hfinkel@anl.gov" \
target="_blank">hfinkel@anl.gov</a>&gt;<br> &gt;&gt; Cc: &quot;<a \
href="mailto:cfe-dev@cs.uiuc.edu" target="_blank">cfe-dev@cs.uiuc.edu</a> \
Developers&quot; &lt;<a href="mailto:cfe-dev@cs.uiuc.edu" \
target="_blank">cfe-dev@cs.uiuc.edu</a>&gt;, &quot;Richard Smith&quot; &lt;<a \
href="mailto:richard@metafoo.co.uk" target="_blank">richard@metafoo.co.uk</a>&gt;<br> \
&gt;&gt; Sent: Thursday, July 16, 2015 12:48:05 AM<br> &gt;&gt; Subject: Re: \
[cfe-dev] C++11 and enhacned devirtualization<br> &gt;&gt;<br>
&gt;&gt; There a quite a few open bugs about devirtualization. A quick search<br>
&gt;&gt; finds<br>
&gt;&gt;<br>
&gt;&gt; pr18972, pr3100, pr13227, pr15961, pr15963, pr16984, pr17863,<br>
&gt;&gt; pr19545, pr6747.<br>
&gt;&gt;<br>
&gt;&gt; A fairly important restriction to keep in mind is that the itanium<br>
&gt;&gt; abi<br>
&gt;&gt; requires some vtables to be exported from a given file (the one with<br>
&gt;&gt; the key function), but the functions in those vtables don&#39;t have to<br>
&gt;&gt; be<br>
&gt;&gt; exported.<br>
&gt;&gt;<br>
&gt;&gt; That means that to devirtualize we have to produce a copy, which hits<br>
&gt;&gt; issues with code that wants avoid #including definitions.<br>
&gt;&gt;<br>
&gt;&gt; See the commit message of r189852 for more details.<br>
&gt;&gt;<br>
&gt;&gt; Cheers,<br>
&gt;&gt; Rafael<br>
&gt;&gt;<br>
&gt;&gt;<br>
&gt;&gt; On 15 July 2015 at 22:11, Hal Finkel &lt;<a href="mailto:hfinkel@anl.gov" \
target="_blank">hfinkel@anl.gov</a>&gt; wrote:<br> &gt;&gt; &gt; Hi everyone,<br>
&gt;&gt; &gt;<br>
&gt;&gt; &gt; C++11 added features that allow for certain parts of the class<br>
&gt;&gt; &gt; hierarchy to be closed, specifically the &#39;final&#39; keyword and \
the<br> &gt;&gt; &gt; semantics of anonymous namespaces, and I think we take \
advantage<br> &gt;&gt; &gt; of these to enhance our ability to perform \
devirtualization. For<br> &gt;&gt; &gt; example, given this situation:<br>
&gt;&gt; &gt;<br>
&gt;&gt; &gt; struct Base {<br>
&gt;&gt; &gt;     virtual void foo() = 0;<br>
&gt;&gt; &gt; };<br>
&gt;&gt; &gt;<br>
&gt;&gt; &gt; void external();<br>
&gt;&gt; &gt; struct Final final : Base {<br>
&gt;&gt; &gt;     void foo() {<br>
&gt;&gt; &gt;        external();<br>
&gt;&gt; &gt;     }<br>
&gt;&gt; &gt; };<br>
&gt;&gt; &gt;<br>
&gt;&gt; &gt; void dispatch(Base *B) {<br>
&gt;&gt; &gt;     B-&gt;foo();<br>
&gt;&gt; &gt; }<br>
&gt;&gt; &gt;<br>
&gt;&gt; &gt; void opportunity(Final *F) {<br>
&gt;&gt; &gt;     dispatch(F);<br>
&gt;&gt; &gt; }<br>
&gt;&gt; &gt;<br>
&gt;&gt; &gt; When we optimize this code, we do the expected thing and inline<br>
&gt;&gt; &gt; &#39;dispatch&#39; into &#39;opportunity&#39; but we don&#39;t \
devirtualize the call<br> &gt;&gt; &gt; to foo(). The fact that we know what the \
vtable of F is at that<br> &gt;&gt; &gt; callsite is not exploited. To a lesser \
extent, we can do similar<br> &gt;&gt; &gt; things for final virtual methods, and \
derived classes in anonymous<br> &gt;&gt; &gt; namespaces (because Clang could \
determine whether or not a class<br> &gt;&gt; &gt; (or method) there is effectively \
final).<br> &gt;&gt; &gt;<br>
&gt;&gt; &gt; One possibility might be to @llvm.assume to say something about<br>
&gt;&gt; &gt; what the vtable ptr of F might be/contain should it be needed<br>
&gt;&gt; &gt; later when we emit the initial IR for &#39;opportunity&#39; (and \
then<br> &gt;&gt; &gt; teach the optimizer to use that information), but I&#39;m not \
at all<br> &gt;&gt; &gt; sure that&#39;s the best solution. Thoughts?<br>
&gt;&gt; &gt;<br>
&gt;&gt; &gt; Thanks again,<br>
&gt;&gt; &gt; Hal<br>
&gt;&gt; &gt;<br>
&gt;&gt; &gt; --<br>
&gt;&gt; &gt; Hal Finkel<br>
&gt;&gt; &gt; Assistant Computational Scientist<br>
&gt;&gt; &gt; Leadership Computing Facility<br>
&gt;&gt; &gt; Argonne National Laboratory<br>
&gt;&gt; &gt; _______________________________________________<br>
&gt;&gt; &gt; cfe-dev mailing list<br>
&gt;&gt; &gt; <a href="mailto:cfe-dev@cs.uiuc.edu" \
target="_blank">cfe-dev@cs.uiuc.edu</a><br> &gt;&gt; &gt; <a \
href="http://lists.cs.uiuc.edu/mailman/listinfo/cfe-dev" rel="noreferrer" \
target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/cfe-dev</a><br> \
&gt;&gt;<br> &gt;<br>
&gt; --<br>
&gt; Hal Finkel<br>
&gt; Assistant Computational Scientist<br>
&gt; Leadership Computing Facility<br>
&gt; Argonne National Laboratory<br>
<br>
_______________________________________________<br>
cfe-dev mailing list<br>
<a href="mailto:cfe-dev@cs.uiuc.edu" target="_blank">cfe-dev@cs.uiuc.edu</a><br>
<a href="http://lists.cs.uiuc.edu/mailman/listinfo/cfe-dev" rel="noreferrer" \
target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/cfe-dev</a><br> \
</div></div></blockquote></div><br></div> </blockquote></div><br></div>



_______________________________________________
cfe-dev mailing list
cfe-dev@cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-dev


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic