[llvm-dev] RFC: Strong GC References in LLVM

Eli Friedman via llvm-dev llvm-dev at lists.llvm.org
Mon Jul 11 18:49:20 PDT 2016

On Mon, Jul 11, 2016 at 4:26 PM, Sanjoy Das <sanjoy at playingwithpointers.com>

> Hi Eli,
> Eli Friedman wrote:
> >
> > I'm not really convinced that the GCREF type is really necessary...
> > consider an alternate model:
> >
> > 1. A GCREF is never loaded into a register; it's either on the heap, or
> > in an alloca.
> > 2. Add an intrinsic gcref.copy which copies a gcref between two allocas.
> > 3. Add intrinsics gcref.load_gcref(GCREF*, GCREF*, offset) and
> > gcref.store_gcref(GCREF*, GCREF*, offset, value) which load and store a
> > gcref through a gcref.
> > 4. Add intrinsics gcref.load_value(GCREF*, offset) and
> > gcref.store_value(GCREF*, offset, value) which load and store normal
> > values a gcref.
> > 5. The statepoint lowering pass gets rid of the allocas.
> This is similar to what we used to call "early safepoint insertion",
> but ...
> >
> > Keeping GCREFs exclusively in memory means the LLVM optimizer will
> > handle them conservatively, but correctly.
> >
> > I guess the problem with this is precisely that the LLVM optimizer will
> > handle them conservatively...
> ... yup.  We _want_ LLVM to optimize well.

What optimizations are you missing?  The very fact that it isn't in SSA
form hurts to some extent... and I guess you want to leverage existing
optimizations for loads and stores?

> > but on the flip side, I think you're going
> > to end up chasing down weird problems forever if a "load" from an alloca
> > has side-effects.
> I need to carefully think through this before committing to it, but I
> think we're generally okay with completely disallowing allocas of
> GCREF type (like we do for token types today).  If we could do that
> is your concern addressed?

In general, if I think of a GCREF as an unsized handle to an object rather
than a pointer with weird properties, it's somewhat less scary.  Also, it's
more clear how to deal with a GCREF if you explicitly list out operations
which are legal rather than which operations are illegal.  For example "A
GCREF is a new type of value.  It does not have a representation in
memory.  You can use GEP on a GCREF.  You can load or store through a
GCREF; this resolves the GCREF to a specific address in memory, then acts
like a load/store from that address.  GCREFs have these aliasing rules:
[...].  There are GCREF intrinsics for constructing and manipulating
GCREFs.  No other operations on GCREFs are allowed."

I guess the bit I'm most worried about is using plain loads to create
GCREFs, and plain stores to store them.  As long as we don't have that,
existing optimization passes will essentially just work, I think; we won't
try to duplicate or hoist loads in situations where that isn't allowed, and
we won't try to perform weird value manipulations like trying to construct
one using an inttoptr.  (I guess there are some passes that assume the
operand of a load is specifically a PointerType, but that's not really a
semantic difference.)

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20160711/24ad079a/attachment.html>

More information about the llvm-dev mailing list