[PATCH] D101701: [nofree] Refine concurrency requirements
Johannes Doerfert via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Mon May 10 07:54:00 PDT 2021
jdoerfert added a comment.
In D101701#2747492 <https://reviews.llvm.org/D101701#2747492>, @nlopes wrote:
> In D101701#2746949 <https://reviews.llvm.org/D101701#2746949>, @jdoerfert wrote:
>
>> In D101701#2746841 <https://reviews.llvm.org/D101701#2746841>, @nlopes wrote:
>>
>>> @jdoerfert a function that syncs with another thread may not free anything itself and the other thread may not free anything either.
>>> If you require an optimization to have nofree + nosync in a call to preserve dereferenceability then you can't optimize this case.
>>
>> I disagree, and I think this is the conceptual differences we have here.
>>
>> If one does only look at a function in isolation then I agree, `nofree` alone is not sufficient to make statements about all call sites and arguments.
>> However, if you look at a call site of a `nofree` function the situation is different because you have context information about the arguments.
>>
>> Let's go back to my last example:
>>
>> a = malloc
>> b = malloc
>> unknown(a); // no attributes 0-> escapes
>> nofree_nocapture_only(a, b); // `nofree`, `nocapture` on args
>>
>> I know that at the end of this sequence `b` has not been freed, even though there is no `nosync` in sight.
>> I can also derive `nofree` for `nofree_nocapture_only` without worrying about atomics, for example.
>> (Here is the sequence in action with heap2stack kicking in for b: https://godbolt.org/z/hjYrhaEvW)
>>
>> So, with `nofree` and `nosync` being completely separated, as it was in the very beginning, you can:
>>
>> 1. Optimize even if only one is present, given additional call site information.
>> 2. Derive `nofree` even if `nosync` is not present.
>
> Your examples are around nofree arguments, not nofree functions, which is what this patch is about.
`nofree` functions imply `nofree` arguments so it very much makes a difference if we make it harder to infer
and annotate the former. As we already moved to a more semantic-based definition of escaped we can actually
look at an example where this makes a difference. Take pointers passed via memory to see how you cannot just
move the `nofree` to account for the change made by this patch:
struct { int *a } s;
s.a = malloc() // this is a store.
nofree_nocapture_only(&s) // we can potentially show `s.a` is not captured in the function but we cannot
// annotate that fact as a `nofree` argument without argument promotion, which
// we cannot always do.
// s.a is still known to be dereferenceable even without `nosync`. The function `nofree` is needed, `nofree`
// argument attributes are not involved.
> nofree in functions is useful for pointers that are *not* passed as argument, like this:
>
> f(i8* %p) {
> load %p ; implies it's dereferenceable
> call @g() nofree
> ; is %p still dereferenceable or not?
> }
>
> This patch states that yes, %p is still dereferenceable after the call to @g as it's tagged with nofree. That's it.
Let's not ignore the arguments that are somehow passed though. Anyway, this patch does not actually add anything you
need for you example. If `g` is `nofree` & `nosync` you get exactly the same effect already. I hope we agree on that.
If we allow user feedback you can also make your `@f` `nosync` and get the effect you want even if `@g` is not `nosync`,
This is especially useful if @g is an intrinsic users cannot actually annotate.
In addition to the examples I brought up that are impacted, let me reiterate what I said in my first post:
Other attributes work in the same composable way:
void foo(int * __restrict__ flag, char* p) {
argmemonly(flag); // Says argmemonly and p is not passed nor does p alias flag, still p is potentially written.
// This is like a call to a `nofree` function which might still free pointers via synchronization.
// `nosync` is a orthogonal component to these attributes as we can otherwise not derive them.
// However, as with `nofree`, we can use the attributes even without `nosync` in some situations.
}
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D101701/new/
https://reviews.llvm.org/D101701
More information about the llvm-commits
mailing list