<div dir="ltr">"
but the compiler cannot make that assumption because the C++ Standard technically permits a virtual method to destroy and re-create `b` with a completely different dynamic type." - thanks, I wasn't aware of this. I'll look into the smart pointer lifetime optimizations thread soon.</div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Tue, Jun 16, 2020 at 6:27 PM Arthur O'Dwyer <<a href="mailto:arthur.j.odwyer@gmail.com">arthur.j.odwyer@gmail.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr">On Tue, Jun 16, 2020 at 2:31 AM Ninu-Ciprian Marginean via cfe-dev <<a href="mailto:cfe-dev@lists.llvm.org" target="_blank">cfe-dev@lists.llvm.org</a>> wrote:<br></div><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr"><div><br></div><div>I have a virtual function call in a loop. All the time, the same method is called:<br></div><div><a href="https://godbolt.org/z/WFp2rm" target="_blank">https://godbolt.org/z/WFp2rm</a> </div><div><br></div><div>The loop is in method work; the virtual call is to method id.</div><div><br></div><div>We can see that method work gets inlined, but inside the loop, there are always two pointer dereferences:</div><div><span style="background-color:rgb(255,255,254);font-family:"Consolas, ";color:rgb(0,0,255)">mov</span><span style="background-color:rgb(255,255,254);color:rgb(0,0,0);font-family:"Consolas, ""> </span><span style="background-color:rgb(255,255,254);font-family:"Consolas, ";color:rgb(72,100,170)">rax</span><span style="background-color:rgb(255,255,254);color:rgb(0,0,0);font-family:"Consolas, "">, </span><span style="background-color:rgb(255,255,254);font-family:"Consolas, ";color:rgb(0,128,128)">qword</span><span style="background-color:rgb(255,255,254);color:rgb(0,0,0);font-family:"Consolas, ""> </span><span style="background-color:rgb(255,255,254);font-family:"Consolas, ";color:rgb(0,128,128)">ptr</span><span style="background-color:rgb(255,255,254);color:rgb(0,0,0);font-family:"Consolas, ""> [</span><span style="background-color:rgb(255,255,254);font-family:"Consolas, ";color:rgb(72,100,170)">r14</span><span style="background-color:rgb(255,255,254);color:rgb(0,0,0);font-family:"Consolas, "">]</span></div><div><span style="background-color:rgb(255,255,254);font-family:"Consolas, ";color:rgb(0,0,255)">call</span><span style="background-color:rgb(255,255,254);color:rgb(0,0,0);font-family:"Consolas, ""> </span><span style="background-color:rgb(255,255,254);font-family:"Consolas, ";color:rgb(0,128,128)">qword</span><span style="background-color:rgb(255,255,254);color:rgb(0,0,0);font-family:"Consolas, ""> </span><span style="background-color:rgb(255,255,254);font-family:"Consolas, ";color:rgb(0,128,128)">ptr</span><span style="background-color:rgb(255,255,254);color:rgb(0,0,0);font-family:"Consolas, ""> [</span><span style="background-color:rgb(255,255,254);font-family:"Consolas, ";color:rgb(72,100,170)">rax</span><span style="background-color:rgb(255,255,254);color:rgb(0,0,0);font-family:"Consolas, "">]</span></div><div><br></div><div>Since the object referred to by b, never changes to a different object, this could(at least in this case), be cached.</div></div></blockquote><div><br></div><div>I believe that this is a similar problem to what was recently discussed in the thread titled "[cfe-dev] Smart Pointer Lifetime Optimizations". In this case (as in that case), the human programmer knows that the call to `b->do_id()` does not actually change the value of b's vptr; but the compiler cannot make that assumption because the C++ Standard technically permits a virtual method to destroy and re-create `b` with a completely different dynamic type.</div><div><br></div><div>As in the smart-pointer case, Clang provides a "noescape" attribute that addresses half of the problem, but doesn't provide any "really_const" attribute that allows the human programmer to say "Look, I promise that this function call <i><b>really does not change</b></i> its argument!" (I think LLVM's `readonly` attribute would help, but Clang does not expose that attribute to the C++ programmer.)</div><div>I tried slapping all the attributes I could think of onto this member function — noescape, const, pure — and none of them helped.</div><div><a href="https://godbolt.org/z/arzMYD" target="_blank">https://godbolt.org/z/arzMYD</a><br></div><div>Even marking the stack objects as `const` didn't help, which surprises me in this case:</div><div><a href="https://godbolt.org/z/CpMMkd" target="_blank">https://godbolt.org/z/CpMMkd</a></div><div><br></div><div>–Arthur</div></div></div></div></div>
</blockquote></div>