<div dir="ltr"><br><div class="gmail_extra"><br><div class="gmail_quote">2017-01-26 15:41 GMT+01:00 Hal Finkel <span dir="ltr"><<a href="mailto:hfinkel@anl.gov" target="_blank">hfinkel@anl.gov</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 bgcolor="#FFFFFF"><span class="gmail-">
    <p><br>
    </p>
    <div class="gmail-m_3802625087396114044moz-cite-prefix">On 01/26/2017 06:44 AM, Piotr Padlewski
      wrote:<br>
    </div>
    <blockquote type="cite">
      
      <div dir="ltr"><br>
        <div class="gmail_extra"><br>
          <div class="gmail_quote">2017-01-26 3:28 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="ltr">
                <div class="gmail_extra">
                  <div class="gmail_quote"><span>On 25 January 2017 at
                      15:03, Hal Finkel via cfe-dev <span dir="ltr"><<a href="mailto:cfe-dev@lists.llvm.org" target="_blank">cfe-dev@lists.llvm.org</a>></span>
                      wrote:<br>
                      <blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
                        <div bgcolor="#FFFFFF">
                          <p>Hi Piotr,</p>
                          <p>I think makes sense. Modulo bitcasts, the
                            invariant is identified by a particular
                            pointer SSA value. Given that you can't
                            sensibly have two nonequivalent invariants
                            associated with the same pointer SSA value
                            simultaneously, there's no need to also
                            identify the invariant with a metadata
                            string as well. When we need a new
                            "identifier" for the pointed-to value, we
                            get one using invariant.group.barrier.</p>
                        </div>
                      </blockquote>
                      <div><br>
                      </div>
                    </span>
                    <div>As I recall, the original motivation for the
                      identifier was to support cases where the
                      "invariant" region's value changes and then
                      changes back (remember that invariant.group does
                      not imply the storage doesn't change, just that a
                      particular set of loads and stores witness the
                      same value):</div>
                    <div><br>
                    </div>
                    <div>struct A { void *vptr; /*...*/ };</div>
                    <div>struct B { void *vptr; /*...*/ };</div>
                    <div>union U { A a; B b; };</div>
                    <div><br>
                    </div>
                    <div>void f(U *u) {</div>
                    <div>  // #1, load A vptr</div>
                    <div>  load u->a.vptr, !invariant "A::vptr"</div>
                    <div>  // #2, change union member to B ...</div>
                    <div>  store u->b.vptr, !invariant "B::vptr"</div>
                    <div>  // #3, change union member back to A ...</div>
                    <div>  f(u); // performs: store u->a.vptr,
                      !invariant "A::vptr"</div>
                    <div>  // #4, load A vptr again, can be forwarded
                      from #1 but not from #2</div>
                    <div>  load u->a.vptr, !invariant "A::vptr"</div>
                    <div>}</div>
                    <div><br>
                    </div>
                  </div>
                </div>
              </div>
            </blockquote>
            <div>Excellent point, I forgot that one don't have to call
              placement new in order to emplace different type.</div>
            <div>I discussed it with Krzysztof and we belive the best
              way to solve it is to introduce barriers before every use
              of union if it contains any polymorphic class (recursively
              for each class in union). This might look very bad, but
              assuming we will be able skip barrier for optimizations
              not relying on !invariant.group, then it will not
              pessimize anything. <br>
            </div>
          </div>
        </div>
      </div>
    </blockquote>
    <br></span>
    In light of this, can we go back and reevaluate your list of
    proposed solutions? You pointed out two problems:<br>
     1. "This works well if the pointer type doesn’t change, but when it
    does, devirtualization might not happen" (e.g. a conversion to a
    base-class pointer/reference).<br>
     2. "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."<br>
    <br>
    Given what's been said, I'm leaning toward favoring solution (b),
    "having sub invariant groups - like inheritance, so we could figure
    out that one group is subgroup of another" because 1) it seems to
    solve both problems and 2) it seems like we could get all of the
    non-trivial logic (for generation, comparison, and merging) from our
    TBAA implementation (we might even be able to directly reuse the
    same metadata).<span class="gmail-HOEnZb"><font color="#888888"><br>
    <br>
     -Hal</font></span><div><div class="gmail-h5"><br></div></div></div></blockquote><div><br></div><div>I was thinking about this, and as long as I think about it I am convincing myself that different groups, or even sub groups that you have mentioned,</div><div>will have no use for const memory propagation. In the future we probably would like to decorate const member loads and </div><div>stores with<b> !invariant.group</b> (or <b>!invariant</b> if groups will be removed [if name will change :P]). </div><div><br></div><div>In order to decorate const members, we will need to insert barrier before <b>every</b> use of union member.</div><div>So I was thinking about this example: <a href="https://godbolt.org/g/iSUjKD">https://godbolt.org/g/iSUjKD</a> but it doesn't compile, but Krzysztof figured out this one:</div><div><a href="https://godbolt.org/g/lYQFBd">https://godbolt.org/g/lYQFBd</a> (BTW it seems that clang is pretty bad at cleaning out iostreams)<br></div><div><font face="monospace, monospace"><br></font></div><div><div><pre style="color:rgb(51,51,51);margin-top:0px;margin-bottom:0px;line-height:16.25px"><font face="monospace, monospace"><span style="color:rgb(0,136,0);font-weight:bold">struct</span> A {
    <span style="color:rgb(0,136,0);font-weight:bold">const</span> <span style="color:rgb(51,51,153);font-weight:bold">int</span> x;
};

<span style="color:rgb(0,136,0);font-weight:bold">union</span> B {
    A a1;
    A a2;

    B() : a1{<span style="color:rgb(0,0,221);font-weight:bold">42</span>} { }
    <span style="color:rgb(51,51,153);font-weight:bold">void</span> switch2(<span style="color:rgb(51,51,153);font-weight:bold">int</span> x) {
        a1.~A();
        <span style="color:rgb(0,136,0);font-weight:bold">new</span> (&a2) A{x};
    }
};

<span style="color:rgb(51,51,153);font-weight:bold">int</span> <span style="color:rgb(0,102,187);font-weight:bold">main</span>() {
    B b;
    std::cout << b.a1.x << std::endl;
    b.switch2(<span style="color:rgb(0,0,221);font-weight:bold">50</span>);
    std::cout << b.a2.x << std::endl;
}</font></pre><pre style="color:rgb(51,51,51);margin-top:0px;margin-bottom:0px;line-height:16.25px"><font face="monospace, monospace"><br></font></pre></div></div><div>As he checked in standard, it seems to be valid C++11 code by <b>9.5.4</b>. </div><div>So as you can see different groups won't gonna work in case of const members inside union, like:</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"><span style="color:rgb(51,51,153);font-weight:bold">int</span> <span style="color:rgb(0,102,187);font-weight:bold">main</span>() {
    B b;
    std::cout << b.a1.x << std::endl;
    b.switch2(<span style="color:rgb(0,0,221);font-weight:bold">50</span>);
    std::cout << b.a2.x << std::endl;
    b.switch2(<span style="color:rgb(0,0,221);font-weight:bold">51</span>);
    std::cout << b.a2.x << std::end; <span style="color:rgb(136,136,136)">// This is not 50, as we would thought based on invariant.groups</span>
}</font></pre></div><div><br></div><div><br></div><div>I am not familiar with the TBAA implementation, but after digging more int MSSA, I have other reason to not like the sub groups. </div><div>It might be pretty hard to handle them efficiently in many algorithms including MSSA.</div><div><br></div><div>Hal, what are the things that you dislike about the emitting barriers everywhere for unions?</div><div>It only seems to be very heavy, but I am pretty sure we can get to the point where we will be able to</div><div>delete barriers when we can, and teach optimizations and analysis how to skip them, so they will not pesimize any code.</div><div><br></div><div><br></div><div><b>TL;DR </b></div><div>different groups works for devirtualization, but it is seem to not be a general way to go with "invariant" things.</div><div><br></div><div>Piotr</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 bgcolor="#FFFFFF"><div><div class="gmail-h5">
    <br>
    <blockquote type="cite">
      <div dir="ltr">
        <div class="gmail_extra">
          <div class="gmail_quote">
            <div><br>
            </div>
            <div> <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 class="gmail_extra">
                  <div class="gmail_quote">
                    <div>However, I don't immediately see a way in which
                      the C++ object model would require us to track
                      multiple distinct groups of loads and stores, so
                      if it isn't useful to be able to do that outside
                      of C++ vptr / const member invariant tracking, I
                      think we can remove it.</div>
                  </div>
                </div>
              </div>
            </blockquote>
            <div><br>
            </div>
            <div>It should not make optimizations in LLVM any harder
              with group or without, so I will postpone the removal of
              groups for some time.</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="ltr">
                <div class="gmail_extra">
                  <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>
                        <div class="gmail-m_3802625087396114044m_2260526803923265845h5">
                          <div bgcolor="#FFFFFF">
                            <p> -Hal<br>
                            </p>
                            <div>
                              <div class="gmail-m_3802625087396114044m_2260526803923265845m_-5474282151935520877gmail-h5">
                                <br>
                                <div class="gmail-m_3802625087396114044m_2260526803923265845m_-5474282151935520877gmail-m_8071376148364838946moz-cite-prefix">On
                                  01/24/2017 01:39 PM, Piotr Padlewski
                                  via llvm-dev wrote:<br>
                                </div>
                              </div>
                            </div>
                            <blockquote type="cite">
                              <div>
                                <div class="gmail-m_3802625087396114044m_2260526803923265845m_-5474282151935520877gmail-h5">
                                  <div dir="ltr">Hi,
                                    <div>I would really like to hear
                                      some feedback about this.</div>
                                    <div><br>
                                    </div>
                                    <div>Piotr</div>
                                  </div>
                                  <div class="gmail_extra"><br>
                                    <div class="gmail_quote">2017-01-20
                                      17:07 GMT+01:00 Piotr Padlewski <span dir="ltr"><<a href="mailto:piotr.padlewski@gmail.com" target="_blank">piotr.padlewski@gmail.com</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="ltr"><span id="gmail-m_3802625087396114044m_2260526803923265845m_-5474282151935520877gmail-m_8071376148364838946m_3685817574736257236gmail-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">
</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>
</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.htm<wbr>l</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>
<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>
<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">
</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">
</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>

<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">
</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">
</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">
</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">
</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">
</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">
</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">
</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">
</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">!</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>


<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>
<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">
</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">
</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">
</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">
</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">
</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">
</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">
</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">
</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">
</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">
</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">
</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">
</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">
</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">
</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">
</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">
</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">
</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>
<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>
<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>
<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>

<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>
<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">
</span></div></span></div>
</blockquote></div>
</div>


<fieldset class="gmail-m_3802625087396114044m_2260526803923265845m_-5474282151935520877gmail-m_8071376148364838946mimeAttachmentHeader"></fieldset>
</div></div><pre>______________________________<wbr>_________________
LLVM Developers mailing list
<a class="gmail-m_3802625087396114044m_2260526803923265845m_-5474282151935520877gmail-m_8071376148364838946moz-txt-link-abbreviated" href="mailto:llvm-dev@lists.llvm.org" target="_blank">llvm-dev@lists.llvm.org</a>
<a class="gmail-m_3802625087396114044m_2260526803923265845m_-5474282151935520877gmail-m_8071376148364838946moz-txt-link-freetext" href="http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev" target="_blank">http://lists.llvm.org/cgi-bin/<wbr>mailman/listinfo/llvm-dev</a><span class="gmail-m_3802625087396114044m_2260526803923265845m_-5474282151935520877gmail-HOEnZb"><font color="#888888">
</font></span></pre><span class="gmail-m_3802625087396114044m_2260526803923265845m_-5474282151935520877gmail-HOEnZb"><font color="#888888">

</font></span></blockquote><span class="gmail-m_3802625087396114044m_2260526803923265845m_-5474282151935520877gmail-HOEnZb"><font color="#888888">
<pre class="gmail-m_3802625087396114044m_2260526803923265845m_-5474282151935520877gmail-m_8071376148364838946moz-signature" cols="72">-- 
Hal Finkel
Lead, Compiler Technology and Programming Languages
Leadership Computing Facility
Argonne National Laboratory</pre></font></span></div>
</div></div>______________________________<wbr>_________________

cfe-dev mailing list

<a href="mailto:cfe-dev@lists.llvm.org" target="_blank">cfe-dev@lists.llvm.org</a>

<a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev" rel="noreferrer" target="_blank">http://lists.llvm.org/cgi-bin/<wbr>mailman/listinfo/cfe-dev</a>


</blockquote></div>
</div></div>
</blockquote></div>
</div></div>



</blockquote>
<pre class="gmail-m_3802625087396114044moz-signature" cols="72">-- 
Hal Finkel
Lead, Compiler Technology and Programming Languages
Leadership Computing Facility
Argonne National Laboratory</pre></div></div></div></blockquote></div><br></div></div>