[PATCH] D92808: [ObjC][ARC] Use operand bundle 'clang.arc.rv' instead of explicitly emitting retainRV or claimRV calls in the IR

Duncan P. N. Exon Smith via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Tue Feb 9 13:41:06 PST 2021


dexonsmith added a comment.

I have a couple of suggestions below to add to the mix (but I don't feel strongly about either of them, just adding them for consideration).

In D92808#2552100 <https://reviews.llvm.org/D92808#2552100>, @ahatanak wrote:

>   define void @test() {
>     %r = call i8* @foo() [ "clang.arc.rv"(i64 1) ]
>     call void (...) @llvm.objc.clang.arc.noop.use(i8* %r)
>     ret void
>   }

Firstly, it feels to me like this IR would clarify that the bundle looks at the return value:

  define void @test() {
    %r = call i8* @foo() [ "clang.arc.rv"(i64 1, i8* %r) ]
    ret void
  }

Notice this passes `%r` to the operand bundle, which the verifier rejects. I wonder if the IR rule could safely be weakened to allow an operand bundle to reference the call/invoke it's attached to? (Not sure what all the implications would be, or if this would be sufficient...)

In D92808#2552100 <https://reviews.llvm.org/D92808#2552100>, @ahatanak wrote:

> Or we could use a bundle that is more generic than `clang.arc.rv` (for example, `"implicitly.used.by"(@llvm.objc.retainAutoreleasedReturnValue)`, which indicates the result is used by an instruction that isn't explicitly emitted in the IR).

Secondly, I agree it might be cleaner to formalize a generic operand bundle that has the semantics ARC needs. It might be nice to have this also model the inlining semantics, maybe something like "returnfilter":

  %x = call type @f1(...) [ "returnfilter"(type(type)* @f2) ]

The semantics could be that `%x` is implicitly passed through `@f2`. Concretely, maybe that's:

- `%x` has an implicit use.
- `@f1`'s return type cannot be changed.
- Inlining `@f1` generates explicit calls to `@f2`.
- The backend lowers the bundle as late as possible to calls to `@f2`.

Thirdly, you could combine the two previous ideas, generalizing the semantics to an "onreturn" bundle that is allowed to self-reference the callable, that the inliner knows about, etc., something like:

  %x = call type @f1(...) [ "onreturn"(type(type)* @f2, type %x) ]

This `@f2` is implicitly called and its return used in place of `%x`, but it explicitly lists its arguments. Compared to "returnfilter", it has the flexibility to specify argument order and might be more useful for other applications.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D92808/new/

https://reviews.llvm.org/D92808



More information about the cfe-commits mailing list