[cfe-dev] [LLVMdev] "load groups" IR feature to improve C++ devirtualization

Nick Lewycky nlewycky at google.com
Fri May 10 00:22:25 PDT 2013

On 9 May 2013 22:37, Owen Anderson <resistor at mac.com> wrote:

> Hi Nick,
> Won't this approach run into problems with inlining, unrolling, or just
> about anything that duplicates code?  Suppose I have a bunch of loads of
> the same load group in the body of the loop, but update the pointer they're
> dereferencing on the backedge.  If that loop gets unrolled, all the loads
> in the unrolled copies will have the same load group, but it would not be
> correct to replace loads from the first iteration with loads from the
> second iteration.

No, @llvm.load.group returns a new group each time it's run. We'll
unroll/inline/duplicate that call with the rest of the loads.


On May 9, 2013, at 9:22 PM, Nick Lewycky <nlewycky at google.com> wrote:
> On 9 May 2013 19:13, John McCall <rjmccall at apple.com> wrote:
>> On May 9, 2013, at 6:34 PM, Nick Lewycky <nlewycky at google.com> wrote:
>> > I'm looking into how we can improve devirtualization in clang, and
>> there a language in C++ feature I'd like to take advantage of which would
>> let us perform elimination of more vptr loads. In this code:
>> >
>> >   Cls *p = new Cls;
>> >   p->virtual_method1();
>> >   p->method_changing_vptr();  // uses placement new to legally change
>> the vptr
>> >   p->virtual_method2();  // invalid!
>> >   Cls *q = p;
>> >   q->virtual_method2();  // this must get a new vptr lookup.
> I bungled my example, and I want to fix that first. I was thinking:
>   Derived *p = new Derived;
>   p->virtual_method1();
>   p->method_changing_vptr();  // uses placement new to legally change the
> vptr to Base
>   p->virtual_method2();  // invalid!
>   Base *q = p;
>   q->virtual_method2();  // this must get a new vptr lookup.
> which doesn't address your concerns.
> This is not how I understand the [basic.life] rules.  The question is
>> whether a pointer value, reference, or name is formally forwarded to point
>> to the new object.  Because the dynamic type is different, the pointer
>> value held in 'p' is not updated.  Copying that value into 'q' does not
>> change the fact that the pointer value still refers to a non-existent
>> object.
> I'm actually okay with the simple copy not forming a new object pointer.
> However, "Base *q = reinterpret_cast<Base*>(p);" really ought to.
> It is unclear what, exactly, under the rules constitutes forming a valid
>> pointer to the newly-constructed object except using the result of the
>> new-expression itself.  I think an explicit cast might, ignoring all
>> "object-ness" of the source pointer and simply treating it formally as a
>> pointer to some storage that you are casting to the type of an object
>> stored there?
> I want to make optimizations to the program that people can't object to
> through a cursory reading of the standard, which is made difficult by the
> standard being contradictory on many relevant points here. Ultimately I've
> chosen to be very liberal about what I'm allowing to be considered a newly
> formed valid pointer.
> BTW, Richard came up with a wonderful example. What do you make of this?:
>   char alignas(A, B) buffer[max(sizeof(A), sizeof(B))];
>   A *a = reinterpret_cast<A*>(buffer);
>   B *b = reinterpret_cast<B*>(buffer);
>   new(buffer) A;
>   a->vfn();
>   new(buffer) B;
>   b->vfn();
> Valid?
> Nick
> _______________________________________________
> LLVM Developers mailing list
> LLVMdev at cs.uiuc.edu         http://llvm.cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20130510/3013d69d/attachment.html>

More information about the cfe-dev mailing list