[LLVMdev] Interfacing llvm with a precise, relocating GC

Ben Karel eschew at gmail.com
Fri Oct 25 13:10:33 PDT 2013


On Thu, Oct 24, 2013 at 6:42 PM, Sanjoy Das <sanjoy at azulsystems.com> wrote:

> Hi Rafael, Andrew,
>
> Thank you for the prompt reply.
>
> One approach we've been considering involves representing the
> constraint "pointers to heap objects are invalidated at every
> safepoint" somehow in the IR itself.  So, if %a and %b are values the
> GC is interested in, the safepoint at the back-edge of a loop might
> look like:
>
>   ; <label>: body
>     %a = phi i32 [ %a.relocated, %body ] [ %a.initial_value, %pred ]
>     %b = phi i32 [ %b.relocated, %body ] [ %b.initial_value, %pred ]
>     ;; Use %a and %b
>
>     ;; The safepoint starts here
>     %a.relocated = @llvm.gc_relocate(%a)
>     %b.relocated = @llvm.gc_relocate(%b)
>     br %body
>
> This allows us to not bother with relocating derived pointers pointing
> inside %a and %b, since it is semantically incorrect for llvm to reuse
> them in the next iteration of the loop.


This is the right general idea, but you can already express this constraint
in LLVM as it exists today, by using llvm.gcroot().  As you noted, this
also solves the interior-pointer problem by making it the front end's job
to convey to LLVM when it would/would not be safe to cache interior
pointers across loop iterations. The invariant that a front-end must
maintain is that any pointer which is live across a given
potential-GC-point must be reloaded from its root after a (relocating) GC
might have occurred. This falls naturally out of the viewpoint that %a is
not an object pointer, it's the name of an object pointer's value at a
given point in time. So, of course, whenever that object pointer's value
might change, there must be a new name.

The fact that the mutable memory associated with a gcroot() is allocated on
the stack (rather than, say, a machine register) is an implementation
detail; fixing it doesn't require altering the (conceptual) interface for
LLVM's existing GC support, AFAICT.


> We lower gc_relocate to a
> pseudo opcode which lowered into nothing after register allocation.
>
> The problem is, of course, the performance penalty.  Does it make
> sense to get the register allocator "see" the gc_relocate instruction
> as a copy so that they get the same register / slot?  Will that
> violate the intended semantics of gc_relocate (for example, after
> assigning the same register / slot to %a and %a.relocated, are there
> passes that will try to cache derived pointers across loop
> iterations)?
>
> Thanks,
> -- Sanjoy
>
>
> _______________________________________________
> LLVM Developers mailing list
> LLVMdev at cs.uiuc.edu         http://llvm.cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20131025/d77b69ff/attachment.html>


More information about the llvm-dev mailing list