RFC: Strong GC References in LLVM

Hi all,

  1. Introduce a flag on load and stores that either

a. Denotes a “gc_safety” control dependence.

b. Denotes a “blackbox_safety” control dependence. In this case

we will probably have some optional metadata on loads and

stores to indicate that the control dependence is actually on

GC safety.

Suggested name for 2b: “unsafe” or “predicated”. Essentially, that the

load is not generally safe to do even if the memory is generally safe

to load from because of some external effect.

Sounds like “volatile” to me …

–Peter Lawrence.

Hi Peter,

>
> Sounds like “volatile” to me …

volatile accesses can't be sunk (i.e. changed to execute in a subset of the cases it would have executed in the original > > program) or elided (e.g. if the result of the load is unused), but both of these are valid for gc references.

-- Sanjoy

Sanjoy,
             Thanks. So it sounds "volatile"-ish, is it conceptually possible to spell out its
semantics in detail ? if so then it might sound like a (yet another) attribute "like" volatile.

IE basically I'm agreeing with #2, and you don't need to spell it out in detail just
for my sake, I'm really asking "can it be spelled out in detail" when it comes to
documenting the IR, such that someone writing an optimization pass will be able
to do the right thing.

--Peter.

Hi Peter,

Just to be clear, as a starting point I'm focusing on getting the
no-pointer-to-integer-funny-business bits reviewed and checked in.
The nospeculate bits will have a separate RFC / design review when the
time comes.

Lawrence, Peter wrote:
>>> Sounds like “volatile” to me …
>
>> -- Sanjoy
>
> Sanjoy,
> Thanks. So it sounds "volatile"-ish, is it conceptually possible to spell out its
> semantics in detail ? if so then it might sound like a (yet another) attribute "like" volatile.

The semantic constraint is about safety. The safety of nospeculate
loads and stores don't just depend on the physical dereferenceability
of the memory location (and in case of stores, thread-locality), but
on some unknown external source. This means you can't speculate

   %x = alloca; // x is dereferenceable
   if (cond)
     %y = load nospeculate %x

into

   %x = alloca;
   %y = load nospeculate %x
   if (cond)
     ...

so in that way it _is_ like volatile. However, as I said before, you
can still DCE unused loads, DSE stores, forward loads to loads,
forward stores to loads etc.

> IE basically I'm agreeing with #2, and you don't need to spell it out in detail just
> for my sake, I'm really asking "can it be spelled out in detail" when it comes to
> documenting the IR, such that someone writing an optimization pass will be able
> to do the right thing.

Initially the rule will be: you cannot speculate nospeculate loads or
stores, period (that is, a transform cannot cause a 'nospeculate'
load/store to execute in a situation that it would not have previously
executed in). Over time we will add a metadata based scheme that
elucidates _why_ a load or store instruction is nospeculate
(e.g. "load nospeculate ... !gc", or something like that) and add
support to LLVM to speculate them in cases that are legal.

Thanks!
-- Sanjoy