issue #99 LLVM JIT updates to support RaviArray breakout from Table structure

arrays
Dibyendu Majumdar 4 years ago
parent f3886accbe
commit a8ee5a60e1

@ -137,7 +137,7 @@ LUAI_FUNC RaviArray *raviH_new_number_array(lua_State *L, unsigned int len,
/* Returns the array length - note that this function will
* ignore any elements outside of the Ravi Array structure
*/
LUAI_FUNC int raviH_getn(RaviArray *t);
#define raviH_getn(t) ((t)->len - 1)
/* Type specific array set operation */
LUAI_FUNC void raviH_set_int(lua_State *L, RaviArray *t, lua_Unsigned key,
@ -161,9 +161,6 @@ LUAI_FUNC void raviH_set_float(lua_State *L, RaviArray *t, lua_Unsigned key,
LUAI_FUNC RaviArray *raviH_new_slice(lua_State *L, TValue *parent,
unsigned int start, unsigned int len);
/* Obtain parent array of the slice */
LUAI_FUNC const RaviArray *raviH_slice_parent(lua_State *L, TValue *slice);
/* Type specific array get operation */
#define raviH_get_int_inline(L, t, key, v) \
{ \

@ -179,6 +179,8 @@ struct LuaLLVMTypes {
llvm::StructType *UdataT;
llvm::StructType *RaviArrayT;
llvm::PointerType* pRaviArrayT;
llvm::PointerType* ppRaviArrayT;
llvm::StructType *TableT;
llvm::PointerType *pTableT;
llvm::PointerType *ppTableT;
@ -1036,6 +1038,9 @@ class RaviCodeGenerator {
// emit code to load the table value from register
llvm::Instruction *emit_load_reg_h(RaviFunctionDef *def, llvm::Value *ra);
// emit code to load the RaviArray value from register
llvm::Instruction* emit_load_reg_arr(RaviFunctionDef* def, llvm::Value* ra);
// Gets the size of the hash table
// This is the sizenode() macro in lobject.h
llvm::Value *emit_table_get_hashsize(RaviFunctionDef *def, llvm::Value *table);
@ -1097,7 +1102,8 @@ class RaviCodeGenerator {
llvm::Instruction *emit_load_type(RaviFunctionDef *def, llvm::Value *value);
// emit code to load the array type
llvm::Instruction *emit_load_ravi_arraytype(RaviFunctionDef *def, llvm::Value *value);
// Disabled as it is now broken
//llvm::Instruction *emit_load_ravi_arraytype(RaviFunctionDef *def, llvm::Value *value);
// emit code to load the array length
llvm::Instruction *emit_load_ravi_arraylength(RaviFunctionDef *def, llvm::Value *value);

@ -767,11 +767,6 @@ int luaH_getn (Table *t) {
else return unbound_search(t, j);
}
/* RAVI array specialization */
int raviH_getn(RaviArray *t) {
return t->len - 1;
}
/* resize array and initialize new elements if requested */
static int ravi_resize_array(lua_State *L, RaviArray *t, unsigned int new_size, int initialize) {
if (t->flags & RAVI_ARRAY_FIXEDSIZE || t->flags & RAVI_ARRAY_SLICE) {
@ -920,7 +915,8 @@ RaviArray *raviH_new_slice(lua_State *L, TValue *parent, unsigned int start,
L, "cannot create slice from dynamic integer[] or number[] array");
/* Create the slice table */
RaviArray *t = raviH_new(L, (orig->flags & RAVI_ARRAY_ISFLOAT) ? RAVI_TARRAYFLT : RAVI_TARRAYINT, 1);
/* Add a reference to the parent table */
/* Add a reference to the parent table. From GC perspective the slice is a white object
so we do not need a write barrier */
t->parent = orig;
/* Initialize */
if (orig->flags & RAVI_ARRAY_ISFLOAT) {
@ -936,18 +932,6 @@ RaviArray *raviH_new_slice(lua_State *L, TValue *parent, unsigned int start,
return t;
}
/* Obtain parent array of the slice */
const RaviArray *raviH_slice_parent(lua_State *L, TValue *slice) {
if (!ttisarray(slice))
luaG_runerror(L, "slice of integer[] or number[] expected");
RaviArray *orig = arrvalue(slice);
if ((orig->flags & RAVI_ARRAY_SLICE) == 0)
luaG_runerror(L, "slice of integer[] or number[] expected");
/* Get reference to the parent table */
//TODO do a liveness check here
return orig->parent;
}
#if defined(LUA_DEBUG)
Node *luaH_mainposition (const Table *t, const TValue *key) {

@ -345,6 +345,15 @@ llvm::Instruction *RaviCodeGenerator::emit_load_reg_h(RaviFunctionDef *def,
return h;
}
// emit code to load the RaviArray value from register (TValue)
llvm::Instruction* RaviCodeGenerator::emit_load_reg_arr(RaviFunctionDef* def,
llvm::Value* rb) {
llvm::Value* rb_h = def->builder->CreateBitCast(rb, def->types->ppRaviArrayT);
llvm::Instruction* h = def->builder->CreateLoad(rb_h);
h->setMetadata(llvm::LLVMContext::MD_tbaa, def->types->tbaa_TValue_hT);
return h;
}
// Gets the size of the hash table
// This is the sizenode() macro in lobject.h
llvm::Value *RaviCodeGenerator::emit_table_get_hashsize(RaviFunctionDef *def,
@ -370,7 +379,7 @@ llvm::Value *RaviCodeGenerator::emit_table_get_hashstr(RaviFunctionDef *def,
TString *key) {
#if RAVI_USE_NEWHASH
unsigned int hash = key->hash;
llvm::Value *hmask_ptr = emit_gep(def, "hmask", table, 0, 12);
llvm::Value *hmask_ptr = emit_gep(def, "hmask", table, 0, 11);
llvm::Instruction *hmask = def->builder->CreateLoad(hmask_ptr);
hmask->setMetadata(llvm::LLVMContext::MD_tbaa, def->types->tbaa_Table_hmask);
llvm::Value *offset = def->builder->CreateAnd(
@ -462,9 +471,10 @@ llvm::Instruction *RaviCodeGenerator::emit_load_reg_s(RaviFunctionDef *def,
return s;
}
/* Loads the data pointer as lua_Number[] from a RaviArray object */
llvm::Instruction *RaviCodeGenerator::emit_load_reg_h_floatarray(
RaviFunctionDef *def, llvm::Instruction *h) {
llvm::Value *data_ptr = emit_gep(def, "data_ptr", h, 0, 11, 0);
llvm::Value *data_ptr = emit_gep(def, "data_ptr", h, 0, 7);
llvm::Value *darray_ptr =
def->builder->CreateBitCast(data_ptr, def->types->pplua_NumberT);
llvm::Instruction *darray = def->builder->CreateLoad(darray_ptr);
@ -473,9 +483,10 @@ llvm::Instruction *RaviCodeGenerator::emit_load_reg_h_floatarray(
return darray;
}
/* Loads the data pointer as lua_Integer[] from a RaviArray object */
llvm::Instruction *RaviCodeGenerator::emit_load_reg_h_intarray(
RaviFunctionDef *def, llvm::Instruction *h) {
llvm::Value *data_ptr = emit_gep(def, "data_ptr", h, 0, 11, 0);
llvm::Value *data_ptr = emit_gep(def, "data_ptr", h, 0, 7);
llvm::Value *darray_ptr =
def->builder->CreateBitCast(data_ptr, def->types->pplua_IntegerT);
llvm::Instruction *darray = def->builder->CreateLoad(darray_ptr);
@ -580,17 +591,21 @@ llvm::Value *RaviCodeGenerator::emit_is_not_value_of_type_class(
llvm::ConstantInt::get(def->types->lua_LuaTypeT, lua_type), varname);
}
llvm::Instruction *RaviCodeGenerator::emit_load_ravi_arraytype(
RaviFunctionDef *def, llvm::Value *value) {
llvm::Value *tt_ptr = emit_gep(def, "raviarray.type_ptr", value, 0, 11, 3);
llvm::Instruction *tt = def->builder->CreateLoad(tt_ptr, "raviarray.type");
tt->setMetadata(llvm::LLVMContext::MD_tbaa, def->types->tbaa_RaviArray_typeT);
return tt;
}
/* This loads the RaviArray type value from the tt field maintained in the
GC part. However this tt is 8-bit value and needs to be converted to
the 16-bit value used in TValue objects */
//llvm::Instruction *RaviCodeGenerator::emit_load_ravi_arraytype(
// RaviFunctionDef *def, llvm::Value *value) {
// llvm::Value *tt_ptr = emit_gep(def, "raviarray.type_ptr", value, 0, 1);
// llvm::Instruction *tt = def->builder->CreateLoad(tt_ptr, "raviarray.type");
// // FIXME promote to 16 bit and set collectible bit
// tt->setMetadata(llvm::LLVMContext::MD_tbaa, def->types->tbaa_RaviArray_typeT);
// return tt;
//}
llvm::Instruction *RaviCodeGenerator::emit_load_ravi_arraylength(
RaviFunctionDef *def, llvm::Value *value) {
llvm::Value *tt_ptr = emit_gep(def, "raviarray.len_ptr", value, 0, 11, 1);
llvm::Value *tt_ptr = emit_gep(def, "raviarray.len_ptr", value, 0, 4);
llvm::Instruction *tt = def->builder->CreateLoad(tt_ptr, "raviarray.len");
tt->setMetadata(llvm::LLVMContext::MD_tbaa, def->types->tbaa_RaviArray_lenT);
return tt;

@ -477,8 +477,8 @@ void RaviCodeGenerator::emit_FARRAY_GET(RaviFunctionDef *def, int A, int B,
int pc) {
//#define raviH_get_float_inline(L, t, key, v)
//{ unsigned ukey = (unsigned)((key));
// lua_Number *data = (lua_Number *)t->ravi_array.data;
// if (ukey < t->ravi_array.len) {
// lua_Number *data = (lua_Number *)t->data;
// if (ukey < t->len) {
// setfltvalue(v, data[ukey]);
// }else
// luaG_runerror(L, "array out of bounds");
@ -496,7 +496,7 @@ void RaviCodeGenerator::emit_FARRAY_GET(RaviFunctionDef *def, int A, int B,
llvm::Value *rb = emit_gep_register(def, B);
llvm::Value *rc = emit_gep_register_or_constant(def, C);
llvm::Instruction *key = emit_load_reg_i(def, rc);
llvm::Instruction *t = emit_load_reg_h(def, rb);
llvm::Instruction *t = emit_load_reg_arr(def, rb);
llvm::Instruction *data = emit_load_reg_h_floatarray(def, t);
llvm::BasicBlock *then_block = nullptr;
llvm::BasicBlock *else_block = nullptr;
@ -541,8 +541,8 @@ void RaviCodeGenerator::emit_IARRAY_GET(RaviFunctionDef *def, int A, int B,
int pc) {
//#define raviH_get_int_inline(L, t, key, v)
//{ unsigned ukey = (unsigned)((key));
// lua_Integer *data = (lua_Integer *)t->ravi_array.data;
// if (ukey < t->ravi_array.len) {
// lua_Integer *data = (lua_Integer *)t->data;
// if (ukey < t->len) {
// setivalue(v, data[ukey]);
// } else
// luaG_runerror(L, "array out of bounds");
@ -560,7 +560,7 @@ void RaviCodeGenerator::emit_IARRAY_GET(RaviFunctionDef *def, int A, int B,
llvm::Value *rb = emit_gep_register(def, B);
llvm::Value *rc = emit_gep_register_or_constant(def, C);
llvm::Instruction *key = emit_load_reg_i(def, rc);
llvm::Instruction *t = emit_load_reg_h(def, rb);
llvm::Instruction *t = emit_load_reg_arr(def, rb);
llvm::Instruction *data = emit_load_reg_h_intarray(def, t);
llvm::BasicBlock *then_block = nullptr;
@ -605,8 +605,8 @@ void RaviCodeGenerator::emit_IARRAY_SET(RaviFunctionDef *def, int A, int B,
int C, bool known_int, int pc) {
//#define raviH_set_int_inline(L, t, key, value)
//{ unsigned ukey = (unsigned)((key));
// lua_Integer *data = (lua_Integer *)t->ravi_array.data;
// if (ukey < t->ravi_array.len) {
// lua_Integer *data = (lua_Integer *)t->data;
// if (ukey < t->len) {
// data[ukey] = value;
// } else
// raviH_set_int(L, t, ukey, value);
@ -628,7 +628,7 @@ void RaviCodeGenerator::emit_IARRAY_SET(RaviFunctionDef *def, int A, int B,
llvm::Instruction *key = emit_load_reg_i(def, rb);
llvm::Instruction *value =
known_int ? emit_load_reg_i(def, rc) : emit_tointeger(def, rc);
llvm::Instruction *t = emit_load_reg_h(def, ra);
llvm::Instruction *t = emit_load_reg_arr(def, ra);
llvm::Instruction *data = emit_load_reg_h_intarray(def, t);
llvm::Instruction *len = emit_load_ravi_arraylength(def, t);
llvm::Value *ulen =
@ -665,8 +665,8 @@ void RaviCodeGenerator::emit_FARRAY_SET(RaviFunctionDef *def, int A, int B,
int C, bool known_float, int pc) {
//#define raviH_set_float_inline(L, t, key, value)
//{ unsigned ukey = (unsigned)((key));
// lua_Number *data = (lua_Number *)t->ravi_array.data;
// if (ukey < t->ravi_array.len) {
// lua_Number *data = (lua_Number *)t->data;
// if (ukey < t->len) {
// data[ukey] = value;
// } else
// raviH_set_float(L, t, ukey, value);
@ -692,7 +692,7 @@ void RaviCodeGenerator::emit_FARRAY_SET(RaviFunctionDef *def, int A, int B,
llvm::Instruction *key = emit_load_reg_i(def, rb);
llvm::Instruction *value =
known_float ? emit_load_reg_n(def, rc) : emit_tofloat(def, rc);
llvm::Instruction *t = emit_load_reg_h(def, ra);
llvm::Instruction *t = emit_load_reg_arr(def, ra);
llvm::Instruction *data = emit_load_reg_h_floatarray(def, t);
llvm::Instruction *len = emit_load_ravi_arraylength(def, t);
llvm::Value *ulen =

@ -446,22 +446,32 @@ LuaLLVMTypes::LuaLLVMTypes(llvm::LLVMContext &context) : mdbuilder(context) {
NodeT->setBody(elements);
pNodeT = llvm::PointerType::get(NodeT, 0);
// typedef struct RaviArray {
// char *data;
// unsigned int len; /* RAVI len specialization */
// unsigned int size; /* amount of memory allocated */
// lu_byte array_type; /* RAVI specialization */
// lu_byte array_modifier; /* Flags that affect how the array is handled */
//} RaviArray;
//struct RaviArray {
// CommonHeader;
// lu_byte flags;
// unsigned int len; /* array length, holds real length which is 1+Lua length */
// unsigned int size; /* size of data, in arrays (not slices) if == RAVI_ARRAY_MAX_INLINE then it means we are using inline storage */
// union {
// lua_Number numarray[RAVI_ARRAY_MAX_INLINE];
// lua_Integer intarray[RAVI_ARRAY_MAX_INLINE];
// struct RaviArray* parent; /* Only set if this is a slice, parent must be a slice or a fixed length array */
// };
// char* data; /* Pointer to data. In case of slices points in parent->data. In case of arrays this may point to heap or internal data */
// struct Table* metatable;
//}
RaviArrayT = llvm::StructType::create(context, "struct.RaviArray");
elements.clear();
elements.push_back(C_pcharT);
elements.push_back(C_intT);
elements.push_back(C_intT);
elements.push_back(lu_byteT);
elements.push_back(lu_byteT);
addCommonGCHeader(elements);
elements.push_back(lu_byteT); /* flags */
elements.push_back(C_intT); /* len - 4 */
elements.push_back(C_intT); /* size */
elements.push_back(llvm::ArrayType::get(lua_NumberT, RAVI_ARRAY_MAX_INLINE)); /* numarray: Assumption: lua_Number and lua_Integer have same size */
elements.push_back(C_pcharT); /* data - 7 */
elements.push_back(pTableT); /* metatable*/
RaviArrayT->setBody(elements);
pRaviArrayT = llvm::PointerType::get(RaviArrayT, 0);
ppRaviArrayT = llvm::PointerType::get(pRaviArrayT, 0);
// typedef struct Table {
// CommonHeader;
@ -473,7 +483,6 @@ LuaLLVMTypes::LuaLLVMTypes(llvm::LLVMContext &context) : mdbuilder(context) {
// Node *lastfree; /* any free position is before this position */
// struct Table *metatable;
// GCObject *gclist;
// RaviArray ravi_array;
// unsigned int hmask; /* Hash part mask (size of hash part - 1) */
//} Table;
elements.clear();
@ -486,7 +495,6 @@ LuaLLVMTypes::LuaLLVMTypes(llvm::LLVMContext &context) : mdbuilder(context) {
elements.push_back(pNodeT); /* lastfree */
elements.push_back(pTableT); /* metatable */
elements.push_back(pGCObjectT); /* gclist */
elements.push_back(RaviArrayT); /* RaviArray */
#if RAVI_USE_NEWHASH
elements.push_back(C_intT); /* hmask */
#endif
@ -999,21 +1007,21 @@ LuaLLVMTypes::LuaLLVMTypes(llvm::LLVMContext &context) : mdbuilder(context) {
elements.push_back(pTStringT);
luaH_getstrT = llvm::FunctionType::get(pTValueT, elements, false);
// void raviH_set_int(lua_State *L, Table *t, lua_Unsigned key, lua_Integer
// void raviH_set_int(lua_State *L, RaviArray *t, lua_Unsigned key, lua_Integer
// value);
elements.clear();
elements.push_back(plua_StateT);
elements.push_back(pTableT);
elements.push_back(pRaviArrayT);
elements.push_back(lua_UnsignedT);
elements.push_back(lua_IntegerT);
raviH_set_intT =
llvm::FunctionType::get(llvm::Type::getVoidTy(context), elements, false);
// void raviH_set_float(lua_State *L, Table *t, lua_Unsigned key, lua_Number
// void raviH_set_float(lua_State *L, RaviArray *t, lua_Unsigned key, lua_Number
// value);
elements.clear();
elements.push_back(plua_StateT);
elements.push_back(pTableT);
elements.push_back(pRaviArrayT);
elements.push_back(lua_UnsignedT);
elements.push_back(lua_NumberT);
raviH_set_floatT =
@ -1295,16 +1303,17 @@ LuaLLVMTypes::LuaLLVMTypes(llvm::LLVMContext &context) : mdbuilder(context) {
mdbuilder.createTBAAStructTagNode(tbaa_UpValT, tbaa_pointerT, 0);
// RaviArray
// !{!"RaviArray", !5, i64 0, !6, i64 4, !6, i64 5, !6, i64 6, !11, i64 8, !11, i64 12, !6, i64 16, !5, i64 40, !5, i64 44}
nodes.clear();
nodes.push_back(
std::pair<llvm::MDNode *, uint64_t>(tbaa_pointerT, 0)); /* data */
nodes.push_back(std::pair<llvm::MDNode *, uint64_t>(tbaa_intT, 4)); /* len */
nodes.push_back(std::pair<llvm::MDNode *, uint64_t>(tbaa_intT, 8)); /* size */
nodes.push_back(
std::pair<llvm::MDNode *, uint64_t>(tbaa_charT, 12)); /* type */
nodes.push_back(
std::pair<llvm::MDNode *, uint64_t>(tbaa_charT, 13)); /* modifiers */
nodes.push_back(std::pair<llvm::MDNode *, uint64_t>(tbaa_pointerT, 0)); /* next */
nodes.push_back(std::pair<llvm::MDNode *, uint64_t>(tbaa_charT, 4)); /* tt */
nodes.push_back(std::pair<llvm::MDNode *, uint64_t>(tbaa_charT, 5)); /* marked */
nodes.push_back(std::pair<llvm::MDNode *, uint64_t>(tbaa_charT, 6)); /* flags */
nodes.push_back(std::pair<llvm::MDNode *, uint64_t>(tbaa_intT, 8)); /* len */
nodes.push_back(std::pair<llvm::MDNode *, uint64_t>(tbaa_intT, 12)); /* size */
nodes.push_back(std::pair<llvm::MDNode *, uint64_t>(tbaa_charT, 16)); /* numarray */
nodes.push_back(std::pair<llvm::MDNode *, uint64_t>(tbaa_pointerT, 40)); /* data */
nodes.push_back(std::pair<llvm::MDNode *, uint64_t>(tbaa_pointerT, 44)); /* metatable */
tbaa_RaviArrayT = mdbuilder.createTBAAStructTypeNode("RaviArray", nodes);
// Table TBAA struct type
@ -1330,11 +1339,9 @@ LuaLLVMTypes::LuaLLVMTypes(llvm::LLVMContext &context) : mdbuilder(context) {
std::pair<llvm::MDNode *, uint64_t>(tbaa_pointerT, 24)); /* metatable */
nodes.push_back(
std::pair<llvm::MDNode *, uint64_t>(tbaa_pointerT, 28)); /* gclist */
nodes.push_back(std::pair<llvm::MDNode *, uint64_t>(tbaa_RaviArrayT,
32)); /* ravi_array */
#if RAVI_USE_NEWHASH
nodes.push_back(
std::pair<llvm::MDNode *, uint64_t>(tbaa_intT, 48)); /* hmask */
std::pair<llvm::MDNode *, uint64_t>(tbaa_intT, 32)); /* hmask */
#endif
tbaa_TableT = mdbuilder.createTBAAStructTypeNode("Table", nodes);
@ -1350,16 +1357,17 @@ LuaLLVMTypes::LuaLLVMTypes(llvm::LLVMContext &context) : mdbuilder(context) {
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);
#if RAVI_USE_NEWHASH
tbaa_Table_hmask =
mdbuilder.createTBAAStructTagNode(tbaa_TableT, tbaa_intT, 48);
mdbuilder.createTBAAStructTagNode(tbaa_TableT, tbaa_intT, 32);
#endif
tbaa_RaviArray_dataT =
mdbuilder.createTBAAStructTagNode(tbaa_RaviArrayT, tbaa_pointerT, 40);
tbaa_RaviArray_lenT =
mdbuilder.createTBAAStructTagNode(tbaa_RaviArrayT, tbaa_intT, 8);
tbaa_RaviArray_typeT =
mdbuilder.createTBAAStructTagNode(tbaa_RaviArrayT, tbaa_charT, 4);
}
void LuaLLVMTypes::dump() {

Loading…
Cancel
Save