Use a giant packed struct working for type info table

This commit is contained in:
gingerBill
2023-09-22 15:32:32 +01:00
parent 082324d7b9
commit 61f39ae0a0
3 changed files with 107 additions and 64 deletions
+1
View File
@@ -254,6 +254,7 @@ Typeid_Kind :: enum u8 {
Relative_Pointer, Relative_Pointer,
Relative_Multi_Pointer, Relative_Multi_Pointer,
Matrix, Matrix,
Soa_Pointer,
} }
#assert(len(Typeid_Kind) < 32) #assert(len(Typeid_Kind) < 32)
+23 -2
View File
@@ -1025,8 +1025,10 @@ gb_internal lbProcedure *lb_create_startup_type_info(lbModule *m) {
LLVMSetLinkage(p->value, LLVMInternalLinkage); LLVMSetLinkage(p->value, LLVMInternalLinkage);
lb_add_attribute_to_proc(m, p->value, "nounwind"); lb_add_attribute_to_proc(m, p->value, "nounwind");
lb_add_attribute_to_proc(m, p->value, "optnone"); if (!LB_USE_GIANT_PACKED_STRUCT) {
lb_add_attribute_to_proc(m, p->value, "noinline"); lb_add_attribute_to_proc(m, p->value, "optnone");
lb_add_attribute_to_proc(m, p->value, "noinline");
}
lb_begin_procedure_body(p); lb_begin_procedure_body(p);
@@ -2243,6 +2245,10 @@ gb_internal bool lb_generate_code(lbGenerator *gen) {
lb_global_type_info_data_entity = alloc_entity_variable(nullptr, make_token_ident(LB_TYPE_INFO_DATA_NAME), t, EntityState_Resolved); lb_global_type_info_data_entity = alloc_entity_variable(nullptr, make_token_ident(LB_TYPE_INFO_DATA_NAME), t, EntityState_Resolved);
lb_add_entity(m, lb_global_type_info_data_entity, value); lb_add_entity(m, lb_global_type_info_data_entity, value);
if (LB_USE_GIANT_PACKED_STRUCT) {
lb_make_global_private_const(g);
}
} }
{ // Type info member buffer { // Type info member buffer
// NOTE(bill): Removes need for heap allocation by making it global memory // NOTE(bill): Removes need for heap allocation by making it global memory
@@ -2274,6 +2280,9 @@ gb_internal bool lb_generate_code(lbGenerator *gen) {
LLVMValueRef g = LLVMAddGlobal(m->mod, lb_type(m, t), name); LLVMValueRef g = LLVMAddGlobal(m->mod, lb_type(m, t), name);
LLVMSetInitializer(g, LLVMConstNull(lb_type(m, t))); LLVMSetInitializer(g, LLVMConstNull(lb_type(m, t)));
LLVMSetLinkage(g, LLVMInternalLinkage); LLVMSetLinkage(g, LLVMInternalLinkage);
if (LB_USE_GIANT_PACKED_STRUCT) {
lb_make_global_private_const(g);
}
lb_global_type_info_member_types = lb_addr({g, alloc_type_pointer(t)}); lb_global_type_info_member_types = lb_addr({g, alloc_type_pointer(t)});
} }
@@ -2283,6 +2292,9 @@ gb_internal bool lb_generate_code(lbGenerator *gen) {
LLVMValueRef g = LLVMAddGlobal(m->mod, lb_type(m, t), name); LLVMValueRef g = LLVMAddGlobal(m->mod, lb_type(m, t), name);
LLVMSetInitializer(g, LLVMConstNull(lb_type(m, t))); LLVMSetInitializer(g, LLVMConstNull(lb_type(m, t)));
LLVMSetLinkage(g, LLVMInternalLinkage); LLVMSetLinkage(g, LLVMInternalLinkage);
if (LB_USE_GIANT_PACKED_STRUCT) {
lb_make_global_private_const(g);
}
lb_global_type_info_member_names = lb_addr({g, alloc_type_pointer(t)}); lb_global_type_info_member_names = lb_addr({g, alloc_type_pointer(t)});
} }
{ {
@@ -2291,6 +2303,9 @@ gb_internal bool lb_generate_code(lbGenerator *gen) {
LLVMValueRef g = LLVMAddGlobal(m->mod, lb_type(m, t), name); LLVMValueRef g = LLVMAddGlobal(m->mod, lb_type(m, t), name);
LLVMSetInitializer(g, LLVMConstNull(lb_type(m, t))); LLVMSetInitializer(g, LLVMConstNull(lb_type(m, t)));
LLVMSetLinkage(g, LLVMInternalLinkage); LLVMSetLinkage(g, LLVMInternalLinkage);
if (LB_USE_GIANT_PACKED_STRUCT) {
lb_make_global_private_const(g);
}
lb_global_type_info_member_offsets = lb_addr({g, alloc_type_pointer(t)}); lb_global_type_info_member_offsets = lb_addr({g, alloc_type_pointer(t)});
} }
@@ -2300,6 +2315,9 @@ gb_internal bool lb_generate_code(lbGenerator *gen) {
LLVMValueRef g = LLVMAddGlobal(m->mod, lb_type(m, t), name); LLVMValueRef g = LLVMAddGlobal(m->mod, lb_type(m, t), name);
LLVMSetInitializer(g, LLVMConstNull(lb_type(m, t))); LLVMSetInitializer(g, LLVMConstNull(lb_type(m, t)));
LLVMSetLinkage(g, LLVMInternalLinkage); LLVMSetLinkage(g, LLVMInternalLinkage);
if (LB_USE_GIANT_PACKED_STRUCT) {
lb_make_global_private_const(g);
}
lb_global_type_info_member_usings = lb_addr({g, alloc_type_pointer(t)}); lb_global_type_info_member_usings = lb_addr({g, alloc_type_pointer(t)});
} }
@@ -2309,6 +2327,9 @@ gb_internal bool lb_generate_code(lbGenerator *gen) {
LLVMValueRef g = LLVMAddGlobal(m->mod, lb_type(m, t), name); LLVMValueRef g = LLVMAddGlobal(m->mod, lb_type(m, t), name);
LLVMSetInitializer(g, LLVMConstNull(lb_type(m, t))); LLVMSetInitializer(g, LLVMConstNull(lb_type(m, t)));
LLVMSetLinkage(g, LLVMInternalLinkage); LLVMSetLinkage(g, LLVMInternalLinkage);
if (LB_USE_GIANT_PACKED_STRUCT) {
lb_make_global_private_const(g);
}
lb_global_type_info_member_tags = lb_addr({g, alloc_type_pointer(t)}); lb_global_type_info_member_tags = lb_addr({g, alloc_type_pointer(t)});
} }
} }
+83 -62
View File
@@ -139,38 +139,43 @@ gb_internal lbValue lb_const_array_epi(lbModule *m, lbValue value, isize index)
} }
gb_internal lbValue lb_type_info_member_types_offset(lbModule *m, isize count) { gb_internal lbValue lb_type_info_member_types_offset(lbModule *m, isize count, isize *offset_=nullptr) {
GB_ASSERT(m == &m->gen->default_module); GB_ASSERT(m == &m->gen->default_module);
if (offset_) *offset_ = lb_global_type_info_member_types_index;
lbValue offset = lb_const_array_epi(m, lb_global_type_info_member_types.addr, lb_global_type_info_member_types_index); lbValue offset = lb_const_array_epi(m, lb_global_type_info_member_types.addr, lb_global_type_info_member_types_index);
lb_global_type_info_member_types_index += cast(i32)count; lb_global_type_info_member_types_index += cast(i32)count;
return offset; return offset;
} }
gb_internal lbValue lb_type_info_member_names_offset(lbModule *m, isize count) { gb_internal lbValue lb_type_info_member_names_offset(lbModule *m, isize count, isize *offset_=nullptr) {
GB_ASSERT(m == &m->gen->default_module); GB_ASSERT(m == &m->gen->default_module);
if (offset_) *offset_ = lb_global_type_info_member_names_index;
lbValue offset = lb_const_array_epi(m, lb_global_type_info_member_names.addr, lb_global_type_info_member_names_index); lbValue offset = lb_const_array_epi(m, lb_global_type_info_member_names.addr, lb_global_type_info_member_names_index);
lb_global_type_info_member_names_index += cast(i32)count; lb_global_type_info_member_names_index += cast(i32)count;
return offset; return offset;
} }
gb_internal lbValue lb_type_info_member_offsets_offset(lbModule *m, isize count) { gb_internal lbValue lb_type_info_member_offsets_offset(lbModule *m, isize count, isize *offset_=nullptr) {
GB_ASSERT(m == &m->gen->default_module); GB_ASSERT(m == &m->gen->default_module);
if (offset_) *offset_ = lb_global_type_info_member_offsets_index;
lbValue offset = lb_const_array_epi(m, lb_global_type_info_member_offsets.addr, lb_global_type_info_member_offsets_index); lbValue offset = lb_const_array_epi(m, lb_global_type_info_member_offsets.addr, lb_global_type_info_member_offsets_index);
lb_global_type_info_member_offsets_index += cast(i32)count; lb_global_type_info_member_offsets_index += cast(i32)count;
return offset; return offset;
} }
gb_internal lbValue lb_type_info_member_usings_offset(lbModule *m, isize count) { gb_internal lbValue lb_type_info_member_usings_offset(lbModule *m, isize count, isize *offset_=nullptr) {
GB_ASSERT(m == &m->gen->default_module); GB_ASSERT(m == &m->gen->default_module);
if (offset_) *offset_ = lb_global_type_info_member_usings_index;
lbValue offset = lb_const_array_epi(m, lb_global_type_info_member_usings.addr, lb_global_type_info_member_usings_index); lbValue offset = lb_const_array_epi(m, lb_global_type_info_member_usings.addr, lb_global_type_info_member_usings_index);
lb_global_type_info_member_usings_index += cast(i32)count; lb_global_type_info_member_usings_index += cast(i32)count;
return offset; return offset;
} }
gb_internal lbValue lb_type_info_member_tags_offset(lbModule *m, isize count) { gb_internal lbValue lb_type_info_member_tags_offset(lbModule *m, isize count, isize *offset_=nullptr) {
GB_ASSERT(m == &m->gen->default_module); GB_ASSERT(m == &m->gen->default_module);
if (offset_) *offset_ = lb_global_type_info_member_tags_index;
lbValue offset = lb_const_array_epi(m, lb_global_type_info_member_tags.addr, lb_global_type_info_member_tags_index); lbValue offset = lb_const_array_epi(m, lb_global_type_info_member_tags.addr, lb_global_type_info_member_tags_index);
lb_global_type_info_member_tags_index += cast(i32)count; lb_global_type_info_member_tags_index += cast(i32)count;
return offset; return offset;
} }
enum {LB_USE_GIANT_PACKED_STRUCT = false}; enum {LB_USE_GIANT_PACKED_STRUCT = true};
gb_internal LLVMTypeRef lb_setup_type_info_data_internal_type(lbModule *m, isize max_type_info_count) { gb_internal LLVMTypeRef lb_setup_type_info_data_internal_type(lbModule *m, isize max_type_info_count) {
if (!LB_USE_GIANT_PACKED_STRUCT) { if (!LB_USE_GIANT_PACKED_STRUCT) {
@@ -292,10 +297,30 @@ gb_internal void lb_setup_type_info_data_giant_packed_struct(lbModule *m, i64 gl
giant_const_values[0] = LLVMConstNull(LLVMStructGetTypeAtIndex(giant_struct_type, 0)); giant_const_values[0] = LLVMConstNull(LLVMStructGetTypeAtIndex(giant_struct_type, 0));
LLVMValueRef *small_const_values = gb_alloc_array(heap_allocator(), LLVMValueRef, 6); LLVMValueRef *small_const_values = gb_alloc_array(heap_allocator(), LLVMValueRef, 6);
defer (gb_free(heap_allocator(), small_const_values)); defer (gb_free(heap_allocator(), small_const_values));
#define type_info_allocate_values(name) \
LLVMValueRef *name##_values = gb_alloc_array(heap_allocator(), LLVMValueRef, type_deref(name.addr.type)->Array.count); \
defer (gb_free(heap_allocator(), name##_values)); \
defer ({ \
Type *at = type_deref(name.addr.type); \
LLVMTypeRef elem = lb_type(m, at->Array.elem); \
for (i64 i = 0; i < at->Array.count; i++) { \
if ((name##_values)[i] == nullptr) { \
(name##_values)[i] = LLVMConstNull(elem); \
} \
} \
LLVMSetInitializer(name.addr.value, LLVMConstArray2(elem, name##_values, at->Array.count)); \
})
type_info_allocate_values(lb_global_type_info_member_types);
type_info_allocate_values(lb_global_type_info_member_names);
type_info_allocate_values(lb_global_type_info_member_offsets);
type_info_allocate_values(lb_global_type_info_member_usings);
type_info_allocate_values(lb_global_type_info_member_tags);
for_array(type_info_type_index, info->type_info_types) { for_array(type_info_type_index, info->type_info_types) {
Type *t = info->type_info_types[type_info_type_index]; Type *t = info->type_info_types[type_info_type_index];
if (t == nullptr || t == t_invalid) { if (t == nullptr || t == t_invalid) {
@@ -627,37 +652,35 @@ gb_internal void lb_setup_type_info_data_giant_packed_struct(lbModule *m, i64 gl
} }
case Type_Tuple: { case Type_Tuple: {
tag_type = t_type_info_parameters; tag_type = t_type_info_parameters;
// TODO(bill) i64 type_offset = 0;
// lbValue memory_types = lb_type_info_member_types_offset(m, t->Tuple.variables.count); i64 name_offset = 0;
// lbValue memory_names = lb_type_info_member_names_offset(m, t->Tuple.variables.count); lbValue memory_types = lb_type_info_member_types_offset(m, t->Tuple.variables.count, &type_offset);
lbValue memory_names = lb_type_info_member_names_offset(m, t->Tuple.variables.count, &name_offset);
for_array(i, t->Tuple.variables) {
// NOTE(bill): offset is not used for tuples
Entity *f = t->Tuple.variables[i];
// for_array(i, t->Tuple.variables) { lbValue index = lb_const_int(m, t_int, i);
// // NOTE(bill): offset is not used for tuples lbValue type_info = lb_const_ptr_offset(m, memory_types, index);
// Entity *f = t->Tuple.variables[i];
// lbValue index = lb_const_int(m, t_int, i); lb_global_type_info_member_types_values[type_offset+i] = lb_type_info(m, f->type).value;
// lbValue type_info = lb_const_ptr_offset(m, memory_types, index); if (f->token.string.len > 0) {
lb_global_type_info_member_names_values[name_offset+i] = lb_const_string(m, f->token.string).value;
}
}
// // TODO(bill): Make this constant if possible, 'lb_const_store' does not work lbValue count = lb_const_int(m, t_int, t->Tuple.variables.count);
// lb_emit_store(p, type_info, lb_type_info(m, f->type));
// if (f->token.string.len > 0) {
// lbValue name = lb_const_ptr_offset(m, memory_names, index);
// lb_emit_store(p, name, lb_const_string(m, f->token.string));
// }
// }
// lbValue count = lb_const_int(m, t_int, t->Tuple.variables.count); LLVMValueRef types_slice = llvm_const_slice(m, memory_types, count);
LLVMValueRef names_slice = llvm_const_slice(m, memory_names, count);
// LLVMValueRef types_slice = llvm_const_slice(m, memory_types, count); LLVMValueRef vals[2] = {
// LLVMValueRef names_slice = llvm_const_slice(m, memory_names, count); types_slice,
names_slice,
};
// LLVMValueRef vals[2] = { variant_value = llvm_const_named_struct(m, tag_type, vals, gb_count_of(vals));
// types_slice,
// names_slice,
// };
// variant_value = llvm_const_named_struct(m, tag_type, vals, gb_count_of(vals));
break; break;
} }
@@ -717,16 +740,14 @@ gb_internal void lb_setup_type_info_data_giant_packed_struct(lbModule *m, i64 gl
LLVMValueRef vals[7] = {}; LLVMValueRef vals[7] = {};
isize variant_count = gb_max(0, t->Union.variants.count); isize variant_count = gb_max(0, t->Union.variants.count);
lbValue memory_types = lb_type_info_member_types_offset(m, variant_count); i64 variant_offset = 0;
lbValue memory_types = lb_type_info_member_types_offset(m, variant_count, &variant_offset);
for (isize variant_index = 0; variant_index < variant_count; variant_index++) { for (isize variant_index = 0; variant_index < variant_count; variant_index++) {
// TODO(bill) Type *vt = t->Union.variants[variant_index];
// Type *vt = t->Union.variants[variant_index]; lbValue tip = lb_type_info(m, vt);
// lbValue tip = lb_type_info(m, vt);
// lbValue index = lb_const_int(m, t_int, variant_index); lb_global_type_info_member_types_values[variant_offset+variant_index] = lb_type_info(m, vt).value;
// lbValue type_info = lb_const_ptr_offset(m, memory_types, index);
// lb_emit_store(p, type_info, lb_type_info(m, vt));
} }
lbValue count = lb_const_int(m, t_int, variant_count); lbValue count = lb_const_int(m, t_int, variant_count);
@@ -796,11 +817,17 @@ gb_internal void lb_setup_type_info_data_giant_packed_struct(lbModule *m, i64 gl
isize count = t->Struct.fields.count; isize count = t->Struct.fields.count;
if (count > 0) { if (count > 0) {
lbValue memory_types = lb_type_info_member_types_offset (m, count); i64 types_offset = 0;
lbValue memory_names = lb_type_info_member_names_offset (m, count); i64 names_offset = 0;
lbValue memory_offsets = lb_type_info_member_offsets_offset(m, count); i64 offsets_offset = 0;
lbValue memory_usings = lb_type_info_member_usings_offset (m, count); i64 usings_offset = 0;
lbValue memory_tags = lb_type_info_member_tags_offset (m, count); i64 tags_offset = 0;
lbValue memory_types = lb_type_info_member_types_offset (m, count, &types_offset);
lbValue memory_names = lb_type_info_member_names_offset (m, count, &names_offset);
lbValue memory_offsets = lb_type_info_member_offsets_offset(m, count, &offsets_offset);
lbValue memory_usings = lb_type_info_member_usings_offset (m, count, &usings_offset);
lbValue memory_tags = lb_type_info_member_tags_offset (m, count, &tags_offset);
type_set_offsets(t); // NOTE(bill): Just incase the offsets have not been set yet type_set_offsets(t); // NOTE(bill): Just incase the offsets have not been set yet
for (isize source_index = 0; source_index < count; source_index++) { for (isize source_index = 0; source_index < count; source_index++) {
@@ -814,27 +841,21 @@ gb_internal void lb_setup_type_info_data_giant_packed_struct(lbModule *m, i64 gl
} }
GB_ASSERT(f->kind == Entity_Variable && f->flags & EntityFlag_Field); GB_ASSERT(f->kind == Entity_Variable && f->flags & EntityFlag_Field);
lbValue index = lb_const_int(m, t_int, source_index);
lbValue type_info = lb_const_ptr_offset(m, memory_types, index);
lbValue offset = lb_const_ptr_offset(m, memory_offsets, index);
lbValue is_using = lb_const_ptr_offset(m, memory_usings, index);
// TODO(bill) lb_global_type_info_member_types_values[types_offset+source_index] = lb_type_info(m, f->type).value;
// lb_emit_store(p, type_info, lb_type_info(m, f->type)); lb_global_type_info_member_offsets_values[offsets_offset+source_index] = lb_const_int(m, t_uintptr, foffset).value;
// if (f->token.string.len > 0) { lb_global_type_info_member_usings_values[usings_offset+source_index] = lb_const_bool(m, t_bool, (f->flags&EntityFlag_Using) != 0).value;
// lbValue name = lb_emit_ptr_offset(p, memory_names, index);
// lb_emit_store(p, name, lb_const_string(m, f->token.string));
// }
// lb_emit_store(p, offset, lb_const_int(m, t_uintptr, foffset));
// lb_emit_store(p, is_using, lb_const_bool(m, t_bool, (f->flags&EntityFlag_Using) != 0));
// if (t->Struct.tags != nullptr) { if (f->token.string.len > 0) {
// String tag_string = t->Struct.tags[source_index]; lb_global_type_info_member_names_values[names_offset+source_index] = lb_const_string(m, f->token.string).value;
// if (tag_string.len > 0) { }
// lbValue tag_ptr = lb_emit_ptr_offset(p, memory_tags, index);
// lb_emit_store(p, tag_ptr, lb_const_string(m, tag_string)); if (t->Struct.tags != nullptr) {
// } String tag_string = t->Struct.tags[source_index];
// } if (tag_string.len > 0) {
lb_global_type_info_member_tags_values[tags_offset+source_index] = lb_const_string(m, tag_string).value;
}
}
} }