Thanks for the quick reply, Anton. On 2007-08-12, at 16:43, Anton Korobeynikov wrote:> Hello, Gordon. > > Just a quick thinko (that's why I'm sending this e-mail personally):No problem. I hope you don't mind me redirecting back to the list, though…> maybe current infrastructure used for eh/debug info emission can be > extended to handle ocaml data?Perhaps. I'm pretty sure the code to generate this stuff doesn't belong in LLVM proper like DWARF support does, though; this is not even a vague approximation of a standard. :)> Now it emits just DWARF information. Probably, we can think about > extending it to emit some "random" information. For example, there > is a term "landing pad", which corresponds to catch-block in C++. > Internally, landing pad is just pair of labels plus some additional > info. Labels appears from lowering of invoke inst, maybe something > like this can be used to emit necessary information?Oo, that sounds like the right track. Maybe I could tack an optional something onto the call/invoke instructions that says "export a return address label", like this: %tmp.1 = i8* call @_camlPervasives__print_endline_298(i8* % greeting.0) ret internal i8* @L103 And then adjust the code generators to insert the specified label. Afterwards, @L103 would be a normal constant and I could build the frame table as a plain old LLVM constant.> Some amount of intrinsics plus additional lowering code.I can think of two ways to use an intrinsic toward this end, both of which seem unfortunately flawed: ; Annotation on the call instruction. %tmp.1 = i8* call @_camlPervasives__print_endline_298(i8* % greeting.0) call void @llvm.var.annotate(i8* %tmp.1, i8* "L103", i8* null, i32 0) The code generator can notice the annotation and insert the label. But… what if the callee had a void return type? There's no register to annotate. ; A freestanding call immediately following the call instruction. %tmp.1 = i8* call @_camlPervasives__print_endline_298(i8* % greeting.0) call void @llvm.pcmarker(i32 103) The marker can just be lowered to a label. But… what about caller- save calling convention? The PC marker won't be on the right instruction. If I'm just imagining this problem, then this may be the solution to this problem.> Even more, maybe some present functionaly can be trivially > extended, or annotation intrinsic used for this?Hopefully Chris has something up his sleeve! I don't think llvm.var.annotate works, though as pointed out above. — Gordon -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20070813/ba0100b3/attachment.html>
>> maybe current infrastructure used for eh/debug info emission can be >> extended to handle ocaml data? > > Perhaps. I'm pretty sure the code to generate this stuff doesn't belong in > LLVM proper like DWARF support does, though; this is not even a vague > approximation of a standard. :)>From your original email:>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: > > key : the return address of the call site > value : the stack offset of every variable live after return > >The garbage collector uses this when walking the stack to find >live objects.I don't think you want to try to have the LLVM code generator build this table. 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. In the LLVM world, you should use the first-class support we already have for accurate GC: http://llvm.org/docs/GarbageCollection.html Based on this, you annotate the variables with llvm.gcroot intrinsics, and 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 :) -Chris -- http://nondot.org/sabre/ http://llvm.org/
Hi Chris, Chris Lattner wrote:> I don't think you want to try to have the LLVM code generator build this > table. 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. > > In the LLVM world, you should use the first-class support we already have > for accurate GC: http://llvm.org/docs/GarbageCollection.htmlI was wondering recently: are there actually any projects that are using these facilities? Preferably ones that I could take a look at?> Based on this, you annotate the variables with llvm.gcroot intrinsics, and > 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 :)How is this function actually implemented? Is there special stack-walking code emitted or does LLVM keep an extra stack of roots? Cheers, Carl Friedrich Bolz
On 2007-08-13, at 16:33, Chris Lattner wrote:>> 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: >> >> key : the return address of the call site >> value : the stack offset of every variable live after return >> >> The garbage collector uses this when walking the stack to find >> live objects. > > I don't think you want to try to have the LLVM code generator build > this table. > > 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.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).> In the LLVM world, you should use the first-class support we > already have for accurate GC: http://llvm.org/docs/ > GarbageCollection.html > > Based on this, you annotate the variables with llvm.gcroot intrinsics,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.> and 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 :)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 does exist in order to avoid building a simple data structure. Here are the respective negatives I perceive: Ditch the frame table and write a new runtime: - no need to write any interesting LLVM code! [1] - breaks binary compatibility (including C interop) - have to write new runtime; llvm's GC is a strawman - makes an ugly patch, which makes for licensing problems [2] Tread lightly: - generated .bc is incompatible with llc due to runtime-specific GC codegen � Gordon [1] Yes, this is a downside. :) Possibly the dominant one, since this is a weekend project. [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. -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20070813/e8ca789e/attachment.html>