gccjit-ravi534
Dibyendu Majumdar 7 years ago
commit 8d9c9310ad

@ -81,7 +81,7 @@ enum ravi_codegen_type {
RAVI_CODEGEN_ALL = 3,
};
typedef struct ravi_compile_options_t {
struct ravi_compile_options_t {
/* Is this a manual request? */
int manual_request;
@ -95,7 +95,7 @@ typedef struct ravi_compile_options_t {
int verification_level;
enum ravi_codegen_type codegen_type;
} ravi_compile_options_t;
};
LUAI_FUNC bool raviJ_cancompile(Proto *p);
@ -103,7 +103,7 @@ LUAI_FUNC bool raviJ_cancompile(Proto *p);
// Returns true if compilation was successful
// If successful then buf will be set
LUAI_FUNC bool raviJ_codegen(struct lua_State *L, struct Proto *p,
ravi_compile_options_t *options, const char *fname, membuff_t *buf);
struct ravi_compile_options_t *options, const char *fname, membuff_t *buf);
#ifdef __cplusplus
};

@ -16,6 +16,7 @@ extern void membuff_rewindpos(membuff_t *mb);
extern void membuff_resize(membuff_t *mb, size_t new_size);
extern void membuff_free(membuff_t *mb);
extern void membuff_add_string(membuff_t *mb, const char *str);
extern void membuff_add_fstring(membuff_t *mb, const char *str, ...);
extern void membuff_add_bool(membuff_t *mb, bool value);
extern void membuff_add_int(membuff_t *mb, int value);
extern void membuff_add_longlong(membuff_t *mb, int64_t value);

@ -980,7 +980,9 @@ int luaV_execute (lua_State *L) {
k = cl->p->k; /* local reference to function's constant table */
base = ci->u.l.base; /* local copy of function's base */
/* main loop of interpreter */
#if RAVI_BYTECODE_PROFILING_ENABLED
OpCode prevop = -1;
#endif
for (;;) {
Instruction i;
OpCode op;

@ -43,28 +43,6 @@ enum errorcode {
Error_array_out_of_bounds,
};
static const char *errortext[] = {
"integer expected",
"number expected",
"integer[] expected",
"number[] expected",
"table expected",
"upvalue of integer type, cannot be set to non integer value",
"upvalue of number type, cannot be set to non number value",
"upvalue of integer[] type, cannot be set to non integer[] value",
"upvalue of number[] type, cannot be set to non number[] value",
"upvalue of table type, cannot be set to non table value",
"'for' limit must be a number",
"'for' step must be a number",
"'for' initial value must be a number",
"array out of bounds",
NULL };
static void raise_error(lua_State *L, int errorcode) {
assert(errorcode >= 0 && errorcode <= Error_upval_needs_table);
luaG_runerror(L, errortext[errorcode]);
}
static const char Lua_header[] = ""
"#define NULL ((void *)0)\n"
"typedef struct lua_State lua_State;\n"
@ -714,8 +692,6 @@ struct function {
membuff_t body;
};
static int add_local_var(struct function *fn) { return fn->var++; }
// Identify Ravi bytecode instructions that are jump
// targets - we need this so that when generating code
// we can emit labels for gotos
@ -771,6 +747,8 @@ static void emit_gettable_ai(struct function *fn, int A, int B,
int C, bool omitArrayGetRangeCheck,
int pc)
{
(void)omitArrayGetRangeCheck;
(void)pc;
emit_reg(fn, "ra", A);
emit_reg(fn, "rb", B);
emit_reg_or_k(fn, "rc", C);
@ -789,6 +767,8 @@ static void emit_gettable_af(struct function *fn, int A, int B,
int C, bool omitArrayGetRangeCheck,
int pc)
{
(void)omitArrayGetRangeCheck;
(void)pc;
emit_reg(fn, "ra", A);
emit_reg(fn, "rb", B);
emit_reg_or_k(fn, "rc", C);
@ -806,6 +786,8 @@ static void emit_gettable_af(struct function *fn, int A, int B,
static void emit_settable_aii(struct function *fn, int A, int B,
int C, bool known_int, int pc)
{
(void)pc;
(void)known_int;
emit_reg(fn, "ra", A);
emit_reg_or_k(fn, "rb", B);
emit_reg_or_k(fn, "rc", C);
@ -843,6 +825,8 @@ static void emit_settable_ai(struct function *fn, int A, int B,
static void emit_settable_aff(struct function *fn, int A, int B,
int C, bool known_int, int pc)
{
(void)pc;
(void)known_int;
emit_reg(fn, "ra", A);
emit_reg_or_k(fn, "rb", B);
emit_reg_or_k(fn, "rc", C);
@ -880,6 +864,7 @@ static void emit_settable_af(struct function *fn, int A, int B,
static void emit_comparison(struct function *fn, int A, int B, int C, int j,
int jA, const char *compfunc, OpCode opCode,
int pc) {
(void)pc;
const char *oper = "==";
switch (opCode) {
case OP_RAVI_LT_II: oper = "<"; goto Lemitint;
@ -969,6 +954,7 @@ static void emit_jump_label(struct function *fn, int pc) {
static void emit_op_loadk(struct function *fn, int A, int Bx, int pc) {
emit_reg(fn, "ra", A);
(void)pc;
TValue *Konst = &fn->p->k[Bx];
switch (Konst->tt_) {
case LUA_TNUMINT:
@ -990,9 +976,9 @@ static void emit_op_loadk(struct function *fn, int A, int Bx, int pc) {
}
static void emit_op_return(struct function *fn, int A, int B, int pc) {
(void)pc;
emit_reg(fn, "ra", A);
membuff_add_string(&fn->body, "if (cl->p->sizep > 0) luaF_close(L, base);\n");
int var = add_local_var(fn);
membuff_add_fstring(&fn->body,
"result = (%d != 0 ? %d - 1 : cast_int(L->top - ra));\n",
B, B);
@ -1000,18 +986,21 @@ static void emit_op_return(struct function *fn, int A, int B, int pc) {
}
static void emit_op_move(struct function *fn, int A, int B, int pc) {
(void)pc;
emit_reg(fn, "ra", A);
membuff_add_fstring(&fn->body, "rb = R(%d);\n", B);
membuff_add_fstring(&fn->body, "setobj2s(L, ra, rb);\n");
}
static void emit_op_loadnil(struct function *fn, int A, int B, int pc) {
(void)pc;
int b = B;
emit_reg(fn, "ra", A);
do { membuff_add_fstring(&fn->body, "setnilvalue(ra++);\n"); } while (b--);
}
static void emit_op_jmp(struct function *fn, int A, int sBx, int pc) {
(void)pc;
if (A > 0) {
membuff_add_fstring(&fn->body, "ra = R(%d);\n", A - 1);
membuff_add_string(&fn->body, "luaF_close(L, ra);\n");
@ -1021,6 +1010,7 @@ static void emit_op_jmp(struct function *fn, int A, int sBx, int pc) {
static void emit_op_loadbool(struct function *fn, int A, int B, int C, int j,
int pc) {
(void)pc;
membuff_add_fstring(&fn->body, "ra = R(%d);\n", A);
membuff_add_fstring(&fn->body, "setbvalue(ra, %d);\n", B);
@ -1029,6 +1019,8 @@ static void emit_op_loadbool(struct function *fn, int A, int B, int C, int j,
static void emit_op_test(struct function *fn, int A, int B, int C, int j,
int jA, int pc) {
(void)pc;
(void)B;
emit_reg(fn, "ra", A);
if (C) { membuff_add_string(&fn->body, "result = l_isfalse(ra);\n"); }
else {
@ -1045,6 +1037,7 @@ static void emit_op_test(struct function *fn, int A, int B, int C, int j,
static void emit_op_testset(struct function *fn, int A, int B, int C, int j,
int jA, int pc) {
(void)pc;
membuff_add_fstring(&fn->body, "rb = R(%d);\n", B);
if (C) { membuff_add_string(&fn->body, "result = l_isfalse(rb);\n"); }
else {
@ -1063,6 +1056,7 @@ static void emit_op_testset(struct function *fn, int A, int B, int C, int j,
static void emit_op_iforloop(struct function *fn, int A, int pc, int step_one,
int pc1) {
(void)pc1;
if (!step_one) { membuff_add_fstring(&fn->body, "i_%d += step_%d;\n", A, A); }
else {
membuff_add_fstring(&fn->body, "i_%d += 1;\n", A);
@ -1075,6 +1069,7 @@ static void emit_op_iforloop(struct function *fn, int A, int pc, int step_one,
static void emit_op_iforprep(struct function *fn, int A, int pc, int step_one,
int pc1) {
(void)pc1;
if (!fn->locals[A]) {
fn->locals[A] =
1; // Lua can reuse the same forloop vars if loop isn't nested
@ -1150,6 +1145,7 @@ static void initfn(struct function *fn, struct lua_State *L, struct Proto *p, co
// so we need to take care of the behaviour differences between
// OP_CALL and external calls
static void emit_op_call(struct function *fn, int A, int B, int C, int pc) {
(void)pc;
int nresults = C - 1;
if (B != 0) { membuff_add_fstring(&fn->body, "L->top = R(%d);\n", A + B); }
emit_reg(fn, "ra", A);
@ -1168,6 +1164,7 @@ static void emit_op_call(struct function *fn, int A, int B, int C, int pc) {
// R(A) := UpValue[B][RK(C)]
static void emit_op_gettabup(struct function *fn, int A, int B, int C, int pc) {
(void)pc;
emit_reg(fn, "ra", A);
emit_reg_or_k(fn, "rc", C);
membuff_add_fstring(&fn->body,
@ -1177,6 +1174,7 @@ static void emit_op_gettabup(struct function *fn, int A, int B, int C, int pc) {
// R(A) := UpValue[B][RK(C)]
static void emit_op_settabup(struct function *fn, int A, int B, int C, int pc) {
(void)pc;
emit_reg_or_k(fn, "rb", B);
emit_reg_or_k(fn, "rc", C);
membuff_add_fstring(&fn->body,
@ -1186,6 +1184,7 @@ static void emit_op_settabup(struct function *fn, int A, int B, int C, int pc) {
// R(A) := R(B)[RK(C)]
static void emit_op_gettable(struct function *fn, int A, int B, int C, int pc) {
(void)pc;
emit_reg(fn, "ra", A);
emit_reg(fn, "rb", B);
emit_reg_or_k(fn, "rc", C);
@ -1194,6 +1193,7 @@ static void emit_op_gettable(struct function *fn, int A, int B, int C, int pc) {
}
static void emit_op_self(struct function *fn, int A, int B, int C, int pc) {
(void)pc;
emit_reg(fn, "ra", A);
emit_reg(fn, "rb", B);
membuff_add_string(&fn->body, "setobjs2s(L, ra + 1, rb);\n");
@ -1203,6 +1203,7 @@ static void emit_op_self(struct function *fn, int A, int B, int C, int pc) {
}
static void emit_op_len(struct function *fn, int A, int B, int pc) {
(void)pc;
emit_reg(fn, "ra", A);
emit_reg(fn, "rb", B);
membuff_add_string(&fn->body, "luaV_objlen(L, ra, rb);\n");
@ -1211,6 +1212,7 @@ static void emit_op_len(struct function *fn, int A, int B, int pc) {
// R(A)[RK(B)] := RK(C)
static void emit_op_settable(struct function *fn, int A, int B, int C, int pc) {
(void)pc;
emit_reg(fn, "ra", A);
emit_reg_or_k(fn, "rb", B);
emit_reg_or_k(fn, "rc", C);
@ -1220,22 +1222,26 @@ static void emit_op_settable(struct function *fn, int A, int B, int C, int pc) {
// R(A) := UpValue[B]
static void emit_op_getupval(struct function *fn, int A, int B, int pc) {
(void)pc;
emit_reg(fn, "ra", A);
membuff_add_fstring(&fn->body, "setobjs2s(L, ra, cl->upvals[%d]->v);\n", B);
}
static void emit_op_newtable(struct function *fn, int A, int B, int C, int pc) {
(void)pc;
emit_reg(fn, "ra", A);
membuff_add_fstring(&fn->body, "raviV_op_newtable(L, ci, ra, %d, %d);\n", B,
C);
}
static void emit_op_newarrayint(struct function *fn, int A, int pc) {
(void)pc;
emit_reg(fn, "ra", A);
membuff_add_string(&fn->body, "raviV_op_newarrayint(L, ci, ra);\n");
}
static void emit_op_newarrayfloat(struct function *fn, int A, int pc) {
(void)pc;
emit_reg(fn, "ra", A);
membuff_add_string(&fn->body, "raviV_op_newarrayfloat(L, ci, ra);\n");
}
@ -1243,6 +1249,7 @@ static void emit_op_newarrayfloat(struct function *fn, int A, int pc) {
// Default implementation for binary ops
static void emit_binary_op(struct function *fn, int A, int B, int C, OpCode op,
int pc) {
(void)pc;
emit_reg(fn, "ra", A);
emit_reg_or_k(fn, "rb", B);
emit_reg_or_k(fn, "rc", C);
@ -1253,6 +1260,7 @@ static void emit_binary_op(struct function *fn, int A, int B, int C, OpCode op,
void emit_ff_op(struct function *fn, int A, int B, int C, int pc,
const char *op) {
(void)pc;
emit_reg(fn, "ra", A);
emit_reg_or_k(fn, "rb", B);
emit_reg_or_k(fn, "rc", C);
@ -1262,6 +1270,7 @@ void emit_ff_op(struct function *fn, int A, int B, int C, int pc,
static void emit_fi_op(struct function *fn, int A, int B, int C, int pc,
const char *op) {
(void)pc;
emit_reg(fn, "ra", A);
emit_reg_or_k(fn, "rb", B);
emit_reg_or_k(fn, "rc", C);
@ -1271,6 +1280,7 @@ static void emit_fi_op(struct function *fn, int A, int B, int C, int pc,
static void emit_if_op(struct function *fn, int A, int B, int C, int pc,
const char *op) {
(void)pc;
emit_reg(fn, "ra", A);
emit_reg_or_k(fn, "rb", B);
emit_reg_or_k(fn, "rc", C);
@ -1280,6 +1290,7 @@ static void emit_if_op(struct function *fn, int A, int B, int C, int pc,
static void emit_ii_op(struct function *fn, int A, int B, int C, int pc,
const char *op) {
(void)pc;
emit_reg(fn, "ra", A);
emit_reg_or_k(fn, "rb", B);
emit_reg_or_k(fn, "rc", C);
@ -1288,6 +1299,7 @@ static void emit_ii_op(struct function *fn, int A, int B, int C, int pc,
}
static void emit_op_divii(struct function *fn, int A, int B, int C, int pc) {
(void)pc;
emit_reg(fn, "ra", A);
emit_reg_or_k(fn, "rb", B);
emit_reg_or_k(fn, "rc", C);
@ -1297,15 +1309,18 @@ static void emit_op_divii(struct function *fn, int A, int B, int C, int pc) {
}
static void emit_op_loadfz(struct function *fn, int A, int pc) {
(void)pc;
emit_reg(fn, "ra", A);
membuff_add_string(&fn->body, "setfltvalue(ra, 0.0);\n");
}
static void emit_op_loadiz(struct function *fn, int A, int pc) {
(void)pc;
emit_reg(fn, "ra", A);
membuff_add_string(&fn->body, "setivalue(ra, 0);\n");
}
static void emit_op_movei(struct function *fn, int A, int B, int pc) {
(void)pc;
emit_reg(fn, "ra", A);
emit_reg(fn, "rb", B);
membuff_add_string(&fn->body, "i = 0;\n");
@ -1319,6 +1334,7 @@ static void emit_op_movei(struct function *fn, int A, int B, int pc) {
}
static void emit_op_movef(struct function *fn, int A, int B, int pc) {
(void)pc;
emit_reg(fn, "ra", A);
emit_reg(fn, "rb", B);
membuff_add_string(&fn->body, "n = 0.0;\n");
@ -1331,6 +1347,7 @@ static void emit_op_movef(struct function *fn, int A, int B, int pc) {
}
static void emit_op_moveai(struct function *fn, int A, int B, int pc) {
(void)pc;
emit_reg(fn, "ra", A);
emit_reg(fn, "rb", B);
membuff_add_string(&fn->body,
@ -1343,6 +1360,7 @@ static void emit_op_moveai(struct function *fn, int A, int B, int pc) {
}
static void emit_op_moveaf(struct function *fn, int A, int B, int pc) {
(void)pc;
emit_reg(fn, "ra", A);
emit_reg(fn, "rb", B);
membuff_add_string(&fn->body,
@ -1355,6 +1373,7 @@ static void emit_op_moveaf(struct function *fn, int A, int B, int pc) {
}
static void emit_op_movetab(struct function *fn, int A, int B, int pc) {
(void)pc;
emit_reg(fn, "ra", A);
emit_reg(fn, "rb", B);
membuff_add_string(&fn->body,
@ -1366,6 +1385,7 @@ static void emit_op_movetab(struct function *fn, int A, int B, int pc) {
}
static void emit_op_toint(struct function *fn, int A, int pc) {
(void)pc;
emit_reg(fn, "ra", A);
membuff_add_string(&fn->body, "i = 0;\n");
membuff_add_string(&fn->body,
@ -1378,6 +1398,7 @@ static void emit_op_toint(struct function *fn, int A, int pc) {
}
static void emit_op_toflt(struct function *fn, int A, int pc) {
(void)pc;
emit_reg(fn, "ra", A);
membuff_add_string(&fn->body, "n = 0.0;\n");
membuff_add_string(&fn->body,
@ -1389,6 +1410,7 @@ static void emit_op_toflt(struct function *fn, int A, int pc) {
}
static void emit_op_toai(struct function *fn, int A, int pc) {
(void)pc;
emit_reg(fn, "ra", A);
membuff_add_string(&fn->body, "if (!ttisiarray(ra)) {\n");
membuff_add_fstring(&fn->body, " error_code = %d;\n",
@ -1398,6 +1420,7 @@ static void emit_op_toai(struct function *fn, int A, int pc) {
}
static void emit_op_toaf(struct function *fn, int A, int pc) {
(void)pc;
emit_reg(fn, "ra", A);
membuff_add_string(&fn->body, "if (!ttisfarray(ra)) {\n");
membuff_add_fstring(&fn->body, " error_code = %d;\n",
@ -1407,6 +1430,7 @@ static void emit_op_toaf(struct function *fn, int A, int pc) {
}
static void emit_op_totab(struct function *fn, int A, int pc) {
(void)pc;
emit_reg(fn, "ra", A);
membuff_add_string(&fn->body, "if (!ttisLtable(ra)) {\n");
membuff_add_fstring(&fn->body, " error_code = %d;\n", Error_table_expected);
@ -1415,26 +1439,31 @@ static void emit_op_totab(struct function *fn, int A, int pc) {
}
static void emit_op_setlist(struct function *fn, int A, int B, int C, int pc) {
(void)pc;
emit_reg(fn, "ra", A);
membuff_add_fstring(&fn->body, "raviV_op_setlist(L, ci, ra, %d, %d);\n", B,
C);
}
static void emit_op_concat(struct function *fn, int A, int B, int C, int pc) {
(void)pc;
membuff_add_fstring(&fn->body, "raviV_op_concat(L, ci, %d, %d, %d);\n", A, B,
C);
}
static void emit_op_closure(struct function *fn, int A, int Bx, int pc) {
(void)pc;
membuff_add_fstring(&fn->body, "raviV_op_closure(L, ci, cl, %d, %d);\n", A,
Bx);
}
static void emit_op_vararg(struct function *fn, int A, int B, int pc) {
(void)pc;
membuff_add_fstring(&fn->body, "raviV_op_vararg(L, ci, cl, %d, %d);\n", A, B);
}
static void emit_op_not(struct function *fn, int A, int B, int pc) {
(void)pc;
emit_reg(fn, "ra", A);
emit_reg(fn, "rb", B);
membuff_add_string(&fn->body, "result = l_isfalse(rb);\n");
@ -1442,12 +1471,14 @@ static void emit_op_not(struct function *fn, int A, int B, int pc) {
}
static void emit_op_setupval(struct function *fn, int A, int B, int pc, const char *suffix) {
(void)pc;
emit_reg(fn, "ra", A);
membuff_add_fstring(&fn->body, "raviV_op_setupval%s(L, cl, ra, %d);\n", suffix, B);
}
static void emit_op_forprep(struct function *fn, int A, int pc,
int pc1)
{
(void)pc1;
if (!fn->locals[A]) {
fn->locals[A] =
1; // Lua can reuse the same forloop vars if loop isn't nested
@ -1488,6 +1519,7 @@ static void emit_op_forprep(struct function *fn, int A, int pc,
static void emit_op_forloop(struct function *fn, int A, int pc,
int pc1) {
(void)pc1;
membuff_add_fstring(&fn->body, "if (intloop_%d) {\n", A);
membuff_add_fstring(&fn->body, " init_%d += step_%d;\n", A, A);
membuff_add_fstring(&fn->body, " if ((0 < step_%d) ? (init_%d <= limit_%d) : (limit_%d <= init_%d)) {\n", A, A, A, A, A);
@ -1504,6 +1536,8 @@ static void emit_op_forloop(struct function *fn, int A, int pc,
static void emit_op_tforcall(struct function *fn, int A, int B, int C,
int j, int jA, int pc) {
(void)B;
(void)pc;
emit_reg(fn, "ra", A);
membuff_add_string(&fn->body, "rb = ra + 3 + 2;\n"); /*rb = cb*/
membuff_add_string(&fn->body, "rc = ra + 2;\n"); /*rb = cb*/
@ -1527,6 +1561,7 @@ static void emit_op_tforcall(struct function *fn, int A, int B, int C,
static void emit_op_tforloop(struct function *fn, int A, int j,
int pc) {
(void)pc;
emit_reg(fn, "ra", A);
membuff_add_string(&fn->body, "if (!ttisnil(ra + 1)) {\n");
membuff_add_string(&fn->body, " rb = ra + 1;\n");
@ -1545,7 +1580,7 @@ static void cleanup(struct function *fn) {
// Compile a Lua function
// Returns true if compilation was successful
bool raviJ_codegen(struct lua_State *L, struct Proto *p,
ravi_compile_options_t *options, const char *fname, membuff_t *buf) {
struct ravi_compile_options_t *options, const char *fname, membuff_t *buf) {
if (options->codegen_type == RAVI_CODEGEN_HEADER_ONLY) {
membuff_rewindpos(buf);

@ -30,7 +30,7 @@ namespace ravi {
// Code size priority so go via function calls
void RaviCodeGenerator::emit_ARITH_calls(RaviFunctionDef *def, int A, int B,
int C, OpCode op, TMS tms, int pc) {
bool traced = emit_debug_trace(def, op, pc);
emit_debug_trace(def, op, pc);
emit_load_base(def);
llvm::Value *ra = emit_gep_register(def, A);
llvm::Value *rb = emit_gep_register_or_constant(def, B);

@ -779,7 +779,7 @@ static int collect_args(lua_State *L, int tabindex, char *argv[], int maxargs,
}
static int module_compile_C(lua_State *L) {
ModuleHolder *mh = check_LLVM_module(L, 1);
check_LLVM_module(L, 1);
const char *codebuffer = NULL; // luaL_checkstring(L, 2);
char *argv[MAX_ARGS + 1] = {NULL};
int argc = 0;

Loading…
Cancel
Save