* matmul1.ravi - matrix multiplication (ravi version with static typing)
* matmul1_ravi.lua - matrix multiplication (ravi version with static typing)
Following performance tests were obtained from the `The Computer Programming Language Benchmarks Game <http://benchmarksgame.alioth.debian.org/>`_. Original author is `Mike Pall <http://luajit.org/>`_.
@ -415,7 +415,7 @@ The main changes compared to ``explist()`` are the calls to ``ravi_typecheck()``
/* code an instruction to convert in place */
luaK_codeABC(ls->fs,
vars[i] == RAVI_TARRAYFLT ?
OP_RAVI_TOARRAYF : OP_RAVI_TOARRAYI,
OP_RAVI_TOFARRAY : OP_RAVI_TOIARRAY,
a + (i - n), 0, 0);
}
else if ((vars[n] == RAVI_TNUMFLT || vars[n] == RAVI_TNUMINT) &&
@ -435,7 +435,7 @@ The simple case is when the type of the expression matches the variable.
Secondly if the expression is a table initializer then we need to generate specialized opcodes if the target variable is supposed to be ``integer[]`` or ``number[]``. The specialized opcode sets up some information in the ``Table`` structure. The problem is that this requires us to modify ``OP_NEWTABLE`` instruction which has already been emitted. So we scan the generated instructions to find the last ``OP_NEWTABLE`` instruction that assigns to the register associated with the target variable.
Next bit of special handling is for function calls. If the assignment makes a function call then we perform type coercion on return values where these values are being assigned to variables with defined types. This means that if the target variable is ``integer`` or ``number`` we issue opcodes ``TOINT`` and ``TOFLT`` respectively. If the target variable is ``integer[]`` or ``number[]`` then we issue ``TOARRAYI`` and ``TOARRAYF`` respectively. These opcodes ensure that the values are of required type or can be cast to the required type.
Next bit of special handling is for function calls. If the assignment makes a function call then we perform type coercion on return values where these values are being assigned to variables with defined types. This means that if the target variable is ``integer`` or ``number`` we issue opcodes ``TOINT`` and ``TOFLT`` respectively. If the target variable is ``integer[]`` or ``number[]`` then we issue ``TOIARRAY`` and ``TOFARRAY`` respectively. These opcodes ensure that the values are of required type or can be cast to the required type.
Note that any left over variables that are not assigned values, are set to 0 if they are of integer or number type, else they are set to nil as per Lua's default behavior. This is handled in ``localvar_adjust_assign()`` which is described later on.
@ -558,7 +558,7 @@ Note the use of ``register_to_localvar_index()`` in functions below.
OP_RAVI_TOFLT : OP_RAVI_TOINT, i, 0, 0);
else if (ravi_type == RAVI_TARRAYINT || ravi_type == RAVI_TARRAYFLT)
@ -34,7 +34,7 @@ The Architecture of Ravi's JIT Compilation
* The decision to call a JIT compiled version is made in the Lua Infrastructure (specifically in ``luaD_precall()`` function in ``ldo.c``)
* The JIT compiler translates Lua/Ravi bytecode to LLVM IR - i.e. it does not translate Lua source code.
* There is no inlining of Lua functions.
* Generally the JIT compiler implements the same instructions as in ``lvm.c`` - however for some bytecodes the code calls a C function rather than generating inline IR. These opcodes are OP_LOADNIL, OP_NEWTABLE, OP_RAVI_NEWARRAYINT, OP_RAVI_NEWARRAYFLT, OP_SETLIST, OP_CONCAT, OP_CLOSURE, OP_VARARG, OP_RAVI_SHL_II, OP_RAVI_SHR_II.
* Generally the JIT compiler implements the same instructions as in ``lvm.c`` - however for some bytecodes the code calls a C function rather than generating inline IR. These opcodes are OP_LOADNIL, OP_NEWTABLE, OP_RAVI_NEW_IARRAYNT, OP_RAVI_NEW_FARRAYLT, OP_SETLIST, OP_CONCAT, OP_CLOSURE, OP_VARARG, OP_RAVI_SHL_II, OP_RAVI_SHR_II.
* Ravi represents Lua values as done by Lua 5.3 - i.e. in a 16 byte structure.
* Ravi compiler generates type specifc opcodes which result in simpler and higher performance LLVM IR.
@ -154,9 +154,9 @@ Note that if a Lua functions contains a bytecode that cannot be be JITed then th
,opmode(0,1,OpArgR,OpArgN,iABC)/* OP_RAVI_MOVEI A B R(A) := tointeger(R(B)) */
,opmode(0,1,OpArgR,OpArgN,iABC)/* OP_RAVI_MOVEF A B R(A) := tonumber(R(B)) */
,opmode(0,1,OpArgR,OpArgN,iABC)/* OP_RAVI_MOVEAI A B R(A) := R(B), check R(B) is array of int */
,opmode(0,1,OpArgR,OpArgN,iABC)/* OP_RAVI_MOVEAF A B R(A) := R(B), check R(B) is array of floats */
,opmode(0,1,OpArgR,OpArgN,iABC)/* OP_RAVI_MOVEIARRAY A B R(A) := R(B), check R(B) is array of int */
,opmode(0,1,OpArgR,OpArgN,iABC)/* OP_RAVI_MOVEFARRAY A B R(A) := R(B), check R(B) is array of floats */
,opmode(0,1,OpArgR,OpArgN,iABC)/* OP_RAVI_MOVETAB A B R(A) := R(B), check R(B) is a table */
,opmode(0,1,OpArgR,OpArgK,iABC)/* OP_RAVI_GETTABLE_AI A B C R(A) := R(B)[RK(C)] where R(B) is array of integers and RK(C) is int */
,opmode(0,1,OpArgR,OpArgK,iABC)/* OP_RAVI_GETTABLE_AF A B C R(A) := R(B)[RK(C)] where R(B) is array of floats and RK(C) is int */
,opmode(0,1,OpArgR,OpArgK,iABC)/* OP_RAVI_IARRAY_GET A B C R(A) := R(B)[RK(C)] where R(B) is array of integers and RK(C) is int */
,opmode(0,1,OpArgR,OpArgK,iABC)/* OP_RAVI_FARRAY_GET A B C R(A) := R(B)[RK(C)] where R(B) is array of floats and RK(C) is int */
,opmode(0,0,OpArgK,OpArgK,iABC)/* OP_RAVI_SETTABLE_AI A B C R(A)[RK(B)] := RK(C) where RK(B) is an int, R(A) is array of ints, and RK(C) is an int */
,opmode(0,0,OpArgK,OpArgK,iABC)/* OP_RAVI_SETTABLE_AF A B C R(A)[RK(B)] := RK(C) where RK(B) is an int, R(A) is array of floats, and RK(C) is an float */
,opmode(0,0,OpArgK,OpArgK,iABC)/* OP_RAVI_SETTABLE_AII A B C R(A)[RK(B)] := RK(C) where RK(B) is an int, R(A) is array of ints, and RK(C) is an int */
,opmode(0,0,OpArgK,OpArgK,iABC)/* OP_RAVI_SETTABLE_AFF A B C R(A)[RK(B)] := RK(C) where RK(B) is an int, R(A) is array of floats, and RK(C) is an float */
,opmode(0,0,OpArgK,OpArgK,iABC)/* OP_RAVI_IARRAY_SET A B C R(A)[RK(B)] := RK(C) where RK(B) is an int, R(A) is array of ints, and RK(C) is an int */
,opmode(0,0,OpArgK,OpArgK,iABC)/* OP_RAVI_FARRAY_SET A B C R(A)[RK(B)] := RK(C) where RK(B) is an int, R(A) is array of floats, and RK(C) is an float */
,opmode(0,0,OpArgK,OpArgK,iABC)/* OP_RAVI_IARRAY_SETI A B C R(A)[RK(B)] := RK(C) where RK(B) is an int, R(A) is array of ints, and RK(C) is an int */
,opmode(0,0,OpArgK,OpArgK,iABC)/* OP_RAVI_FARRAY_SETF A B C R(A)[RK(B)] := RK(C) where RK(B) is an int, R(A) is array of floats, and RK(C) is an float */