@ -32,3 +32,39 @@ There are a number of reasons why Ravi's performance is not as good as Luajit.
from being useful in constrained devices - although ahead of time
compilation could be used in such cases.
Ideas
-----
There are a number of improvements possible. Below are some of my thoughts.
Optimizing Fornum loops
-----------------------
The Lua fornum loops create an `extra "external" variable <http://www.lua.org/manual/5.3/manual.html#3.3.5>`_ that has the name given by the user.
However an internal variable is actually used as the loop index. The external variable is updated at every iteration - this entails several IR
instructions. The obvious optimization is to eliminate this variable by making the loop index available as a readonly value. If for backward
compatiblity it is necessary to allow updates to the external variable then a compromise would be analyse the Lua program and only create the
external variable if necessary.
The Value Storage
-----------------
In Lua the type of the value and the data associated with a value are stored in separate fields. Luajit however overlays the storage by utilizing
the `technique known as NaN tagging <http://lua-users.org/lists/lua-l/2009-11/msg00089.html>`_. The Luajit model is not suited for Lua 5.3 as in this version 64-int integers are natively supported by Lua.
There is however still a possibility that NaN tagging can be used to improve performance of values that hold doubles. The following scheme should work.
Let the first 8 bytes hold a double value. And let the other values be held in the second 8 bytes.
Then the NaN tagging technique can be used to overlay the type information with the double part.
This would allow operations involving doubles to be faster as an extra step to set the type can be avoided. This would mean greater
performance in floating point operations which are important in many domains.
Above scheme has the additional advantage that it can be extended to support complex numbers.
* First 8 bytes could be a double representing the real part.
* Second 8 bytes could be a double representing the imaginary part.
If a value is a not a complex number then the real part will either be
NaN, or if the real part is a double then the imaginary part will be a
NaN.
The problem of course is that NaN tagging may not be viable in mainstream Lua as it is probably a non-portable technique. It could also
introduce incompatibility between Lua and Ravi especially if Ravi supported complex numbers.
@ -18,10 +18,11 @@ The LLVM JIT implementation is in following sources:
* ravi_llvmtypes.cpp - contains LLVM type definitions for Lua objects
* ravi_llvmcodegen.cpp - LLVM JIT compiler - main driver for compiling Lua bytecodes into LLVM IR, also contains implementations of opcodes like OP_JMP
* ravi_llvmload.cpp - implements OP_LOADK and OP_MOVE, and related operations
* ravi_llvmcomp.cpp - implements OP_EQ, OP_LT and OP_LE.
* ravi_llvmcomp.cpp - implements OP_EQ, OP_LT, OP_LE, OP_TEST and OP_TESTSET.
* ravi_llvmreturn.cpp - implements OP_RETURN
* ravi_llvmforprep.cpp - implements OP_FORPREP
* ravi_llvmforloop.cpp - implements OP_FORLOOP
* ravi_llvmarith1.cpp - implements various arithmetic operations
* ravi_llvmarith1.cpp - implements various type specialized arithmetic operations - these are Ravi extensions
* ravi_llvmarith2.cpp - implements Lua opcodes such as OP_ADD, OP_SUB, OP_MUL, OP_DIV
* ravi_llvmcall.cpp - implements OP_CALL
* ravi_llvmtable.cpp - implements OP_GETTABLE, OP_SETTABLE etc. table operations