implement GETUPVAL and GETTABUP and fix bug in LOADBOOL

pull/81/head
Dibyendu Majumdar 9 years ago
parent 92532969a3
commit df91c9a2a9

@ -280,6 +280,7 @@ extern void luaC_upvalbarrier_ (struct lua_State *L, struct UpVal *uv);
void luaV_op_call(struct lua_State *L, struct LClosure *cl, struct TValue *ra, int b, int c) {
struct UpVal *uv = cl->upvals[b];
ra->tt_ = uv->tt_;
uv->v->tt_ = ra->tt_;
uv->v->value_.n = ra->value_.n;
int b1 = iscollectable(uv->v);

@ -206,7 +206,7 @@ struct LuaLLVMTypes {
llvm::FunctionType *luaV_op_loadnilT;
std::array<llvm::Constant *, TM_N> kInt;
std::array<llvm::Constant *, 256> kInt;
std::array<llvm::Constant *, 21> kluaInteger;
llvm::Constant *kFalse;
@ -241,7 +241,6 @@ struct LuaLLVMTypes {
llvm::MDNode *tbaa_UpValT;
llvm::MDNode *tbaa_UpVal_vT;
llvm::MDNode *tbaa_UpVal_valueT;
};
class RAVI_API RaviJITStateImpl;
@ -517,18 +516,25 @@ public:
// TValue assign
void emit_assign(RaviFunctionDef *def, llvm::Value *ra, llvm::Value *rb);
// Get &upvals[offset] from LClosure
llvm::Value *emit_gep_upvals(RaviFunctionDef *def, llvm::Value *cl_ptr, int offset);
// Get &upvals[offset] from LClosure
llvm::Value *emit_gep_upvals(RaviFunctionDef *def, llvm::Value *cl_ptr,
int offset);
// Load the &upvals[offset] -> result is UpVal*
llvm::Instruction *emit_load_pupval(RaviFunctionDef *def, llvm::Value *ppupval);
llvm::Instruction *emit_load_pupval(RaviFunctionDef *def,
llvm::Value *ppupval);
// Get &upval->v
llvm::Value *emit_gep_upval_v(RaviFunctionDef *def,
llvm::Instruction *pupval);
// Load upval->v
llvm::Instruction *emit_load_upval_v(RaviFunctionDef *def, llvm::Instruction *pupval);
llvm::Instruction *emit_load_upval_v(RaviFunctionDef *def,
llvm::Instruction *pupval);
// Get &upval->value -> result is TValue *
llvm::Value *emit_gep_upval_value(RaviFunctionDef *def, llvm::Instruction *pupval);
llvm::Value *emit_gep_upval_value(RaviFunctionDef *def,
llvm::Instruction *pupval);
// isnil(reg) || isboolean(reg) && reg.value == 0
// !(isnil(reg) || isboolean(reg) && reg.value == 0)
@ -678,6 +684,12 @@ public:
void emit_GETTABLE(RaviFunctionDef *def, llvm::Value *L_ci,
llvm::Value *proto, int A, int B, int C);
void emit_GETUPVAL(RaviFunctionDef *def, llvm::Value *L_ci,
llvm::Value *proto, int A, int B);
void emit_GETTABUP(RaviFunctionDef *def, llvm::Value *L_ci,
llvm::Value *proto, int A, int B, int C);
// Emit code for OP_EQ, OP_LT and OP_LE
// The callee parameter should be luaV_equalobj, luaV_lessthan and
// luaV_lessequal

@ -341,3 +341,46 @@ assert(math.abs(testdiv(1.5,1.6)-0.9375) < 1e-12)
assert(math.abs(testdiv("1.5",1.6)-0.9375) < 1e-12)
assert(math.abs(testdiv("1.5","1.6")-0.9375) < 1e-12)
print("test 26 OK")
-- test 27
-- upvalues
local x = 1
local y=function()
local f = function()
return x
end
ravi.compile(f)
return f
end
--ravi.dumplua(y)
--ravi.compile(y)
local f = y()
assert(ravi.iscompiled(f))
--ravi.dumplua(f)
--ravi.dumpllvm(f)
assert(f() == 1)
x=5
assert(f() == 5)
print("test 27 OK")
-- test 28
-- upvalues
x1 = 3
local y=function()
local f = function()
return x1
end
ravi.compile(f)
return f
end
--ravi.dumplua(y)
--ravi.compile(y)
local f = y()
assert(ravi.iscompiled(f))
--ravi.dumplua(f)
--ravi.dumpllvm(f)
assert(f() == 3)
x1=5
assert(f() == 5)
print("test 28 OK")

@ -244,6 +244,8 @@ bool RaviCodeGenerator::canCompile(Proto *p) {
case OP_DIV:
case OP_SETTABLE:
case OP_GETTABLE:
case OP_GETUPVAL:
case OP_GETTABUP:
case OP_RAVI_MOVEI:
case OP_RAVI_MOVEF:
case OP_RAVI_TOINT:
@ -435,30 +437,42 @@ void RaviCodeGenerator::link_block(RaviFunctionDef *def, int pc) {
}
}
llvm::Value *RaviCodeGenerator::emit_gep_upvals(RaviFunctionDef *def, llvm::Value *cl_ptr, int offset) {
llvm::Value *RaviCodeGenerator::emit_gep_upvals(RaviFunctionDef *def,
llvm::Value *cl_ptr,
int offset) {
return emit_gep(def, "upvals", cl_ptr, 0, 6, offset);
}
llvm::Instruction *RaviCodeGenerator::emit_load_pupval(RaviFunctionDef *def, llvm::Value *ppupval) {
llvm::Instruction *RaviCodeGenerator::emit_load_pupval(RaviFunctionDef *def,
llvm::Value *ppupval) {
llvm::Instruction *ins = def->builder->CreateLoad(ppupval);
ins->setMetadata(llvm::LLVMContext::MD_tbaa, def->types->tbaa_ppointerT);
return ins;
}
// Load upval->v
llvm::Instruction *RaviCodeGenerator::emit_load_upval_v(RaviFunctionDef *def, llvm::Instruction *pupval) {
llvm::Value *p_v = emit_gep(def, "v", pupval, 0, 0);
llvm::Instruction *
RaviCodeGenerator::emit_load_upval_v(RaviFunctionDef *def,
llvm::Instruction *pupval) {
llvm::Value *p_v = emit_gep_upval_v(def, pupval);
llvm::Instruction *v = def->builder->CreateLoad(p_v);
v->setMetadata(llvm::LLVMContext::MD_tbaa, def->types->tbaa_UpVal_vT);
return v;
}
// Get &upval->v
llvm::Value *RaviCodeGenerator::emit_gep_upval_v(RaviFunctionDef *def,
llvm::Instruction *pupval) {
return emit_gep(def, "v", pupval, 0, 0);
}
// Get &upval->value -> result is TValue *
llvm::Value *RaviCodeGenerator::emit_gep_upval_value(RaviFunctionDef *def, llvm::Instruction *pupval) {
llvm::Value *
RaviCodeGenerator::emit_gep_upval_value(RaviFunctionDef *def,
llvm::Instruction *pupval) {
return emit_gep(def, "value", pupval, 0, 2);
}
void RaviCodeGenerator::compile(lua_State *L, Proto *p) {
if (p->ravi_jit.jit_status != 0 || !canCompile(p))
return;
@ -655,6 +669,15 @@ void RaviCodeGenerator::compile(lua_State *L, Proto *p) {
int C = GETARG_C(i);
emit_GETTABLE(&def, L_ci, proto, A, B, C);
} break;
case OP_GETTABUP: {
int B = GETARG_B(i);
int C = GETARG_C(i);
emit_GETTABUP(&def, L_ci, proto, A, B, C);
} break;
case OP_GETUPVAL: {
int B = GETARG_B(i);
emit_GETUPVAL(&def, L_ci, proto, A, B);
} break;
case OP_ADD: {
int B = GETARG_B(i);

@ -59,8 +59,12 @@ void RaviCodeGenerator::emit_LOADBOOL(RaviFunctionDef *def, llvm::Value *L_ci, l
emit_store_reg_b(def, llvm::ConstantInt::get(def->types->C_intT, B), dest);
// dest->type = LUA_TBOOLEAN
emit_store_type(def, dest, LUA_TBOOLEAN);
if (C)
if (C) {
def->builder->CreateBr(def->jmp_targets[j].jmp1);
llvm::BasicBlock *block = llvm::BasicBlock::Create(
def->jitState->context(), "nextblock", def->f);
def->builder->SetInsertPoint(block);
}
}
void RaviCodeGenerator::emit_MOVE(RaviFunctionDef *def, llvm::Value *L_ci,

@ -34,7 +34,7 @@ void RaviCodeGenerator::emit_SETTABLE(RaviFunctionDef *def, llvm::Value *L_ci,
def->builder->CreateCall4(def->luaV_settableF, def->L, ra, rb, rc);
}
// R(A) := R(B)[RK(C)]
// R(A) := R(B)[RK(C)]
void RaviCodeGenerator::emit_GETTABLE(RaviFunctionDef *def, llvm::Value *L_ci,
llvm::Value *proto, int A, int B, int C) {
llvm::Instruction *base_ptr = emit_load_base(def);
@ -43,4 +43,36 @@ void RaviCodeGenerator::emit_GETTABLE(RaviFunctionDef *def, llvm::Value *L_ci,
llvm::Value *rc = emit_gep_rkb(def, base_ptr, C);
def->builder->CreateCall4(def->luaV_gettableF, def->L, rb, rc, ra);
}
// R(A) := UpValue[B]
void RaviCodeGenerator::emit_GETUPVAL(RaviFunctionDef *def, llvm::Value *L_ci,
llvm::Value *proto, int A, int B) {
// case OP_GETUPVAL: {
// int b = GETARG_B(i);
// setobj2s(L, ra, cl->upvals[b]->v);
// } break;
llvm::Instruction *base_ptr = emit_load_base(def);
llvm::Value *ra = emit_gep_ra(def, base_ptr, A);
llvm::Value *upval_ptr = emit_gep_upvals(def, def->p_LClosure, B);
llvm::Instruction *upval = emit_load_pupval(def, upval_ptr);
llvm::Value *v = emit_load_upval_v(def, upval);
emit_assign(def, ra, v);
}
// R(A) := UpValue[B][RK(C)]
void RaviCodeGenerator::emit_GETTABUP(RaviFunctionDef *def, llvm::Value *L_ci,
llvm::Value *proto, int A, int B, int C) {
// case OP_GETTABUP: {
// int b = GETARG_B(i);
// Protect(luaV_gettable(L, cl->upvals[b]->v, RKC(i), ra));
// } break;
llvm::Instruction *base_ptr = emit_load_base(def);
llvm::Value *ra = emit_gep_ra(def, base_ptr, A);
llvm::Value *rc = emit_gep_rkb(def, base_ptr, C);
llvm::Value *upval_ptr = emit_gep_upvals(def, def->p_LClosure, B);
llvm::Instruction *upval = emit_load_pupval(def, upval_ptr);
llvm::Value *v = emit_load_upval_v(def, upval);
def->builder->CreateCall4(def->luaV_gettableF, def->L, v, rc, ra);
}
}

@ -32,7 +32,8 @@ LuaLLVMTypes::LuaLLVMTypes(llvm::LLVMContext &context) : mdbuilder(context) {
lua_NumberT = llvm::Type::getDoubleTy(context);
plua_NumberT = llvm::PointerType::get(lua_NumberT, 0);
static_assert(sizeof(lua_Integer) == sizeof(lua_Number) && sizeof(lua_Integer) == sizeof(int64_t),
static_assert(sizeof(lua_Integer) == sizeof(lua_Number) &&
sizeof(lua_Integer) == sizeof(int64_t),
"Only 64-bit int supported");
static_assert(std::is_integral<lua_Integer>::value,
"lua_Integer is not an integer type");
@ -124,8 +125,8 @@ LuaLLVMTypes::LuaLLVMTypes(llvm::LLVMContext &context) : mdbuilder(context) {
static_assert(sizeof(Value) == sizeof(lua_Number) &&
sizeof(Value) == sizeof(lua_Integer),
"Value type is larger than lua_Number");
static_assert(sizeof(TValue) == sizeof(lua_Number) * 2,
"TValue type is not 2*sizeof(lua_Number)");
static_assert(sizeof(TValue) == sizeof(lua_Number) * 2,
"TValue type is not 2*sizeof(lua_Number)");
// In LLVM unions should be set to the largest member
// So in the case of a Value this is the double type
// union Value {
@ -618,7 +619,7 @@ LuaLLVMTypes::LuaLLVMTypes(llvm::LLVMContext &context) : mdbuilder(context) {
elements.push_back(lu_byteT); /* allowhook */
lua_StateT->setBody(elements);
//struct UpVal {
// struct UpVal {
// struct TValue *v; /* points to stack or to its own value */
// unsigned long long refcount; /* reference counter */
// union {
@ -656,12 +657,14 @@ LuaLLVMTypes::LuaLLVMTypes(llvm::LLVMContext &context) : mdbuilder(context) {
elements.push_back(StkIdT);
elements.push_back(C_intT);
elements.push_back(C_intT);
luaD_callT = llvm::FunctionType::get(llvm::Type::getVoidTy(context), elements, false);
luaD_callT =
llvm::FunctionType::get(llvm::Type::getVoidTy(context), elements, false);
// void luaV_execute(lua_State L);
elements.clear();
elements.push_back(plua_StateT);
luaV_executeT = llvm::FunctionType::get(llvm::Type::getVoidTy(context), elements, false);
luaV_executeT =
llvm::FunctionType::get(llvm::Type::getVoidTy(context), elements, false);
// void luaF_close (lua_State *L, StkId level)
elements.clear();
@ -712,8 +715,10 @@ LuaLLVMTypes::LuaLLVMTypes(llvm::LLVMContext &context) : mdbuilder(context) {
elements.push_back(pTValueT);
elements.push_back(pTValueT);
elements.push_back(pTValueT);
luaV_gettableT = llvm::FunctionType::get(llvm::Type::getVoidTy(context), elements, false);
luaV_settableT = llvm::FunctionType::get(llvm::Type::getVoidTy(context), elements, false);
luaV_gettableT =
llvm::FunctionType::get(llvm::Type::getVoidTy(context), elements, false);
luaV_settableT =
llvm::FunctionType::get(llvm::Type::getVoidTy(context), elements, false);
elements.clear();
elements.push_back(plua_StateT);
@ -721,7 +726,8 @@ LuaLLVMTypes::LuaLLVMTypes(llvm::LLVMContext &context) : mdbuilder(context) {
elements.push_back(pTValueT);
elements.push_back(pTValueT);
elements.push_back(tmsT);
luaT_trybinTMT = llvm::FunctionType::get(llvm::Type::getVoidTy(context), elements, false);
luaT_trybinTMT =
llvm::FunctionType::get(llvm::Type::getVoidTy(context), elements, false);
elements.clear();
elements.push_back(pCallInfoT);
@ -753,7 +759,8 @@ LuaLLVMTypes::LuaLLVMTypes(llvm::LLVMContext &context) : mdbuilder(context) {
//!9 = metadata !{metadata !"long long", metadata !4, i64 0}
tbaa_longlongT =
mdbuilder.createTBAAScalarTypeNode("long long", tbaa_charT, 0);
tbaa_ppointerT = mdbuilder.createTBAAStructTagNode(tbaa_pointerT, tbaa_pointerT, 0);
tbaa_ppointerT =
mdbuilder.createTBAAStructTagNode(tbaa_pointerT, tbaa_pointerT, 0);
//!14 = metadata !{metadata !"CallInfoL", metadata !3, i64 0, metadata !3, i64
// 4, metadata !9, i64 8}
@ -887,7 +894,8 @@ LuaLLVMTypes::LuaLLVMTypes(llvm::LLVMContext &context) : mdbuilder(context) {
tbaa_LClosure_pT =
mdbuilder.createTBAAStructTagNode(tbaa_LClosureT, tbaa_pointerT, 12);
tbaa_LClosure_upvalsT = mdbuilder.createTBAAStructTagNode(tbaa_LClosureT, tbaa_pointerT, 16);
tbaa_LClosure_upvalsT =
mdbuilder.createTBAAStructTagNode(tbaa_LClosureT, tbaa_pointerT, 16);
//!19 = metadata !{metadata !20, metadata !3, i64 44}
tbaa_Proto_kT =
@ -911,8 +919,10 @@ LuaLLVMTypes::LuaLLVMTypes(llvm::LLVMContext &context) : mdbuilder(context) {
nodes.push_back(std::pair<llvm::MDNode *, uint64_t>(tbaa_longlongT, 8));
nodes.push_back(std::pair<llvm::MDNode *, uint64_t>(tbaa_TValueT, 16));
tbaa_UpValT = mdbuilder.createTBAAStructTypeNode("UpVal", nodes);
tbaa_UpVal_vT = mdbuilder.createTBAAStructTagNode(tbaa_UpValT, tbaa_pointerT, 0);
tbaa_UpVal_valueT = mdbuilder.createTBAAStructTagNode(tbaa_UpValT, tbaa_TValueT, 16);
tbaa_UpVal_vT =
mdbuilder.createTBAAStructTagNode(tbaa_UpValT, tbaa_pointerT, 0);
tbaa_UpVal_valueT =
mdbuilder.createTBAAStructTagNode(tbaa_UpValT, tbaa_TValueT, 16);
}
void LuaLLVMTypes::dump() {

@ -159,7 +159,7 @@ void *RaviJITFunctionImpl::compile() {
FPM->add(new llvm::DataLayoutPass(*engine_->getDataLayout()));
#endif
llvm::PassManagerBuilder pmb;
pmb.OptLevel = 3;
pmb.OptLevel = 1;
pmb.SizeLevel = 0;
pmb.populateFunctionPassManager(*FPM);
FPM->doInitialization();

@ -122,6 +122,7 @@ int main(int argc, const char *argv[])
{
int failures = 0;
//
failures += test_luacompexec1("function cannotload (msg, a,b); assert(not a and string.find(b, msg)); end; ravi.compile(cannotload); return 1", 1);
failures += test_luacompexec1("function z(); local a = 5; a = a + 1; return a; end; ravi.compile(z); return z()", 6);
failures += test_luacompexec1("function z(x); x[1] = 5; return x[1]; end; ravi.compile(z); return z({})", 5);
failures += test_luacompexec1("function z(x,y) return x<y end; ravi.compile(z); return not z(2,1)", 1);

Loading…
Cancel
Save