From 1e0902677f905e752b42e2f48dcda53141b78eee Mon Sep 17 00:00:00 2001 From: gingerBill Date: Wed, 10 Sep 2025 17:29:11 +0100 Subject: Multithread min dep set by removing the set itself --- src/llvm_backend_stmt.cpp | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'src/llvm_backend_stmt.cpp') diff --git a/src/llvm_backend_stmt.cpp b/src/llvm_backend_stmt.cpp index 5481ca447..590920b59 100644 --- a/src/llvm_backend_stmt.cpp +++ b/src/llvm_backend_stmt.cpp @@ -3,8 +3,6 @@ gb_internal void lb_build_constant_value_decl(lbProcedure *p, AstValueDecl *vd) return; } - auto *min_dep_set = &p->module->info->minimum_dependency_set; - for (Ast *ident : vd->names) { GB_ASSERT(ident->kind == Ast_Ident); Entity *e = entity_of_node(ident); @@ -21,7 +19,7 @@ gb_internal void lb_build_constant_value_decl(lbProcedure *p, AstValueDecl *vd) } } - if (!polymorphic_struct && !ptr_set_exists(min_dep_set, e)) { + if (!polymorphic_struct && e->min_dep_count.load(std::memory_order_relaxed) == 0) { continue; } @@ -56,7 +54,7 @@ gb_internal void lb_build_constant_value_decl(lbProcedure *p, AstValueDecl *vd) if (gpd) { rw_mutex_shared_lock(&gpd->mutex); for (Entity *e : gpd->procs) { - if (!ptr_set_exists(min_dep_set, e)) { + if (e->min_dep_count.load(std::memory_order_relaxed) == 0) { continue; } DeclInfo *d = decl_info_of_entity(e); -- cgit v1.2.3 From 6bca1475edb8e2aec4bcbe942835bcc54f9e837e Mon Sep 17 00:00:00 2001 From: gingerBill Date: Fri, 19 Sep 2025 14:15:25 +0100 Subject: Convert `procedures_to_generate` to a queue --- src/llvm_backend.cpp | 54 +++++++++++++++++++++++++------------------- src/llvm_backend.hpp | 7 +++++- src/llvm_backend_general.cpp | 18 ++++++++++++--- src/llvm_backend_proc.cpp | 2 +- src/llvm_backend_stmt.cpp | 2 +- 5 files changed, 54 insertions(+), 29 deletions(-) (limited to 'src/llvm_backend_stmt.cpp') diff --git a/src/llvm_backend.cpp b/src/llvm_backend.cpp index f18d4af64..3ac5970f8 100644 --- a/src/llvm_backend.cpp +++ b/src/llvm_backend.cpp @@ -246,26 +246,12 @@ gb_internal String lb_internal_gen_name_from_type(char const *prefix, Type *type return proc_name; } - -gb_internal lbValue lb_equal_proc_for_type(lbModule *m, Type *type) { - type = base_type(type); - GB_ASSERT(is_type_comparable(type)); +gb_internal void lb_equal_proc_generate_body(lbModule *m, lbProcedure *p) { + Type *type = p->internal_gen_type; Type *pt = alloc_type_pointer(type); LLVMTypeRef ptr_type = lb_type(m, pt); - String proc_name = lb_internal_gen_name_from_type("__$equal", type); - lbProcedure **found = string_map_get(&m->gen_procs, proc_name); - lbProcedure *compare_proc = nullptr; - if (found) { - compare_proc = *found; - GB_ASSERT(compare_proc != nullptr); - return {compare_proc->value, compare_proc->type}; - } - - - lbProcedure *p = lb_create_dummy_procedure(m, proc_name, t_equal_proc); - string_map_set(&m->gen_procs, proc_name, p); lb_begin_procedure_body(p); LLVMSetLinkage(p->value, LLVMInternalLinkage); @@ -393,9 +379,29 @@ gb_internal lbValue lb_equal_proc_for_type(lbModule *m, Type *type) { } lb_end_procedure_body(p); +} + +gb_internal lbValue lb_equal_proc_for_type(lbModule *m, Type *type) { + type = base_type(type); + GB_ASSERT(is_type_comparable(type)); + + String proc_name = lb_internal_gen_name_from_type("__$equal", type); + lbProcedure **found = string_map_get(&m->gen_procs, proc_name); + if (found) { + lbProcedure *p = *found; + GB_ASSERT(p != nullptr); + return {p->value, p->type}; + } - compare_proc = p; - return {compare_proc->value, compare_proc->type}; + lbProcedure *p = lb_create_dummy_procedure(m, proc_name, t_equal_proc); + string_map_set(&m->gen_procs, proc_name, p); + p->internal_gen_type = type; + p->generate_body = lb_equal_proc_generate_body; + + // p->generate_body(m, p); + mpsc_enqueue(&m->procedures_to_generate, p); + + return {p->value, p->type}; } gb_internal lbValue lb_simple_compare_hash(lbProcedure *p, Type *type, lbValue data, lbValue seed) { @@ -2068,7 +2074,7 @@ gb_internal lbProcedure *lb_create_startup_runtime(lbModule *main_module, lbProc p->global_variables = &global_variables; p->objc_names = objc_names; - array_add(&main_module->procedures_to_generate, p); + mpsc_enqueue(&main_module->procedures_to_generate, p); return p; } @@ -2110,7 +2116,7 @@ gb_internal WORKER_TASK_PROC(lb_generate_procedures_and_types_per_module) { for (Entity *e : m->global_procedures_to_create) { (void)lb_get_entity_name(m, e); - array_add(&m->procedures_to_generate, lb_create_procedure(m, e)); + mpsc_enqueue(&m->procedures_to_generate, lb_create_procedure(m, e)); } return 0; } @@ -2298,7 +2304,7 @@ gb_internal WORKER_TASK_PROC(lb_llvm_function_pass_per_module) { lb_llvm_function_pass_per_function_internal(m, m->gen->objc_names); } - for (lbProcedure *p : m->procedures_to_generate) { + MUTEX_GUARD_BLOCK(&m->generated_procedures_mutex) for (lbProcedure *p : m->generated_procedures) { if (p->body != nullptr) { // Build Procedure lbFunctionPassManagerKind pass_manager_kind = lbFunctionPassManager_default; if (p->flags & lbProcedureFlag_WithoutMemcpyPass) { @@ -2447,8 +2453,7 @@ gb_internal WORKER_TASK_PROC(lb_llvm_module_pass_worker_proc) { gb_internal WORKER_TASK_PROC(lb_generate_procedures_worker_proc) { lbModule *m = cast(lbModule *)data; - for (isize i = 0; i < m->procedures_to_generate.count; i++) { - lbProcedure *p = m->procedures_to_generate[i]; + for (lbProcedure *p = nullptr; mpsc_dequeue(&m->procedures_to_generate, &p); /**/) { lb_generate_procedure(p->module, p); } return 0; @@ -2876,6 +2881,9 @@ gb_internal void lb_generate_procedure(lbModule *m, lbProcedure *p) { } lb_verify_function(m, p, true); + + MUTEX_GUARD(&m->generated_procedures_mutex); + array_add(&m->generated_procedures, p); } diff --git a/src/llvm_backend.hpp b/src/llvm_backend.hpp index 7fe4651bb..6d94df399 100644 --- a/src/llvm_backend.hpp +++ b/src/llvm_backend.hpp @@ -186,10 +186,13 @@ struct lbModule { StringMap gen_procs; // key is the canonicalized name - Array procedures_to_generate; + MPSCQueue procedures_to_generate; Array global_procedures_to_create; Array global_types_to_create; + BlockingMutex generated_procedures_mutex; + Array generated_procedures; + lbProcedure *curr_procedure; LLVMBuilderRef const_dummy_builder; @@ -238,6 +241,8 @@ struct lbGenerator : LinkerData { PtrMap modules_through_ctx; lbModule default_module; + lbModule *equal_module; + isize used_module_count; lbProcedure *startup_runtime; diff --git a/src/llvm_backend_general.cpp b/src/llvm_backend_general.cpp index 49a7fb13f..c84edc178 100644 --- a/src/llvm_backend_general.cpp +++ b/src/llvm_backend_general.cpp @@ -97,12 +97,16 @@ gb_internal WORKER_TASK_PROC(lb_init_module_worker_proc) { map_init(&m->function_type_map); string_map_init(&m->gen_procs); if (USE_SEPARATE_MODULES) { - array_init(&m->procedures_to_generate, a, 0, 1<<10); + mpsc_init(&m->procedures_to_generate, a); map_init(&m->procedure_values, 1<<11); + array_init(&m->generated_procedures, a, 0, 1<<10); } else { - array_init(&m->procedures_to_generate, a, 0, c->info.all_procedures.count); + mpsc_init(&m->procedures_to_generate, a); map_init(&m->procedure_values, c->info.all_procedures.count*2); + array_init(&m->generated_procedures, a, 0, c->info.all_procedures.count*2); } + + array_init(&m->global_procedures_to_create, a, 0, 1024); array_init(&m->global_types_to_create, a, 0, 1024); array_init(&m->missing_procedures_to_check, a, 0, 16); @@ -213,6 +217,14 @@ gb_internal bool lb_init_generator(lbGenerator *gen, Checker *c) { } } } + + if (LLVM_WEAK_MONOMORPHIZATION) { + lbModule *m = gb_alloc_item(permanent_allocator(), lbModule); + gen->equal_module = m; + m->checker = c; + map_set(&gen->modules, cast(void *)m, m); // point to itself just add it to the list + lb_init_module(m, do_threading); + } } gen->default_module.gen = gen; @@ -3169,7 +3181,7 @@ gb_internal lbValue lb_generate_anonymous_proc_lit(lbModule *m, String const &pr value.value = p->value; value.type = p->type; - array_add(&m->procedures_to_generate, p); + mpsc_enqueue(&m->procedures_to_generate, p); if (parent != nullptr) { array_add(&parent->children, p); } else { diff --git a/src/llvm_backend_proc.cpp b/src/llvm_backend_proc.cpp index f71b693eb..3b8a829b7 100644 --- a/src/llvm_backend_proc.cpp +++ b/src/llvm_backend_proc.cpp @@ -835,7 +835,7 @@ gb_internal void lb_build_nested_proc(lbProcedure *p, AstProcLit *pd, Entity *e) lb_add_entity(m, e, value); array_add(&p->children, nested_proc); - array_add(&m->procedures_to_generate, nested_proc); + mpsc_enqueue(&m->procedures_to_generate, nested_proc); } diff --git a/src/llvm_backend_stmt.cpp b/src/llvm_backend_stmt.cpp index 590920b59..f247fa2a7 100644 --- a/src/llvm_backend_stmt.cpp +++ b/src/llvm_backend_stmt.cpp @@ -92,7 +92,7 @@ gb_internal void lb_build_constant_value_decl(lbProcedure *p, AstValueDecl *vd) value.value = nested_proc->value; value.type = nested_proc->type; - array_add(&p->module->procedures_to_generate, nested_proc); + mpsc_enqueue(&p->module->procedures_to_generate, nested_proc); array_add(&p->children, nested_proc); string_map_set(&p->module->members, name, value); } -- cgit v1.2.3 From c4d1cd6ee5b903f7ef8c2d9adbded1144b428b86 Mon Sep 17 00:00:00 2001 From: Laytan Date: Tue, 4 Nov 2025 20:14:53 +0100 Subject: fixes for 32bit with regards to typeid --- src/llvm_backend_const.cpp | 5 ++--- src/llvm_backend_debug.cpp | 6 +++--- src/llvm_backend_stmt.cpp | 13 ++++++++----- src/llvm_backend_type.cpp | 25 ++++++------------------- src/llvm_backend_utility.cpp | 2 ++ src/types.cpp | 5 ++++- 6 files changed, 25 insertions(+), 31 deletions(-) (limited to 'src/llvm_backend_stmt.cpp') diff --git a/src/llvm_backend_const.cpp b/src/llvm_backend_const.cpp index c014adc05..9b785c4b4 100644 --- a/src/llvm_backend_const.cpp +++ b/src/llvm_backend_const.cpp @@ -185,8 +185,7 @@ gb_internal LLVMValueRef llvm_const_named_struct(lbModule *m, Type *t, LLVMValue } Type *bt = base_type(t); GB_ASSERT(bt->kind == Type_Struct || bt->kind == Type_Union); - - GB_ASSERT(value_count_ == bt->Struct.fields.count); + GB_ASSERT(bt->kind != Type_Struct || value_count_ == bt->Struct.fields.count); auto field_remapping = lb_get_struct_remapping(m, t); unsigned values_with_padding_count = elem_count; @@ -513,7 +512,7 @@ gb_internal LLVMValueRef lb_big_int_to_llvm(lbModule *m, Type *original_type, Bi max_count = mp_pack_count(a, nails, size); if (sz < max_count) { debug_print_big_int(a); - gb_printf_err("%s -> %tu\n", type_to_string(original_type), sz);; + gb_printf_err("%s -> %tu\n", type_to_string(original_type), sz); } GB_ASSERT_MSG(sz >= max_count, "max_count: %tu, sz: %tu, written: %tu, type %s", max_count, sz, written, type_to_string(original_type)); GB_ASSERT(gb_size_of(rop64) >= sz); diff --git a/src/llvm_backend_debug.cpp b/src/llvm_backend_debug.cpp index 3372165f2..187aebf7c 100644 --- a/src/llvm_backend_debug.cpp +++ b/src/llvm_backend_debug.cpp @@ -704,7 +704,7 @@ gb_internal LLVMMetadataRef lb_debug_type_internal(lbModule *m, Type *type) { case Basic_uintptr: return lb_debug_type_basic_type(m, str_lit("uintptr"), ptr_bits, LLVMDWARFTypeEncoding_Unsigned); case Basic_typeid: - return lb_debug_type_basic_type(m, str_lit("typeid"), ptr_bits, LLVMDWARFTypeEncoding_Unsigned); + return lb_debug_type_basic_type(m, str_lit("typeid"), 64, LLVMDWARFTypeEncoding_Unsigned); // Endian Specific Types case Basic_i16le: return lb_debug_type_basic_type(m, str_lit("i16le"), 16, LLVMDWARFTypeEncoding_Signed, LLVMDIFlagLittleEndian); @@ -820,8 +820,8 @@ gb_internal LLVMMetadataRef lb_debug_type_internal(lbModule *m, Type *type) { { LLVMMetadataRef elements[2] = {}; elements[0] = lb_debug_struct_field(m, str_lit("data"), t_rawptr, 0); - elements[1] = lb_debug_struct_field(m, str_lit("id"), t_typeid, ptr_bits); - return lb_debug_basic_struct(m, str_lit("any"), 2*ptr_bits, ptr_bits, elements, gb_count_of(elements)); + elements[1] = lb_debug_struct_field(m, str_lit("id"), t_typeid, 64); + return lb_debug_basic_struct(m, str_lit("any"), 128, 64, elements, gb_count_of(elements)); } // Untyped types diff --git a/src/llvm_backend_stmt.cpp b/src/llvm_backend_stmt.cpp index f247fa2a7..3dbcea4fb 100644 --- a/src/llvm_backend_stmt.cpp +++ b/src/llvm_backend_stmt.cpp @@ -2178,11 +2178,14 @@ gb_internal void lb_build_static_variables(lbProcedure *p, AstValueDecl *vd) { LLVMSetLinkage(var_global_ref, LLVMInternalLinkage); } - LLVMValueRef vals[2] = { - lb_emit_conv(p, var_global.addr, t_rawptr).value, - lb_typeid(p->module, var_type).value, - }; - LLVMValueRef init = llvm_const_named_struct(p->module, e->type, vals, gb_count_of(vals)); + auto vals = array_make(temporary_allocator(), 0, 3); + array_add(&vals, lb_emit_conv(p, var_global.addr, t_rawptr).value); + if (build_context.metrics.ptr_size == 4) { + array_add(&vals, LLVMConstNull(lb_type_padding_filler(p->module, 4, 4))); + } + array_add(&vals, lb_typeid(p->module, var_type).value); + + LLVMValueRef init = llvm_const_named_struct(p->module, e->type, vals.data, vals.count); LLVMSetInitializer(global, init); } else { LLVMSetInitializer(global, value.value); diff --git a/src/llvm_backend_type.cpp b/src/llvm_backend_type.cpp index 7d412eb15..abaf3716e 100644 --- a/src/llvm_backend_type.cpp +++ b/src/llvm_backend_type.cpp @@ -181,15 +181,9 @@ gb_internal LLVMTypeRef *lb_setup_modified_types_for_type_info(lbModule *m, isiz stypes[0] = lb_type(m, tibt->Struct.fields[0]->type); stypes[1] = lb_type(m, tibt->Struct.fields[1]->type); stypes[2] = lb_type(m, tibt->Struct.fields[2]->type); - isize variant_index = 0; - if (build_context.ptr_size == 8) { - stypes[3] = lb_type(m, t_i32); // padding - stypes[4] = lb_type(m, tibt->Struct.fields[3]->type); - variant_index = 5; - } else { - stypes[3] = lb_type(m, tibt->Struct.fields[3]->type); - variant_index = 4; - } + stypes[3] = lb_type(m, t_i32); // padding + stypes[4] = lb_type(m, tibt->Struct.fields[3]->type); + isize variant_index = 5; LLVMTypeRef *modified_types = gb_alloc_array(heap_allocator(), LLVMTypeRef, Typeid__COUNT); GB_ASSERT(Typeid__COUNT == ut->Union.variants.count); @@ -360,16 +354,9 @@ gb_internal void lb_setup_type_info_data_giant_array(lbModule *m, i64 global_typ small_const_values[0] = LLVMConstInt(lb_type(m, t_int), size, true); small_const_values[1] = LLVMConstInt(lb_type(m, t_int), align, true); small_const_values[2] = type_info_flags.value; - - unsigned variant_index = 0; - if (build_context.ptr_size == 8) { - small_const_values[3] = LLVMConstNull(LLVMStructGetTypeAtIndex(stype, 3)); - small_const_values[4] = id.value; - variant_index = 5; - } else { - small_const_values[3] = id.value; - variant_index = 4; - } + small_const_values[3] = LLVMConstNull(LLVMStructGetTypeAtIndex(stype, 3)); + small_const_values[4] = id.value; + isize variant_index = 5; LLVMTypeRef full_variant_type = LLVMStructGetTypeAtIndex(stype, variant_index); unsigned full_variant_elem_count = LLVMCountStructElementTypes(full_variant_type); diff --git a/src/llvm_backend_utility.cpp b/src/llvm_backend_utility.cpp index c7b4170e9..33ad2ee8d 100644 --- a/src/llvm_backend_utility.cpp +++ b/src/llvm_backend_utility.cpp @@ -1005,6 +1005,7 @@ gb_internal i32 lb_convert_struct_index(lbModule *m, Type *t, i32 index) { switch (index) { case 0: return 0; // data case 1: return 2; // id + default: GB_PANIC("index > 1"); } } else if (build_context.ptr_size != build_context.int_size) { switch (t->kind) { @@ -1203,6 +1204,7 @@ gb_internal lbValue lb_emit_struct_ep(lbProcedure *p, lbValue s, i32 index) { switch (index) { case 0: result_type = t_rawptr; break; case 1: result_type = t_typeid; break; + default: GB_PANIC("index > 1"); } } else if (is_type_dynamic_array(t)) { switch (index) { diff --git a/src/types.cpp b/src/types.cpp index a1311ba5d..b9089b9fc 100644 --- a/src/types.cpp +++ b/src/types.cpp @@ -4577,6 +4577,8 @@ gb_internal i64 type_offset_of(Type *t, i64 index, Type **field_type_) { case 1: if (field_type_) *field_type_ = t_typeid; return 8; // id + default: + GB_PANIC("index > 1"); } } break; @@ -4654,6 +4656,7 @@ gb_internal i64 type_offset_of_from_selection(Type *type, Selection sel) { switch (index) { case 0: t = t_rawptr; break; case 1: t = t_typeid; break; + default: GB_PANIC("index > 1"); } } break; @@ -4919,7 +4922,7 @@ gb_internal Type *type_internal_index(Type *t, isize index) { case Type_Slice: { GB_ASSERT(index == 0 || index == 1); - return index == 0 ? t_rawptr : t_typeid; + return index == 0 ? t_rawptr : t_int; } case Type_DynamicArray: { -- cgit v1.2.3