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