Just In Time Compiler
Since May 2012, 24th Gambas
got a Just In Time
The compiler has been implemented by Emil Lenngren
The compiler uses LLVM to produce machine code for x86 or x86_64.
Find more instructions in the gb.jit/README
To use it, place the keyword FAST
at the top of a Gambas Class
file, for a
that you want all functions JIT-compiled instead of interpreted, or at the beginning
of a function declaration, so that only that function is JIT-compiled.
As it takes some milliseconds for LLVM to emit machine code and do
optimizations, you should only use it for functions you really need
Additional Type Checking
As the JIT compiler analyses the whole function before execution starts,
some extra type safety is added. In interpreter mode, you can normally do
Print 1.3 \ 5
and you will first see hello on the screen, and then an error message
complaining you can't do integer division on floats.
If you run the same function in the JIT compiler, the error message will be
thrown before execution starts instead, hopefully in order to make programs
As a consequence, you can not have code like Try Print 1.3 \ 5
The best speed-ups will be in functions that use a lot of low-level
calculations and control flows (except For Each
loops), like functions that
do a lot of math. If the function mostly calls other libraries, you won't
see speed-ups either.
There are still the same overhead when calling functions, since the Gambas
stack must be maintained as before, to make error handling work.
is probably slightly slower too because a real exception
handler must be set up.
Something the LLVM optimizer is very good at is transforming a chain of
if-else statements to a jump table, so code like:
Select Case x
will be much faster than before, so you don't have to use the ON GOTO
syntax and a lot of labels. This will produce identical machine code.
Some of the benchmarks from the benchmarking page
- Polynom: 100 seconds to 9.2 seconds.
- Primes: 20.4 seconds to 5.95 seconds.
- Nbody: 20.8 seconds to 3.07 seconds.
Most things are implemented, but there are still some features and bugs to fix.
Some of the (so far) unimplemented features are:
- Making a callback function pointer of a Gambas function in another class, for use with external libraries.
- Using Component.Load to load functions that are executed right after in the same function.
If you are curious and want to see the optimized LLVM IR, just define the GB_JIT
with a non-null string.