I would like to announce the availability of llvm-lua.
llvm-lua, converts Lua bytecode to LLVM IR code and supports JIT and static
compiling. Using LLVM gives Lua JIT support on cpu architectures other then
I converted the Lua bytecode dispatch loop code into a set of C functions one
for each opcode. The opcode functions take two parmeters one is the current
Lua function's state, and the other is the 32bit opcode. The function state
holds all the local variables that where outside the dispatch loop
(lua_State, stack base, constants, closure). That set of opcode functions is
compiled into a LLVM bitcode file (called lua_vm_ops.bc) that is used by
llvm-lua at runtime. llvm-lua load that bitcode file on start-up (right now
it only looks in the working directory for 'lua_vm_ops.bc', I need to find a
better way to load it).
Each Lua function in converted one LLVM function with each Lua opcode in that
function being converted into a function call to one of the opcode functions
in lua_vm_ops.bc with the opcode's 32bit value being a constant for the
second parmeter. Most of those function calls are inlined before running a
few LLVM optimization passes over the whole function.
The performance is better then the normal lua vm on most scripts that I have
tried. For one script I had to disable JIT for any Lua function that had
more then 800 opcodes since the LLVM codegen phase was taking atleast a
second to codegen the LLVM IR to machine code. The first time I ran the
meteor.lua script it used more then 30 seconds to codegen all the Lua code,
where as the normal Lua vm took less then 4 seconds to run the whole script.
See the attached benchmark.log comparing the normal Lua vm with llvm-lua,
native, and luajit. The "native" column shows the scripts after they have
been compiled to machine code and made into standalone executables, the time
for that column doesn't include the compile time. All the code used in this
benchmark to compare the VMs can be downloaded from the project's website.
The code can be downloaded from the project's website:
benchmark.log (2.18 KB)