On Friday I translated my libjit-based JIT to use LLVM.
This took a good part of the day; then I spent a chunk of Saturday
debugging it.
LLVM has a few drawbacks, as compared to libjit. There’s not
really any documentation for how to use LLVM as a JIT, so I ended up
reading the header files quite a bit; libjit is much better here.
LLVM’s API is quite a bit bulkier than libjit’s, and it is more
idiosyncratic. For instance, in LLVM many objects can have a name,
and many classes require a name in their constructors; this seems a
bit bloaty in a JIT context — but I didn’t measure it. Finally, LLVM
is installed strangely; it is mostly static libraries, but with a few
random object files thrown in for good measure. This is unfriendly to
say the least… also, link times with LLVM are much longer than with
libjit, reducing my efficiency.
Some of these I would like to see fixed — either in LLVM or in
whatever ends up, someday, in GCC. Names could perhaps be handled
optionally. Other oddities in the interface could be fixed (not that
I have a list or anything…). Shared libraries should be made.
All this is gas, though, in a way. LLVM is generally more
functional than libjit: it has many more ports, more optimizers, and a
friendlier license. It probably represents a better long-term
approach.
With a little help on irc from Chris Lattner I got the LLVM JIT
running a couple very simple Java programs; with the optimizers
enabled it appears that LLVM correctly notices that the empty loops
are empty and removes them… so, it is working. There’s still a lot
of debugging to do (“hello world” still crashes), but this isn’t a big
deal.
Naturally, exception handling remains a problem. I’m hoping to
get Bryce or Andrew to solve that problem 🙂
One Comment
Did you do any benchmarks comparing the generated bytecodes?