<div dir="ltr">On Mon, Jul 11, 2016 at 4:26 PM, Sanjoy Das <span dir="ltr"><<a href="mailto:sanjoy@playingwithpointers.com" target="_blank">sanjoy@playingwithpointers.com</a>></span> wrote:<br><div class="gmail_extra"><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">Hi Eli,<span class=""><br>
<br>
Eli Friedman wrote:<br>
><br>
> I'm not really convinced that the GCREF type is really necessary...<br>
> consider an alternate model:<br>
><br>
> 1. A GCREF is never loaded into a register; it's either on the heap, or<br>
> in an alloca.<br>
> 2. Add an intrinsic gcref.copy which copies a gcref between two allocas.<br>
> 3. Add intrinsics gcref.load_gcref(GCREF*, GCREF*, offset) and<br>
> gcref.store_gcref(GCREF*, GCREF*, offset, value) which load and store a<br>
> gcref through a gcref.<br>
> 4. Add intrinsics gcref.load_value(GCREF*, offset) and<br>
> gcref.store_value(GCREF*, offset, value) which load and store normal<br>
> values a gcref.<br>
> 5. The statepoint lowering pass gets rid of the allocas.<br>
<br></span>
This is similar to what we used to call "early safepoint insertion",<br>
but ...<span class=""><br>
<br>
><br>
> Keeping GCREFs exclusively in memory means the LLVM optimizer will<br>
> handle them conservatively, but correctly.<br>
><br>
> I guess the problem with this is precisely that the LLVM optimizer will<br>
> handle them conservatively...<br>
<br></span>
... yup.  We _want_ LLVM to optimize well.<span class=""><br></span></blockquote><div><br></div><div>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?<br></div><div> <span class=""></span><br><span class=""></span></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><span class="">
> but on the flip side, I think you're going<br>
> to end up chasing down weird problems forever if a "load" from an alloca<br>
> has side-effects.<br>
<br></span>
I need to carefully think through this before committing to it, but I<br>
think we're generally okay with completely disallowing allocas of<br>
GCREF type (like we do for token types today).  If we could do that<br>
is your concern addressed?<br></blockquote><div><br></div>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."<br><br></div><div class="gmail_quote">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.)<br><br></div><div class="gmail_quote">-Eli<br></div></div></div>