more work on issue #73

pull/81/head
dibyendumajumdar 9 years ago
parent 7531acff65
commit 704b6faf10

@ -264,6 +264,7 @@ struct LuaLLVMTypes {
llvm::FunctionType *raviV_op_setupvalaiT;
llvm::FunctionType *raviV_op_setupvalafT;
llvm::FunctionType *raviV_op_setupvaltT;
llvm::FunctionType *raviV_finishgetT;
llvm::FunctionType *raviH_set_intT;
llvm::FunctionType *raviH_set_floatT;
@ -331,6 +332,8 @@ struct LuaLLVMTypes {
llvm::MDNode *tbaa_Table_node;
llvm::MDNode *tbaa_Table_sizearray;
llvm::MDNode *tbaa_Table_array;
llvm::MDNode *tbaa_Table_flags;
llvm::MDNode *tbaa_Table_metatable;
};
class RAVI_API RaviJITStateImpl;
@ -566,6 +569,7 @@ struct RaviFunctionDef {
llvm::Function *raviV_op_setupvalaiF;
llvm::Function *raviV_op_setupvalafF;
llvm::Function *raviV_op_setupvaltF;
llvm::Function *raviV_finishgetF;
// array setters
llvm::Function *raviH_set_intF;
@ -780,6 +784,8 @@ public:
llvm::Value *emit_table_get_array(RaviFunctionDef *def, llvm::Value *table);
llvm::Value *emit_table_no_metamethod(RaviFunctionDef *def, llvm::Value *table, TMS event);
llvm::Instruction *emit_load_reg_s(RaviFunctionDef *def, llvm::Value *rb);
// emit code to load pointer to int array
@ -992,6 +998,8 @@ public:
void emit_GETTABLE_I(RaviFunctionDef *def, int A, int B, int C, int pc);
void emit_finish_GETTABLE(RaviFunctionDef *def, llvm::Value *phi, llvm::Value *t, llvm::Value *ra, llvm::Value *rb, llvm::Value *rc);
void emit_SELF(RaviFunctionDef *def, int A, int B, int C, int pc);
void emit_SELF_S(RaviFunctionDef *def, int A, int B, int C, int pc, TString *key);

@ -1184,8 +1184,7 @@ function bug_index_event()
end
bug_index_event()
compile(bug_index_event)
--bug_index_event()
bug_index_event()
print 'Test 50 OK'

@ -990,8 +990,8 @@ newframe: /* reentry point when frame changes (call/return) */
*/
l_gettable_s: {
StkId rb = RB(i);
TValue *kv = k + INDEXK(GETARG_C(i));
TString *key = tsvalue(kv);
TValue *rc = k + INDEXK(GETARG_C(i));
TString *key = tsvalue(rc);
lua_assert(key->tt == LUA_TSHRSTR);
Table *h = hvalue(rb);
int position = lmod(key->hash, sizenode(h));
@ -1016,7 +1016,7 @@ newframe: /* reentry point when frame changes (call/return) */
setobj2s(L, ra, v);
}
else {
Protect(raviV_finishget(L, rb, kv, ra));
Protect(raviV_finishget(L, rb, rc, ra));
}
}
} break;

@ -526,6 +526,28 @@ RaviCodeGenerator::emit_load_ravi_arraylength(RaviFunctionDef *def,
return tt;
}
// Tests following:
// ((t) == NULL) || ((t)->flags & (1u<<e)) != 0)
llvm::Value *RaviCodeGenerator::emit_table_no_metamethod(RaviFunctionDef *def, llvm::Value *table, TMS event) {
// Is metatable NULL?
llvm::Value *metatable_ptr = emit_gep(def, "table.metatable_ptr", table, 0, 9);
llvm::Instruction *metatable = def->builder->CreateLoad(metatable_ptr, "table.metatable");
metatable->setMetadata(llvm::LLVMContext::MD_tbaa, def->types->tbaa_Table_metatable);
llvm::Value *null_constant = llvm::ConstantPointerNull::get(def->types->pTableT);
llvm::Value *is_null = def->builder->CreateICmpEQ(def->builder->CreatePtrToInt(null_constant, def->types->C_intptr_t),
def->builder->CreatePtrToInt(metatable, def->types->C_intptr_t));
// Is metatable->flags & (1<<event) set?
llvm::Value *flags_ptr = emit_gep(def, "table.flags_ptr", metatable, 0, 3);
llvm::Instruction *flags = def->builder->CreateLoad(flags_ptr, "table.flags");
flags->setMetadata(llvm::LLVMContext::MD_tbaa, def->types->tbaa_Table_flags);
llvm::Value *no_event = def->builder->CreateICmpNE(def->builder->CreateAnd(flags, llvm::ConstantInt::get(def->types->lu_byteT, 1u << event)),
llvm::ConstantInt::get(def->types->lu_byteT, 0));
llvm::Value *metaabsent = def->builder->CreateOr(is_null, no_event, "metatable.isnull.or.no.event");
return metaabsent;
}
// Store lua_Number or lua_Integer
llvm::Instruction *RaviCodeGenerator::emit_store_local_n(RaviFunctionDef *def,
llvm::Value *src,
@ -1129,6 +1151,9 @@ void RaviCodeGenerator::emit_extern_declarations(RaviFunctionDef *def) {
def->raviV_op_setupvaltF = def->raviF->addExternFunction(
def->types->raviV_op_setupvaltT,
reinterpret_cast<void *>(&raviV_op_setupvalt), "raviV_op_setupvalt");
def->raviV_finishgetF = def->raviF->addExternFunction(
def->types->raviV_finishgetT, reinterpret_cast<void *>(&raviV_finishget),
"raviV_finishget");
def->ravi_dump_valueF = def->raviF->addExternFunction(
def->types->ravi_dump_valueT, reinterpret_cast<void *>(&ravi_dump_value),

@ -188,39 +188,42 @@ void RaviCodeGenerator::emit_GETTABLE_I(RaviFunctionDef *def, int A, int B,
llvm::PHINode *phi = def->builder->CreatePHI(def->types->pTValueT, 2);
phi->addIncoming(value1, then_block);
phi->addIncoming(value2, else_block);
emit_finish_GETTABLE(def, phi, t, ra, rb, rc);
}
// We need to test if value is nil
// TODO we should really also check if
// table has metatable and if the metatable cached flags
// indicate no metamethod
void RaviCodeGenerator::emit_finish_GETTABLE(RaviFunctionDef *def, llvm::Value *phi, llvm::Value *t, llvm::Value *ra, llvm::Value *rb, llvm::Value *rc) {
// We need to test if value is not nil
// or table has no metatable
// or if the metatable cached flags indicate metamethod absent
llvm::Value *value_type = emit_load_type(def, phi);
llvm::Value *isnil = emit_is_value_of_type(def, value_type, LUA__TNIL);
llvm::BasicBlock *if_nil_block =
llvm::BasicBlock::Create(def->jitState->context(), "if.nil", def->f);
llvm::BasicBlock *if_not_nil_block =
llvm::BasicBlock::Create(def->jitState->context(), "if.not.nil");
llvm::BasicBlock *if_nil_end_block =
llvm::BasicBlock::Create(def->jitState->context(), "if.nil.end");
def->builder->CreateCondBr(isnil, if_nil_block, if_not_nil_block);
def->builder->SetInsertPoint(if_nil_block);
// If value is nil Lua requires that an index event be
// generated - so we fall back on slow path for that
CreateCall4(def->builder, def->luaV_gettableF, def->L, rb, rc, ra);
def->builder->CreateBr(if_nil_end_block);
llvm::Value *isnotnil = emit_is_not_value_of_type(def, value_type, LUA__TNIL);
llvm::Value *metamethod_absent = emit_table_no_metamethod(def, t, TM_INDEX);
llvm::Value *cond = def->builder->CreateOr(isnotnil, metamethod_absent);
llvm::BasicBlock *if_true_block =
llvm::BasicBlock::Create(def->jitState->context(), "if.not.nil.or.metamethod.absent", def->f);
llvm::BasicBlock *if_false_block =
llvm::BasicBlock::Create(def->jitState->context(), "if.try.metamethod");
llvm::BasicBlock *if_end_block =
llvm::BasicBlock::Create(def->jitState->context(), "if.end");
def->builder->CreateCondBr(cond, if_true_block, if_false_block);
def->builder->SetInsertPoint(if_true_block);
// Fast path when valus is not nil
// TODO or table has no metatable
// TODO or table's metatable flags indicate no index metamethod
def->f->getBasicBlockList().push_back(if_not_nil_block);
def->builder->SetInsertPoint(if_not_nil_block);
// Fast path
emit_assign(def, ra, phi);
def->builder->CreateBr(if_nil_end_block);
def->builder->CreateBr(if_end_block);
def->f->getBasicBlockList().push_back(if_false_block);
def->builder->SetInsertPoint(if_false_block);
// If value is nil Lua requires that an index event be
// generated - so we fall back on slow path for that
CreateCall4(def->builder, def->raviV_finishgetF, def->L, rb, rc, ra);
def->builder->CreateBr(if_end_block);
// Merge results from the two branches above
def->f->getBasicBlockList().push_back(if_nil_end_block);
def->builder->SetInsertPoint(if_nil_end_block);
def->f->getBasicBlockList().push_back(if_end_block);
def->builder->SetInsertPoint(if_end_block);
}
// R(A) := R(B)[RK(C)]
@ -317,37 +320,7 @@ void RaviCodeGenerator::emit_common_GETTABLE_S(RaviFunctionDef *def, int A, int
llvm::PHINode *phi = def->builder->CreatePHI(def->types->pTValueT, 2);
phi->addIncoming(value1, testok);
phi->addIncoming(value2, testfail);
// We need to test if value is nil
// TODO we should really also check if
// table has metatable and if the metatable cached flags
// indicate no metamethod
llvm::Value *value_type = emit_load_type(def, phi);
llvm::Value *isnil = emit_is_value_of_type(def, value_type, LUA__TNIL);
llvm::BasicBlock *if_nil_block =
llvm::BasicBlock::Create(def->jitState->context(), "if.nil", def->f);
llvm::BasicBlock *if_not_nil_block =
llvm::BasicBlock::Create(def->jitState->context(), "if.not.nil");
llvm::BasicBlock *if_nil_end_block =
llvm::BasicBlock::Create(def->jitState->context(), "if.nil.end");
def->builder->CreateCondBr(isnil, if_nil_block, if_not_nil_block);
def->builder->SetInsertPoint(if_nil_block);
// If value is nil Lua requires that an index event be
// generated - so we fall back on slow path for that
CreateCall4(def->builder, def->luaV_gettableF, def->L, rb, rc, ra);
def->builder->CreateBr(if_nil_end_block);
// Fast path
def->f->getBasicBlockList().push_back(if_not_nil_block);
def->builder->SetInsertPoint(if_not_nil_block);
emit_assign(def, ra, phi);
def->builder->CreateBr(if_nil_end_block);
// Merge results from the two branches above
def->f->getBasicBlockList().push_back(if_nil_end_block);
def->builder->SetInsertPoint(if_nil_end_block);
emit_finish_GETTABLE(def, phi, t, ra, rb, rc);
}
// R(A) := R(B)[RK(C)]

@ -781,6 +781,9 @@ LuaLLVMTypes::LuaLLVMTypes(llvm::LLVMContext &context) : mdbuilder(context) {
// void luaV_settable (lua_State *L, const TValue *t, TValue *key, StkId val)
luaV_settableT =
llvm::FunctionType::get(llvm::Type::getVoidTy(context), elements, false);
// void raviV_finishget(lua_State *L, const TValue *t, TValue *key, StkId val);
raviV_finishgetT =
llvm::FunctionType::get(llvm::Type::getVoidTy(context), elements, false);
// void luaT_trybinTM (lua_State *L, const TValue *p1, const TValue *p2,
// StkId res, TMS event);
@ -1223,16 +1226,18 @@ LuaLLVMTypes::LuaLLVMTypes(llvm::LLVMContext &context) : mdbuilder(context) {
nodes.push_back(std::pair<llvm::MDNode *, uint64_t>(tbaa_RaviArrayT, 32)); /* ravi_array */
tbaa_TableT = mdbuilder.createTBAAStructTypeNode("Table", nodes);
tbaa_RaviArray_dataT =
mdbuilder.createTBAAStructTagNode(tbaa_TableT, tbaa_pointerT, 32);
tbaa_RaviArray_lenT =
mdbuilder.createTBAAStructTagNode(tbaa_TableT, tbaa_intT, 36);
tbaa_RaviArray_typeT =
mdbuilder.createTBAAStructTagNode(tbaa_TableT, tbaa_charT, 44);
tbaa_Table_flags = mdbuilder.createTBAAStructTagNode(tbaa_TableT, tbaa_charT, 6);
tbaa_Table_lsizenode = mdbuilder.createTBAAStructTagNode(tbaa_TableT, tbaa_charT, 7);
tbaa_Table_sizearray = mdbuilder.createTBAAStructTagNode(tbaa_TableT, tbaa_pointerT, 8);
tbaa_Table_array = mdbuilder.createTBAAStructTagNode(tbaa_TableT, tbaa_pointerT, 12);
tbaa_Table_node = mdbuilder.createTBAAStructTagNode(tbaa_TableT, tbaa_pointerT, 16);
tbaa_Table_metatable = mdbuilder.createTBAAStructTagNode(tbaa_TableT, tbaa_pointerT, 24);
tbaa_RaviArray_dataT =
mdbuilder.createTBAAStructTagNode(tbaa_TableT, tbaa_pointerT, 32);
tbaa_RaviArray_lenT =
mdbuilder.createTBAAStructTagNode(tbaa_TableT, tbaa_intT, 36);
tbaa_RaviArray_typeT =
mdbuilder.createTBAAStructTagNode(tbaa_TableT, tbaa_charT, 44);
}
void LuaLLVMTypes::dump() {

Loading…
Cancel
Save