<html>
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
  </head>
  <body>
    <p><br>
    </p>
    <div class="moz-cite-prefix">On 1/6/22 9:13 AM, James Y Knight
      wrote:<br>
    </div>
    <blockquote type="cite"
cite="mid:CAA2zVHoEBTnKMazwh3Nh3MsH1=iTsfnix19s0sw4jpc3XujGDw@mail.gmail.com">
      <meta http-equiv="content-type" content="text/html; charset=UTF-8">
      <div dir="ltr">
        <div dir="ltr"><br>
        </div>
        <br>
        <div class="gmail_quote">
          <div dir="ltr" class="gmail_attr">On Thu, Jan 6, 2022 at 11:40
            AM Philip Reames via llvm-dev <<a
              href="mailto:llvm-dev@lists.llvm.org"
              moz-do-not-send="true">llvm-dev@lists.llvm.org</a>>
            wrote:<br>
          </div>
          <blockquote class="gmail_quote" style="margin:0px 0px 0px
            0.8ex;border-left:1px solid
            rgb(204,204,204);padding-left:1ex">
            <div>
              <p><br>
              </p>
              <div>On 1/5/22 2:32 PM, Augie Fackler via llvm-dev wrote:<br>
              </div>
              <blockquote type="cite">
                <div dir="ltr"><span
id="gmail-m_-1957120311742917308gmail-docs-internal-guid-6b433c83-7fff-1432-96a7-42c8edd2bab6">
                    <p dir="ltr"
                      style="line-height:1.38;margin-top:0pt;margin-bottom:0pt"><span style="font-size:11pt;font-family:Arial;color:rgb(0,0,0);background-color:transparent;font-variant-numeric:normal;font-variant-east-asian:normal;vertical-align:baseline;white-space:pre-wrap">Hi everyone! I’m working on making the Rust compiler being able to track LLVM HEAD more closely, and as part of that we need to obviate a patch[0] that teaches LLVM about some Rust allocator implementation details. This proposal is the product of many conversations and a couple of failed attempts at simpler implementations.</span></p>
                    <br>
                    <p dir="ltr"
                      style="line-height:1.38;margin-top:0pt;margin-bottom:0pt"><span style="font-size:11pt;font-family:Arial;color:rgb(0,0,0);background-color:transparent;font-variant-numeric:normal;font-variant-east-asian:normal;vertical-align:baseline;white-space:pre-wrap">Background</span></p>
                    <p dir="ltr"
                      style="line-height:1.38;margin-top:0pt;margin-bottom:0pt"><span style="font-size:11pt;font-family:Arial;color:rgb(0,0,0);background-color:transparent;font-variant-numeric:normal;font-variant-east-asian:normal;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:11pt;font-family:Arial;color:rgb(0,0,0);background-color:transparent;font-variant-numeric:normal;font-variant-east-asian:normal;vertical-align:baseline;white-space:pre-wrap">Rust uses LLVM for codegen, and has its own allocator functions. In order for LLVM to correctly optimize out allocations we have to tell the optimizer about the allocation/deallocation functions used by Rust.</span></p>
                    <br>
                    <p dir="ltr"
                      style="line-height:1.38;margin-top:0pt;margin-bottom:0pt"><span style="font-size:11pt;font-family:Arial;color:rgb(0,0,0);background-color:transparent;font-variant-numeric:normal;font-variant-east-asian:normal;vertical-align:baseline;white-space:pre-wrap">Languages supported by Clang, such as C and C++, have stable symbol names for their allocation functions, which are hardcoded in LLVM[1][2]. Unfortunately, this strategy does not work for Rust, where developers don't want to commit to a particular symbol name and calling convention yet.</span></p>
                    <br>
                    <p dir="ltr"
                      style="line-height:1.38;margin-top:0pt;margin-bottom:0pt"><span style="font-size:11pt;font-family:Arial;color:rgb(0,0,0);background-color:transparent;font-variant-numeric:normal;font-variant-east-asian:normal;vertical-align:baseline;white-space:pre-wrap">Proposal</span></p>
                    <p dir="ltr"
                      style="line-height:1.38;margin-top:0pt;margin-bottom:0pt"><span style="font-size:11pt;font-family:Arial;color:rgb(0,0,0);background-color:transparent;font-variant-numeric:normal;font-variant-east-asian:normal;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:11pt;font-family:Arial;color:rgb(0,0,0);background-color:transparent;font-variant-numeric:normal;font-variant-east-asian:normal;vertical-align:baseline;white-space:pre-wrap">We add two attributes to LLVM IR:</span></p>
                    <br>
                    <p dir="ltr"
                      style="line-height:1.38;margin-top:0pt;margin-bottom:0pt"><span style="font-size:11pt;font-family:Arial;color:rgb(0,0,0);background-color:transparent;font-variant-numeric:normal;font-variant-east-asian:normal;vertical-align:baseline;white-space:pre-wrap"> * `allocator(FAMILY)`: Marks a function as part of an allocator family, named by the “primary” allocation function (e.g. `allocator(“malloc”)`, `allocator(“_Znwm”)`, or `allocator(“__rust_alloc”)`).</span></p>
                    <br>
                    <p dir="ltr"
                      style="line-height:1.38;margin-top:0pt;margin-bottom:0pt"><span style="font-size:11pt;font-family:Arial;color:rgb(0,0,0);background-color:transparent;font-variant-numeric:normal;font-variant-east-asian:normal;vertical-align:baseline;white-space:pre-wrap"> * `releaseptr(idx)`: Indicates that the function releases the pointer that is its Nth argument.</span></p>
                  </span></div>
              </blockquote>
              <p>Can you expand a bit on the motivation for this one? 
                What are some small examples that you think this will
                enable?</p>
              <p>I don't see how this could allow allocation elimination
                without aggressive inlining.  Maybe you could use it to
                prove a particular bit of storage is undefined after
                return, but what does that buy you in terms of practical
                optimization benefit?  Do you have something else in
                mind?</p>
            </div>
          </blockquote>
          <div>The example was written below -- `free(foo)` would get
            the attributes `”allocator”=”malloc” releaseptr(1)`. The
            "allocator" attribute declares that the function is an
            allocator function (and is thus removable if matched), while
            the releaseptr attribute declares that it is a freeing
            function (or, combined with allocsize, a realloc-like
            function), which frees the 1st argument.</div>
          <div><br>
          </div>
          <div>Remember that the genesis of the proposal is to enable
            all the optimizations LLVM previously enabled via the
            hardcoded lists in MemoryBuiltins.cpp. So this attribute is
            effectively intended to support the same optimizations that
            "llvm::isFreeCall" does today. (Certainly, "What LLVM does
            today" is insufficient for a spec, but it does clearly
            describe the motivation!)</div>
        </div>
      </div>
    </blockquote>
    <p>Oh!  I'd been assuming the free routine would just be annotated
      with the allocator family.  Functions which return new objects
      allocate, those which take arguments free.  (Realloc does both.)</p>
    <p>I do see that's somewhat vague, and the appeal to annotating them
      both.  I just didn't get that from the original text.  :)</p>
    <p>Philip<br>
    </p>
  </body>
</html>