issue #110 add support for omitting range checks on array read access for OMR JIT

pull/167/head
Dibyendu Majumdar 6 years ago
parent 8830789362
commit 405fc20f91

@ -69,7 +69,7 @@ local function fannkuch(n: integer)
end
local n = tonumber(arg and arg[1]) or 11
ravi.compile(fannkuch)
ravi.compile(fannkuch, {omitArrayGetRangeCheck=1})
local t1 = os.clock()
local sum, flips = fannkuch(n)
local t2 = os.clock()

@ -45,7 +45,7 @@ local function domandel(pfunc)
end
if ravi.jit() then
assert(ravi.compile(domandel))
assert(ravi.compile(domandel, {omitArrayGetRangeCheck=1}))
end
t1 = os.clock()

@ -707,6 +707,7 @@ struct function {
unsigned char *locals;
membuff_t prologue;
membuff_t body;
struct ravi_compile_options_t *options;
};
// Identify Ravi bytecode instructions that are jump
@ -761,7 +762,6 @@ static void emit_reg_or_k(struct function *fn, const char *name, int regnum) {
}
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);
@ -769,20 +769,21 @@ static void emit_gettable_ai(struct function *fn, int A, int B, int C, bool omit
membuff_add_string(&fn->body, "ukey = (lua_Unsigned)(ivalue(rc));\n");
membuff_add_string(&fn->body, "t = hvalue(rb);");
membuff_add_string(&fn->body, "iptr = (lua_Integer *)t->ravi_array.data;\n");
membuff_add_string(&fn->body, "if (ukey < (lua_Unsigned)(t->ravi_array.len)) {\n");
if (!omitArrayGetRangeCheck) { membuff_add_string(&fn->body, "if (ukey < (lua_Unsigned)(t->ravi_array.len)) {\n"); }
membuff_add_string(&fn->body, " setivalue(ra, iptr[ukey]);\n");
membuff_add_string(&fn->body, "} else {\n");
if (!omitArrayGetRangeCheck) {
membuff_add_string(&fn->body, "} else {\n");
#if GOTO_ON_ERROR
membuff_add_fstring(&fn->body, " error_code = %d;\n", Error_array_out_of_bounds);
membuff_add_string(&fn->body, " goto Lraise_error;\n");
membuff_add_fstring(&fn->body, " error_code = %d;\n", Error_array_out_of_bounds);
membuff_add_string(&fn->body, " goto Lraise_error;\n");
#else
membuff_add_fstring(&fn->body, " raise_error(L, %d);\n", Error_array_out_of_bounds);
membuff_add_fstring(&fn->body, " raise_error(L, %d);\n", Error_array_out_of_bounds);
#endif
membuff_add_string(&fn->body, "}\n");
membuff_add_string(&fn->body, "}\n");
}
}
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);
@ -790,16 +791,18 @@ static void emit_gettable_af(struct function *fn, int A, int B, int C, bool omit
membuff_add_string(&fn->body, "ukey = (lua_Unsigned)(ivalue(rc));\n");
membuff_add_string(&fn->body, "t = hvalue(rb);");
membuff_add_string(&fn->body, "nptr = (lua_Number *)t->ravi_array.data;\n");
membuff_add_string(&fn->body, "if (ukey < (lua_Unsigned)(t->ravi_array.len)) {\n");
if (!omitArrayGetRangeCheck) { membuff_add_string(&fn->body, "if (ukey < (lua_Unsigned)(t->ravi_array.len)) {\n"); }
membuff_add_string(&fn->body, " setfltvalue(ra, nptr[ukey]);\n");
membuff_add_string(&fn->body, "} else {\n");
if (!omitArrayGetRangeCheck) {
membuff_add_string(&fn->body, "} else {\n");
#if GOTO_ON_ERROR
membuff_add_fstring(&fn->body, " error_code = %d;\n", Error_array_out_of_bounds);
membuff_add_string(&fn->body, " goto Lraise_error;\n");
membuff_add_fstring(&fn->body, " error_code = %d;\n", Error_array_out_of_bounds);
membuff_add_string(&fn->body, " goto Lraise_error;\n");
#else
membuff_add_fstring(&fn->body, " raise_error(L, %d);\n", Error_array_out_of_bounds);
membuff_add_fstring(&fn->body, " raise_error(L, %d);\n", Error_array_out_of_bounds);
#endif
membuff_add_string(&fn->body, "}\n");
membuff_add_string(&fn->body, "}\n");
}
}
static void emit_settable_aii(struct function *fn, int A, int B, int C, bool known_int, int pc) {
@ -1085,10 +1088,11 @@ static void emit_endf(struct function *fn) {
membuff_add_string(&fn->body, "}\n");
}
static void initfn(struct function *fn, struct lua_State *L, struct Proto *p, const char *fname, bool body_only) {
static void initfn(struct function *fn, struct lua_State *L, struct Proto *p, const char *fname, struct ravi_compile_options_t *options) {
fn->L = L;
fn->p = p;
fn->var = 0;
fn->options = options;
snprintf(fn->fname, sizeof fn->fname, "%s", fname);
fn->jmps = calloc(p->sizecode, sizeof fn->jmps[0]);
if (p->sizelocvars)
@ -1097,7 +1101,8 @@ static void initfn(struct function *fn, struct lua_State *L, struct Proto *p, co
fn->locals = NULL;
membuff_init(&fn->prologue, strlen(Lua_header) + 4096);
membuff_init(&fn->body, 4096);
if (!body_only) membuff_add_string(&fn->prologue, Lua_header);
if (!(options->codegen_type == RAVI_CODEGEN_FUNCTION_ONLY))
membuff_add_string(&fn->prologue, Lua_header);
membuff_add_fstring(&fn->prologue, "extern int %s(lua_State *L);\n", fn->fname);
membuff_add_fstring(&fn->prologue, "int %s(lua_State *L) {\n", fn->fname);
membuff_add_string(&fn->prologue, "int error_code = 0;\n");
@ -1648,7 +1653,7 @@ bool raviJ_codegen(struct lua_State *L, struct Proto *p,
return false;
struct function fn;
initfn(&fn, L, p, fname, options->codegen_type == RAVI_CODEGEN_FUNCTION_ONLY);
initfn(&fn, L, p, fname, options);
scan_jump_targets(&fn);
const Instruction *code = p->code;
@ -1799,12 +1804,12 @@ bool raviJ_codegen(struct lua_State *L, struct Proto *p,
case OP_RAVI_GETTABLE_AI: {
int B = GETARG_B(i);
int C = GETARG_C(i);
emit_gettable_ai(&fn, A, B, C, false, pc);
emit_gettable_ai(&fn, A, B, C, options->omit_array_get_range_check, pc);
} break;
case OP_RAVI_GETTABLE_AF: {
int B = GETARG_B(i);
int C = GETARG_C(i);
emit_gettable_af(&fn, A, B, C, false, pc);
emit_gettable_af(&fn, A, B, C, options->omit_array_get_range_check, pc);
} break;
case OP_RAVI_SETTABLE_SK:
case OP_RAVI_SETTABLE_S:

Loading…
Cancel
Save