upvalues wip

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

@ -280,9 +280,11 @@ 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];
*uv->v = *ra;
uv->v->tt_ = ra->tt_;
uv->v->value_.n = ra->value_.n;
int b1 = iscollectable(uv->v);
int b2 = uv->v != &uv->u.value;
struct TValue *value = &uv->u.value;
int b2 = uv->v != value;
if (b1 && !b2)
luaC_upvalbarrier_(L,uv);
}

@ -29,37 +29,36 @@ define void @luaV_op_call(%struct.lua_State* %L, %struct.LClosure* nocapture rea
entry:
%arrayidx = getelementptr inbounds %struct.LClosure* %cl, i32 0, i32 6, i32 %b
%0 = load %struct.UpVal** %arrayidx, align 4, !tbaa !1
%tt_ = getelementptr inbounds %struct.TValue* %ra, i32 0, i32 1
%1 = load i32* %tt_, align 4, !tbaa !5
%v = getelementptr inbounds %struct.UpVal* %0, i32 0, i32 0
%1 = bitcast %struct.UpVal* %0 to i8**
%2 = load i8** %1, align 4, !tbaa !5
%3 = bitcast %struct.TValue* %ra to i8*
tail call void @llvm.memcpy.p0i8.p0i8.i32(i8* %2, i8* %3, i32 16, i32 8, i1 false), !tbaa.struct !8
%4 = load %struct.TValue** %v, align 4, !tbaa !5
%tt_ = getelementptr inbounds %struct.TValue* %4, i32 0, i32 1
%5 = load i32* %tt_, align 4, !tbaa !14
%and = and i32 %5, 64
%value = getelementptr inbounds %struct.UpVal* %0, i32 0, i32 2, i32 0
%cmp = icmp ne %struct.TValue* %4, %value
%2 = load %struct.TValue** %v, align 4, !tbaa !8
%tt_1 = getelementptr inbounds %struct.TValue* %2, i32 0, i32 1
store i32 %1, i32* %tt_1, align 4, !tbaa !5
%n = bitcast %struct.TValue* %ra to double*
%3 = load double* %n, align 8, !tbaa !11
%4 = bitcast %struct.TValue* %2 to double*
store double %3, double* %4, align 8, !tbaa !11
%and = and i32 %1, 64
%value7 = getelementptr inbounds %struct.UpVal* %0, i32 0, i32 2, i32 0
%cmp = icmp ne %struct.TValue* %2, %value7
%tobool = icmp eq i32 %and, 0
%or.cond = or i1 %cmp, %tobool
br i1 %or.cond, label %if.end, label %if.then
if.then: ; preds = %entry
tail call void @luaC_upvalbarrier_(%struct.lua_State* %L, %struct.UpVal* %0) #1
tail call void @luaC_upvalbarrier_(%struct.lua_State* %L, %struct.UpVal* %0) #2
br label %if.end
if.end: ; preds = %entry, %if.then
ret void
}
; Function Attrs: nounwind
declare void @llvm.memcpy.p0i8.p0i8.i32(i8* nocapture, i8* nocapture readonly, i32, i32, i1) #1
declare void @luaC_upvalbarrier_(%struct.lua_State*, %struct.UpVal*) #2
declare void @luaC_upvalbarrier_(%struct.lua_State*, %struct.UpVal*) #1
attributes #0 = { nounwind "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" }
attributes #1 = { nounwind }
attributes #2 = { "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" }
attributes #1 = { "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" }
attributes #2 = { nounwind }
!llvm.ident = !{!0}
@ -68,14 +67,11 @@ attributes #2 = { "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "n
!2 = metadata !{metadata !"any pointer", metadata !3, i64 0}
!3 = metadata !{metadata !"omnipotent char", metadata !4, i64 0}
!4 = metadata !{metadata !"Simple C/C++ TBAA"}
!5 = metadata !{metadata !6, metadata !2, i64 0}
!6 = metadata !{metadata !"UpVal", metadata !2, i64 0, metadata !7, i64 8, metadata !3, i64 16}
!7 = metadata !{metadata !"long long", metadata !3, i64 0}
!8 = metadata !{i64 0, i64 4, metadata !1, i64 0, i64 4, metadata !1, i64 0, i64 4, metadata !9, i64 0, i64 4, metadata !1, i64 0, i64 8, metadata !11, i64 0, i64 8, metadata !12, i64 8, i64 4, metadata !9}
!9 = metadata !{metadata !10, metadata !10, i64 0}
!10 = metadata !{metadata !"int", metadata !3, i64 0}
!11 = metadata !{metadata !7, metadata !7, i64 0}
!12 = metadata !{metadata !13, metadata !13, i64 0}
!13 = metadata !{metadata !"double", metadata !3, i64 0}
!14 = metadata !{metadata !15, metadata !10, i64 8}
!15 = metadata !{metadata !"TValue", metadata !3, i64 0, metadata !10, i64 8}
!5 = metadata !{metadata !6, metadata !7, i64 8}
!6 = metadata !{metadata !"TValue", metadata !3, i64 0, metadata !7, i64 8}
!7 = metadata !{metadata !"int", metadata !3, i64 0}
!8 = metadata !{metadata !9, metadata !2, i64 0}
!9 = metadata !{metadata !"UpVal", metadata !2, i64 0, metadata !10, i64 8, metadata !3, i64 16}
!10 = metadata !{metadata !"long long", metadata !3, i64 0}
!11 = metadata !{metadata !12, metadata !12, i64 0}
!12 = metadata !{metadata !"double", metadata !3, i64 0}

@ -221,6 +221,7 @@ struct LuaLLVMTypes {
llvm::MDNode *tbaa_intT;
llvm::MDNode *tbaa_longlongT;
llvm::MDNode *tbaa_pointerT;
llvm::MDNode *tbaa_ppointerT;
llvm::MDNode *tbaa_CallInfo_lT;
llvm::MDNode *tbaa_CallInfoT;
llvm::MDNode *tbaa_luaStateT;
@ -230,12 +231,17 @@ struct LuaLLVMTypes {
llvm::MDNode *tbaa_CallInfo_func_LClosureT;
llvm::MDNode *tbaa_LClosureT;
llvm::MDNode *tbaa_LClosure_pT;
llvm::MDNode *tbaa_LClosure_upvalsT;
llvm::MDNode *tbaa_ProtoT;
llvm::MDNode *tbaa_Proto_kT;
llvm::MDNode *tbaa_TValueT;
llvm::MDNode *tbaa_TValue_nT;
llvm::MDNode *tbaa_TValue_ttT;
llvm::MDNode *tbaa_luaState_topT;
llvm::MDNode *tbaa_UpValT;
llvm::MDNode *tbaa_UpVal_vT;
llvm::MDNode *tbaa_UpVal_valueT;
};
class RAVI_API RaviJITStateImpl;
@ -421,6 +427,9 @@ struct RaviFunctionDef {
// Get pointer to base
llvm::Value *Ci_base;
// Pointer to LClosure
llvm::Value *p_LClosure;
};
// This class is responsible for compiling Lua byte code
@ -508,6 +517,19 @@ 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);
// Load the &upvals[offset] -> result is UpVal*
llvm::Instruction *emit_load_pupval(RaviFunctionDef *def, llvm::Value *ppupval);
// Load upval->v
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);
// isnil(reg) || isboolean(reg) && reg.value == 0
// !(isnil(reg) || isboolean(reg) && reg.value == 0)
llvm::Value *emit_boolean_testfalse(RaviFunctionDef *def, llvm::Value *reg,

@ -435,6 +435,30 @@ void RaviCodeGenerator::link_block(RaviFunctionDef *def, int pc) {
}
}
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 *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 *v = def->builder->CreateLoad(p_v);
v->setMetadata(llvm::LLVMContext::MD_tbaa, def->types->tbaa_UpVal_vT);
return v;
}
// Get &upval->value -> result is TValue *
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;
@ -477,6 +501,8 @@ void RaviCodeGenerator::compile(lua_State *L, Proto *p) {
cl_ptr->setMetadata(llvm::LLVMContext::MD_tbaa,
def.types->tbaa_CallInfo_func_LClosureT);
def.p_LClosure = cl_ptr;
// Get pointer to the Proto* which is cl->p
llvm::Value *proto = emit_gep(&def, "Proto", cl_ptr, 0, 5);

@ -32,7 +32,7 @@ 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),
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,6 +124,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)");
// In LLVM unions should be set to the largest member
// So in the case of a Value this is the double type
// union Value {
@ -616,6 +618,23 @@ LuaLLVMTypes::LuaLLVMTypes(llvm::LLVMContext &context) : mdbuilder(context) {
elements.push_back(lu_byteT); /* allowhook */
lua_StateT->setBody(elements);
//struct UpVal {
// struct TValue *v; /* points to stack or to its own value */
// unsigned long long refcount; /* reference counter */
// union {
// struct { /* (when open) */
// struct UpVal *next; /* linked list */
// int touched; /* mark to avoid cycles with dead threads */
// } open;
// struct TValue value; /* the value (when closed) */
// } u;
//};
elements.clear();
elements.push_back(pTValueT);
elements.push_back(C_size_t);
elements.push_back(TValueT);
UpValT->setBody(elements);
// int luaD_poscall (lua_State *L, StkId firstResult)
elements.clear();
elements.push_back(plua_StateT);
@ -734,6 +753,7 @@ 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);
//!14 = metadata !{metadata !"CallInfoL", metadata !3, i64 0, metadata !3, i64
// 4, metadata !9, i64 8}
@ -862,11 +882,12 @@ LuaLLVMTypes::LuaLLVMTypes(llvm::LLVMContext &context) : mdbuilder(context) {
nodes.push_back(std::pair<llvm::MDNode *, uint64_t>(tbaa_charT, 6));
nodes.push_back(std::pair<llvm::MDNode *, uint64_t>(tbaa_pointerT, 8));
nodes.push_back(std::pair<llvm::MDNode *, uint64_t>(tbaa_pointerT, 12));
nodes.push_back(std::pair<llvm::MDNode *, uint64_t>(tbaa_charT, 16));
nodes.push_back(std::pair<llvm::MDNode *, uint64_t>(tbaa_pointerT, 16));
tbaa_LClosureT = mdbuilder.createTBAAStructTypeNode("LClosure", nodes);
tbaa_LClosure_pT =
mdbuilder.createTBAAStructTagNode(tbaa_LClosureT, tbaa_pointerT, 12);
tbaa_LClosure_upvalsT = mdbuilder.createTBAAStructTagNode(tbaa_LClosureT, tbaa_pointerT, 16);
//!19 = metadata !{metadata !20, metadata !3, i64 44}
tbaa_Proto_kT =
@ -884,6 +905,14 @@ LuaLLVMTypes::LuaLLVMTypes(llvm::LLVMContext &context) : mdbuilder(context) {
tbaa_luaState_topT =
mdbuilder.createTBAAStructTagNode(tbaa_luaStateT, tbaa_pointerT, 8);
nodes.clear();
nodes.push_back(std::pair<llvm::MDNode *, uint64_t>(tbaa_pointerT, 0));
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);
}
void LuaLLVMTypes::dump() {

Loading…
Cancel
Save