<html><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space; "><div><div>On 2007-08-13, at 16:33, Chris Lattner wrote:</div><div><br class="webkit-block-placeholder"></div><div><div><blockquote type="cite"><blockquote type="cite"><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; "><span class="Apple-style-span" style="-webkit-text-stroke-width: -1; ">The biggest problem is a data structure called the frame table, aÊsimple structure for which LLVM seems ill-prepared. For each callÊsite in the program, ocaml emits an entry into this table:</span></div></blockquote></blockquote><blockquote type="cite"></blockquote><blockquote type="cite"></blockquote><blockquote type="cite"><blockquote type="cite"><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; min-height: 14px; "><br></div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; ">Ê ÊÊkeyÊÊÊ: the return address of the call site</div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; ">Ê ÊÊvalue : the stack offset of every variable live after return</div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; min-height: 14px; "><br></div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; ">The garbage collector uses this when walking the stack to findÊ<span class="Apple-style-span" style="-webkit-text-stroke-width: -1; ">live objects.</span></div></blockquote><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; min-height: 14px; "><br></div></blockquote><blockquote type="cite"><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; ">I don't think you want to try to have the LLVM code generator build thisÊ<span class="Apple-style-span" style="-webkit-text-stroke-width: -1; ">table.</span></div></blockquote><blockquote type="cite"><br></blockquote><blockquote type="cite"><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; "><span class="Apple-style-span" style="-webkit-text-stroke-width: -1; ">The table is a contract between the specific codegen you're usingÊand the GC runtime you're using.Ê This contract is specific to the currentÊocaml code generator.</span></div></blockquote><div><br class="webkit-block-placeholder"></div><div>Ocaml is compiled statically; this isn't an ephemeral link from JIT to runtime as might be the case for a Java or Perl program. Changing these structures breaks binary compatibility (including C interop).</div><br><blockquote type="cite"><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; "><span class="Apple-style-span" style="-webkit-text-stroke-width: -1; ">In the LLVM world, you should use the first-class support we already haveÊfor accurate GC: <a href="http://llvm.org/docs/GarbageCollection.html">http://llvm.org/docs/GarbageCollection.html</a></span></div></blockquote><blockquote type="cite"><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; "><br></div></blockquote><blockquote type="cite"><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; ">Based on this, you annotate the variables with llvm.gcroot intrinsics,</div></blockquote><div><br class="webkit-block-placeholder"></div><div>I'm totally on board with that. The llvm.gc* intrinsics are well-designed as hooks for runtime-specific code generation. I just need to custom lower llvm.gcroot, too.</div><br><blockquote type="cite"><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; ">andÊ<span class="Apple-style-span" style="-webkit-text-stroke-width: -1; ">then walk the stack with the llvm_cg_walk_gcroots function.ÊNote thatÊthese are not well tested and probably have holes in them, but these areÊthe interfaces we want to use :)</span></div></blockquote><div><br class="webkit-block-placeholder"></div><div>But here I have to disagree.ÊQuite by design, LLVM lacks an existing runtime to leverage: LLVM ­ CLR. In light of that, it is difficult to justify ignoring a mature runtime that <i>does</i> exist in order to avoid building a simple data structure.</div><div><br class="webkit-block-placeholder"></div><div>Here are the respective negatives I perceive:</div><div><br></div><div></div><div>Ditch the frame table and write a new runtime:</div><div>-Êno need to write any interesting LLVM code! [1]</div><div>-Êbreaks binary compatibility (including C interop)</div><div>-Êhave to write new runtime; llvm's GC is a strawman</div><div>- makes an ugly patch, which makes for licensing problemsÊ[2]</div><div><div><div><br></div><div><div><div>Tread lightly:</div><div>- generated .bc is incompatible with llc due to runtime-specific GC codegen</div></div><br class="webkit-block-placeholder"></div></div></div><div><div>Ñ Gordon</div></div><div><br></div><div><div><div><br class="webkit-block-placeholder"></div><div>[1] Yes, this is a downside. :) Possibly the dominant one, since this is a weekend project.</div><div><br class="webkit-block-placeholder"></div><div>[2] ocaml is licensed under the QPL [Trolltech/KDE], which has an onerous distribution clause which prohibits forks. My current work leaves the existing code generator in place, touching only a few files to integrate LLVM code generation as a runtime option; this improves the possibility that a patch would be accepted, and otherwise makes patch maintenance manageable.</div></div><div><br></div></div></div><div></div></div></div></body></html>