<html>
  <head>
    <meta content="text/html; charset=windows-1252"
      http-equiv="Content-Type">
  </head>
  <body bgcolor="#FFFFFF" text="#000000">
    <br>
    <br>
    <div class="moz-cite-prefix">On 07/31/2015 02:47 PM, Philip Reames
      wrote:<br>
    </div>
    <blockquote cite="mid:55BBECD6.2040209@philipreames.com" type="cite">
      <meta content="text/html; charset=windows-1252"
        http-equiv="Content-Type">
      <br>
      <br>
      <div class="moz-cite-prefix">On 07/29/2015 09:32 AM, Reid Kleckner
        wrote:<br>
      </div>
      <blockquote
cite="mid:CACs=tyJJ7WZJgc+BapjV=AcZkoe-wcHMzk3M0Br=YrbySDmbsw@mail.gmail.com"
        type="cite">
        <div dir="ltr">
          <div class="gmail_extra">
            <div class="gmail_quote">On Tue, Jul 28, 2015 at 10:58 AM,
              Philip Reames <span dir="ltr"><<a
                  moz-do-not-send="true"
                  href="mailto:listmail@philipreames.com"
                  target="_blank">listmail@philipreames.com</a>></span>
              wrote:<br>
              <blockquote class="gmail_quote" style="margin:0 0 0
                .8ex;border-left:1px #ccc solid;padding-left:1ex">
                <div bgcolor="#FFFFFF" text="#000000"> Having read
                  through the proposal, I feel like I missing some of
                  the background to understand the problem you're trying
                  to solve.<br>
                  <br>
                  My mental model is that construction of an object
                  creates a new abstract location in an infinite heap
                  with each object infinitely far apart.  Destruction of
                  the object destroys the abstract location.  As a
                  result, destructing one object and constructing
                  another produce unique incomparable abstract
                  locations.  The fact the two abstract locations might
                  happen to share a physical address is irrelevant.  <br>
                  <br>
                  If I'm understanding the proposal correctly, this
                  model works for most code.  The key optimization you
                  appear to want to perform is to recognize the fact
                  that these two abstract locations occupy the same
                  memory.  In particular, you want to be able to return
                  mustalias for alias(loc1, loc2).  Another way of
                  saying this is that you want to reason about abstract
                  locations as defined by allocation/deallocation events
                  rather than construction/destruction events.  Is that
                  a fair summary?<br>
                  <br>
                  What I'm not clear on is *why* recognizing the two
                  abstract locations share a physical address is
                  important.  Given that the contents of the abstract
                  location before construction or after destruction are
                  undefined (right?), what optimization does recognizing
                  the mustalias relation enable?<br>
                </div>
              </blockquote>
              <div><br>
              </div>
              <div>I think this is incorrect. LLVM's model is closer to
                the second model, and we need something like the first
                model to prevent erroneous devirtualization.</div>
              <div><br>
              </div>
              <div>The corner case for C++ is when the optimizer
                observes that two abstract objects share the same
                physical memory location. In practice, this could happen
                if the memory allocator becomes visible to the optimizer
                through inlining. For illustration, do placement new
                into the stack memory of another object. This is
                illustrated in example 2 of the proposal:</div>
              <div><br>
              </div>
              <div>
                <div>struct MyClass {</div>
                <div>  virtual void foo();</div>
                <div>};</div>
                <div>struct MyOtherClass : MyClass {</div>
                <div>  virtual void foo();</div>
                <div>};</div>
                <div>int main() {</div>
                <div>  MyClass c;</div>
                <div>  c.foo();</div>
                <div>  // Reuse the storage temporarily.  UB to access
                  the object through ‘c’</div>
                <div>  c.~MyClass();</div>
                <div>  auto c2 = new (&c) MyOtherClass();</div>
                <div>  c2->foo(); //fine, we have new pointer</div>
                <div>  // c.foo() // UB, the type has changed</div>
                <div>  </div>
                <div>  // The storage has to contain a ‘MyClass’ when it
                  goes out of scope.</div>
                <div>  c2->~MyOtherClass();</div>
                <div>  new (&c) MyClass(); // we have to get back to
                  previous type because calling destructor using c would
                  be UB</div>
                <div>}</div>
              </div>
              <div><br>
              </div>
              <div>Without @llvm.invariant.group.barrier, LLVM will
                probably replace %c2 with %c here, since they are
                trivially the same.</div>
              <div><br>
              </div>
              <div>With @llvm.invariant.group.barrier, the result of
                placement new will be a distinct SSA value that LLVM
                can't reason about, and we won't accidentally
                devirtualize c2->foo() to MyClass::foo.</div>
            </div>
          </div>
        </div>
      </blockquote>
      So, to phrase this differently, the @llvm.invariant.group.barrier
      is responsible for introducing a new abstract memory location and
      the optimizer is agreeing to never exploit the fact the new
      abstract memory location is in fact at the same address?<br>
      <br>
      Where in the execution would this new abstract location be
      introduced?  Is it immediately before the placement new?  If so,
      that would seem consistent.  <br>
    </blockquote>
    Sorry, ignore the above.  I got to the part below and forgot to
    update this before sending.  I hadn't yet internalized the bit about
    not being able to reason about disjoint abstract locations when I
    wrote this.  <br>
    <blockquote cite="mid:55BBECD6.2040209@philipreames.com" type="cite">
      <br>
      <blockquote
cite="mid:CACs=tyJJ7WZJgc+BapjV=AcZkoe-wcHMzk3M0Br=YrbySDmbsw@mail.gmail.com"
        type="cite">
        <div dir="ltr">
          <div class="gmail_extra">
            <div class="gmail_quote">
              <div><br>
              </div>
              <div>There is, however, a small problem with this model.
                If the code happened to do this:</div>
              <div><br>
              </div>
              <div>  ...</div>
              <div>
                <div>  auto c2 = new (&c) MyOtherClass();</div>
              </div>
              <div>  assert(c2 == &c);</div>
              <div>  ...</div>
              <div><br>
              </div>
              <div>LLVM might once again replace %c2 with %c, causing
                bad devirtualization.</div>
            </div>
          </div>
        </div>
      </blockquote>
      Is this well defined C++?  My reading would be that it is.  If
      this was realloc, it clearly wouldn't be, but I'm not sure
      placement new has the same restrictions.  <br>
      <br>
      Assuming that it is well defined C, this was exactly the counter
      example I was missing and the reason that reasoning about abstract
      locations per object doesn't work.  Thanks.<br>
      <br>
      Given that, I can see why we're stuck with a single abstract
      location for the storage and need to add and remove the
      invariantness of a particular location.  I'll go take another read
      through the proposal with that in mind.  <br>
      <br>
      Philip<br>
      <br>
      <br>
      <fieldset class="mimeAttachmentHeader"></fieldset>
      <br>
      <pre wrap="">_______________________________________________
LLVM Developers mailing list
<a class="moz-txt-link-abbreviated" href="mailto:LLVMdev@cs.uiuc.edu">LLVMdev@cs.uiuc.edu</a>         <a class="moz-txt-link-freetext" href="http://llvm.cs.uiuc.edu">http://llvm.cs.uiuc.edu</a>
<a class="moz-txt-link-freetext" href="http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev">http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev</a>
</pre>
    </blockquote>
    <br>
  </body>
</html>