From 529383f5b17d74f66bebb8679820a69476635b6a Mon Sep 17 00:00:00 2001 From: gingerBill Date: Mon, 2 Jan 2023 15:30:04 +0000 Subject: Correct a race condition when checking the procedure body --- src/llvm_backend_stmt.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'src/llvm_backend_stmt.cpp') diff --git a/src/llvm_backend_stmt.cpp b/src/llvm_backend_stmt.cpp index 6400a8a9d..cdfb28aa7 100644 --- a/src/llvm_backend_stmt.cpp +++ b/src/llvm_backend_stmt.cpp @@ -1531,6 +1531,9 @@ gb_internal void lb_build_static_variables(lbProcedure *p, AstValueDecl *vd) { lbValue global_val = {global, alloc_type_pointer(e->type)}; lb_add_entity(p->module, e, global_val); lb_add_member(p->module, mangled_name, global_val); + if (e) { + map_set(&p->local_entity_map, e, global_val); + } } } gb_internal void lb_append_tuple_values(lbProcedure *p, Array *dst_values, lbValue src_value) { @@ -2188,9 +2191,10 @@ gb_internal void lb_build_stmt(lbProcedure *p, Ast *node) { for_array(i, vd->names) { Ast *name = vd->names[i]; if (!is_blank_ident(name)) { + GB_ASSERT(name->kind == Ast_Ident); Entity *e = entity_of_node(name); TokenPos pos = ast_token(name).pos; - GB_ASSERT_MSG(e != nullptr, "%s", token_pos_to_string(pos)); + GB_ASSERT_MSG(e != nullptr, "\n%s missing entity for %.*s", token_pos_to_string(pos), LIT(name->Ident.token.string)); if (e->flags & EntityFlag_Static) { // NOTE(bill): If one of the entities is static, they all are is_static = true; -- cgit v1.2.3 From fa562ec5d60319f5cd7e85bb337bd21feb7ceeb8 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Mon, 2 Jan 2023 15:40:25 +0000 Subject: Remove unneeded `local_entity_map` --- src/llvm_backend.hpp | 1 - src/llvm_backend_expr.cpp | 6 +----- src/llvm_backend_general.cpp | 4 ---- src/llvm_backend_proc.cpp | 1 - src/llvm_backend_stmt.cpp | 3 --- 5 files changed, 1 insertion(+), 14 deletions(-) (limited to 'src/llvm_backend_stmt.cpp') diff --git a/src/llvm_backend.hpp b/src/llvm_backend.hpp index 50fb5701f..9f7caa3bb 100644 --- a/src/llvm_backend.hpp +++ b/src/llvm_backend.hpp @@ -301,7 +301,6 @@ struct lbProcedure { lbBlock * curr_block; lbTargetList * target_list; PtrMap direct_parameters; - PtrMap local_entity_map; Ast *curr_stmt; diff --git a/src/llvm_backend_expr.cpp b/src/llvm_backend_expr.cpp index 28a68b065..d574caf4c 100644 --- a/src/llvm_backend_expr.cpp +++ b/src/llvm_backend_expr.cpp @@ -3404,11 +3404,7 @@ gb_internal lbAddr lb_build_addr_from_entity(lbProcedure *p, Entity *e, Ast *exp lbValue v = {}; - lbValue *found = nullptr; - found = map_get(&p->local_entity_map, e); - if (found == nullptr) { - found = map_get(&p->module->values, e); - } + lbValue *found = map_get(&p->module->values, e); if (found) { v = *found; } else if (e->kind == Entity_Variable && e->flags & EntityFlag_Using) { diff --git a/src/llvm_backend_general.cpp b/src/llvm_backend_general.cpp index 940c94a13..22628e895 100644 --- a/src/llvm_backend_general.cpp +++ b/src/llvm_backend_general.cpp @@ -2844,10 +2844,6 @@ gb_internal lbAddr lb_add_local(lbProcedure *p, Type *type, Entity *e, bool zero lb_mem_zero_ptr(p, ptr, type, alignment); } - if (e != nullptr) { - map_set(&p->local_entity_map, e, val); - } - return lb_addr(val); } diff --git a/src/llvm_backend_proc.cpp b/src/llvm_backend_proc.cpp index 9691afebc..7245bdd80 100644 --- a/src/llvm_backend_proc.cpp +++ b/src/llvm_backend_proc.cpp @@ -487,7 +487,6 @@ gb_internal void lb_begin_procedure_body(lbProcedure *p) { lb_start_block(p, p->entry_block); map_init(&p->direct_parameters, heap_allocator()); - map_init(&p->local_entity_map, heap_allocator()); GB_ASSERT(p->type != nullptr); diff --git a/src/llvm_backend_stmt.cpp b/src/llvm_backend_stmt.cpp index cdfb28aa7..06abebc78 100644 --- a/src/llvm_backend_stmt.cpp +++ b/src/llvm_backend_stmt.cpp @@ -1531,9 +1531,6 @@ gb_internal void lb_build_static_variables(lbProcedure *p, AstValueDecl *vd) { lbValue global_val = {global, alloc_type_pointer(e->type)}; lb_add_entity(p->module, e, global_val); lb_add_member(p->module, mangled_name, global_val); - if (e) { - map_set(&p->local_entity_map, e, global_val); - } } } gb_internal void lb_append_tuple_values(lbProcedure *p, Array *dst_values, lbValue src_value) { -- cgit v1.2.3 From c293f5b7ebc3b733e996a97c6e32d678f13b3ee5 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Mon, 2 Jan 2023 16:56:05 +0000 Subject: Remove unneeded mutex --- src/check_expr.cpp | 33 +++++++++++++++++---------------- src/checker.hpp | 7 ++++++- src/common_memory.cpp | 18 ++++++------------ src/llvm_backend_stmt.cpp | 5 ++--- src/main.cpp | 3 +-- src/threading.cpp | 17 +++++++++-------- 6 files changed, 41 insertions(+), 42 deletions(-) (limited to 'src/llvm_backend_stmt.cpp') diff --git a/src/check_expr.cpp b/src/check_expr.cpp index 5445e73c7..f47361c27 100644 --- a/src/check_expr.cpp +++ b/src/check_expr.cpp @@ -193,8 +193,7 @@ gb_internal void check_did_you_mean_objc_entity(String const &name, Entity *e, b GB_ASSERT(e->kind == Entity_TypeName); GB_ASSERT(e->TypeName.objc_metadata != nullptr); auto *objc_metadata = e->TypeName.objc_metadata; - mutex_lock(objc_metadata->mutex); - defer (mutex_unlock(objc_metadata->mutex)); + MUTEX_GUARD(objc_metadata->mutex); StringSet set = {}; string_set_init(&set, heap_allocator()); @@ -369,8 +368,7 @@ gb_internal bool find_or_generate_polymorphic_procedure(CheckerContext *old_c, E GB_ASSERT(dst == nullptr); } - mutex_lock(&info->gen_procs_mutex); - defer (mutex_unlock(&info->gen_procs_mutex)); + // MUTEX_GUARD(&info->gen_procs_mutex); if (!src->Proc.is_polymorphic || src->Proc.is_poly_specialized) { return false; @@ -436,11 +434,14 @@ gb_internal bool find_or_generate_polymorphic_procedure(CheckerContext *old_c, E return false; } - auto *found_gen_procs = map_get(&info->gen_procs, base_entity->identifier.load()); + GenProcsData *found_gen_procs = nullptr; + + MUTEX_GUARD(&info->gen_procs_mutex); + + found_gen_procs = map_get(&info->gen_procs, base_entity->identifier.load()); if (found_gen_procs) { - auto procs = *found_gen_procs; - for_array(i, procs) { - Entity *other = procs[i]; + MUTEX_GUARD(&found_gen_procs->mutex); + for (Entity *other : found_gen_procs->procs) { Type *pt = base_type(other->type); if (are_types_identical(pt, final_proc_type)) { if (poly_proc_data) { @@ -463,15 +464,13 @@ gb_internal bool find_or_generate_polymorphic_procedure(CheckerContext *old_c, E // LEAK TODO(bill): Cloning this AST may be leaky Ast *cloned_proc_type_node = clone_ast(pt->node); success = check_procedure_type(&nctx, final_proc_type, cloned_proc_type_node, &operands); - if (!success) { return false; } if (found_gen_procs) { - auto procs = *found_gen_procs; - for_array(i, procs) { - Entity *other = procs[i]; + MUTEX_GUARD(&found_gen_procs->mutex); + for (Entity *other : found_gen_procs->procs) { Type *pt = base_type(other->type); if (are_types_identical(pt, final_proc_type)) { if (poly_proc_data) { @@ -567,11 +566,13 @@ gb_internal bool find_or_generate_polymorphic_procedure(CheckerContext *old_c, E proc_info->poly_def_node = poly_def_node; if (found_gen_procs) { - array_add(found_gen_procs, entity); + MUTEX_GUARD(&found_gen_procs->mutex); + array_add(&found_gen_procs->procs, entity); } else { - auto array = array_make(heap_allocator()); - array_add(&array, entity); - map_set(&info->gen_procs, base_entity->identifier.load(), array); + GenProcsData gen_proc_data = {}; + gen_proc_data.procs = array_make(heap_allocator()); + array_add(&gen_proc_data.procs, entity); + map_set(&info->gen_procs, base_entity->identifier.load(), gen_proc_data); } if (poly_proc_data) { diff --git a/src/checker.hpp b/src/checker.hpp index 37aff41b1..56f8707d3 100644 --- a/src/checker.hpp +++ b/src/checker.hpp @@ -311,6 +311,11 @@ struct LoadFileCache { StringMap hashes; }; +struct GenProcsData { + Array procs; + BlockingMutex mutex; +}; + // CheckerInfo stores all the symbol information for a type-checked program struct CheckerInfo { Checker *checker; @@ -360,7 +365,7 @@ struct CheckerInfo { RecursiveMutex gen_procs_mutex; RecursiveMutex gen_types_mutex; - PtrMap > gen_procs; // Key: Ast * | Identifier -> Entity + PtrMap gen_procs; // Key: Ast * | Identifier -> Entity PtrMap > gen_types; BlockingMutex type_info_mutex; // NOT recursive diff --git a/src/common_memory.cpp b/src/common_memory.cpp index 2022554cf..cdf2281fe 100644 --- a/src/common_memory.cpp +++ b/src/common_memory.cpp @@ -37,7 +37,6 @@ gb_internal gb_inline void *align_formula_ptr(void *ptr, isize align) { gb_global BlockingMutex global_memory_block_mutex; -gb_global BlockingMutex global_memory_allocator_mutex; gb_internal void platform_virtual_memory_init(void); @@ -55,9 +54,9 @@ struct MemoryBlock { }; struct Arena { - MemoryBlock *curr_block; - isize minimum_block_size; - bool ignore_mutex; + MemoryBlock * curr_block; + isize minimum_block_size; + BlockingMutex mutex; }; enum { DEFAULT_MINIMUM_BLOCK_SIZE = 8ll*1024ll*1024ll }; @@ -83,10 +82,7 @@ gb_internal isize arena_align_forward_offset(Arena *arena, isize alignment) { gb_internal void *arena_alloc(Arena *arena, isize min_size, isize alignment) { GB_ASSERT(gb_is_power_of_two(alignment)); - BlockingMutex *mutex = &global_memory_allocator_mutex; - if (!arena->ignore_mutex) { - mutex_lock(mutex); - } + mutex_lock(&arena->mutex); isize size = 0; if (arena->curr_block != nullptr) { @@ -113,9 +109,7 @@ gb_internal void *arena_alloc(Arena *arena, isize min_size, isize alignment) { curr_block->used += size; GB_ASSERT(curr_block->used <= curr_block->size); - if (!arena->ignore_mutex) { - mutex_unlock(mutex); - } + mutex_unlock(&arena->mutex); // NOTE(bill): memory will be zeroed by default due to virtual memory return ptr; @@ -304,7 +298,7 @@ gb_internal GB_ALLOCATOR_PROC(arena_allocator_proc) { } -gb_global gb_thread_local Arena permanent_arena = {nullptr, DEFAULT_MINIMUM_BLOCK_SIZE, true}; +gb_global gb_thread_local Arena permanent_arena = {nullptr, DEFAULT_MINIMUM_BLOCK_SIZE}; gb_internal gbAllocator permanent_allocator() { return arena_allocator(&permanent_arena); } diff --git a/src/llvm_backend_stmt.cpp b/src/llvm_backend_stmt.cpp index 06abebc78..8742423a5 100644 --- a/src/llvm_backend_stmt.cpp +++ b/src/llvm_backend_stmt.cpp @@ -57,9 +57,8 @@ gb_internal void lb_build_constant_value_decl(lbProcedure *p, AstValueDecl *vd) if (pl->body != nullptr) { auto *found = map_get(&info->gen_procs, ident); if (found) { - auto procs = *found; - for_array(i, procs) { - Entity *e = procs[i]; + MUTEX_GUARD(&found->mutex); + for (Entity *e : found->procs) { if (!ptr_set_exists(min_dep_set, e)) { continue; } diff --git a/src/main.cpp b/src/main.cpp index 42d6f8e87..ad9d6b0ef 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -17,8 +17,7 @@ gb_global ThreadPool global_thread_pool; gb_internal void init_global_thread_pool(void) { isize thread_count = gb_max(build_context.thread_count, 1); - isize worker_count = thread_count-1; // NOTE(bill): The main thread will also be used for work - thread_pool_init(&global_thread_pool, permanent_allocator(), worker_count, "ThreadPoolWorker"); + thread_pool_init(&global_thread_pool, permanent_allocator(), thread_count, "ThreadPoolWorker"); } gb_internal bool thread_pool_add_task(WorkerTaskProc *proc, void *data) { return thread_pool_add_task(&global_thread_pool, proc, data); diff --git a/src/threading.cpp b/src/threading.cpp index 4c7aa8f92..c5db5d1b4 100644 --- a/src/threading.cpp +++ b/src/threading.cpp @@ -77,22 +77,23 @@ gb_internal void yield_process(void); struct MutexGuard { - MutexGuard() = delete; + MutexGuard() = delete; MutexGuard(MutexGuard const &) = delete; + MutexGuard(MutexGuard &&) = delete; - MutexGuard(BlockingMutex *bm) : bm{bm} { + explicit MutexGuard(BlockingMutex *bm) noexcept : bm{bm} { mutex_lock(this->bm); } - MutexGuard(RecursiveMutex *rm) : rm{rm} { + explicit MutexGuard(RecursiveMutex *rm) noexcept : rm{rm} { mutex_lock(this->rm); } - MutexGuard(BlockingMutex &bm) : bm{&bm} { + explicit MutexGuard(BlockingMutex &bm) noexcept : bm{&bm} { mutex_lock(this->bm); } - MutexGuard(RecursiveMutex &rm) : rm{&rm} { + explicit MutexGuard(RecursiveMutex &rm) noexcept : rm{&rm} { mutex_lock(this->rm); } - ~MutexGuard() { + ~MutexGuard() noexcept { if (this->bm) { mutex_unlock(this->bm); } else if (this->rm) { @@ -100,14 +101,14 @@ struct MutexGuard { } } - operator bool() const { return true; } + operator bool() const noexcept { return true; } BlockingMutex *bm; RecursiveMutex *rm; }; #define MUTEX_GUARD_BLOCK(m) if (MutexGuard GB_DEFER_3(_mutex_guard_){m}) -#define MUTEX_GUARD(m) MutexGuard GB_DEFER_3(_mutex_guard_){m} +#define MUTEX_GUARD(m) mutex_lock(m); defer (mutex_unlock(m)) struct RecursiveMutex { -- cgit v1.2.3 From 8ece92f1f69217ae5b143cf0e7d812c0f857fa8d Mon Sep 17 00:00:00 2001 From: gingerBill Date: Mon, 2 Jan 2023 23:21:16 +0000 Subject: Minimize the parapoly mutex usage a bit --- src/check_expr.cpp | 94 +++++++++++++++++++++-------------------------- src/checker.hpp | 2 +- src/llvm_backend_stmt.cpp | 5 ++- 3 files changed, 46 insertions(+), 55 deletions(-) (limited to 'src/llvm_backend_stmt.cpp') diff --git a/src/check_expr.cpp b/src/check_expr.cpp index 9feac93ea..65a411dc1 100644 --- a/src/check_expr.cpp +++ b/src/check_expr.cpp @@ -434,20 +434,22 @@ gb_internal bool find_or_generate_polymorphic_procedure(CheckerContext *old_c, E return false; } - GenProcsData *found_gen_procs = nullptr; + GenProcsData *gen_procs = nullptr; - // @@GPM + // @@GPM ////////////////////////// mutex_lock(&info->gen_procs_mutex); + /////////////////////////////////// - found_gen_procs = map_get(&info->gen_procs, base_entity->identifier.load()); - - if (found_gen_procs) { - MUTEX_GUARD(&found_gen_procs->mutex); - for (Entity *other : found_gen_procs->procs) { + auto *found = map_get(&info->gen_procs, base_entity->identifier.load()); + if (found) { + gen_procs = *found; + MUTEX_GUARD(&gen_procs->mutex); + for (Entity *other : gen_procs->procs) { Type *pt = base_type(other->type); if (are_types_identical(pt, final_proc_type)) { - // @@GPM + // @@GPM //////////////////////////// mutex_unlock(&info->gen_procs_mutex); + ///////////////////////////////////// if (poly_proc_data) { poly_proc_data->gen_entity = other; @@ -455,6 +457,10 @@ gb_internal bool find_or_generate_polymorphic_procedure(CheckerContext *old_c, E return true; } } + } else { + gen_procs = gb_alloc_item(permanent_allocator(), GenProcsData); + gen_procs->procs.allocator = heap_allocator(); + map_set(&info->gen_procs, base_entity->identifier.load(), gen_procs); } { @@ -469,50 +475,43 @@ gb_internal bool find_or_generate_polymorphic_procedure(CheckerContext *old_c, E // LEAK TODO(bill): Cloning this AST may be leaky Ast *cloned_proc_type_node = clone_ast(pt->node); success = check_procedure_type(&nctx, final_proc_type, cloned_proc_type_node, &operands); + + // @@GPM //////////////////////////// + mutex_unlock(&info->gen_procs_mutex); + ///////////////////////////////////// + if (!success) { - // @@GPM - mutex_unlock(&info->gen_procs_mutex); return false; } - if (found_gen_procs) { - MUTEX_GUARD(&found_gen_procs->mutex); - for (Entity *other : found_gen_procs->procs) { - Type *pt = base_type(other->type); - if (are_types_identical(pt, final_proc_type)) { - // @@GPM - mutex_unlock(&info->gen_procs_mutex); - - if (poly_proc_data) { - poly_proc_data->gen_entity = other; - } + MUTEX_GUARD(&gen_procs->mutex); + for (Entity *other : gen_procs->procs) { + Type *pt = base_type(other->type); + if (are_types_identical(pt, final_proc_type)) { + if (poly_proc_data) { + poly_proc_data->gen_entity = other; + } - DeclInfo *decl = other->decl_info; - if (decl->proc_checked_state != ProcCheckedState_Checked) { - ProcInfo *proc_info = gb_alloc_item(permanent_allocator(), ProcInfo); - proc_info->file = other->file; - proc_info->token = other->token; - proc_info->decl = decl; - proc_info->type = other->type; - proc_info->body = decl->proc_lit->ProcLit.body; - proc_info->tags = other->Procedure.tags;; - proc_info->generated_from_polymorphic = true; - proc_info->poly_def_node = poly_def_node; - - check_procedure_later(nctx.checker, proc_info); - } + DeclInfo *decl = other->decl_info; + if (decl->proc_checked_state != ProcCheckedState_Checked) { + ProcInfo *proc_info = gb_alloc_item(permanent_allocator(), ProcInfo); + proc_info->file = other->file; + proc_info->token = other->token; + proc_info->decl = decl; + proc_info->type = other->type; + proc_info->body = decl->proc_lit->ProcLit.body; + proc_info->tags = other->Procedure.tags;; + proc_info->generated_from_polymorphic = true; + proc_info->poly_def_node = poly_def_node; - return true; + check_procedure_later(nctx.checker, proc_info); } + + return true; } } } - if (found_gen_procs) { - // @@GPM - mutex_unlock(&info->gen_procs_mutex); - } - Ast *proc_lit = clone_ast(old_decl->proc_lit); ast_node(pl, ProcLit, proc_lit); @@ -570,17 +569,8 @@ gb_internal bool find_or_generate_polymorphic_procedure(CheckerContext *old_c, E } } - if (found_gen_procs) { - MUTEX_GUARD(&found_gen_procs->mutex); - array_add(&found_gen_procs->procs, entity); - } else { - GenProcsData gen_proc_data = {}; - gen_proc_data.procs = array_make(heap_allocator()); - array_add(&gen_proc_data.procs, entity); - map_set(&info->gen_procs, base_entity->identifier.load(), gen_proc_data); - - // @@GPM - mutex_unlock(&info->gen_procs_mutex); + MUTEX_GUARD_BLOCK(&gen_procs->mutex) { + array_add(&gen_procs->procs, entity); } ProcInfo *proc_info = gb_alloc_item(permanent_allocator(), ProcInfo); diff --git a/src/checker.hpp b/src/checker.hpp index 04cb1e311..cc92fce28 100644 --- a/src/checker.hpp +++ b/src/checker.hpp @@ -369,7 +369,7 @@ struct CheckerInfo { RecursiveMutex gen_procs_mutex; RecursiveMutex gen_types_mutex; - PtrMap gen_procs; // Key: Ast * | Identifier -> Entity + PtrMap gen_procs; // Key: Ast * | Identifier -> Entity PtrMap > gen_types; BlockingMutex type_info_mutex; // NOT recursive diff --git a/src/llvm_backend_stmt.cpp b/src/llvm_backend_stmt.cpp index 8742423a5..2703c511a 100644 --- a/src/llvm_backend_stmt.cpp +++ b/src/llvm_backend_stmt.cpp @@ -57,8 +57,9 @@ gb_internal void lb_build_constant_value_decl(lbProcedure *p, AstValueDecl *vd) if (pl->body != nullptr) { auto *found = map_get(&info->gen_procs, ident); if (found) { - MUTEX_GUARD(&found->mutex); - for (Entity *e : found->procs) { + GenProcsData *gpd = *found; + MUTEX_GUARD(&gpd->mutex); + for (Entity *e : gpd->procs) { if (!ptr_set_exists(min_dep_set, e)) { continue; } -- cgit v1.2.3 From 69934c3b0b1b8ad0a499574c39c1ab177a1fe30a Mon Sep 17 00:00:00 2001 From: gingerBill Date: Tue, 3 Jan 2023 13:04:09 +0000 Subject: More `for_array(i, y)` to `for (x : y)` translations --- src/check_builtin.cpp | 15 ++++------ src/check_decl.cpp | 27 +++++++---------- src/check_stmt.cpp | 73 ++++++++++++++++------------------------------ src/llvm_backend.cpp | 9 ++---- src/llvm_backend_expr.cpp | 18 ++++-------- src/llvm_backend_stmt.cpp | 74 +++++++++++++++++++---------------------------- 6 files changed, 80 insertions(+), 136 deletions(-) (limited to 'src/llvm_backend_stmt.cpp') diff --git a/src/check_builtin.cpp b/src/check_builtin.cpp index af196234e..7c5521dde 100644 --- a/src/check_builtin.cpp +++ b/src/check_builtin.cpp @@ -96,8 +96,7 @@ gb_internal void check_or_else_expr_no_value_error(CheckerContext *c, String con gbString th = nullptr; if (type_hint != nullptr) { GB_ASSERT(bsrc->kind == Type_Union); - for_array(i, bsrc->Union.variants) { - Type *vt = bsrc->Union.variants[i]; + for (Type *vt : bsrc->Union.variants) { if (are_types_identical(vt, type_hint)) { th = type_to_string(type_hint); break; @@ -198,8 +197,7 @@ gb_internal void add_objc_proc_type(CheckerContext *c, Ast *call, Type *return_t { auto variables = array_make(permanent_allocator(), 0, param_types.count); - for_array(i, param_types) { - Type *type = param_types[i]; + for (Type *type : param_types) { Entity *param = alloc_entity_param(scope, blank_token, type, false, true); array_add(&variables, param); } @@ -3071,8 +3069,7 @@ gb_internal bool check_builtin_procedure(CheckerContext *c, Operand *operand, As bool first_is_field_value = (ce->args[0]->kind == Ast_FieldValue); bool fail = false; - for_array(i, ce->args) { - Ast *arg = ce->args[i]; + for (Ast *arg : ce->args) { bool mix = false; if (first_is_field_value) { mix = arg->kind != Ast_FieldValue; @@ -3088,9 +3085,8 @@ gb_internal bool check_builtin_procedure(CheckerContext *c, Operand *operand, As StringSet name_set = {}; string_set_init(&name_set, 2*ce->args.count); - for_array(i, ce->args) { + for (Ast *arg : ce->args) { String name = {}; - Ast *arg = ce->args[i]; if (arg->kind == Ast_FieldValue) { Ast *ename = arg->FieldValue.field; if (!fail && ename->kind != Ast_Ident) { @@ -4987,8 +4983,7 @@ gb_internal bool check_builtin_procedure(CheckerContext *c, Operand *operand, As bool is_variant = false; - for_array(i, u->Union.variants) { - Type *vt = u->Union.variants[i]; + for (Type *vt : u->Union.variants) { if (are_types_identical(v, vt)) { is_variant = true; break; diff --git a/src/check_decl.cpp b/src/check_decl.cpp index 7b229db08..66f16546c 100644 --- a/src/check_decl.cpp +++ b/src/check_decl.cpp @@ -354,8 +354,7 @@ gb_internal void check_type_decl(CheckerContext *ctx, Entity *e, Ast *init_expr, Type *t = base_type(e->type); if (t->kind == Type_Enum) { - for_array(i, t->Enum.fields) { - Entity *f = t->Enum.fields[i]; + for (Entity *f : t->Enum.fields) { if (f->kind != Entity_Constant) { continue; } @@ -1237,8 +1236,7 @@ gb_internal void check_proc_group_decl(CheckerContext *ctx, Entity *&pg_entity, PtrSet entity_set = {}; ptr_set_init(&entity_set, 2*pg->args.count); - for_array(i, pg->args) { - Ast *arg = pg->args[i]; + for (Ast *arg : pg->args) { Entity *e = nullptr; Operand o = {}; if (arg->kind == Ast_Ident) { @@ -1271,7 +1269,7 @@ gb_internal void check_proc_group_decl(CheckerContext *ctx, Entity *&pg_entity, ptr_set_destroy(&entity_set); - for_array(j, pge->entities) { + for (isize j = 0; j < pge->entities.count; j++) { Entity *p = pge->entities[j]; if (p->type == t_invalid) { // NOTE(bill): This invalid overload has already been handled @@ -1462,8 +1460,7 @@ gb_internal bool check_proc_body(CheckerContext *ctx_, Token token, DeclInfo *de { if (type->Proc.param_count > 0) { TypeTuple *params = &type->Proc.params->Tuple; - for_array(i, params->variables) { - Entity *e = params->variables[i]; + for (Entity *e : params->variables) { if (e->kind != Entity_Variable) { continue; } @@ -1499,9 +1496,9 @@ gb_internal bool check_proc_body(CheckerContext *ctx_, Token token, DeclInfo *de } } - MUTEX_GUARD_BLOCK(ctx->scope->mutex) for_array(i, using_entities) { - Entity *e = using_entities[i].e; - Entity *uvar = using_entities[i].uvar; + MUTEX_GUARD_BLOCK(ctx->scope->mutex) for (auto const &entry : using_entities) { + Entity *e = entry.e; + Entity *uvar = entry.uvar; Entity *prev = scope_insert_no_mutex(ctx->scope, uvar); if (prev != nullptr) { error(e->token, "Namespace collision while 'using' procedure argument '%.*s' of: %.*s", LIT(e->token.string), LIT(prev->token.string)); @@ -1519,8 +1516,8 @@ gb_internal bool check_proc_body(CheckerContext *ctx_, Token token, DeclInfo *de check_open_scope(ctx, body); { - for_array(i, using_entities) { - Entity *uvar = using_entities[i].uvar; + for (auto const &entry : using_entities) { + Entity *uvar = entry.uvar; Entity *prev = scope_insert(ctx->scope, uvar); gb_unused(prev); // NOTE(bill): Don't err here @@ -1537,12 +1534,10 @@ gb_internal bool check_proc_body(CheckerContext *ctx_, Token token, DeclInfo *de decl->defer_use_checked = true; - for_array(i, bs->stmts) { - Ast *stmt = bs->stmts[i]; + for (Ast *stmt : bs->stmts) { if (stmt->kind == Ast_ValueDecl) { ast_node(vd, ValueDecl, stmt); - for_array(j, vd->names) { - Ast *name = vd->names[j]; + for (Ast *name : vd->names) { if (!is_blank_ident(name)) { if (name->kind == Ast_Ident) { GB_ASSERT(name->Ident.entity != nullptr); diff --git a/src/check_stmt.cpp b/src/check_stmt.cpp index 7192b16b5..e075297a4 100644 --- a/src/check_stmt.cpp +++ b/src/check_stmt.cpp @@ -931,16 +931,15 @@ gb_internal void check_switch_stmt(CheckerContext *ctx, Ast *node, u32 mod_flags SeenMap seen = {}; // NOTE(bill): Multimap, Key: ExactValue defer (map_destroy(&seen)); - for_array(stmt_index, bs->stmts) { - Ast *stmt = bs->stmts[stmt_index]; + for (Ast *stmt : bs->stmts) { if (stmt->kind != Ast_CaseClause) { // NOTE(bill): error handled by above multiple default checker continue; } ast_node(cc, CaseClause, stmt); - for_array(j, cc->list) { - Ast *expr = unparen_expr(cc->list[j]); + for (Ast *expr : cc->list) { + expr = unparen_expr(expr); if (is_ast_range(expr)) { ast_node(be, BinaryExpr, expr); @@ -1052,8 +1051,7 @@ gb_internal void check_switch_stmt(CheckerContext *ctx, Ast *node, u32 mod_flags auto unhandled = array_make(temporary_allocator(), 0, fields.count); - for_array(i, fields) { - Entity *f = fields[i]; + for (Entity *f : fields) { if (f->kind != Entity_Constant) { continue; } @@ -1072,8 +1070,7 @@ gb_internal void check_switch_stmt(CheckerContext *ctx, Ast *node, u32 mod_flags error_no_newline(node, "Unhandled switch case: %.*s", LIT(unhandled[0]->token.string)); } else { error(node, "Unhandled switch cases:"); - for_array(i, unhandled) { - Entity *f = unhandled[i]; + for (Entity *f : unhandled) { error_line("\t%.*s\n", LIT(f->token.string)); } } @@ -1154,8 +1151,7 @@ gb_internal void check_type_switch_stmt(CheckerContext *ctx, Ast *node, u32 mod_ // NOTE(bill): Check for multiple defaults Ast *first_default = nullptr; ast_node(bs, BlockStmt, ss->body); - for_array(i, bs->stmts) { - Ast *stmt = bs->stmts[i]; + for (Ast *stmt : bs->stmts) { Ast *default_stmt = nullptr; if (stmt->kind == Ast_CaseClause) { ast_node(cc, CaseClause, stmt); @@ -1186,8 +1182,7 @@ gb_internal void check_type_switch_stmt(CheckerContext *ctx, Ast *node, u32 mod_ PtrSet seen = {}; defer (ptr_set_destroy(&seen)); - for_array(i, bs->stmts) { - Ast *stmt = bs->stmts[i]; + for (Ast *stmt : bs->stmts) { if (stmt->kind != Ast_CaseClause) { // NOTE(bill): error handled by above multiple default checker continue; @@ -1198,8 +1193,7 @@ gb_internal void check_type_switch_stmt(CheckerContext *ctx, Ast *node, u32 mod_ Type *bt = base_type(type_deref(x.type)); Type *case_type = nullptr; - for_array(type_index, cc->list) { - Ast *type_expr = cc->list[type_index]; + for (Ast *type_expr : cc->list) { if (type_expr != nullptr) { // Otherwise it's a default expression Operand y = {}; check_expr_or_type(ctx, &y, type_expr); @@ -1213,8 +1207,7 @@ gb_internal void check_type_switch_stmt(CheckerContext *ctx, Ast *node, u32 mod_ if (switch_kind == TypeSwitch_Union) { GB_ASSERT(is_type_union(bt)); bool tag_type_found = false; - for_array(j, bt->Union.variants) { - Type *vt = bt->Union.variants[j]; + for (Type *vt : bt->Union.variants) { if (are_types_identical(vt, y.type)) { tag_type_found = true; break; @@ -1288,8 +1281,7 @@ gb_internal void check_type_switch_stmt(CheckerContext *ctx, Ast *node, u32 mod_ auto unhandled = array_make(temporary_allocator(), 0, variants.count); - for_array(i, variants) { - Type *t = variants[i]; + for (Type *t : variants) { if (!type_ptr_set_exists(&seen, t)) { array_add(&unhandled, t); } @@ -1302,8 +1294,7 @@ gb_internal void check_type_switch_stmt(CheckerContext *ctx, Ast *node, u32 mod_ gb_string_free(s); } else { error_no_newline(node, "Unhandled switch cases:\n"); - for_array(i, unhandled) { - Type *t = unhandled[i]; + for (Type *t : unhandled) { gbString s = type_to_string(t); error_line("\t%s\n", s); gb_string_free(s); @@ -1340,8 +1331,7 @@ gb_internal void check_block_stmt_for_errors(CheckerContext *ctx, Ast *body) { isize stmt_count = 0; Ast *the_stmt = nullptr; - for_array(i, bs->stmts) { - Ast *stmt = bs->stmts[i]; + for (Ast *stmt : bs->stmts) { GB_ASSERT(stmt != nullptr); switch (stmt->kind) { case_ast_node(es, EmptyStmt, stmt); @@ -1359,8 +1349,7 @@ gb_internal void check_block_stmt_for_errors(CheckerContext *ctx, Ast *body) { if (stmt_count == 1) { if (the_stmt->kind == Ast_ValueDecl) { - for_array(i, the_stmt->ValueDecl.names) { - Ast *name = the_stmt->ValueDecl.names[i]; + for (Ast *name : the_stmt->ValueDecl.names) { if (name->kind != Ast_Ident) { continue; } @@ -1376,8 +1365,8 @@ gb_internal void check_block_stmt_for_errors(CheckerContext *ctx, Ast *body) { gb_internal bool all_operands_valid(Array const &operands) { if (any_errors()) { - for_array(i, operands) { - if (operands[i].type == t_invalid) { + for (Operand const &o : operands) { + if (o.type == t_invalid) { return false; } } @@ -1548,16 +1537,9 @@ gb_internal void check_stmt_internal(CheckerContext *ctx, Ast *node, u32 flags) check_assignment_arguments(ctx, lhs_operands, &rhs_operands, as->rhs); - isize rhs_count = rhs_operands.count; - for_array(i, rhs_operands) { - if (rhs_operands[i].mode == Addressing_Invalid) { - // TODO(bill): Should I ignore invalid parameters? - // rhs_count--; - } - } - auto lhs_to_ignore = array_make(temporary_allocator(), lhs_count); + isize rhs_count = rhs_operands.count; isize max = gb_min(lhs_count, rhs_count); for (isize i = 0; i < max; i++) { if (lhs_to_ignore[i]) { @@ -1856,8 +1838,8 @@ gb_internal void check_stmt_internal(CheckerContext *ctx, Ast *node, u32 flags) break; } - for_array(ti, t->Tuple.variables) { - array_add(&vals, t->Tuple.variables[ti]->type); + for (Entity *e : t->Tuple.variables) { + array_add(&vals, e->type); } if (rs->vals.count > 1 && rs->vals[1] != nullptr && count < 3) { @@ -1976,8 +1958,7 @@ gb_internal void check_stmt_internal(CheckerContext *ctx, Ast *node, u32 flags) } } - for_array(i, entities) { - Entity *e = entities[i]; + for (Entity *e : entities) { DeclInfo *d = decl_info_of_entity(e); GB_ASSERT(d == nullptr); add_entity(ctx, ctx->scope, e->identifier, e); @@ -2091,8 +2072,8 @@ gb_internal void check_stmt_internal(CheckerContext *ctx, Ast *node, u32 flags) error(us->token, "Empty 'using' list"); return; } - for_array(i, us->list) { - Ast *expr = unparen_expr(us->list[i]); + for (Ast *expr : us->list) { + expr = unparen_expr(expr); Entity *e = nullptr; bool is_selector = false; @@ -2132,8 +2113,7 @@ gb_internal void check_stmt_internal(CheckerContext *ctx, Ast *node, u32 flags) check_decl_attributes(&c, fb->attributes, foreign_block_decl_attribute, nullptr); ast_node(block, BlockStmt, fb->body); - for_array(i, block->stmts) { - Ast *decl = block->stmts[i]; + for (Ast *decl : block->stmts) { if (decl->kind == Ast_ValueDecl && decl->ValueDecl.is_mutable) { check_stmt(&c, decl, flags); } @@ -2146,8 +2126,7 @@ gb_internal void check_stmt_internal(CheckerContext *ctx, Ast *node, u32 flags) isize entity_count = 0; isize new_name_count = 0; - for_array(i, vd->names) { - Ast *name = vd->names[i]; + for (Ast *name : vd->names) { Entity *entity = nullptr; if (name->kind != Ast_Ident) { error(name, "A variable declaration must be an identifier"); @@ -2193,8 +2172,7 @@ gb_internal void check_stmt_internal(CheckerContext *ctx, Ast *node, u32 flags) begin_error_block(); error(node, "No new declarations on the left hand side"); bool all_underscore = true; - for_array(i, vd->names) { - Ast *name = vd->names[i]; + for (Ast *name : vd->names) { if (name->kind == Ast_Ident) { if (!is_blank_ident(name)) { all_underscore = false; @@ -2388,8 +2366,7 @@ gb_internal void check_stmt_internal(CheckerContext *ctx, Ast *node, u32 flags) } else { // constant value declaration // NOTE(bill): Check `_` declarations - for_array(i, vd->names) { - Ast *name = vd->names[i]; + for (Ast *name : vd->names) { if (is_blank_ident(name)) { Entity *e = name->Ident.entity; DeclInfo *d = decl_info_of_entity(e); diff --git a/src/llvm_backend.cpp b/src/llvm_backend.cpp index 3e62f678a..304e5ef36 100644 --- a/src/llvm_backend.cpp +++ b/src/llvm_backend.cpp @@ -240,11 +240,10 @@ gb_internal lbValue lb_equal_proc_for_type(lbModule *m, Type *type) { LLVMValueRef v_switch = LLVMBuildSwitch(p->builder, left_tag.value, block_false->block, cast(unsigned)type->Union.variants.count); - for_array(i, type->Union.variants) { + for (Type *v : type->Union.variants) { lbBlock *case_block = lb_create_block(p, "bcase"); lb_start_block(p, case_block); - Type *v = type->Union.variants[i]; lbValue case_tag = lb_const_union_tag(p->module, type, v); Type *vp = alloc_type_pointer(v); @@ -374,11 +373,10 @@ gb_internal lbValue lb_hasher_proc_for_type(lbModule *m, Type *type) { LLVMValueRef v_switch = LLVMBuildSwitch(p->builder, tag.value, end_block->block, cast(unsigned)type->Union.variants.count); - for_array(i, type->Union.variants) { + for (Type *v : type->Union.variants) { lbBlock *case_block = lb_create_block(p, "bcase"); lb_start_block(p, case_block); - Type *v = type->Union.variants[i]; lbValue case_tag = lb_const_union_tag(p->module, type, v); lbValue variant_hasher = lb_hasher_proc_for_type(m, v); @@ -2235,8 +2233,7 @@ gb_internal void lb_generate_code(lbGenerator *gen) { for (auto const &entry : gen->modules) { lbModule *m = entry.value; - for_array(i, m->info->required_foreign_imports_through_force) { - Entity *e = m->info->required_foreign_imports_through_force[i]; + for (Entity *e : m->info->required_foreign_imports_through_force) { lb_add_foreign_library_path(m, e); } diff --git a/src/llvm_backend_expr.cpp b/src/llvm_backend_expr.cpp index d574caf4c..c28e9fb2b 100644 --- a/src/llvm_backend_expr.cpp +++ b/src/llvm_backend_expr.cpp @@ -61,8 +61,7 @@ gb_internal lbValue lb_emit_logical_binary_expr(lbProcedure *p, TokenKind op, As GB_ASSERT(incoming_values.count > 0); LLVMTypeRef phi_type = nullptr; - for_array(i, incoming_values) { - LLVMValueRef incoming_value = incoming_values[i]; + for (LLVMValueRef incoming_value : incoming_values) { if (!LLVMIsConstant(incoming_value)) { phi_type = LLVMTypeOf(incoming_value); break; @@ -1921,8 +1920,7 @@ gb_internal lbValue lb_emit_conv(lbProcedure *p, lbValue value, Type *t) { } if (is_type_union(dst)) { - for_array(i, dst->Union.variants) { - Type *vt = dst->Union.variants[i]; + for (Type *vt : dst->Union.variants) { if (are_types_identical(vt, src_type)) { lbAddr parent = lb_add_local_generated(p, t, true); lb_emit_store_union_variant(p, parent.addr, value, vt); @@ -3596,8 +3594,7 @@ gb_internal void lb_build_addr_compound_lit_populate(lbProcedure *p, Slice const &temp_data) { - for_array(i, temp_data) { - auto td = temp_data[i]; + for (auto const &td : temp_data) { if (td.value.value != nullptr) { if (td.elem_length > 0) { auto loop_data = lb_loop_start(p, cast(isize)td.elem_length, t_i32); @@ -4129,8 +4126,7 @@ gb_internal lbAddr lb_build_addr_compound_lit(lbProcedure *p, Ast *expr) { lbValue err = lb_dynamic_map_reserve(p, v.addr, 2*cl->elems.count, pos); gb_unused(err); - for_array(field_index, cl->elems) { - Ast *elem = cl->elems[field_index]; + for (Ast *elem : cl->elems) { ast_node(fv, FieldValue, elem); lbValue key = lb_build_expr(p, fv->field); @@ -4304,8 +4300,7 @@ gb_internal lbAddr lb_build_addr_compound_lit(lbProcedure *p, Ast *expr) { lb_addr_store(p, v, lb_const_value(p->module, type, exact_value_compound(expr))); lbValue lower = lb_const_value(p->module, t_int, exact_value_i64(bt->BitSet.lower)); - for_array(i, cl->elems) { - Ast *elem = cl->elems[i]; + for (Ast *elem : cl->elems) { GB_ASSERT(elem->kind != Ast_FieldValue); if (lb_is_elem_const(elem, et)) { @@ -4359,8 +4354,7 @@ gb_internal lbAddr lb_build_addr_compound_lit(lbProcedure *p, Ast *expr) { // TODO(bill): reduce the need for individual `insertelement` if a `shufflevector` // might be a better option - for_array(i, temp_data) { - auto td = temp_data[i]; + for (auto const &td : temp_data) { if (td.value.value != nullptr) { if (td.elem_length > 0) { for (i64 k = 0; k < td.elem_length; k++) { diff --git a/src/llvm_backend_stmt.cpp b/src/llvm_backend_stmt.cpp index 2703c511a..c48115079 100644 --- a/src/llvm_backend_stmt.cpp +++ b/src/llvm_backend_stmt.cpp @@ -7,8 +7,7 @@ gb_internal void lb_build_constant_value_decl(lbProcedure *p, AstValueDecl *vd) static i32 global_guid = 0; - for_array(i, vd->names) { - Ast *ident = vd->names[i]; + for (Ast *ident : vd->names) { GB_ASSERT(ident->kind == Ast_Ident); Entity *e = entity_of_node(ident); GB_ASSERT(e != nullptr); @@ -106,8 +105,7 @@ gb_internal void lb_build_constant_value_decl(lbProcedure *p, AstValueDecl *vd) gb_internal void lb_build_stmt_list(lbProcedure *p, Slice const &stmts) { - for_array(i, stmts) { - Ast *stmt = stmts[i]; + for (Ast *stmt : stmts) { switch (stmt->kind) { case_ast_node(vd, ValueDecl, stmt); lb_build_constant_value_decl(p, vd); @@ -118,8 +116,8 @@ gb_internal void lb_build_stmt_list(lbProcedure *p, Slice const &stmts) { case_end; } } - for_array(i, stmts) { - lb_build_stmt(p, stmts[i]); + for (Ast *stmt : stmts) { + lb_build_stmt(p, stmt); } } @@ -129,10 +127,9 @@ gb_internal lbBranchBlocks lb_lookup_branch_blocks(lbProcedure *p, Ast *ident) { GB_ASSERT(ident->kind == Ast_Ident); Entity *e = entity_of_node(ident); GB_ASSERT(e->kind == Entity_Label); - for_array(i, p->branch_blocks) { - lbBranchBlocks *b = &p->branch_blocks[i]; - if (b->label == e->Label.node) { - return *b; + for (lbBranchBlocks const &b : p->branch_blocks) { + if (b.label == e->Label.node) { + return b; } } @@ -153,13 +150,12 @@ gb_internal lbTargetList *lb_push_target_list(lbProcedure *p, Ast *label, lbBloc if (label != nullptr) { // Set label blocks GB_ASSERT(label->kind == Ast_Label); - for_array(i, p->branch_blocks) { - lbBranchBlocks *b = &p->branch_blocks[i]; - GB_ASSERT(b->label != nullptr && label != nullptr); - GB_ASSERT(b->label->kind == Ast_Label); - if (b->label == label) { - b->break_ = break_; - b->continue_ = continue_; + for (lbBranchBlocks &b : p->branch_blocks) { + GB_ASSERT(b.label != nullptr && label != nullptr); + GB_ASSERT(b.label->kind == Ast_Label); + if (b.label == label) { + b.break_ = break_; + b.continue_ = continue_; return tl; } } @@ -1095,8 +1091,7 @@ gb_internal bool lb_switch_stmt_can_be_trivial_jump_table(AstSwitchStmt *ss, boo } ast_node(body, BlockStmt, ss->body); - for_array(i, body->stmts) { - Ast *clause = body->stmts[i]; + for (Ast *clause : body->stmts) { ast_node(cc, CaseClause, clause); if (cc->list.count == 0) { @@ -1104,8 +1099,8 @@ gb_internal bool lb_switch_stmt_can_be_trivial_jump_table(AstSwitchStmt *ss, boo continue; } - for_array(j, cc->list) { - Ast *expr = unparen_expr(cc->list[j]); + for (Ast *expr : cc->list) { + expr = unparen_expr(expr); if (is_ast_range(expr)) { return false; } @@ -1166,8 +1161,7 @@ gb_internal void lb_build_switch_stmt(lbProcedure *p, AstSwitchStmt *ss, Scope * LLVMValueRef switch_instr = nullptr; if (is_trivial) { isize num_cases = 0; - for_array(i, body->stmts) { - Ast *clause = body->stmts[i]; + for (Ast *clause : body->stmts) { ast_node(cc, CaseClause, clause); num_cases += cc->list.count; } @@ -1204,8 +1198,8 @@ gb_internal void lb_build_switch_stmt(lbProcedure *p, AstSwitchStmt *ss, Scope * } lbBlock *next_cond = nullptr; - for_array(j, cc->list) { - Ast *expr = unparen_expr(cc->list[j]); + for (Ast *expr : cc->list) { + expr = unparen_expr(expr); if (switch_instr != nullptr) { lbValue on_val = {}; @@ -1384,8 +1378,7 @@ gb_internal void lb_build_type_switch_stmt(lbProcedure *p, AstTypeSwitchStmt *ss lbBlock *default_block = nullptr; isize num_cases = 0; - for_array(i, body->stmts) { - Ast *clause = body->stmts[i]; + for (Ast *clause : body->stmts) { ast_node(cc, CaseClause, clause); num_cases += cc->list.count; if (cc->list.count == 0) { @@ -1405,8 +1398,7 @@ gb_internal void lb_build_type_switch_stmt(lbProcedure *p, AstTypeSwitchStmt *ss switch_instr = LLVMBuildSwitch(p->builder, tag.value, else_block->block, cast(unsigned)num_cases); } - for_array(i, body->stmts) { - Ast *clause = body->stmts[i]; + for (Ast *clause : body->stmts) { ast_node(cc, CaseClause, clause); lb_open_scope(p, cc->scope); if (cc->list.count == 0) { @@ -1420,9 +1412,8 @@ gb_internal void lb_build_type_switch_stmt(lbProcedure *p, AstTypeSwitchStmt *ss if (p->debug_info != nullptr) { LLVMSetCurrentDebugLocation2(p->builder, lb_debug_location_from_ast(p, clause)); } - Type *case_type = nullptr; - for_array(type_index, cc->list) { - case_type = type_of_expr(cc->list[type_index]); + for (Ast *type_expr : cc->list) { + Type *case_type = type_of_expr(type_expr); lbValue on_val = {}; if (switch_kind == TypeSwitch_Union) { Type *ut = base_type(type_deref(parent.type)); @@ -1538,8 +1529,8 @@ gb_internal void lb_append_tuple_values(lbProcedure *p, Array *dst_valu if (t->kind == Type_Tuple) { lbTupleFix *tf = map_get(&p->tuple_fix_map, src_value.value); if (tf) { - for_array(j, tf->values) { - array_add(dst_values, tf->values[j]); + for (lbValue const &value : tf->values) { + array_add(dst_values, value); } } else { for_array(i, t->Tuple.variables) { @@ -1560,8 +1551,7 @@ gb_internal void lb_build_assignment(lbProcedure *p, Array &lvals, Slice auto inits = array_make(permanent_allocator(), 0, lvals.count); - for_array(i, values) { - Ast *rhs = values[i]; + for (Ast *rhs : values) { lbValue init = lb_build_expr(p, rhs); lb_append_tuple_values(p, &inits, init); } @@ -1971,8 +1961,7 @@ gb_internal void lb_build_assign_stmt_array(lbProcedure *p, TokenKind op, lbAddr auto indices_handled = slice_make(temporary_allocator(), bt->Array.count); auto indices = slice_make(temporary_allocator(), bt->Array.count); i32 index_count = 0; - for_array(i, lhs.swizzle_large.indices) { - i32 index = lhs.swizzle_large.indices[i]; + for (i32 index : lhs.swizzle_large.indices) { if (indices_handled[index]) { continue; } @@ -2049,8 +2038,7 @@ gb_internal void lb_build_assign_stmt(lbProcedure *p, AstAssignStmt *as) { if (as->op.kind == Token_Eq) { auto lvals = array_make(permanent_allocator(), 0, as->lhs.count); - for_array(i, as->lhs) { - Ast *lhs = as->lhs[i]; + for (Ast *lhs : as->lhs) { lbAddr lval = {}; if (!is_blank_ident(lhs)) { lval = lb_build_addr(p, lhs); @@ -2185,8 +2173,7 @@ gb_internal void lb_build_stmt(lbProcedure *p, Ast *node) { bool is_static = false; if (vd->names.count > 0) { - for_array(i, vd->names) { - Ast *name = vd->names[i]; + for (Ast *name : vd->names) { if (!is_blank_ident(name)) { GB_ASSERT(name->kind == Ast_Ident); Entity *e = entity_of_node(name); @@ -2208,8 +2195,7 @@ gb_internal void lb_build_stmt(lbProcedure *p, Ast *node) { auto lvals = array_make(permanent_allocator(), 0, vd->names.count); - for_array(i, vd->names) { - Ast *name = vd->names[i]; + for (Ast *name : vd->names) { lbAddr lval = {}; if (!is_blank_ident(name)) { Entity *e = entity_of_node(name); -- cgit v1.2.3 From 774fea1e63941473b9899a50585e0f171184a147 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Tue, 3 Jan 2023 15:47:25 +0000 Subject: Use `RwMutex` for `gen_procs` --- src/check_expr.cpp | 16 ++++++++-------- src/checker.cpp | 13 +++++++------ src/checker.hpp | 11 +++-------- src/llvm_backend_stmt.cpp | 3 ++- 4 files changed, 20 insertions(+), 23 deletions(-) (limited to 'src/llvm_backend_stmt.cpp') diff --git a/src/check_expr.cpp b/src/check_expr.cpp index 38fe33c24..746a29ce0 100644 --- a/src/check_expr.cpp +++ b/src/check_expr.cpp @@ -440,11 +440,11 @@ gb_internal bool find_or_generate_polymorphic_procedure(CheckerContext *old_c, E auto *found = map_get(&info->gen_procs, base_entity->identifier.load()); if (found) { gen_procs = *found; - mutex_lock(&gen_procs->mutex); // @local-mutex + rw_mutex_shared_lock(&gen_procs->mutex); // @local-mutex for (Entity *other : gen_procs->procs) { Type *pt = base_type(other->type); if (are_types_identical(pt, final_proc_type)) { - mutex_unlock(&gen_procs->mutex); // @local-mutex + rw_mutex_shared_unlock(&gen_procs->mutex); // @local-mutex // @@GPM //////////////////////////// mutex_unlock(&info->gen_procs_mutex); ///////////////////////////////////// @@ -455,7 +455,7 @@ gb_internal bool find_or_generate_polymorphic_procedure(CheckerContext *old_c, E return true; } } - mutex_unlock(&gen_procs->mutex); // @local-mutex + rw_mutex_shared_unlock(&gen_procs->mutex); // @local-mutex } else { gen_procs = gb_alloc_item(permanent_allocator(), GenProcsData); gen_procs->procs.allocator = heap_allocator(); @@ -481,11 +481,11 @@ gb_internal bool find_or_generate_polymorphic_procedure(CheckerContext *old_c, E return false; } - mutex_lock(&gen_procs->mutex); // @local-mutex + rw_mutex_shared_lock(&gen_procs->mutex); // @local-mutex for (Entity *other : gen_procs->procs) { Type *pt = base_type(other->type); if (are_types_identical(pt, final_proc_type)) { - mutex_unlock(&gen_procs->mutex); // @local-mutex + rw_mutex_shared_unlock(&gen_procs->mutex); // @local-mutex if (poly_proc_data) { poly_proc_data->gen_entity = other; @@ -509,7 +509,7 @@ gb_internal bool find_or_generate_polymorphic_procedure(CheckerContext *old_c, E return true; } } - mutex_unlock(&gen_procs->mutex); // @local-mutex + rw_mutex_shared_unlock(&gen_procs->mutex); // @local-mutex } @@ -569,9 +569,9 @@ gb_internal bool find_or_generate_polymorphic_procedure(CheckerContext *old_c, E } } - mutex_lock(&gen_procs->mutex); // @local-mutex + rw_mutex_lock(&gen_procs->mutex); // @local-mutex array_add(&gen_procs->procs, entity); - mutex_unlock(&gen_procs->mutex); // @local-mutex + rw_mutex_unlock(&gen_procs->mutex); // @local-mutex ProcInfo *proc_info = gb_alloc_item(permanent_allocator(), ProcInfo); proc_info->file = file; diff --git a/src/checker.cpp b/src/checker.cpp index fd80d07de..3f5c2892f 100644 --- a/src/checker.cpp +++ b/src/checker.cpp @@ -1356,9 +1356,9 @@ gb_internal ExprInfo *check_get_expr_info(CheckerContext *c, Ast *expr) { } return nullptr; } else { - mutex_lock(&c->info->global_untyped_mutex); - defer (mutex_unlock(&c->info->global_untyped_mutex)); + rw_mutex_shared_lock(&c->info->global_untyped_mutex); ExprInfo **found = map_get(&c->info->global_untyped, expr); + rw_mutex_shared_unlock(&c->info->global_untyped_mutex); if (found) { return *found; } @@ -1370,9 +1370,9 @@ gb_internal void check_set_expr_info(CheckerContext *c, Ast *expr, AddressingMod if (c->untyped != nullptr) { map_set(c->untyped, expr, make_expr_info(mode, type, value, false)); } else { - mutex_lock(&c->info->global_untyped_mutex); + rw_mutex_lock(&c->info->global_untyped_mutex); map_set(&c->info->global_untyped, expr, make_expr_info(mode, type, value, false)); - mutex_unlock(&c->info->global_untyped_mutex); + rw_mutex_unlock(&c->info->global_untyped_mutex); } } @@ -1382,10 +1382,10 @@ gb_internal void check_remove_expr_info(CheckerContext *c, Ast *e) { GB_ASSERT(map_get(c->untyped, e) == nullptr); } else { auto *untyped = &c->info->global_untyped; - mutex_lock(&c->info->global_untyped_mutex); + rw_mutex_lock(&c->info->global_untyped_mutex); map_remove(untyped, e); GB_ASSERT(map_get(untyped, e) == nullptr); - mutex_unlock(&c->info->global_untyped_mutex); + rw_mutex_unlock(&c->info->global_untyped_mutex); } } @@ -1454,6 +1454,7 @@ gb_internal void add_type_and_value(CheckerContext *ctx, Ast *expr, AddressingMo BlockingMutex *mutex = &ctx->info->type_and_value_mutex; if (ctx->pkg) { + // TODO(bill): is a per package mutex is a good idea here? mutex = &ctx->pkg->type_and_value_mutex; } diff --git a/src/checker.hpp b/src/checker.hpp index 554c8ddf4..226f69c1c 100644 --- a/src/checker.hpp +++ b/src/checker.hpp @@ -317,7 +317,7 @@ struct LoadFileCache { struct GenProcsData { Array procs; - BlockingMutex mutex; + RwMutex mutex; }; // CheckerInfo stores all the symbol information for a type-checked program @@ -347,14 +347,9 @@ struct CheckerInfo { // Below are accessed within procedures - // NOTE(bill): If the semantic checker (check_proc_body) is to ever to be multithreaded, - // these variables will be of contention - - Semaphore collect_semaphore; - + RwMutex global_untyped_mutex; UntypedExprInfoMap global_untyped; // NOTE(bill): This needs to be a map and not on the Ast // as it needs to be iterated across afterwards - BlockingMutex global_untyped_mutex; BlockingMutex builtin_mutex; BlockingMutex type_and_value_mutex; @@ -388,7 +383,7 @@ struct CheckerInfo { BlockingMutex load_file_mutex; StringMap load_file_cache; - BlockingMutex all_procedures_mutex;; + BlockingMutex all_procedures_mutex; Array all_procedures; }; diff --git a/src/llvm_backend_stmt.cpp b/src/llvm_backend_stmt.cpp index c48115079..1660d3487 100644 --- a/src/llvm_backend_stmt.cpp +++ b/src/llvm_backend_stmt.cpp @@ -57,7 +57,7 @@ gb_internal void lb_build_constant_value_decl(lbProcedure *p, AstValueDecl *vd) auto *found = map_get(&info->gen_procs, ident); if (found) { GenProcsData *gpd = *found; - MUTEX_GUARD(&gpd->mutex); + rw_mutex_shared_lock(&gpd->mutex); for (Entity *e : gpd->procs) { if (!ptr_set_exists(min_dep_set, e)) { continue; @@ -65,6 +65,7 @@ gb_internal void lb_build_constant_value_decl(lbProcedure *p, AstValueDecl *vd) DeclInfo *d = decl_info_of_entity(e); lb_build_nested_proc(p, &d->proc_lit->ProcLit, e); } + rw_mutex_shared_unlock(&gpd->mutex); } else { lb_build_nested_proc(p, pl, e); } -- cgit v1.2.3 From 12e42d92d30b3a9cf4d7bb7bb17a2e031285073b Mon Sep 17 00:00:00 2001 From: gingerBill Date: Wed, 4 Jan 2023 15:35:24 +0000 Subject: Localize `GenProcsData` to the entity itself --- src/check_expr.cpp | 29 ++++++++++++++--------------- src/checker.cpp | 4 ++-- src/checker.hpp | 2 -- src/entity.cpp | 5 ++++- src/llvm_backend_stmt.cpp | 6 ++---- 5 files changed, 22 insertions(+), 24 deletions(-) (limited to 'src/llvm_backend_stmt.cpp') diff --git a/src/check_expr.cpp b/src/check_expr.cpp index 5f28504a2..bce16f304 100644 --- a/src/check_expr.cpp +++ b/src/check_expr.cpp @@ -366,8 +366,6 @@ gb_internal bool find_or_generate_polymorphic_procedure(CheckerContext *old_c, E GB_ASSERT(dst == nullptr); } - // MUTEX_GUARD(&info->gen_procs_mutex); - if (!src->Proc.is_polymorphic || src->Proc.is_poly_specialized) { return false; } @@ -434,20 +432,21 @@ gb_internal bool find_or_generate_polymorphic_procedure(CheckerContext *old_c, E GenProcsData *gen_procs = nullptr; - // @@GPM ////////////////////////// - mutex_lock(&info->gen_procs_mutex); - /////////////////////////////////// - auto *found = map_get(&info->gen_procs, base_entity->identifier.load()); - if (found) { - gen_procs = *found; + GB_ASSERT(base_entity->identifier.load()->kind == Ast_Ident); + GB_ASSERT(base_entity->kind == Entity_Procedure); + + + mutex_lock(&base_entity->Procedure.gen_procs_mutex); // @entity-mutex + + gen_procs = base_entity->Procedure.gen_procs; + if (gen_procs) { rw_mutex_shared_lock(&gen_procs->mutex); // @local-mutex + for (Entity *other : gen_procs->procs) { Type *pt = base_type(other->type); if (are_types_identical(pt, final_proc_type)) { rw_mutex_shared_unlock(&gen_procs->mutex); // @local-mutex - // @@GPM //////////////////////////// - mutex_unlock(&info->gen_procs_mutex); - ///////////////////////////////////// + mutex_unlock(&base_entity->Procedure.gen_procs_mutex); // @entity-mutex if (poly_proc_data) { poly_proc_data->gen_entity = other; @@ -455,15 +454,15 @@ gb_internal bool find_or_generate_polymorphic_procedure(CheckerContext *old_c, E return true; } } + rw_mutex_shared_unlock(&gen_procs->mutex); // @local-mutex } else { gen_procs = gb_alloc_item(permanent_allocator(), GenProcsData); gen_procs->procs.allocator = heap_allocator(); - map_set(&info->gen_procs, base_entity->identifier.load(), gen_procs); + base_entity->Procedure.gen_procs = gen_procs; } - // @@GPM //////////////////////////// - mutex_unlock(&info->gen_procs_mutex); - ///////////////////////////////////// + + mutex_unlock(&base_entity->Procedure.gen_procs_mutex); // @entity-mutex { // LEAK TODO(bill): This is technically a memory leak as it has to generate the type twice diff --git a/src/checker.cpp b/src/checker.cpp index 5fc9a5551..0bebce232 100644 --- a/src/checker.cpp +++ b/src/checker.cpp @@ -1143,7 +1143,7 @@ gb_internal void init_checker_info(CheckerInfo *i) { array_init(&i->entities, a); map_init(&i->global_untyped); string_map_init(&i->foreigns); - map_init(&i->gen_procs); + // map_init(&i->gen_procs); map_init(&i->gen_types); array_init(&i->type_info_types, a); map_init(&i->type_info_map); @@ -1172,7 +1172,7 @@ gb_internal void destroy_checker_info(CheckerInfo *i) { array_free(&i->entities); map_destroy(&i->global_untyped); string_map_destroy(&i->foreigns); - map_destroy(&i->gen_procs); + // map_destroy(&i->gen_procs); map_destroy(&i->gen_types); array_free(&i->type_info_types); map_destroy(&i->type_info_map); diff --git a/src/checker.hpp b/src/checker.hpp index 92926689e..8b8819d97 100644 --- a/src/checker.hpp +++ b/src/checker.hpp @@ -368,9 +368,7 @@ struct CheckerInfo { RecursiveMutex lazy_mutex; // Mutex required for lazy type checking of specific files - BlockingMutex gen_procs_mutex; RwMutex gen_types_mutex; - PtrMap gen_procs; // Key: Ast * | Identifier -> Entity PtrMap gen_types; BlockingMutex type_info_mutex; // NOT recursive diff --git a/src/entity.cpp b/src/entity.cpp index f82a2fb05..b92ba825f 100644 --- a/src/entity.cpp +++ b/src/entity.cpp @@ -130,7 +130,7 @@ enum EntityConstantFlags : u32 { EntityConstantFlag_ImplicitEnumValue = 1<<0, }; -enum ProcedureOptimizationMode : u32 { +enum ProcedureOptimizationMode : u8 { ProcedureOptimizationMode_Default, ProcedureOptimizationMode_None, ProcedureOptimizationMode_Minimal, @@ -233,6 +233,9 @@ struct Entity { String link_name; String link_prefix; DeferredProcedure deferred_procedure; + + struct GenProcsData *gen_procs; + BlockingMutex gen_procs_mutex; ProcedureOptimizationMode optimization_mode; bool is_foreign : 1; bool is_export : 1; diff --git a/src/llvm_backend_stmt.cpp b/src/llvm_backend_stmt.cpp index 1660d3487..0e6f75118 100644 --- a/src/llvm_backend_stmt.cpp +++ b/src/llvm_backend_stmt.cpp @@ -50,13 +50,11 @@ gb_internal void lb_build_constant_value_decl(lbProcedure *p, AstValueDecl *vd) continue; // It's an alias } - CheckerInfo *info = p->module->info; DeclInfo *decl = decl_info_of_entity(e); ast_node(pl, ProcLit, decl->proc_lit); if (pl->body != nullptr) { - auto *found = map_get(&info->gen_procs, ident); - if (found) { - GenProcsData *gpd = *found; + GenProcsData *gpd = e->Procedure.gen_procs; + if (gpd) { rw_mutex_shared_lock(&gpd->mutex); for (Entity *e : gpd->procs) { if (!ptr_set_exists(min_dep_set, e)) { -- cgit v1.2.3 From 213a0499a1964e0bc5d2c48cd3b4450b45f59314 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Thu, 5 Jan 2023 12:29:16 +0000 Subject: Begin multithreading the llvm backend when `-use-separate-modules` is enabled --- src/llvm_backend.cpp | 46 +++++++++++++++++++++++++++++--------------- src/llvm_backend.hpp | 3 +++ src/llvm_backend_general.cpp | 21 +++++++++++++++++--- src/llvm_backend_stmt.cpp | 2 +- 4 files changed, 53 insertions(+), 19 deletions(-) (limited to 'src/llvm_backend_stmt.cpp') diff --git a/src/llvm_backend.cpp b/src/llvm_backend.cpp index 192e5cc56..f3c4dd50d 100644 --- a/src/llvm_backend.cpp +++ b/src/llvm_backend.cpp @@ -730,6 +730,8 @@ gb_internal lbValue lb_map_set_proc_for_type(lbModule *m, Type *type) { gb_internal lbValue lb_generate_anonymous_proc_lit(lbModule *m, String const &prefix_name, Ast *expr, lbProcedure *parent) { + MUTEX_GUARD(&m->gen->anonymous_proc_lits_mutex); + lbProcedure **found = map_get(&m->gen->anonymous_proc_lits, expr); if (found) { return lb_find_procedure_value_from_entity(m, (*found)->entity); @@ -1526,6 +1528,10 @@ struct lbLLVMModulePassWorkerData { gb_internal WORKER_TASK_PROC(lb_llvm_module_pass_worker_proc) { auto wd = cast(lbLLVMModulePassWorkerData *)data; + + lb_run_remove_unused_function_pass(wd->m); + lb_run_remove_unused_globals_pass(wd->m); + LLVMPassManagerRef module_pass_manager = LLVMCreatePassManager(); lb_populate_module_pass_manager(wd->target_machine, module_pass_manager, build_context.optimization_level); LLVMRunPassManager(module_pass_manager, wd->m->mod); @@ -2155,29 +2161,47 @@ gb_internal void lb_generate_code(lbGenerator *gen) { } } + isize non_empty_module_count = 0; + for (auto const &entry : gen->modules) { + lbModule *m = entry.value; + if (!lb_is_module_empty(m)) { + non_empty_module_count += 1; + } + } + if (non_empty_module_count <= 1) { + do_threading = false; + } TIME_SECTION("LLVM Function Pass"); for (auto const &entry : gen->modules) { lbModule *m = entry.value; - lb_llvm_function_pass_worker_proc(m); + // if (do_threading) { + // thread_pool_add_task(lb_llvm_function_pass_worker_proc, m); + // } else { + lb_llvm_function_pass_worker_proc(m); + // } } + thread_pool_wait(); TIME_SECTION("LLVM Module Pass"); - for (auto const &entry : gen->modules) { lbModule *m = entry.value; - lb_run_remove_unused_function_pass(m); - lb_run_remove_unused_globals_pass(m); - auto wd = gb_alloc_item(permanent_allocator(), lbLLVMModulePassWorkerData); wd->m = m; wd->target_machine = m->target_machine; - lb_llvm_module_pass_worker_proc(wd); + if (do_threading) { + thread_pool_add_task(lb_llvm_module_pass_worker_proc, wd); + } else { + lb_llvm_module_pass_worker_proc(wd); + } } + thread_pool_wait(); + TIME_SECTION("LLVM Module Verification"); + llvm_error = nullptr; defer (LLVMDisposeMessage(llvm_error)); @@ -2245,21 +2269,13 @@ gb_internal void lb_generate_code(lbGenerator *gen) { TIME_SECTION("LLVM Object Generation"); - isize non_empty_module_count = 0; - for (auto const &entry : gen->modules) { - lbModule *m = entry.value; - if (!lb_is_module_empty(m)) { - non_empty_module_count += 1; - } - } - if (build_context.ignore_llvm_build) { gb_printf_err("LLVM SUCCESS!\n"); gb_exit(1); return; } - if (do_threading && non_empty_module_count > 1) { + if (do_threading) { for (auto const &entry : gen->modules) { lbModule *m = entry.value; if (lb_is_module_empty(m)) { diff --git a/src/llvm_backend.hpp b/src/llvm_backend.hpp index 9f7caa3bb..d824b99cf 100644 --- a/src/llvm_backend.hpp +++ b/src/llvm_backend.hpp @@ -132,6 +132,8 @@ struct lbModule { PtrMap struct_field_remapping; // Key: LLVMTypeRef or Type * i32 internal_type_level; + RecursiveMutex values_mutex; + PtrMap values; PtrMap soa_values; StringMap members; @@ -178,6 +180,7 @@ struct lbGenerator { PtrMap modules_through_ctx; lbModule default_module; + BlockingMutex anonymous_proc_lits_mutex; PtrMap anonymous_proc_lits; BlockingMutex foreign_mutex; diff --git a/src/llvm_backend_general.cpp b/src/llvm_backend_general.cpp index a849929f0..c09648825 100644 --- a/src/llvm_backend_general.cpp +++ b/src/llvm_backend_general.cpp @@ -316,6 +316,7 @@ gb_internal bool lb_is_instr_terminating(LLVMValueRef instr) { gb_internal lbModule *lb_pkg_module(lbGenerator *gen, AstPackage *pkg) { + // NOTE(bill): no need for a mutex since it's immutable auto *found = map_get(&gen->modules, pkg); if (found) { return *found; @@ -1354,7 +1355,7 @@ gb_internal String lb_mangle_name(lbModule *m, Entity *e) { return mangled_name; } -gb_internal String lb_set_nested_type_name_ir_mangled_name(Entity *e, lbProcedure *p) { +gb_internal String lb_set_nested_type_name_ir_mangled_name(Entity *e, lbProcedure *p, lbModule *module) { // NOTE(bill, 2020-03-08): A polymorphic procedure may take a nested type declaration // and as a result, the declaration does not have time to determine what it should be @@ -1421,7 +1422,7 @@ gb_internal String lb_get_entity_name(lbModule *m, Entity *e, String default_nam } if (e->kind == Entity_TypeName && (e->scope->flags & ScopeFlag_File) == 0) { - return lb_set_nested_type_name_ir_mangled_name(e, nullptr); + return lb_set_nested_type_name_ir_mangled_name(e, nullptr, m); } String name = {}; @@ -2164,19 +2165,25 @@ gb_internal void lb_ensure_abi_function_type(lbModule *m, lbProcedure *p) { gb_internal void lb_add_entity(lbModule *m, Entity *e, lbValue val) { if (e != nullptr) { + mutex_lock(&m->values_mutex); map_set(&m->values, e, val); + mutex_unlock(&m->values_mutex); } } gb_internal void lb_add_member(lbModule *m, String const &name, lbValue val) { if (name.len > 0) { + mutex_lock(&m->values_mutex); string_map_set(&m->members, name, val); + mutex_unlock(&m->values_mutex); } } gb_internal void lb_add_procedure_value(lbModule *m, lbProcedure *p) { + mutex_lock(&m->values_mutex); if (p->entity != nullptr) { map_set(&m->procedure_values, p->value, p->entity); } string_map_set(&m->procedures, p->name, p); + mutex_unlock(&m->values_mutex); } @@ -2519,6 +2526,8 @@ gb_internal lbValue lb_find_ident(lbProcedure *p, lbModule *m, Entity *e, Ast *e return *found; } } + mutex_lock(&m->values_mutex); + defer (mutex_unlock(&m->values_mutex)); auto *found = map_get(&m->values, e); if (found) { @@ -2538,7 +2547,6 @@ gb_internal lbValue lb_find_ident(lbProcedure *p, lbModule *m, Entity *e, Ast *e if (USE_SEPARATE_MODULES) { lbModule *other_module = lb_pkg_module(m->gen, e->pkg); if (other_module != m) { - String name = lb_get_entity_name(other_module, e); lb_set_entity_from_other_modules_linkage_correctly(other_module, e, name); @@ -2569,6 +2577,9 @@ gb_internal lbValue lb_find_procedure_value_from_entity(lbModule *m, Entity *e) e = strip_entity_wrapping(e); GB_ASSERT(e != nullptr); + mutex_lock(&m->values_mutex); + defer (mutex_unlock(&m->values_mutex)); + auto *found = map_get(&m->values, e); if (found) { return *found; @@ -2657,6 +2668,10 @@ gb_internal lbValue lb_find_value_from_entity(lbModule *m, Entity *e) { return lb_find_procedure_value_from_entity(m, e); } + mutex_lock(&m->values_mutex); + defer (mutex_unlock(&m->values_mutex)); + + auto *found = map_get(&m->values, e); if (found) { return *found; diff --git a/src/llvm_backend_stmt.cpp b/src/llvm_backend_stmt.cpp index 0e6f75118..73b4e251f 100644 --- a/src/llvm_backend_stmt.cpp +++ b/src/llvm_backend_stmt.cpp @@ -32,7 +32,7 @@ gb_internal void lb_build_constant_value_decl(lbProcedure *p, AstValueDecl *vd) continue; } - lb_set_nested_type_name_ir_mangled_name(e, p); + lb_set_nested_type_name_ir_mangled_name(e, p, p->module); } for_array(i, vd->names) { -- cgit v1.2.3