On Fri, Apr 1, 2011 at 1:58 AM, Jay Foad <span dir="ltr"><<a href="mailto:jay.foad@gmail.com">jay.foad@gmail.com</a>></span> wrote:<br><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">

<div class="im">On 30 March 2011 19:08, Talin <<a href="mailto:viridia@gmail.com">viridia@gmail.com</a>> wrote:<br>
> llvm.gc.declare(alloca, meta). This intrinsic marks an alloca as a garbage<br>
> collection root. It can occur anywhere within a function, and lasts either<br>
> until the end of the function, or a until matching call to<br>
> llvm.gc.undeclare().<br>
> llvm.gc.undeclare(alloca). This intrinsic unmarks and alloca, so that it is<br>
> no longer considered a root from that point onward.<br>
<br>
</div>Hi Talin,<br>
<br>
What changes to code generation would be necessary to support this?<br>
<br></blockquote><div>I can only describe this in abstract terms, since I know very little about LLVM's code generation. (I am primarily a user of LLVM, not a developer of it, although I have made a few minor contributions.)</div>

<div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">
Is there any intention of supporting a collector that has static stack<br>
maps for each function, i.e. a table telling you, for each point in<br>
the code, where all the roots are on the stack (similar to unwind info<br>
for exception handling)? If so, I think it's a bit dodgy to use<br></blockquote><div><br></div><div>That is already supported in the current LLVM. The changes I am proposing are merely an extension of what we have now, allowing frontends to emit more efficient code.</div>

<div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">
intrinsic function calls to mark the start/end of the lifetime of a GC<br>
root, because function calls are inherently dynamic. For example, you<br>
can't represent this code with a static stack map:<br>
<br>
if (cond) {<br>
  llvm.gc.declare(foo, bar);<br>
}<br>
...<br>
// foo may or may not be a root here<br>
...<br>
if (cond) { // same condition as above<br>
  llvm.gc.undeclare(foo);<br>
}<br>
<br></blockquote><div>You would need to do the same as what is done today: Move the declare outside of the condition, and initialize the variable to a null state, such that the garbage collector will know to ignore the variable. In the if-block, you then overwrite the variable with actual data.</div>

<div><br></div><div>The difference is that in the today's LLVM, the variable declaration has to be in the first block, and lasts for the entire function - so you have to initialize all of your stack variables to a null state in the first block. By extending the notation to allow stack roots to have a limited lifetime, we can avoid having to initialize the stack root unless we actually enter the block where it is defined.</div>

<div><br></div><div>I should mention that the declare/undeclare intrinsics are the least important part of this proposal. The important part is the ability to declare SSA values as roots - that is what will make a world of difference to folks like myself that are writing frontends that use garbage collection.</div>

<div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">
Even if you're careful not to generate code like this in your front<br>
end, how can you guarantee that LLVM optimisation passes won't<br>
introduce it?<br>
<br>
The old llvm.dbg.region.start and llvm.dbg.region.end had the same<br>
kind of problem.<br>
<br>
Thanks,<br>
<font color="#888888">Jay.<br>
</font></blockquote></div><br><br clear="all"><br>-- <br>-- Talin<br>