[llvm-dev] [RFC] Adding support for marking allocator functions in LLVM IR

Philip Reames via llvm-dev llvm-dev at lists.llvm.org
Thu Jan 6 09:16:46 PST 2022


On 1/6/22 9:13 AM, James Y Knight wrote:
>
>
> On Thu, Jan 6, 2022 at 11:40 AM Philip Reames via llvm-dev 
> <llvm-dev at lists.llvm.org <mailto:llvm-dev at lists.llvm.org>> wrote:
>
>
>     On 1/5/22 2:32 PM, Augie Fackler via llvm-dev wrote:
>>
>>     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.
>>
>>
>>     Background
>>
>>     ========
>>
>>     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.
>>
>>
>>     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.
>>
>>
>>     Proposal
>>
>>     =======
>>
>>     We add two attributes to LLVM IR:
>>
>>
>>      * `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”)`).
>>
>>
>>      * `releaseptr(idx)`: Indicates that the function releases the
>>     pointer that is its Nth argument.
>>
>     Can you expand a bit on the motivation for this one? What are some
>     small examples that you think this will enable?
>
>     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?
>
> 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.
>
> 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!)

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.)

I do see that's somewhat vague, and the appeal to annotating them both.  
I just didn't get that from the original text.  :)

Philip

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20220106/45868f91/attachment.html>


More information about the llvm-dev mailing list