gccjit-ravi534
Dibyendu Majumdar 8 years ago
parent 0eb6e8e645
commit 4f3851e8f3

@ -117,7 +117,7 @@ LUAI_FUNC lua_Integer luaV_shiftl (lua_Integer x, lua_Integer y);
LUAI_FUNC void luaV_objlen (lua_State *L, StkId ra, const TValue *rb);
/* RAVI changes for JIT */
/* The following expose some of the VM opcodes for the JIT compiler */
LUAI_FUNC int luaV_forlimit(const TValue *obj, lua_Integer *p, lua_Integer step,
int *stopnow);
LUAI_FUNC void raviV_op_loadnil(CallInfo *ci, int a, int b);
@ -136,6 +136,10 @@ LUAI_FUNC void raviV_op_setupvalt(lua_State *L, LClosure *cl, TValue *ra, int b)
LUAI_FUNC void raviV_op_setupval(lua_State *L, LClosure *cl, TValue *ra, int b);
LUAI_FUNC void raviV_op_shl(lua_State *L, TValue *ra, TValue *rb, TValue *rc);
LUAI_FUNC void raviV_op_shr(lua_State *L, TValue *ra, TValue *rb, TValue *rc);
LUAI_FUNC void raviV_op_bor(lua_State *L, TValue *ra, TValue *rb, TValue *rc);
LUAI_FUNC void raviV_op_bxor(lua_State *L, TValue *ra, TValue *rb, TValue *rc);
LUAI_FUNC void raviV_op_band(lua_State *L, TValue *ra, TValue *rb, TValue *rc);
LUAI_FUNC void raviV_op_bnot(lua_State *L, TValue *ra, TValue *rb);
LUAI_FUNC void raviV_gettable_sskey(lua_State *L, const TValue *t, TValue *key, StkId val);
LUAI_FUNC void raviV_settable_sskey(lua_State *L, const TValue *t, TValue *key, StkId val);

@ -267,6 +267,10 @@ struct LuaLLVMTypes {
llvm::FunctionType *raviV_op_varargT;
llvm::FunctionType *raviV_op_shrT;
llvm::FunctionType *raviV_op_shlT;
llvm::FunctionType *raviV_op_borT;
llvm::FunctionType *raviV_op_bxorT;
llvm::FunctionType *raviV_op_bandT;
llvm::FunctionType *raviV_op_bnotT;
llvm::FunctionType *raviV_op_setupvaliT;
llvm::FunctionType *raviV_op_setupvalfT;
llvm::FunctionType *raviV_op_setupvalaiT;
@ -638,6 +642,10 @@ struct RaviFunctionDef {
llvm::Function *raviV_op_varargF;
llvm::Function *raviV_op_shrF;
llvm::Function *raviV_op_shlF;
llvm::Function *raviV_op_borF;
llvm::Function *raviV_op_bxorF;
llvm::Function *raviV_op_bandF;
llvm::Function *raviV_op_bnotF;
llvm::Function *raviV_op_setupvaliF;
llvm::Function *raviV_op_setupvalfF;
llvm::Function *raviV_op_setupvalaiF;
@ -1190,6 +1198,11 @@ class RaviCodeGenerator {
void emit_BNOT_I(RaviFunctionDef *def, int A, int B, int pc);
void emit_BOR_BXOR_BAND(RaviFunctionDef *def, OpCode op, int A, int B,
int C, int pc);
void emit_BNOT(RaviFunctionDef *def, int A, int B, int pc);
void emit_bitwise_shiftl(RaviFunctionDef *def, llvm::Value *ra, int B,
lua_Integer y);

@ -47,6 +47,7 @@ foo()
foo = nil
if _soft then return 10 end
if ravi and ravi.auto() then return 10 end
print "testing large programs (>64k)"

@ -284,11 +284,6 @@ void luaV_finishset (lua_State *L, const TValue *t, TValue *key,
else { \
protect(luaV_finishget(L, t, key, val, NULL)); \
}
// { \
// const TValue *aux; \
// if (luaV_fastget(L,t,tsvalue(key),aux,luaH_getshortstr)) { setobj2s(L, val, aux); } \
// else protect(luaV_finishget(L,t,key,val,aux)); \
// }
#define GETTABLE_INLINE_SSKEY_PROTECTED(L, t, key, val) GETTABLE_INLINE_SSKEY_(L, t, key, val, Protect)
#define GETTABLE_INLINE_SSKEY(L, t, key, val) GETTABLE_INLINE_SSKEY_(L, t, key, val, Unprotect)
@ -359,12 +354,6 @@ void luaV_finishset (lua_State *L, const TValue *t, TValue *key,
protect(luaV_finishset(L, t, key, val, NULL)); \
}
// { \
// const TValue *slot; \
// if (!luaV_fastset(L, t, tsvalue(key), slot, luaH_getshortstr, val)) \
// protect(luaV_finishset(L, t, key, val, slot)); \
// }
#define SETTABLE_INLINE_SSKEY_PROTECTED(L, t, key, val) SETTABLE_INLINE_SSKEY_(L, t, key, val, Protect)
#define SETTABLE_INLINE_SSKEY(L, t, key, val) SETTABLE_INLINE_SSKEY_(L, t, key, val, Unprotect)
@ -829,7 +818,9 @@ void luaV_finishOp (lua_State *L) {
case OP_BAND: case OP_BOR: case OP_BXOR: case OP_SHL: case OP_SHR:
case OP_MOD: case OP_POW:
case OP_UNM: case OP_BNOT: case OP_LEN:
case OP_RAVI_GETTABUP_SK: case OP_RAVI_GETTABLE_SK: case OP_RAVI_SELF_SK:
case OP_RAVI_GETTABUP_SK:
case OP_RAVI_GETTABLE_SK: case OP_RAVI_GETTABLE_I: case OP_RAVI_GETTABLE_S:
case OP_RAVI_SELF_SK: case OP_RAVI_SELF_S:
case OP_GETTABUP: case OP_GETTABLE: case OP_SELF: {
setobjs2s(L, base + GETARG_A(inst), --L->top);
break;
@ -871,6 +862,7 @@ void luaV_finishOp (lua_State *L) {
L->top = ci->top; /* adjust results */
break;
}
case OP_RAVI_SETTABLE_I: case OP_RAVI_SETTABLE_S: case OP_RAVI_SETTABLE_SK:
case OP_TAILCALL: case OP_SETTABUP: case OP_SETTABLE:
break;
default: lua_assert(0);
@ -1684,7 +1676,7 @@ int luaV_execute (lua_State *L) {
v = &t->array[idx - 1];
else
v = luaH_getint(t, idx);
if (!ttisnil(v) || metamethod_absent(t->metatable, TM_INDEX)) {
if (!ttisnil(v)) {
setobj2s(L, ra, v);
}
else {
@ -2372,6 +2364,46 @@ void raviV_op_shr(lua_State *L, TValue *ra, TValue *rb, TValue *rc) {
}
}
void raviV_op_band(lua_State *L, TValue *ra, TValue *rb, TValue *rc) {
lua_Integer ib;
lua_Integer ic;
if (tointeger(rb, &ib) && tointeger(rc, &ic)) {
setivalue(ra, intop(&, ib, ic));
}
else {
luaT_trybinTM(L, rb, rc, ra, TM_BAND);
}
}
void raviV_op_bor(lua_State *L, TValue *ra, TValue *rb, TValue *rc) {
lua_Integer ib;
lua_Integer ic;
if (tointeger(rb, &ib) && tointeger(rc, &ic)) {
setivalue(ra, intop(|, ib, ic));
}
else {
luaT_trybinTM(L, rb, rc, ra, TM_BOR);
}
}
void raviV_op_bxor(lua_State *L, TValue *ra, TValue *rb, TValue *rc) {
lua_Integer ib;
lua_Integer ic;
if (tointeger(rb, &ib) && tointeger(rc, &ic)) {
setivalue(ra, intop (^, ib, ic));
}
else {
luaT_trybinTM(L, rb, rc, ra, TM_BXOR);
}
}
void raviV_op_bnot(lua_State *L, TValue *ra, TValue *rb) {
lua_Integer ib;
if (tointeger(rb, &ib)) { setivalue(ra, intop (^, ~l_castS2U(0), ib)); }
else {
luaT_trybinTM(L, rb, rb, ra, TM_BNOT);
}
}
/*
** Main function for table access (invoking metamethods if needed).

@ -342,4 +342,30 @@ void RaviCodeGenerator::emit_BNOT_I(RaviFunctionDef *def, int A, int B,
llvm::Value *result = def->builder->CreateXor(lhs, rhs, "");
emit_store_reg_i_withtype(def, result, ra);
}
void RaviCodeGenerator::emit_BOR_BXOR_BAND(RaviFunctionDef *def, OpCode op, int A, int B,
int C, int pc) {
bool traced = emit_debug_trace(def, op, pc);
// Below may invoke metamethod so we set savedpc
if (!traced) emit_update_savedpc(def, pc);
emit_load_base(def);
llvm::Value *ra = emit_gep_register(def, A);
llvm::Value *rb = emit_gep_register_or_constant(def, B);
llvm::Value *rc = emit_gep_register_or_constant(def, C);
CreateCall4(def->builder, op == OP_BOR ? def->raviV_op_borF :
(op == OP_BAND ? def->raviV_op_bandF : def->raviV_op_bxorF),
def->L, ra, rb, rc);
}
void RaviCodeGenerator::emit_BNOT(RaviFunctionDef *def, int A, int B, int pc) {
bool traced = emit_debug_trace(def, OP_BNOT, pc);
// Below may invoke metamethod so we set savedpc
if (!traced) emit_update_savedpc(def, pc);
emit_load_base(def);
llvm::Value *ra = emit_gep_register(def, A);
llvm::Value *rb = emit_gep_register(def, B);
CreateCall3(def->builder, def->raviV_op_bnotF, def->L, ra, rb);
}
}

@ -839,20 +839,20 @@ bool RaviCodeGenerator::canCompile(Proto *p) {
p->ravi_jit.jit_status = RAVI_JIT_CANT_COMPILE;
return false;
}
const Instruction *code = p->code;
int pc, n = p->sizecode;
//const Instruction *code = p->code;
//int pc, n = p->sizecode;
// Loop over the byte codes; as Lua compiler inserts
// an extra RETURN op we need to ignore the last op
for (pc = 0; pc < n; pc++) {
Instruction i = code[pc];
OpCode o = GET_OPCODE(i);
if (o == OP_BNOT || o == OP_BAND || o == OP_BOR || o == OP_BXOR || o == OP_EXTRAARG)
return false;
else if (o == OP_RAVI_UNMF || o == OP_RAVI_UNMI) {
fprintf(stderr, "Unexpected bytecode %d\n", o);
abort();
}
}
//for (pc = 0; pc < n; pc++) {
// Instruction i = code[pc];
// OpCode o = GET_OPCODE(i);
// if (o == OP_EXTRAARG)
// return false;
// else if (o == OP_RAVI_UNMF || o == OP_RAVI_UNMI) {
// fprintf(stderr, "Unexpected bytecode %d\n", o);
// abort();
// }
//}
return true;
}
@ -1057,6 +1057,18 @@ void RaviCodeGenerator::emit_extern_declarations(RaviFunctionDef *def) {
def->raviV_op_shrF = def->raviF->addExternFunction(
def->types->raviV_op_shrT, reinterpret_cast<void *>(&raviV_op_shr),
"raviV_op_shr");
def->raviV_op_borF = def->raviF->addExternFunction(
def->types->raviV_op_borT, reinterpret_cast<void *>(&raviV_op_bor),
"raviV_op_bor");
def->raviV_op_bxorF = def->raviF->addExternFunction(
def->types->raviV_op_bxorT, reinterpret_cast<void *>(&raviV_op_bxor),
"raviV_op_bxor");
def->raviV_op_bandF = def->raviF->addExternFunction(
def->types->raviV_op_bandT, reinterpret_cast<void *>(&raviV_op_band),
"raviV_op_band");
def->raviV_op_bnotF = def->raviF->addExternFunction(
def->types->raviV_op_bnotT, reinterpret_cast<void *>(&raviV_op_bnot),
"raviV_op_bnot");
def->raviV_op_setupvaliF = def->raviF->addExternFunction(
def->types->raviV_op_setupvaliT,
reinterpret_cast<void *>(&raviV_op_setupvali), "raviV_op_setupvali");
@ -1387,6 +1399,12 @@ bool RaviCodeGenerator::compile(lua_State *L, Proto *p,
case OP_SETLIST: {
int B = GETARG_B(i);
int C = GETARG_C(i);
if (C == 0) {
// OP_SETLIST is followed by OP_EXTRAARG
Instruction inst = code[++pc];
C = GETARG_Ax(inst);
lua_assert(GET_OPCODE(inst) == OP_EXTRAARG);
}
emit_SETLIST(def, A, B, C, pc);
} break;
case OP_SELF:
@ -1464,6 +1482,10 @@ bool RaviCodeGenerator::compile(lua_State *L, Proto *p,
int B = GETARG_B(i);
emit_BNOT_I(def, A, B, pc);
} break;
case OP_BNOT: {
int B = GETARG_B(i);
emit_BNOT(def, A, B, pc);
} break;
case OP_TEST: {
int B = GETARG_B(i);
int C = GETARG_C(i);
@ -1555,15 +1577,14 @@ bool RaviCodeGenerator::compile(lua_State *L, Proto *p,
emit_SETTABLE_SK(def, A, B, C, pc);
} break;
// The SETTABLE_I code generation is broken as it
// doesn't handle metamethods etc. Needs to be done
// similar to SETTABLE_SK
case OP_RAVI_SETTABLE_I: /* {
int B = GETARG_B(i);
int C = GETARG_C(i);
emit_SETTABLE_I(def, A, B, C, pc);
} break; */
/* The SETTABLE_I code generation is broken as it
doesn't handle metamethods etc. Needs to be done
similar to SETTABLE_SK
*/
case OP_SETTABLE: {
int B = GETARG_B(i);
int C = GETARG_C(i);
@ -1705,6 +1726,14 @@ bool RaviCodeGenerator::compile(lua_State *L, Proto *p,
emit_BITWISE_BINARY_OP(def, op, A, B, C, pc);
} break;
case OP_BAND:
case OP_BOR:
case OP_BXOR: {
int B = GETARG_B(i);
int C = GETARG_C(i);
emit_BOR_BXOR_BAND(def, op, A, B, C, pc);
} break;
case OP_SHR:
case OP_SHL:
case OP_RAVI_SHL_II:

@ -47,7 +47,7 @@ void RaviCodeGenerator::emit_SELF_SK(RaviFunctionDef *def, int A, int B, int C,
int pc) {
// StkId rb = RB(i);
// setobjs2s(L, ra + 1, rb);
// Protect(luaV_gettable(L, rb, RKC(i), ra));
// Protect(raviV_gettable_sskey(L, rb, RKC(i), ra));
bool traced = emit_debug_trace(def, OP_RAVI_SELF_SK, pc);
// Below may invoke metamethod so we set savedpc
if (!traced) emit_update_savedpc(def, pc);
@ -128,7 +128,7 @@ void RaviCodeGenerator::emit_SETTABLE(RaviFunctionDef *def, int A, int B, int C,
// R(A)[RK(B)] := RK(C)
void RaviCodeGenerator::emit_SETTABLE_SK(RaviFunctionDef *def, int A, int B, int C,
int pc) {
// Protect(luaV_settable(L, ra, RKB(i), RKC(i)));
// Protect(raviV_settable_sskey(L, ra, RKB(i), RKC(i)));
bool traced = emit_debug_trace(def, OP_RAVI_SETTABLE_SK, pc);
// Below may invoke metamethod so we set savedpc
if (!traced) emit_update_savedpc(def, pc);
@ -157,7 +157,7 @@ void RaviCodeGenerator::emit_GETTABLE(RaviFunctionDef *def, int A, int B, int C,
// R(A) := R(B)[RK(C)]
void RaviCodeGenerator::emit_GETTABLE_SK(RaviFunctionDef *def, int A, int B, int C,
int pc) {
// Protect(luaV_gettable(L, RB(i), RKC(i), ra));
// Protect(raviV_gettable_sskey(L, RB(i), RKC(i), ra));
bool traced = emit_debug_trace(def, OP_RAVI_GETTABLE_SK, pc);
// Below may invoke metamethod so we set savedpc
if (!traced) emit_update_savedpc(def, pc);
@ -425,52 +425,6 @@ void RaviCodeGenerator::emit_GETTABLE_S(RaviFunctionDef *def, int A, int B,
emit_common_GETTABLE_S(def, A, B, C, key);
}
#if 0
void RaviCodeGenerator::emit_GETTABLE_SK(RaviFunctionDef *def, int A, int B,
int C, int pc, TString *key) {
emit_debug_trace(def, OP_RAVI_GETTABLE_SK, pc);
emit_load_base(def);
llvm::Value *rb = emit_gep_register(def, B);
llvm::Instruction *type = emit_load_type(def, rb);
// if not table
// call luaV_gettable
// else
// do GETTABLE_S
// BUG FIXME - this check is not adequate as it
// also needs to verify that we are not dealing with a Ravi array
// type != LUA_TTABLE ?
llvm::Value *cmp1 =
emit_is_not_value_of_type_class(def, type, LUA__TTABLE, "is_not_table");
llvm::BasicBlock *not_table = llvm::BasicBlock::Create(
def->jitState->context(), "GETTABLE_SK_if_not_table", def->f);
llvm::BasicBlock *else_not_table = llvm::BasicBlock::Create(
def->jitState->context(), "GETTABLE_SK_if_table");
llvm::BasicBlock *done =
llvm::BasicBlock::Create(def->jitState->context(), "GETTABLE_SK_done");
def->builder->CreateCondBr(cmp1, not_table, else_not_table);
def->builder->SetInsertPoint(not_table);
llvm::Value *ra = emit_gep_register(def, A);
llvm::Value *rc = emit_gep_register_or_constant(def, C);
CreateCall4(def->builder, def->luaV_gettableF, def->L, rb, rc, ra);
def->builder->CreateBr(done);
def->f->getBasicBlockList().push_back(else_not_table);
def->builder->SetInsertPoint(else_not_table);
emit_common_GETTABLE_S(def, A, B, C, key);
def->builder->CreateBr(done);
def->f->getBasicBlockList().push_back(done);
def->builder->SetInsertPoint(done);
}
#endif
void RaviCodeGenerator::emit_GETTABLE_AF(RaviFunctionDef *def, int A, int B,
int C, bool omitArrayGetRangeCheck,
int pc) {
@ -824,62 +778,6 @@ void RaviCodeGenerator::emit_GETTABUP_SK(RaviFunctionDef *def, int A, int B, int
}
#if 0
// R(A) := UpValue[B][RK(C)]
void RaviCodeGenerator::emit_GETTABUP_SK(RaviFunctionDef *def, int A, int B,
int C, int pc, TString *key) {
// int b = GETARG_B(i);
// Protect(luaV_gettable(L, cl->upvals[b]->v, RKC(i), ra));
bool traced = emit_debug_trace(def, OP_RAVI_GETTABUP_SK, pc);
// Below may invoke metamethod so we set savedpc
if (!traced) emit_update_savedpc(def, pc);
emit_load_base(def);
// cl->upvals[b]->v
llvm::Value *upval_ptr = emit_gep_upvals(def, B);
llvm::Instruction *upval = emit_load_pupval(def, upval_ptr);
llvm::Value *rb = emit_load_upval_v(def, upval);
// rb = cl->upvals[b]->v
llvm::Instruction *type = emit_load_type(def, rb);
// if not table
// call luaV_gettable
// else
// do GETTABLE_S
// BUG FIXME - this check is not adequate as it
// also needs to verify that we are not dealing with a Ravi array
// type != LUA_TTABLE ?
llvm::Value *cmp1 =
emit_is_not_value_of_type_class(def, type, LUA__TTABLE, "is_not_table");
llvm::BasicBlock *not_table = llvm::BasicBlock::Create(
def->jitState->context(), "GETTABUP_SK_if_not_table", def->f);
llvm::BasicBlock *else_not_table = llvm::BasicBlock::Create(
def->jitState->context(), "GETTABUP_SK_if_table");
llvm::BasicBlock *done =
llvm::BasicBlock::Create(def->jitState->context(), "GETTABUP_SK_done");
def->builder->CreateCondBr(cmp1, not_table, else_not_table);
def->builder->SetInsertPoint(not_table);
llvm::Value *ra = emit_gep_register(def, A);
llvm::Value *rc = emit_gep_register_or_constant(def, C);
CreateCall4(def->builder, def->luaV_gettableF, def->L, rb, rc, ra);
def->builder->CreateBr(done);
def->f->getBasicBlockList().push_back(else_not_table);
def->builder->SetInsertPoint(else_not_table);
emit_common_GETTABLE_S_(def, A, rb, C, key);
def->builder->CreateBr(done);
def->f->getBasicBlockList().push_back(done);
def->builder->SetInsertPoint(done);
}
#endif
// UpValue[A][RK(B)] := RK(C)
void RaviCodeGenerator::emit_SETTABUP(RaviFunctionDef *def, int A, int B, int C,
int pc) {
@ -1000,43 +898,6 @@ void RaviCodeGenerator::emit_TOARRAY(RaviFunctionDef *def, int A,
def->f->getBasicBlockList().push_back(done);
def->builder->SetInsertPoint(done);
#if 0
// type != LUA_TTABLE ?
llvm::Value *cmp1 =
emit_is_not_value_of_type_class(def, type, LUA__TTABLE, "is.not.table");
llvm::BasicBlock *raise_error = llvm::BasicBlock::Create(
def->jitState->context(), "if.not.table", def->f);
llvm::BasicBlock *else1 =
llvm::BasicBlock::Create(def->jitState->context(), "test.if.array");
llvm::BasicBlock *done =
llvm::BasicBlock::Create(def->jitState->context(), "done");
def->builder->CreateCondBr(cmp1, raise_error, else1);
def->builder->SetInsertPoint(raise_error);
// Conversion failed, so raise error
emit_raise_lua_error(def, errmsg);
def->builder->CreateBr(done);
def->f->getBasicBlockList().push_back(else1);
def->builder->SetInsertPoint(else1);
// Get table
llvm::Instruction *h = emit_load_reg_h(def, ra);
// Get array type
llvm::Instruction *ravi_array_type = emit_load_ravi_arraytype(def, h);
// array_type == RAVI_TARRAYXXX?
llvm::Value *cmp2 = def->builder->CreateICmpEQ(
ravi_array_type, def->types->kByte[array_type_expected], "is.array.type");
// If array then fine else raise error
def->builder->CreateCondBr(cmp2, done, raise_error);
def->f->getBasicBlockList().push_back(done);
def->builder->SetInsertPoint(done);
#endif
}
void RaviCodeGenerator::emit_MOVEAI(RaviFunctionDef *def, int A, int B,

@ -903,17 +903,29 @@ LuaLLVMTypes::LuaLLVMTypes(llvm::LLVMContext &context) : mdbuilder(context) {
raviV_op_setupvaltT =
llvm::FunctionType::get(llvm::Type::getVoidTy(context), elements, false);
// void raviV_op_bor(lua_State *L, TValue *ra, TValue *rb, TValue *rc);
// void raviV_op_bxor(lua_State *L, TValue *ra, TValue *rb, TValue *rc);
// void raviV_op_band(lua_State *L, TValue *ra, TValue *rb, TValue *rc);
// void raviV_op_bnot(lua_State *L, TValue *ra, TValue *rb);
// void raviV_op_shl(lua_State *L, TValue *ra, TValue *rb, TValue *rc);
// void raviV_op_shr(lua_State *L, TValue *ra, TValue *rb, TValue *rc);
elements.clear();
elements.push_back(plua_StateT);
elements.push_back(pTValueT);
elements.push_back(pTValueT);
raviV_op_bnotT =
llvm::FunctionType::get(llvm::Type::getVoidTy(context), elements, false);
elements.push_back(pTValueT);
raviV_op_shlT =
llvm::FunctionType::get(llvm::Type::getVoidTy(context), elements, false);
raviV_op_shrT =
llvm::FunctionType::get(llvm::Type::getVoidTy(context), elements, false);
raviV_op_borT =
llvm::FunctionType::get(llvm::Type::getVoidTy(context), elements, false);
raviV_op_bxorT =
llvm::FunctionType::get(llvm::Type::getVoidTy(context), elements, false);
raviV_op_bandT =
llvm::FunctionType::get(llvm::Type::getVoidTy(context), elements, false);
// const TValue *luaH_getint(Table *t, lua_Integer key);
elements.clear();

Loading…
Cancel
Save