<div dir="ltr"><br><div class="gmail_extra"><br><div class="gmail_quote">2017-01-30 18:38 GMT+01:00 Richard Smith <span dir="ltr"><<a href="mailto:richard@metafoo.co.uk" target="_blank">richard@metafoo.co.uk</a>></span>:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="auto"><div><div class="gmail-h5"><div><div class="gmail_extra"><div class="gmail_quote">On 20 Jan 2017 8:07 am, "Piotr Padlewski" <<a href="mailto:piotr.padlewski@gmail.com" target="_blank">piotr.padlewski@gmail.com</a>> wrote:<br type="attribution"><blockquote class="gmail-m_7695891327250848386quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr"><span id="gmail-m_7695891327250848386m_-8131894752840521725gmail-docs-internal-guid-f4b3e122-bc9b-30cb-5204-c95e1095750e"><p dir="ltr" style="text-align:left;line-height:1.38;margin-top:0pt;margin-bottom:3pt"><span style="background-color:transparent;color:rgb(0,0,0);font-family:arial;font-size:14.6667px;white-space:pre-wrap">Hi all,</span></p><p dir="ltr" style="text-align:left;line-height:1.38;margin-top:0pt;margin-bottom:3pt"><span style="background-color:transparent;color:rgb(0,0,0);font-family:arial;font-size:14.6667px;white-space:pre-wrap">I would like to propose a new way clang would decorate vtable loads in order to handle devirtualization better.</span></p><p dir="ltr" style="text-align:left;line-height:1.38;margin-top:0pt;margin-bottom:3pt"><span style="background-color:transparent;color:rgb(0,0,0);font-family:arial;font-size:14.6667px;white-space:pre-wrap">I've added <b>llvm-dev</b> also, because this can start a discussion about changing invariant.group to just invariant. </span></p><p dir="ltr" style="text-align:left;line-height:1.38;margin-top:0pt;margin-bottom:3pt"><span style="background-color:transparent;color:rgb(0,0,0);font-family:arial;font-size:14.6667px;white-space:pre-wrap">PDF version of this RFC can be found here:</span></p><p dir="ltr" style="text-align:left;line-height:1.38;margin-top:0pt;margin-bottom:3pt"><a href="https://drive.google.com/file/d/0B72TmzNsY6Z8ZmpOUnB5dDZfSFU/view?usp=sharing" style="font-size:14.6667px;white-space:pre-wrap;font-family:arial;background-color:transparent" target="_blank">https://drive.google.com/file/<wbr>d/0B72TmzNsY6Z8ZmpOUnB5dDZfSFU<wbr>/view?usp=sharing</a></p><h2 style="line-height:1.38;margin-top:18pt;margin-bottom:6pt"><p style="line-height:1.38;margin-top:0pt;margin-bottom:0pt"><span style="background-color:transparent;color:rgb(0,0,0);font-family:arial;font-size:21.3333px;font-weight:400;white-space:pre-wrap"><br></span></p><p style="line-height:1.38;margin-top:0pt;margin-bottom:0pt"><span style="background-color:transparent;color:rgb(0,0,0);font-family:arial;font-size:21.3333px;font-weight:400;white-space:pre-wrap">Background:</span><br></p></h2><p dir="ltr" style="line-height:1.38;margin-top:0pt;margin-bottom:0pt"><span style="font-size:14.6667px;font-family:arial;color:rgb(0,0,0);background-color:transparent;vertical-align:baseline;white-space:pre-wrap">Initial old design:</span></p><p dir="ltr" style="line-height:1.38;margin-top:0pt;margin-bottom:0pt"><a href="http://lists.llvm.org/pipermail/cfe-dev/2015-July/044227.html" style="text-decoration:none" target="_blank"><span style="font-size:14.6667px;font-family:arial;background-color:transparent;text-decoration:underline;vertical-align:baseline;white-space:pre-wrap">http://lists.llvm.org/pipermai<wbr>l/cfe-dev/2015-July/044227.<wbr>html</span></a></p><p dir="ltr" style="line-height:1.38;margin-top:0pt;margin-bottom:0pt"><span style="font-size:14.6667px;font-family:arial;color:rgb(0,0,0);background-color:transparent;vertical-align:baseline;white-space:pre-wrap">My talk from LLVM Dev Meeting</span></p><p dir="ltr" style="line-height:1.38;margin-top:0pt;margin-bottom:0pt"><span style="font-size:14.6667px;font-family:arial;color:rgb(0,0,0);background-color:transparent;vertical-align:baseline;white-space:pre-wrap"><a href="http://llvm.org/devmtg/2016-11/#talk6" target="_blank">http://llvm.org/devmtg/2016-11<wbr>/#talk6</a></span></p><br><h2 dir="ltr" style="line-height:1.38;margin-top:18pt;margin-bottom:6pt"><span style="font-size:21.3333px;font-family:arial;color:rgb(0,0,0);background-color:transparent;font-weight:400;vertical-align:baseline;white-space:pre-wrap">The problem</span></h2><p dir="ltr" style="line-height:1.38;margin-top:0pt;margin-bottom:0pt"><span style="font-size:14.6667px;font-family:arial;color:rgb(0,0,0);background-color:transparent;vertical-align:baseline;white-space:pre-wrap">Clang with </span><span style="font-size:14.6667px;font-family:arial;color:rgb(0,0,0);background-color:transparent;font-weight:700;vertical-align:baseline;white-space:pre-wrap">-fstrict-vtable-pointers </span><span style="font-size:14.6667px;font-family:arial;color:rgb(0,0,0);background-color:transparent;vertical-align:baseline;white-space:pre-wrap">decorates vtable loads with metadata corresponding to mangled pointer type name like:</span></p><br><p dir="ltr" style="line-height:1.32955;margin-top:0pt;margin-bottom:0pt"><span style="font-size:14.6667px;font-family:arial;color:rgb(51,51,153);background-color:transparent;font-weight:700;vertical-align:baseline;white-space:pre-wrap">void</span><span style="font-size:14.6667px;font-family:arial;color:rgb(51,51,51);background-color:transparent;vertical-align:baseline;white-space:pre-wrap"> </span><span style="font-size:14.6667px;font-family:arial;color:rgb(0,102,187);background-color:transparent;font-weight:700;vertical-align:baseline;white-space:pre-wrap">g</span><span style="font-size:14.6667px;font-family:arial;color:rgb(51,51,51);background-color:transparent;vertical-align:baseline;white-space:pre-wrap">(A& a){</span><span style="font-size:14.6667px;font-family:arial;color:rgb(51,51,51);background-color:transparent;vertical-align:baseline;white-space:pre-wrap"><br class="gmail-m_7695891327250848386m_-8131894752840521725gmail-kix-line-break"></span><span style="font-size:14.6667px;font-family:arial;color:rgb(51,51,51);background-color:transparent;vertical-align:baseline;white-space:pre-wrap">    a.foo();</span><span style="font-size:14.6667px;font-family:arial;color:rgb(51,51,51);background-color:transparent;vertical-align:baseline;white-space:pre-wrap"><br class="gmail-m_7695891327250848386m_-8131894752840521725gmail-kix-line-break"></span><span style="font-size:14.6667px;font-family:arial;color:rgb(51,51,51);background-color:transparent;vertical-align:baseline;white-space:pre-wrap">}</span></p><br><br><p dir="ltr" style="line-height:1.32955;margin-top:0pt;margin-bottom:0pt"><span style="font-size:14.6667px;font-family:arial;color:rgb(51,51,51);background-color:transparent;vertical-align:baseline;white-space:pre-wrap">define </span><span style="font-size:14.6667px;font-family:arial;color:rgb(51,51,153);background-color:transparent;font-weight:700;vertical-align:baseline;white-space:pre-wrap">void</span><span style="font-size:14.6667px;font-family:arial;color:rgb(51,51,51);background-color:transparent;vertical-align:baseline;white-space:pre-wrap"> </span><span style="font-size:14.6667px;font-family:arial;color:rgb(255,0,0);background-color:rgb(255,170,170);vertical-align:baseline;white-space:pre-wrap">@</span><span style="font-size:14.6667px;font-family:arial;color:rgb(51,51,51);background-color:transparent;vertical-align:baseline;white-space:pre-wrap">_Z1gR1A(%</span><span style="font-size:14.6667px;font-family:arial;color:rgb(0,136,0);background-color:transparent;font-weight:700;vertical-align:baseline;white-space:pre-wrap">struct</span><span style="font-size:14.6667px;font-family:arial;color:rgb(51,51,51);background-color:transparent;vertical-align:baseline;white-space:pre-wrap">.A* dereferenceable(</span><span style="font-size:14.6667px;font-family:arial;color:rgb(0,0,221);background-color:transparent;font-weight:700;vertical-align:baseline;white-space:pre-wrap">8</span><span style="font-size:14.6667px;font-family:arial;color:rgb(51,51,51);background-color:transparent;vertical-align:baseline;white-space:pre-wrap">) %a) local_unnamed_addr </span><span style="font-size:14.6667px;font-family:arial;color:rgb(255,0,0);background-color:rgb(255,170,170);vertical-align:baseline;white-space:pre-wrap">#</span><span style="font-size:14.6667px;font-family:arial;color:rgb(0,0,221);background-color:transparent;font-weight:700;vertical-align:baseline;white-space:pre-wrap">0</span><span style="font-size:14.6667px;font-family:arial;color:rgb(51,51,51);background-color:transparent;vertical-align:baseline;white-space:pre-wrap"> {</span><span style="font-size:14.6667px;font-family:arial;color:rgb(51,51,51);background-color:transparent;vertical-align:baseline;white-space:pre-wrap"><br class="gmail-m_7695891327250848386m_-8131894752840521725gmail-kix-line-break"></span><span style="font-size:14.6667px;font-family:arial;color:rgb(153,119,0);background-color:transparent;font-weight:700;vertical-align:baseline;white-space:pre-wrap">entry:</span><span style="font-size:14.6667px;font-family:arial;color:rgb(51,51,51);background-color:transparent;vertical-align:baseline;white-space:pre-wrap"><br class="gmail-m_7695891327250848386m_-8131894752840521725gmail-kix-line-break"></span><span style="font-size:14.6667px;font-family:arial;color:rgb(51,51,51);background-color:transparent;vertical-align:baseline;white-space:pre-wrap">  %</span><span style="font-size:14.6667px;font-family:arial;color:rgb(0,0,221);background-color:transparent;font-weight:700;vertical-align:baseline;white-space:pre-wrap">0</span><span style="font-size:14.6667px;font-family:arial;color:rgb(51,51,51);background-color:transparent;vertical-align:baseline;white-space:pre-wrap"> = bitcast %</span><span style="font-size:14.6667px;font-family:arial;color:rgb(0,136,0);background-color:transparent;font-weight:700;vertical-align:baseline;white-space:pre-wrap">struct</span><span style="font-size:14.6667px;font-family:arial;color:rgb(51,51,51);background-color:transparent;vertical-align:baseline;white-space:pre-wrap">.A* %a to </span><span style="font-size:14.6667px;font-family:arial;color:rgb(51,51,153);background-color:transparent;font-weight:700;vertical-align:baseline;white-space:pre-wrap">void</span><span style="font-size:14.6667px;font-family:arial;color:rgb(51,51,51);background-color:transparent;vertical-align:baseline;white-space:pre-wrap"> (%</span><span style="font-size:14.6667px;font-family:arial;color:rgb(0,136,0);background-color:transparent;font-weight:700;vertical-align:baseline;white-space:pre-wrap">struct</span><span style="font-size:14.6667px;font-family:arial;color:rgb(51,51,51);background-color:transparent;vertical-align:baseline;white-space:pre-wrap">.A*)***</span><span style="font-size:14.6667px;font-family:arial;color:rgb(51,51,51);background-color:transparent;vertical-align:baseline;white-space:pre-wrap"><br class="gmail-m_7695891327250848386m_-8131894752840521725gmail-kix-line-break"></span><span style="font-size:14.6667px;font-family:arial;color:rgb(51,51,51);background-color:transparent;vertical-align:baseline;white-space:pre-wrap">  %vtable = load </span><span style="font-size:14.6667px;font-family:arial;color:rgb(51,51,153);background-color:transparent;font-weight:700;vertical-align:baseline;white-space:pre-wrap">void</span><span style="font-size:14.6667px;font-family:arial;color:rgb(51,51,51);background-color:transparent;vertical-align:baseline;white-space:pre-wrap"> (%</span><span style="font-size:14.6667px;font-family:arial;color:rgb(0,136,0);background-color:transparent;font-weight:700;vertical-align:baseline;white-space:pre-wrap">struct</span><span style="font-size:14.6667px;font-family:arial;color:rgb(51,51,51);background-color:transparent;vertical-align:baseline;white-space:pre-wrap">.A*)**, </span><span style="font-size:14.6667px;font-family:arial;color:rgb(51,51,153);background-color:transparent;font-weight:700;vertical-align:baseline;white-space:pre-wrap">void</span><span style="font-size:14.6667px;font-family:arial;color:rgb(51,51,51);background-color:transparent;vertical-align:baseline;white-space:pre-wrap"> (%</span><span style="font-size:14.6667px;font-family:arial;color:rgb(0,136,0);background-color:transparent;font-weight:700;vertical-align:baseline;white-space:pre-wrap">struct</span><span style="font-size:14.6667px;font-family:arial;color:rgb(51,51,51);background-color:transparent;vertical-align:baseline;white-space:pre-wrap">.A*)*** %</span><span style="font-size:14.6667px;font-family:arial;color:rgb(0,0,221);background-color:transparent;font-weight:700;vertical-align:baseline;white-space:pre-wrap">0</span><span style="font-size:14.6667px;font-family:arial;color:rgb(51,51,51);background-color:transparent;vertical-align:baseline;white-space:pre-wrap">, !invariant.group !</span><span style="font-size:14.6667px;font-family:arial;color:rgb(0,0,221);background-color:transparent;font-weight:700;vertical-align:baseline;white-space:pre-wrap">7</span><span style="font-size:14.6667px;font-family:arial;color:rgb(51,51,51);background-color:transparent;vertical-align:baseline;white-space:pre-wrap"><br class="gmail-m_7695891327250848386m_-8131894752840521725gmail-kix-line-break"></span><span style="font-size:14.6667px;font-family:arial;color:rgb(51,51,51);background-color:transparent;vertical-align:baseline;white-space:pre-wrap">  %</span><span style="font-size:14.6667px;font-family:arial;color:rgb(0,0,221);background-color:transparent;font-weight:700;vertical-align:baseline;white-space:pre-wrap">1</span><span style="font-size:14.6667px;font-family:arial;color:rgb(51,51,51);background-color:transparent;vertical-align:baseline;white-space:pre-wrap"> = load </span><span style="font-size:14.6667px;font-family:arial;color:rgb(51,51,153);background-color:transparent;font-weight:700;vertical-align:baseline;white-space:pre-wrap">void</span><span style="font-size:14.6667px;font-family:arial;color:rgb(51,51,51);background-color:transparent;vertical-align:baseline;white-space:pre-wrap"> (%</span><span style="font-size:14.6667px;font-family:arial;color:rgb(0,136,0);background-color:transparent;font-weight:700;vertical-align:baseline;white-space:pre-wrap">struct</span><span style="font-size:14.6667px;font-family:arial;color:rgb(51,51,51);background-color:transparent;vertical-align:baseline;white-space:pre-wrap">.A*)*, </span><span style="font-size:14.6667px;font-family:arial;color:rgb(51,51,153);background-color:transparent;font-weight:700;vertical-align:baseline;white-space:pre-wrap">void</span><span style="font-size:14.6667px;font-family:arial;color:rgb(51,51,51);background-color:transparent;vertical-align:baseline;white-space:pre-wrap"> (%</span><span style="font-size:14.6667px;font-family:arial;color:rgb(0,136,0);background-color:transparent;font-weight:700;vertical-align:baseline;white-space:pre-wrap">struct</span><span style="font-size:14.6667px;font-family:arial;color:rgb(51,51,51);background-color:transparent;vertical-align:baseline;white-space:pre-wrap">.A*)** %vtable</span><span style="font-size:14.6667px;font-family:arial;color:rgb(51,51,51);background-color:transparent;vertical-align:baseline;white-space:pre-wrap"><br class="gmail-m_7695891327250848386m_-8131894752840521725gmail-kix-line-break"></span><span style="font-size:14.6667px;font-family:arial;color:rgb(51,51,51);background-color:transparent;vertical-align:baseline;white-space:pre-wrap">  tail call </span><span style="font-size:14.6667px;font-family:arial;color:rgb(51,51,153);background-color:transparent;font-weight:700;vertical-align:baseline;white-space:pre-wrap">void</span><span style="font-size:14.6667px;font-family:arial;color:rgb(51,51,51);background-color:transparent;vertical-align:baseline;white-space:pre-wrap"> %</span><span style="font-size:14.6667px;font-family:arial;color:rgb(0,0,221);background-color:transparent;font-weight:700;vertical-align:baseline;white-space:pre-wrap">1</span><span style="font-size:14.6667px;font-family:arial;color:rgb(51,51,51);background-color:transparent;vertical-align:baseline;white-space:pre-wrap">(%</span><span style="font-size:14.6667px;font-family:arial;color:rgb(0,136,0);background-color:transparent;font-weight:700;vertical-align:baseline;white-space:pre-wrap">struct</span><span style="font-size:14.6667px;font-family:arial;color:rgb(51,51,51);background-color:transparent;vertical-align:baseline;white-space:pre-wrap">.A* nonnull %a)</span><span style="font-size:14.6667px;font-family:arial;color:rgb(51,51,51);background-color:transparent;vertical-align:baseline;white-space:pre-wrap"><br class="gmail-m_7695891327250848386m_-8131894752840521725gmail-kix-line-break"></span><span style="font-size:14.6667px;font-family:arial;color:rgb(51,51,51);background-color:transparent;vertical-align:baseline;white-space:pre-wrap">  ret </span><span style="font-size:14.6667px;font-family:arial;color:rgb(51,51,153);background-color:transparent;font-weight:700;vertical-align:baseline;white-space:pre-wrap">void</span><span style="font-size:14.6667px;font-family:arial;color:rgb(51,51,51);background-color:transparent;vertical-align:baseline;white-space:pre-wrap"><br class="gmail-m_7695891327250848386m_-8131894752840521725gmail-kix-line-break"></span><span style="font-size:14.6667px;font-family:arial;color:rgb(51,51,51);background-color:transparent;vertical-align:baseline;white-space:pre-wrap">}</span><span style="font-size:14.6667px;font-family:arial;color:rgb(51,51,51);background-color:transparent;vertical-align:baseline;white-space:pre-wrap"><br class="gmail-m_7695891327250848386m_-8131894752840521725gmail-kix-line-break"></span><span style="font-size:14.6667px;font-family:arial;color:rgb(51,51,51);background-color:transparent;vertical-align:baseline;white-space:pre-wrap"><br class="gmail-m_7695891327250848386m_-8131894752840521725gmail-kix-line-break"></span><span style="font-size:14.6667px;font-family:arial;color:rgb(51,51,51);background-color:transparent;vertical-align:baseline;white-space:pre-wrap">!</span><span style="font-size:14.6667px;font-family:arial;color:rgb(0,0,221);background-color:transparent;font-weight:700;vertical-align:baseline;white-space:pre-wrap">7</span><span style="font-size:14.6667px;font-family:arial;color:rgb(51,51,51);background-color:transparent;vertical-align:baseline;white-space:pre-wrap"> = !{!</span><span style="font-size:14.6667px;font-family:arial;color:rgb(51,51,51);background-color:rgb(255,240,240);vertical-align:baseline;white-space:pre-wrap">"_ZTS1A"</span><span style="font-size:14.6667px;font-family:arial;color:rgb(51,51,51);background-color:transparent;vertical-align:baseline;white-space:pre-wrap">}</span></p><br><br><br><p dir="ltr" style="line-height:1.38;margin-top:0pt;margin-bottom:0pt"><span style="font-size:14.6667px;font-family:arial;color:rgb(0,0,0);background-color:transparent;vertical-align:baseline;white-space:pre-wrap">This works well if the pointer type doesn’t change, but when it does, devirtualization might not happen like here:</span></p><br><p dir="ltr" style="line-height:1.32955;margin-top:0pt;margin-bottom:0pt"><span style="font-size:14.6667px;font-family:arial;color:rgb(0,136,0);background-color:transparent;font-weight:700;vertical-align:baseline;white-space:pre-wrap">struct</span><span style="font-size:14.6667px;font-family:arial;color:rgb(51,51,51);background-color:transparent;vertical-align:baseline;white-space:pre-wrap"> A {</span><span style="font-size:14.6667px;font-family:arial;color:rgb(51,51,51);background-color:transparent;vertical-align:baseline;white-space:pre-wrap"><br class="gmail-m_7695891327250848386m_-8131894752840521725gmail-kix-line-break"></span><span style="font-size:14.6667px;font-family:arial;color:rgb(51,51,51);background-color:transparent;vertical-align:baseline;white-space:pre-wrap">    A();</span><span style="font-size:14.6667px;font-family:arial;color:rgb(51,51,51);background-color:transparent;vertical-align:baseline;white-space:pre-wrap"><br class="gmail-m_7695891327250848386m_-8131894752840521725gmail-kix-line-break"></span><span style="font-size:14.6667px;font-family:arial;color:rgb(51,51,51);background-color:transparent;vertical-align:baseline;white-space:pre-wrap">    </span><span style="font-size:14.6667px;font-family:arial;color:rgb(0,136,0);background-color:transparent;font-weight:700;vertical-align:baseline;white-space:pre-wrap">virtual</span><span style="font-size:14.6667px;font-family:arial;color:rgb(51,51,51);background-color:transparent;vertical-align:baseline;white-space:pre-wrap"> </span><span style="font-size:14.6667px;font-family:arial;color:rgb(51,51,153);background-color:transparent;font-weight:700;vertical-align:baseline;white-space:pre-wrap">void</span><span style="font-size:14.6667px;font-family:arial;color:rgb(51,51,51);background-color:transparent;vertical-align:baseline;white-space:pre-wrap"> </span><span style="font-size:14.6667px;font-family:arial;color:rgb(0,102,187);background-color:transparent;font-weight:700;vertical-align:baseline;white-space:pre-wrap">foo</span><span style="font-size:14.6667px;font-family:arial;color:rgb(51,51,51);background-color:transparent;vertical-align:baseline;white-space:pre-wrap">();</span><span style="font-size:14.6667px;font-family:arial;color:rgb(51,51,51);background-color:transparent;vertical-align:baseline;white-space:pre-wrap"><br class="gmail-m_7695891327250848386m_-8131894752840521725gmail-kix-line-break"></span><span style="font-size:14.6667px;font-family:arial;color:rgb(51,51,51);background-color:transparent;vertical-align:baseline;white-space:pre-wrap">};</span><span style="font-size:14.6667px;font-family:arial;color:rgb(51,51,51);background-color:transparent;vertical-align:baseline;white-space:pre-wrap"><br class="gmail-m_7695891327250848386m_-8131894752840521725gmail-kix-line-break"></span><span style="font-size:14.6667px;font-family:arial;color:rgb(0,136,0);background-color:transparent;font-weight:700;vertical-align:baseline;white-space:pre-wrap">struct</span><span style="font-size:14.6667px;font-family:arial;color:rgb(51,51,51);background-color:transparent;vertical-align:baseline;white-space:pre-wrap"> B : A{</span><span style="font-size:14.6667px;font-family:arial;color:rgb(51,51,51);background-color:transparent;vertical-align:baseline;white-space:pre-wrap"><br class="gmail-m_7695891327250848386m_-8131894752840521725gmail-kix-line-break"></span><span style="font-size:14.6667px;font-family:arial;color:rgb(51,51,51);background-color:transparent;vertical-align:baseline;white-space:pre-wrap">    B();</span><span style="font-size:14.6667px;font-family:arial;color:rgb(51,51,51);background-color:transparent;vertical-align:baseline;white-space:pre-wrap"><br class="gmail-m_7695891327250848386m_-8131894752840521725gmail-kix-line-break"></span><span style="font-size:14.6667px;font-family:arial;color:rgb(51,51,51);background-color:transparent;vertical-align:baseline;white-space:pre-wrap">    </span><span style="font-size:14.6667px;font-family:arial;color:rgb(0,136,0);background-color:transparent;font-weight:700;vertical-align:baseline;white-space:pre-wrap">virtual</span><span style="font-size:14.6667px;font-family:arial;color:rgb(51,51,51);background-color:transparent;vertical-align:baseline;white-space:pre-wrap"> </span><span style="font-size:14.6667px;font-family:arial;color:rgb(51,51,153);background-color:transparent;font-weight:700;vertical-align:baseline;white-space:pre-wrap">void</span><span style="font-size:14.6667px;font-family:arial;color:rgb(51,51,51);background-color:transparent;vertical-align:baseline;white-space:pre-wrap"> </span><span style="font-size:14.6667px;font-family:arial;color:rgb(0,102,187);background-color:transparent;font-weight:700;vertical-align:baseline;white-space:pre-wrap">foo</span><span style="font-size:14.6667px;font-family:arial;color:rgb(51,51,51);background-color:transparent;vertical-align:baseline;white-space:pre-wrap">();</span><span style="font-size:14.6667px;font-family:arial;color:rgb(51,51,51);background-color:transparent;vertical-align:baseline;white-space:pre-wrap"><br class="gmail-m_7695891327250848386m_-8131894752840521725gmail-kix-line-break"></span><span style="font-size:14.6667px;font-family:arial;color:rgb(51,51,51);background-color:transparent;vertical-align:baseline;white-space:pre-wrap">};</span><span style="font-size:14.6667px;font-family:arial;color:rgb(51,51,51);background-color:transparent;vertical-align:baseline;white-space:pre-wrap"><br class="gmail-m_7695891327250848386m_-8131894752840521725gmail-kix-line-break"></span><span style="font-size:14.6667px;font-family:arial;color:rgb(51,51,153);background-color:transparent;font-weight:700;vertical-align:baseline;white-space:pre-wrap">void</span><span style="font-size:14.6667px;font-family:arial;color:rgb(51,51,51);background-color:transparent;vertical-align:baseline;white-space:pre-wrap"> </span><span style="font-size:14.6667px;font-family:arial;color:rgb(0,102,187);background-color:transparent;font-weight:700;vertical-align:baseline;white-space:pre-wrap">g</span><span style="font-size:14.6667px;font-family:arial;color:rgb(51,51,51);background-color:transparent;vertical-align:baseline;white-space:pre-wrap">(A& a){</span><span style="font-size:14.6667px;font-family:arial;color:rgb(51,51,51);background-color:transparent;vertical-align:baseline;white-space:pre-wrap"><br class="gmail-m_7695891327250848386m_-8131894752840521725gmail-kix-line-break"></span><span style="font-size:14.6667px;font-family:arial;color:rgb(51,51,51);background-color:transparent;vertical-align:baseline;white-space:pre-wrap">    a.foo();</span><span style="font-size:14.6667px;font-family:arial;color:rgb(51,51,51);background-color:transparent;vertical-align:baseline;white-space:pre-wrap"><br class="gmail-m_7695891327250848386m_-8131894752840521725gmail-kix-line-break"></span><span style="font-size:14.6667px;font-family:arial;color:rgb(51,51,51);background-color:transparent;vertical-align:baseline;white-space:pre-wrap">    a.foo();</span><span style="font-size:14.6667px;font-family:arial;color:rgb(51,51,51);background-color:transparent;vertical-align:baseline;white-space:pre-wrap"><br class="gmail-m_7695891327250848386m_-8131894752840521725gmail-kix-line-break"></span><span style="font-size:14.6667px;font-family:arial;color:rgb(51,51,51);background-color:transparent;vertical-align:baseline;white-space:pre-wrap">}</span><span style="font-size:14.6667px;font-family:arial;color:rgb(51,51,51);background-color:transparent;vertical-align:baseline;white-space:pre-wrap"><br class="gmail-m_7695891327250848386m_-8131894752840521725gmail-kix-line-break"></span><span style="font-size:14.6667px;font-family:arial;color:rgb(51,51,153);background-color:transparent;font-weight:700;vertical-align:baseline;white-space:pre-wrap">void</span><span style="font-size:14.6667px;font-family:arial;color:rgb(51,51,51);background-color:transparent;vertical-align:baseline;white-space:pre-wrap"> </span><span style="font-size:14.6667px;font-family:arial;color:rgb(0,102,187);background-color:transparent;font-weight:700;vertical-align:baseline;white-space:pre-wrap">clobber</span><span style="font-size:14.6667px;font-family:arial;color:rgb(51,51,51);background-color:transparent;vertical-align:baseline;white-space:pre-wrap">(A&);</span><span style="font-size:14.6667px;font-family:arial;color:rgb(51,51,51);background-color:transparent;vertical-align:baseline;white-space:pre-wrap"><br class="gmail-m_7695891327250848386m_-8131894752840521725gmail-kix-line-break"></span><span style="font-size:14.6667px;font-family:arial;color:rgb(51,51,153);background-color:transparent;font-weight:700;vertical-align:baseline;white-space:pre-wrap">void</span><span style="font-size:14.6667px;font-family:arial;color:rgb(51,51,51);background-color:transparent;vertical-align:baseline;white-space:pre-wrap"> </span><span style="font-size:14.6667px;font-family:arial;color:rgb(0,102,187);background-color:transparent;font-weight:700;vertical-align:baseline;white-space:pre-wrap">f</span><span style="font-size:14.6667px;font-family:arial;color:rgb(51,51,51);background-color:transparent;vertical-align:baseline;white-space:pre-wrap">() {</span><span style="font-size:14.6667px;font-family:arial;color:rgb(51,51,51);background-color:transparent;vertical-align:baseline;white-space:pre-wrap"><br class="gmail-m_7695891327250848386m_-8131894752840521725gmail-kix-line-break"></span><span style="font-size:14.6667px;font-family:arial;color:rgb(51,51,51);background-color:transparent;vertical-align:baseline;white-space:pre-wrap">      B b;</span><span style="font-size:14.6667px;font-family:arial;color:rgb(51,51,51);background-color:transparent;vertical-align:baseline;white-space:pre-wrap"><br class="gmail-m_7695891327250848386m_-8131894752840521725gmail-kix-line-break"></span><span style="font-size:14.6667px;font-family:arial;color:rgb(51,51,51);background-color:transparent;vertical-align:baseline;white-space:pre-wrap">      clobber(b);</span><span style="font-size:14.6667px;font-family:arial;color:rgb(51,51,51);background-color:transparent;vertical-align:baseline;white-space:pre-wrap"><br class="gmail-m_7695891327250848386m_-8131894752840521725gmail-kix-line-break"></span><span style="font-size:14.6667px;font-family:arial;color:rgb(51,51,51);background-color:transparent;vertical-align:baseline;white-space:pre-wrap">      g(b);</span><span style="font-size:14.6667px;font-family:arial;color:rgb(51,51,51);background-color:transparent;vertical-align:baseline;white-space:pre-wrap"><br class="gmail-m_7695891327250848386m_-8131894752840521725gmail-kix-line-break"></span><span style="font-size:14.6667px;font-family:arial;color:rgb(51,51,51);background-color:transparent;vertical-align:baseline;white-space:pre-wrap">}</span></p><br><p dir="ltr" style="line-height:1.38;margin-top:0pt;margin-bottom:0pt"><span style="font-size:14.6667px;font-family:arial;color:rgb(0,0,0);background-color:transparent;vertical-align:baseline;white-space:pre-wrap">The other problem is that when we combine 2 instructions with different invariant.group metadata, then we pick one of them, because for now we can have only single !invariant.group metadata.</span></p><br><h1 dir="ltr" style="line-height:1.38;margin-top:20pt;margin-bottom:6pt"><span style="font-size:26.6667px;font-family:arial;color:rgb(0,0,0);background-color:transparent;font-weight:400;vertical-align:baseline;white-space:pre-wrap">The solution</span></h1><p dir="ltr" style="line-height:1.38;margin-top:0pt;margin-bottom:0pt"><span style="font-size:14.6667px;font-family:arial;color:rgb(0,0,0);background-color:transparent;vertical-align:baseline;white-space:pre-wrap">I had some initial ideas how it can be solved, like </span></p><ol style="margin-top:0pt;margin-bottom:0pt"><li dir="ltr" style="list-style-type:lower-alpha;font-size:14.6667px;font-family:arial;color:rgb(0,0,0);background-color:transparent;vertical-align:baseline"><p dir="ltr" style="line-height:1.38;margin-top:0pt;margin-bottom:0pt"><span style="font-size:14.6667px;background-color:transparent;vertical-align:baseline;white-space:pre-wrap">introducing multi invariant groups</span></p></li><li dir="ltr" style="list-style-type:lower-alpha;font-size:14.6667px;font-family:arial;color:rgb(0,0,0);background-color:transparent;vertical-align:baseline"><p dir="ltr" style="line-height:1.38;margin-top:0pt;margin-bottom:0pt"><span style="font-size:14.6667px;background-color:transparent;vertical-align:baseline;white-space:pre-wrap">having sub invariant groups - like inheritance, so we could figure out that one group is subgroup of another</span></p></li><li dir="ltr" style="list-style-type:lower-alpha;font-size:14.6667px;font-family:arial;color:rgb(0,0,0);background-color:transparent;vertical-align:baseline"><p dir="ltr" style="line-height:1.38;margin-top:0pt;margin-bottom:0pt"><span style="font-size:14.6667px;background-color:transparent;vertical-align:baseline;white-space:pre-wrap">decorating all loads with base pointer MD (doesn’t work with multiple inheritance)</span></p></li></ol></span></div></blockquote></div></div></div><div dir="auto"><br></div></div></div><div dir="auto">The original idea was that the metadata would indicate the class that introduced the vptr; that seems like it should work ok with multiple inheritance. Is there a problem with that approach? (We may still be able to remove it entirely, which could still be preferable.)</div><span class="gmail-"><div dir="auto"><br></div></span></div></blockquote><div><br></div><div>You are referring to the last point, right? So it is possible to decorate with the base class type (the introducing vptr class, which will be only one for every vfunction). But there is problem with it. Consider example:</div><div><br></div><div><pre style="color:rgb(51,51,51);margin-top:0px;margin-bottom:0px;line-height:16.25px"><span style="color:rgb(0,136,0);font-weight:bold">struct</span> A {
  <span style="color:rgb(0,136,0);font-weight:bold">virtual</span> <span style="color:rgb(51,51,153);font-weight:bold">void</span> foo();
};

<span style="color:rgb(0,136,0);font-weight:bold">struct</span> B {
  <span style="color:rgb(0,136,0);font-weight:bold">virtual</span> <span style="color:rgb(51,51,153);font-weight:bold">void</span> bar();
};

<span style="color:rgb(0,136,0);font-weight:bold">struct</span> C : A, B {
  <span style="color:rgb(0,136,0);font-weight:bold">virtual</span> <span style="color:rgb(51,51,153);font-weight:bold">void</span> foo();
  <span style="color:rgb(0,136,0);font-weight:bold">virtual</span> <span style="color:rgb(51,51,153);font-weight:bold">void</span> <span style="color:rgb(0,102,187);font-weight:bold">bar</span>();
};

<span style="color:rgb(51,51,153);font-weight:bold">void</span> <span style="color:rgb(0,102,187);font-weight:bold">test</span>(C &c) {
  c.foo();</pre><pre style="color:rgb(51,51,51);margin-top:0px;margin-bottom:0px;line-height:16.25px">  c.bar();
}</pre></div><div><br></div><div>Right now call to foo and bar will get the same invariant.group, so we will end up with only one load (the <b>!invariant.loads</b> - doesn't play any role here):</div><div><br></div><div><pre style="color:rgb(51,51,51);margin-top:0px;margin-bottom:0px;line-height:16.25px"><font face="monospace, monospace">define <span style="color:rgb(51,51,153);font-weight:bold">void</span> <span style="color:rgb(255,0,0);background-color:rgb(255,170,170)">@</span>_Z4testR1C(%<span style="color:rgb(0,136,0);font-weight:bold">struct</span>.C* dereferenceable(<span style="color:rgb(0,0,221);font-weight:bold">16</span>) %c) {
<span style="color:rgb(153,119,0);font-weight:bold">entry:</span>
  %<span style="color:rgb(0,0,221);font-weight:bold">0</span> = bitcast %<span style="color:rgb(0,136,0);font-weight:bold">struct</span>.C* %c to <span style="color:rgb(51,51,153);font-weight:bold">void</span> (%<span style="color:rgb(0,136,0);font-weight:bold">struct</span>.C*)***
  %vtable = load <span style="color:rgb(51,51,153);font-weight:bold">void</span> (%<span style="color:rgb(0,136,0);font-weight:bold">struct</span>.C*)**, <span style="color:rgb(51,51,153);font-weight:bold">void</span> (%<span style="color:rgb(0,136,0);font-weight:bold">struct</span>.C*)*** %<span style="color:rgb(0,0,221);font-weight:bold">0</span>, <b>!invariant.group</b> !<span style="color:rgb(0,0,221);font-weight:bold">7</span>
  %<span style="color:rgb(0,0,221);font-weight:bold">1</span> = load <span style="color:rgb(51,51,153);font-weight:bold">void</span> (%<span style="color:rgb(0,136,0);font-weight:bold">struct</span>.C*)*, <span style="color:rgb(51,51,153);font-weight:bold">void</span> (%<span style="color:rgb(0,136,0);font-weight:bold">struct</span>.C*)** %vtable, !invariant.load !<span style="color:rgb(0,0,221);font-weight:bold">8</span>
  tail call <span style="color:rgb(51,51,153);font-weight:bold">void</span> %<span style="color:rgb(0,0,221);font-weight:bold">1</span>(%<span style="color:rgb(0,136,0);font-weight:bold">struct</span>.C* nonnull %c)

  %vfn2 = getelementptr inbounds <span style="color:rgb(51,51,153);font-weight:bold">void</span> (%<span style="color:rgb(0,136,0);font-weight:bold">struct</span>.C*)*, <span style="color:rgb(51,51,153);font-weight:bold">void</span> (%<span style="color:rgb(0,136,0);font-weight:bold">struct</span>.C*)** %vtable, i64 <span style="color:rgb(0,0,221);font-weight:bold">1</span>
  %<span style="color:rgb(0,0,221);font-weight:bold">2</span> = load <span style="color:rgb(51,51,153);font-weight:bold">void</span> (%<span style="color:rgb(0,136,0);font-weight:bold">struct</span>.C*)*, <span style="color:rgb(51,51,153);font-weight:bold">void</span> (%<span style="color:rgb(0,136,0);font-weight:bold">struct</span>.C*)** %vfn2, !invariant.load !<span style="color:rgb(0,0,221);font-weight:bold">8</span>
  tail call <span style="color:rgb(51,51,153);font-weight:bold">void</span> %<span style="color:rgb(0,0,221);font-weight:bold">2</span>(%<span style="color:rgb(0,136,0);font-weight:bold">struct</span>.C* nonnull %c)
  ret <span style="color:rgb(51,51,153);font-weight:bold">void</span>
}</font></pre><pre style="margin-top:0px;margin-bottom:0px;line-height:16.25px"><font color="#333333">!7 = !{!"_ZTS1C"}
!8 = !{}</font><span style="color:rgb(51,51,51)">
</span></pre><div><br></div><pre style="color:rgb(51,51,51);margin-top:0px;margin-bottom:0px;line-height:16.25px"><br></pre><pre style="color:rgb(51,51,51);margin-top:0px;margin-bottom:0px;line-height:16.25px">If we would decorate vtable load from c.foo() with !invariant.group !"typeA", and from c.bar() with !"typeB", then</pre><pre style="color:rgb(51,51,51);margin-top:0px;margin-bottom:0px;line-height:16.25px">the second one won't be removed:</pre><pre style="color:rgb(51,51,51);margin-top:0px;margin-bottom:0px;line-height:16.25px"><br></pre><pre style="color:rgb(51,51,51);margin-top:0px;margin-bottom:0px;line-height:16.25px"><br></pre><pre style="color:rgb(51,51,51);margin-top:0px;margin-bottom:0px;line-height:16.25px"><pre style="margin-top:0px;margin-bottom:0px;line-height:16.25px">define <span style="color:rgb(51,51,153);font-weight:bold">void</span> <span style="color:rgb(255,0,0);background-color:rgb(255,170,170)">@</span>_Z4testR1C(%<span style="color:rgb(0,136,0);font-weight:bold">struct</span>.C* dereferenceable(<span style="color:rgb(0,0,221);font-weight:bold">16</span>) %c) {
<span style="color:rgb(153,119,0);font-weight:bold">entry:</span>
  %<span style="color:rgb(0,0,221);font-weight:bold">0</span> = bitcast %<span style="color:rgb(0,136,0);font-weight:bold">struct</span>.C* %c to <span style="color:rgb(51,51,153);font-weight:bold">void</span> (%<span style="color:rgb(0,136,0);font-weight:bold">struct</span>.C*)***
  %vtable = load <span style="color:rgb(51,51,153);font-weight:bold">void</span> (%<span style="color:rgb(0,136,0);font-weight:bold">struct</span>.C*)**, <span style="color:rgb(51,51,153);font-weight:bold">void</span> (%<span style="color:rgb(0,136,0);font-weight:bold">struct</span>.C*)*** %<span style="color:rgb(0,0,221);font-weight:bold">0</span>, <b>!invariant.group</b> !<span style="color:rgb(0,0,221);font-weight:bold">0</span>
  %<span style="color:rgb(0,0,221);font-weight:bold">1</span> = load <span style="color:rgb(51,51,153);font-weight:bold">void</span> (%<span style="color:rgb(0,136,0);font-weight:bold">struct</span>.C*)*, <span style="color:rgb(51,51,153);font-weight:bold">void</span> (%<span style="color:rgb(0,136,0);font-weight:bold">struct</span>.C*)** %vtable, !invariant.load !<span style="color:rgb(0,0,221);font-weight:bold">2</span>
  tail call <span style="color:rgb(51,51,153);font-weight:bold">void</span> %<span style="color:rgb(0,0,221);font-weight:bold">1</span>(%<span style="color:rgb(0,136,0);font-weight:bold">struct</span>.C* nonnull %c)
  
  %vtable1 = load <span style="color:rgb(51,51,153);font-weight:bold">void</span> (%<span style="color:rgb(0,136,0);font-weight:bold">struct</span>.C*)**, <span style="color:rgb(51,51,153);font-weight:bold">void</span> (%<span style="color:rgb(0,136,0);font-weight:bold">struct</span>.C*)*** %<span style="color:rgb(0,0,221);font-weight:bold">0</span>, <b>!invariant.group</b> !<span style="color:rgb(0,0,221);font-weight:bold">1</span>
  %vfn2 = getelementptr inbounds <span style="color:rgb(51,51,153);font-weight:bold">void</span> (%<span style="color:rgb(0,136,0);font-weight:bold">struct</span>.C*)*, <span style="color:rgb(51,51,153);font-weight:bold">void</span> (%<span style="color:rgb(0,136,0);font-weight:bold">struct</span>.C*)** %vtable1, i64 <span style="color:rgb(0,0,221);font-weight:bold">1</span>
  %<span style="color:rgb(0,0,221);font-weight:bold">2</span> = load <span style="color:rgb(51,51,153);font-weight:bold">void</span> (%<span style="color:rgb(0,136,0);font-weight:bold">struct</span>.C*)*, <span style="color:rgb(51,51,153);font-weight:bold">void</span> (%<span style="color:rgb(0,136,0);font-weight:bold">struct</span>.C*)** %vfn2, !invariant.load !<span style="color:rgb(0,0,221);font-weight:bold">2</span>
  tail call <span style="color:rgb(51,51,153);font-weight:bold">void</span> %<span style="color:rgb(0,0,221);font-weight:bold">2</span>(%<span style="color:rgb(0,136,0);font-weight:bold">struct</span>.C* nonnull %c)
  ret <span style="color:rgb(51,51,153);font-weight:bold">void</span>
}

!<span style="color:rgb(0,0,221);font-weight:bold">0</span> = !{!<span style="background-color:rgb(255,240,240)">"_ZTS1A"</span>}
!<span style="color:rgb(0,0,221);font-weight:bold">1</span> = !{!<span style="background-color:rgb(255,240,240)">"_ZTS1B"</span>}
!<span style="color:rgb(0,0,221);font-weight:bold">2</span> = {}</pre></pre></div><div><br></div><div><br></div><div><br></div><div>Piotr</div><div><br></div><div><br></div><div> </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="auto"><span class="gmail-"><div dir="auto"></div><div dir="auto"><div class="gmail_extra"><div class="gmail_quote"><blockquote class="gmail-m_7695891327250848386quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr"><span id="gmail-m_7695891327250848386m_-8131894752840521725gmail-docs-internal-guid-f4b3e122-bc9b-30cb-5204-c95e1095750e"><p dir="ltr" style="line-height:1.38;margin-top:0pt;margin-bottom:0pt"><span style="font-size:14.6667px;font-family:arial;color:rgb(0,0,0);background-color:transparent;vertical-align:baseline;white-space:pre-wrap">I consulted my ideas with Krzysztof Pszeniczny, and he proposed something much simpler: we can decorate every invariant.group md with empty metadata.</span></p><p dir="ltr" style="line-height:1.38;margin-top:0pt;margin-bottom:0pt"><span style="font-size:14.6667px;font-family:arial;color:rgb(0,0,0);background-color:transparent;vertical-align:baseline;white-space:pre-wrap">This should work because the lifetime of the object is strictly defined by invariant.group.barrier.</span></p><br><br><p dir="ltr" style="line-height:1.38;margin-top:0pt;margin-bottom:0pt"><span style="font-size:14.6667px;font-family:arial;color:rgb(0,0,0);background-color:transparent;vertical-align:baseline;white-space:pre-wrap">If this holds, we can start discussion about if it makes sense to keep invariant groups, and instead have just “invariant”, that would be equivalent to having invariant.group with the same metadata.</span></p><br><p dir="ltr" style="line-height:1.38;margin-top:0pt;margin-bottom:0pt"><span style="font-size:14.6667px;font-family:arial;color:rgb(0,0,0);background-color:transparent;vertical-align:baseline;white-space:pre-wrap">Do you have some thoughts about this approach? I don’t have a mathematical proof, but I am confident that it should be valid.</span></p><div><span style="font-size:14.6667px;font-family:arial;color:rgb(0,0,0);background-color:transparent;vertical-align:baseline;white-space:pre-wrap"><br></span></div></span></div>
</blockquote></div><br></div></div></span></div>
</blockquote></div><br></div></div>