[PATCH] D103492: [RS4GC] Treat inttoptr as base pointer

Sam Dirkswager via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Fri Jun 4 19:44:46 PDT 2021


tolziplohu added a comment.

In D103492#2800032 <https://reviews.llvm.org/D103492#2800032>, @reames wrote:

> Good idea, post a patch and it'd be a quick LGTM.

Okay, here it is <https://reviews.llvm.org/D103732>. It turns out most of the existing test cases for RS4GC actually forgot to mark `addrspace(1)` as non-integral as well, and one even uses a bunch of `inttoptr`s.

> A few quick examples:
>
> - You could spell a "pin" operator which prevents an object from being moved, and an "unpin" that releases. Within that dynamic scope, it's fine to loose copies of the pointer, provided at least one isn't lost. In this world, the conversion operator only exists from reference to integer, not the other way around. Such a conversion can be hoisted no further than the containing pin operation.
> - For that same language with a non-relocating GC, you can let the conversion float above the pin.
> - A language could allow a "create object from raw memory" mechanism, with all the invariants about a) having valid object state, and b) having the creation object being a *move* of the raw pointer. (e.g. the raw pointer can't survive the creation.) In this model, we'd need the optimizer never to look back through the conversion operator. (e.g. a transform which did convert(p)->f to p->f would be wrong.)
>
> I have yet to find/come up with a sufficiently general model to describe all reasonable variants. At the moment, I'd suggest your variant (1), but as you note, that impacts optimization. Are there concrete examples you're trying to optimize?

My current use case is what I alluded to in the first post: I want to pass something like an i32 to a polymorphic function, without allocating. So I mark the lowest bit and do an `inttoptr` before passing it to the function. This is the same strategy OCaml uses. So if LLVM inlines the polymorphic function, I'd ideally like it to be able to cancel out the `inttoptr -> ptrtoint`.

Something else I've noticed a need for is something like `declare i8 addrspace(1)* @llvm.gc.is_base_ptr(i8 addrspace(1)*)`, which would just return its argument, to wrap around the return value of my allocation function. I'd like that to be inlined, but then LLVM finds the wrong base pointer, so currently I have to have another `noinline` function to pass the return value through. This intrinsic would probably also work for your "create object from raw memory" example, although I'm not sure how to tell the optimizer that the previous pointer is no longer valid. For your other examples, I'm not sure I fully understand the scenario, but converting from a reference to an integer and not back again is always safe, isn't it?

> Warning: I'm really bad at responding promptly to long design discussions in email.  I strongly advise setting up a time to talk offline.

What do you mean by "offline"? A video call or something? I'd be open to that, when you have time.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D103492



More information about the llvm-commits mailing list