[llvm-dev] [RFC] A nofree (and nosynch) function attribute: Mixing dereferenceable and delete

Hal Finkel via llvm-dev llvm-dev at lists.llvm.org
Wed Jul 11 16:17:48 PDT 2018


On 07/11/2018 04:07 AM, Artur Pilipenko wrote:
> It looks like the current proposal doesn’t allow to express the semantics
> of GC managed pointers. In this scenario functions don’t deallocate. We 
> might be able to mark every single function as nofree, but nosynch part is
> problematic. We do have functions which synchronize with other threads 
> but it doesn’t change the property that no function call can invalidate a
> reference. 
>
> With that in mind the alternative with a new attribute looks like a better option
> for me.

Makes sense to me.

 -Hal

>  But I haven't given it much thought.
>
> Artur
>
>> On 11 Jul 2018, at 05:01, Hal Finkel via llvm-dev <llvm-dev at lists.llvm.org> wrote:
>>
>> Hi, everyone,
>>
>> I'd like to propose adding a nofree function attribute to indicate that
>> a function does not, directly or indirectly, call a memory-deallocation
>> function (e.g., free, C++'s operator delete). Clang/LLVM can currently
>> misoptimize functions that:
>>
>>  1. Have a reference argument.
>>
>>  2. Free the memory backing the object to which the reference is bound
>> during the function's execution.
>>
>> Because we tag, in Clang, all reference arguments using the
>> dereferenceable attribute, LLVM assumes that the pointer is
>> unconditionally dereferenceable throughout the course of the entire
>> function. This isn't true, however, if the memory is freed during the
>> execution of the function. For more information, please see the
>> discussion in https://reviews.llvm.org/D48239.
>>
>> To solve this problem, we need to give LLVM more information in order to
>> help it determine when a pointer, which is dereferenceable when the
>> functions begins to execute, will still be dereferenceable later on in
>> the function's execution. This nofree attribute can be part of that
>> solution. If we know that free (and friends) are not called by the
>> function (nor by any function called by the function, and so on), then
>> we know that pointers that started out dereferenceable will stay that
>> way (except as explained below).
>>
>> I'm initially proposing this to be only a function attribute, although
>> one could easily imagine a parameter attribute as well (that indicates
>> that a particular pointer argument is not freed by the function). This
>> might be useful, but for the use case of helping dereferenceable, it
>> would be subtle to use, unless the parameter was also marked as noalias,
>> because you'd need to know that the parameter was not also aliased with
>> another argument (or had not been captured). Another analysis would need
>> to provide this kind of information.
>>
>> Also, just because a function does not, directly or indirectly, call
>> free does not mean that it cannot cause memory to be deallocated. The
>> function might communicate (synchronize) with another thread causing
>> that other thread to delete the memory. For this reason, to use
>> dereferenceable as we currently do, we also need to know that the
>> function does not synchronize with any other threads. To solve this
>> problem, like nofree, I propose to add a nosynch attribute (to indicate
>> that a function does not use (non-relaxed) atomics or otherwise
>> synchronize with any other threads (e.g., perform I/O or, as a practical
>> matter, use volatile accesses).
>>
>> I've posted a patch for the nofree attribute
>> (https://reviews.llvm.org/D49165). nosynch's implementation would be
>> very similar (except instead of looking for calls to free, it would look
>> for uses of non-relaxed atomics, volatile ops, and known functions that
>> are not I/O functions).
>>
>> With both of these attributes (nofree and nosynch), a function argument
>> with the dereferenceable attribute will be known to be dereferenceable
>> throughout the execution of the attributed function. We can update
>> isDereferenceableAndAlignedPointer to include these additional checks on
>> the current function.
>>
>> One more choice we have: We can, as I proposed above, essentially weaken
>> the current semantics of dereferenceable to not exclude
>> mid-function-execution deallocation. We can also add a second attribute
>> with the current, stronger, semantics. We can keep the current attribute
>> as-is, and add a second attribute with the weaker semantics (and switch
>> Clang to use that).
>>
>> Please let me know what you think.
>>
>> Thanks again,
>>
>> Hal
>>
>> -- 
>> Hal Finkel
>> Lead, Compiler Technology and Programming Languages
>> Leadership Computing Facility
>> Argonne National Laboratory
>>
>> _______________________________________________
>> LLVM Developers mailing list
>> llvm-dev at lists.llvm.org
>> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev

-- 
Hal Finkel
Lead, Compiler Technology and Programming Languages
Leadership Computing Facility
Argonne National Laboratory



More information about the llvm-dev mailing list