If you’re JITing with LLVM and haven’t made the switch to MCJIT already, now is the time. As per discussions on the mailing list and at the last dev meeting, LLVM 3.5 will be the last release to support the old JIT infrastructure. Now that LLVM 3.5 has branched, we plan to start removing the old JIT from the mainline.
If you’re looking for help in making the switch, Andy Kaylor wrote a great LLVM blog post about porting Kaleidoscope to MCJIT, which you can find at http://blog.llvm.org/2013/07/using-mcjit-with-kaleidoscope-tutorial.html. I’ll also be working to update the LLVM docs and the Kaleidoscope tutorial, and as always you can ask for help in the mailing lists and on IRC.
Good luck with the switch over!
If you have specific questions about this transition, I might be able
to help out here, as I've gone through this process with Julia (the
process should be a lot smoother now that it's working for a good set
of people, so most bugs should have been found)
Could you give a short high-level overview of the way Julia works now with MCJIT instead the JIT:
What I gather so far…
Compiled IR functions are emitted to a shadow module.
Any used function is cloned into its own new module and the module is added to MCJIT.
Called functions or globalvars are only declared in that module.
Modules are never removed meaning “old” functions are abandoned rather then replaced.
All function calls go through a trampoline function doing the multiple dispatch, also enabling old function replacement to new version.
I feel really bad for answering this sooner. I had a draft email but
for some reason never sent it out (though I had). My apologies.
* Compiled IR functions are emitted to a shadow module.
Julia has two different modes of compilation. In one we do the shadow
module thing and whenever we need to call something that's not been
pulled out yet, we compile it and the closure of it's callgraph and
pull it out into a separate module, because we later dump the shadow
module as a whole and compile it as a shared library for caching
generated code. In the other we create a module per function and just
emit it into the module directly (because we don't want to keep around
the bitcode if we're not going to use it, so we delete it right
aftre). Eventually I'm going to have to reevaluate this, because one
module per function is slightly expensive (though not as bad now as it
used to be because of some changes in MCJIT).
* Any used function is cloned into its own new module and the module is added to MCJIT.
Correct, when the shadow module exists, yes.
* Called functions or globalvars are only declared in that module.
I'm not sure what you mean by that. When generating the code (or
copying it), we declare all used global in the module.
* Modules are never removed meaning "old" functions are abandoned rather then replaced.
* All function calls go through a trampoline function doing the multiple dispatch, also enabling old function replacement to new version.
Correct, though this is actually a long standing issue we have where
we are not correctly replacing functions if they are sufficiently
optimized (so that we don't go through the trampoline). I'm hoping to
address this soon using patchpoints, but haven't gotten to that yet.
For now what people who want to replace functions basically do is
replace the bindings in the repl which will force the old code to be
Hope that helps and sorry for forgetting to send this out, please do
send further questions and I'll promise I'll respond more swiftly.