From bca08d3b85f59c35f4eb43731099bc96730b12cd Mon Sep 17 00:00:00 2001 From: gingerBill Date: Sun, 5 Jan 2025 13:22:27 +0000 Subject: Make `-no-dynamic-literals` the default now --- src/llvm_backend.cpp | 2 -- 1 file changed, 2 deletions(-) (limited to 'src/llvm_backend.cpp') diff --git a/src/llvm_backend.cpp b/src/llvm_backend.cpp index 01ded321e..696ced0df 100644 --- a/src/llvm_backend.cpp +++ b/src/llvm_backend.cpp @@ -1096,8 +1096,6 @@ gb_internal void lb_internal_dynamic_map_set(lbProcedure *p, lbValue const &map_ } gb_internal lbValue lb_dynamic_map_reserve(lbProcedure *p, lbValue const &map_ptr, isize const capacity, TokenPos const &pos) { - GB_ASSERT(!build_context.no_dynamic_literals); - TEMPORARY_ALLOCATOR_GUARD(); String proc_name = {}; -- cgit v1.2.3 From b2aaf90f88aa85e8893325f78260b3723dc4fe99 Mon Sep 17 00:00:00 2001 From: Laytan Laats Date: Fri, 24 Jan 2025 19:23:49 +0100 Subject: fix separate modules with objc code --- src/llvm_backend.cpp | 12 +++++- src/llvm_backend.hpp | 4 +- src/llvm_backend_utility.cpp | 92 ++++++++++++++++++++++++-------------------- 3 files changed, 63 insertions(+), 45 deletions(-) (limited to 'src/llvm_backend.cpp') diff --git a/src/llvm_backend.cpp b/src/llvm_backend.cpp index 696ced0df..277d0433e 100644 --- a/src/llvm_backend.cpp +++ b/src/llvm_backend.cpp @@ -1147,14 +1147,22 @@ gb_internal void lb_finalize_objc_names(lbProcedure *p) { String name = entry.key; args[0] = lb_const_value(m, t_cstring, exact_value_string(name)); lbValue ptr = lb_emit_runtime_call(p, "objc_lookUpClass", args); - lb_addr_store(p, entry.value, ptr); + + lbValue ptr_ = lb_find_value_from_entity(m, entry.value); + lbAddr local_addr = lb_addr(ptr_); + + lb_addr_store(p, local_addr, ptr); } for (auto const &entry : m->objc_selectors) { String name = entry.key; args[0] = lb_const_value(m, t_cstring, exact_value_string(name)); lbValue ptr = lb_emit_runtime_call(p, "sel_registerName", args); - lb_addr_store(p, entry.value, ptr); + + lbValue ptr_ = lb_find_value_from_entity(m, entry.value); + lbAddr local_addr = lb_addr(ptr_); + + lb_addr_store(p, local_addr, ptr); } lb_end_procedure_body(p); diff --git a/src/llvm_backend.hpp b/src/llvm_backend.hpp index 42d283a1e..dd56d56a3 100644 --- a/src/llvm_backend.hpp +++ b/src/llvm_backend.hpp @@ -196,8 +196,8 @@ struct lbModule { RecursiveMutex debug_values_mutex; PtrMap debug_values; - StringMap objc_classes; - StringMap objc_selectors; + StringMap objc_classes; + StringMap objc_selectors; PtrMap map_cell_info_map; // address of runtime.Map_Info PtrMap map_info_map; // address of runtime.Map_Cell_Info diff --git a/src/llvm_backend_utility.cpp b/src/llvm_backend_utility.cpp index 7b7c9d6e9..61dafa1c0 100644 --- a/src/llvm_backend_utility.cpp +++ b/src/llvm_backend_utility.cpp @@ -2093,23 +2093,36 @@ gb_internal void lb_set_wasm_export_attributes(LLVMValueRef value, String export gb_internal lbAddr lb_handle_objc_find_or_register_selector(lbProcedure *p, String const &name) { - lbAddr *found = string_map_get(&p->module->objc_selectors, name); - if (found) { - return *found; - } else { - lbModule *default_module = &p->module->gen->default_module; - Entity *e = nullptr; - lbAddr default_addr = lb_add_global_generated(default_module, t_objc_SEL, {}, &e); + lbModule *default_module = &p->module->gen->default_module; + Entity *entity = {}; - lbValue ptr = lb_find_value_from_entity(p->module, e); - lbAddr local_addr = lb_addr(ptr); + Entity **found = string_map_get(&p->module->objc_selectors, name); + if (found) { + entity = *found; + } - string_map_set(&default_module->objc_selectors, name, default_addr); + if (!entity) { if (default_module != p->module) { - string_map_set(&p->module->objc_selectors, name, local_addr); + found = string_map_get(&default_module->objc_selectors, name); + if (found) { + entity = *found; + } + } + + if (!entity) { + lbAddr default_addr = lb_add_global_generated(default_module, t_objc_SEL, {}, &entity); + string_map_set(&default_module->objc_selectors, name, entity); } - return local_addr; } + + lbValue ptr = lb_find_value_from_entity(p->module, entity); + lbAddr local_addr = lb_addr(ptr); + + if (default_module != p->module) { + string_map_set(&p->module->objc_selectors, name, entity); + } + + return local_addr; } gb_internal lbValue lb_handle_objc_find_selector(lbProcedure *p, Ast *expr) { @@ -2139,23 +2152,36 @@ gb_internal lbValue lb_handle_objc_register_selector(lbProcedure *p, Ast *expr) } gb_internal lbAddr lb_handle_objc_find_or_register_class(lbProcedure *p, String const &name) { - lbAddr *found = string_map_get(&p->module->objc_classes, name); - if (found) { - return *found; - } else { - lbModule *default_module = &p->module->gen->default_module; - Entity *e = nullptr; - lbAddr default_addr = lb_add_global_generated(default_module, t_objc_SEL, {}, &e); + lbModule *default_module = &p->module->gen->default_module; + Entity *entity = {}; - lbValue ptr = lb_find_value_from_entity(p->module, e); - lbAddr local_addr = lb_addr(ptr); + Entity **found = string_map_get(&p->module->objc_classes, name); + if (found) { + entity = *found; + } - string_map_set(&default_module->objc_classes, name, default_addr); + if (!entity) { if (default_module != p->module) { - string_map_set(&p->module->objc_classes, name, local_addr); + found = string_map_get(&default_module->objc_classes, name); + if (found) { + entity = *found; + } + } + + if (!entity) { + lbAddr default_addr = lb_add_global_generated(default_module, t_objc_Class, {}, &entity); + string_map_set(&default_module->objc_classes, name, entity); } - return local_addr; } + + lbValue ptr = lb_find_value_from_entity(p->module, entity); + lbAddr local_addr = lb_addr(ptr); + + if (default_module != p->module) { + string_map_set(&p->module->objc_classes, name, entity); + } + + return local_addr; } gb_internal lbValue lb_handle_objc_find_class(lbProcedure *p, Ast *expr) { @@ -2196,23 +2222,7 @@ gb_internal lbValue lb_handle_objc_id(lbProcedure *p, Ast *expr) { GB_ASSERT(e->kind == Entity_TypeName); String name = e->TypeName.objc_class_name; - lbAddr *found = string_map_get(&p->module->objc_classes, name); - if (found) { - return lb_addr_load(p, *found); - } else { - lbModule *default_module = &p->module->gen->default_module; - Entity *e = nullptr; - lbAddr default_addr = lb_add_global_generated(default_module, t_objc_Class, {}, &e); - - lbValue ptr = lb_find_value_from_entity(p->module, e); - lbAddr local_addr = lb_addr(ptr); - - string_map_set(&default_module->objc_classes, name, default_addr); - if (default_module != p->module) { - string_map_set(&p->module->objc_classes, name, local_addr); - } - return lb_addr_load(p, local_addr); - } + return lb_addr_load(p, lb_handle_objc_find_or_register_class(p, name)); } return lb_build_expr(p, expr); -- cgit v1.2.3 From 9dc17f4c47471829b8360c9114ac382582e2b9b6 Mon Sep 17 00:00:00 2001 From: Laytan Laats Date: Fri, 24 Jan 2025 19:33:57 +0100 Subject: optimize fix --- src/llvm_backend.cpp | 12 ++-------- src/llvm_backend.hpp | 9 +++++-- src/llvm_backend_utility.cpp | 56 ++++++++++++++++++++------------------------ 3 files changed, 35 insertions(+), 42 deletions(-) (limited to 'src/llvm_backend.cpp') diff --git a/src/llvm_backend.cpp b/src/llvm_backend.cpp index 277d0433e..29fa67f3f 100644 --- a/src/llvm_backend.cpp +++ b/src/llvm_backend.cpp @@ -1147,22 +1147,14 @@ gb_internal void lb_finalize_objc_names(lbProcedure *p) { String name = entry.key; args[0] = lb_const_value(m, t_cstring, exact_value_string(name)); lbValue ptr = lb_emit_runtime_call(p, "objc_lookUpClass", args); - - lbValue ptr_ = lb_find_value_from_entity(m, entry.value); - lbAddr local_addr = lb_addr(ptr_); - - lb_addr_store(p, local_addr, ptr); + lb_addr_store(p, entry.value.local_module_addr, ptr); } for (auto const &entry : m->objc_selectors) { String name = entry.key; args[0] = lb_const_value(m, t_cstring, exact_value_string(name)); lbValue ptr = lb_emit_runtime_call(p, "sel_registerName", args); - - lbValue ptr_ = lb_find_value_from_entity(m, entry.value); - lbAddr local_addr = lb_addr(ptr_); - - lb_addr_store(p, local_addr, ptr); + lb_addr_store(p, entry.value.local_module_addr, ptr); } lb_end_procedure_body(p); diff --git a/src/llvm_backend.hpp b/src/llvm_backend.hpp index dd56d56a3..a0775ac3b 100644 --- a/src/llvm_backend.hpp +++ b/src/llvm_backend.hpp @@ -143,6 +143,11 @@ struct lbPadType { LLVMTypeRef type; }; +struct lbObjcRef { + Entity * entity; + lbAddr local_module_addr; +}; + struct lbModule { LLVMModuleRef mod; LLVMContextRef ctx; @@ -196,8 +201,8 @@ struct lbModule { RecursiveMutex debug_values_mutex; PtrMap debug_values; - StringMap objc_classes; - StringMap objc_selectors; + StringMap objc_classes; + StringMap objc_selectors; PtrMap map_cell_info_map; // address of runtime.Map_Info PtrMap map_info_map; // address of runtime.Map_Cell_Info diff --git a/src/llvm_backend_utility.cpp b/src/llvm_backend_utility.cpp index 61dafa1c0..8910bd67a 100644 --- a/src/llvm_backend_utility.cpp +++ b/src/llvm_backend_utility.cpp @@ -2093,33 +2093,31 @@ gb_internal void lb_set_wasm_export_attributes(LLVMValueRef value, String export gb_internal lbAddr lb_handle_objc_find_or_register_selector(lbProcedure *p, String const &name) { + lbObjcRef *found = string_map_get(&p->module->objc_selectors, name); + if (found) { + return found->local_module_addr; + } + lbModule *default_module = &p->module->gen->default_module; Entity *entity = {}; - Entity **found = string_map_get(&p->module->objc_selectors, name); - if (found) { - entity = *found; + if (default_module != p->module) { + found = string_map_get(&default_module->objc_selectors, name); + if (found) { + entity = found->entity; + } } if (!entity) { - if (default_module != p->module) { - found = string_map_get(&default_module->objc_selectors, name); - if (found) { - entity = *found; - } - } - - if (!entity) { - lbAddr default_addr = lb_add_global_generated(default_module, t_objc_SEL, {}, &entity); - string_map_set(&default_module->objc_selectors, name, entity); - } + lbAddr default_addr = lb_add_global_generated(default_module, t_objc_SEL, {}, &entity); + string_map_set(&default_module->objc_selectors, name, lbObjcRef{entity, default_addr}); } lbValue ptr = lb_find_value_from_entity(p->module, entity); lbAddr local_addr = lb_addr(ptr); if (default_module != p->module) { - string_map_set(&p->module->objc_selectors, name, entity); + string_map_set(&p->module->objc_selectors, name, lbObjcRef{entity, local_addr}); } return local_addr; @@ -2152,33 +2150,31 @@ gb_internal lbValue lb_handle_objc_register_selector(lbProcedure *p, Ast *expr) } gb_internal lbAddr lb_handle_objc_find_or_register_class(lbProcedure *p, String const &name) { + lbObjcRef *found = string_map_get(&p->module->objc_classes, name); + if (found) { + return found->local_module_addr; + } + lbModule *default_module = &p->module->gen->default_module; Entity *entity = {}; - Entity **found = string_map_get(&p->module->objc_classes, name); - if (found) { - entity = *found; + if (default_module != p->module) { + found = string_map_get(&default_module->objc_classes, name); + if (found) { + entity = found->entity; + } } if (!entity) { - if (default_module != p->module) { - found = string_map_get(&default_module->objc_classes, name); - if (found) { - entity = *found; - } - } - - if (!entity) { - lbAddr default_addr = lb_add_global_generated(default_module, t_objc_Class, {}, &entity); - string_map_set(&default_module->objc_classes, name, entity); - } + lbAddr default_addr = lb_add_global_generated(default_module, t_objc_Class, {}, &entity); + string_map_set(&default_module->objc_classes, name, lbObjcRef{entity, default_addr}); } lbValue ptr = lb_find_value_from_entity(p->module, entity); lbAddr local_addr = lb_addr(ptr); if (default_module != p->module) { - string_map_set(&p->module->objc_classes, name, entity); + string_map_set(&p->module->objc_classes, name, lbObjcRef{entity, local_addr}); } return local_addr; -- cgit v1.2.3 From 1053ec30518486e3feb523d1a37e814ce992e79c Mon Sep 17 00:00:00 2001 From: Laytan Laats Date: Thu, 6 Feb 2025 20:42:41 +0100 Subject: make corrected linkage with -use-separate-modules apply hidden visibility Fixes #4798 The DLL was using the type info of the host/exe, causing crashes. This PR tries fixing by applying hidden visibility to these corrected symbols which makes sure that the DLL can't see the type table of the host/exe. --- src/llvm_backend.cpp | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'src/llvm_backend.cpp') diff --git a/src/llvm_backend.cpp b/src/llvm_backend.cpp index 29fa67f3f..0896ea8c7 100644 --- a/src/llvm_backend.cpp +++ b/src/llvm_backend.cpp @@ -169,11 +169,17 @@ gb_internal void lb_correct_entity_linkage(lbGenerator *gen) { other_global = LLVMGetNamedGlobal(ec.other_module->mod, ec.cname); if (other_global) { LLVMSetLinkage(other_global, LLVMWeakAnyLinkage); + if (!ec.e->Variable.is_export) { + LLVMSetVisibility(other_global, LLVMHiddenVisibility); + } } } else if (ec.e->kind == Entity_Procedure) { other_global = LLVMGetNamedFunction(ec.other_module->mod, ec.cname); if (other_global) { LLVMSetLinkage(other_global, LLVMWeakAnyLinkage); + if (!ec.e->Procedure.is_export) { + LLVMSetVisibility(other_global, LLVMHiddenVisibility); + } } } } -- cgit v1.2.3 From 9b26bb2e6a1e32e17102550b481c6909549b87e5 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Mon, 17 Feb 2025 13:10:38 +0000 Subject: Begin work on hash types --- src/checker.cpp | 44 +++++++++++++++++++++++++++++++++++++++++-- src/checker.hpp | 7 ++++++- src/llvm_backend.cpp | 7 ++++--- src/llvm_backend_general.cpp | 2 -- src/llvm_backend_type.cpp | 6 +++--- src/name_canonicalization.cpp | 25 +++++++++++++++++++----- src/ptr_set.cpp | 10 +++++----- src/types.cpp | 36 +++++++++++++++++++++++++++++++++-- 8 files changed, 114 insertions(+), 23 deletions(-) (limited to 'src/llvm_backend.cpp') diff --git a/src/checker.cpp b/src/checker.cpp index c74a72a14..054d6aeb0 100644 --- a/src/checker.cpp +++ b/src/checker.cpp @@ -3,7 +3,10 @@ #include "entity.cpp" #include "types.cpp" -String get_final_microarchitecture(); + +gb_internal u64 type_hash_canonical_type(Type *type); + +gb_internal String get_final_microarchitecture(); gb_internal void check_expr(CheckerContext *c, Operand *operand, Ast *expression); gb_internal void check_expr_or_type(CheckerContext *c, Operand *operand, Ast *expression, Type *type_hint=nullptr); @@ -2037,7 +2040,8 @@ gb_internal void add_type_info_type_internal(CheckerContext *c, Type *t) { // Unique entry // NOTE(bill): map entries grow linearly and in order ti_index = c->info->type_info_types.count; - array_add(&c->info->type_info_types, t); + Type_Info_Type tt = {t, type_hash_canonical_type(t)}; + array_add(&c->info->type_info_types, tt); } map_set(&c->checker->info.type_info_map, t, ti_index); @@ -6725,6 +6729,42 @@ gb_internal void check_parsed_files(Checker *c) { add_type_and_value(&c->builtin_ctx, u.expr, u.info->mode, u.info->type, u.info->value); } + TIME_SECTION("check for type hash collisions"); + { + PtrSet found = {}; + ptr_set_init(&found, c->info.type_info_types.count); + defer (ptr_set_destroy(&found)); + for (auto const &tt : c->info.type_info_types) { + if (ptr_set_update(&found, cast(uintptr)tt.hash)) { + Type *other_type = nullptr; + for (auto const &other : c->info.type_info_types) { + if (&tt == &other) { + continue; + } + if (cast(uintptr)other.hash == cast(uintptr)tt.hash && + !are_types_identical(tt.type, other.type)) { + other_type = other.type; + break; + } + } + if (other_type != nullptr) { + String ts = type_to_canonical_string(temporary_allocator(), tt.type); + String os = type_to_canonical_string(temporary_allocator(), other_type); + if (ts != os) { + compiler_error("%s found type hash collision with %s (hash = %llu)\n" + "%s vs %s\n", + type_to_string(tt.type), type_to_string(other_type), cast(unsigned long long)tt.hash, + temp_canonical_string(tt.type), + temp_canonical_string(other_type) + ); + } + } + } + } + } + + + TIME_SECTION("sort init and fini procedures"); check_sort_init_and_fini_procedures(c); diff --git a/src/checker.hpp b/src/checker.hpp index 472ab8e50..c9a0c3302 100644 --- a/src/checker.hpp +++ b/src/checker.hpp @@ -409,6 +409,11 @@ struct Defineable { String pos_str; }; +struct Type_Info_Type { + Type *type; + u64 hash; // see: type_hash_canonical_type +}; + // CheckerInfo stores all the symbol information for a type-checked program struct CheckerInfo { Checker *checker; @@ -453,7 +458,7 @@ struct CheckerInfo { PtrMap gen_types; BlockingMutex type_info_mutex; // NOT recursive - Array type_info_types; + Array type_info_types; PtrMap type_info_map; BlockingMutex foreign_mutex; // NOT recursive diff --git a/src/llvm_backend.cpp b/src/llvm_backend.cpp index 0896ea8c7..8cb480dd4 100644 --- a/src/llvm_backend.cpp +++ b/src/llvm_backend.cpp @@ -24,7 +24,7 @@ #include "llvm_backend_stmt.cpp" #include "llvm_backend_proc.cpp" -String get_default_microarchitecture() { +gb_internal String get_default_microarchitecture() { String default_march = str_lit("generic"); if (build_context.metrics.arch == TargetArch_amd64) { // NOTE(bill): x86-64-v2 is more than enough for everyone @@ -47,7 +47,7 @@ String get_default_microarchitecture() { return default_march; } -String get_final_microarchitecture() { +gb_internal String get_final_microarchitecture() { BuildContext *bc = &build_context; String microarch = bc->microarch; @@ -3182,7 +3182,8 @@ gb_internal bool lb_generate_code(lbGenerator *gen) { isize count = 0; isize offsets_extra = 0; - for (Type *t : m->info->type_info_types) { + for (auto const &tt : m->info->type_info_types) { + Type *t = tt.type; isize index = lb_type_info_index(m->info, t, false); if (index < 0) { continue; diff --git a/src/llvm_backend_general.cpp b/src/llvm_backend_general.cpp index 7fdfa0bb2..b9ae3d254 100644 --- a/src/llvm_backend_general.cpp +++ b/src/llvm_backend_general.cpp @@ -1460,8 +1460,6 @@ gb_internal String lb_get_entity_name(lbModule *m, Entity *e) { w = write_canonical_entity_name(w, e); defer (gb_string_free(w)); - gb_printf_err("%s\n", w); - String name = copy_string(permanent_allocator(), make_string(cast(u8 const *)w, gb_string_length(w))); if (e->kind == Entity_TypeName) { diff --git a/src/llvm_backend_type.cpp b/src/llvm_backend_type.cpp index 6c12b37be..6f9f94fbd 100644 --- a/src/llvm_backend_type.cpp +++ b/src/llvm_backend_type.cpp @@ -12,7 +12,7 @@ gb_internal isize lb_type_info_index(CheckerInfo *info, Type *type, bool err_on_ gb_printf_err("NOT FOUND lb_type_info_index:\n\t%s\n\t@ index %td\n\tmax count: %u\nFound:\n", type_to_string(type), index, set->count); for (auto const &entry : *set) { isize type_info_index = entry.key; - gb_printf_err("\t%s\n", type_to_string(info->type_info_types[type_info_index])); + gb_printf_err("\t%s\n", type_to_string(info->type_info_types[type_info_index].type)); } GB_PANIC("NOT FOUND"); } @@ -280,7 +280,7 @@ gb_internal void lb_setup_type_info_data_giant_array(lbModule *m, i64 global_typ LLVMTypeRef *modified_types = lb_setup_modified_types_for_type_info(m, global_type_info_data_entity_count); defer (gb_free(heap_allocator(), modified_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].type; if (t == nullptr || t == t_invalid) { continue; } @@ -343,7 +343,7 @@ gb_internal void lb_setup_type_info_data_giant_array(lbModule *m, i64 global_typ }; 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].type; if (t == nullptr || t == t_invalid) { continue; } diff --git a/src/name_canonicalization.cpp b/src/name_canonicalization.cpp index 3910c573d..8edb5e968 100644 --- a/src/name_canonicalization.cpp +++ b/src/name_canonicalization.cpp @@ -7,7 +7,7 @@ * builtin names - just their normal name e.g. `i32` or `string` * nested - pkg.parent1.parent2.name * file private - pkg.[file_name].name - * Example: `foo.[bar.odin].Type` + * Example: `pkg.[file.odin].Type` * polymorphic procedure/type - pkg.foo::TYPE * naming convention for parameters * type @@ -15,7 +15,7 @@ * $$constant_parameter * Example: `foo.to_thing::proc(u64)->([]u8)` * nested decl in polymorphic procedure - pkg.foo::TYPE.name - * anonymous procedures - pkg.foo.$anon123 + * anonymous procedures - pkg.foo.$anon[file.odin:123] * 123 is the file offset in bytes @@ -38,7 +38,12 @@ #define CANONICAL_NONE_TYPE "<>" + gb_internal gbString write_type_to_canonical_string(gbString w, Type *type); +gb_internal u64 type_hash_canonical_type(Type *type); +gb_internal String type_to_canonical_string(gbAllocator allocator, Type *type); +gb_internal gbString temp_canonical_string(Type *type); + gb_internal gbString write_canonical_params(gbString w, Type *params) { w = gb_string_appendc(w, "("); if (params) { @@ -81,7 +86,7 @@ gb_internal u64 type_hash_canonical_type(Type *type) { TEMPORARY_ALLOCATOR_GUARD(); gbString w = write_type_to_canonical_string(gb_string_make(temporary_allocator(), ""), type); u64 hash = fnv64a(w, gb_string_length(w)); - return hash; + return hash ? hash : 1; } gb_internal String type_to_canonical_string(gbAllocator allocator, Type *type) { @@ -90,6 +95,11 @@ gb_internal String type_to_canonical_string(gbAllocator allocator, Type *type) { return make_string(cast(u8 const *)w, gb_string_length(w)); } +gb_internal gbString temp_canonical_string(Type *type) { + gbString w = gb_string_make(temporary_allocator(), ""); + return write_type_to_canonical_string(w, type); +} + gb_internal void print_scope_flags(Scope *s) { if (s->flags & ScopeFlag_Pkg) gb_printf_err("Pkg "); if (s->flags & ScopeFlag_Builtin) gb_printf_err("Builtin "); @@ -156,7 +166,8 @@ gb_internal gbString write_canonical_parent_prefix(gbString w, Entity *e, bool i } if (e->kind == Entity_Procedure && e->Procedure.is_anonymous) { - w = gb_string_appendc(w, gb_bprintf(CANONICAL_ANON_PREFIX "%d", e->token.pos.offset)); + String file_name = filename_without_directory(e->file->fullpath); + w = gb_string_appendc(w, gb_bprintf(CANONICAL_ANON_PREFIX "[%.*s:%d]", LIT(file_name), e->token.pos.offset)); } else { w = gb_string_append_length(w, e->token.string.text, e->token.string.len); } @@ -449,8 +460,12 @@ gb_internal gbString write_type_to_canonical_string(gbString w, Type *type) { } return w; + case Type_Tuple: + w = gb_string_appendc(w, "params"); + w = write_canonical_params(w, type); + return w; default: - GB_PANIC("unknown type kind %d", type->kind); + GB_PANIC("unknown type kind %d %.*s", type->kind, LIT(type_strings[type->kind])); break; } diff --git a/src/ptr_set.cpp b/src/ptr_set.cpp index ff4befc37..5097e2bb6 100644 --- a/src/ptr_set.cpp +++ b/src/ptr_set.cpp @@ -42,7 +42,7 @@ gb_internal void ptr_set_destroy(PtrSet *s) { template gb_internal isize ptr_set__find(PtrSet *s, T ptr) { - GB_ASSERT(ptr != nullptr); + GB_ASSERT(ptr != 0); if (s->count != 0) { #if 0 for (usize i = 0; i < s->capacity; i++) { @@ -58,7 +58,7 @@ gb_internal isize ptr_set__find(PtrSet *s, T ptr) { T key = s->keys[hash_index]; if (key == ptr) { return hash_index; - } else if (key == nullptr) { + } else if (key == 0) { return -1; } hash_index = (hash_index+1)&mask; @@ -122,7 +122,7 @@ gb_internal bool ptr_set_update(PtrSet *s, T ptr) { // returns true if it pre for (usize i = 0; i < s->capacity; i++) { T *key = &s->keys[hash_index]; GB_ASSERT(*key != ptr); - if (*key == (T)PtrSet::TOMBSTONE || *key == nullptr) { + if (*key == (T)PtrSet::TOMBSTONE || *key == 0) { *key = ptr; s->count++; return false; @@ -169,7 +169,7 @@ struct PtrSetIterator { return *this; } T key = set->keys[index]; - if (key != nullptr && key != (T)PtrSet::TOMBSTONE) { + if (key != 0 && key != (T)PtrSet::TOMBSTONE) { return *this; } } @@ -191,7 +191,7 @@ gb_internal PtrSetIterator begin(PtrSet &set) noexcept { usize index = 0; while (index < set.capacity) { T key = set.keys[index]; - if (key != nullptr && key != (T)PtrSet::TOMBSTONE) { + if (key != 0 && key != (T)PtrSet::TOMBSTONE) { break; } index++; diff --git a/src/types.cpp b/src/types.cpp index d6dea56ad..15e1bcf45 100644 --- a/src/types.cpp +++ b/src/types.cpp @@ -2774,7 +2774,37 @@ gb_internal bool are_types_identical_internal(Type *x, Type *y, bool check_tuple case Type_Enum: - return x == y; // NOTE(bill): All enums are unique + if (x == y) { + return true; + } + if (x->Enum.fields.count != y->Enum.fields.count) { + return false; + } + if (!are_types_identical(x->Enum.base_type, y->Enum.base_type)) { + return false; + } + if (x->Enum.min_value_index != y->Enum.min_value_index) { + return false; + } + if (x->Enum.max_value_index != y->Enum.max_value_index) { + return false; + } + + for (isize i = 0; i < x->Enum.fields.count; i++) { + Entity *a = x->Enum.fields[i]; + Entity *b = y->Enum.fields[i]; + if (a->token.string != b->token.string) { + return false; + } + GB_ASSERT(a->kind == b->kind); + GB_ASSERT(a->kind == Entity_Constant); + bool same = compare_exact_values(Token_CmpEq, a->Constant.value, b->Constant.value); + if (!same) { + return false; + } + } + + return true; case Type_Union: if (x->Union.variants.count == y->Union.variants.count && @@ -2832,7 +2862,9 @@ gb_internal bool are_types_identical_internal(Type *x, Type *y, bool check_tuple return false; } } - return are_types_identical(x->Struct.polymorphic_params, y->Struct.polymorphic_params); + // TODO(bill): Which is the correct logic here? + // return are_types_identical(x->Struct.polymorphic_params, y->Struct.polymorphic_params); + return true; } break; -- cgit v1.2.3 From 4a29d9bb845050c483e537c7a0d6b2889af0f7bc Mon Sep 17 00:00:00 2001 From: gingerBill Date: Mon, 17 Feb 2025 16:29:42 +0000 Subject: Simplify type info table construction --- src/checker.cpp | 162 ++++++++++++++++++++++++++---------------- src/checker.hpp | 17 +++-- src/llvm_backend.cpp | 4 +- src/llvm_backend_type.cpp | 25 +++---- src/name_canonicalization.cpp | 23 ++++-- 5 files changed, 146 insertions(+), 85 deletions(-) (limited to 'src/llvm_backend.cpp') diff --git a/src/checker.cpp b/src/checker.cpp index 6ceb31489..1c7126e9a 100644 --- a/src/checker.cpp +++ b/src/checker.cpp @@ -828,9 +828,15 @@ gb_internal void add_dependency(CheckerInfo *info, DeclInfo *d, Entity *e) { rw_mutex_unlock(&d->deps_mutex); } gb_internal void add_type_info_dependency(CheckerInfo *info, DeclInfo *d, Type *type) { - if (d == nullptr) { + if (d == nullptr || type == nullptr) { return; } + if (type->kind == Type_Named) { + Entity *e = type->Named.type_name; + if (e->TypeName.is_type_alias) { + type = type->Named.base; + } + } rw_mutex_lock(&d->type_info_deps_mutex); ptr_set_add(&d->type_info_deps, type); rw_mutex_unlock(&d->type_info_deps_mutex); @@ -1361,9 +1367,12 @@ gb_internal void init_checker_info(CheckerInfo *i) { string_map_init(&i->foreigns); // map_init(&i->gen_procs); map_init(&i->gen_types); + array_init(&i->type_info_types, a); - map_init(&i->type_info_map); - type_set_init(&i->type_info_set); + type_set_init(&i->min_dep_type_info_set); + map_init(&i->minimum_dependency_type_info_index_map); + + // map_init(&i->type_info_map); string_map_init(&i->files); string_map_init(&i->packages); array_init(&i->variable_init_order, a); @@ -1396,9 +1405,11 @@ gb_internal void destroy_checker_info(CheckerInfo *i) { string_map_destroy(&i->foreigns); // map_destroy(&i->gen_procs); map_destroy(&i->gen_types); + array_free(&i->type_info_types); - map_destroy(&i->type_info_map); - type_set_destroy(&i->type_info_set); + type_set_destroy(&i->min_dep_type_info_set); + map_destroy(&i->minimum_dependency_type_info_index_map); + string_map_destroy(&i->files); string_map_destroy(&i->packages); array_free(&i->variable_init_order); @@ -1632,41 +1643,36 @@ gb_internal void check_remove_expr_info(CheckerContext *c, Ast *e) { } } - -gb_internal isize type_info_index(CheckerInfo *info, Type *type, bool error_on_failure) { - type = default_type(type); - if (type == t_llvm_bool) { - type = t_bool; - } - - mutex_lock(&info->type_info_mutex); +gb_internal isize type_info_index(CheckerInfo *info, TypeInfoPair pair, bool error_on_failure) { + mutex_lock(&info->minimum_dependency_type_info_mutex); isize entry_index = -1; - isize *found_entry_index = map_get(&info->type_info_map, type); + uintptr hash = cast(uintptr)pair.hash; + isize *found_entry_index = map_get(&info->minimum_dependency_type_info_index_map, hash); if (found_entry_index) { entry_index = *found_entry_index; } - if (entry_index < 0) { - // NOTE(bill): Do manual linear search - for (auto const &e : info->type_info_map) { - if (are_types_identical_unique_tuples(e.key, type)) { - entry_index = e.value; - // NOTE(bill): Add it to the search map - map_set(&info->type_info_map, type, entry_index); - break; - } - } - } - - mutex_unlock(&info->type_info_mutex); + mutex_unlock(&info->minimum_dependency_type_info_mutex); if (error_on_failure && entry_index < 0) { - compiler_error("Type_Info for '%s' could not be found", type_to_string(type)); + compiler_error("Type_Info for '%s' could not be found", type_to_string(pair.type)); } return entry_index; } +gb_internal isize type_info_index(CheckerInfo *info, Type *type, bool error_on_failure) { + type = default_type(type); + if (type == t_llvm_bool) { + type = t_bool; + } + + u64 hash = type_hash_canonical_type(type); + return type_info_index(info, {type, hash}, error_on_failure); +} + + + gb_internal void add_untyped(CheckerContext *c, Ast *expr, AddressingMode mode, Type *type, ExactValue const &value) { if (expr == nullptr) { return; @@ -2018,8 +2024,12 @@ gb_internal void add_type_info_type_internal(CheckerContext *c, Type *t) { } add_type_info_dependency(c->info, c->decl, t); - +#if 0 MUTEX_GUARD_BLOCK(&c->info->type_info_mutex) { + if (type_set_update(&c->info->type_info_set, t)) { + // return; + } + auto found = map_get(&c->info->type_info_map, t); if (found != nullptr) { // Types have already been added @@ -2238,6 +2248,7 @@ gb_internal void add_type_info_type_internal(CheckerContext *c, Type *t) { GB_PANIC("Unhandled type: %*.s %d", LIT(type_strings[bt->kind]), bt->kind); break; } +#endif } @@ -2295,11 +2306,10 @@ gb_internal void add_min_dep_type_info(Checker *c, Type *t) { return; } - if (type_set_update(&c->info.type_info_set, t)) { - // return; + if (type_set_update(&c->info.min_dep_type_info_set, t)) { + return; } - // Add nested types if (t->kind == Type_Named) { // NOTE(bill): Just in case @@ -2697,7 +2707,6 @@ gb_internal void generate_minimum_dependency_set(Checker *c, Entity *start) { isize min_dep_set_cap = next_pow2_isize(entity_count*4); // empirically determined factor ptr_set_init(&c->info.minimum_dependency_set, min_dep_set_cap); - map_init(&c->info.minimum_dependency_type_info_set); #define FORCE_ADD_RUNTIME_ENTITIES(condition, ...) do { \ if (condition) { \ @@ -6720,39 +6729,70 @@ gb_internal void check_parsed_files(Checker *c) { add_type_and_value(&c->builtin_ctx, u.expr, u.info->mode, u.info->type, u.info->value); } - TIME_SECTION("check for type hash collisions"); + TIME_SECTION("initilize type info array"); { - PtrSet found = {}; - ptr_set_init(&found, c->info.type_info_types.count); - defer (ptr_set_destroy(&found)); - for (auto const &tt : c->info.type_info_types) { - if (ptr_set_update(&found, cast(uintptr)tt.hash)) { - Type *other_type = nullptr; - for (auto const &other : c->info.type_info_types) { - if (&tt == &other) { - continue; - } - if (cast(uintptr)other.hash == cast(uintptr)tt.hash && - !are_types_identical(tt.type, other.type)) { - other_type = other.type; - break; - } - } - if (other_type != nullptr) { - String ts = type_to_canonical_string(temporary_allocator(), tt.type); - String os = type_to_canonical_string(temporary_allocator(), other_type); - if (ts != os) { - compiler_error("%s found type hash collision with %s (hash = %llu)\n" - "%s vs %s\n", - type_to_string(tt.type), type_to_string(other_type), cast(unsigned long long)tt.hash, - temp_canonical_string(tt.type), - temp_canonical_string(other_type) - ); + for (auto const &tt : c->info.min_dep_type_info_set) { + array_add(&c->info.type_info_types, tt); + } + array_sort(c->info.type_info_types, type_info_pair_cmp); + + map_reserve(&c->info.minimum_dependency_type_info_index_map, c->info.type_info_types.count); + + for_array(i, c->info.type_info_types) { + auto const &tt = c->info.type_info_types[i]; + bool exists = map_set_if_not_previously_exists(&c->info.minimum_dependency_type_info_index_map, cast(uintptr)tt.hash, i); + if (exists) { + for (auto const &entry : c->info.minimum_dependency_type_info_index_map) { + if (entry.key == cast(uintptr)tt.hash) { + auto const &other = c->info.type_info_types[entry.value]; + if (!are_types_identical_unique_tuples(tt.type, other.type)) { + gbString t = temp_canonical_string(tt.type); + gbString o = temp_canonical_string(other.type); + GB_PANIC("%s (%s) %llu vs %s (%s) %llu", + type_to_string(tt.type, false), t, cast(unsigned long long)tt.hash, + type_to_string(other.type, false), o, cast(unsigned long long)other.hash); + } } } } } - } + + GB_ASSERT(c->info.minimum_dependency_type_info_index_map.count <= c->info.type_info_types.count); + } + + // TIME_SECTION("check for type hash collisions"); + // { + // PtrSet found = {}; + // ptr_set_init(&found, c->info.type_info_types.count); + // defer (ptr_set_destroy(&found)); + // for (auto const &tt : c->info.type_info_types) { + // if (ptr_set_update(&found, cast(uintptr)tt.hash)) { + // Type *other_type = nullptr; + // for (auto const &other : c->info.type_info_types) { + // if (&tt == &other) { + // continue; + // } + // if (cast(uintptr)other.hash == cast(uintptr)tt.hash && + // !are_types_identical(tt.type, other.type)) { + // other_type = other.type; + // break; + // } + // } + // if (other_type != nullptr) { + // String ts = type_to_canonical_string(temporary_allocator(), tt.type); + // String os = type_to_canonical_string(temporary_allocator(), other_type); + // if (ts != os) { + // compiler_error("%s found type hash collision with %s (hash = %llu)\n" + // "%s vs %s\n", + // type_to_string(tt.type), type_to_string(other_type), cast(unsigned long long)tt.hash, + // temp_canonical_string(tt.type), + // temp_canonical_string(other_type) + // ); + // } + // } + // } + // } + // } diff --git a/src/checker.hpp b/src/checker.hpp index 725c1ccf5..52676d4ee 100644 --- a/src/checker.hpp +++ b/src/checker.hpp @@ -222,7 +222,7 @@ struct DeclInfo { PtrSet deps; RwMutex type_info_deps_mutex; - PtrSet type_info_deps; + PtrSet type_info_deps; // TODO(bill): Use TypeSet BlockingMutex type_and_value_mutex; @@ -444,8 +444,10 @@ struct CheckerInfo { Scope * init_scope; Entity * entry_point; PtrSet minimum_dependency_set; - PtrMap minimum_dependency_type_info_set; - + BlockingMutex minimum_dependency_type_info_mutex; + PtrMap minimum_dependency_type_info_index_map; + TypeSet min_dep_type_info_set; + Array type_info_types; // sorted after filled Array testing_procedures; @@ -473,10 +475,10 @@ struct CheckerInfo { BlockingMutex gen_types_mutex; PtrMap gen_types; - BlockingMutex type_info_mutex; // NOT recursive - Array type_info_types; - PtrMap type_info_map; - TypeSet type_info_set; + // BlockingMutex type_info_mutex; // NOT recursive + // Array type_info_types; + // PtrMap type_info_map; + // TypeSet type_info_set; BlockingMutex foreign_mutex; // NOT recursive StringMap foreigns; @@ -595,6 +597,7 @@ gb_internal DeclInfo * decl_info_of_entity (Entity * e); gb_internal AstFile * ast_file_of_filename (CheckerInfo *i, String filename); // IMPORTANT: Only to use once checking is done gb_internal isize type_info_index (CheckerInfo *i, Type *type, bool error_on_failure); +gb_internal isize type_info_index (CheckerInfo *info, TypeInfoPair pair, bool error_on_failure); // Will return nullptr if not found gb_internal Entity *entity_of_node(Ast *expr); diff --git a/src/llvm_backend.cpp b/src/llvm_backend.cpp index 8cb480dd4..908117501 100644 --- a/src/llvm_backend.cpp +++ b/src/llvm_backend.cpp @@ -3154,7 +3154,9 @@ gb_internal bool lb_generate_code(lbGenerator *gen) { lbModule *m = default_module; { // Add type info data - isize max_type_info_count = info->minimum_dependency_type_info_set.count+1; + GB_ASSERT_MSG(info->minimum_dependency_type_info_index_map.count == info->type_info_types.count, "%tu vs %tu", info->minimum_dependency_type_info_index_map.count, info->type_info_types.count); + + isize max_type_info_count = info->minimum_dependency_type_info_index_map.count+1; Type *t = alloc_type_array(t_type_info_ptr, max_type_info_count); // IMPORTANT NOTE(bill): As LLVM does not have a union type, an array of unions cannot be initialized diff --git a/src/llvm_backend_type.cpp b/src/llvm_backend_type.cpp index 6f9f94fbd..8e0f15f35 100644 --- a/src/llvm_backend_type.cpp +++ b/src/llvm_backend_type.cpp @@ -1,16 +1,12 @@ -gb_internal isize lb_type_info_index(CheckerInfo *info, Type *type, bool err_on_not_found=true) { - auto *set = &info->minimum_dependency_type_info_set; - isize index = type_info_index(info, type, err_on_not_found); + +gb_internal isize lb_type_info_index(CheckerInfo *info, TypeInfoPair pair, bool err_on_not_found=true) { + isize index = type_info_index(info, pair, err_on_not_found); if (index >= 0) { - auto *found = map_get(set, index+1); - if (found) { - GB_ASSERT(*found >= 0); - return *found + 1; - } + return index+1; } if (err_on_not_found) { - gb_printf_err("NOT FOUND lb_type_info_index:\n\t%s\n\t@ index %td\n\tmax count: %u\nFound:\n", type_to_string(type), index, set->count); - for (auto const &entry : *set) { + gb_printf_err("NOT FOUND lb_type_info_index:\n\t%s\n\t@ index %td\n\tmax count: %u\nFound:\n", type_to_string(pair.type), index, info->minimum_dependency_type_info_index_map.count); + for (auto const &entry : info->minimum_dependency_type_info_index_map) { isize type_info_index = entry.key; gb_printf_err("\t%s\n", type_to_string(info->type_info_types[type_info_index].type)); } @@ -19,6 +15,10 @@ gb_internal isize lb_type_info_index(CheckerInfo *info, Type *type, bool err_on_ return -1; } +gb_internal isize lb_type_info_index(CheckerInfo *info, Type *type, bool err_on_not_found=true) { + return lb_type_info_index(info, {type, type_hash_canonical_type(type)}, err_on_not_found); +} + gb_internal u64 lb_typeid_kind(lbModule *m, Type *type, u64 id=0) { GB_ASSERT(!build_context.no_rtti); @@ -280,12 +280,13 @@ gb_internal void lb_setup_type_info_data_giant_array(lbModule *m, i64 global_typ LLVMTypeRef *modified_types = lb_setup_modified_types_for_type_info(m, global_type_info_data_entity_count); defer (gb_free(heap_allocator(), modified_types)); for_array(type_info_type_index, info->type_info_types) { - Type *t = info->type_info_types[type_info_type_index].type; + auto const &tt = info->type_info_types[type_info_type_index]; + Type *t = tt.type; if (t == nullptr || t == t_invalid) { continue; } - isize entry_index = lb_type_info_index(info, t, false); + isize entry_index = lb_type_info_index(info, tt, false); if (entry_index <= 0) { continue; } diff --git a/src/name_canonicalization.cpp b/src/name_canonicalization.cpp index b83441b19..de35312da 100644 --- a/src/name_canonicalization.cpp +++ b/src/name_canonicalization.cpp @@ -48,6 +48,15 @@ gb_internal gbString temp_canonical_string(Type *type); struct TypeInfoPair; struct TypeSet; +gb_internal GB_COMPARE_PROC(type_info_pair_cmp) { + TypeInfoPair *x = cast(TypeInfoPair *)a; + TypeInfoPair *y = cast(TypeInfoPair *)b; + if (x->hash == y->hash) { + return 0; + } + return x->hash < y->hash ? -1 : +1; +} + static constexpr u64 TYPE_SET_TOMBSTONE = ~(u64)(0ull); gb_internal void type_set_init (TypeSet *s, isize capacity); @@ -136,7 +145,7 @@ gb_internal isize type_set__find(TypeSet *s, TypeInfoPair pair) { usize hash_index = cast(usize)hash & mask; for (usize i = 0; i < s->capacity; i++) { Type *key = s->keys[hash_index].type; - if (are_types_identical(key, pair.type)) { + if (are_types_identical_unique_tuples(key, pair.type)) { return hash_index; } else if (key == 0) { return -1; @@ -154,7 +163,7 @@ gb_internal isize type_set__find(TypeSet *s, Type *ptr) { usize hash_index = cast(usize)hash & mask; for (usize i = 0; i < s->capacity; i++) { Type *key = s->keys[hash_index].type; - if (are_types_identical(key, ptr)) { + if (are_types_identical_unique_tuples(key, ptr)) { return hash_index; } else if (key == 0) { return -1; @@ -224,7 +233,7 @@ gb_internal bool type_set_update(TypeSet *s, TypeInfoPair pair) { // returns tru GB_ASSERT(hash_index < s->capacity); for (usize i = 0; i < s->capacity; i++) { TypeInfoPair *key = &s->keys[hash_index]; - GB_ASSERT(!are_types_identical(key->type, pair.type)); + GB_ASSERT(!are_types_identical_unique_tuples(key->type, pair.type)); if (key->hash == TYPE_SET_TOMBSTONE || key->hash == 0) { *key = pair; s->count++; @@ -274,6 +283,9 @@ gb_internal gbString write_canonical_params(gbString w, Type *params) { if (i > 0) { w = gb_string_appendc(w, CANONICAL_PARAM_SEPARATOR); } + w = gb_string_append_length(w, v->token.string.text, v->token.string.len); + w = gb_string_appendc(w, CANONICAL_TYPE_SEPARATOR); + if (v->kind == Entity_Variable) { if (v->flags&EntityFlag_CVarArg) { w = gb_string_appendc(w, CANONICAL_PARAM_C_VARARG); @@ -466,14 +478,17 @@ write_base_name: switch (e->kind) { case Entity_TypeName: { + Type *params = nullptr; Entity *parent = type_get_polymorphic_parent(e->type, ¶ms); - if (parent) { + if (parent && (parent->token.string == e->token.string)) { w = gb_string_append_length(w, parent->token.string.text, parent->token.string.len); w = write_canonical_params(w, params); } else { w = gb_string_append_length(w, e->token.string.text, e->token.string.len); } + gb_unused(parent); + } // Handle parapoly stuff here? return w; -- cgit v1.2.3 From 5489a889832ac05e5edca7355b4601c1a82c2d27 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Thu, 20 Feb 2025 14:10:45 +0000 Subject: Change `typeid` definition to be based around the canonical type hash `typeid` used to be a fancy index with extra metadata stored on it. Now it is direct hash of the type. This is safe to do in practice since any possible collisions are checked at compile time AND the chances of having a 1% collision are around 1 in 600K (see the Birthday Paradox). Therefore accessing a `^Type_Info` is now a hash table lookup with linear probing. The table is twice the size than necessary so prevent too much probing due to an overly dense hash table. --- base/runtime/core.odin | 56 ++++++++-------------------------------------- odin.rdi | Bin 6593532 -> 0 bytes src/checker.cpp | 45 ++++++++++++++++++++++++------------- src/checker.hpp | 1 + src/llvm_backend.cpp | 5 +++-- src/llvm_backend_type.cpp | 52 ++++++++++++------------------------------ src/types.cpp | 16 ++++++------- 7 files changed, 64 insertions(+), 111 deletions(-) delete mode 100644 odin.rdi (limited to 'src/llvm_backend.cpp') diff --git a/base/runtime/core.odin b/base/runtime/core.odin index e47f3ecbc..94a126082 100644 --- a/base/runtime/core.odin +++ b/base/runtime/core.odin @@ -239,47 +239,6 @@ Type_Info :: struct { }, } -// NOTE(bill): This must match the compiler's -Typeid_Kind :: enum u8 { - Invalid, - Integer, - Rune, - Float, - Complex, - Quaternion, - String, - Boolean, - Any, - Type_Id, - Pointer, - Multi_Pointer, - Procedure, - Array, - Enumerated_Array, - Dynamic_Array, - Slice, - Tuple, - Struct, - Union, - Enum, - Map, - Bit_Set, - Simd_Vector, - Matrix, - Soa_Pointer, - Bit_Field, -} -#assert(len(Typeid_Kind) < 32) - -Typeid_Bit_Field :: bit_field uintptr { - index: uintptr | 8*size_of(uintptr) - 8, - kind: Typeid_Kind | 5, // Typeid_Kind - named: bool | 1, - special: bool | 1, // signed, cstring, etc - reserved: bool | 1, -} -#assert(size_of(Typeid_Bit_Field) == size_of(uintptr)) - // NOTE(bill): only the ones that are needed (not all types) // This will be set by the compiler type_table: []^Type_Info @@ -686,13 +645,16 @@ type_info_core :: proc "contextless" (info: ^Type_Info) -> ^Type_Info { type_info_base_without_enum :: type_info_core __type_info_of :: proc "contextless" (id: typeid) -> ^Type_Info #no_bounds_check { - MASK :: 1<<(8*size_of(typeid) - 8) - 1 - data := transmute(uintptr)id - n := int(data & MASK) - if n < 0 || n >= len(type_table) { - n = 0 + n := u64(len(type_table)) + i := transmute(u64)id % n + for k in 0..info.type_info_types, type_info_pair_cmp); + array_init(&c->info.type_info_types_hash_map, heap_allocator(), c->info.type_info_types.count*2 + 1); map_reserve(&c->info.minimum_dependency_type_info_index_map, c->info.type_info_types.count); - for_array(i, c->info.type_info_types) { - auto const &tt = c->info.type_info_types[i]; - bool exists = map_set_if_not_previously_exists(&c->info.minimum_dependency_type_info_index_map, tt.hash, i); - if (!exists) { - continue; - } - for (auto const &entry : c->info.minimum_dependency_type_info_index_map) { - if (entry.key != tt.hash) { + isize hash_map_len = c->info.type_info_types_hash_map.count; + for (auto const &tt : c->info.type_info_types) { + isize index = tt.hash % hash_map_len; + // NOTE(bill): no need for a sanity check since there + // will always be enough space for the entries + for (;;) { + if (index == 0 || c->info.type_info_types_hash_map[index].hash != 0) { + index = (index+1) % hash_map_len; continue; } - auto const &other = c->info.type_info_types[entry.value]; - if (are_types_identical_unique_tuples(tt.type, other.type)) { - continue; + break; + } + c->info.type_info_types_hash_map[index] = tt; + + bool exists = map_set_if_not_previously_exists(&c->info.minimum_dependency_type_info_index_map, tt.hash, index); + if (exists) { + for (auto const &entry : c->info.minimum_dependency_type_info_index_map) { + if (entry.key != tt.hash) { + continue; + } + auto const &other = c->info.type_info_types[entry.value]; + if (are_types_identical_unique_tuples(tt.type, other.type)) { + continue; + } + gbString t = temp_canonical_string(tt.type); + gbString o = temp_canonical_string(other.type); + GB_PANIC("%s (%s) %llu vs %s (%s) %llu", + type_to_string(tt.type, false), t, cast(unsigned long long)tt.hash, + type_to_string(other.type, false), o, cast(unsigned long long)other.hash); } - gbString t = temp_canonical_string(tt.type); - gbString o = temp_canonical_string(other.type); - GB_PANIC("%s (%s) %llu vs %s (%s) %llu", - type_to_string(tt.type, false), t, cast(unsigned long long)tt.hash, - type_to_string(other.type, false), o, cast(unsigned long long)other.hash); } } + GB_ASSERT(c->info.minimum_dependency_type_info_index_map.count <= c->info.type_info_types.count); } diff --git a/src/checker.hpp b/src/checker.hpp index 3d1e5b6eb..d482f396c 100644 --- a/src/checker.hpp +++ b/src/checker.hpp @@ -432,6 +432,7 @@ struct CheckerInfo { PtrMap minimum_dependency_type_info_index_map; TypeSet min_dep_type_info_set; Array type_info_types; // sorted after filled + Array type_info_types_hash_map; // 2 * type_info_types.count Array testing_procedures; diff --git a/src/llvm_backend.cpp b/src/llvm_backend.cpp index 908117501..4ebcf7578 100644 --- a/src/llvm_backend.cpp +++ b/src/llvm_backend.cpp @@ -3154,9 +3154,10 @@ gb_internal bool lb_generate_code(lbGenerator *gen) { lbModule *m = default_module; { // Add type info data - GB_ASSERT_MSG(info->minimum_dependency_type_info_index_map.count == info->type_info_types.count, "%tu vs %tu", info->minimum_dependency_type_info_index_map.count, info->type_info_types.count); + // GB_ASSERT_MSG(info->minimum_dependency_type_info_index_map.count == info->type_info_types.count, "%tu vs %tu", info->minimum_dependency_type_info_index_map.count, info->type_info_types.count); - isize max_type_info_count = info->minimum_dependency_type_info_index_map.count+1; + // isize max_type_info_count = info->minimum_dependency_type_info_index_map.count+1; + isize max_type_info_count = info->type_info_types_hash_map.count; Type *t = alloc_type_array(t_type_info_ptr, max_type_info_count); // IMPORTANT NOTE(bill): As LLVM does not have a union type, an array of unions cannot be initialized diff --git a/src/llvm_backend_type.cpp b/src/llvm_backend_type.cpp index 8e0f15f35..170da5b2b 100644 --- a/src/llvm_backend_type.cpp +++ b/src/llvm_backend_type.cpp @@ -2,13 +2,13 @@ gb_internal isize lb_type_info_index(CheckerInfo *info, TypeInfoPair pair, bool err_on_not_found=true) { isize index = type_info_index(info, pair, err_on_not_found); if (index >= 0) { - return index+1; + return index; } if (err_on_not_found) { gb_printf_err("NOT FOUND lb_type_info_index:\n\t%s\n\t@ index %td\n\tmax count: %u\nFound:\n", type_to_string(pair.type), index, info->minimum_dependency_type_info_index_map.count); for (auto const &entry : info->minimum_dependency_type_info_index_map) { isize type_info_index = entry.key; - gb_printf_err("\t%s\n", type_to_string(info->type_info_types[type_info_index].type)); + gb_printf_err("\t%s\n", type_to_string(info->type_info_types_hash_map[type_info_index].type)); } GB_PANIC("NOT FOUND"); } @@ -73,37 +73,8 @@ gb_internal lbValue lb_typeid(lbModule *m, Type *type) { type = default_type(type); - u64 id = cast(u64)lb_type_info_index(m->info, type); - GB_ASSERT(id >= 0); - - u64 kind = lb_typeid_kind(m, type, id); - u64 named = is_type_named(type) && type->kind != Type_Basic; - u64 special = 0; - u64 reserved = 0; - - if (is_type_cstring(type)) { - special = 1; - } else if (is_type_integer(type) && !is_type_unsigned(type)) { - special = 1; - } - - u64 data = 0; - if (build_context.ptr_size == 4) { - GB_ASSERT(id <= (1u<<24u)); - data |= (id &~ (1u<<24)) << 0u; // index - data |= (kind &~ (1u<<5)) << 24u; // kind - data |= (named &~ (1u<<1)) << 29u; // named - data |= (special &~ (1u<<1)) << 30u; // special - data |= (reserved &~ (1u<<1)) << 31u; // reserved - } else { - GB_ASSERT(build_context.ptr_size == 8); - GB_ASSERT(id <= (1ull<<56u)); - data |= (id &~ (1ull<<56)) << 0ul; // index - data |= (kind &~ (1ull<<5)) << 56ull; // kind - data |= (named &~ (1ull<<1)) << 61ull; // named - data |= (special &~ (1ull<<1)) << 62ull; // special - data |= (reserved &~ (1ull<<1)) << 63ull; // reserved - } + u64 data = type_hash_canonical_type(type); + GB_ASSERT(data != 0); lbValue res = {}; res.value = LLVMConstInt(lb_type(m, t_typeid), data, false); @@ -279,8 +250,8 @@ gb_internal void lb_setup_type_info_data_giant_array(lbModule *m, i64 global_typ LLVMTypeRef *modified_types = lb_setup_modified_types_for_type_info(m, global_type_info_data_entity_count); defer (gb_free(heap_allocator(), modified_types)); - for_array(type_info_type_index, info->type_info_types) { - auto const &tt = info->type_info_types[type_info_type_index]; + for_array(type_info_type_index, info->type_info_types_hash_map) { + auto const &tt = info->type_info_types_hash_map[type_info_type_index]; Type *t = tt.type; if (t == nullptr || t == t_invalid) { continue; @@ -343,8 +314,8 @@ gb_internal void lb_setup_type_info_data_giant_array(lbModule *m, i64 global_typ return giant_const_values[index]; }; - for_array(type_info_type_index, info->type_info_types) { - Type *t = info->type_info_types[type_info_type_index].type; + for_array(type_info_type_index, info->type_info_types_hash_map) { + Type *t = info->type_info_types_hash_map[type_info_type_index].type; if (t == nullptr || t == t_invalid) { continue; } @@ -1072,7 +1043,12 @@ gb_internal void lb_setup_type_info_data_giant_array(lbModule *m, i64 global_typ LLVMSetInitializer(giant_const_values[entry_index], LLVMConstNamedStruct(stype, small_const_values, variant_index+1)); } for (isize i = 0; i < global_type_info_data_entity_count; i++) { - giant_const_values[i] = LLVMConstPointerCast(giant_const_values[i], lb_type(m, t_type_info_ptr)); + auto *ptr = &giant_const_values[i]; + if (*ptr != nullptr) { + *ptr = LLVMConstPointerCast(*ptr, lb_type(m, t_type_info_ptr)); + } else { + *ptr = LLVMConstNull(lb_type(m, t_type_info_ptr)); + } } diff --git a/src/types.cpp b/src/types.cpp index 9b23fad0f..fedb85230 100644 --- a/src/types.cpp +++ b/src/types.cpp @@ -503,9 +503,9 @@ gb_global Type basic_types[] = { {Type_Basic, {Basic_rawptr, BasicFlag_Pointer, -1, STR_LIT("rawptr")}}, {Type_Basic, {Basic_string, BasicFlag_String, -1, STR_LIT("string")}}, {Type_Basic, {Basic_cstring, BasicFlag_String, -1, STR_LIT("cstring")}}, - {Type_Basic, {Basic_any, 0, -1, STR_LIT("any")}}, + {Type_Basic, {Basic_any, 0, 16, STR_LIT("any")}}, - {Type_Basic, {Basic_typeid, 0, -1, STR_LIT("typeid")}}, + {Type_Basic, {Basic_typeid, 0, 8, STR_LIT("typeid")}}, // Endian {Type_Basic, {Basic_i16le, BasicFlag_Integer | BasicFlag_EndianLittle, 2, STR_LIT("i16le")}}, @@ -3700,7 +3700,7 @@ gb_internal i64 type_size_of(Type *t) { switch (t->Basic.kind) { case Basic_string: size = 2*build_context.int_size; break; case Basic_cstring: size = build_context.ptr_size; break; - case Basic_any: size = 2*build_context.ptr_size; break; + case Basic_any: size = 16; break; case Basic_typeid: size = build_context.ptr_size; break; case Basic_int: case Basic_uint: @@ -3763,7 +3763,7 @@ gb_internal i64 type_align_of_internal(Type *t, TypePath *path) { switch (t->Basic.kind) { case Basic_string: return build_context.int_size; case Basic_cstring: return build_context.ptr_size; - case Basic_any: return build_context.ptr_size; + case Basic_any: return 8; case Basic_typeid: return build_context.ptr_size; case Basic_int: case Basic_uint: @@ -4014,7 +4014,7 @@ gb_internal i64 type_size_of_internal(Type *t, TypePath *path) { switch (kind) { case Basic_string: return 2*build_context.int_size; case Basic_cstring: return build_context.ptr_size; - case Basic_any: return 2*build_context.ptr_size; + case Basic_any: return 16; case Basic_typeid: return build_context.ptr_size; case Basic_int: case Basic_uint: @@ -4251,7 +4251,7 @@ gb_internal i64 type_offset_of(Type *t, i64 index, Type **field_type_) { return 0; // data case 1: if (field_type_) *field_type_ = t_typeid; - return build_context.ptr_size; // id + return 8; // id } } break; @@ -4322,8 +4322,8 @@ gb_internal i64 type_offset_of_from_selection(Type *type, Selection sel) { } } else if (t->Basic.kind == Basic_any) { switch (index) { - case 0: t = t_type_info_ptr; break; - case 1: t = t_rawptr; break; + case 0: t = t_rawptr; break; + case 1: t = t_typeid; break; } } break; -- cgit v1.2.3 From ebda946d61d4b7447348afeccd16a6e5786fa91b Mon Sep 17 00:00:00 2001 From: gingerBill Date: Sat, 22 Feb 2025 18:12:43 +0000 Subject: Move temporary array out of `CheckerInfo` --- src/checker.cpp | 30 ++++++++++++++++-------------- src/checker.hpp | 5 ++--- src/llvm_backend.cpp | 5 ++++- src/llvm_backend_type.cpp | 4 ++-- 4 files changed, 24 insertions(+), 20 deletions(-) (limited to 'src/llvm_backend.cpp') diff --git a/src/checker.cpp b/src/checker.cpp index 056eef3b2..bee3f1efe 100644 --- a/src/checker.cpp +++ b/src/checker.cpp @@ -1372,9 +1372,8 @@ gb_internal void init_checker_info(CheckerInfo *i) { // map_init(&i->gen_procs); map_init(&i->gen_types); - array_init(&i->type_info_types, a); type_set_init(&i->min_dep_type_info_set); - map_init(&i->minimum_dependency_type_info_index_map); + map_init(&i->min_dep_type_info_index_map); // map_init(&i->type_info_map); string_map_init(&i->files); @@ -1410,9 +1409,8 @@ gb_internal void destroy_checker_info(CheckerInfo *i) { // map_destroy(&i->gen_procs); map_destroy(&i->gen_types); - array_free(&i->type_info_types); type_set_destroy(&i->min_dep_type_info_set); - map_destroy(&i->minimum_dependency_type_info_index_map); + map_destroy(&i->min_dep_type_info_index_map); string_map_destroy(&i->files); string_map_destroy(&i->packages); @@ -1652,7 +1650,7 @@ gb_internal isize type_info_index(CheckerInfo *info, TypeInfoPair pair, bool err isize entry_index = -1; u64 hash = pair.hash; - isize *found_entry_index = map_get(&info->minimum_dependency_type_info_index_map, hash); + isize *found_entry_index = map_get(&info->min_dep_type_info_index_map, hash); if (found_entry_index) { entry_index = *found_entry_index; } @@ -6735,16 +6733,20 @@ gb_internal void check_parsed_files(Checker *c) { TIME_SECTION("initialize and check for collisions in type info array"); { + Array type_info_types; // sorted after filled + array_init(&type_info_types, heap_allocator()); + defer (array_free(&type_info_types)); + for (auto const &tt : c->info.min_dep_type_info_set) { - array_add(&c->info.type_info_types, tt); + array_add(&type_info_types, tt); } - array_sort(c->info.type_info_types, type_info_pair_cmp); + array_sort(type_info_types, type_info_pair_cmp); - array_init(&c->info.type_info_types_hash_map, heap_allocator(), c->info.type_info_types.count*2 + 1); - map_reserve(&c->info.minimum_dependency_type_info_index_map, c->info.type_info_types.count); + array_init(&c->info.type_info_types_hash_map, heap_allocator(), type_info_types.count*2 + 1); + map_reserve(&c->info.min_dep_type_info_index_map, type_info_types.count); isize hash_map_len = c->info.type_info_types_hash_map.count; - for (auto const &tt : c->info.type_info_types) { + for (auto const &tt : type_info_types) { isize index = tt.hash % hash_map_len; // NOTE(bill): no need for a sanity check since there // will always be enough space for the entries @@ -6757,13 +6759,13 @@ gb_internal void check_parsed_files(Checker *c) { } c->info.type_info_types_hash_map[index] = tt; - bool exists = map_set_if_not_previously_exists(&c->info.minimum_dependency_type_info_index_map, tt.hash, index); + bool exists = map_set_if_not_previously_exists(&c->info.min_dep_type_info_index_map, tt.hash, index); if (exists) { - for (auto const &entry : c->info.minimum_dependency_type_info_index_map) { + for (auto const &entry : c->info.min_dep_type_info_index_map) { if (entry.key != tt.hash) { continue; } - auto const &other = c->info.type_info_types[entry.value]; + auto const &other = type_info_types[entry.value]; if (are_types_identical_unique_tuples(tt.type, other.type)) { continue; } @@ -6777,7 +6779,7 @@ gb_internal void check_parsed_files(Checker *c) { } - GB_ASSERT(c->info.minimum_dependency_type_info_index_map.count <= c->info.type_info_types.count); + GB_ASSERT(c->info.min_dep_type_info_index_map.count <= type_info_types.count); } diff --git a/src/checker.hpp b/src/checker.hpp index d482f396c..d3b2d7d89 100644 --- a/src/checker.hpp +++ b/src/checker.hpp @@ -429,9 +429,8 @@ struct CheckerInfo { Entity * entry_point; PtrSet minimum_dependency_set; BlockingMutex minimum_dependency_type_info_mutex; - PtrMap minimum_dependency_type_info_index_map; - TypeSet min_dep_type_info_set; - Array type_info_types; // sorted after filled + PtrMap min_dep_type_info_index_map; + TypeSet min_dep_type_info_set; Array type_info_types_hash_map; // 2 * type_info_types.count diff --git a/src/llvm_backend.cpp b/src/llvm_backend.cpp index 4ebcf7578..d8e1af062 100644 --- a/src/llvm_backend.cpp +++ b/src/llvm_backend.cpp @@ -3185,8 +3185,11 @@ gb_internal bool lb_generate_code(lbGenerator *gen) { isize count = 0; isize offsets_extra = 0; - for (auto const &tt : m->info->type_info_types) { + for (auto const &tt : m->info->type_info_types_hash_map) { Type *t = tt.type; + if (t == nullptr) { + continue; + } isize index = lb_type_info_index(m->info, t, false); if (index < 0) { continue; diff --git a/src/llvm_backend_type.cpp b/src/llvm_backend_type.cpp index 170da5b2b..ad4250f3c 100644 --- a/src/llvm_backend_type.cpp +++ b/src/llvm_backend_type.cpp @@ -5,8 +5,8 @@ gb_internal isize lb_type_info_index(CheckerInfo *info, TypeInfoPair pair, bool return index; } if (err_on_not_found) { - gb_printf_err("NOT FOUND lb_type_info_index:\n\t%s\n\t@ index %td\n\tmax count: %u\nFound:\n", type_to_string(pair.type), index, info->minimum_dependency_type_info_index_map.count); - for (auto const &entry : info->minimum_dependency_type_info_index_map) { + gb_printf_err("NOT FOUND lb_type_info_index:\n\t%s\n\t@ index %td\n\tmax count: %u\nFound:\n", type_to_string(pair.type), index, info->min_dep_type_info_index_map.count); + for (auto const &entry : info->min_dep_type_info_index_map) { isize type_info_index = entry.key; gb_printf_err("\t%s\n", type_to_string(info->type_info_types_hash_map[type_info_index].type)); } -- cgit v1.2.3 From 46a8991d0fae4fb119e9934d62959e5a1729a636 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Mon, 24 Feb 2025 14:19:02 +0000 Subject: Canonicalize generated procedures --- src/llvm_backend.cpp | 39 ++++++++++++++------------------------- src/llvm_backend.hpp | 3 +++ src/llvm_backend_stmt.cpp | 2 -- 3 files changed, 17 insertions(+), 27 deletions(-) (limited to 'src/llvm_backend.cpp') diff --git a/src/llvm_backend.cpp b/src/llvm_backend.cpp index d8e1af062..9bbcc2184 100644 --- a/src/llvm_backend.cpp +++ b/src/llvm_backend.cpp @@ -233,6 +233,16 @@ gb_internal lbContextData *lb_push_context_onto_stack(lbProcedure *p, lbAddr ctx } +gb_internal String lb_internal_gen_proc_name_from_type(char const *prefix, Type *type) { + gbString str = gb_string_make(permanent_allocator(), prefix); + gbString tcs = temp_canonical_string(type); + str = gb_string_appendc(str, CANONICAL_TYPE_SEPARATOR); + str = gb_string_append_length(str, tcs, gb_string_length(tcs)); + String proc_name = make_string(cast(u8 const *)str, gb_string_length(str)); + 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)); @@ -248,16 +258,8 @@ gb_internal lbValue lb_equal_proc_for_type(lbModule *m, Type *type) { return {compare_proc->value, compare_proc->type}; } - static std::atomic proc_index; - char buf[32] = {}; - isize n = gb_snprintf(buf, 32, "__$equal%u", 1+proc_index.fetch_add(1)); - char *str = gb_alloc_str_len(permanent_allocator(), buf, n-1); - String proc_name = make_string_c(str); - - lbProcedure *p = lb_create_dummy_procedure(m, proc_name, t_equal_proc); - map_set(&m->equal_procs, type, p); - lb_begin_procedure_body(p); + String proc_name = lb_internal_gen_proc_name_from_type("__$equal", type); // lb_add_attribute_to_proc(m, p->value, "readonly"); lb_add_attribute_to_proc(m, p->value, "nounwind"); @@ -416,12 +418,7 @@ gb_internal lbValue lb_hasher_proc_for_type(lbModule *m, Type *type) { return {(*found)->value, (*found)->type}; } - static std::atomic proc_index; - - char buf[32] = {}; - isize n = gb_snprintf(buf, 32, "__$hasher%u", 1+proc_index.fetch_add(1)); - char *str = gb_alloc_str_len(permanent_allocator(), buf, n-1); - String proc_name = make_string_c(str); + String proc_name = lb_internal_gen_proc_name_from_type("__$hasher", type); lbProcedure *p = lb_create_dummy_procedure(m, proc_name, t_hasher_proc); map_set(&m->hasher_procs, type, p); @@ -583,12 +580,8 @@ gb_internal lbValue lb_map_get_proc_for_type(lbModule *m, Type *type) { GB_ASSERT(*found != nullptr); return {(*found)->value, (*found)->type}; } - static std::atomic proc_index; - char buf[32] = {}; - isize n = gb_snprintf(buf, 32, "__$map_get-%u", 1+proc_index.fetch_add(1)); - char *str = gb_alloc_str_len(permanent_allocator(), buf, n-1); - String proc_name = make_string_c(str); + String proc_name = lb_internal_gen_proc_name_from_type("__$map_get", type); lbProcedure *p = lb_create_dummy_procedure(m, proc_name, t_map_get_proc); map_set(&m->map_get_procs, type, p); @@ -764,12 +757,8 @@ gb_internal lbValue lb_map_set_proc_for_type(lbModule *m, Type *type) { GB_ASSERT(*found != nullptr); return {(*found)->value, (*found)->type}; } - static std::atomic proc_index; - char buf[32] = {}; - isize n = gb_snprintf(buf, 32, "__$map_set-%u", 1+proc_index.fetch_add(1)); - char *str = gb_alloc_str_len(permanent_allocator(), buf, n-1); - String proc_name = make_string_c(str); + String proc_name = lb_internal_gen_proc_name_from_type("__$map_set", type); lbProcedure *p = lb_create_dummy_procedure(m, proc_name, t_map_set_proc); map_set(&m->map_set_procs, type, p); diff --git a/src/llvm_backend.hpp b/src/llvm_backend.hpp index dd6f1a083..d596c2d5c 100644 --- a/src/llvm_backend.hpp +++ b/src/llvm_backend.hpp @@ -610,6 +610,9 @@ gb_internal LLVMTypeRef llvm_array_type(LLVMTypeRef ElementType, uint64_t Elemen } +gb_internal String lb_internal_gen_proc_name_from_type(char const *prefix, Type *type); + + gb_internal void lb_set_metadata_custom_u64(lbModule *m, LLVMValueRef v_ref, String name, u64 value); gb_internal u64 lb_get_metadata_custom_u64(lbModule *m, LLVMValueRef v_ref, String name); diff --git a/src/llvm_backend_stmt.cpp b/src/llvm_backend_stmt.cpp index b83472075..758cd353f 100644 --- a/src/llvm_backend_stmt.cpp +++ b/src/llvm_backend_stmt.cpp @@ -5,8 +5,6 @@ gb_internal void lb_build_constant_value_decl(lbProcedure *p, AstValueDecl *vd) auto *min_dep_set = &p->module->info->minimum_dependency_set; - static i32 global_guid = 0; - for (Ast *ident : vd->names) { GB_ASSERT(ident->kind == Ast_Ident); Entity *e = entity_of_node(ident); -- cgit v1.2.3 From f0f395c510a7b0c625b0a222d00ddbe4c63a496b Mon Sep 17 00:00:00 2001 From: gingerBill Date: Mon, 24 Feb 2025 14:24:06 +0000 Subject: Fix canonicalization --- src/llvm_backend.cpp | 19 ++++++++++++------- src/llvm_backend.hpp | 2 +- src/llvm_backend_general.cpp | 26 ++++++++++++++++++++++++++ 3 files changed, 39 insertions(+), 8 deletions(-) (limited to 'src/llvm_backend.cpp') diff --git a/src/llvm_backend.cpp b/src/llvm_backend.cpp index 9bbcc2184..fc56044d3 100644 --- a/src/llvm_backend.cpp +++ b/src/llvm_backend.cpp @@ -233,7 +233,7 @@ gb_internal lbContextData *lb_push_context_onto_stack(lbProcedure *p, lbAddr ctx } -gb_internal String lb_internal_gen_proc_name_from_type(char const *prefix, Type *type) { +gb_internal String lb_internal_gen_name_from_type(char const *prefix, Type *type) { gbString str = gb_string_make(permanent_allocator(), prefix); gbString tcs = temp_canonical_string(type); str = gb_string_appendc(str, CANONICAL_TYPE_SEPARATOR); @@ -259,7 +259,10 @@ gb_internal lbValue lb_equal_proc_for_type(lbModule *m, Type *type) { } - String proc_name = lb_internal_gen_proc_name_from_type("__$equal", type); + String proc_name = lb_internal_gen_name_from_type("__$equal", type); + lbProcedure *p = lb_create_dummy_procedure(m, proc_name, t_equal_proc); + map_set(&m->equal_procs, type, p); + lb_begin_procedure_body(p); // lb_add_attribute_to_proc(m, p->value, "readonly"); lb_add_attribute_to_proc(m, p->value, "nounwind"); @@ -418,7 +421,7 @@ gb_internal lbValue lb_hasher_proc_for_type(lbModule *m, Type *type) { return {(*found)->value, (*found)->type}; } - String proc_name = lb_internal_gen_proc_name_from_type("__$hasher", type); + String proc_name = lb_internal_gen_name_from_type("__$hasher", type); lbProcedure *p = lb_create_dummy_procedure(m, proc_name, t_hasher_proc); map_set(&m->hasher_procs, type, p); @@ -581,7 +584,7 @@ gb_internal lbValue lb_map_get_proc_for_type(lbModule *m, Type *type) { return {(*found)->value, (*found)->type}; } - String proc_name = lb_internal_gen_proc_name_from_type("__$map_get", type); + String proc_name = lb_internal_gen_name_from_type("__$map_get", type); lbProcedure *p = lb_create_dummy_procedure(m, proc_name, t_map_get_proc); map_set(&m->map_get_procs, type, p); @@ -758,7 +761,7 @@ gb_internal lbValue lb_map_set_proc_for_type(lbModule *m, Type *type) { return {(*found)->value, (*found)->type}; } - String proc_name = lb_internal_gen_proc_name_from_type("__$map_set", type); + String proc_name = lb_internal_gen_name_from_type("__$map_set", type); lbProcedure *p = lb_create_dummy_procedure(m, proc_name, t_map_set_proc); map_set(&m->map_set_procs, type, p); @@ -906,7 +909,9 @@ gb_internal lbValue lb_gen_map_cell_info_ptr(lbModule *m, Type *type) { LLVMValueRef llvm_res = llvm_const_named_struct(m, t_map_cell_info, const_values, gb_count_of(const_values)); lbValue res = {llvm_res, t_map_cell_info}; - lbAddr addr = lb_add_global_generated(m, t_map_cell_info, res, nullptr); + lbAddr addr = lb_add_global_generated_with_name(m, t_map_cell_info, res, lb_internal_gen_name_from_type("ggv$map_cell_info", type)); + + lb_add_global_generated(m, t_map_cell_info, res, nullptr); lb_make_global_private_const(addr); map_set(&m->map_cell_info_map, type, addr); @@ -937,7 +942,7 @@ gb_internal lbValue lb_gen_map_info_ptr(lbModule *m, Type *map_type) { LLVMValueRef llvm_res = llvm_const_named_struct(m, t_map_info, const_values, gb_count_of(const_values)); lbValue res = {llvm_res, t_map_info}; - lbAddr addr = lb_add_global_generated(m, t_map_info, res, nullptr); + lbAddr addr = lb_add_global_generated_with_name(m, t_map_info, res, lb_internal_gen_name_from_type("ggv$map_info", map_type)); lb_make_global_private_const(addr); map_set(&m->map_info_map, map_type, addr); diff --git a/src/llvm_backend.hpp b/src/llvm_backend.hpp index d596c2d5c..60ae91f9b 100644 --- a/src/llvm_backend.hpp +++ b/src/llvm_backend.hpp @@ -610,7 +610,7 @@ gb_internal LLVMTypeRef llvm_array_type(LLVMTypeRef ElementType, uint64_t Elemen } -gb_internal String lb_internal_gen_proc_name_from_type(char const *prefix, Type *type); +gb_internal String lb_internal_gen_name_from_type(char const *prefix, Type *type); gb_internal void lb_set_metadata_custom_u64(lbModule *m, LLVMValueRef v_ref, String name, u64 value); diff --git a/src/llvm_backend_general.cpp b/src/llvm_backend_general.cpp index 94a9023d1..96572437c 100644 --- a/src/llvm_backend_general.cpp +++ b/src/llvm_backend_general.cpp @@ -2814,6 +2814,32 @@ gb_internal lbAddr lb_add_global_generated(lbModule *m, Type *type, lbValue valu return lb_addr(g); } +gb_internal lbAddr lb_add_global_generated_with_name(lbModule *m, Type *type, lbValue value, String name) { + GB_ASSERT(type != nullptr); + type = default_type(type); + + isize max_len = 7+8+1; + u8 *str = cast(u8 *)gb_alloc_array(permanent_allocator(), u8, max_len); + + Scope *scope = nullptr; + Entity *e = alloc_entity_variable(scope, make_token_ident(name), type); + lbValue g = {}; + g.type = alloc_type_pointer(type); + g.value = LLVMAddGlobal(m->mod, lb_type(m, type), cast(char const *)str); + if (value.value != nullptr) { + GB_ASSERT_MSG(LLVMIsConstant(value.value), LLVMPrintValueToString(value.value)); + LLVMSetInitializer(g.value, value.value); + } else { + LLVMSetInitializer(g.value, LLVMConstNull(lb_type(m, type))); + } + + lb_add_entity(m, e, g); + lb_add_member(m, name, g); + + return lb_addr(g); +} + + gb_internal lbValue lb_find_runtime_value(lbModule *m, String const &name) { AstPackage *p = m->info->runtime_package; Entity *e = scope_lookup_current(p->scope, name); -- cgit v1.2.3 From 2c86fadee1df955127abf8b4aa73708a35d9d43a Mon Sep 17 00:00:00 2001 From: gingerBill Date: Mon, 24 Feb 2025 14:28:24 +0000 Subject: More name canonicalization for globals --- src/llvm_backend.cpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'src/llvm_backend.cpp') diff --git a/src/llvm_backend.cpp b/src/llvm_backend.cpp index fc56044d3..4c4dc4c51 100644 --- a/src/llvm_backend.cpp +++ b/src/llvm_backend.cpp @@ -910,8 +910,6 @@ gb_internal lbValue lb_gen_map_cell_info_ptr(lbModule *m, Type *type) { lbValue res = {llvm_res, t_map_cell_info}; lbAddr addr = lb_add_global_generated_with_name(m, t_map_cell_info, res, lb_internal_gen_name_from_type("ggv$map_cell_info", type)); - - lb_add_global_generated(m, t_map_cell_info, res, nullptr); lb_make_global_private_const(addr); map_set(&m->map_cell_info_map, type, addr); @@ -1278,7 +1276,10 @@ gb_internal lbProcedure *lb_create_startup_runtime(lbModule *main_module, lbProc if (is_type_any(t)) { // NOTE(bill): Edge case for 'any' type Type *var_type = default_type(var.init.type); - lbAddr g = lb_add_global_generated(main_module, var_type, var.init); + gbString var_name = gb_string_make(permanent_allocator(), "__$global_any::"); + gbString e_str = string_canonical_entity_name(temporary_allocator(), e); + var_name = gb_string_append_length(var_name, e_str, gb_strlen(e_str)); + lbAddr g = lb_add_global_generated_with_name(main_module, var_type, var.init, make_string_c(var_name)); lb_addr_store(p, g, var.init); lbValue gp = lb_addr_get_ptr(p, g); @@ -2819,7 +2820,7 @@ gb_internal lbProcedure *lb_create_main_procedure(lbModule *m, lbProcedure *star Type *t_Internal_Test = find_type_in_pkg(m->info, str_lit("testing"), str_lit("Internal_Test")); Type *array_type = alloc_type_array(t_Internal_Test, m->info->testing_procedures.count); Type *slice_type = alloc_type_slice(t_Internal_Test); - lbAddr all_tests_array_addr = lb_add_global_generated(p->module, array_type, {}); + lbAddr all_tests_array_addr = lb_add_global_generated_with_name(p->module, array_type, {}, str_lit("__$all_tests_array")); lbValue all_tests_array = lb_addr_get_ptr(p, all_tests_array_addr); LLVMValueRef indices[2] = {}; -- cgit v1.2.3 From 83f1c879ecce5ca586f99c89d9d6b89c22555921 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Mon, 24 Feb 2025 15:18:27 +0000 Subject: Canonicalize generated procedures (hasher/equal/map) --- src/llvm_backend.cpp | 57 ++++++++++++++++++-------------------------- src/llvm_backend.hpp | 5 +--- src/llvm_backend_general.cpp | 5 +--- 3 files changed, 25 insertions(+), 42 deletions(-) (limited to 'src/llvm_backend.cpp') diff --git a/src/llvm_backend.cpp b/src/llvm_backend.cpp index 4c4dc4c51..24807a9ba 100644 --- a/src/llvm_backend.cpp +++ b/src/llvm_backend.cpp @@ -235,9 +235,9 @@ gb_internal lbContextData *lb_push_context_onto_stack(lbProcedure *p, lbAddr ctx gb_internal String lb_internal_gen_name_from_type(char const *prefix, Type *type) { gbString str = gb_string_make(permanent_allocator(), prefix); - gbString tcs = temp_canonical_string(type); - str = gb_string_appendc(str, CANONICAL_TYPE_SEPARATOR); - str = gb_string_append_length(str, tcs, gb_string_length(tcs)); + u64 hash = type_hash_canonical_type(type); + str = gb_string_appendc(str, "-"); + str = gb_string_append_fmt(str, "%llu", cast(unsigned long long)hash); String proc_name = make_string(cast(u8 const *)str, gb_string_length(str)); return proc_name; } @@ -250,7 +250,8 @@ gb_internal lbValue lb_equal_proc_for_type(lbModule *m, Type *type) { Type *pt = alloc_type_pointer(type); LLVMTypeRef ptr_type = lb_type(m, pt); - lbProcedure **found = map_get(&m->equal_procs, type); + 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; @@ -259,11 +260,11 @@ gb_internal lbValue lb_equal_proc_for_type(lbModule *m, Type *type) { } - String proc_name = lb_internal_gen_name_from_type("__$equal", type); lbProcedure *p = lb_create_dummy_procedure(m, proc_name, t_equal_proc); - map_set(&m->equal_procs, type, p); + string_map_set(&m->gen_procs, proc_name, p); lb_begin_procedure_body(p); + LLVMSetLinkage(p->value, LLVMInternalLinkage); // lb_add_attribute_to_proc(m, p->value, "readonly"); lb_add_attribute_to_proc(m, p->value, "nounwind"); @@ -415,19 +416,19 @@ gb_internal lbValue lb_hasher_proc_for_type(lbModule *m, Type *type) { Type *pt = alloc_type_pointer(type); - lbProcedure **found = map_get(&m->hasher_procs, type); + String proc_name = lb_internal_gen_name_from_type("__$hasher", type); + lbProcedure **found = string_map_get(&m->gen_procs, proc_name); if (found) { GB_ASSERT(*found != nullptr); return {(*found)->value, (*found)->type}; } - String proc_name = lb_internal_gen_name_from_type("__$hasher", type); - lbProcedure *p = lb_create_dummy_procedure(m, proc_name, t_hasher_proc); - map_set(&m->hasher_procs, type, p); + string_map_set(&m->gen_procs, proc_name, p); lb_begin_procedure_body(p); defer (lb_end_procedure_body(p)); + LLVMSetLinkage(p->value, LLVMInternalLinkage); // lb_add_attribute_to_proc(m, p->value, "readonly"); lb_add_attribute_to_proc(m, p->value, "nounwind"); @@ -577,17 +578,15 @@ gb_internal lbValue lb_map_get_proc_for_type(lbModule *m, Type *type) { type = base_type(type); GB_ASSERT(type->kind == Type_Map); - - lbProcedure **found = map_get(&m->map_get_procs, type); + String proc_name = lb_internal_gen_name_from_type("__$map_get", type); + lbProcedure **found = string_map_get(&m->gen_procs, proc_name); if (found) { GB_ASSERT(*found != nullptr); return {(*found)->value, (*found)->type}; } - String proc_name = lb_internal_gen_name_from_type("__$map_get", type); - lbProcedure *p = lb_create_dummy_procedure(m, proc_name, t_map_get_proc); - map_set(&m->map_get_procs, type, p); + string_map_set(&m->gen_procs, proc_name, p); lb_begin_procedure_body(p); defer (lb_end_procedure_body(p)); @@ -754,17 +753,15 @@ gb_internal lbValue lb_map_set_proc_for_type(lbModule *m, Type *type) { type = base_type(type); GB_ASSERT(type->kind == Type_Map); - - lbProcedure **found = map_get(&m->map_set_procs, type); + String proc_name = lb_internal_gen_name_from_type("__$map_set", type); + lbProcedure **found = string_map_get(&m->gen_procs, proc_name); if (found) { GB_ASSERT(*found != nullptr); return {(*found)->value, (*found)->type}; } - String proc_name = lb_internal_gen_name_from_type("__$map_set", type); - lbProcedure *p = lb_create_dummy_procedure(m, proc_name, t_map_set_proc); - map_set(&m->map_set_procs, type, p); + string_map_set(&m->gen_procs, proc_name, p); lb_begin_procedure_body(p); defer (lb_end_procedure_body(p)); @@ -1558,21 +1555,13 @@ gb_internal WORKER_TASK_PROC(lb_llvm_function_pass_per_module) { } } - for (auto const &entry : m->equal_procs) { + for (auto const &entry : m->gen_procs) { lbProcedure *p = entry.value; - lb_llvm_function_pass_per_function_internal(m, p); - } - for (auto const &entry : m->hasher_procs) { - lbProcedure *p = entry.value; - lb_llvm_function_pass_per_function_internal(m, p); - } - for (auto const &entry : m->map_get_procs) { - lbProcedure *p = entry.value; - lb_llvm_function_pass_per_function_internal(m, p, lbFunctionPassManager_none); - } - for (auto const &entry : m->map_set_procs) { - lbProcedure *p = entry.value; - lb_llvm_function_pass_per_function_internal(m, p, lbFunctionPassManager_none); + if (string_starts_with(p->name, str_lit("__$map"))) { + lb_llvm_function_pass_per_function_internal(m, p, lbFunctionPassManager_none); + } else { + lb_llvm_function_pass_per_function_internal(m, p); + } } return 0; diff --git a/src/llvm_backend.hpp b/src/llvm_backend.hpp index 60ae91f9b..3617c267f 100644 --- a/src/llvm_backend.hpp +++ b/src/llvm_backend.hpp @@ -180,10 +180,7 @@ struct lbModule { PtrMap function_type_map; - PtrMap equal_procs; - PtrMap hasher_procs; - PtrMap map_get_procs; - PtrMap map_set_procs; + StringMap gen_procs; // key is the canonicalized name std::atomic nested_type_name_guid; diff --git a/src/llvm_backend_general.cpp b/src/llvm_backend_general.cpp index 96572437c..80856ac8c 100644 --- a/src/llvm_backend_general.cpp +++ b/src/llvm_backend_general.cpp @@ -67,10 +67,7 @@ gb_internal void lb_init_module(lbModule *m, Checker *c) { string_map_init(&m->procedures); string_map_init(&m->const_strings); map_init(&m->function_type_map); - map_init(&m->equal_procs); - map_init(&m->hasher_procs); - map_init(&m->map_get_procs); - map_init(&m->map_set_procs); + string_map_init(&m->gen_procs); if (USE_SEPARATE_MODULES) { array_init(&m->procedures_to_generate, a, 0, 1<<10); map_init(&m->procedure_values, 1<<11); -- cgit v1.2.3 From fd6d7d412dbf666bbd10eddc98b04e1af3ef9f81 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Tue, 25 Feb 2025 14:55:33 +0000 Subject: Use more predictable object name --- src/llvm_backend.cpp | 40 ++++++++++++++++++++-------------------- src/llvm_backend_general.cpp | 15 +++++++++------ src/llvm_backend_utility.cpp | 4 ++-- 3 files changed, 31 insertions(+), 28 deletions(-) (limited to 'src/llvm_backend.cpp') diff --git a/src/llvm_backend.cpp b/src/llvm_backend.cpp index 24807a9ba..9cf996e84 100644 --- a/src/llvm_backend.cpp +++ b/src/llvm_backend.cpp @@ -2559,17 +2559,15 @@ gb_internal String lb_filepath_ll_for_module(lbModule *m) { build_context.build_paths[BuildPath_Output].name ); - if (m->file) { - char buf[32] = {}; - isize n = gb_snprintf(buf, gb_size_of(buf), "-%u", m->file->id); - String suffix = make_string((u8 *)buf, n-1); - path = concatenate_strings(permanent_allocator(), path, suffix); - } else if (m->pkg) { - path = concatenate3_strings(permanent_allocator(), path, STR_LIT("-"), m->pkg->name); - } else if (USE_SEPARATE_MODULES) { - path = concatenate_strings(permanent_allocator(), path, STR_LIT("-builtin")); - } - path = concatenate_strings(permanent_allocator(), path, STR_LIT(".ll")); + GB_ASSERT(m->module_name != nullptr); + String s = make_string_c(m->module_name); + String prefix = str_lit("odin_package-"); + GB_ASSERT(string_starts_with(s, prefix)); + s.text += prefix.len; + s.len -= prefix.len; + + path = concatenate_strings(permanent_allocator(), path, s); + path = concatenate_strings(permanent_allocator(), s, STR_LIT(".ll")); return path; } @@ -2592,14 +2590,16 @@ gb_internal String lb_filepath_obj_for_module(lbModule *m) { path = gb_string_appendc(path, "/"); path = gb_string_append_length(path, name.text, name.len); - if (m->file) { - char buf[32] = {}; - isize n = gb_snprintf(buf, gb_size_of(buf), "-%u", m->file->id); - String suffix = make_string((u8 *)buf, n-1); - path = gb_string_append_length(path, suffix.text, suffix.len); - } else if (m->pkg) { - path = gb_string_appendc(path, "-"); - path = gb_string_append_length(path, m->pkg->name.text, m->pkg->name.len); + { + + GB_ASSERT(m->module_name != nullptr); + String s = make_string_c(m->module_name); + String prefix = str_lit("odin_package"); + GB_ASSERT(string_starts_with(s, prefix)); + s.text += prefix.len; + s.len -= prefix.len; + + path = gb_string_append_length(path, s.text, s.len); } if (use_temporary_directory) { @@ -3153,7 +3153,7 @@ gb_internal bool lb_generate_code(lbGenerator *gen) { LLVMValueRef g = LLVMAddGlobal(m->mod, internal_llvm_type, LB_TYPE_INFO_DATA_NAME); LLVMSetInitializer(g, LLVMConstNull(internal_llvm_type)); LLVMSetLinkage(g, USE_SEPARATE_MODULES ? LLVMExternalLinkage : LLVMInternalLinkage); - LLVMSetUnnamedAddress(g, LLVMGlobalUnnamedAddr); + // LLVMSetUnnamedAddress(g, LLVMGlobalUnnamedAddr); LLVMSetGlobalConstant(g, true); lbValue value = {}; diff --git a/src/llvm_backend_general.cpp b/src/llvm_backend_general.cpp index b994ec330..2d19097c7 100644 --- a/src/llvm_backend_general.cpp +++ b/src/llvm_backend_general.cpp @@ -221,7 +221,7 @@ gb_internal void lb_loop_end(lbProcedure *p, lbLoopData const &data) { gb_internal void lb_make_global_private_const(LLVMValueRef global_data) { LLVMSetLinkage(global_data, LLVMLinkerPrivateLinkage); - LLVMSetUnnamedAddress(global_data, LLVMGlobalUnnamedAddr); + // LLVMSetUnnamedAddress(global_data, LLVMGlobalUnnamedAddr); LLVMSetGlobalConstant(global_data, true); } gb_internal void lb_make_global_private_const(lbAddr const &addr) { @@ -2786,6 +2786,7 @@ gb_internal lbValue lb_generate_anonymous_proc_lit(lbModule *m, String const &pr gb_internal lbAddr lb_add_global_generated_with_name(lbModule *m, Type *type, lbValue value, String name, Entity **entity_) { + GB_ASSERT(name.len != 0); GB_ASSERT(type != nullptr); type = default_type(type); @@ -2817,12 +2818,14 @@ gb_internal lbAddr lb_add_global_generated_from_procedure(lbProcedure *p, Type * GB_ASSERT(type != nullptr); type = default_type(type); - u32 index = ++p->global_generated_index; + static std::atomic global_index; + u32 index = ++global_index; + // u32 index = ++p->global_generated_index; gbString s = gb_string_make(temporary_allocator(), "ggv$"); - s = gb_string_appendc(s, p->module->module_name); - s = gb_string_appendc(s, "$"); - s = gb_string_append_length(s, p->name.text, p->name.len); + // s = gb_string_appendc(s, p->module->module_name); + // s = gb_string_appendc(s, "$"); + // s = gb_string_append_length(s, p->name.text, p->name.len); s = gb_string_append_fmt(s, "$%u", index); String name = make_string(cast(u8 const *)s, gb_string_length(s)); @@ -2938,7 +2941,7 @@ gb_internal lbValue lb_generate_global_array(lbModule *m, Type *elem_type, i64 c g.type = alloc_type_pointer(t); LLVMSetInitializer(g.value, LLVMConstNull(lb_type(m, t))); LLVMSetLinkage(g.value, LLVMPrivateLinkage); - LLVMSetUnnamedAddress(g.value, LLVMGlobalUnnamedAddr); + // LLVMSetUnnamedAddress(g.value, LLVMGlobalUnnamedAddr); string_map_set(&m->members, s, g); return g; } diff --git a/src/llvm_backend_utility.cpp b/src/llvm_backend_utility.cpp index 9624a78e6..c876169f3 100644 --- a/src/llvm_backend_utility.cpp +++ b/src/llvm_backend_utility.cpp @@ -2112,7 +2112,7 @@ gb_internal lbAddr lb_handle_objc_find_or_register_selector(lbProcedure *p, Stri } if (!entity) { - gbString global_name = gb_string_make(temporary_allocator(), "__$objc_selector-"); + gbString global_name = gb_string_make(temporary_allocator(), "__$objc_SEL$"); global_name = gb_string_append_length(global_name, name.text, name.len); lbAddr default_addr = lb_add_global_generated_with_name( @@ -2175,7 +2175,7 @@ gb_internal lbAddr lb_handle_objc_find_or_register_class(lbProcedure *p, String } if (!entity) { - gbString global_name = gb_string_make(temporary_allocator(), "__$objc_class-"); + gbString global_name = gb_string_make(temporary_allocator(), "__$objc_Class$"); global_name = gb_string_append_length(global_name, name.text, name.len); lbAddr default_addr = lb_add_global_generated_with_name(default_module, t_objc_Class, {}, -- cgit v1.2.3 From 66540b75f50315e372a74545de7fe91d04b1be62 Mon Sep 17 00:00:00 2001 From: Laytan Laats Date: Sat, 1 Mar 2025 16:06:32 +0100 Subject: fix hidden linkage applied to foreign symbols --- src/llvm_backend.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/llvm_backend.cpp') diff --git a/src/llvm_backend.cpp b/src/llvm_backend.cpp index 9cf996e84..f21ca9f75 100644 --- a/src/llvm_backend.cpp +++ b/src/llvm_backend.cpp @@ -169,7 +169,7 @@ gb_internal void lb_correct_entity_linkage(lbGenerator *gen) { other_global = LLVMGetNamedGlobal(ec.other_module->mod, ec.cname); if (other_global) { LLVMSetLinkage(other_global, LLVMWeakAnyLinkage); - if (!ec.e->Variable.is_export) { + if (!ec.e->Variable.is_export && !ec.e->Variable.is_foreign) { LLVMSetVisibility(other_global, LLVMHiddenVisibility); } } @@ -177,7 +177,7 @@ gb_internal void lb_correct_entity_linkage(lbGenerator *gen) { other_global = LLVMGetNamedFunction(ec.other_module->mod, ec.cname); if (other_global) { LLVMSetLinkage(other_global, LLVMWeakAnyLinkage); - if (!ec.e->Procedure.is_export) { + if (!ec.e->Procedure.is_export && !ec.e->Procedure.is_foreign) { LLVMSetVisibility(other_global, LLVMHiddenVisibility); } } -- cgit v1.2.3 From 211680569f93db8896fafa9693158725925138fd Mon Sep 17 00:00:00 2001 From: gingerBill Date: Sat, 1 Mar 2025 15:19:46 +0000 Subject: Fix for `-use-single-module` --- src/llvm_backend.cpp | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) (limited to 'src/llvm_backend.cpp') diff --git a/src/llvm_backend.cpp b/src/llvm_backend.cpp index 9cf996e84..a9cca2695 100644 --- a/src/llvm_backend.cpp +++ b/src/llvm_backend.cpp @@ -2562,9 +2562,10 @@ gb_internal String lb_filepath_ll_for_module(lbModule *m) { GB_ASSERT(m->module_name != nullptr); String s = make_string_c(m->module_name); String prefix = str_lit("odin_package-"); - GB_ASSERT(string_starts_with(s, prefix)); - s.text += prefix.len; - s.len -= prefix.len; + if (string_starts_with(s, prefix)) { + s.text += prefix.len; + s.len -= prefix.len; + } path = concatenate_strings(permanent_allocator(), path, s); path = concatenate_strings(permanent_allocator(), s, STR_LIT(".ll")); @@ -2595,14 +2596,16 @@ gb_internal String lb_filepath_obj_for_module(lbModule *m) { GB_ASSERT(m->module_name != nullptr); String s = make_string_c(m->module_name); String prefix = str_lit("odin_package"); - GB_ASSERT(string_starts_with(s, prefix)); - s.text += prefix.len; - s.len -= prefix.len; + if (string_starts_with(s, prefix)) { + s.text += prefix.len; + s.len -= prefix.len; + } path = gb_string_append_length(path, s.text, s.len); } if (use_temporary_directory) { + // NOTE(bill): this must be suffixed to ensure it is not conflicting with anything else in the temporary directory path = gb_string_append_fmt(path, "-%p", m); } -- cgit v1.2.3