From 61f39ae0a09429610d78961fa1e86cac071dd08c Mon Sep 17 00:00:00 2001 From: gingerBill Date: Fri, 22 Sep 2023 15:32:32 +0100 Subject: [PATCH] Use a giant packed struct working for type info table --- core/runtime/core.odin | 1 + src/llvm_backend.cpp | 25 ++++++- src/llvm_backend_type.cpp | 145 ++++++++++++++++++++++---------------- 3 files changed, 107 insertions(+), 64 deletions(-) diff --git a/core/runtime/core.odin b/core/runtime/core.odin index 44717f8d0..8abe9938d 100644 --- a/core/runtime/core.odin +++ b/core/runtime/core.odin @@ -254,6 +254,7 @@ Typeid_Kind :: enum u8 { Relative_Pointer, Relative_Multi_Pointer, Matrix, + Soa_Pointer, } #assert(len(Typeid_Kind) < 32) diff --git a/src/llvm_backend.cpp b/src/llvm_backend.cpp index db5af0647..8f838ea31 100644 --- a/src/llvm_backend.cpp +++ b/src/llvm_backend.cpp @@ -1025,8 +1025,10 @@ gb_internal lbProcedure *lb_create_startup_type_info(lbModule *m) { LLVMSetLinkage(p->value, LLVMInternalLinkage); lb_add_attribute_to_proc(m, p->value, "nounwind"); - lb_add_attribute_to_proc(m, p->value, "optnone"); - lb_add_attribute_to_proc(m, p->value, "noinline"); + if (!LB_USE_GIANT_PACKED_STRUCT) { + lb_add_attribute_to_proc(m, p->value, "optnone"); + lb_add_attribute_to_proc(m, p->value, "noinline"); + } 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_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 // 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); LLVMSetInitializer(g, LLVMConstNull(lb_type(m, t))); 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)}); } @@ -2283,6 +2292,9 @@ gb_internal bool lb_generate_code(lbGenerator *gen) { LLVMValueRef g = LLVMAddGlobal(m->mod, lb_type(m, t), name); LLVMSetInitializer(g, LLVMConstNull(lb_type(m, t))); 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)}); } { @@ -2291,6 +2303,9 @@ gb_internal bool lb_generate_code(lbGenerator *gen) { LLVMValueRef g = LLVMAddGlobal(m->mod, lb_type(m, t), name); LLVMSetInitializer(g, LLVMConstNull(lb_type(m, t))); 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)}); } @@ -2300,6 +2315,9 @@ gb_internal bool lb_generate_code(lbGenerator *gen) { LLVMValueRef g = LLVMAddGlobal(m->mod, lb_type(m, t), name); LLVMSetInitializer(g, LLVMConstNull(lb_type(m, t))); 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)}); } @@ -2309,6 +2327,9 @@ gb_internal bool lb_generate_code(lbGenerator *gen) { LLVMValueRef g = LLVMAddGlobal(m->mod, lb_type(m, t), name); LLVMSetInitializer(g, LLVMConstNull(lb_type(m, t))); 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)}); } } diff --git a/src/llvm_backend_type.cpp b/src/llvm_backend_type.cpp index 3654e8005..954e80881 100644 --- a/src/llvm_backend_type.cpp +++ b/src/llvm_backend_type.cpp @@ -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); + 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); lb_global_type_info_member_types_index += cast(i32)count; 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); + 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); lb_global_type_info_member_names_index += cast(i32)count; 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); + 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); lb_global_type_info_member_offsets_index += cast(i32)count; 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); + 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); lb_global_type_info_member_usings_index += cast(i32)count; 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); + 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); lb_global_type_info_member_tags_index += cast(i32)count; 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) { 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)); - LLVMValueRef *small_const_values = gb_alloc_array(heap_allocator(), LLVMValueRef, 6); 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) { Type *t = info->type_info_types[type_info_type_index]; 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: { tag_type = t_type_info_parameters; - // TODO(bill) - // lbValue memory_types = lb_type_info_member_types_offset(m, t->Tuple.variables.count); - // lbValue memory_names = lb_type_info_member_names_offset(m, t->Tuple.variables.count); + i64 type_offset = 0; + i64 name_offset = 0; + 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) { - // // NOTE(bill): offset is not used for tuples - // Entity *f = t->Tuple.variables[i]; + lbValue index = lb_const_int(m, t_int, i); + lbValue type_info = lb_const_ptr_offset(m, memory_types, index); - // lbValue index = lb_const_int(m, t_int, i); - // lbValue type_info = lb_const_ptr_offset(m, memory_types, index); + lb_global_type_info_member_types_values[type_offset+i] = lb_type_info(m, f->type).value; + 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 - // 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); - // 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 names_slice = llvm_const_slice(m, memory_names, count); + LLVMValueRef vals[2] = { + types_slice, + names_slice, + }; - // LLVMValueRef vals[2] = { - // types_slice, - // names_slice, - // }; - - // variant_value = llvm_const_named_struct(m, tag_type, vals, gb_count_of(vals)); + variant_value = llvm_const_named_struct(m, tag_type, vals, gb_count_of(vals)); break; } @@ -717,16 +740,14 @@ gb_internal void lb_setup_type_info_data_giant_packed_struct(lbModule *m, i64 gl LLVMValueRef vals[7] = {}; 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++) { - // TODO(bill) - // Type *vt = t->Union.variants[variant_index]; - // lbValue tip = lb_type_info(m, vt); + Type *vt = t->Union.variants[variant_index]; + lbValue tip = lb_type_info(m, vt); - // lbValue index = lb_const_int(m, t_int, variant_index); - // lbValue type_info = lb_const_ptr_offset(m, memory_types, index); - // lb_emit_store(p, type_info, lb_type_info(m, vt)); + lb_global_type_info_member_types_values[variant_offset+variant_index] = lb_type_info(m, vt).value; } 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; if (count > 0) { - lbValue memory_types = lb_type_info_member_types_offset (m, count); - lbValue memory_names = lb_type_info_member_names_offset (m, count); - lbValue memory_offsets = lb_type_info_member_offsets_offset(m, count); - lbValue memory_usings = lb_type_info_member_usings_offset (m, count); - lbValue memory_tags = lb_type_info_member_tags_offset (m, count); + i64 types_offset = 0; + i64 names_offset = 0; + i64 offsets_offset = 0; + i64 usings_offset = 0; + 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 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); - 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_emit_store(p, type_info, lb_type_info(m, f->type)); - // if (f->token.string.len > 0) { - // 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)); + lb_global_type_info_member_types_values[types_offset+source_index] = lb_type_info(m, f->type).value; + lb_global_type_info_member_offsets_values[offsets_offset+source_index] = lb_const_int(m, t_uintptr, foffset).value; + lb_global_type_info_member_usings_values[usings_offset+source_index] = lb_const_bool(m, t_bool, (f->flags&EntityFlag_Using) != 0).value; - // if (t->Struct.tags != nullptr) { - // String tag_string = t->Struct.tags[source_index]; - // 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 (f->token.string.len > 0) { + lb_global_type_info_member_names_values[names_offset+source_index] = lb_const_string(m, f->token.string).value; + } + + 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; + } + } }