gccjit-ravi534
Dibyendu Majumdar 7 years ago
parent 389663e165
commit b67f492c04

@ -105,12 +105,6 @@ struct ravi_compile_options_t {
/* Should range check be omitted when compiling array access */
int omit_array_get_range_check;
/* Should the compiler dump generated code ? */
int dump_level;
/* Should the compiler validate the generated code ? */
int verification_level;
enum ravi_codegen_type codegen_type;
};

@ -425,21 +425,27 @@ class RaviJITState {
LuaLLVMTypes *types_;
// Should we auto compile what we can?
bool auto_;
int auto_ : 1;
// Is JIT enabled
bool enabled_;
int enabled_ : 1;
// Optimizer level (LLVM PassManagerBuilder)
int opt_level_;
int opt_level_ : 2;
// Size level (LLVM PassManagerBuilder)
int size_level_;
int size_level_ : 2;
// Verbosity
// 1 - Dump IR
// 2 - Dump assembly
int verbosity_;
int verbosity_ : 3;
// enable calls to luaG_traceexec() at every bytecode
// instruction; this is expensive!
int tracehook_enabled_ : 1;
// Enable extra validation such as IR verification
// May slow down compilation
int validation_ : 1;
// min code size for compilation
int min_code_size_;
@ -447,13 +453,6 @@ class RaviJITState {
// min execution count for compilation
int min_exec_count_;
// gc step size; defaults to 200
int gc_step_;
// enable calls to luaG_traceexec() at every bytecode
// instruction; this is expensive!
bool tracehook_enabled_;
// Count of modules allocated
// Used to debug module deallocation
size_t allocated_modules_;
@ -490,7 +489,7 @@ class RaviJITState {
}
int get_verbosity() const { return verbosity_; }
void set_verbosity(int value) {
if (value >= 0) verbosity_ = value;
if (value >= 0 && value <= 3) verbosity_ = value;
}
int get_mincodesize() const { return min_code_size_; }
void set_mincodesize(int value) {
@ -500,8 +499,8 @@ class RaviJITState {
void set_minexeccount(int value) {
min_exec_count_ = value > 0 ? value : min_exec_count_;
}
int get_gcstep() const { return gc_step_; }
void set_gcstep(int value) { gc_step_ = value > 0 ? value : gc_step_; }
int get_validation() const { return validation_; }
void set_validation(bool value) { validation_ = value; }
bool is_tracehook_enabled() const { return tracehook_enabled_; }
void set_tracehook_enabled(bool value) { tracehook_enabled_ = value; }
void incr_allocated_modules() { allocated_modules_++; }

@ -53,6 +53,7 @@
struct ravi_State {
NJXContextRef jit;
unsigned long long id; // counter to generate function names
int verbosity;
};
#ifdef __cplusplus

@ -76,9 +76,9 @@ int raviV_getmincodesize(struct lua_State *L);
void raviV_setminexeccount(struct lua_State *L, int minexecccount);
int raviV_getminexeccount(struct lua_State *L);
/* Enable GC Collection at every JIT compile */
void raviV_setgcstep(struct lua_State *L, int stepsize);
int raviV_getgcstep(struct lua_State *L);
/* Enable IR / codegen validations */
void raviV_setvalidation(struct lua_State *L, int enabled);
int raviV_getvalidation(struct lua_State *L);
/* Enable or disable trace hook */
void raviV_settraceenabled(struct lua_State *L, int enabled);

@ -468,7 +468,6 @@ int luaD_precall (lua_State *L, StkId func, int nresults, int op_call) {
/* not compiled */
ravi_compile_options_t options;
memset(&options, 0, sizeof options);
options.verification_level = 1;
raviV_compile(L, p, &options);
}
if (L == G(L)->mainthread && p->ravi_jit.jit_function) {

@ -232,11 +232,11 @@ int raviV_getsizelevel(lua_State *L) {
return 0;
}
void raviV_setgcstep(lua_State *L, int value) {
void raviV_setvalidation(lua_State *L, int value) {
(void)L;
(void)value;
}
int raviV_getgcstep(lua_State *L) {
int raviV_getvalidation(lua_State *L) {
(void)L;
return 0;
}

@ -1297,7 +1297,7 @@ bool RaviCodeGenerator::compile(lua_State *L, Proto *p,
ravi_compile_options_t *options) {
if (p->ravi_jit.jit_status == RAVI_JIT_COMPILED) return true;
bool doVerify = options ? options->verification_level != 0 : 0;
bool doVerify = module->owner()->get_validation() != 0;
bool omitArrayGetRangeCheck =
options ? options->omit_array_get_range_check != 0 : 0;
@ -1312,22 +1312,6 @@ bool RaviCodeGenerator::compile(lua_State *L, Proto *p,
RaviFunctionDef definition = {0};
RaviFunctionDef *def = &definition;
// The Lua GC doesn't know about memory allocated by the JIT
// compiler; this means that if lots of functions are being compiled
// such as in the test cases, then memory usage can grow very large
// as the GC is blissfully unaware of the actual memory in use
// To workaround this issue we provide an option that can be used to
// force a GC after every n compilations where n is supplied
// by the gcstep parameter; this is not ideal as it kills performance
// but appears to work for the test cases
// A better solution is needed
int gcstep = this->jitState_->get_gcstep();
if (gcstep > 0 && (id_ % gcstep) == 0) {
lua_unlock(L);
lua_gc(L, LUA_GCCOLLECT, 0);
lua_lock(L);
}
auto f = create_function(p, module, builder, def);
if (!f) {
p->ravi_jit.jit_status = RAVI_JIT_CANT_COMPILE; // can't compile
@ -1917,11 +1901,20 @@ bool RaviCodeGenerator::compile(lua_State *L, Proto *p,
}
}
}
if (doVerify && llvm::verifyFunction(*f->function(), &llvm::errs())) {
if (doVerify &&
llvm::verifyFunction(*f->function(), &llvm::errs())) {
f->dump();
fprintf(stderr, "LLVM Code Verification failed\n");
exit(1);
}
// The Lua GC doesn't know about memory allocated by the JIT
// compiler; this means that if lots of functions are being compiled
// such as in the test cases, then memory usage can grow very large
// as the GC is blissfully unaware of the actual memory in use
// To workaround this issue we tell the GC that we increased
// memory usage by approximately n kbytes where n is the
// number of bytecodes in the function compiled
lua_gc(L, LUA_GCSTEP, n); // nKbytes?
ravi::RaviJITFunction *llvm_func = f.release();
p->ravi_jit.jit_data = reinterpret_cast<void *>(llvm_func);
p->ravi_jit.jit_function = nullptr;

@ -122,10 +122,10 @@ RaviJITState::RaviJITState()
opt_level_(2),
size_level_(0),
verbosity_(0),
tracehook_enabled_(false),
validation_(false),
min_code_size_(150),
min_exec_count_(50),
gc_step_(300),
tracehook_enabled_(false),
allocated_modules_(0) {
// LLVM needs to be initialized else
// ExecutionEngine cannot be created
@ -203,6 +203,10 @@ std::shared_ptr<llvm::Module> RaviJITState::optimizeModule(
TM->Options.PrintMachineCode = 1;
else
TM->Options.PrintMachineCode = 0;
if (get_optlevel() == 0)
TM->Options.EnableFastISel = 1;
else
TM->Options.EnableFastISel = 0;
// We use the PassManagerBuilder to setup optimization
// passes - the PassManagerBuilder allows easy configuration of
@ -639,7 +643,7 @@ void RaviJITModule::dump() {
// Dumps the machine code
// Will execute the passes as required by currently set
// optimzation level; this may or may not match the actual
// optimization level; this may or may not match the actual
// JITed code which would have used the optimzation level set at the
// time of compilation
void RaviJITModule::dumpAssembly() { runpasses(true); }
@ -708,7 +712,7 @@ int raviV_compile(struct lua_State *L, struct Proto *p,
auto module = std::make_shared<ravi::RaviJITModule>(G->ravi_state->jit);
if (G->ravi_state->code_generator->compile(L, p, module, options)) {
module->runpasses();
module->finalize(options ? options->dump_level != 0 : 0);
module->finalize(G->ravi_state->jit->get_verbosity() == 3);
}
}
return p->ravi_jit.jit_function != nullptr;
@ -728,7 +732,7 @@ int raviV_compile_n(struct lua_State *L, struct Proto *p[], int n,
}
if (count) {
module->runpasses();
module->finalize(options ? options->dump_level != 0 : 0);
module->finalize(G->ravi_state->jit->get_verbosity() == 3);
}
return count > 0;
}
@ -841,15 +845,15 @@ int raviV_getverbosity(lua_State *L) {
return G->ravi_state->jit->get_verbosity();
}
void raviV_setgcstep(lua_State *L, int value) {
void raviV_setvalidation(lua_State *L, int value) {
global_State *G = G(L);
if (!G->ravi_state) return;
G->ravi_state->jit->set_gcstep(value);
G->ravi_state->jit->set_validation(value != 0);
}
int raviV_getgcstep(lua_State *L) {
int raviV_getvalidation(lua_State *L) {
global_State *G = G(L);
if (!G->ravi_state) return 0;
return G->ravi_state->jit->get_gcstep();
return G->ravi_state->jit->get_validation();
}
// Turn on/off the JIT compiler

@ -284,11 +284,11 @@ int raviV_getsizelevel(lua_State *L) {
return 0;
}
void raviV_setgcstep(lua_State *L, int value) {
void raviV_setvalidation(lua_State *L, int value) {
(void)L;
(void)value;
}
int raviV_getgcstep(lua_State *L) {
int raviV_getvalidation(lua_State *L) {
(void)L;
return 0;
}

@ -93,16 +93,11 @@ static int ravi_compile_n(lua_State *L) {
}
ravi_compile_options_t options = {0};
options.manual_request = 1;
options.verification_level = 1;
if (lua_istable(L, 2)) {
lua_Integer do_dump, do_verify, omit_arrayget_rangecheck;
l_table_get_integer(L, 2, "dump", &do_dump, 0);
l_table_get_integer(L, 2, "verify", &do_verify, 1);
l_table_get_integer(L, 2, "omitArrayGetRangeCheck",
&omit_arrayget_rangecheck, 0);
options.omit_array_get_range_check = (int)omit_arrayget_rangecheck;
options.dump_level = (int)do_dump;
options.verification_level = (int)do_verify;
}
int result = 0;
if (n > 0) { result = raviV_compile_n(L, functions, n, &options); }
@ -197,14 +192,14 @@ static int ravi_sizelevel(lua_State *L) {
}
// Set GC step when JIT compiling
static int ravi_gcstep(lua_State *L) {
static int ravi_validation(lua_State *L) {
int n = lua_gettop(L);
int oldvalue = raviV_getgcstep(L);
int oldvalue = raviV_getvalidation(L);
if (n == 1) {
int value = lua_tointeger(L, 1);
raviV_setgcstep(L, value);
raviV_setvalidation(L, value);
}
lua_pushinteger(L, oldvalue);
lua_pushboolean(L, oldvalue);
return 1;
}
@ -250,7 +245,7 @@ static const luaL_Reg ravilib[] = {{"iscompiled", ravi_is_compiled},
{"optlevel", ravi_optlevel},
{"sizelevel", ravi_sizelevel},
{"verbosity", ravi_verbosity},
{"gcstep", ravi_gcstep},
{"validation", ravi_validation},
{"tracehook", ravi_traceenable},
{"listcode", ravi_listcode},
{"limits", ravi_get_limits},

Loading…
Cancel
Save