[LLVMdev] Integrating LLVM in an existing project
Nicolas Geoffray
nicolas.geoffray at lip6.fr
Thu Apr 5 05:10:52 PDT 2007
Hi everyone,
After some time hacking on llvm, let me introduce myself :)
I'm a PhD student at the French university Pierre et Marie Curie in
Paris. I work on a project
called the "Virtual Virtual Machine" project. You can find some (dated)
information on the
website http://vvm.lip6.fr.
Basically it's a "low level virtual machine" :) with a just in time
compiler called the VPU, an execution environment
(GC + threads) and it parses a lisp-like language that is translated to
the VPU's internal bytecode.
On top of this execution environment we have implemented a java virtual
machine and a .net virtual machine. They
are both functional and we achieve reasonable performance (1/3 of IBM's
JVM or Mono).
Our just in time compiler is however what we think the main limit for
having better performance. Our register allocator
is really simple and we don't have any basic optimization passes. So we
decided to take a look at llvm and see if it was
possible to translate the VPU's internal bytecode to llvm's bytecode.
After porting llvm to linux/ppc, and adding some
functionality in llvm (like knowing the required size for the code of a
method before allocating memory for the method), we can now execute
a large amount of code of our lisp-like language.
So the next step was to execute our Java and .Net virtual machine on top
of the new execution environment with llvm. They are both
implemented in the lisp-like language, therefore we expected nothing or
at least little changes. Which was the case. However when executing Java
or .Net applications we turned into the problem of exception handling.
Exception handling is not integrated in our execution environment. The
JIT is not aware of exception handling. Therefore they are handled at
the application level with setjmp and longjmp. When a method with
exceptions is compiled, we set labels (start, end, handler) in the
compiler for each exception and after compilation grab the address of
these labels in the generated code. When an exception is thrown, we
compare the current instruction pointer with all couples (start, end) of
the current method. If the IP is in the interval, and if the exception
type is correct, we setjmp to an instruction in the method's code which
will jump to the handler. If not, we look at the calling method's
exceptions, and so on until we reach the end of the backtrace.
This algorithm does not work with llvm because creating labels (which
correspond to creating basic blocks) does not imply that the label (ie
the basic block) will have an address. Even without optimizations
enabled in llvm, some basicblocks are not emitted (obviously because
some basic blocks are useless).
We can not use current exception handling in llvm, see
http://www.nondot.org/sabre/LLVMNotes/ExceptionHandlingChanges.txt.
We can not use the llvm.dbg.stoppoint feature because it is not
implemented in llvm's JIT.
So we are stuck :). However we would really like to see what performance
gains we have with llvm.
So here are a few questions whose answers will help me go through this issue
1) Is the Chris' exception handling note actually implemented or is it
still in project? And how difficult do you expect it to be? (Even if I
have implemented some stuff in llvm, I am still not entirely comfortable
with the code)
2) The llvm.dbg.stoppoint: how far is it actually implemented?
3) Getting the address of basic blocks: is there a workaround?
Thanks a lot for your answers. And don't hesitate to ask me more infos
if things aren't clear in my explanations.
Best,
Nicolas
More information about the llvm-dev
mailing list