<div dir="ltr"><div class="gmail_extra"><div class="gmail_quote">On 9 May 2013 22:37, Owen Anderson <span dir="ltr"><<a href="mailto:resistor@mac.com" target="_blank">resistor@mac.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">

<div style="word-wrap:break-word">Hi Nick,<div><br></div><div>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.</div>

</div></blockquote><div><br></div><div>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.<br><br>Nick<br><br></div><blockquote class="gmail_quote" style="margin:0pt 0pt 0pt 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">

<div style="word-wrap:break-word">On May 9, 2013, at 9:22 PM, Nick Lewycky <<a href="mailto:nlewycky@google.com" target="_blank">nlewycky@google.com</a>> wrote:<div><div><div><div class="h5"><br></div></div><blockquote type="cite">

<div><div class="h5"><div dir="ltr">On 9 May 2013 19:13, John McCall <span dir="ltr"><<a href="mailto:rjmccall@apple.com" target="_blank">rjmccall@apple.com</a>></span> wrote:<br><div class="gmail_extra"><div class="gmail_quote">

<blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">


<div>On May 9, 2013, at 6:34 PM, Nick Lewycky <<a href="mailto:nlewycky@google.com" target="_blank">nlewycky@google.com</a>> wrote:<br>
> 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:<br>
><br>
>   Cls *p = new Cls;<br>
>   p->virtual_method1();<br>
>   p->method_changing_vptr();  // uses placement new to legally change the vptr<br>
>   p->virtual_method2();  // invalid!<br>
>   Cls *q = p;<br>
>   q->virtual_method2();  // this must get a new vptr lookup.<br></div></blockquote><div><br></div><div class="gmail_quote"><div>I bungled my example, and I want to fix that first. I was thinking:</div><div class="gmail_quote">




<br></div>  Derived *p = new Derived;<br>  p->virtual_method1();<br>  p->method_changing_vptr();  // uses placement new to legally change the vptr to Base<br>  p->virtual_method2();  // invalid!<br>  Base *q = p;<br>




  q->virtual_method2();  // this must get a new vptr lookup.</div><div class="gmail_quote"><br></div><div class="gmail_quote">which doesn't address your concerns.</div><div class="gmail_quote"><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">




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.<br>




</blockquote><div><br></div><div><div class="gmail_quote">I'm actually okay with the simple copy not forming a new object pointer. However, "Base *q = reinterpret_cast<Base*>(p);" really ought to.</div>




<div class="gmail_quote"><br></div><div class="gmail_quote"></div></div></div><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">




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?<br>




</blockquote><div><br></div><div>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.</div>




<div><br></div><div>BTW, Richard came up with a wonderful example. What do you make of this?:<br></div><div><div><br></div><div>  char alignas(A, B) buffer[max(sizeof(A), sizeof(B))];</div><div>  A *a = reinterpret_cast<A*>(buffer);</div>



<div>  B *b = reinterpret_cast<B*>(buffer);<br></div><div>  new(buffer) A;</div><div>  a->vfn();</div><div>  new(buffer) B;</div><div>  b->vfn();</div><div><br></div><div>

Valid?</div><div><br></div><div>Nick<br></div><div><br></div></div></div></div></div></div></div>
_______________________________________________<br>LLVM Developers mailing list<br><a href="mailto:LLVMdev@cs.uiuc.edu" target="_blank">LLVMdev@cs.uiuc.edu</a>         <a href="http://llvm.cs.uiuc.edu" target="_blank">http://llvm.cs.uiuc.edu</a><br>

<a href="http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev</a><br></blockquote></div><br></div></div></blockquote></div><br></div></div>