add options to control minimum code size and execution count for functions to be considered for JIT

pull/81/head
Dibyendu Majumdar 9 years ago
parent c70f5c2cb1
commit bbcf31601e

@ -359,6 +359,12 @@ class RAVI_API RaviJITStateImpl : public RaviJITState {
// Size level (LLVM PassManagerBuilder)
int size_level_;
// min code size for compilation
int min_code_size_;
// min execution count for compilation
int min_exec_count_;
public:
RaviJITStateImpl();
@ -394,6 +400,11 @@ public:
if (value >= 0 && value <= 2)
size_level_ = value;
}
int get_mincodesize() const { return min_code_size_; }
void set_mincodesize(int value) { min_code_size_ = value > 0 ? value : min_code_size_; }
int get_minexeccount() const { return min_exec_count_; }
void set_minexeccount(int value) { min_exec_count_ = value > 0 ? value : min_exec_count_; }
};
// To optimise fornum loops

@ -127,6 +127,11 @@ public:
virtual void set_optlevel(int value) = 0;
virtual int get_sizelevel() const = 0;
virtual void set_sizelevel(int value) = 0;
virtual int get_mincodesize() const = 0;
virtual void set_mincodesize(int) = 0;
virtual int get_minexeccount() const = 0;
virtual void set_minexeccount(int) = 0;
protected:
RaviJITState() {}
private:

@ -1762,13 +1762,12 @@ static void forbody (LexState *ls, int base, int line, int nvars, int isnum, For
adjustlocalvars(ls, 3); /* control variables */
checknext(ls, TK_DO);
if (isnum) {
ls->fs->f->ravi_jit.jit_flags = 1;
if (info && info->is_constant && info->int_value > 1) {
ls->fs->f->ravi_jit.jit_flags = 1;
forprep_inst = OP_RAVI_FORPREP_IP;
forloop_inst = OP_RAVI_FORLOOP_IP;
}
else if (info && info->is_constant && info->int_value == 1) {
ls->fs->f->ravi_jit.jit_flags = 1;
forprep_inst = OP_RAVI_FORPREP_I1;
forloop_inst = OP_RAVI_FORLOOP_I1;
}

@ -38,7 +38,7 @@ RaviJITState *RaviJITFunctionImpl::owner() const { return owner_; }
RaviJITStateImpl::RaviJITStateImpl()
: context_(llvm::getGlobalContext()), auto_(false), enabled_(true),
opt_level_(2), size_level_(0) {
opt_level_(2), size_level_(0), min_code_size_(150), min_exec_count_(50) {
// LLVM needs to be initialized else
// ExecutionEngine cannot be created
// This should ideally be an atomic check but because LLVM docs
@ -117,16 +117,18 @@ RaviJITFunctionImpl::RaviJITFunctionImpl(
#endif
function_ = llvm::Function::Create(type, linkage, name, module_);
// function_->addFnAttr(llvm::Attribute::StackProtectReq);
//TODO add stack checks as debug more
// function_->addFnAttr(llvm::Attribute::StackProtectReq);
#if defined(_WIN32)
// For some reason on Windows we get inaligned stack
// error when calling longjmp - following appears to help in at
// least one test case
//llvm::AttrBuilder attr;
//attr.addStackAlignmentAttr(16);
//function_->addAttributes(
// llvm::AttributeSet::FunctionIndex,
// llvm::AttributeSet::get(owner_->context(),
// TODO On 32-bit Windows we need to force
// 16-byte alignment
// llvm::AttrBuilder attr;
// attr.addStackAlignmentAttr(16);
// function_->addAttributes(
// llvm::AttributeSet::FunctionIndex,
// llvm::AttributeSet::get(owner_->context(),
// llvm::AttributeSet::FunctionIndex, attr));
#endif
std::string errStr;
@ -161,6 +163,7 @@ RaviJITFunctionImpl::~RaviJITFunctionImpl() {
delete module_;
}
// Following two functions based upon similar in Clang
static void addAddressSanitizerPasses(const llvm::PassManagerBuilder &Builder,
llvm::PassManagerBase &PM) {
PM.add(llvm::createAddressSanitizerFunctionPass());
@ -194,6 +197,8 @@ void *RaviJITFunctionImpl::compile() {
pmb.SizeLevel = owner_->get_sizelevel();
#if 0
// TODO following appears to require linking to some
// additional LLVM libraries
pmb.addExtension(llvm::PassManagerBuilder::EP_OptimizerLast,
addAddressSanitizerPasses);
pmb.addExtension(llvm::PassManagerBuilder::EP_EnabledOnOptLevel0,
@ -326,25 +331,26 @@ int raviV_compile(struct lua_State *L, struct Proto *p, int manual_request) {
if (!G->ravi_state->jit->is_enabled()) {
return 0;
}
#if 0
#ifdef _WIN32
// For some reason on Windows we sometimes get
// an exception in luaD_throw() when JIT compilation
// is ON.
bool doCompile = (G->ravi_state->jit->is_auto() || (bool)manual_request);
#else
bool doCompile = (bool)manual_request;
if (!doCompile && G->ravi_state->jit->is_auto()) {
if (p->ravi_jit.jit_flags != 0) /* loop */
doCompile = true;
else if (p->sizecode > 1)
else if (p->sizecode > G->ravi_state->jit->get_mincodesize())
doCompile = true;
else {
if (p->ravi_jit.execution_count < 50)
if (p->ravi_jit.execution_count < G->ravi_state->jit->get_minexeccount())
p->ravi_jit.execution_count++;
else
doCompile = true;
}
}
#endif
//if (manual_request)
// printf("do compile %d\n", (int)doCompile);
if (doCompile)
G->ravi_state->code_generator->compile(L, p);
return p->ravi_jit.jit_status == 2;
@ -427,16 +433,30 @@ static int ravi_dump_llvmir(lua_State *L) {
static int ravi_auto(lua_State *L) {
global_State *G = G(L);
int n = lua_gettop(L);
bool value = false;
if (n == 1)
value = lua_toboolean(L, 1);
if (G->ravi_state == NULL)
if (G->ravi_state == NULL) {
lua_pushboolean(L, 0);
else
lua_pushinteger(L, -1);
lua_pushinteger(L, -1);
}
else {
lua_pushboolean(L, G->ravi_state->jit->is_auto());
if (n == 1 && G->ravi_state)
G->ravi_state->jit->set_auto(value);
return 1;
lua_pushinteger(L, G->ravi_state->jit->get_mincodesize());
lua_pushinteger(L, G->ravi_state->jit->get_minexeccount());
}
if (G->ravi_state) {
bool value = false;
if (n >= 1)
value = lua_toboolean(L, 1);
if (n >= 1)
G->ravi_state->jit->set_auto(value);
int min_code_size = (n >= 2) ? (int)(lua_tointeger(L, 2)) : -1;
int min_exec_count = (n == 3) ? (int)(lua_tointeger(L, 3)) : -1;
if (min_code_size >= 1)
G->ravi_state->jit->set_mincodesize(min_code_size);
if (min_exec_count >= 1)
G->ravi_state->jit->set_minexeccount(min_exec_count);
}
return 3;
}
// Turn on/off the JIT compiler

Loading…
Cancel
Save