Just In Time Compiler (old version)
On May 24, 2012, Gambas got a Just In
Time compiler.
The compiler was implemented by
Emil Lenngren.
The compiler uses LLVM to produce machine code for x86 or x86_64.
You need LLVM version 3.1-3.5 on your computer for the Just In Time compiler to work.
Since 3.3
Find more instructions in the
gb.jit/README
file.
Syntax
To use it, place the keyword
FAST at the top of a Gambas
Class file, for a
class 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 that really need
optimization.
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
things like:
Print "hello"
Print 1.3 \ 5
You would 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. Hopefully, this will make programs less buggy.
As a consequence, you can not have code like
Try Print 1.3 \ 5
either.
Performance
The biggest increases in speed will be in functions that use a lot of low-level
calculations and control flows (except
For Each
loops), such as functions that
do a lot of math. However, if the function mostly calls other libraries, you won't
see any great increase in speed.
There is still the same overhead when calling functions, since the Gambas
stack must be maintained as before, to make error handling work.
Using
Try=/=Catch
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
Case 1
...
Case 2
...
Case 3
...
End Select
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.
Caveats
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 one right after in the same function.
-
Breakpoints.
-
Automatic conversion between classes.
Debugging
If you are curious and want to see the optimized LLVM IR, just define the
GB_JIT
environment variable
with a non-null string.