<div dir="ltr"><br><div class="gmail_extra"><br><br><div class="gmail_quote">On Thu, Oct 24, 2013 at 6:42 PM, Sanjoy Das <span dir="ltr"><<a href="mailto:sanjoy@azulsystems.com" target="_blank">sanjoy@azulsystems.com</a>></span> wrote:<br>

<blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">Hi Rafael, Andrew,<br>
<br>
Thank you for the prompt reply.<br>
<br>
One approach we've been considering involves representing the<br>
constraint "pointers to heap objects are invalidated at every<br>
safepoint" somehow in the IR itself.  So, if %a and %b are values the<br>
GC is interested in, the safepoint at the back-edge of a loop might<br>
look like:<br>
<br>
  ; <label>: body<br>
    %a = phi i32 [ %a.relocated, %body ] [ %a.initial_value, %pred ]<br>
    %b = phi i32 [ %b.relocated, %body ] [ %b.initial_value, %pred ]<br>
    ;; Use %a and %b<br>
<br>
    ;; The safepoint starts here<br>
    %a.relocated = @llvm.gc_relocate(%a)<br>
    %b.relocated = @llvm.gc_relocate(%b)<br>
    br %body<br>
<br>
This allows us to not bother with relocating derived pointers pointing<br>
inside %a and %b, since it is semantically incorrect for llvm to reuse<br>
them in the next iteration of the loop. </blockquote><div><br></div><div>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.</div>

<div><br></div><div>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.</div>

<div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">We lower gc_relocate to a<br>
pseudo opcode which lowered into nothing after register allocation.<br>
<br>
The problem is, of course, the performance penalty.  Does it make<br>
sense to get the register allocator "see" the gc_relocate instruction<br>
as a copy so that they get the same register / slot?  Will that<br>
violate the intended semantics of gc_relocate (for example, after<br>
assigning the same register / slot to %a and %a.relocated, are there<br>
passes that will try to cache derived pointers across loop<br>
iterations)?<br>
<br>
Thanks,<br>
-- Sanjoy<br>
<div class=""><div class="h5"><br>
<br>
_______________________________________________<br>
LLVM Developers mailing list<br>
<a href="mailto:LLVMdev@cs.uiuc.edu">LLVMdev@cs.uiuc.edu</a>         <a href="http://llvm.cs.uiuc.edu" target="_blank">http://llvm.cs.uiuc.edu</a><br>
<a href="http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev</a><br>
</div></div></blockquote></div><br></div></div>