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

Nick Lewycky nlewycky at google.com
Thu May 9 21:22:54 PDT 2013


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
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20130509/06228a9a/attachment.html>


More information about the llvm-dev mailing list