From 34a048f7daaf93b16ae4121bf5238f9008f3465b Mon Sep 17 00:00:00 2001 From: gingerBill Date: Fri, 9 Dec 2022 11:29:28 +0000 Subject: Replace compiler for loops for the hash-table types to simplify code usage --- src/checker.cpp | 134 +++++++++++++++++++++++++++----------------------------- 1 file changed, 65 insertions(+), 69 deletions(-) (limited to 'src/checker.cpp') diff --git a/src/checker.cpp b/src/checker.cpp index 30a070d06..d5222f615 100644 --- a/src/checker.cpp +++ b/src/checker.cpp @@ -308,8 +308,8 @@ Scope *create_scope_from_package(CheckerContext *c, AstPackage *pkg) { } void destroy_scope(Scope *scope) { - for_array(i, scope->elements.entries) { - Entity *e =scope->elements.entries[i].value; + for (auto const &entry : scope->elements) { + Entity *e = entry.value; if (e->kind == Entity_Variable) { if (!(e->flags & EntityFlag_Used)) { #if 0 @@ -659,8 +659,8 @@ void check_scope_usage(Checker *c, Scope *scope) { Array vetted_entities = {}; array_init(&vetted_entities, heap_allocator()); - MUTEX_GUARD_BLOCK(scope->mutex) for_array(i, scope->elements.entries) { - Entity *e = scope->elements.entries[i].value; + MUTEX_GUARD_BLOCK(scope->mutex) for (auto const &entry : scope->elements) { + Entity *e = entry.value; if (e == nullptr) continue; VettedEntity ve_unused = {}; VettedEntity ve_shadowed = {}; @@ -755,9 +755,8 @@ AstPackage *get_core_package(CheckerInfo *info, String name) { gb_printf_err("Name: %.*s\n", LIT(name)); gb_printf_err("Fullpath: %.*s\n", LIT(path)); - for_array(i, info->packages.entries) { - auto *entry = &info->packages.entries[i]; - gb_printf_err("%.*s\n", LIT(entry->key.string)); + for (auto const &entry : info->packages) { + gb_printf_err("%.*s\n", LIT(entry.key.string)); } GB_ASSERT_MSG(found != nullptr, "Missing core package %.*s", LIT(name)); } @@ -1065,9 +1064,9 @@ void init_universal(void) { } bool defined_values_double_declaration = false; - for_array(i, bc->defined_values.entries) { - char const *name = bc->defined_values.entries[i].key; - ExactValue value = bc->defined_values.entries[i].value; + for (auto const &entry : bc->defined_values) { + char const *name = entry.key; + ExactValue value = entry.value; GB_ASSERT(value.kind != ExactValue_Invalid); Type *type = nullptr; @@ -1418,10 +1417,9 @@ isize type_info_index(CheckerInfo *info, Type *type, bool error_on_failure) { if (entry_index < 0) { // NOTE(bill): Do manual search // TODO(bill): This is O(n) and can be very slow - for_array(i, info->type_info_map.entries){ - auto *e = &info->type_info_map.entries[i]; - if (are_types_identical_unique_tuples(e->key, type)) { - entry_index = e->value; + 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; @@ -1781,11 +1779,10 @@ void add_type_info_type_internal(CheckerContext *c, Type *t) { bool prev = false; isize ti_index = -1; - for_array(i, c->info->type_info_map.entries) { - auto *e = &c->info->type_info_map.entries[i]; - if (are_types_identical_unique_tuples(t, e->key)) { + for (auto const &e : c->info->type_info_map) { + if (are_types_identical_unique_tuples(t, e.key)) { // Duplicate entry - ti_index = e->value; + ti_index = e.value; prev = true; break; } @@ -1908,8 +1905,8 @@ void add_type_info_type_internal(CheckerContext *c, Type *t) { case Type_Struct: if (bt->Struct.scope != nullptr) { - for_array(i, bt->Struct.scope->elements.entries) { - Entity *e = bt->Struct.scope->elements.entries[i].value; + for (auto const &entry : bt->Struct.scope->elements) { + Entity *e = entry.value; switch (bt->Struct.soa_kind) { case StructSoa_Dynamic: add_type_info_type_internal(c, t_allocator); @@ -2132,8 +2129,8 @@ void add_min_dep_type_info(Checker *c, Type *t) { case Type_Struct: if (bt->Struct.scope != nullptr) { - for_array(i, bt->Struct.scope->elements.entries) { - Entity *e = bt->Struct.scope->elements.entries[i].value; + for (auto const &entry : bt->Struct.scope->elements) { + Entity *e = entry.value; switch (bt->Struct.soa_kind) { case StructSoa_Dynamic: add_min_dep_type_info(c, t_allocator); @@ -2230,13 +2227,12 @@ void add_dependency_to_set(Checker *c, Entity *entity) { return; } - for_array(i, decl->type_info_deps.entries) { - Type *type = decl->type_info_deps.entries[i].ptr; - add_min_dep_type_info(c, type); + for (auto const &entry : decl->type_info_deps) { + add_min_dep_type_info(c, entry.ptr); } - for_array(i, decl->deps.entries) { - Entity *e = decl->deps.entries[i].ptr; + for (auto const &entry : decl->deps) { + Entity *e = entry.ptr; add_dependency_to_set(c, e); if (e->kind == Entity_Procedure && e->Procedure.is_foreign) { Entity *fl = e->Procedure.foreign_library; @@ -2430,8 +2426,8 @@ void generate_minimum_dependency_set(Checker *c, Entity *start) { Scope *testing_scope = testing_package->scope; // Add all of testing library as a dependency - for_array(i, testing_scope->elements.entries) { - Entity *e = testing_scope->elements.entries[i].value; + for (auto const &entry : testing_scope->elements) { + Entity *e = entry.value; if (e != nullptr) { e->flags |= EntityFlag_Used; add_dependency_to_set(c, e); @@ -2445,8 +2441,8 @@ void generate_minimum_dependency_set(Checker *c, Entity *start) { AstPackage *pkg = c->info.init_package; Scope *s = pkg->scope; - for_array(i, s->elements.entries) { - Entity *e = s->elements.entries[i].value; + for (auto const &entry : s->elements) { + Entity *e = entry.value; if (e->kind != Entity_Procedure) { continue; } @@ -2512,15 +2508,15 @@ Array generate_entity_dependency_graph(CheckerInfo *info, gbA TIME_SECTION("generate_entity_dependency_graph: Calculate edges for graph M - Part 1"); // Calculate edges for graph M - for_array(i, M.entries) { - EntityGraphNode *n = M.entries[i].value; + for (auto const &entry : M) { + EntityGraphNode *n = entry.value; Entity *e = n->entity; DeclInfo *decl = decl_info_of_entity(e); GB_ASSERT(decl != nullptr); - for_array(j, decl->deps.entries) { - Entity *dep = decl->deps.entries[j].ptr; + for (auto const &entry : decl->deps) { + Entity *dep = entry.ptr; if (dep->flags & EntityFlag_Field) { continue; } @@ -2539,23 +2535,22 @@ Array generate_entity_dependency_graph(CheckerInfo *info, gbA TIME_SECTION("generate_entity_dependency_graph: Calculate edges for graph M - Part 2"); auto G = array_make(allocator, 0, M.entries.count); - for_array(i, M.entries) { - auto *entry = &M.entries[i]; - auto *e = entry->key; - EntityGraphNode *n = entry->value; + for (auto const &m_entry : M) { + auto *e = m_entry.key; + EntityGraphNode *n = m_entry.value; if (e->kind == Entity_Procedure) { // Connect each pred 'p' of 'n' with each succ 's' and from // the procedure node - for_array(j, n->pred.entries) { - EntityGraphNode *p = n->pred.entries[j].ptr; + for (auto const &p_entry : n->pred) { + EntityGraphNode *p = p_entry.ptr; // Ignore self-cycles if (p != n) { // Each succ 's' of 'n' becomes a succ of 'p', and // each pred 'p' of 'n' becomes a pred of 's' - for_array(k, n->succ.entries) { - EntityGraphNode *s = n->succ.entries[k].ptr; + for (auto const &s_entry : n->succ) { + EntityGraphNode *s = s_entry.ptr; // Ignore self-cycles if (s != n) { if (p->entity->kind == Entity_Procedure && @@ -4273,9 +4268,10 @@ Array generate_import_dependency_graph(Checker *c) { Array G = {}; array_init(&G, heap_allocator(), 0, M.entries.count); - for_array(i, M.entries) { - auto n = M.entries[i].value; - n->index = i; + isize i = 0; + for (auto const &entry : M) { + auto n = entry.value; + n->index = i++; n->dep_count = n->succ.entries.count; GB_ASSERT(n->dep_count >= 0); array_add(&G, n); @@ -4376,8 +4372,8 @@ void check_add_import_decl(CheckerContext *ctx, Ast *decl) { } else { AstPackage **found = string_map_get(pkgs, id->fullpath); if (found == nullptr) { - for_array(pkg_index, pkgs->entries) { - AstPackage *pkg = pkgs->entries[pkg_index].value; + for (auto const &entry : *pkgs) { + AstPackage *pkg = entry.value; gb_printf_err("%.*s\n", LIT(pkg->fullpath)); } gb_printf_err("%s\n", token_pos_to_string(token.pos)); @@ -4871,8 +4867,8 @@ void check_import_entities(Checker *c) { } } - for_array(i, n->pred.entries) { - ImportGraphNode *p = n->pred.entries[i].ptr; + for (auto const &entry : n->pred) { + ImportGraphNode *p = entry.ptr; p->dep_count = gb_max(p->dep_count-1, 0); priority_queue_fix(&pq, p->index); } @@ -4979,8 +4975,8 @@ bool find_entity_path_tuple(Type *tuple, Entity *end, PtrSet *visited, if (var_decl == nullptr) { continue; } - for_array(i, var_decl->deps.entries) { - Entity *dep = var_decl->deps.entries[i].ptr; + for (auto const &entry : var_decl->deps) { + Entity *dep = entry.ptr; if (dep == end) { auto path = array_make(heap_allocator()); array_add(&path, dep); @@ -5032,8 +5028,8 @@ Array find_entity_path(Entity *start, Entity *end, PtrSet *v return path; } } else { - for_array(i, decl->deps.entries) { - Entity *dep = decl->deps.entries[i].ptr; + for (auto const &entry : decl->deps) { + Entity *dep = entry.ptr; if (dep == end) { auto path = array_make(heap_allocator()); array_add(&path, dep); @@ -5091,8 +5087,8 @@ void calculate_global_init_order(Checker *c) { } } - for_array(i, n->pred.entries) { - EntityGraphNode *p = n->pred.entries[i].ptr; + for (auto const &entry : n->pred) { + EntityGraphNode *p = entry.ptr; p->dep_count -= 1; p->dep_count = gb_max(p->dep_count, 0); priority_queue_fix(&pq, p->index); @@ -5217,8 +5213,8 @@ void check_unchecked_bodies(Checker *c) { map_init(&untyped, heap_allocator()); defer (map_destroy(&untyped)); - for_array(i, c->info.minimum_dependency_set.entries) { - Entity *e = c->info.minimum_dependency_set.entries[i].ptr; + for (auto const &entry : c->info.minimum_dependency_set) { + Entity *e = entry.ptr; if (e == nullptr || e->kind != Entity_Procedure) { continue; } @@ -5267,8 +5263,8 @@ void check_test_procedures(Checker *c) { AstPackage *pkg = c->info.init_package; Scope *s = pkg->scope; - for_array(i, build_context.test_names.entries) { - String name = build_context.test_names.entries[i].value; + for (auto const &entry : build_context.test_names) { + String name = entry.value; Entity *e = scope_lookup(s, name); if (e == nullptr) { Token tok = {}; @@ -5422,9 +5418,9 @@ void add_untyped_expressions(CheckerInfo *cinfo, UntypedExprInfoMap *untyped) { if (untyped == nullptr) { return; } - for_array(i, untyped->entries) { - Ast *expr = untyped->entries[i].key; - ExprInfo *info = untyped->entries[i].value; + for (auto const &entry : *untyped) { + Ast *expr = entry.key; + ExprInfo *info = entry.value; if (expr != nullptr && info != nullptr) { mpmc_enqueue(&cinfo->checker->global_untyped_queue, UntypedExprInfo{expr, info}); } @@ -5590,8 +5586,8 @@ void check_unique_package_names(Checker *c) { string_map_init(&pkgs, heap_allocator(), 2*c->info.packages.entries.count); defer (string_map_destroy(&pkgs)); - for_array(i, c->info.packages.entries) { - AstPackage *pkg = c->info.packages.entries[i].value; + for (auto const &entry : c->info.packages) { + AstPackage *pkg = entry.value; if (pkg->files.count == 0) { continue; // Sanity check } @@ -5752,8 +5748,8 @@ void check_parsed_files(Checker *c) { check_merge_queues_into_arrays(c); TIME_SECTION("check scope usage"); - for_array(i, c->info.files.entries) { - AstFile *f = c->info.files.entries[i].value; + for (auto const &entry : c->info.files) { + AstFile *f = entry.value; check_scope_usage(c, f->scope); } @@ -5789,8 +5785,8 @@ void check_parsed_files(Checker *c) { DeclInfo *decl = e->decl_info; ast_node(pl, ProcLit, decl->proc_lit); if (pl->inlining == ProcInlining_inline) { - for_array(j, decl->deps.entries) { - Entity *dep = decl->deps.entries[j].ptr; + for (auto const &entry : decl->deps) { + Entity *dep = entry.ptr; if (dep == e) { error(e->token, "Cannot inline recursive procedure '%.*s'", LIT(e->token.string)); break; -- cgit v1.2.3 From 690666537c8a27d3c418b38b3285899100c9a556 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Sun, 18 Dec 2022 21:46:27 +0000 Subject: Add `gb_internal` to checker --- src/check_builtin.cpp | 34 ++--- src/check_decl.cpp | 44 +++--- src/check_expr.cpp | 334 +++++++++++++++++++++--------------------- src/check_stmt.cpp | 46 +++--- src/check_type.cpp | 80 +++++----- src/checker.cpp | 393 +++++++++++++++++++++++++------------------------- src/types.cpp | 3 +- 7 files changed, 466 insertions(+), 468 deletions(-) (limited to 'src/checker.cpp') diff --git a/src/check_builtin.cpp b/src/check_builtin.cpp index 533929200..859fbea28 100644 --- a/src/check_builtin.cpp +++ b/src/check_builtin.cpp @@ -1,6 +1,6 @@ typedef bool (BuiltinTypeIsProc)(Type *t); -BuiltinTypeIsProc *builtin_type_is_procs[BuiltinProc__type_simple_boolean_end - BuiltinProc__type_simple_boolean_begin] = { +gb_global BuiltinTypeIsProc *builtin_type_is_procs[BuiltinProc__type_simple_boolean_end - BuiltinProc__type_simple_boolean_begin] = { nullptr, // BuiltinProc__type_simple_boolean_begin is_type_boolean, @@ -51,7 +51,7 @@ BuiltinTypeIsProc *builtin_type_is_procs[BuiltinProc__type_simple_boolean_end - }; -void check_or_else_right_type(CheckerContext *c, Ast *expr, String const &name, Type *right_type) { +gb_internal void check_or_else_right_type(CheckerContext *c, Ast *expr, String const &name, Type *right_type) { if (right_type == nullptr) { return; } @@ -62,7 +62,7 @@ void check_or_else_right_type(CheckerContext *c, Ast *expr, String const &name, } } -void check_or_else_split_types(CheckerContext *c, Operand *x, String const &name, Type **left_type_, Type **right_type_) { +gb_internal void check_or_else_split_types(CheckerContext *c, Operand *x, String const &name, Type **left_type_, Type **right_type_) { Type *left_type = nullptr; Type *right_type = nullptr; if (x->type->kind == Type_Tuple) { @@ -88,7 +88,7 @@ void check_or_else_split_types(CheckerContext *c, Operand *x, String const &name } -void check_or_else_expr_no_value_error(CheckerContext *c, String const &name, Operand const &x, Type *type_hint) { +gb_internal void check_or_else_expr_no_value_error(CheckerContext *c, String const &name, Operand const &x, Type *type_hint) { // TODO(bill): better error message gbString t = type_to_string(x.type); error(x.expr, "'%.*s' does not return a value, value is of type %s", LIT(name), t); @@ -118,7 +118,7 @@ void check_or_else_expr_no_value_error(CheckerContext *c, String const &name, Op } -void check_or_return_split_types(CheckerContext *c, Operand *x, String const &name, Type **left_type_, Type **right_type_) { +gb_internal void check_or_return_split_types(CheckerContext *c, Operand *x, String const &name, Type **left_type_, Type **right_type_) { Type *left_type = nullptr; Type *right_type = nullptr; if (x->type->kind == Type_Tuple) { @@ -144,7 +144,7 @@ void check_or_return_split_types(CheckerContext *c, Operand *x, String const &na } -bool does_require_msgSend_stret(Type *return_type) { +gb_internal bool does_require_msgSend_stret(Type *return_type) { if (return_type == nullptr) { return false; } @@ -165,7 +165,7 @@ bool does_require_msgSend_stret(Type *return_type) { return false; } -ObjcMsgKind get_objc_proc_kind(Type *return_type) { +gb_internal ObjcMsgKind get_objc_proc_kind(Type *return_type) { if (return_type == nullptr) { return ObjcMsg_normal; } @@ -189,7 +189,7 @@ ObjcMsgKind get_objc_proc_kind(Type *return_type) { return ObjcMsg_normal; } -void add_objc_proc_type(CheckerContext *c, Ast *call, Type *return_type, Slice param_types) { +gb_internal void add_objc_proc_type(CheckerContext *c, Ast *call, Type *return_type, Slice param_types) { ObjcMsgKind kind = get_objc_proc_kind(return_type); Scope *scope = create_scope(c->info, nullptr); @@ -230,7 +230,7 @@ void add_objc_proc_type(CheckerContext *c, Ast *call, Type *return_type, Sliceproc); String builtin_name = bd->name.string; @@ -1170,7 +1170,7 @@ bool cache_load_file_directive(CheckerContext *c, Ast *call, String const &origi } -bool is_valid_type_for_load(Type *type) { +gb_internal bool is_valid_type_for_load(Type *type) { if (type == t_invalid) { return false; } else if (is_type_string(type)) { @@ -1191,7 +1191,7 @@ bool is_valid_type_for_load(Type *type) { return false; } -LoadDirectiveResult check_load_directive(CheckerContext *c, Operand *operand, Ast *call, Type *type_hint, bool err_on_not_found) { +gb_internal LoadDirectiveResult check_load_directive(CheckerContext *c, Operand *operand, Ast *call, Type *type_hint, bool err_on_not_found) { ast_node(ce, CallExpr, call); ast_node(bd, BasicDirective, ce->proc); String name = bd->name.string; @@ -1256,7 +1256,7 @@ LoadDirectiveResult check_load_directive(CheckerContext *c, Operand *operand, As } -bool check_builtin_procedure_directive(CheckerContext *c, Operand *operand, Ast *call, Type *type_hint) { +gb_internal bool check_builtin_procedure_directive(CheckerContext *c, Operand *operand, Ast *call, Type *type_hint) { ast_node(ce, CallExpr, call); ast_node(bd, BasicDirective, ce->proc); String name = bd->name.string; @@ -1581,7 +1581,7 @@ bool check_builtin_procedure_directive(CheckerContext *c, Operand *operand, Ast return true; } -bool check_builtin_procedure(CheckerContext *c, Operand *operand, Ast *call, i32 id, Type *type_hint) { +gb_internal bool check_builtin_procedure(CheckerContext *c, Operand *operand, Ast *call, i32 id, Type *type_hint) { ast_node(ce, CallExpr, call); if (ce->inlining != ProcInlining_none) { error(call, "Inlining operators are not allowed on built-in procedures"); diff --git a/src/check_decl.cpp b/src/check_decl.cpp index 18e5477d6..a976c1b73 100644 --- a/src/check_decl.cpp +++ b/src/check_decl.cpp @@ -1,7 +1,7 @@ -void check_stmt (CheckerContext *ctx, Ast *node, u32 flags); +gb_internal void check_stmt(CheckerContext *ctx, Ast *node, u32 flags); // NOTE(bill): 'content_name' is for debugging and error messages -Type *check_init_variable(CheckerContext *ctx, Entity *e, Operand *operand, String context_name) { +gb_internal Type *check_init_variable(CheckerContext *ctx, Entity *e, Operand *operand, String context_name) { if (operand->mode == Addressing_Invalid || operand->type == t_invalid || e->type == t_invalid) { @@ -110,7 +110,7 @@ Type *check_init_variable(CheckerContext *ctx, Entity *e, Operand *operand, Stri return e->type; } -void check_init_variables(CheckerContext *ctx, Entity **lhs, isize lhs_count, Slice const &inits, String context_name) { +gb_internal void check_init_variables(CheckerContext *ctx, Entity **lhs, isize lhs_count, Slice const &inits, String context_name) { if ((lhs == nullptr || lhs_count == 0) && inits.count == 0) { return; } @@ -144,7 +144,7 @@ void check_init_variables(CheckerContext *ctx, Entity **lhs, isize lhs_count, Sl } } -void check_init_constant(CheckerContext *ctx, Entity *e, Operand *operand) { +gb_internal void check_init_constant(CheckerContext *ctx, Entity *e, Operand *operand) { if (operand->mode == Addressing_Invalid || operand->type == t_invalid || e->type == t_invalid) { @@ -184,7 +184,7 @@ void check_init_constant(CheckerContext *ctx, Entity *e, Operand *operand) { } -bool is_type_distinct(Ast *node) { +gb_internal bool is_type_distinct(Ast *node) { for (;;) { if (node == nullptr) { return false; @@ -217,7 +217,7 @@ bool is_type_distinct(Ast *node) { return false; } -Ast *remove_type_alias_clutter(Ast *node) { +gb_internal Ast *remove_type_alias_clutter(Ast *node) { for (;;) { if (node == nullptr) { return nullptr; @@ -232,7 +232,7 @@ Ast *remove_type_alias_clutter(Ast *node) { } } -isize total_attribute_count(DeclInfo *decl) { +gb_internal isize total_attribute_count(DeclInfo *decl) { isize attribute_count = 0; for_array(i, decl->attributes) { Ast *attr = decl->attributes[i]; @@ -242,7 +242,7 @@ isize total_attribute_count(DeclInfo *decl) { return attribute_count; } -Type *clone_enum_type(CheckerContext *ctx, Type *original_enum_type, Type *named_type) { +gb_internal Type *clone_enum_type(CheckerContext *ctx, Type *original_enum_type, Type *named_type) { // NOTE(bill, 2022-02-05): Stupid edge case for `distinct` declarations // // X :: enum {A, B, C} @@ -288,7 +288,7 @@ Type *clone_enum_type(CheckerContext *ctx, Type *original_enum_type, Type *named return et; } -void check_type_decl(CheckerContext *ctx, Entity *e, Ast *init_expr, Type *def) { +gb_internal void check_type_decl(CheckerContext *ctx, Entity *e, Ast *init_expr, Type *def) { GB_ASSERT(e->type == nullptr); DeclInfo *decl = decl_info_of_entity(e); @@ -390,7 +390,7 @@ void check_type_decl(CheckerContext *ctx, Entity *e, Ast *init_expr, Type *def) } -void override_entity_in_scope(Entity *original_entity, Entity *new_entity) { +gb_internal void override_entity_in_scope(Entity *original_entity, Entity *new_entity) { // NOTE(bill): The original_entity's scope may not be same scope that it was inserted into // e.g. file entity inserted into its package scope String original_name = original_entity->token.string; @@ -433,7 +433,7 @@ void override_entity_in_scope(Entity *original_entity, Entity *new_entity) { -void check_const_decl(CheckerContext *ctx, Entity *e, Ast *type_expr, Ast *init, Type *named_type) { +gb_internal void check_const_decl(CheckerContext *ctx, Entity *e, Ast *type_expr, Ast *init, Type *named_type) { GB_ASSERT(e->type == nullptr); GB_ASSERT(e->kind == Entity_Constant); init = unparen_expr(init); @@ -609,12 +609,12 @@ void check_const_decl(CheckerContext *ctx, Entity *e, Ast *type_expr, Ast *init, typedef bool TypeCheckSig(Type *t); -bool sig_compare(TypeCheckSig *a, Type *x, Type *y) { +gb_internal bool sig_compare(TypeCheckSig *a, Type *x, Type *y) { x = core_type(x); y = core_type(y); return (a(x) && a(y)); } -bool sig_compare(TypeCheckSig *a, TypeCheckSig *b, Type *x, Type *y) { +gb_internal bool sig_compare(TypeCheckSig *a, TypeCheckSig *b, Type *x, Type *y) { x = core_type(x); y = core_type(y); if (a == b) { @@ -623,7 +623,7 @@ bool sig_compare(TypeCheckSig *a, TypeCheckSig *b, Type *x, Type *y) { return ((a(x) && b(y)) || (b(x) && a(y))); } -bool signature_parameter_similar_enough(Type *x, Type *y) { +gb_internal bool signature_parameter_similar_enough(Type *x, Type *y) { if (sig_compare(is_type_pointer, x, y)) { return true; } @@ -674,7 +674,7 @@ bool signature_parameter_similar_enough(Type *x, Type *y) { } -bool are_signatures_similar_enough(Type *a_, Type *b_) { +gb_internal bool are_signatures_similar_enough(Type *a_, Type *b_) { GB_ASSERT(a_->kind == Type_Proc); GB_ASSERT(b_->kind == Type_Proc); TypeProc *a = &a_->Proc; @@ -704,7 +704,7 @@ bool are_signatures_similar_enough(Type *a_, Type *b_) { return true; } -Entity *init_entity_foreign_library(CheckerContext *ctx, Entity *e) { +gb_internal Entity *init_entity_foreign_library(CheckerContext *ctx, Entity *e) { Ast *ident = nullptr; Entity **foreign_library = nullptr; @@ -747,7 +747,7 @@ Entity *init_entity_foreign_library(CheckerContext *ctx, Entity *e) { return nullptr; } -String handle_link_name(CheckerContext *ctx, Token token, String link_name, String link_prefix) { +gb_internal String handle_link_name(CheckerContext *ctx, Token token, String link_name, String link_prefix) { if (link_prefix.len > 0) { if (link_name.len > 0) { error(token, "'link_name' and 'link_prefix' cannot be used together"); @@ -764,7 +764,7 @@ String handle_link_name(CheckerContext *ctx, Token token, String link_name, Stri return link_name; } -void check_proc_decl(CheckerContext *ctx, Entity *e, DeclInfo *d) { +gb_internal void check_proc_decl(CheckerContext *ctx, Entity *e, DeclInfo *d) { GB_ASSERT(e->type == nullptr); if (d->proc_lit->kind != Ast_ProcLit) { // TOOD(bill): Better error message @@ -1121,7 +1121,7 @@ void check_proc_decl(CheckerContext *ctx, Entity *e, DeclInfo *d) { } } -void check_global_variable_decl(CheckerContext *ctx, Entity *&e, Ast *type_expr, Ast *init_expr) { +gb_internal void check_global_variable_decl(CheckerContext *ctx, Entity *&e, Ast *type_expr, Ast *init_expr) { GB_ASSERT(e->type == nullptr); GB_ASSERT(e->kind == Entity_Variable); @@ -1239,7 +1239,7 @@ void check_global_variable_decl(CheckerContext *ctx, Entity *&e, Ast *type_expr, check_rtti_type_disallowed(e->token, e->type, "A variable declaration is using a type, %s, which has been disallowed"); } -void check_proc_group_decl(CheckerContext *ctx, Entity *&pg_entity, DeclInfo *d) { +gb_internal void check_proc_group_decl(CheckerContext *ctx, Entity *&pg_entity, DeclInfo *d) { GB_ASSERT(pg_entity->kind == Entity_ProcGroup); auto *pge = &pg_entity->ProcGroup; String proc_group_name = pg_entity->token.string; @@ -1367,7 +1367,7 @@ void check_proc_group_decl(CheckerContext *ctx, Entity *&pg_entity, DeclInfo *d) } -void check_entity_decl(CheckerContext *ctx, Entity *e, DeclInfo *d, Type *named_type) { +gb_internal void check_entity_decl(CheckerContext *ctx, Entity *e, DeclInfo *d, Type *named_type) { if (e->state == EntityState_Resolved) { return; } @@ -1437,7 +1437,7 @@ struct ProcUsingVar { }; -void check_proc_body(CheckerContext *ctx_, Token token, DeclInfo *decl, Type *type, Ast *body) { +gb_internal void check_proc_body(CheckerContext *ctx_, Token token, DeclInfo *decl, Type *type, Ast *body) { if (body == nullptr) { return; } diff --git a/src/check_expr.cpp b/src/check_expr.cpp index fbc4f8b63..3003e07b6 100644 --- a/src/check_expr.cpp +++ b/src/check_expr.cpp @@ -17,7 +17,7 @@ enum CallArgumentError { CallArgumentError_MAX, }; -char const *CallArgumentError_strings[CallArgumentError_MAX] = { +gb_global char const *CallArgumentError_strings[CallArgumentError_MAX] = { "None", "NoneProcedureType", "WrongTypes", @@ -57,7 +57,7 @@ struct ValidIndexAndScore { i64 score; }; -int valid_index_and_score_cmp(void const *a, void const *b) { +gb_internal int valid_index_and_score_cmp(void const *a, void const *b) { i64 si = (cast(ValidIndexAndScore const *)a)->score; i64 sj = (cast(ValidIndexAndScore const *)b)->score; return sj < si ? -1 : sj > si; @@ -70,56 +70,56 @@ typedef CALL_ARGUMENT_CHECKER(CallArgumentCheckerType); -void check_expr (CheckerContext *c, Operand *operand, Ast *expression); -void check_multi_expr (CheckerContext *c, Operand *operand, Ast *expression); -void check_multi_expr_or_type (CheckerContext *c, Operand *operand, Ast *expression); -void check_multi_expr_with_type_hint(CheckerContext *c, Operand *o, Ast *e, Type *type_hint); -void check_expr_or_type (CheckerContext *c, Operand *operand, Ast *expression, Type *type_hint); -ExprKind check_expr_base (CheckerContext *c, Operand *operand, Ast *expression, Type *type_hint); -void check_expr_with_type_hint (CheckerContext *c, Operand *o, Ast *e, Type *t); -Type * check_type (CheckerContext *c, Ast *expression); -Type * check_type_expr (CheckerContext *c, Ast *expression, Type *named_type); -Type * make_optional_ok_type (Type *value, bool typed=true); -Entity * check_selector (CheckerContext *c, Operand *operand, Ast *node, Type *type_hint); -Entity * check_ident (CheckerContext *c, Operand *o, Ast *n, Type *named_type, Type *type_hint, bool allow_import_name); -Entity * find_polymorphic_record_entity (CheckerContext *c, Type *original_type, isize param_count, Array const &ordered_operands, bool *failure); -void check_not_tuple (CheckerContext *c, Operand *operand); -void convert_to_typed (CheckerContext *c, Operand *operand, Type *target_type); -gbString expr_to_string (Ast *expression); -void check_proc_body (CheckerContext *c, Token token, DeclInfo *decl, Type *type, Ast *body); -void update_untyped_expr_type (CheckerContext *c, Ast *e, Type *type, bool final); -bool check_is_terminating (Ast *node, String const &label); -bool check_has_break (Ast *stmt, String const &label, bool implicit); -void check_stmt (CheckerContext *c, Ast *node, u32 flags); -void check_stmt_list (CheckerContext *c, Slice const &stmts, u32 flags); -void check_init_constant (CheckerContext *c, Entity *e, Operand *operand); -bool check_representable_as_constant(CheckerContext *c, ExactValue in_value, Type *type, ExactValue *out_value); -bool check_procedure_type (CheckerContext *c, Type *type, Ast *proc_type_node, Array *operands = nullptr); -void check_struct_type (CheckerContext *c, Type *struct_type, Ast *node, Array *poly_operands, - Type *named_type = nullptr, Type *original_type_for_poly = nullptr); -void check_union_type (CheckerContext *c, Type *union_type, Ast *node, Array *poly_operands, - Type *named_type = nullptr, Type *original_type_for_poly = nullptr); +gb_internal void check_expr (CheckerContext *c, Operand *operand, Ast *expression); +gb_internal void check_multi_expr (CheckerContext *c, Operand *operand, Ast *expression); +gb_internal void check_multi_expr_or_type (CheckerContext *c, Operand *operand, Ast *expression); +gb_internal void check_multi_expr_with_type_hint(CheckerContext *c, Operand *o, Ast *e, Type *type_hint); +gb_internal void check_expr_or_type (CheckerContext *c, Operand *operand, Ast *expression, Type *type_hint); +gb_internal ExprKind check_expr_base (CheckerContext *c, Operand *operand, Ast *expression, Type *type_hint); +gb_internal void check_expr_with_type_hint (CheckerContext *c, Operand *o, Ast *e, Type *t); +gb_internal Type * check_type (CheckerContext *c, Ast *expression); +gb_internal Type * check_type_expr (CheckerContext *c, Ast *expression, Type *named_type); +gb_internal Type * make_optional_ok_type (Type *value, bool typed=true); +gb_internal Entity * check_selector (CheckerContext *c, Operand *operand, Ast *node, Type *type_hint); +gb_internal Entity * check_ident (CheckerContext *c, Operand *o, Ast *n, Type *named_type, Type *type_hint, bool allow_import_name); +gb_internal Entity * find_polymorphic_record_entity (CheckerContext *c, Type *original_type, isize param_count, Array const &ordered_operands, bool *failure); +gb_internal void check_not_tuple (CheckerContext *c, Operand *operand); +gb_internal void convert_to_typed (CheckerContext *c, Operand *operand, Type *target_type); +gb_internal gbString expr_to_string (Ast *expression); +gb_internal void check_proc_body (CheckerContext *c, Token token, DeclInfo *decl, Type *type, Ast *body); +gb_internal void update_untyped_expr_type (CheckerContext *c, Ast *e, Type *type, bool final); +gb_internal bool check_is_terminating (Ast *node, String const &label); +gb_internal bool check_has_break (Ast *stmt, String const &label, bool implicit); +gb_internal void check_stmt (CheckerContext *c, Ast *node, u32 flags); +gb_internal void check_stmt_list (CheckerContext *c, Slice const &stmts, u32 flags); +gb_internal void check_init_constant (CheckerContext *c, Entity *e, Operand *operand); +gb_internal bool check_representable_as_constant(CheckerContext *c, ExactValue in_value, Type *type, ExactValue *out_value); +gb_internal bool check_procedure_type (CheckerContext *c, Type *type, Ast *proc_type_node, Array *operands = nullptr); +gb_internal void check_struct_type (CheckerContext *c, Type *struct_type, Ast *node, Array *poly_operands, + Type *named_type = nullptr, Type *original_type_for_poly = nullptr); +gb_internal void check_union_type (CheckerContext *c, Type *union_type, Ast *node, Array *poly_operands, + Type *named_type = nullptr, Type *original_type_for_poly = nullptr); -CallArgumentData check_call_arguments (CheckerContext *c, Operand *operand, Type *proc_type, Ast *call); -Type * check_init_variable (CheckerContext *c, Entity *e, Operand *operand, String context_name); +gb_internal CallArgumentData check_call_arguments (CheckerContext *c, Operand *operand, Type *proc_type, Ast *call); +gb_internal Type * check_init_variable (CheckerContext *c, Entity *e, Operand *operand, String context_name); -void check_assignment_error_suggestion(CheckerContext *c, Operand *o, Type *type); -void add_map_key_type_dependencies(CheckerContext *ctx, Type *key); +gb_internal void check_assignment_error_suggestion(CheckerContext *c, Operand *o, Type *type); +gb_internal void add_map_key_type_dependencies(CheckerContext *ctx, Type *key); -Type *make_soa_struct_slice(CheckerContext *ctx, Ast *array_typ_expr, Ast *elem_expr, Type *elem); -Type *make_soa_struct_dynamic_array(CheckerContext *ctx, Ast *array_typ_expr, Ast *elem_expr, Type *elem); +gb_internal Type *make_soa_struct_slice(CheckerContext *ctx, Ast *array_typ_expr, Ast *elem_expr, Type *elem); +gb_internal Type *make_soa_struct_dynamic_array(CheckerContext *ctx, Ast *array_typ_expr, Ast *elem_expr, Type *elem); -bool check_builtin_procedure(CheckerContext *c, Operand *operand, Ast *call, i32 id, Type *type_hint); +gb_internal bool check_builtin_procedure(CheckerContext *c, Operand *operand, Ast *call, i32 id, Type *type_hint); -void check_promote_optional_ok(CheckerContext *c, Operand *x, Type **val_type_, Type **ok_type_); +gb_internal void check_promote_optional_ok(CheckerContext *c, Operand *x, Type **val_type_, Type **ok_type_); -void check_or_else_right_type(CheckerContext *c, Ast *expr, String const &name, Type *right_type); -void check_or_else_split_types(CheckerContext *c, Operand *x, String const &name, Type **left_type_, Type **right_type_); -void check_or_else_expr_no_value_error(CheckerContext *c, String const &name, Operand const &x, Type *type_hint); -void check_or_return_split_types(CheckerContext *c, Operand *x, String const &name, Type **left_type_, Type **right_type_); +gb_internal void check_or_else_right_type(CheckerContext *c, Ast *expr, String const &name, Type *right_type); +gb_internal void check_or_else_split_types(CheckerContext *c, Operand *x, String const &name, Type **left_type_, Type **right_type_); +gb_internal void check_or_else_expr_no_value_error(CheckerContext *c, String const &name, Operand const &x, Type *type_hint); +gb_internal void check_or_return_split_types(CheckerContext *c, Operand *x, String const &name, Type **left_type_, Type **right_type_); -bool is_diverging_expr(Ast *expr); +gb_internal bool is_diverging_expr(Ast *expr); enum LoadDirectiveResult { @@ -128,7 +128,7 @@ enum LoadDirectiveResult { LoadDirective_NotFound = 2, }; -bool is_load_directive_call(Ast *call) { +gb_internal bool is_load_directive_call(Ast *call) { call = unparen_expr(call); if (call->kind != Ast_CallExpr) { return false; @@ -141,9 +141,9 @@ bool is_load_directive_call(Ast *call) { String name = bd->name.string; return name == "load"; } -LoadDirectiveResult check_load_directive(CheckerContext *c, Operand *operand, Ast *call, Type *type_hint, bool err_on_not_found); +gb_internal LoadDirectiveResult check_load_directive(CheckerContext *c, Operand *operand, Ast *call, Type *type_hint, bool err_on_not_found); -void check_did_you_mean_print(DidYouMeanAnswers *d, char const *prefix = "") { +gb_internal void check_did_you_mean_print(DidYouMeanAnswers *d, char const *prefix = "") { auto results = did_you_mean_results(d); if (results.count != 0) { error_line("\tSuggestion: Did you mean?\n"); @@ -155,7 +155,7 @@ void check_did_you_mean_print(DidYouMeanAnswers *d, char const *prefix = "") { } } -void populate_check_did_you_mean_objc_entity(StringSet *set, Entity *e, bool is_type) { +gb_internal void populate_check_did_you_mean_objc_entity(StringSet *set, Entity *e, bool is_type) { if (e->kind != Entity_TypeName) { return; } @@ -189,7 +189,7 @@ void populate_check_did_you_mean_objc_entity(StringSet *set, Entity *e, bool is_ } -void check_did_you_mean_objc_entity(String const &name, Entity *e, bool is_type, char const *prefix = "") { +gb_internal void check_did_you_mean_objc_entity(String const &name, Entity *e, bool is_type, char const *prefix = "") { ERROR_BLOCK(); GB_ASSERT(e->kind == Entity_TypeName); GB_ASSERT(e->TypeName.objc_metadata != nullptr); @@ -211,7 +211,7 @@ void check_did_you_mean_objc_entity(String const &name, Entity *e, bool is_type, check_did_you_mean_print(&d, prefix); } -void check_did_you_mean_type(String const &name, Array const &fields, char const *prefix = "") { +gb_internal void check_did_you_mean_type(String const &name, Array const &fields, char const *prefix = "") { ERROR_BLOCK(); DidYouMeanAnswers d = did_you_mean_make(heap_allocator(), fields.count, name); @@ -224,7 +224,7 @@ void check_did_you_mean_type(String const &name, Array const &fields, } -void check_did_you_mean_type(String const &name, Slice const &fields, char const *prefix = "") { +gb_internal void check_did_you_mean_type(String const &name, Slice const &fields, char const *prefix = "") { ERROR_BLOCK(); DidYouMeanAnswers d = did_you_mean_make(heap_allocator(), fields.count, name); @@ -236,7 +236,7 @@ void check_did_you_mean_type(String const &name, Slice const &fields, check_did_you_mean_print(&d, prefix); } -void check_did_you_mean_scope(String const &name, Scope *scope, char const *prefix = "") { +gb_internal void check_did_you_mean_scope(String const &name, Scope *scope, char const *prefix = "") { ERROR_BLOCK(); DidYouMeanAnswers d = did_you_mean_make(heap_allocator(), scope->elements.entries.count, name); @@ -249,7 +249,7 @@ void check_did_you_mean_scope(String const &name, Scope *scope, char const *pref check_did_you_mean_print(&d, prefix); } -Entity *entity_from_expr(Ast *expr) { +gb_internal Entity *entity_from_expr(Ast *expr) { expr = unparen_expr(expr); switch (expr->kind) { case Ast_Ident: @@ -260,7 +260,7 @@ Entity *entity_from_expr(Ast *expr) { return nullptr; } -void error_operand_not_expression(Operand *o) { +gb_internal void error_operand_not_expression(Operand *o) { if (o->mode == Addressing_Type) { gbString err = expr_to_string(o->expr); error(o->expr, "'%s' is not an expression but a type", err); @@ -269,7 +269,7 @@ void error_operand_not_expression(Operand *o) { } } -void error_operand_no_value(Operand *o) { +gb_internal void error_operand_no_value(Operand *o) { if (o->mode == Addressing_NoValue) { gbString err = expr_to_string(o->expr); Ast *x = unparen_expr(o->expr); @@ -283,7 +283,7 @@ void error_operand_no_value(Operand *o) { } } -void add_map_get_dependencies(CheckerContext *c) { +gb_internal void add_map_get_dependencies(CheckerContext *c) { if (build_context.use_static_map_calls) { add_package_dependency(c, "runtime", "map_desired_position"); add_package_dependency(c, "runtime", "map_probe_distance"); @@ -292,7 +292,7 @@ void add_map_get_dependencies(CheckerContext *c) { } } -void add_map_set_dependencies(CheckerContext *c) { +gb_internal void add_map_set_dependencies(CheckerContext *c) { init_core_source_code_location(c->checker); if (t_map_set_proc == nullptr) { @@ -308,14 +308,14 @@ void add_map_set_dependencies(CheckerContext *c) { } } -void add_map_reserve_dependencies(CheckerContext *c) { +gb_internal void add_map_reserve_dependencies(CheckerContext *c) { init_core_source_code_location(c->checker); add_package_dependency(c, "runtime", "__dynamic_map_reserve"); } -void check_scope_decls(CheckerContext *c, Slice const &nodes, isize reserve_size) { +gb_internal void check_scope_decls(CheckerContext *c, Slice const &nodes, isize reserve_size) { Scope *s = c->scope; check_collect_entities(c, nodes); @@ -337,8 +337,8 @@ void check_scope_decls(CheckerContext *c, Slice const &nodes, isize reser } } -bool find_or_generate_polymorphic_procedure(CheckerContext *old_c, Entity *base_entity, Type *type, - Array *param_operands, Ast *poly_def_node, PolyProcData *poly_proc_data) { +gb_internal bool find_or_generate_polymorphic_procedure(CheckerContext *old_c, Entity *base_entity, Type *type, + Array *param_operands, Ast *poly_def_node, PolyProcData *poly_proc_data) { /////////////////////////////////////////////////////////////////////////////// // // // TODO CLEANUP(bill): This procedure is very messy and hacky. Clean this!!! // @@ -571,24 +571,24 @@ bool find_or_generate_polymorphic_procedure(CheckerContext *old_c, Entity *base_ return true; } -bool check_polymorphic_procedure_assignment(CheckerContext *c, Operand *operand, Type *type, Ast *poly_def_node, PolyProcData *poly_proc_data) { +gb_internal bool check_polymorphic_procedure_assignment(CheckerContext *c, Operand *operand, Type *type, Ast *poly_def_node, PolyProcData *poly_proc_data) { if (operand->expr == nullptr) return false; Entity *base_entity = entity_of_node(operand->expr); if (base_entity == nullptr) return false; return find_or_generate_polymorphic_procedure(c, base_entity, type, nullptr, poly_def_node, poly_proc_data); } -bool find_or_generate_polymorphic_procedure_from_parameters(CheckerContext *c, Entity *base_entity, Array *operands, Ast *poly_def_node, PolyProcData *poly_proc_data) { +gb_internal bool find_or_generate_polymorphic_procedure_from_parameters(CheckerContext *c, Entity *base_entity, Array *operands, Ast *poly_def_node, PolyProcData *poly_proc_data) { return find_or_generate_polymorphic_procedure(c, base_entity, nullptr, operands, poly_def_node, poly_proc_data); } -bool check_type_specialization_to(CheckerContext *c, Type *specialization, Type *type, bool compound, bool modify_type); -bool is_polymorphic_type_assignable(CheckerContext *c, Type *poly, Type *source, bool compound, bool modify_type); -bool check_cast_internal(CheckerContext *c, Operand *x, Type *type); +gb_internal bool check_type_specialization_to(CheckerContext *c, Type *specialization, Type *type, bool compound, bool modify_type); +gb_internal bool is_polymorphic_type_assignable(CheckerContext *c, Type *poly, Type *source, bool compound, bool modify_type); +gb_internal bool check_cast_internal(CheckerContext *c, Operand *x, Type *type); #define MAXIMUM_TYPE_DISTANCE 10 -i64 check_distance_between_types(CheckerContext *c, Operand *operand, Type *type) { +gb_internal i64 check_distance_between_types(CheckerContext *c, Operand *operand, Type *type) { if (c == nullptr) { GB_ASSERT(operand->mode == Addressing_Value); GB_ASSERT(is_type_typed(operand->type)); @@ -887,7 +887,7 @@ i64 check_distance_between_types(CheckerContext *c, Operand *operand, Type *type } -i64 assign_score_function(i64 distance, bool is_variadic=false) { +gb_internal i64 assign_score_function(i64 distance, bool is_variadic=false) { // 3*x^2 + 1 > x^2 + x + 1 (for positive x) i64 const c = 3*MAXIMUM_TYPE_DISTANCE*MAXIMUM_TYPE_DISTANCE + 1; @@ -900,7 +900,7 @@ i64 assign_score_function(i64 distance, bool is_variadic=false) { } -bool check_is_assignable_to_with_score(CheckerContext *c, Operand *operand, Type *type, i64 *score_, bool is_variadic=false) { +gb_internal bool check_is_assignable_to_with_score(CheckerContext *c, Operand *operand, Type *type, i64 *score_, bool is_variadic=false) { i64 score = 0; i64 distance = check_distance_between_types(c, operand, type); bool ok = distance >= 0; @@ -912,19 +912,19 @@ bool check_is_assignable_to_with_score(CheckerContext *c, Operand *operand, Type } -bool check_is_assignable_to(CheckerContext *c, Operand *operand, Type *type) { +gb_internal bool check_is_assignable_to(CheckerContext *c, Operand *operand, Type *type) { i64 score = 0; return check_is_assignable_to_with_score(c, operand, type, &score); } -bool internal_check_is_assignable_to(Type *src, Type *dst) { +gb_internal bool internal_check_is_assignable_to(Type *src, Type *dst) { Operand x = {}; x.type = src; x.mode = Addressing_Value; return check_is_assignable_to(nullptr, &x, dst); } -AstPackage *get_package_of_type(Type *type) { +gb_internal AstPackage *get_package_of_type(Type *type) { for (;;) { if (type == nullptr) { return nullptr; @@ -962,7 +962,7 @@ AstPackage *get_package_of_type(Type *type) { // NOTE(bill): 'content_name' is for debugging and error messages -void check_assignment(CheckerContext *c, Operand *operand, Type *type, String context_name) { +gb_internal void check_assignment(CheckerContext *c, Operand *operand, Type *type, String context_name) { check_not_tuple(c, operand); if (operand->mode == Addressing_Invalid) { return; @@ -1110,7 +1110,7 @@ void check_assignment(CheckerContext *c, Operand *operand, Type *type, String co } } -bool polymorphic_assign_index(Type **gt_, i64 *dst_count, i64 source_count) { +gb_internal bool polymorphic_assign_index(Type **gt_, i64 *dst_count, i64 source_count) { Type *gt = *gt_; GB_ASSERT(gt->kind == Type_Generic); @@ -1139,7 +1139,7 @@ bool polymorphic_assign_index(Type **gt_, i64 *dst_count, i64 source_count) { return false; } -bool is_polymorphic_type_assignable(CheckerContext *c, Type *poly, Type *source, bool compound, bool modify_type) { +gb_internal bool is_polymorphic_type_assignable(CheckerContext *c, Type *poly, Type *source, bool compound, bool modify_type) { Operand o = {Addressing_Value}; o.type = source; switch (poly->kind) { @@ -1439,7 +1439,7 @@ bool is_polymorphic_type_assignable(CheckerContext *c, Type *poly, Type *source, return false; } -bool check_cycle(CheckerContext *c, Entity *curr, bool report) { +gb_internal bool check_cycle(CheckerContext *c, Entity *curr, bool report) { if (curr->state != EntityState_InProgress) { return false; } @@ -1461,7 +1461,7 @@ bool check_cycle(CheckerContext *c, Entity *curr, bool report) { return false; } -Entity *check_ident(CheckerContext *c, Operand *o, Ast *n, Type *named_type, Type *type_hint, bool allow_import_name) { +gb_internal Entity *check_ident(CheckerContext *c, Operand *o, Ast *n, Type *named_type, Type *type_hint, bool allow_import_name) { GB_ASSERT(n->kind == Ast_Ident); o->mode = Addressing_Invalid; o->expr = n; @@ -1630,7 +1630,7 @@ Entity *check_ident(CheckerContext *c, Operand *o, Ast *n, Type *named_type, Typ } -bool check_unary_op(CheckerContext *c, Operand *o, Token op) { +gb_internal bool check_unary_op(CheckerContext *c, Operand *o, Token op) { if (o->type == nullptr) { gbString str = expr_to_string(o->expr); error(o->expr, "Expression has no value '%s'", str); @@ -1672,7 +1672,7 @@ bool check_unary_op(CheckerContext *c, Operand *o, Token op) { return true; } -bool check_binary_op(CheckerContext *c, Operand *o, Token op) { +gb_internal bool check_binary_op(CheckerContext *c, Operand *o, Token op) { Type *main_type = o->type; // TODO(bill): Handle errors correctly @@ -1783,7 +1783,7 @@ bool check_binary_op(CheckerContext *c, Operand *o, Token op) { } -bool check_representable_as_constant(CheckerContext *c, ExactValue in_value, Type *type, ExactValue *out_value) { +gb_internal bool check_representable_as_constant(CheckerContext *c, ExactValue in_value, Type *type, ExactValue *out_value) { if (in_value.kind == ExactValue_Invalid) { // NOTE(bill): There's already been an error return true; @@ -1998,7 +1998,7 @@ bool check_representable_as_constant(CheckerContext *c, ExactValue in_value, Typ } -void check_assignment_error_suggestion(CheckerContext *c, Operand *o, Type *type) { +gb_internal void check_assignment_error_suggestion(CheckerContext *c, Operand *o, Type *type) { gbString a = expr_to_string(o->expr); gbString b = type_to_string(type); defer( @@ -2032,7 +2032,7 @@ void check_assignment_error_suggestion(CheckerContext *c, Operand *o, Type *type } } -void check_cast_error_suggestion(CheckerContext *c, Operand *o, Type *type) { +gb_internal void check_cast_error_suggestion(CheckerContext *c, Operand *o, Type *type) { gbString a = expr_to_string(o->expr); gbString b = type_to_string(type); defer( @@ -2074,7 +2074,7 @@ void check_cast_error_suggestion(CheckerContext *c, Operand *o, Type *type) { } -bool check_is_expressible(CheckerContext *ctx, Operand *o, Type *type) { +gb_internal bool check_is_expressible(CheckerContext *ctx, Operand *o, Type *type) { GB_ASSERT(o->mode == Addressing_Constant); ExactValue out_value = o->value; if (is_type_constant_type(type) && check_representable_as_constant(ctx, o->value, type, &out_value)) { @@ -2112,7 +2112,7 @@ bool check_is_expressible(CheckerContext *ctx, Operand *o, Type *type) { } } -bool check_is_not_addressable(CheckerContext *c, Operand *o) { +gb_internal bool check_is_not_addressable(CheckerContext *c, Operand *o) { if (o->mode == Addressing_OptionalOk) { Ast *expr = unselector_expr(o->expr); if (expr->kind != Ast_TypeAssertion) { @@ -2143,7 +2143,7 @@ bool check_is_not_addressable(CheckerContext *c, Operand *o) { return o->mode != Addressing_Variable && o->mode != Addressing_SoaVariable; } -void check_unary_expr(CheckerContext *c, Operand *o, Token op, Ast *node) { +gb_internal void check_unary_expr(CheckerContext *c, Operand *o, Token op, Ast *node) { switch (op.kind) { case Token_And: { // Pointer address if (check_is_not_addressable(c, o)) { @@ -2270,7 +2270,7 @@ void check_unary_expr(CheckerContext *c, Operand *o, Token op, Ast *node) { o->mode = Addressing_Value; } -void add_comparison_procedures_for_fields(CheckerContext *c, Type *t) { +gb_internal void add_comparison_procedures_for_fields(CheckerContext *c, Type *t) { if (t == nullptr) { return; } @@ -2323,7 +2323,7 @@ void add_comparison_procedures_for_fields(CheckerContext *c, Type *t) { } -void check_comparison(CheckerContext *c, Operand *x, Operand *y, TokenKind op) { +gb_internal void check_comparison(CheckerContext *c, Operand *x, Operand *y, TokenKind op) { if (x->mode == Addressing_Type && y->mode == Addressing_Type) { bool comp = are_types_identical(x->type, y->type); switch (op) { @@ -2516,7 +2516,7 @@ void check_comparison(CheckerContext *c, Operand *x, Operand *y, TokenKind op) { } -void check_shift(CheckerContext *c, Operand *x, Operand *y, Ast *node, Type *type_hint) { +gb_internal void check_shift(CheckerContext *c, Operand *x, Operand *y, Ast *node, Type *type_hint) { GB_ASSERT(node->kind == Ast_BinaryExpr); ast_node(be, BinaryExpr, node); @@ -2635,7 +2635,7 @@ void check_shift(CheckerContext *c, Operand *x, Operand *y, Ast *node, Type *typ -bool check_is_castable_to(CheckerContext *c, Operand *operand, Type *y) { +gb_internal bool check_is_castable_to(CheckerContext *c, Operand *operand, Type *y) { if (check_is_assignable_to(c, operand, y)) { return true; } @@ -2851,7 +2851,7 @@ bool check_is_castable_to(CheckerContext *c, Operand *operand, Type *y) { return false; } -bool check_cast_internal(CheckerContext *c, Operand *x, Type *type) { +gb_internal bool check_cast_internal(CheckerContext *c, Operand *x, Type *type) { bool is_const_expr = x->mode == Addressing_Constant; Type *bt = base_type(type); @@ -2886,7 +2886,7 @@ bool check_cast_internal(CheckerContext *c, Operand *x, Type *type) { } -void check_cast(CheckerContext *c, Operand *x, Type *type) { +gb_internal void check_cast(CheckerContext *c, Operand *x, Type *type) { if (!is_operand_value(*x)) { error(x->expr, "Only values can be casted"); x->mode = Addressing_Invalid; @@ -2930,7 +2930,7 @@ void check_cast(CheckerContext *c, Operand *x, Type *type) { x->type = type; } -bool check_transmute(CheckerContext *c, Ast *node, Operand *o, Type *t) { +gb_internal bool check_transmute(CheckerContext *c, Ast *node, Operand *o, Type *t) { if (!is_operand_value(*o)) { error(o->expr, "'transmute' can only be applied to values"); o->mode = Addressing_Invalid; @@ -3043,7 +3043,7 @@ bool check_transmute(CheckerContext *c, Ast *node, Operand *o, Type *t) { return true; } -bool check_binary_array_expr(CheckerContext *c, Token op, Operand *x, Operand *y) { +gb_internal bool check_binary_array_expr(CheckerContext *c, Token op, Operand *x, Operand *y) { if (is_type_array(x->type) && !is_type_array(y->type)) { if (check_is_assignable_to(c, y, x->type)) { if (check_binary_op(c, x, op)) { @@ -3054,19 +3054,19 @@ bool check_binary_array_expr(CheckerContext *c, Token op, Operand *x, Operand *y return false; } -bool is_ise_expr(Ast *node) { +gb_internal bool is_ise_expr(Ast *node) { node = unparen_expr(node); return node->kind == Ast_ImplicitSelectorExpr; } -bool can_use_other_type_as_type_hint(bool use_lhs_as_type_hint, Type *other_type) { +gb_internal bool can_use_other_type_as_type_hint(bool use_lhs_as_type_hint, Type *other_type) { if (use_lhs_as_type_hint) { // RHS in this case return other_type != nullptr && other_type != t_invalid && is_type_typed(other_type); } return false; } -Type *check_matrix_type_hint(Type *matrix, Type *type_hint) { +gb_internal Type *check_matrix_type_hint(Type *matrix, Type *type_hint) { Type *xt = base_type(matrix); if (type_hint != nullptr) { Type *th = base_type(type_hint); @@ -3086,7 +3086,7 @@ Type *check_matrix_type_hint(Type *matrix, Type *type_hint) { } -void check_binary_matrix(CheckerContext *c, Token const &op, Operand *x, Operand *y, Type *type_hint, bool use_lhs_as_type_hint) { +gb_internal void check_binary_matrix(CheckerContext *c, Token const &op, Operand *x, Operand *y, Type *type_hint, bool use_lhs_as_type_hint) { if (!check_binary_op(c, x, op)) { x->mode = Addressing_Invalid; return; @@ -3197,7 +3197,7 @@ matrix_error: } -void check_binary_expr(CheckerContext *c, Operand *x, Ast *node, Type *type_hint, bool use_lhs_as_type_hint=false) { +gb_internal void check_binary_expr(CheckerContext *c, Operand *x, Ast *node, Type *type_hint, bool use_lhs_as_type_hint=false) { GB_ASSERT(node->kind == Ast_BinaryExpr); Operand y_ = {}, *y = &y_; @@ -3563,7 +3563,7 @@ void check_binary_expr(CheckerContext *c, Operand *x, Ast *node, Type *type_hint x->mode = Addressing_Value; } -Operand make_operand_from_node(Ast *node) { +gb_internal Operand make_operand_from_node(Ast *node) { GB_ASSERT(node != nullptr); Operand x = {}; x.expr = node; @@ -3574,7 +3574,7 @@ Operand make_operand_from_node(Ast *node) { } -void update_untyped_expr_type(CheckerContext *c, Ast *e, Type *type, bool final) { +gb_internal void update_untyped_expr_type(CheckerContext *c, Ast *e, Type *type, bool final) { GB_ASSERT(e != nullptr); ExprInfo *old = check_get_expr_info(c, e); if (old == nullptr) { @@ -3689,7 +3689,7 @@ void update_untyped_expr_type(CheckerContext *c, Ast *e, Type *type, bool final) add_type_and_value(c->info, e, old->mode, type, old->value); } -void update_untyped_expr_value(CheckerContext *c, Ast *e, ExactValue value) { +gb_internal void update_untyped_expr_value(CheckerContext *c, Ast *e, ExactValue value) { GB_ASSERT(e != nullptr); ExprInfo *found = check_get_expr_info(c, e); if (found) { @@ -3697,7 +3697,7 @@ void update_untyped_expr_value(CheckerContext *c, Ast *e, ExactValue value) { } } -void convert_untyped_error(CheckerContext *c, Operand *operand, Type *target_type) { +gb_internal void convert_untyped_error(CheckerContext *c, Operand *operand, Type *target_type) { gbString expr_str = expr_to_string(operand->expr); gbString type_str = type_to_string(target_type); gbString from_type_str = type_to_string(operand->type); @@ -3728,7 +3728,7 @@ void convert_untyped_error(CheckerContext *c, Operand *operand, Type *target_typ operand->mode = Addressing_Invalid; } -ExactValue convert_exact_value_for_type(ExactValue v, Type *type) { +gb_internal ExactValue convert_exact_value_for_type(ExactValue v, Type *type) { Type *t = core_type(type); if (is_type_boolean(t)) { // v = exact_value_to_boolean(v); @@ -3746,7 +3746,7 @@ ExactValue convert_exact_value_for_type(ExactValue v, Type *type) { return v; } -void convert_to_typed(CheckerContext *c, Operand *operand, Type *target_type) { +gb_internal void convert_to_typed(CheckerContext *c, Operand *operand, Type *target_type) { GB_ASSERT_NOT_NULL(target_type); if (operand->mode == Addressing_Invalid || operand->mode == Addressing_Type || @@ -3995,7 +3995,7 @@ void convert_to_typed(CheckerContext *c, Operand *operand, Type *target_type) { operand->type = target_type; } -bool check_index_value(CheckerContext *c, Type *main_type, bool open_range, Ast *index_value, i64 max_count, i64 *value, Type *type_hint=nullptr) { +gb_internal bool check_index_value(CheckerContext *c, Type *main_type, bool open_range, Ast *index_value, i64 max_count, i64 *value, Type *type_hint=nullptr) { Operand operand = {Addressing_Invalid}; check_expr_with_type_hint(c, &operand, index_value, type_hint); if (operand.mode == Addressing_Invalid) { @@ -4121,7 +4121,7 @@ bool check_index_value(CheckerContext *c, Type *main_type, bool open_range, Ast return true; } -ExactValue get_constant_field_single(CheckerContext *c, ExactValue value, i32 index, bool *success_, bool *finish_) { +gb_internal ExactValue get_constant_field_single(CheckerContext *c, ExactValue value, i32 index, bool *success_, bool *finish_) { if (value.kind == ExactValue_String) { GB_ASSERT(0 <= index && index < value.value_string.len); u8 val = value.value_string[index]; @@ -4269,7 +4269,7 @@ ExactValue get_constant_field_single(CheckerContext *c, ExactValue value, i32 in -ExactValue get_constant_field(CheckerContext *c, Operand const *operand, Selection sel, bool *success_) { +gb_internal ExactValue get_constant_field(CheckerContext *c, Operand const *operand, Selection sel, bool *success_) { if (operand->mode != Addressing_Constant) { if (success_) *success_ = false; return empty_exact_value; @@ -4349,7 +4349,7 @@ ExactValue get_constant_field(CheckerContext *c, Operand const *operand, Selecti return empty_exact_value; } -Type *determine_swizzle_array_type(Type *original_type, Type *type_hint, isize new_count) { +gb_internal Type *determine_swizzle_array_type(Type *original_type, Type *type_hint, isize new_count) { Type *array_type = base_type(type_deref(original_type)); GB_ASSERT(array_type->kind == Type_Array || array_type->kind == Type_SimdVector); if (array_type->kind == Type_SimdVector) { @@ -4376,7 +4376,7 @@ Type *determine_swizzle_array_type(Type *original_type, Type *type_hint, isize n } -bool is_entity_declared_for_selector(Entity *entity, Scope *import_scope, bool *allow_builtin) { +gb_internal bool is_entity_declared_for_selector(Entity *entity, Scope *import_scope, bool *allow_builtin) { bool is_declared = entity != nullptr; if (is_declared) { if (entity->kind == Entity_Builtin) { @@ -4391,7 +4391,7 @@ bool is_entity_declared_for_selector(Entity *entity, Scope *import_scope, bool * } // NOTE(bill, 2022-02-03): see `check_const_decl` for why it exists reasoning -Entity *check_entity_from_ident_or_selector(CheckerContext *c, Ast *node, bool ident_only) { +gb_internal Entity *check_entity_from_ident_or_selector(CheckerContext *c, Ast *node, bool ident_only) { if (node->kind == Ast_Ident) { String name = node->Ident.token.string; return scope_lookup(c->scope, name); @@ -4471,7 +4471,7 @@ Entity *check_entity_from_ident_or_selector(CheckerContext *c, Ast *node, bool i } -Entity *check_selector(CheckerContext *c, Operand *operand, Ast *node, Type *type_hint) { +gb_internal Entity *check_selector(CheckerContext *c, Operand *operand, Ast *node, Type *type_hint) { ast_node(se, SelectorExpr, node); bool check_op_expr = true; @@ -4865,7 +4865,7 @@ Entity *check_selector(CheckerContext *c, Operand *operand, Ast *node, Type *typ return entity; } -bool is_type_normal_pointer(Type *ptr, Type **elem) { +gb_internal bool is_type_normal_pointer(Type *ptr, Type **elem) { ptr = base_type(ptr); if (is_type_pointer(ptr)) { if (is_type_rawptr(ptr)) { @@ -4877,7 +4877,7 @@ bool is_type_normal_pointer(Type *ptr, Type **elem) { return false; } -bool check_identifier_exists(Scope *s, Ast *node, bool nested = false, Scope **out_scope = nullptr) { +gb_internal bool check_identifier_exists(Scope *s, Ast *node, bool nested = false, Scope **out_scope = nullptr) { switch (node->kind) { case_ast_node(i, Ident, node); String name = i->token.string; @@ -4907,7 +4907,7 @@ bool check_identifier_exists(Scope *s, Ast *node, bool nested = false, Scope **o return false; } -isize add_dependencies_from_unpacking(CheckerContext *c, Entity **lhs, isize lhs_count, isize tuple_index, isize tuple_count) { +gb_internal isize add_dependencies_from_unpacking(CheckerContext *c, Entity **lhs, isize lhs_count, isize tuple_index, isize tuple_count) { if (lhs != nullptr && c->decl != nullptr) { mutex_lock(&c->info->deps_mutex); @@ -4930,7 +4930,7 @@ isize add_dependencies_from_unpacking(CheckerContext *c, Entity **lhs, isize lhs } -bool check_assignment_arguments(CheckerContext *ctx, Array const &lhs, Array *operands, Slice const &rhs) { +gb_internal bool check_assignment_arguments(CheckerContext *ctx, Array const &lhs, Array *operands, Slice const &rhs) { bool optional_ok = false; isize tuple_index = 0; for_array(i, rhs) { @@ -5011,7 +5011,7 @@ bool check_assignment_arguments(CheckerContext *ctx, Array const &lhs, -bool check_unpack_arguments(CheckerContext *ctx, Entity **lhs, isize lhs_count, Array *operands, Slice const &rhs, bool allow_ok, bool is_variadic) { +gb_internal bool check_unpack_arguments(CheckerContext *ctx, Entity **lhs, isize lhs_count, Array *operands, Slice const &rhs, bool allow_ok, bool is_variadic) { bool optional_ok = false; isize tuple_index = 0; for_array(i, rhs) { @@ -5104,7 +5104,7 @@ bool check_unpack_arguments(CheckerContext *ctx, Entity **lhs, isize lhs_count, } -bool is_expr_constant_zero(Ast *expr) { +gb_internal bool is_expr_constant_zero(Ast *expr) { GB_ASSERT(expr != nullptr); auto v = exact_value_to_integer(expr->tav.value); if (v.kind == ExactValue_Integer) { @@ -5113,7 +5113,7 @@ bool is_expr_constant_zero(Ast *expr) { return false; } -isize get_procedure_param_count_excluding_defaults(Type *pt, isize *param_count_) { +gb_internal isize get_procedure_param_count_excluding_defaults(Type *pt, isize *param_count_) { GB_ASSERT(pt != nullptr); GB_ASSERT(pt->kind == Type_Proc); isize param_count = 0; @@ -5167,7 +5167,7 @@ isize get_procedure_param_count_excluding_defaults(Type *pt, isize *param_count_ } -CALL_ARGUMENT_CHECKER(check_call_arguments_internal) { +gb_internal CALL_ARGUMENT_CHECKER(check_call_arguments_internal) { ast_node(ce, CallExpr, call); GB_ASSERT(is_type_proc(proc_type)); proc_type = base_type(proc_type); @@ -5406,7 +5406,7 @@ CALL_ARGUMENT_CHECKER(check_call_arguments_internal) { return err; } -bool is_call_expr_field_value(AstCallExpr *ce) { +gb_internal bool is_call_expr_field_value(AstCallExpr *ce) { GB_ASSERT(ce != nullptr); if (ce->args.count == 0) { @@ -5415,7 +5415,7 @@ bool is_call_expr_field_value(AstCallExpr *ce) { return ce->args[0]->kind == Ast_FieldValue; } -isize lookup_procedure_parameter(TypeProc *pt, String parameter_name) { +gb_internal isize lookup_procedure_parameter(TypeProc *pt, String parameter_name) { isize param_count = pt->param_count; for (isize i = 0; i < param_count; i++) { Entity *e = pt->params->Tuple.variables[i]; @@ -5429,7 +5429,7 @@ isize lookup_procedure_parameter(TypeProc *pt, String parameter_name) { } return -1; } -isize lookup_procedure_result(TypeProc *pt, String result_name) { +gb_internal isize lookup_procedure_result(TypeProc *pt, String result_name) { isize result_count = pt->result_count; for (isize i = 0; i < result_count; i++) { Entity *e = pt->results->Tuple.variables[i]; @@ -5444,7 +5444,7 @@ isize lookup_procedure_result(TypeProc *pt, String result_name) { return -1; } -CALL_ARGUMENT_CHECKER(check_named_call_arguments) { +gb_internal CALL_ARGUMENT_CHECKER(check_named_call_arguments) { ast_node(ce, CallExpr, call); GB_ASSERT(is_type_proc(proc_type)); proc_type = base_type(proc_type); @@ -5628,7 +5628,7 @@ CALL_ARGUMENT_CHECKER(check_named_call_arguments) { return err; } -Entity **populate_proc_parameter_list(CheckerContext *c, Type *proc_type, isize *lhs_count_, bool *is_variadic) { +gb_internal Entity **populate_proc_parameter_list(CheckerContext *c, Type *proc_type, isize *lhs_count_, bool *is_variadic) { Entity **lhs = nullptr; isize lhs_count = -1; @@ -5667,7 +5667,7 @@ Entity **populate_proc_parameter_list(CheckerContext *c, Type *proc_type, isize } -bool evaluate_where_clauses(CheckerContext *ctx, Ast *call_expr, Scope *scope, Slice *clauses, bool print_err) { +gb_internal bool evaluate_where_clauses(CheckerContext *ctx, Ast *call_expr, Scope *scope, Slice *clauses, bool print_err) { if (clauses != nullptr) { for (Ast *clause : *clauses) { Operand o = {}; @@ -5733,7 +5733,7 @@ bool evaluate_where_clauses(CheckerContext *ctx, Ast *call_expr, Scope *scope, S } -CallArgumentData check_call_arguments(CheckerContext *c, Operand *operand, Type *proc_type, Ast *call, Slice const &args) { +gb_internal CallArgumentData check_call_arguments(CheckerContext *c, Operand *operand, Type *proc_type, Ast *call, Slice const &args) { ast_node(ce, CallExpr, call); CallArgumentCheckerType *call_checker = check_call_arguments_internal; @@ -6262,7 +6262,7 @@ CallArgumentData check_call_arguments(CheckerContext *c, Operand *operand, Type } -isize lookup_polymorphic_record_parameter(Type *t, String parameter_name) { +gb_internal isize lookup_polymorphic_record_parameter(Type *t, String parameter_name) { if (!is_type_polymorphic_record(t)) { return -1; } @@ -6285,7 +6285,7 @@ isize lookup_polymorphic_record_parameter(Type *t, String parameter_name) { } -CallArgumentError check_polymorphic_record_type(CheckerContext *c, Operand *operand, Ast *call) { +gb_internal CallArgumentError check_polymorphic_record_type(CheckerContext *c, Operand *operand, Ast *call) { ast_node(ce, CallExpr, call); Type *original_type = operand->type; @@ -6605,7 +6605,7 @@ CallArgumentError check_polymorphic_record_type(CheckerContext *c, Operand *oper -ExprKind check_call_expr(CheckerContext *c, Operand *operand, Ast *call, Ast *proc, Slice const &args, ProcInlining inlining, Type *type_hint) { +gb_internal ExprKind check_call_expr(CheckerContext *c, Operand *operand, Ast *call, Ast *proc, Slice const &args, ProcInlining inlining, Type *type_hint) { if (proc != nullptr && proc->kind == Ast_BasicDirective) { ast_node(bd, BasicDirective, proc); @@ -6880,7 +6880,7 @@ ExprKind check_call_expr(CheckerContext *c, Operand *operand, Ast *call, Ast *pr } -void check_expr_with_type_hint(CheckerContext *c, Operand *o, Ast *e, Type *t) { +gb_internal void check_expr_with_type_hint(CheckerContext *c, Operand *o, Ast *e, Type *t) { check_expr_base(c, o, e, t); check_not_tuple(c, o); char const *err_str = nullptr; @@ -6905,7 +6905,7 @@ void check_expr_with_type_hint(CheckerContext *c, Operand *o, Ast *e, Type *t) { } } -bool check_set_index_data(Operand *o, Type *t, bool indirection, i64 *max_count, Type *original_type) { +gb_internal bool check_set_index_data(Operand *o, Type *t, bool indirection, i64 *max_count, Type *original_type) { switch (t->kind) { case Type_Basic: if (t->Basic.kind == Basic_string) { @@ -7018,7 +7018,7 @@ bool check_set_index_data(Operand *o, Type *t, bool indirection, i64 *max_count, return false; } -bool ternary_compare_types(Type *x, Type *y) { +gb_internal bool ternary_compare_types(Type *x, Type *y) { if (is_type_untyped_undef(x) && type_has_undef(y)) { return true; } else if (is_type_untyped_nil(x) && type_has_nil(y)) { @@ -7032,7 +7032,7 @@ bool ternary_compare_types(Type *x, Type *y) { } -bool check_range(CheckerContext *c, Ast *node, Operand *x, Operand *y, ExactValue *inline_for_depth_, Type *type_hint=nullptr) { +gb_internal bool check_range(CheckerContext *c, Ast *node, Operand *x, Operand *y, ExactValue *inline_for_depth_, Type *type_hint=nullptr) { if (!is_ast_range(node)) { return false; } @@ -7124,7 +7124,7 @@ bool check_range(CheckerContext *c, Ast *node, Operand *x, Operand *y, ExactValu return true; } -bool check_is_operand_compound_lit_constant(CheckerContext *c, Operand *o) { +gb_internal bool check_is_operand_compound_lit_constant(CheckerContext *c, Operand *o) { if (is_operand_nil(*o)) { return true; } @@ -7143,7 +7143,7 @@ bool check_is_operand_compound_lit_constant(CheckerContext *c, Operand *o) { } -bool attempt_implicit_selector_expr(CheckerContext *c, Operand *o, AstImplicitSelectorExpr *ise, Type *th) { +gb_internal bool attempt_implicit_selector_expr(CheckerContext *c, Operand *o, AstImplicitSelectorExpr *ise, Type *th) { if (is_type_enum(th)) { Type *enum_type = base_type(th); GB_ASSERT(enum_type->kind == Type_Enum); @@ -7182,7 +7182,7 @@ bool attempt_implicit_selector_expr(CheckerContext *c, Operand *o, AstImplicitSe return false; } -ExprKind check_implicit_selector_expr(CheckerContext *c, Operand *o, Ast *node, Type *type_hint) { +gb_internal ExprKind check_implicit_selector_expr(CheckerContext *c, Operand *o, Ast *node, Type *type_hint) { ast_node(ise, ImplicitSelectorExpr, node); o->type = t_invalid; @@ -7226,7 +7226,7 @@ ExprKind check_implicit_selector_expr(CheckerContext *c, Operand *o, Ast *node, } -void check_promote_optional_ok(CheckerContext *c, Operand *x, Type **val_type_, Type **ok_type_) { +gb_internal void check_promote_optional_ok(CheckerContext *c, Operand *x, Type **val_type_, Type **ok_type_) { switch (x->mode) { case Addressing_MapIndex: case Addressing_OptionalOk: @@ -7263,7 +7263,7 @@ void check_promote_optional_ok(CheckerContext *c, Operand *x, Type **val_type_, } -void check_matrix_index_expr(CheckerContext *c, Operand *o, Ast *node, Type *type_hint) { +gb_internal void check_matrix_index_expr(CheckerContext *c, Operand *o, Ast *node, Type *type_hint) { ast_node(ie, MatrixIndexExpr, node); check_expr(c, o, ie->expr); @@ -7336,7 +7336,7 @@ struct TypeAndToken { typedef PtrMap SeenMap; -void add_constant_switch_case(CheckerContext *ctx, SeenMap *seen, Operand operand, bool use_expr = true) { +gb_internal void add_constant_switch_case(CheckerContext *ctx, SeenMap *seen, Operand operand, bool use_expr = true) { if (operand.mode != Addressing_Constant) { return; } @@ -7378,7 +7378,7 @@ void add_constant_switch_case(CheckerContext *ctx, SeenMap *seen, Operand operan } -void add_to_seen_map(CheckerContext *ctx, SeenMap *seen, TokenKind upper_op, Operand const &x, Operand const &lhs, Operand const &rhs) { +gb_internal void add_to_seen_map(CheckerContext *ctx, SeenMap *seen, TokenKind upper_op, Operand const &x, Operand const &lhs, Operand const &rhs) { if (is_type_enum(x.type)) { // TODO(bill): Fix this logic so it's fast!!! @@ -7419,11 +7419,11 @@ void add_to_seen_map(CheckerContext *ctx, SeenMap *seen, TokenKind upper_op, Ope } } } -void add_to_seen_map(CheckerContext *ctx, SeenMap *seen, Operand const &x) { +gb_internal void add_to_seen_map(CheckerContext *ctx, SeenMap *seen, Operand const &x) { add_constant_switch_case(ctx, seen, x); } -ExprKind check_basic_directive_expr(CheckerContext *c, Operand *o, Ast *node, Type *type_hint) { +gb_internal ExprKind check_basic_directive_expr(CheckerContext *c, Operand *o, Ast *node, Type *type_hint) { ast_node(bd, BasicDirective, node); ExprKind kind = Expr_Expr; @@ -7477,7 +7477,7 @@ ExprKind check_basic_directive_expr(CheckerContext *c, Operand *o, Ast *node, Ty return kind; } -ExprKind check_ternary_if_expr(CheckerContext *c, Operand *o, Ast *node, Type *type_hint) { +gb_internal ExprKind check_ternary_if_expr(CheckerContext *c, Operand *o, Ast *node, Type *type_hint) { ExprKind kind = Expr_Expr; Operand cond = {Addressing_Invalid}; ast_node(te, TernaryIfExpr, node); @@ -7555,7 +7555,7 @@ ExprKind check_ternary_if_expr(CheckerContext *c, Operand *o, Ast *node, Type *t return kind; } -ExprKind check_ternary_when_expr(CheckerContext *c, Operand *o, Ast *node, Type *type_hint) { +gb_internal ExprKind check_ternary_when_expr(CheckerContext *c, Operand *o, Ast *node, Type *type_hint) { ExprKind kind = Expr_Expr; Operand cond = {}; ast_node(te, TernaryWhenExpr, node); @@ -7582,7 +7582,7 @@ ExprKind check_ternary_when_expr(CheckerContext *c, Operand *o, Ast *node, Type return kind; } -ExprKind check_or_else_expr(CheckerContext *c, Operand *o, Ast *node, Type *type_hint) { +gb_internal ExprKind check_or_else_expr(CheckerContext *c, Operand *o, Ast *node, Type *type_hint) { ast_node(oe, OrElseExpr, node); String name = oe->token.string; @@ -7696,7 +7696,7 @@ ExprKind check_or_else_expr(CheckerContext *c, Operand *o, Ast *node, Type *type return Expr_Expr; } -ExprKind check_or_return_expr(CheckerContext *c, Operand *o, Ast *node, Type *type_hint) { +gb_internal ExprKind check_or_return_expr(CheckerContext *c, Operand *o, Ast *node, Type *type_hint) { ast_node(re, OrReturnExpr, node); String name = re->token.string; @@ -7775,7 +7775,7 @@ ExprKind check_or_return_expr(CheckerContext *c, Operand *o, Ast *node, Type *ty return Expr_Expr; } -ExprKind check_compound_literal(CheckerContext *c, Operand *o, Ast *node, Type *type_hint) { +gb_internal ExprKind check_compound_literal(CheckerContext *c, Operand *o, Ast *node, Type *type_hint) { ExprKind kind = Expr_Expr; ast_node(cl, CompoundLit, node); @@ -8739,7 +8739,7 @@ ExprKind check_compound_literal(CheckerContext *c, Operand *o, Ast *node, Type * return kind; } -ExprKind check_type_assertion(CheckerContext *c, Operand *o, Ast *node, Type *type_hint) { +gb_internal ExprKind check_type_assertion(CheckerContext *c, Operand *o, Ast *node, Type *type_hint) { ExprKind kind = Expr_Expr; ast_node(ta, TypeAssertion, node); check_expr(c, o, ta->expr); @@ -8868,7 +8868,7 @@ ExprKind check_type_assertion(CheckerContext *c, Operand *o, Ast *node, Type *ty return kind; } -ExprKind check_selector_call_expr(CheckerContext *c, Operand *o, Ast *node, Type *type_hint) { +gb_internal ExprKind check_selector_call_expr(CheckerContext *c, Operand *o, Ast *node, Type *type_hint) { ast_node(se, SelectorCallExpr, node); // IMPORTANT NOTE(bill, 2020-05-22): This is a complete hack to get a shorthand which is extremely useful for vtables // COM APIs is a great example of where this kind of thing is extremely useful @@ -9016,7 +9016,7 @@ ExprKind check_selector_call_expr(CheckerContext *c, Operand *o, Ast *node, Type } -ExprKind check_index_expr(CheckerContext *c, Operand *o, Ast *node, Type *type_hint) { +gb_internal ExprKind check_index_expr(CheckerContext *c, Operand *o, Ast *node, Type *type_hint) { ExprKind kind = Expr_Expr; ast_node(ie, IndexExpr, node); check_expr(c, o, ie->expr); @@ -9140,7 +9140,7 @@ ExprKind check_index_expr(CheckerContext *c, Operand *o, Ast *node, Type *type_h return kind; } -ExprKind check_slice_expr(CheckerContext *c, Operand *o, Ast *node, Type *type_hint) { +gb_internal ExprKind check_slice_expr(CheckerContext *c, Operand *o, Ast *node, Type *type_hint) { ExprKind kind = Expr_Stmt; ast_node(se, SliceExpr, node); check_expr(c, o, se->expr); @@ -9328,7 +9328,7 @@ ExprKind check_slice_expr(CheckerContext *c, Operand *o, Ast *node, Type *type_h return kind; } -ExprKind check_expr_base_internal(CheckerContext *c, Operand *o, Ast *node, Type *type_hint) { +gb_internal ExprKind check_expr_base_internal(CheckerContext *c, Operand *o, Ast *node, Type *type_hint) { u32 prev_state_flags = c->state_flags; defer (c->state_flags = prev_state_flags); if (node->state_flags != 0) { @@ -9755,7 +9755,7 @@ ExprKind check_expr_base_internal(CheckerContext *c, Operand *o, Ast *node, Type -ExprKind check_expr_base(CheckerContext *c, Operand *o, Ast *node, Type *type_hint) { +gb_internal ExprKind check_expr_base(CheckerContext *c, Operand *o, Ast *node, Type *type_hint) { ExprKind kind = check_expr_base_internal(c, o, node, type_hint); if (o->type != nullptr && core_type(o->type) == nullptr) { o->type = t_invalid; @@ -9777,7 +9777,7 @@ ExprKind check_expr_base(CheckerContext *c, Operand *o, Ast *node, Type *type_hi } -void check_multi_expr_or_type(CheckerContext *c, Operand *o, Ast *e) { +gb_internal void check_multi_expr_or_type(CheckerContext *c, Operand *o, Ast *e) { check_expr_base(c, o, e, nullptr); switch (o->mode) { default: @@ -9789,7 +9789,7 @@ void check_multi_expr_or_type(CheckerContext *c, Operand *o, Ast *e) { o->mode = Addressing_Invalid; } -void check_multi_expr(CheckerContext *c, Operand *o, Ast *e) { +gb_internal void check_multi_expr(CheckerContext *c, Operand *o, Ast *e) { check_expr_base(c, o, e, nullptr); switch (o->mode) { default: @@ -9804,7 +9804,7 @@ void check_multi_expr(CheckerContext *c, Operand *o, Ast *e) { o->mode = Addressing_Invalid; } -void check_multi_expr_with_type_hint(CheckerContext *c, Operand *o, Ast *e, Type *type_hint) { +gb_internal void check_multi_expr_with_type_hint(CheckerContext *c, Operand *o, Ast *e, Type *type_hint) { check_expr_base(c, o, e, type_hint); switch (o->mode) { default: @@ -9819,7 +9819,7 @@ void check_multi_expr_with_type_hint(CheckerContext *c, Operand *o, Ast *e, Type o->mode = Addressing_Invalid; } -void check_not_tuple(CheckerContext *c, Operand *o) { +gb_internal void check_not_tuple(CheckerContext *c, Operand *o) { if (o->mode == Addressing_Value) { // NOTE(bill): Tuples are not first class thus never named if (o->type->kind == Type_Tuple) { @@ -9832,13 +9832,13 @@ void check_not_tuple(CheckerContext *c, Operand *o) { } } -void check_expr(CheckerContext *c, Operand *o, Ast *e) { +gb_internal void check_expr(CheckerContext *c, Operand *o, Ast *e) { check_multi_expr(c, o, e); check_not_tuple(c, o); } -void check_expr_or_type(CheckerContext *c, Operand *o, Ast *e, Type *type_hint) { +gb_internal void check_expr_or_type(CheckerContext *c, Operand *o, Ast *e, Type *type_hint) { check_expr_base(c, o, e, type_hint); check_not_tuple(c, o); error_operand_no_value(o); @@ -9846,7 +9846,7 @@ void check_expr_or_type(CheckerContext *c, Operand *o, Ast *e, Type *type_hint) -bool is_exact_value_zero(ExactValue const &v) { +gb_internal bool is_exact_value_zero(ExactValue const &v) { switch (v.kind) { case ExactValue_Invalid: return true; @@ -9910,9 +9910,9 @@ bool is_exact_value_zero(ExactValue const &v) { -gbString write_expr_to_string(gbString str, Ast *node, bool shorthand); +gb_internal gbString write_expr_to_string(gbString str, Ast *node, bool shorthand); -gbString write_struct_fields_to_string(gbString str, Slice const ¶ms) { +gb_internal gbString write_struct_fields_to_string(gbString str, Slice const ¶ms) { for_array(i, params) { if (i > 0) { str = gb_string_appendc(str, ", "); @@ -9922,7 +9922,7 @@ gbString write_struct_fields_to_string(gbString str, Slice const ¶ms) return str; } -gbString string_append_string(gbString str, String string) { +gb_internal gbString string_append_string(gbString str, String string) { if (string.len > 0) { return gb_string_append_length(str, &string[0], string.len); } @@ -9930,13 +9930,13 @@ gbString string_append_string(gbString str, String string) { } -gbString string_append_token(gbString str, Token token) { +gb_internal gbString string_append_token(gbString str, Token token) { str = string_append_string(str, token.string); return str; } -gbString write_expr_to_string(gbString str, Ast *node, bool shorthand) { +gb_internal gbString write_expr_to_string(gbString str, Ast *node, bool shorthand) { if (node == nullptr) return str; @@ -10501,9 +10501,9 @@ gbString write_expr_to_string(gbString str, Ast *node, bool shorthand) { return str; } -gbString expr_to_string(Ast *expression) { +gb_internal gbString expr_to_string(Ast *expression) { return write_expr_to_string(gb_string_make(heap_allocator(), ""), expression, false); } -gbString expr_to_string_shorthand(Ast *expression) { +gb_internal gbString expr_to_string_shorthand(Ast *expression) { return write_expr_to_string(gb_string_make(heap_allocator(), ""), expression, true); } diff --git a/src/check_stmt.cpp b/src/check_stmt.cpp index 3fe6699ea..cae9c3537 100644 --- a/src/check_stmt.cpp +++ b/src/check_stmt.cpp @@ -1,4 +1,4 @@ -bool is_diverging_expr(Ast *expr) { +gb_internal bool is_diverging_expr(Ast *expr) { expr = unparen_expr(expr); if (expr->kind != Ast_CallExpr) { return false; @@ -23,14 +23,14 @@ bool is_diverging_expr(Ast *expr) { t = base_type(t); return t != nullptr && t->kind == Type_Proc && t->Proc.diverging; } -bool is_diverging_stmt(Ast *stmt) { +gb_internal bool is_diverging_stmt(Ast *stmt) { if (stmt->kind != Ast_ExprStmt) { return false; } return is_diverging_expr(stmt->ExprStmt.expr); } -bool contains_deferred_call(Ast *node) { +gb_internal bool contains_deferred_call(Ast *node) { if (node->viral_state_flags & ViralStateFlag_ContainsDeferredProcedure) { return true; } @@ -61,7 +61,7 @@ bool contains_deferred_call(Ast *node) { return false; } -void check_stmt_list(CheckerContext *ctx, Slice const &stmts, u32 flags) { +gb_internal void check_stmt_list(CheckerContext *ctx, Slice const &stmts, u32 flags) { if (stmts.count == 0) { return; } @@ -137,7 +137,7 @@ void check_stmt_list(CheckerContext *ctx, Slice const &stmts, u32 flags) } } -bool check_is_terminating_list(Slice const &stmts, String const &label) { +gb_internal bool check_is_terminating_list(Slice const &stmts, String const &label) { // Iterate backwards for (isize n = stmts.count-1; n >= 0; n--) { Ast *stmt = stmts[n]; @@ -155,7 +155,7 @@ bool check_is_terminating_list(Slice const &stmts, String const &label) { return false; } -bool check_has_break_list(Slice const &stmts, String const &label, bool implicit) { +gb_internal bool check_has_break_list(Slice const &stmts, String const &label, bool implicit) { for_array(i, stmts) { Ast *stmt = stmts[i]; if (check_has_break(stmt, label, implicit)) { @@ -166,7 +166,7 @@ bool check_has_break_list(Slice const &stmts, String const &label, bool i } -bool check_has_break(Ast *stmt, String const &label, bool implicit) { +gb_internal bool check_has_break(Ast *stmt, String const &label, bool implicit) { switch (stmt->kind) { case Ast_BranchStmt: if (stmt->BranchStmt.token.kind == Token_break) { @@ -225,7 +225,7 @@ bool check_has_break(Ast *stmt, String const &label, bool implicit) { // NOTE(bill): The last expression has to be a 'return' statement // TODO(bill): This is a mild hack and should be probably handled properly -bool check_is_terminating(Ast *node, String const &label) { +gb_internal bool check_is_terminating(Ast *node, String const &label) { switch (node->kind) { case_ast_node(rs, ReturnStmt, node); return true; @@ -327,7 +327,7 @@ bool check_is_terminating(Ast *node, String const &label) { -Type *check_assignment_variable(CheckerContext *ctx, Operand *lhs, Operand *rhs) { +gb_internal Type *check_assignment_variable(CheckerContext *ctx, Operand *lhs, Operand *rhs) { if (rhs->mode == Addressing_Invalid) { return nullptr; } @@ -477,8 +477,8 @@ Type *check_assignment_variable(CheckerContext *ctx, Operand *lhs, Operand *rhs) } -void check_stmt_internal(CheckerContext *ctx, Ast *node, u32 flags); -void check_stmt(CheckerContext *ctx, Ast *node, u32 flags) { +gb_internal void check_stmt_internal(CheckerContext *ctx, Ast *node, u32 flags); +gb_internal void check_stmt(CheckerContext *ctx, Ast *node, u32 flags) { u32 prev_state_flags = ctx->state_flags; if (node->state_flags != 0) { @@ -510,7 +510,7 @@ void check_stmt(CheckerContext *ctx, Ast *node, u32 flags) { } -void check_when_stmt(CheckerContext *ctx, AstWhenStmt *ws, u32 flags) { +gb_internal void check_when_stmt(CheckerContext *ctx, AstWhenStmt *ws, u32 flags) { Operand operand = {Addressing_Invalid}; check_expr(ctx, &operand, ws->cond); if (operand.mode != Addressing_Constant || !is_type_boolean(operand.type)) { @@ -539,7 +539,7 @@ void check_when_stmt(CheckerContext *ctx, AstWhenStmt *ws, u32 flags) { } } -void check_label(CheckerContext *ctx, Ast *label, Ast *parent) { +gb_internal void check_label(CheckerContext *ctx, Ast *label, Ast *parent) { if (label == nullptr) { return; } @@ -582,7 +582,7 @@ void check_label(CheckerContext *ctx, Ast *label, Ast *parent) { } // Returns 'true' for 'continue', 'false' for 'return' -bool check_using_stmt_entity(CheckerContext *ctx, AstUsingStmt *us, Ast *expr, bool is_selector, Entity *e) { +gb_internal bool check_using_stmt_entity(CheckerContext *ctx, AstUsingStmt *us, Ast *expr, bool is_selector, Entity *e) { if (e == nullptr) { if (is_blank_ident(expr)) { error(us->token, "'using' in a statement is not allowed with the blank identifier '_'"); @@ -704,7 +704,7 @@ bool check_using_stmt_entity(CheckerContext *ctx, AstUsingStmt *us, Ast *expr, b return true; } -void check_inline_range_stmt(CheckerContext *ctx, Ast *node, u32 mod_flags) { +gb_internal void check_inline_range_stmt(CheckerContext *ctx, Ast *node, u32 mod_flags) { ast_node(irs, UnrollRangeStmt, node); check_open_scope(ctx, node); @@ -863,7 +863,7 @@ void check_inline_range_stmt(CheckerContext *ctx, Ast *node, u32 mod_flags) { check_close_scope(ctx); } -void check_switch_stmt(CheckerContext *ctx, Ast *node, u32 mod_flags) { +gb_internal void check_switch_stmt(CheckerContext *ctx, Ast *node, u32 mod_flags) { ast_node(ss, SwitchStmt, node); Operand x = {}; @@ -1092,7 +1092,7 @@ enum TypeSwitchKind { TypeSwitch_Any, }; -TypeSwitchKind check_valid_type_switch_type(Type *type) { +gb_internal TypeSwitchKind check_valid_type_switch_type(Type *type) { type = type_deref(type); if (is_type_union(type)) { return TypeSwitch_Union; @@ -1103,7 +1103,7 @@ TypeSwitchKind check_valid_type_switch_type(Type *type) { return TypeSwitch_Invalid; } -void check_type_switch_stmt(CheckerContext *ctx, Ast *node, u32 mod_flags) { +gb_internal void check_type_switch_stmt(CheckerContext *ctx, Ast *node, u32 mod_flags) { ast_node(ss, TypeSwitchStmt, node); Operand x = {}; @@ -1318,7 +1318,7 @@ void check_type_switch_stmt(CheckerContext *ctx, Ast *node, u32 mod_flags) { } } -void check_block_stmt_for_errors(CheckerContext *ctx, Ast *body) { +gb_internal void check_block_stmt_for_errors(CheckerContext *ctx, Ast *body) { if (body->kind != Ast_BlockStmt) { return; } @@ -1377,7 +1377,7 @@ void check_block_stmt_for_errors(CheckerContext *ctx, Ast *body) { } } -bool all_operands_valid(Array const &operands) { +gb_internal bool all_operands_valid(Array const &operands) { if (any_errors()) { for_array(i, operands) { if (operands[i].type == t_invalid) { @@ -1388,7 +1388,7 @@ bool all_operands_valid(Array const &operands) { return true; } -bool check_stmt_internal_builtin_proc_id(Ast *expr, BuiltinProcId *id_) { +gb_internal bool check_stmt_internal_builtin_proc_id(Ast *expr, BuiltinProcId *id_) { BuiltinProcId id = BuiltinProc_Invalid; Entity *e = entity_of_node(expr); if (e != nullptr && e->kind == Entity_Builtin) { @@ -1400,7 +1400,7 @@ bool check_stmt_internal_builtin_proc_id(Ast *expr, BuiltinProcId *id_) { return id != BuiltinProc_Invalid; } -bool check_expr_is_stack_variable(Ast *expr) { +gb_internal bool check_expr_is_stack_variable(Ast *expr) { /* expr = unparen_expr(expr); Entity *e = entity_of_node(expr); @@ -1419,7 +1419,7 @@ bool check_expr_is_stack_variable(Ast *expr) { return false; } -void check_stmt_internal(CheckerContext *ctx, Ast *node, u32 flags) { +gb_internal void check_stmt_internal(CheckerContext *ctx, Ast *node, u32 flags) { u32 mod_flags = flags & (~Stmt_FallthroughAllowed); switch (node->kind) { case_ast_node(_, EmptyStmt, node); case_end; diff --git a/src/check_type.cpp b/src/check_type.cpp index 62ca19c57..4634e1fbe 100644 --- a/src/check_type.cpp +++ b/src/check_type.cpp @@ -1,6 +1,6 @@ -ParameterValue handle_parameter_value(CheckerContext *ctx, Type *in_type, Type **out_type_, Ast *expr, bool allow_caller_location); +gb_internal ParameterValue handle_parameter_value(CheckerContext *ctx, Type *in_type, Type **out_type_, Ast *expr, bool allow_caller_location); -void populate_using_array_index(CheckerContext *ctx, Ast *node, AstField *field, Type *t, String name, i32 idx) { +gb_internal void populate_using_array_index(CheckerContext *ctx, Ast *node, AstField *field, Type *t, String name, i32 idx) { t = base_type(t); GB_ASSERT(t->kind == Type_Array); Entity *e = scope_lookup_current(ctx->scope, name); @@ -27,7 +27,7 @@ void populate_using_array_index(CheckerContext *ctx, Ast *node, AstField *field, } } -void populate_using_entity_scope(CheckerContext *ctx, Ast *node, AstField *field, Type *t) { +gb_internal void populate_using_entity_scope(CheckerContext *ctx, Ast *node, AstField *field, Type *t) { if (t == nullptr) { return; } @@ -81,7 +81,7 @@ void populate_using_entity_scope(CheckerContext *ctx, Ast *node, AstField *field } } -bool does_field_type_allow_using(Type *t) { +gb_internal bool does_field_type_allow_using(Type *t) { t = base_type(t); if (is_type_struct(t)) { return true; @@ -91,8 +91,8 @@ bool does_field_type_allow_using(Type *t) { return false; } -void check_struct_fields(CheckerContext *ctx, Ast *node, Slice *fields, String **tags, Slice const ¶ms, - isize init_field_capacity, Type *struct_type, String context) { +gb_internal void check_struct_fields(CheckerContext *ctx, Ast *node, Slice *fields, String **tags, Slice const ¶ms, + isize init_field_capacity, Type *struct_type, String context) { auto fields_array = array_make(heap_allocator(), 0, init_field_capacity); auto tags_array = array_make(heap_allocator(), 0, init_field_capacity); @@ -219,7 +219,7 @@ void check_struct_fields(CheckerContext *ctx, Ast *node, Slice *fields } -bool check_custom_align(CheckerContext *ctx, Ast *node, i64 *align_) { +gb_internal bool check_custom_align(CheckerContext *ctx, Ast *node, i64 *align_) { GB_ASSERT(align_ != nullptr); Operand o = {}; check_expr(ctx, &o, node); @@ -256,7 +256,7 @@ bool check_custom_align(CheckerContext *ctx, Ast *node, i64 *align_) { } -Entity *find_polymorphic_record_entity(CheckerContext *ctx, Type *original_type, isize param_count, Array const &ordered_operands, bool *failure) { +gb_internal Entity *find_polymorphic_record_entity(CheckerContext *ctx, Type *original_type, isize param_count, Array const &ordered_operands, bool *failure) { mutex_lock(&ctx->info->gen_types_mutex); defer (mutex_unlock(&ctx->info->gen_types_mutex)); @@ -320,7 +320,7 @@ Entity *find_polymorphic_record_entity(CheckerContext *ctx, Type *original_type, } -void add_polymorphic_record_entity(CheckerContext *ctx, Ast *node, Type *named_type, Type *original_type) { +gb_internal void add_polymorphic_record_entity(CheckerContext *ctx, Ast *node, Type *named_type, Type *original_type) { GB_ASSERT(is_type_named(named_type)); gbAllocator a = heap_allocator(); Scope *s = ctx->scope->parent; @@ -358,10 +358,10 @@ void add_polymorphic_record_entity(CheckerContext *ctx, Ast *node, Type *named_t mutex_unlock(&ctx->info->gen_types_mutex); } -Type *check_record_polymorphic_params(CheckerContext *ctx, Ast *polymorphic_params, - bool *is_polymorphic_, - Ast *node, Array *poly_operands, - Type *named_type, Type *original_type_for_poly) { +gb_internal Type *check_record_polymorphic_params(CheckerContext *ctx, Ast *polymorphic_params, + bool *is_polymorphic_, + Ast *node, Array *poly_operands, + Type *named_type, Type *original_type_for_poly) { Type *polymorphic_params_type = nullptr; bool can_check_fields = true; GB_ASSERT(is_polymorphic_ != nullptr); @@ -540,7 +540,7 @@ Type *check_record_polymorphic_params(CheckerContext *ctx, Ast *polymorphic_para return polymorphic_params_type; } -bool check_record_poly_operand_specialization(CheckerContext *ctx, Type *record_type, Array *poly_operands, bool *is_polymorphic_) { +gb_internal bool check_record_poly_operand_specialization(CheckerContext *ctx, Type *record_type, Array *poly_operands, bool *is_polymorphic_) { if (poly_operands == nullptr) { return false; } @@ -569,7 +569,7 @@ bool check_record_poly_operand_specialization(CheckerContext *ctx, Type *record_ } -void check_struct_type(CheckerContext *ctx, Type *struct_type, Ast *node, Array *poly_operands, Type *named_type, Type *original_type_for_poly) { +gb_internal void check_struct_type(CheckerContext *ctx, Type *struct_type, Ast *node, Array *poly_operands, Type *named_type, Type *original_type_for_poly) { GB_ASSERT(is_type_struct(struct_type)); ast_node(st, StructType, node); @@ -626,7 +626,7 @@ void check_struct_type(CheckerContext *ctx, Type *struct_type, Ast *node, Array< } } } -void check_union_type(CheckerContext *ctx, Type *union_type, Ast *node, Array *poly_operands, Type *named_type, Type *original_type_for_poly) { +gb_internal void check_union_type(CheckerContext *ctx, Type *union_type, Ast *node, Array *poly_operands, Type *named_type, Type *original_type_for_poly) { GB_ASSERT(is_type_union(union_type)); ast_node(ut, UnionType, node); @@ -709,7 +709,7 @@ void check_union_type(CheckerContext *ctx, Type *union_type, Ast *node, ArrayEnum.max_value_index = max_value_index; } -bool is_type_valid_bit_set_range(Type *t) { +gb_internal bool is_type_valid_bit_set_range(Type *t) { if (is_type_integer(t)) { return true; } @@ -861,7 +861,7 @@ bool is_type_valid_bit_set_range(Type *t) { return false; } -void check_bit_set_type(CheckerContext *c, Type *type, Type *named_type, Ast *node) { +gb_internal void check_bit_set_type(CheckerContext *c, Type *type, Type *named_type, Ast *node) { ast_node(bs, BitSetType, node); GB_ASSERT(type->kind == Type_BitSet); type->BitSet.node = node; @@ -1102,7 +1102,7 @@ void check_bit_set_type(CheckerContext *c, Type *type, Type *named_type, Ast *no } -bool check_type_specialization_to(CheckerContext *ctx, Type *specialization, Type *type, bool compound, bool modify_type) { +gb_internal bool check_type_specialization_to(CheckerContext *ctx, Type *specialization, Type *type, bool compound, bool modify_type) { if (type == nullptr || type == t_invalid) { return true; @@ -1229,7 +1229,7 @@ bool check_type_specialization_to(CheckerContext *ctx, Type *specialization, Typ } -Type *determine_type_from_polymorphic(CheckerContext *ctx, Type *poly_type, Operand const &operand) { +gb_internal Type *determine_type_from_polymorphic(CheckerContext *ctx, Type *poly_type, Operand const &operand) { bool modify_type = !ctx->no_polymorphic_errors; bool show_error = modify_type && !ctx->hide_polymorphic_errors; if (!is_operand_value(operand)) { @@ -1256,7 +1256,7 @@ Type *determine_type_from_polymorphic(CheckerContext *ctx, Type *poly_type, Oper return t_invalid; } -bool is_expr_from_a_parameter(CheckerContext *ctx, Ast *expr) { +gb_internal bool is_expr_from_a_parameter(CheckerContext *ctx, Ast *expr) { if (expr == nullptr) { return false; } @@ -1275,7 +1275,7 @@ bool is_expr_from_a_parameter(CheckerContext *ctx, Ast *expr) { } -ParameterValue handle_parameter_value(CheckerContext *ctx, Type *in_type, Type **out_type_, Ast *expr, bool allow_caller_location) { +gb_internal ParameterValue handle_parameter_value(CheckerContext *ctx, Type *in_type, Type **out_type_, Ast *expr, bool allow_caller_location) { ParameterValue param_value = {}; param_value.original_ast_expr = expr; if (expr == nullptr) { @@ -1370,7 +1370,7 @@ ParameterValue handle_parameter_value(CheckerContext *ctx, Type *in_type, Type * } -Type *check_get_params(CheckerContext *ctx, Scope *scope, Ast *_params, bool *is_variadic_, isize *variadic_index_, bool *success_, isize *specialization_count_, Array *operands) { +gb_internal Type *check_get_params(CheckerContext *ctx, Scope *scope, Ast *_params, bool *is_variadic_, isize *variadic_index_, bool *success_, isize *specialization_count_, Array *operands) { if (_params == nullptr) { return nullptr; } @@ -1814,7 +1814,7 @@ Type *check_get_params(CheckerContext *ctx, Scope *scope, Ast *_params, bool *is return tuple; } -Type *check_get_results(CheckerContext *ctx, Scope *scope, Ast *_results) { +gb_internal Type *check_get_results(CheckerContext *ctx, Scope *scope, Ast *_results) { if (_results == nullptr) { return nullptr; } @@ -1928,7 +1928,7 @@ Type *check_get_results(CheckerContext *ctx, Scope *scope, Ast *_results) { // NOTE(bill): 'operands' is for generating non generic procedure type -bool check_procedure_type(CheckerContext *ctx, Type *type, Ast *proc_type_node, Array *operands) { +gb_internal bool check_procedure_type(CheckerContext *ctx, Type *type, Ast *proc_type_node, Array *operands) { ast_node(pt, ProcType, proc_type_node); if (ctx->polymorphic_scope == nullptr && ctx->allow_polymorphic_types) { @@ -2084,7 +2084,7 @@ bool check_procedure_type(CheckerContext *ctx, Type *type, Ast *proc_type_node, } -i64 check_array_count(CheckerContext *ctx, Operand *o, Ast *e) { +gb_internal i64 check_array_count(CheckerContext *ctx, Operand *o, Ast *e) { if (e == nullptr) { return 0; } @@ -2169,7 +2169,7 @@ i64 check_array_count(CheckerContext *ctx, Operand *o, Ast *e) { return 0; } -Type *make_optional_ok_type(Type *value, bool typed) { +gb_internal Type *make_optional_ok_type(Type *value, bool typed) { gbAllocator a = permanent_allocator(); Type *t = alloc_type_tuple(); slice_init(&t->Tuple.variables, a, 2); @@ -2185,7 +2185,7 @@ enum : i64 { MAP_CACHE_LINE_SIZE = 1 << MAP_CACHE_LINE_LOG2 }; GB_STATIC_ASSERT(MAP_CACHE_LINE_SIZE >= 64); -void map_cell_size_and_len(Type *type, i64 *size_, i64 *len_) { +gb_internal void map_cell_size_and_len(Type *type, i64 *size_, i64 *len_) { i64 elem_sz = type_size_of(type); i64 len = 1; @@ -2197,7 +2197,7 @@ void map_cell_size_and_len(Type *type, i64 *size_, i64 *len_) { if (len_) *len_ = len; } -void init_map_internal_types(Type *type) { +gb_internal void init_map_internal_types(Type *type) { GB_ASSERT(type->kind == Type_Map); GB_ASSERT(t_allocator != nullptr); if (type->Map.lookup_result_type != nullptr) return; @@ -2210,7 +2210,7 @@ void init_map_internal_types(Type *type) { type->Map.lookup_result_type = make_optional_ok_type(value); } -void add_map_key_type_dependencies(CheckerContext *ctx, Type *key) { +gb_internal void add_map_key_type_dependencies(CheckerContext *ctx, Type *key) { key = core_type(key); if (is_type_cstring(key)) { @@ -2249,7 +2249,7 @@ void add_map_key_type_dependencies(CheckerContext *ctx, Type *key) { } } -void check_map_type(CheckerContext *ctx, Type *type, Ast *node) { +gb_internal void check_map_type(CheckerContext *ctx, Type *type, Ast *node) { GB_ASSERT(type->kind == Type_Map); ast_node(mt, MapType, node); @@ -2282,7 +2282,7 @@ void check_map_type(CheckerContext *ctx, Type *type, Ast *node) { // error(node, "'map' types are not yet implemented"); } -void check_matrix_type(CheckerContext *ctx, Type **type, Ast *node) { +gb_internal void check_matrix_type(CheckerContext *ctx, Type **type, Ast *node) { ast_node(mt, MatrixType, node); Operand row = {}; @@ -2346,7 +2346,7 @@ type_assign:; -Type *make_soa_struct_internal(CheckerContext *ctx, Ast *array_typ_expr, Ast *elem_expr, Type *elem, i64 count, Type *generic_type, StructSoaKind soa_kind) { +gb_internal Type *make_soa_struct_internal(CheckerContext *ctx, Ast *array_typ_expr, Ast *elem_expr, Type *elem, i64 count, Type *generic_type, StructSoaKind soa_kind) { Type *bt_elem = base_type(elem); bool is_polymorphic = is_type_polymorphic(elem); @@ -2501,20 +2501,20 @@ Type *make_soa_struct_internal(CheckerContext *ctx, Ast *array_typ_expr, Ast *el } -Type *make_soa_struct_fixed(CheckerContext *ctx, Ast *array_typ_expr, Ast *elem_expr, Type *elem, i64 count, Type *generic_type) { +gb_internal Type *make_soa_struct_fixed(CheckerContext *ctx, Ast *array_typ_expr, Ast *elem_expr, Type *elem, i64 count, Type *generic_type) { return make_soa_struct_internal(ctx, array_typ_expr, elem_expr, elem, count, generic_type, StructSoa_Fixed); } -Type *make_soa_struct_slice(CheckerContext *ctx, Ast *array_typ_expr, Ast *elem_expr, Type *elem) { +gb_internal Type *make_soa_struct_slice(CheckerContext *ctx, Ast *array_typ_expr, Ast *elem_expr, Type *elem) { return make_soa_struct_internal(ctx, array_typ_expr, elem_expr, elem, -1, nullptr, StructSoa_Slice); } -Type *make_soa_struct_dynamic_array(CheckerContext *ctx, Ast *array_typ_expr, Ast *elem_expr, Type *elem) { +gb_internal Type *make_soa_struct_dynamic_array(CheckerContext *ctx, Ast *array_typ_expr, Ast *elem_expr, Type *elem) { return make_soa_struct_internal(ctx, array_typ_expr, elem_expr, elem, -1, nullptr, StructSoa_Dynamic); } -bool check_type_internal(CheckerContext *ctx, Ast *e, Type **type, Type *named_type) { +gb_internal bool check_type_internal(CheckerContext *ctx, Ast *e, Type **type, Type *named_type) { GB_ASSERT_NOT_NULL(type); if (e == nullptr) { *type = t_invalid; @@ -2997,7 +2997,7 @@ bool check_type_internal(CheckerContext *ctx, Ast *e, Type **type, Type *named_t return false; } -Type *check_type(CheckerContext *ctx, Ast *e) { +gb_internal Type *check_type(CheckerContext *ctx, Ast *e) { CheckerContext c = *ctx; c.type_path = new_checker_type_path(); defer (destroy_checker_type_path(c.type_path)); @@ -3005,7 +3005,7 @@ Type *check_type(CheckerContext *ctx, Ast *e) { return check_type_expr(&c, e, nullptr); } -Type *check_type_expr(CheckerContext *ctx, Ast *e, Type *named_type) { +gb_internal Type *check_type_expr(CheckerContext *ctx, Ast *e, Type *named_type) { Type *type = nullptr; bool ok = check_type_internal(ctx, e, &type, named_type); diff --git a/src/checker.cpp b/src/checker.cpp index d5222f615..e2c430dc2 100644 --- a/src/checker.cpp +++ b/src/checker.cpp @@ -1,12 +1,12 @@ #include "entity.cpp" #include "types.cpp" -void check_expr(CheckerContext *c, Operand *operand, Ast *expression); -void check_expr_or_type(CheckerContext *c, Operand *operand, Ast *expression, Type *type_hint=nullptr); -void add_comparison_procedures_for_fields(CheckerContext *c, Type *t); -Type *check_type(CheckerContext *ctx, Ast *e); +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); +gb_internal void add_comparison_procedures_for_fields(CheckerContext *c, Type *t); +gb_internal Type *check_type(CheckerContext *ctx, Ast *e); -bool is_operand_value(Operand o) { +gb_internal bool is_operand_value(Operand o) { switch (o.mode) { case Addressing_Value: case Addressing_Context: @@ -22,14 +22,14 @@ bool is_operand_value(Operand o) { } return false; } -bool is_operand_nil(Operand o) { +gb_internal bool is_operand_nil(Operand o) { return o.mode == Addressing_Value && o.type == t_untyped_nil; } -bool is_operand_undef(Operand o) { +gb_internal bool is_operand_undef(Operand o) { return o.mode == Addressing_Value && o.type == t_untyped_undef; } -bool check_rtti_type_disallowed(Token const &token, Type *type, char const *format) { +gb_internal bool check_rtti_type_disallowed(Token const &token, Type *type, char const *format) { if (build_context.disallow_rtti && type) { if (is_type_any(type)) { gbString t = type_to_string(type); @@ -41,12 +41,12 @@ bool check_rtti_type_disallowed(Token const &token, Type *type, char const *form return false; } -bool check_rtti_type_disallowed(Ast *expr, Type *type, char const *format) { +gb_internal bool check_rtti_type_disallowed(Ast *expr, Type *type, char const *format) { GB_ASSERT(expr != nullptr); return check_rtti_type_disallowed(ast_token(expr), type, format); } -void scope_reset(Scope *scope) { +gb_internal void scope_reset(Scope *scope) { if (scope == nullptr) return; scope->head_child.store(nullptr, std::memory_order_relaxed); @@ -54,14 +54,14 @@ void scope_reset(Scope *scope) { ptr_set_clear(&scope->imported); } -void scope_reserve(Scope *scope, isize capacity) { +gb_internal void scope_reserve(Scope *scope, isize capacity) { isize cap = 2*capacity; if (cap > scope->elements.hashes.count) { string_map_rehash(&scope->elements, capacity); } } -i32 is_scope_an_ancestor(Scope *parent, Scope *child) { +gb_internal i32 is_scope_an_ancestor(Scope *parent, Scope *child) { i32 i = 0; while (child != nullptr) { if (parent == child) { @@ -73,35 +73,35 @@ i32 is_scope_an_ancestor(Scope *parent, Scope *child) { return -1; } -void entity_graph_node_set_destroy(EntityGraphNodeSet *s) { +gb_internal void entity_graph_node_set_destroy(EntityGraphNodeSet *s) { if (s->hashes.data != nullptr) { ptr_set_destroy(s); } } -void entity_graph_node_set_add(EntityGraphNodeSet *s, EntityGraphNode *n) { +gb_internal void entity_graph_node_set_add(EntityGraphNodeSet *s, EntityGraphNode *n) { if (s->hashes.data == nullptr) { ptr_set_init(s, heap_allocator()); } ptr_set_add(s, n); } -bool entity_graph_node_set_exists(EntityGraphNodeSet *s, EntityGraphNode *n) { +gb_internal bool entity_graph_node_set_exists(EntityGraphNodeSet *s, EntityGraphNode *n) { return ptr_set_exists(s, n); } -void entity_graph_node_set_remove(EntityGraphNodeSet *s, EntityGraphNode *n) { +gb_internal void entity_graph_node_set_remove(EntityGraphNodeSet *s, EntityGraphNode *n) { ptr_set_remove(s, n); } -void entity_graph_node_destroy(EntityGraphNode *n, gbAllocator a) { +gb_internal void entity_graph_node_destroy(EntityGraphNode *n, gbAllocator a) { entity_graph_node_set_destroy(&n->pred); entity_graph_node_set_destroy(&n->succ); gb_free(a, n); } -int entity_graph_node_cmp(EntityGraphNode **data, isize i, isize j) { +gb_internal int entity_graph_node_cmp(EntityGraphNode **data, isize i, isize j) { EntityGraphNode *x = data[i]; EntityGraphNode *y = data[j]; u64 a = x->entity->order_in_src; @@ -115,7 +115,7 @@ int entity_graph_node_cmp(EntityGraphNode **data, isize i, isize j) { return +1; } -void entity_graph_node_swap(EntityGraphNode **data, isize i, isize j) { +gb_internal void entity_graph_node_swap(EntityGraphNode **data, isize i, isize j) { EntityGraphNode *x = data[i]; EntityGraphNode *y = data[j]; data[i] = y; @@ -126,42 +126,42 @@ void entity_graph_node_swap(EntityGraphNode **data, isize i, isize j) { -void import_graph_node_set_destroy(ImportGraphNodeSet *s) { +gb_internal void import_graph_node_set_destroy(ImportGraphNodeSet *s) { if (s->hashes.data != nullptr) { ptr_set_destroy(s); } } -void import_graph_node_set_add(ImportGraphNodeSet *s, ImportGraphNode *n) { +gb_internal void import_graph_node_set_add(ImportGraphNodeSet *s, ImportGraphNode *n) { if (s->hashes.data == nullptr) { ptr_set_init(s, heap_allocator()); } ptr_set_add(s, n); } -bool import_graph_node_set_exists(ImportGraphNodeSet *s, ImportGraphNode *n) { +gb_internal bool import_graph_node_set_exists(ImportGraphNodeSet *s, ImportGraphNode *n) { return ptr_set_exists(s, n); } -void import_graph_node_set_remove(ImportGraphNodeSet *s, ImportGraphNode *n) { +gb_internal void import_graph_node_set_remove(ImportGraphNodeSet *s, ImportGraphNode *n) { ptr_set_remove(s, n); } -ImportGraphNode *import_graph_node_create(gbAllocator a, AstPackage *pkg) { +gb_internal ImportGraphNode *import_graph_node_create(gbAllocator a, AstPackage *pkg) { ImportGraphNode *n = gb_alloc_item(a, ImportGraphNode); n->pkg = pkg; n->scope = pkg->scope; return n; } -void import_graph_node_destroy(ImportGraphNode *n, gbAllocator a) { +gb_internal void import_graph_node_destroy(ImportGraphNode *n, gbAllocator a) { import_graph_node_set_destroy(&n->pred); import_graph_node_set_destroy(&n->succ); gb_free(a, n); } -int import_graph_node_cmp(ImportGraphNode **data, isize i, isize j) { +gb_internal int import_graph_node_cmp(ImportGraphNode **data, isize i, isize j) { ImportGraphNode *x = data[i]; ImportGraphNode *y = data[j]; GB_ASSERT(x != y); @@ -177,7 +177,7 @@ int import_graph_node_cmp(ImportGraphNode **data, isize i, isize j) { return 0; } -void import_graph_node_swap(ImportGraphNode **data, isize i, isize j) { +gb_internal void import_graph_node_swap(ImportGraphNode **data, isize i, isize j) { ImportGraphNode *x = data[i]; ImportGraphNode *y = data[j]; data[i] = y; @@ -186,7 +186,7 @@ void import_graph_node_swap(ImportGraphNode **data, isize i, isize j) { y->index = i; } -GB_COMPARE_PROC(ast_node_cmp) { +gb_internal GB_COMPARE_PROC(ast_node_cmp) { Ast *x = *cast(Ast **)a; Ast *y = *cast(Ast **)b; Token i = ast_token(x); @@ -199,7 +199,7 @@ GB_COMPARE_PROC(ast_node_cmp) { -void init_decl_info(DeclInfo *d, Scope *scope, DeclInfo *parent) { +gb_internal void init_decl_info(DeclInfo *d, Scope *scope, DeclInfo *parent) { d->parent = parent; d->scope = scope; ptr_set_init(&d->deps, heap_allocator()); @@ -207,18 +207,18 @@ void init_decl_info(DeclInfo *d, Scope *scope, DeclInfo *parent) { array_init (&d->labels, heap_allocator()); } -DeclInfo *make_decl_info(Scope *scope, DeclInfo *parent) { +gb_internal DeclInfo *make_decl_info(Scope *scope, DeclInfo *parent) { DeclInfo *d = gb_alloc_item(permanent_allocator(), DeclInfo); init_decl_info(d, scope, parent); return d; } -void destroy_declaration_info(DeclInfo *d) { +gb_internal void destroy_declaration_info(DeclInfo *d) { ptr_set_destroy(&d->deps); array_free(&d->labels); } -bool decl_info_has_init(DeclInfo *d) { +gb_internal bool decl_info_has_init(DeclInfo *d) { if (d->init_expr != nullptr) { return true; } @@ -239,7 +239,7 @@ bool decl_info_has_init(DeclInfo *d) { -Scope *create_scope(CheckerInfo *info, Scope *parent, isize init_elements_capacity=DEFAULT_SCOPE_CAPACITY) { +gb_internal Scope *create_scope(CheckerInfo *info, Scope *parent, isize init_elements_capacity=DEFAULT_SCOPE_CAPACITY) { Scope *s = gb_alloc_item(permanent_allocator(), Scope); s->parent = parent; string_map_init(&s->elements, heap_allocator(), init_elements_capacity); @@ -260,7 +260,7 @@ Scope *create_scope(CheckerInfo *info, Scope *parent, isize init_elements_capaci return s; } -Scope *create_scope_from_file(CheckerInfo *info, AstFile *f) { +gb_internal Scope *create_scope_from_file(CheckerInfo *info, AstFile *f) { GB_ASSERT(f != nullptr); GB_ASSERT(f->pkg != nullptr); GB_ASSERT(f->pkg->scope != nullptr); @@ -276,7 +276,7 @@ Scope *create_scope_from_file(CheckerInfo *info, AstFile *f) { return s; } -Scope *create_scope_from_package(CheckerContext *c, AstPackage *pkg) { +gb_internal Scope *create_scope_from_package(CheckerContext *c, AstPackage *pkg) { GB_ASSERT(pkg != nullptr); isize total_pkg_decl_count = 0; @@ -307,7 +307,7 @@ Scope *create_scope_from_package(CheckerContext *c, AstPackage *pkg) { return s; } -void destroy_scope(Scope *scope) { +gb_internal void destroy_scope(Scope *scope) { for (auto const &entry : scope->elements) { Entity *e = entry.value; if (e->kind == Entity_Variable) { @@ -331,7 +331,7 @@ void destroy_scope(Scope *scope) { } -void add_scope(CheckerContext *c, Ast *node, Scope *scope) { +gb_internal void add_scope(CheckerContext *c, Ast *node, Scope *scope) { GB_ASSERT(node != nullptr); GB_ASSERT(scope != nullptr); scope->node = node; @@ -352,7 +352,7 @@ void add_scope(CheckerContext *c, Ast *node, Scope *scope) { } } -Scope *scope_of_node(Ast *node) { +gb_internal Scope *scope_of_node(Ast *node) { if (node == nullptr) { return nullptr; } @@ -375,7 +375,7 @@ Scope *scope_of_node(Ast *node) { } -void check_open_scope(CheckerContext *c, Ast *node) { +gb_internal void check_open_scope(CheckerContext *c, Ast *node) { node = unparen_expr(node); GB_ASSERT(node->kind == Ast_Invalid || is_ast_stmt(node) || @@ -397,12 +397,12 @@ void check_open_scope(CheckerContext *c, Ast *node) { c->state_flags |= StateFlag_bounds_check; } -void check_close_scope(CheckerContext *c) { +gb_internal void check_close_scope(CheckerContext *c) { c->scope = c->scope->parent; } -Entity *scope_lookup_current(Scope *s, String const &name) { +gb_internal Entity *scope_lookup_current(Scope *s, String const &name) { Entity **found = string_map_get(&s->elements, name); if (found) { return *found; @@ -410,7 +410,7 @@ Entity *scope_lookup_current(Scope *s, String const &name) { return nullptr; } -void scope_lookup_parent(Scope *scope, String const &name, Scope **scope_, Entity **entity_) { +gb_internal void scope_lookup_parent(Scope *scope, String const &name, Scope **scope_, Entity **entity_) { if (scope != nullptr) { bool gone_thru_proc = false; bool gone_thru_package = false; @@ -455,7 +455,7 @@ void scope_lookup_parent(Scope *scope, String const &name, Scope **scope_, Entit if (scope_) *scope_ = nullptr; } -Entity *scope_lookup(Scope *s, String const &name) { +gb_internal Entity *scope_lookup(Scope *s, String const &name) { Entity *entity = nullptr; scope_lookup_parent(s, name, nullptr, &entity); return entity; @@ -463,7 +463,7 @@ Entity *scope_lookup(Scope *s, String const &name) { -Entity *scope_insert_with_name(Scope *s, String const &name, Entity *entity, bool use_mutex=true) { +gb_internal Entity *scope_insert_with_name(Scope *s, String const &name, Entity *entity, bool use_mutex=true) { if (name == "") { return nullptr; } @@ -502,7 +502,7 @@ end:; return result; } -Entity *scope_insert(Scope *s, Entity *entity, bool use_mutex) { +gb_internal Entity *scope_insert(Scope *s, Entity *entity, bool use_mutex) { String name = entity->token.string; return scope_insert_with_name(s, name, entity, use_mutex); } @@ -528,14 +528,14 @@ struct VettedEntity { Entity *entity; Entity *other; }; -void init_vetted_entity(VettedEntity *ve, VettedEntityKind kind, Entity *entity, Entity *other=nullptr) { +gb_internal void init_vetted_entity(VettedEntity *ve, VettedEntityKind kind, Entity *entity, Entity *other=nullptr) { ve->kind = kind; ve->entity = entity; ve->other = other; } -GB_COMPARE_PROC(vetted_entity_variable_pos_cmp) { +gb_internal GB_COMPARE_PROC(vetted_entity_variable_pos_cmp) { Entity *x = (cast(VettedEntity *)a)->entity; Entity *y = (cast(VettedEntity *)b)->entity; GB_ASSERT(x != nullptr); @@ -544,7 +544,7 @@ GB_COMPARE_PROC(vetted_entity_variable_pos_cmp) { return token_pos_cmp(x->token.pos, y->token.pos); } -bool check_vet_shadowing_assignment(Checker *c, Entity *shadowed, Ast *expr) { +gb_internal bool check_vet_shadowing_assignment(Checker *c, Entity *shadowed, Ast *expr) { Ast *init = unparen_expr(expr); if (init == nullptr) { return false; @@ -568,7 +568,7 @@ bool check_vet_shadowing_assignment(Checker *c, Entity *shadowed, Ast *expr) { } -bool check_vet_shadowing(Checker *c, Entity *e, VettedEntity *ve) { +gb_internal bool check_vet_shadowing(Checker *c, Entity *e, VettedEntity *ve) { if (e->kind != Entity_Variable) { return false; } @@ -634,7 +634,7 @@ bool check_vet_shadowing(Checker *c, Entity *e, VettedEntity *ve) { return true; } -bool check_vet_unused(Checker *c, Entity *e, VettedEntity *ve) { +gb_internal bool check_vet_unused(Checker *c, Entity *e, VettedEntity *ve) { if ((e->flags&EntityFlag_Used) == 0) { switch (e->kind) { case Entity_Variable: @@ -652,7 +652,7 @@ bool check_vet_unused(Checker *c, Entity *e, VettedEntity *ve) { return false; } -void check_scope_usage(Checker *c, Scope *scope) { +gb_internal void check_scope_usage(Checker *c, Scope *scope) { bool vet_unused = true; bool vet_shadowing = true; @@ -728,12 +728,12 @@ void check_scope_usage(Checker *c, Scope *scope) { } -void add_dependency(CheckerInfo *info, DeclInfo *d, Entity *e) { +gb_internal void add_dependency(CheckerInfo *info, DeclInfo *d, Entity *e) { mutex_lock(&info->deps_mutex); ptr_set_add(&d->deps, e); mutex_unlock(&info->deps_mutex); } -void add_type_info_dependency(CheckerInfo *info, DeclInfo *d, Type *type, bool require_mutex) { +gb_internal void add_type_info_dependency(CheckerInfo *info, DeclInfo *d, Type *type, bool require_mutex) { if (d == nullptr) { return; } @@ -746,7 +746,7 @@ void add_type_info_dependency(CheckerInfo *info, DeclInfo *d, Type *type, bool r } } -AstPackage *get_core_package(CheckerInfo *info, String name) { +gb_internal AstPackage *get_core_package(CheckerInfo *info, String name) { gbAllocator a = heap_allocator(); String path = get_fullpath_core(a, name); defer (gb_free(a, path.text)); @@ -764,7 +764,7 @@ AstPackage *get_core_package(CheckerInfo *info, String name) { } -void add_package_dependency(CheckerContext *c, char const *package_name, char const *name) { +gb_internal void add_package_dependency(CheckerContext *c, char const *package_name, char const *name) { String n = make_string_c(name); AstPackage *p = get_core_package(&c->checker->info, make_string_c(package_name)); Entity *e = scope_lookup(p->scope, n); @@ -774,7 +774,7 @@ void add_package_dependency(CheckerContext *c, char const *package_name, char co add_dependency(c->info, c->decl, e); } -void try_to_add_package_dependency(CheckerContext *c, char const *package_name, char const *name) { +gb_internal void try_to_add_package_dependency(CheckerContext *c, char const *package_name, char const *name) { String n = make_string_c(name); AstPackage *p = get_core_package(&c->checker->info, make_string_c(package_name)); Entity *e = scope_lookup(p->scope, n); @@ -787,7 +787,7 @@ void try_to_add_package_dependency(CheckerContext *c, char const *package_name, } -void add_declaration_dependency(CheckerContext *c, Entity *e) { +gb_internal void add_declaration_dependency(CheckerContext *c, Entity *e) { if (e == nullptr) { return; } @@ -797,7 +797,7 @@ void add_declaration_dependency(CheckerContext *c, Entity *e) { } -Entity *add_global_entity(Entity *entity, Scope *scope=builtin_pkg->scope) { +gb_internal Entity *add_global_entity(Entity *entity, Scope *scope=builtin_pkg->scope) { String name = entity->token.string; defer (entity->state = EntityState_Resolved); @@ -810,27 +810,27 @@ Entity *add_global_entity(Entity *entity, Scope *scope=builtin_pkg->scope) { return entity; } -void add_global_constant(char const *name, Type *type, ExactValue value) { +gb_internal void add_global_constant(char const *name, Type *type, ExactValue value) { Entity *entity = alloc_entity(Entity_Constant, nullptr, make_token_ident(name), type); entity->Constant.value = value; add_global_entity(entity); } -void add_global_string_constant(char const *name, String const &value) { +gb_internal void add_global_string_constant(char const *name, String const &value) { add_global_constant(name, t_untyped_string, exact_value_string(value)); } -void add_global_bool_constant(char const *name, bool value) { +gb_internal void add_global_bool_constant(char const *name, bool value) { add_global_constant(name, t_untyped_bool, exact_value_bool(value)); } -void add_global_type_entity(String name, Type *type) { +gb_internal void add_global_type_entity(String name, Type *type) { add_global_entity(alloc_entity_type_name(nullptr, make_token_ident(name), type)); } -AstPackage *create_builtin_package(char const *name) { +gb_internal AstPackage *create_builtin_package(char const *name) { gbAllocator a = permanent_allocator(); AstPackage *pkg = gb_alloc_item(a, AstPackage); pkg->name = make_string_c(name); @@ -847,7 +847,7 @@ struct GlobalEnumValue { i64 value; }; -Slice add_global_enum_type(String const &type_name, GlobalEnumValue *values, isize value_count, Type **enum_type_ = nullptr) { +gb_internal Slice add_global_enum_type(String const &type_name, GlobalEnumValue *values, isize value_count, Type **enum_type_ = nullptr) { Scope *scope = create_scope(nullptr, builtin_pkg->scope); Entity *entity = alloc_entity_type_name(scope, make_token_ident(type_name), nullptr, EntityState_Resolved); @@ -882,7 +882,7 @@ Slice add_global_enum_type(String const &type_name, GlobalEnumValue *v return slice_from_array(fields); } -void add_global_enum_constant(Slice const &fields, char const *name, i64 value) { +gb_internal void add_global_enum_constant(Slice const &fields, char const *name, i64 value) { for (Entity *field : fields) { GB_ASSERT(field->kind == Entity_Constant); if (value == exact_value_to_i64(field->Constant.value)) { @@ -893,7 +893,7 @@ void add_global_enum_constant(Slice const &fields, char const *name, i GB_PANIC("Unfound enum value for global constant: %s %lld", name, cast(long long)value); } -Type *add_global_type_name(Scope *scope, String const &type_name, Type *backing_type) { +gb_internal Type *add_global_type_name(Scope *scope, String const &type_name, Type *backing_type) { Entity *e = alloc_entity_type_name(scope, make_token_ident(type_name), nullptr, EntityState_Resolved); Type *named_type = alloc_type_named(type_name, backing_type, e); e->type = named_type; @@ -905,7 +905,7 @@ Type *add_global_type_name(Scope *scope, String const &type_name, Type *backing_ } -void init_universal(void) { +gb_internal void init_universal(void) { BuildContext *bc = &build_context; builtin_pkg = create_builtin_package("builtin"); @@ -1122,7 +1122,7 @@ void init_universal(void) { -void init_checker_info(CheckerInfo *i) { +gb_internal void init_checker_info(CheckerInfo *i) { gbAllocator a = heap_allocator(); TIME_SECTION("checker info: general"); @@ -1180,7 +1180,7 @@ void init_checker_info(CheckerInfo *i) { string_map_init(&i->load_file_cache, a); } -void destroy_checker_info(CheckerInfo *i) { +gb_internal void destroy_checker_info(CheckerInfo *i) { array_free(&i->definitions); array_free(&i->entities); map_destroy(&i->global_untyped); @@ -1217,7 +1217,7 @@ void destroy_checker_info(CheckerInfo *i) { string_map_destroy(&i->load_file_cache); } -CheckerContext make_checker_context(Checker *c) { +gb_internal CheckerContext make_checker_context(Checker *c) { CheckerContext ctx = {}; ctx.checker = c; ctx.info = &c->info; @@ -1230,12 +1230,12 @@ CheckerContext make_checker_context(Checker *c) { ctx.poly_level = 0; return ctx; } -void destroy_checker_context(CheckerContext *ctx) { +gb_internal void destroy_checker_context(CheckerContext *ctx) { destroy_checker_type_path(ctx->type_path); destroy_checker_poly_path(ctx->poly_path); } -void add_curr_ast_file(CheckerContext *ctx, AstFile *file) { +gb_internal void add_curr_ast_file(CheckerContext *ctx, AstFile *file) { if (file != nullptr) { ctx->file = file; ctx->decl = file->pkg->decl_info; @@ -1243,7 +1243,7 @@ void add_curr_ast_file(CheckerContext *ctx, AstFile *file) { ctx->pkg = file->pkg; } } -void reset_checker_context(CheckerContext *ctx, AstFile *file, UntypedExprInfoMap *untyped) { +gb_internal void reset_checker_context(CheckerContext *ctx, AstFile *file, UntypedExprInfoMap *untyped) { if (ctx == nullptr) { return; } @@ -1258,7 +1258,7 @@ void reset_checker_context(CheckerContext *ctx, AstFile *file, UntypedExprInfoMa -void init_checker(Checker *c) { +gb_internal void init_checker(Checker *c) { gbAllocator a = heap_allocator(); TIME_SECTION("init checker info"); @@ -1278,7 +1278,7 @@ void init_checker(Checker *c) { c->builtin_ctx = make_checker_context(c); } -void destroy_checker(Checker *c) { +gb_internal void destroy_checker(Checker *c) { destroy_checker_info(&c->info); destroy_checker_context(&c->builtin_ctx); @@ -1290,7 +1290,7 @@ void destroy_checker(Checker *c) { } -TypeAndValue type_and_value_of_expr(Ast *expr) { +gb_internal TypeAndValue type_and_value_of_expr(Ast *expr) { TypeAndValue tav = {}; if (expr != nullptr) { tav = expr->tav; @@ -1298,7 +1298,7 @@ TypeAndValue type_and_value_of_expr(Ast *expr) { return tav; } -Type *type_of_expr(Ast *expr) { +gb_internal Type *type_of_expr(Ast *expr) { TypeAndValue tav = expr->tav; if (tav.mode != Addressing_Invalid) { return tav.type; @@ -1313,14 +1313,14 @@ Type *type_of_expr(Ast *expr) { return nullptr; } -Entity *implicit_entity_of_node(Ast *clause) { +gb_internal Entity *implicit_entity_of_node(Ast *clause) { if (clause != nullptr && clause->kind == Ast_CaseClause) { return clause->CaseClause.implicit_entity; } return nullptr; } -Entity *entity_of_node(Ast *expr) { +gb_internal Entity *entity_of_node(Ast *expr) { expr = unparen_expr(expr); switch (expr->kind) { case_ast_node(ident, Ident, expr); @@ -1341,25 +1341,25 @@ Entity *entity_of_node(Ast *expr) { return nullptr; } -DeclInfo *decl_info_of_entity(Entity *e) { +gb_internal DeclInfo *decl_info_of_entity(Entity *e) { if (e != nullptr) { return e->decl_info; } return nullptr; } -DeclInfo *decl_info_of_ident(Ast *ident) { +gb_internal DeclInfo *decl_info_of_ident(Ast *ident) { return decl_info_of_entity(entity_of_node(ident)); } -AstFile *ast_file_of_filename(CheckerInfo *i, String filename) { +gb_internal AstFile *ast_file_of_filename(CheckerInfo *i, String filename) { AstFile **found = string_map_get(&i->files, filename); if (found != nullptr) { return *found; } return nullptr; } -ExprInfo *check_get_expr_info(CheckerContext *c, Ast *expr) { +gb_internal ExprInfo *check_get_expr_info(CheckerContext *c, Ast *expr) { if (c->untyped != nullptr) { ExprInfo **found = map_get(c->untyped, expr); if (found) { @@ -1377,7 +1377,7 @@ ExprInfo *check_get_expr_info(CheckerContext *c, Ast *expr) { } } -void check_set_expr_info(CheckerContext *c, Ast *expr, AddressingMode mode, Type *type, ExactValue value) { +gb_internal void check_set_expr_info(CheckerContext *c, Ast *expr, AddressingMode mode, Type *type, ExactValue value) { if (c->untyped != nullptr) { map_set(c->untyped, expr, make_expr_info(mode, type, value, false)); } else { @@ -1387,7 +1387,7 @@ void check_set_expr_info(CheckerContext *c, Ast *expr, AddressingMode mode, Type } } -void check_remove_expr_info(CheckerContext *c, Ast *e) { +gb_internal void check_remove_expr_info(CheckerContext *c, Ast *e) { if (c->untyped != nullptr) { map_remove(c->untyped, e); GB_ASSERT(map_get(c->untyped, e) == nullptr); @@ -1401,7 +1401,7 @@ void check_remove_expr_info(CheckerContext *c, Ast *e) { } -isize type_info_index(CheckerInfo *info, Type *type, bool error_on_failure) { +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; @@ -1436,7 +1436,7 @@ isize type_info_index(CheckerInfo *info, Type *type, bool error_on_failure) { } -void add_untyped(CheckerContext *c, Ast *expr, AddressingMode mode, Type *type, ExactValue value) { +gb_internal void add_untyped(CheckerContext *c, Ast *expr, AddressingMode mode, Type *type, ExactValue value) { if (expr == nullptr) { return; } @@ -1453,7 +1453,7 @@ void add_untyped(CheckerContext *c, Ast *expr, AddressingMode mode, Type *type, check_set_expr_info(c, expr, mode, type, value); } -void add_type_and_value(CheckerInfo *i, Ast *expr, AddressingMode mode, Type *type, ExactValue value) { +gb_internal void add_type_and_value(CheckerInfo *i, Ast *expr, AddressingMode mode, Type *type, ExactValue value) { if (expr == nullptr) { return; } @@ -1489,7 +1489,7 @@ void add_type_and_value(CheckerInfo *i, Ast *expr, AddressingMode mode, Type *ty mutex_unlock(&i->type_and_value_mutex); } -void add_entity_definition(CheckerInfo *i, Ast *identifier, Entity *entity) { +gb_internal void add_entity_definition(CheckerInfo *i, Ast *identifier, Entity *entity) { GB_ASSERT(identifier != nullptr); GB_ASSERT(identifier->kind == Ast_Ident); // if (is_blank_ident(identifier)) { @@ -1505,7 +1505,7 @@ void add_entity_definition(CheckerInfo *i, Ast *identifier, Entity *entity) { mpmc_enqueue(&i->definition_queue, entity); } -bool redeclaration_error(String name, Entity *prev, Entity *found) { +gb_internal bool redeclaration_error(String name, Entity *prev, Entity *found) { TokenPos pos = found->token.pos; Entity *up = found->using_parent; if (up != nullptr) { @@ -1548,7 +1548,7 @@ bool redeclaration_error(String name, Entity *prev, Entity *found) { return false; } -void add_entity_flags_from_file(CheckerContext *c, Entity *e, Scope *scope) { +gb_internal void add_entity_flags_from_file(CheckerContext *c, Entity *e, Scope *scope) { if (c->file != nullptr && (c->file->flags & AstFile_IsLazy) != 0 && scope->flags & ScopeFlag_File) { AstPackage *pkg = c->file->pkg; if (pkg->kind == Package_Init && e->kind == Entity_Procedure && e->token.string == "main") { @@ -1561,7 +1561,7 @@ void add_entity_flags_from_file(CheckerContext *c, Entity *e, Scope *scope) { } } -bool add_entity_with_name(CheckerContext *c, Scope *scope, Ast *identifier, Entity *entity, String name) { +gb_internal bool add_entity_with_name(CheckerContext *c, Scope *scope, Ast *identifier, Entity *entity, String name) { if (scope == nullptr) { return false; } @@ -1581,11 +1581,11 @@ bool add_entity_with_name(CheckerContext *c, Scope *scope, Ast *identifier, Enti } return true; } -bool add_entity(CheckerContext *c, Scope *scope, Ast *identifier, Entity *entity) { +gb_internal bool add_entity(CheckerContext *c, Scope *scope, Ast *identifier, Entity *entity) { return add_entity_with_name(c, scope, identifier, entity, entity->token.string); } -void add_entity_use(CheckerContext *c, Ast *identifier, Entity *entity) { +gb_internal void add_entity_use(CheckerContext *c, Ast *identifier, Entity *entity) { if (entity == nullptr) { return; } @@ -1622,7 +1622,7 @@ void add_entity_use(CheckerContext *c, Ast *identifier, Entity *entity) { } -bool could_entity_be_lazy(Entity *e, DeclInfo *d) { +gb_internal bool could_entity_be_lazy(Entity *e, DeclInfo *d) { if ((e->flags & EntityFlag_Lazy) == 0) { return false; } @@ -1673,7 +1673,7 @@ bool could_entity_be_lazy(Entity *e, DeclInfo *d) { return true; } -void add_entity_and_decl_info(CheckerContext *c, Ast *identifier, Entity *e, DeclInfo *d, bool is_exported) { +gb_internal void add_entity_and_decl_info(CheckerContext *c, Ast *identifier, Entity *e, DeclInfo *d, bool is_exported) { if (identifier == nullptr) { // NOTE(bill): Should only happen on errors error(e->token, "Invalid variable declaration"); @@ -1738,16 +1738,15 @@ void add_entity_and_decl_info(CheckerContext *c, Ast *identifier, Entity *e, Dec } -void add_implicit_entity(CheckerContext *c, Ast *clause, Entity *e) { +gb_internal void add_implicit_entity(CheckerContext *c, Ast *clause, Entity *e) { GB_ASSERT(clause != nullptr); GB_ASSERT(e != nullptr); GB_ASSERT(clause->kind == Ast_CaseClause); clause->CaseClause.implicit_entity = e; } -void add_type_info_type(CheckerContext *c, Type *t) { - void add_type_info_type_internal(CheckerContext *c, Type *t); - +gb_internal void add_type_info_type_internal(CheckerContext *c, Type *t); +gb_internal void add_type_info_type(CheckerContext *c, Type *t) { if (build_context.disallow_rtti) { return; } @@ -1757,7 +1756,7 @@ void add_type_info_type(CheckerContext *c, Type *t) { mutex_unlock(&c->info->type_info_mutex); } -void add_type_info_type_internal(CheckerContext *c, Type *t) { +gb_internal void add_type_info_type_internal(CheckerContext *c, Type *t) { if (t == nullptr) { return; } @@ -1982,7 +1981,7 @@ void add_type_info_type_internal(CheckerContext *c, Type *t) { gb_global bool global_procedure_body_in_worker_queue = false; -void check_procedure_later(CheckerContext *c, ProcInfo *info) { +gb_internal void check_procedure_later(CheckerContext *c, ProcInfo *info) { GB_ASSERT(info != nullptr); GB_ASSERT(info->decl != nullptr); @@ -1994,7 +1993,7 @@ void check_procedure_later(CheckerContext *c, ProcInfo *info) { mpmc_enqueue(queue, info); } -void check_procedure_later(CheckerContext *c, AstFile *file, Token token, DeclInfo *decl, Type *type, Ast *body, u64 tags) { +gb_internal void check_procedure_later(CheckerContext *c, AstFile *file, Token token, DeclInfo *decl, Type *type, Ast *body, u64 tags) { ProcInfo *info = gb_alloc_item(permanent_allocator(), ProcInfo); info->file = file; info->token = token; @@ -2006,7 +2005,7 @@ void check_procedure_later(CheckerContext *c, AstFile *file, Token token, DeclIn } -void add_min_dep_type_info(Checker *c, Type *t) { +gb_internal void add_min_dep_type_info(Checker *c, Type *t) { if (t == nullptr) { return; } @@ -2201,7 +2200,7 @@ void add_min_dep_type_info(Checker *c, Type *t) { } -void add_dependency_to_set(Checker *c, Entity *entity) { +gb_internal void add_dependency_to_set(Checker *c, Entity *entity) { if (entity == nullptr) { return; } @@ -2254,7 +2253,7 @@ void add_dependency_to_set(Checker *c, Entity *entity) { } } -void force_add_dependency_entity(Checker *c, Scope *scope, String const &name) { +gb_internal void force_add_dependency_entity(Checker *c, Scope *scope, String const &name) { Entity *e = scope_lookup(scope, name); if (e == nullptr) { return; @@ -2266,7 +2265,7 @@ void force_add_dependency_entity(Checker *c, Scope *scope, String const &name) { -void generate_minimum_dependency_set(Checker *c, Entity *start) { +gb_internal void generate_minimum_dependency_set(Checker *c, Entity *start) { isize entity_count = c->info.entities.count; isize min_dep_set_cap = next_pow2_isize(entity_count*4); // empirically determined factor @@ -2479,7 +2478,7 @@ void generate_minimum_dependency_set(Checker *c, Entity *start) { #undef FORCE_ADD_RUNTIME_ENTITIES } -bool is_entity_a_dependency(Entity *e) { +gb_internal bool is_entity_a_dependency(Entity *e) { if (e == nullptr) return false; switch (e->kind) { case Entity_Procedure: @@ -2493,7 +2492,7 @@ bool is_entity_a_dependency(Entity *e) { return false; } -Array generate_entity_dependency_graph(CheckerInfo *info, gbAllocator allocator) { +gb_internal Array generate_entity_dependency_graph(CheckerInfo *info, gbAllocator allocator) { PtrMap M = {}; map_init(&M, allocator, info->entities.count); defer (map_destroy(&M)); @@ -2612,10 +2611,10 @@ Array generate_entity_dependency_graph(CheckerInfo *info, gbA } -void check_single_global_entity(Checker *c, Entity *e, DeclInfo *d); +gb_internal void check_single_global_entity(Checker *c, Entity *e, DeclInfo *d); -Entity *find_core_entity(Checker *c, String name) { +gb_internal Entity *find_core_entity(Checker *c, String name) { Entity *e = scope_lookup_current(c->info.runtime_package->scope, name); if (e == nullptr) { compiler_error("Could not find type declaration for '%.*s'\n" @@ -2625,7 +2624,7 @@ Entity *find_core_entity(Checker *c, String name) { return e; } -Type *find_core_type(Checker *c, String name) { +gb_internal Type *find_core_type(Checker *c, String name) { Entity *e = scope_lookup_current(c->info.runtime_package->scope, name); if (e == nullptr) { compiler_error("Could not find type declaration for '%.*s'\n" @@ -2640,7 +2639,7 @@ Type *find_core_type(Checker *c, String name) { } -Entity *find_entity_in_pkg(CheckerInfo *info, String const &pkg, String const &name) { +gb_internal Entity *find_entity_in_pkg(CheckerInfo *info, String const &pkg, String const &name) { AstPackage *package = get_core_package(info, pkg); Entity *e = scope_lookup_current(package->scope, name); if (e == nullptr) { @@ -2650,7 +2649,7 @@ Entity *find_entity_in_pkg(CheckerInfo *info, String const &pkg, String const &n return e; } -Type *find_type_in_pkg(CheckerInfo *info, String const &pkg, String const &name) { +gb_internal Type *find_type_in_pkg(CheckerInfo *info, String const &pkg, String const &name) { AstPackage *package = get_core_package(info, pkg); Entity *e = scope_lookup_current(package->scope, name); if (e == nullptr) { @@ -2661,58 +2660,58 @@ Type *find_type_in_pkg(CheckerInfo *info, String const &pkg, String const &name) return e->type; } -CheckerTypePath *new_checker_type_path() { +gb_internal CheckerTypePath *new_checker_type_path() { gbAllocator a = heap_allocator(); auto *tp = gb_alloc_item(a, CheckerTypePath); array_init(tp, a, 0, 16); return tp; } -void destroy_checker_type_path(CheckerTypePath *tp) { +gb_internal void destroy_checker_type_path(CheckerTypePath *tp) { array_free(tp); gb_free(heap_allocator(), tp); } -void check_type_path_push(CheckerContext *c, Entity *e) { +gb_internal void check_type_path_push(CheckerContext *c, Entity *e) { GB_ASSERT(c->type_path != nullptr); GB_ASSERT(e != nullptr); array_add(c->type_path, e); } -Entity *check_type_path_pop(CheckerContext *c) { +gb_internal Entity *check_type_path_pop(CheckerContext *c) { GB_ASSERT(c->type_path != nullptr); return array_pop(c->type_path); } -CheckerPolyPath *new_checker_poly_path(void) { +gb_internal CheckerPolyPath *new_checker_poly_path(void) { gbAllocator a = heap_allocator(); auto *pp = gb_alloc_item(a, CheckerPolyPath); array_init(pp, a, 0, 16); return pp; } -void destroy_checker_poly_path(CheckerPolyPath *pp) { +gb_internal void destroy_checker_poly_path(CheckerPolyPath *pp) { array_free(pp); gb_free(heap_allocator(), pp); } -void check_poly_path_push(CheckerContext *c, Type *t) { +gb_internal void check_poly_path_push(CheckerContext *c, Type *t) { GB_ASSERT(c->poly_path != nullptr); GB_ASSERT(t != nullptr); GB_ASSERT(is_type_polymorphic(t)); array_add(c->poly_path, t); } -Type *check_poly_path_pop(CheckerContext *c) { +gb_internal Type *check_poly_path_pop(CheckerContext *c) { GB_ASSERT(c->poly_path != nullptr); return array_pop(c->poly_path); } -Array proc_group_entities(CheckerContext *c, Operand o) { +gb_internal Array proc_group_entities(CheckerContext *c, Operand o) { Array procs = {}; if (o.mode == Addressing_ProcGroup) { GB_ASSERT(o.proc_group != nullptr); @@ -2724,7 +2723,7 @@ Array proc_group_entities(CheckerContext *c, Operand o) { return procs; } -Array proc_group_entities_cloned(CheckerContext *c, Operand o) { +gb_internal Array proc_group_entities_cloned(CheckerContext *c, Operand o) { auto entities = proc_group_entities(c, o); if (entities.count == 0) { return {}; @@ -2735,7 +2734,7 @@ Array proc_group_entities_cloned(CheckerContext *c, Operand o) { -void init_core_type_info(Checker *c) { +gb_internal void init_core_type_info(Checker *c) { if (t_type_info != nullptr) { return; } @@ -2816,7 +2815,7 @@ void init_core_type_info(Checker *c) { t_type_info_soa_pointer_ptr = alloc_type_pointer(t_type_info_soa_pointer); } -void init_mem_allocator(Checker *c) { +gb_internal void init_mem_allocator(Checker *c) { if (t_allocator != nullptr) { return; } @@ -2825,7 +2824,7 @@ void init_mem_allocator(Checker *c) { t_allocator_error = find_core_type(c, str_lit("Allocator_Error")); } -void init_core_context(Checker *c) { +gb_internal void init_core_context(Checker *c) { if (t_context != nullptr) { return; } @@ -2833,7 +2832,7 @@ void init_core_context(Checker *c) { t_context_ptr = alloc_type_pointer(t_context); } -void init_core_source_code_location(Checker *c) { +gb_internal void init_core_source_code_location(Checker *c) { if (t_source_code_location != nullptr) { return; } @@ -2841,7 +2840,7 @@ void init_core_source_code_location(Checker *c) { t_source_code_location_ptr = alloc_type_pointer(t_source_code_location); } -void init_core_map_type(Checker *c) { +gb_internal void init_core_map_type(Checker *c) { if (t_map_info != nullptr) { return; } @@ -2855,7 +2854,7 @@ void init_core_map_type(Checker *c) { t_raw_map_ptr = alloc_type_pointer(t_raw_map); } -void init_preload(Checker *c) { +gb_internal void init_preload(Checker *c) { init_core_type_info(c); init_mem_allocator(c); init_core_context(c); @@ -2863,7 +2862,7 @@ void init_preload(Checker *c) { init_core_map_type(c); } -ExactValue check_decl_attribute_value(CheckerContext *c, Ast *value) { +gb_internal ExactValue check_decl_attribute_value(CheckerContext *c, Ast *value) { ExactValue ev = {}; if (value != nullptr) { Operand op = {}; @@ -2879,7 +2878,7 @@ ExactValue check_decl_attribute_value(CheckerContext *c, Ast *value) { return ev; } -Type *check_decl_attribute_type(CheckerContext *c, Ast *value) { +gb_internal Type *check_decl_attribute_type(CheckerContext *c, Ast *value) { if (value != nullptr) { return check_type(c, value); } @@ -2890,7 +2889,7 @@ Type *check_decl_attribute_type(CheckerContext *c, Ast *value) { #define ATTRIBUTE_USER_TAG_NAME "tag" -DECL_ATTRIBUTE_PROC(foreign_block_decl_attribute) { +gb_internal DECL_ATTRIBUTE_PROC(foreign_block_decl_attribute) { ExactValue ev = check_decl_attribute_value(c, value); if (name == ATTRIBUTE_USER_TAG_NAME) { @@ -2945,7 +2944,7 @@ DECL_ATTRIBUTE_PROC(foreign_block_decl_attribute) { return false; } -DECL_ATTRIBUTE_PROC(proc_decl_attribute) { +gb_internal DECL_ATTRIBUTE_PROC(proc_decl_attribute) { if (name == ATTRIBUTE_USER_TAG_NAME) { ExactValue ev = check_decl_attribute_value(c, value); if (ev.kind != ExactValue_String) { @@ -3242,7 +3241,7 @@ DECL_ATTRIBUTE_PROC(proc_decl_attribute) { return false; } -DECL_ATTRIBUTE_PROC(var_decl_attribute) { +gb_internal DECL_ATTRIBUTE_PROC(var_decl_attribute) { if (name == ATTRIBUTE_USER_TAG_NAME) { ExactValue ev = check_decl_attribute_value(c, value); if (ev.kind != ExactValue_String) { @@ -3367,7 +3366,7 @@ DECL_ATTRIBUTE_PROC(var_decl_attribute) { return false; } -DECL_ATTRIBUTE_PROC(const_decl_attribute) { +gb_internal DECL_ATTRIBUTE_PROC(const_decl_attribute) { if (name == ATTRIBUTE_USER_TAG_NAME) { ExactValue ev = check_decl_attribute_value(c, value); if (ev.kind != ExactValue_String) { @@ -3381,7 +3380,7 @@ DECL_ATTRIBUTE_PROC(const_decl_attribute) { return false; } -DECL_ATTRIBUTE_PROC(type_decl_attribute) { +gb_internal DECL_ATTRIBUTE_PROC(type_decl_attribute) { if (name == ATTRIBUTE_USER_TAG_NAME) { ExactValue ev = check_decl_attribute_value(c, value); if (ev.kind != ExactValue_String) { @@ -3412,7 +3411,7 @@ DECL_ATTRIBUTE_PROC(type_decl_attribute) { -void check_decl_attributes(CheckerContext *c, Array const &attributes, DeclAttributeProc *proc, AttributeContext *ac) { +gb_internal void check_decl_attributes(CheckerContext *c, Array const &attributes, DeclAttributeProc *proc, AttributeContext *ac) { if (attributes.count == 0) return; String original_link_prefix = {}; @@ -3480,7 +3479,7 @@ void check_decl_attributes(CheckerContext *c, Array const &attributes, De } -isize get_total_value_count(Slice const &values) { +gb_internal isize get_total_value_count(Slice const &values) { isize count = 0; for_array(i, values) { Type *t = type_of_expr(values[i]); @@ -3498,7 +3497,7 @@ isize get_total_value_count(Slice const &values) { return count; } -bool check_arity_match(CheckerContext *c, AstValueDecl *vd, bool is_global) { +gb_internal bool check_arity_match(CheckerContext *c, AstValueDecl *vd, bool is_global) { isize lhs = vd->names.count; isize rhs = 0; if (is_global) { @@ -3541,7 +3540,7 @@ bool check_arity_match(CheckerContext *c, AstValueDecl *vd, bool is_global) { return true; } -void check_collect_entities_from_when_stmt(CheckerContext *c, AstWhenStmt *ws) { +gb_internal void check_collect_entities_from_when_stmt(CheckerContext *c, AstWhenStmt *ws) { Operand operand = {Addressing_Invalid}; if (!ws->is_cond_determined) { check_expr(c, &operand, ws->cond); @@ -3577,7 +3576,7 @@ void check_collect_entities_from_when_stmt(CheckerContext *c, AstWhenStmt *ws) { } } -void check_builtin_attributes(CheckerContext *ctx, Entity *e, Array *attributes) { +gb_internal void check_builtin_attributes(CheckerContext *ctx, Entity *e, Array *attributes) { switch (e->kind) { case Entity_ProcGroup: case Entity_Procedure: @@ -3640,7 +3639,7 @@ void check_builtin_attributes(CheckerContext *ctx, Entity *e, Array *attr } } -void check_collect_value_decl(CheckerContext *c, Ast *decl) { +gb_internal void check_collect_value_decl(CheckerContext *c, Ast *decl) { if (decl->state_flags & StateFlag_BeenHandled) return; decl->state_flags |= StateFlag_BeenHandled; @@ -3891,7 +3890,7 @@ void check_collect_value_decl(CheckerContext *c, Ast *decl) { } } -void check_add_foreign_block_decl(CheckerContext *ctx, Ast *decl) { +gb_internal void check_add_foreign_block_decl(CheckerContext *ctx, Ast *decl) { if (decl->state_flags & StateFlag_BeenHandled) return; decl->state_flags |= StateFlag_BeenHandled; @@ -3912,7 +3911,7 @@ void check_add_foreign_block_decl(CheckerContext *ctx, Ast *decl) { check_collect_entities(&c, block->stmts); } -bool correct_single_type_alias(CheckerContext *c, Entity *e) { +gb_internal bool correct_single_type_alias(CheckerContext *c, Entity *e) { if (e->kind == Entity_Constant) { DeclInfo *d = e->decl_info; if (d != nullptr && d->init_expr != nullptr) { @@ -3927,7 +3926,7 @@ bool correct_single_type_alias(CheckerContext *c, Entity *e) { return false; } -bool correct_type_alias_in_scope_backwards(CheckerContext *c, Scope *s) { +gb_internal bool correct_type_alias_in_scope_backwards(CheckerContext *c, Scope *s) { isize n = s->elements.entries.count; bool correction = false; for (isize i = n-1; i >= 0; i--) { @@ -3935,7 +3934,7 @@ bool correct_type_alias_in_scope_backwards(CheckerContext *c, Scope *s) { } return correction; } -bool correct_type_alias_in_scope_forwards(CheckerContext *c, Scope *s) { +gb_internal bool correct_type_alias_in_scope_forwards(CheckerContext *c, Scope *s) { isize n = s->elements.entries.count; bool correction = false; for (isize i = 0; i < n; i++) { @@ -3945,7 +3944,7 @@ bool correct_type_alias_in_scope_forwards(CheckerContext *c, Scope *s) { } -void correct_type_aliases_in_scope(CheckerContext *c, Scope *s) { +gb_internal void correct_type_aliases_in_scope(CheckerContext *c, Scope *s) { // NOTE(bill, 2022-02-04): This is used to solve the problem caused by type aliases // of type aliases being "confused" as constants // @@ -3966,7 +3965,7 @@ void correct_type_aliases_in_scope(CheckerContext *c, Scope *s) { // NOTE(bill): If file_scopes == nullptr, this will act like a local scope -void check_collect_entities(CheckerContext *c, Slice const &nodes) { +gb_internal void check_collect_entities(CheckerContext *c, Slice const &nodes) { AstFile *curr_file = nullptr; if ((c->scope->flags&ScopeFlag_File) != 0) { curr_file = c->scope->file; @@ -4050,13 +4049,13 @@ void check_collect_entities(CheckerContext *c, Slice const &nodes) { } } -CheckerContext *create_checker_context(Checker *c) { +gb_internal CheckerContext *create_checker_context(Checker *c) { CheckerContext *ctx = gb_alloc_item(permanent_allocator(), CheckerContext); *ctx = make_checker_context(c); return ctx; } -void check_single_global_entity(Checker *c, Entity *e, DeclInfo *d) { +gb_internal void check_single_global_entity(Checker *c, Entity *e, DeclInfo *d) { GB_ASSERT(e != nullptr); GB_ASSERT(d != nullptr); @@ -4089,7 +4088,7 @@ void check_single_global_entity(Checker *c, Entity *e, DeclInfo *d) { check_entity_decl(ctx, e, d, nullptr); } -void check_all_global_entities(Checker *c) { +gb_internal void check_all_global_entities(Checker *c) { // NOTE(bill): This must be single threaded // Don't bother trying for_array(i, c->info.entities) { @@ -4107,7 +4106,7 @@ void check_all_global_entities(Checker *c) { } -bool is_string_an_identifier(String s) { +gb_internal bool is_string_an_identifier(String s) { isize offset = 0; if (s.len < 1) { return false; @@ -4131,7 +4130,7 @@ bool is_string_an_identifier(String s) { return offset == s.len; } -String path_to_entity_name(String name, String fullpath, bool strip_extension=true) { +gb_internal String path_to_entity_name(String name, String fullpath, bool strip_extension=true) { if (name.len != 0) { return name; } @@ -4177,7 +4176,7 @@ String path_to_entity_name(String name, String fullpath, bool strip_extension=tr #if 1 -void add_import_dependency_node(Checker *c, Ast *decl, PtrMap *M) { +gb_internal void add_import_dependency_node(Checker *c, Ast *decl, PtrMap *M) { AstPackage *parent_pkg = decl->file()->pkg; switch (decl->kind) { @@ -4242,7 +4241,7 @@ void add_import_dependency_node(Checker *c, Ast *decl, PtrMap generate_import_dependency_graph(Checker *c) { +gb_internal Array generate_import_dependency_graph(Checker *c) { PtrMap M = {}; map_init(&M, heap_allocator(), 2*c->parser->packages.count); defer (map_destroy(&M)); @@ -4285,7 +4284,7 @@ struct ImportPathItem { Ast * decl; }; -Array find_import_path(Checker *c, AstPackage *start, AstPackage *end, PtrSet *visited) { +gb_internal Array find_import_path(Checker *c, AstPackage *start, AstPackage *end, PtrSet *visited) { Array empty_path = {}; if (ptr_set_update(visited, start)) { @@ -4335,7 +4334,7 @@ Array find_import_path(Checker *c, AstPackage *start, AstPackage } #endif -String get_invalid_import_name(String input) { +gb_internal String get_invalid_import_name(String input) { isize slash = 0; for (isize i = input.len-1; i >= 0; i--) { if (input[i] == '/' || input[i] == '\\') { @@ -4347,7 +4346,7 @@ String get_invalid_import_name(String input) { return input; } -void check_add_import_decl(CheckerContext *ctx, Ast *decl) { +gb_internal void check_add_import_decl(CheckerContext *ctx, Ast *decl) { if (decl->state_flags & StateFlag_BeenHandled) return; decl->state_flags |= StateFlag_BeenHandled; @@ -4422,7 +4421,7 @@ void check_add_import_decl(CheckerContext *ctx, Ast *decl) { scope->flags |= ScopeFlag_HasBeenImported; } -DECL_ATTRIBUTE_PROC(foreign_import_decl_attribute) { +gb_internal DECL_ATTRIBUTE_PROC(foreign_import_decl_attribute) { if (name == ATTRIBUTE_USER_TAG_NAME) { ExactValue ev = check_decl_attribute_value(c, value); if (ev.kind != ExactValue_String) { @@ -4449,7 +4448,7 @@ DECL_ATTRIBUTE_PROC(foreign_import_decl_attribute) { return false; } -void check_add_foreign_import_decl(CheckerContext *ctx, Ast *decl) { +gb_internal void check_add_foreign_import_decl(CheckerContext *ctx, Ast *decl) { if (decl->state_flags & StateFlag_BeenHandled) return; decl->state_flags |= StateFlag_BeenHandled; @@ -4515,10 +4514,10 @@ void check_add_foreign_import_decl(CheckerContext *ctx, Ast *decl) { } // Returns true if a new package is present -bool collect_file_decls(CheckerContext *ctx, Slice const &decls); -bool collect_file_decls_from_when_stmt(CheckerContext *ctx, AstWhenStmt *ws); +gb_internal bool collect_file_decls(CheckerContext *ctx, Slice const &decls); +gb_internal bool collect_file_decls_from_when_stmt(CheckerContext *ctx, AstWhenStmt *ws); -bool collect_when_stmt_from_file(CheckerContext *ctx, AstWhenStmt *ws) { +gb_internal bool collect_when_stmt_from_file(CheckerContext *ctx, AstWhenStmt *ws) { Operand operand = {Addressing_Invalid}; if (!ws->is_cond_determined) { check_expr(ctx, &operand, ws->cond); @@ -4557,7 +4556,7 @@ bool collect_when_stmt_from_file(CheckerContext *ctx, AstWhenStmt *ws) { return false; } -bool collect_file_decls_from_when_stmt(CheckerContext *ctx, AstWhenStmt *ws) { +gb_internal bool collect_file_decls_from_when_stmt(CheckerContext *ctx, AstWhenStmt *ws) { Operand operand = {Addressing_Invalid}; if (!ws->is_cond_determined) { check_expr(ctx, &operand, ws->cond); @@ -4594,7 +4593,7 @@ bool collect_file_decls_from_when_stmt(CheckerContext *ctx, AstWhenStmt *ws) { } -bool collect_file_decl(CheckerContext *ctx, Ast *decl) { +gb_internal bool collect_file_decl(CheckerContext *ctx, Ast *decl) { GB_ASSERT(ctx->scope->flags&ScopeFlag_File); AstFile *curr_file = ctx->scope->file; @@ -4658,7 +4657,7 @@ bool collect_file_decl(CheckerContext *ctx, Ast *decl) { return false; } -bool collect_file_decls(CheckerContext *ctx, Slice const &decls) { +gb_internal bool collect_file_decls(CheckerContext *ctx, Slice const &decls) { GB_ASSERT(ctx->scope->flags&ScopeFlag_File); for_array(i, decls) { @@ -4671,7 +4670,7 @@ bool collect_file_decls(CheckerContext *ctx, Slice const &decls) { return false; } -GB_COMPARE_PROC(sort_file_by_name) { +gb_internal GB_COMPARE_PROC(sort_file_by_name) { AstFile const *x = *cast(AstFile const **)a; AstFile const *y = *cast(AstFile const **)b; String x_name = filename_from_path(x->fullpath); @@ -4679,7 +4678,7 @@ GB_COMPARE_PROC(sort_file_by_name) { return string_compare(x_name, y_name); } -void check_create_file_scopes(Checker *c) { +gb_internal void check_create_file_scopes(Checker *c) { for_array(i, c->parser->packages) { AstPackage *pkg = c->parser->packages[i]; isize total_pkg_decl_count = 0; @@ -4705,7 +4704,7 @@ struct ThreadProcCheckerSection { }; -void check_with_workers(Checker *c, WorkerTaskProc *proc, isize total_count) { +gb_internal void check_with_workers(Checker *c, WorkerTaskProc *proc, isize total_count) { 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 if (!build_context.threaded_checker) { @@ -4744,7 +4743,7 @@ void check_with_workers(Checker *c, WorkerTaskProc *proc, isize total_count) { } -WORKER_TASK_PROC(thread_proc_collect_entities) { +gb_internal WORKER_TASK_PROC(thread_proc_collect_entities) { auto *cs = cast(ThreadProcCheckerSection *)data; Checker *c = cs->checker; CheckerContext collect_entity_ctx = make_checker_context(c); @@ -4775,11 +4774,11 @@ WORKER_TASK_PROC(thread_proc_collect_entities) { } -void check_collect_entities_all(Checker *c) { +gb_internal void check_collect_entities_all(Checker *c) { check_with_workers(c, thread_proc_collect_entities, c->info.files.entries.count); } -void check_export_entities_in_pkg(CheckerContext *ctx, AstPackage *pkg, UntypedExprInfoMap *untyped) { +gb_internal void check_export_entities_in_pkg(CheckerContext *ctx, AstPackage *pkg, UntypedExprInfoMap *untyped) { if (pkg->files.count != 0) { AstPackageExportedEntity item = {}; while (mpmc_dequeue(&pkg->exported_entity_queue, &item)) { @@ -4793,7 +4792,7 @@ void check_export_entities_in_pkg(CheckerContext *ctx, AstPackage *pkg, UntypedE } } -WORKER_TASK_PROC(thread_proc_check_export_entities) { +gb_internal WORKER_TASK_PROC(thread_proc_check_export_entities) { auto cs = cast(ThreadProcCheckerSection *)data; Checker *c = cs->checker; @@ -4815,11 +4814,11 @@ WORKER_TASK_PROC(thread_proc_check_export_entities) { return 0; } -void check_export_entities(Checker *c) { +gb_internal void check_export_entities(Checker *c) { check_with_workers(c, thread_proc_check_export_entities, c->info.packages.entries.count); } -void check_import_entities(Checker *c) { +gb_internal void check_import_entities(Checker *c) { Array dep_graph = generate_import_dependency_graph(c); defer ({ for_array(i, dep_graph) { @@ -4961,9 +4960,9 @@ void check_import_entities(Checker *c) { } -Array find_entity_path(Entity *start, Entity *end, PtrSet *visited = nullptr); +gb_internal Array find_entity_path(Entity *start, Entity *end, PtrSet *visited = nullptr); -bool find_entity_path_tuple(Type *tuple, Entity *end, PtrSet *visited, Array *path_) { +gb_internal bool find_entity_path_tuple(Type *tuple, Entity *end, PtrSet *visited, Array *path_) { GB_ASSERT(path_ != nullptr); if (tuple == nullptr) { return false; @@ -4995,7 +4994,7 @@ bool find_entity_path_tuple(Type *tuple, Entity *end, PtrSet *visited, return false; } -Array find_entity_path(Entity *start, Entity *end, PtrSet *visited) { +gb_internal Array find_entity_path(Entity *start, Entity *end, PtrSet *visited) { PtrSet visited_ = {}; bool made_visited = false; if (visited == nullptr) { @@ -5047,7 +5046,7 @@ Array find_entity_path(Entity *start, Entity *end, PtrSet *v } -void calculate_global_init_order(Checker *c) { +gb_internal void calculate_global_init_order(Checker *c) { CheckerInfo *info = &c->info; TIME_SECTION("calculate_global_init_order: generate entity dependency graph"); @@ -5122,7 +5121,7 @@ void calculate_global_init_order(Checker *c) { } -bool check_proc_info(Checker *c, ProcInfo *pi, UntypedExprInfoMap *untyped, ProcBodyQueue *procs_to_check_queue) { +gb_internal bool check_proc_info(Checker *c, ProcInfo *pi, UntypedExprInfoMap *untyped, ProcBodyQueue *procs_to_check_queue) { if (pi == nullptr) { return false; } @@ -5201,9 +5200,9 @@ bool check_proc_info(Checker *c, ProcInfo *pi, UntypedExprInfoMap *untyped, Proc GB_STATIC_ASSERT(sizeof(isize) == sizeof(void *)); -bool consume_proc_info_queue(Checker *c, ProcInfo *pi, ProcBodyQueue *q, UntypedExprInfoMap *untyped); +gb_internal bool consume_proc_info_queue(Checker *c, ProcInfo *pi, ProcBodyQueue *q, UntypedExprInfoMap *untyped); -void check_unchecked_bodies(Checker *c) { +gb_internal void check_unchecked_bodies(Checker *c) { // NOTE(2021-02-26, bill): Sanity checker // This is a partial hack to make sure all procedure bodies have been checked // even ones which should not exist, due to the multithreaded nature of the parser @@ -5255,7 +5254,7 @@ void check_unchecked_bodies(Checker *c) { } -void check_test_procedures(Checker *c) { +gb_internal void check_test_procedures(Checker *c) { if (build_context.test_names.entries.count == 0) { return; } @@ -5290,7 +5289,7 @@ void check_test_procedures(Checker *c) { gb_global std::atomic total_bodies_checked; -bool consume_proc_info_queue(Checker *c, ProcInfo *pi, ProcBodyQueue *q, UntypedExprInfoMap *untyped) { +gb_internal bool consume_proc_info_queue(Checker *c, ProcInfo *pi, ProcBodyQueue *q, UntypedExprInfoMap *untyped) { GB_ASSERT(pi->decl != nullptr); if (pi->decl->parent && pi->decl->parent->entity) { Entity *parent = pi->decl->parent->entity; @@ -5318,7 +5317,7 @@ struct ThreadProcBodyData { ThreadProcBodyData *all_data; }; -WORKER_TASK_PROC(thread_proc_body) { +gb_internal WORKER_TASK_PROC(thread_proc_body) { ThreadProcBodyData *bd = cast(ThreadProcBodyData *)data; Checker *c = bd->checker; GB_ASSERT(c != nullptr); @@ -5338,7 +5337,7 @@ WORKER_TASK_PROC(thread_proc_body) { return 0; } -void check_procedure_bodies(Checker *c) { +gb_internal void check_procedure_bodies(Checker *c) { GB_ASSERT(c != nullptr); u32 thread_count = cast(u32)gb_max(build_context.thread_count, 1); @@ -5414,7 +5413,7 @@ void check_procedure_bodies(Checker *c) { global_procedure_body_in_worker_queue = false; } -void add_untyped_expressions(CheckerInfo *cinfo, UntypedExprInfoMap *untyped) { +gb_internal void add_untyped_expressions(CheckerInfo *cinfo, UntypedExprInfoMap *untyped) { if (untyped == nullptr) { return; } @@ -5428,7 +5427,7 @@ void add_untyped_expressions(CheckerInfo *cinfo, UntypedExprInfoMap *untyped) { map_clear(untyped); } -void check_deferred_procedures(Checker *c) { +gb_internal void check_deferred_procedures(Checker *c) { for (Entity *src = nullptr; mpmc_dequeue(&c->procs_with_deferred_to_check, &src); /**/) { GB_ASSERT(src->kind == Entity_Procedure); @@ -5581,7 +5580,7 @@ void check_deferred_procedures(Checker *c) { } -void check_unique_package_names(Checker *c) { +gb_internal void check_unique_package_names(Checker *c) { StringMap pkgs = {}; // Key: package name string_map_init(&pkgs, heap_allocator(), 2*c->info.packages.entries.count); defer (string_map_destroy(&pkgs)); @@ -5614,7 +5613,7 @@ void check_unique_package_names(Checker *c) { } } -void check_add_entities_from_queues(Checker *c) { +gb_internal void check_add_entities_from_queues(Checker *c) { isize cap = c->info.entities.count + c->info.entity_queue.count.load(std::memory_order_relaxed); array_reserve(&c->info.entities, cap); for (Entity *e; mpmc_dequeue(&c->info.entity_queue, &e); /**/) { @@ -5622,7 +5621,7 @@ void check_add_entities_from_queues(Checker *c) { } } -void check_add_definitions_from_queues(Checker *c) { +gb_internal void check_add_definitions_from_queues(Checker *c) { isize cap = c->info.definitions.count + c->info.definition_queue.count.load(std::memory_order_relaxed); array_reserve(&c->info.definitions, cap); for (Entity *e; mpmc_dequeue(&c->info.definition_queue, &e); /**/) { @@ -5630,12 +5629,12 @@ void check_add_definitions_from_queues(Checker *c) { } } -void check_merge_queues_into_arrays(Checker *c) { +gb_internal void check_merge_queues_into_arrays(Checker *c) { check_add_entities_from_queues(c); check_add_definitions_from_queues(c); } -GB_COMPARE_PROC(init_procedures_cmp) { +gb_internal GB_COMPARE_PROC(init_procedures_cmp) { int cmp = 0; Entity *x = *(Entity **)a; Entity *y = *(Entity **)b; @@ -5673,11 +5672,11 @@ GB_COMPARE_PROC(init_procedures_cmp) { } -void check_sort_init_procedures(Checker *c) { +gb_internal void check_sort_init_procedures(Checker *c) { gb_sort_array(c->info.init_procedures.data, c->info.init_procedures.count, init_procedures_cmp); } -void add_type_info_for_type_definitions(Checker *c) { +gb_internal void add_type_info_for_type_definitions(Checker *c) { for_array(i, c->info.definitions) { Entity *e = c->info.definitions[i]; if (e->kind == Entity_TypeName && e->type != nullptr) { @@ -5689,7 +5688,7 @@ void add_type_info_for_type_definitions(Checker *c) { } } -void check_parsed_files(Checker *c) { +gb_internal void check_parsed_files(Checker *c) { TIME_SECTION("map full filepaths to scope"); add_type_info_type(&c->builtin_ctx, t_invalid); diff --git a/src/types.cpp b/src/types.cpp index 2ab7374c2..c8e24f01d 100644 --- a/src/types.cpp +++ b/src/types.cpp @@ -4029,9 +4029,8 @@ gb_internal bool has_type_got_objc_class_attribute(Type *t) { +gb_internal bool internal_check_is_assignable_to(Type *src, Type *dst); gb_internal bool is_type_objc_object(Type *t) { - bool internal_check_is_assignable_to(Type *src, Type *dst); - return internal_check_is_assignable_to(t, t_objc_object); } -- cgit v1.2.3 From c1f5be24e28c41efbbbe6d116d533b55d48bbf82 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Sun, 18 Dec 2022 22:49:10 +0000 Subject: Remove dead code in the compiler --- build.bat | 1 + src/build_settings.cpp | 6 +- src/check_decl.cpp | 10 - src/check_expr.cpp | 24 - src/check_stmt.cpp | 6 - src/checker.cpp | 140 ++---- src/checker.hpp | 8 - src/common.cpp | 9 + src/docs.cpp | 9 - src/entity.cpp | 8 - src/exact_value.cpp | 86 ++-- src/llvm_backend.cpp | 10 +- src/llvm_backend_debug.cpp | 6 - src/llvm_backend_general.cpp | 68 --- src/llvm_backend_opt.cpp | 20 +- src/llvm_backend_proc.cpp | 88 ++-- src/llvm_backend_stmt.cpp | 10 - src/llvm_backend_utility.cpp | 12 - src/main.cpp | 77 +--- src/parser.cpp | 36 -- src/parser.hpp | 5 - src/parser_pos.cpp | 2 - src/query_data.cpp | 1030 ------------------------------------------ src/range_cache.cpp | 18 +- src/string.cpp | 14 - src/string_map.cpp | 2 - src/threading.cpp | 50 +- src/types.cpp | 75 --- 28 files changed, 169 insertions(+), 1661 deletions(-) delete mode 100644 src/query_data.cpp (limited to 'src/checker.cpp') diff --git a/build.bat b/build.bat index 7391bd95f..d7a89fe20 100644 --- a/build.bat +++ b/build.bat @@ -62,6 +62,7 @@ if %release_mode% EQU 0 ( rem Debug set compiler_warnings= ^ -W4 -WX ^ -wd4100 -wd4101 -wd4127 -wd4146 ^ + -wd4505 ^ -wd4456 -wd4457 set compiler_includes= ^ diff --git a/src/build_settings.cpp b/src/build_settings.cpp index d66db8099..7d796d775 100644 --- a/src/build_settings.cpp +++ b/src/build_settings.cpp @@ -149,7 +149,6 @@ enum CommandKind : u32 { Command_run = 1<<0, Command_build = 1<<1, Command_check = 1<<3, - Command_query = 1<<4, Command_doc = 1<<5, Command_version = 1<<6, Command_test = 1<<7, @@ -157,7 +156,7 @@ enum CommandKind : u32 { Command_strip_semicolon = 1<<8, Command_bug_report = 1<<9, - Command__does_check = Command_run|Command_build|Command_check|Command_query|Command_doc|Command_test|Command_strip_semicolon, + Command__does_check = Command_run|Command_build|Command_check|Command_doc|Command_test|Command_strip_semicolon, Command__does_build = Command_run|Command_build|Command_test, Command_all = ~(u32)0, }; @@ -166,7 +165,6 @@ gb_global char const *odin_command_strings[32] = { "run", "build", "check", - "query", "doc", "version", "test", @@ -316,8 +314,6 @@ struct BuildContext { u32 cmd_doc_flags; Array extra_packages; - QueryDataSetSettings query_data_set_settings; - StringSet test_names; gbAffinity affinity; diff --git a/src/check_decl.cpp b/src/check_decl.cpp index a976c1b73..d982a69fc 100644 --- a/src/check_decl.cpp +++ b/src/check_decl.cpp @@ -232,16 +232,6 @@ gb_internal Ast *remove_type_alias_clutter(Ast *node) { } } -gb_internal isize total_attribute_count(DeclInfo *decl) { - isize attribute_count = 0; - for_array(i, decl->attributes) { - Ast *attr = decl->attributes[i]; - if (attr->kind != Ast_Attribute) continue; - attribute_count += attr->Attribute.elems.count; - } - return attribute_count; -} - gb_internal Type *clone_enum_type(CheckerContext *ctx, Type *original_enum_type, Type *named_type) { // NOTE(bill, 2022-02-05): Stupid edge case for `distinct` declarations // diff --git a/src/check_expr.cpp b/src/check_expr.cpp index 3003e07b6..ed1ddd1f1 100644 --- a/src/check_expr.cpp +++ b/src/check_expr.cpp @@ -5103,16 +5103,6 @@ gb_internal bool check_unpack_arguments(CheckerContext *ctx, Entity **lhs, isize return optional_ok; } - -gb_internal bool is_expr_constant_zero(Ast *expr) { - GB_ASSERT(expr != nullptr); - auto v = exact_value_to_integer(expr->tav.value); - if (v.kind == ExactValue_Integer) { - return big_int_cmp_zero(&v.value_integer) == 0; - } - return false; -} - gb_internal isize get_procedure_param_count_excluding_defaults(Type *pt, isize *param_count_) { GB_ASSERT(pt != nullptr); GB_ASSERT(pt->kind == Type_Proc); @@ -5429,20 +5419,6 @@ gb_internal isize lookup_procedure_parameter(TypeProc *pt, String parameter_name } return -1; } -gb_internal isize lookup_procedure_result(TypeProc *pt, String result_name) { - isize result_count = pt->result_count; - for (isize i = 0; i < result_count; i++) { - Entity *e = pt->results->Tuple.variables[i]; - String name = e->token.string; - if (is_blank_ident(name)) { - continue; - } - if (name == result_name) { - return i; - } - } - return -1; -} gb_internal CALL_ARGUMENT_CHECKER(check_named_call_arguments) { ast_node(ce, CallExpr, call); diff --git a/src/check_stmt.cpp b/src/check_stmt.cpp index cae9c3537..73adbed8b 100644 --- a/src/check_stmt.cpp +++ b/src/check_stmt.cpp @@ -1520,12 +1520,6 @@ gb_internal void check_stmt_internal(CheckerContext *ctx, Ast *node, u32 flags) } case_end; - case_ast_node(ts, TagStmt, node); - // TODO(bill): Tag Statements - error(node, "Tag statements are not supported yet"); - check_stmt(ctx, ts->stmt, flags); - case_end; - case_ast_node(as, AssignStmt, node); switch (as->op.kind) { case Token_Eq: { diff --git a/src/checker.cpp b/src/checker.cpp index e2c430dc2..f130a965f 100644 --- a/src/checker.cpp +++ b/src/checker.cpp @@ -61,18 +61,6 @@ gb_internal void scope_reserve(Scope *scope, isize capacity) { } } -gb_internal i32 is_scope_an_ancestor(Scope *parent, Scope *child) { - i32 i = 0; - while (child != nullptr) { - if (parent == child) { - return i; - } - child = child->parent; - i++; - } - return -1; -} - gb_internal void entity_graph_node_set_destroy(EntityGraphNodeSet *s) { if (s->hashes.data != nullptr) { ptr_set_destroy(s); @@ -86,9 +74,9 @@ gb_internal void entity_graph_node_set_add(EntityGraphNodeSet *s, EntityGraphNod ptr_set_add(s, n); } -gb_internal bool entity_graph_node_set_exists(EntityGraphNodeSet *s, EntityGraphNode *n) { - return ptr_set_exists(s, n); -} +// gb_internal bool entity_graph_node_set_exists(EntityGraphNodeSet *s, EntityGraphNode *n) { +// return ptr_set_exists(s, n); +// } gb_internal void entity_graph_node_set_remove(EntityGraphNodeSet *s, EntityGraphNode *n) { ptr_set_remove(s, n); @@ -139,13 +127,13 @@ gb_internal void import_graph_node_set_add(ImportGraphNodeSet *s, ImportGraphNod ptr_set_add(s, n); } -gb_internal bool import_graph_node_set_exists(ImportGraphNodeSet *s, ImportGraphNode *n) { - return ptr_set_exists(s, n); -} +// gb_internal bool import_graph_node_set_exists(ImportGraphNodeSet *s, ImportGraphNode *n) { +// return ptr_set_exists(s, n); +// } -gb_internal void import_graph_node_set_remove(ImportGraphNodeSet *s, ImportGraphNode *n) { - ptr_set_remove(s, n); -} +// gb_internal void import_graph_node_set_remove(ImportGraphNodeSet *s, ImportGraphNode *n) { +// ptr_set_remove(s, n); +// } gb_internal ImportGraphNode *import_graph_node_create(gbAllocator a, AstPackage *pkg) { ImportGraphNode *n = gb_alloc_item(a, ImportGraphNode); @@ -186,15 +174,6 @@ gb_internal void import_graph_node_swap(ImportGraphNode **data, isize i, isize j y->index = i; } -gb_internal GB_COMPARE_PROC(ast_node_cmp) { - Ast *x = *cast(Ast **)a; - Ast *y = *cast(Ast **)b; - Token i = ast_token(x); - Token j = ast_token(y); - return token_pos_cmp(i.pos, j.pos); -} - - @@ -213,27 +192,27 @@ gb_internal DeclInfo *make_decl_info(Scope *scope, DeclInfo *parent) { return d; } -gb_internal void destroy_declaration_info(DeclInfo *d) { - ptr_set_destroy(&d->deps); - array_free(&d->labels); -} +// gb_internal void destroy_declaration_info(DeclInfo *d) { +// ptr_set_destroy(&d->deps); +// array_free(&d->labels); +// } -gb_internal bool decl_info_has_init(DeclInfo *d) { - if (d->init_expr != nullptr) { - return true; - } - if (d->proc_lit != nullptr) { - switch (d->proc_lit->kind) { - case_ast_node(pl, ProcLit, d->proc_lit); - if (pl->body != nullptr) { - return true; - } - case_end; - } - } +// gb_internal bool decl_info_has_init(DeclInfo *d) { +// if (d->init_expr != nullptr) { +// return true; +// } +// if (d->proc_lit != nullptr) { +// switch (d->proc_lit->kind) { +// case_ast_node(pl, ProcLit, d->proc_lit); +// if (pl->body != nullptr) { +// return true; +// } +// case_end; +// } +// } - return false; -} +// return false; +// } @@ -528,11 +507,6 @@ struct VettedEntity { Entity *entity; Entity *other; }; -gb_internal void init_vetted_entity(VettedEntity *ve, VettedEntityKind kind, Entity *entity, Entity *other=nullptr) { - ve->kind = kind; - ve->entity = entity; - ve->other = other; -} gb_internal GB_COMPARE_PROC(vetted_entity_variable_pos_cmp) { @@ -1144,7 +1118,7 @@ gb_internal void init_checker_info(CheckerInfo *i) { - i->allow_identifier_uses = build_context.query_data_set_settings.kind == QueryDataSet_GoToDefinitions; + i->allow_identifier_uses = false; if (i->allow_identifier_uses) { array_init(&i->identifier_uses, a); } @@ -1226,13 +1200,10 @@ gb_internal CheckerContext make_checker_context(Checker *c) { ctx.type_path = new_checker_type_path(); ctx.type_level = 0; - ctx.poly_path = new_checker_poly_path(); - ctx.poly_level = 0; return ctx; } gb_internal void destroy_checker_context(CheckerContext *ctx) { destroy_checker_type_path(ctx->type_path); - destroy_checker_poly_path(ctx->poly_path); } gb_internal void add_curr_ast_file(CheckerContext *ctx, AstFile *file) { @@ -1348,17 +1319,17 @@ gb_internal DeclInfo *decl_info_of_entity(Entity *e) { return nullptr; } -gb_internal DeclInfo *decl_info_of_ident(Ast *ident) { - return decl_info_of_entity(entity_of_node(ident)); -} +// gb_internal DeclInfo *decl_info_of_ident(Ast *ident) { +// return decl_info_of_entity(entity_of_node(ident)); +// } -gb_internal AstFile *ast_file_of_filename(CheckerInfo *i, String filename) { - AstFile **found = string_map_get(&i->files, filename); - if (found != nullptr) { - return *found; - } - return nullptr; -} +// gb_internal AstFile *ast_file_of_filename(CheckerInfo *i, String filename) { +// AstFile **found = string_map_get(&i->files, filename); +// if (found != nullptr) { +// return *found; +// } +// return nullptr; +// } gb_internal ExprInfo *check_get_expr_info(CheckerContext *c, Ast *expr) { if (c->untyped != nullptr) { ExprInfo **found = map_get(c->untyped, expr); @@ -2684,32 +2655,6 @@ gb_internal Entity *check_type_path_pop(CheckerContext *c) { } -gb_internal CheckerPolyPath *new_checker_poly_path(void) { - gbAllocator a = heap_allocator(); - auto *pp = gb_alloc_item(a, CheckerPolyPath); - array_init(pp, a, 0, 16); - return pp; -} - -gb_internal void destroy_checker_poly_path(CheckerPolyPath *pp) { - array_free(pp); - gb_free(heap_allocator(), pp); -} - - -gb_internal void check_poly_path_push(CheckerContext *c, Type *t) { - GB_ASSERT(c->poly_path != nullptr); - GB_ASSERT(t != nullptr); - GB_ASSERT(is_type_polymorphic(t)); - array_add(c->poly_path, t); -} - -gb_internal Type *check_poly_path_pop(CheckerContext *c) { - GB_ASSERT(c->poly_path != nullptr); - return array_pop(c->poly_path); -} - - gb_internal Array proc_group_entities(CheckerContext *c, Operand o) { Array procs = {}; @@ -2878,13 +2823,6 @@ gb_internal ExactValue check_decl_attribute_value(CheckerContext *c, Ast *value) return ev; } -gb_internal Type *check_decl_attribute_type(CheckerContext *c, Ast *value) { - if (value != nullptr) { - return check_type(c, value); - } - return nullptr; -} - #define ATTRIBUTE_USER_TAG_NAME "tag" diff --git a/src/checker.hpp b/src/checker.hpp index e1efd5b89..58f6a027c 100644 --- a/src/checker.hpp +++ b/src/checker.hpp @@ -397,8 +397,6 @@ struct CheckerContext { CheckerTypePath *type_path; isize type_level; // TODO(bill): Actually handle correctly - CheckerPolyPath *poly_path; - isize poly_level; // TODO(bill): Actually handle correctly UntypedExprInfoMap *untyped; @@ -489,12 +487,6 @@ gb_internal void destroy_checker_type_path(CheckerTypePath *tp); gb_internal void check_type_path_push(CheckerContext *c, Entity *e); gb_internal Entity *check_type_path_pop (CheckerContext *c); -gb_internal CheckerPolyPath *new_checker_poly_path(); -gb_internal void destroy_checker_poly_path(CheckerPolyPath *); - -gb_internal void check_poly_path_push(CheckerContext *c, Type *t); -gb_internal Type *check_poly_path_pop (CheckerContext *c); - gb_internal void init_core_context(Checker *c); gb_internal void init_mem_allocator(Checker *c); diff --git a/src/common.cpp b/src/common.cpp index 09203e633..3624446f1 100644 --- a/src/common.cpp +++ b/src/common.cpp @@ -50,6 +50,10 @@ gb_internal void debugf(char const *fmt, ...); #include "string.cpp" #include "range_cache.cpp" +#if defined(GB_SYSTEM_WINDOWS) + #pragma warning(push) + #pragma warning(disable: 4505) +#endif gb_internal gb_inline bool is_power_of_two(i64 x) { if (x <= 0) { @@ -900,3 +904,8 @@ gb_internal Slice did_you_mean_results(DidYouMeanAnswers *d) } return slice_array(d->distances, 0, count); } + + +#if defined(GB_SYSTEM_WINDOWS) + #pragma warning(pop) +#endif \ No newline at end of file diff --git a/src/docs.cpp b/src/docs.cpp index 33b1e8361..b1efa2b46 100644 --- a/src/docs.cpp +++ b/src/docs.cpp @@ -85,15 +85,6 @@ gb_internal void print_doc_line(i32 indent, char const *fmt, ...) { va_end(va); gb_printf("\n"); } -gb_internal void print_doc_line_no_newline(i32 indent, char const *fmt, ...) { - while (indent --> 0) { - gb_printf("\t"); - } - va_list va; - va_start(va, fmt); - gb_printf_va(fmt, va); - va_end(va); -} gb_internal void print_doc_line_no_newline(i32 indent, String const &data) { while (indent --> 0) { gb_printf("\t"); diff --git a/src/entity.cpp b/src/entity.cpp index 6a3a69950..0605a293a 100644 --- a/src/entity.cpp +++ b/src/entity.cpp @@ -404,14 +404,6 @@ gb_internal Entity *alloc_entity_proc_group(Scope *scope, Token token, Type *typ return entity; } - -gb_internal Entity *alloc_entity_builtin(Scope *scope, Token token, Type *type, i32 id) { - Entity *entity = alloc_entity(Entity_Builtin, scope, token, type); - entity->Builtin.id = id; - entity->state = EntityState_Resolved; - return entity; -} - gb_internal Entity *alloc_entity_import_name(Scope *scope, Token token, Type *type, String path, String name, Scope *import_scope) { Entity *entity = alloc_entity(Entity_ImportName, scope, token, type); diff --git a/src/exact_value.cpp b/src/exact_value.cpp index 453909a15..f4c85505d 100644 --- a/src/exact_value.cpp +++ b/src/exact_value.cpp @@ -15,16 +15,6 @@ struct Quaternion256 { f64 imag, jmag, kmag, real; }; -gb_internal Quaternion256 quaternion256_inverse(Quaternion256 x) { - f64 invmag2 = 1.0 / (x.real*x.real + x.imag*x.imag + x.jmag*x.jmag + x.kmag*x.kmag); - x.real = +x.real * invmag2; - x.imag = -x.imag * invmag2; - x.jmag = -x.jmag * invmag2; - x.kmag = -x.kmag * invmag2; - return x; -} - - enum ExactValueKind { ExactValue_Invalid = 0, @@ -453,44 +443,44 @@ gb_internal ExactValue exact_value_kmag(ExactValue v) { return r; } -gb_internal ExactValue exact_value_make_imag(ExactValue v) { - switch (v.kind) { - case ExactValue_Integer: - return exact_value_complex(0, exact_value_to_float(v).value_float); - case ExactValue_Float: - return exact_value_complex(0, v.value_float); - default: - GB_PANIC("Expected an integer or float type for 'exact_value_make_imag'"); - } - ExactValue r = {ExactValue_Invalid}; - return r; -} - -gb_internal ExactValue exact_value_make_jmag(ExactValue v) { - switch (v.kind) { - case ExactValue_Integer: - return exact_value_quaternion(0, 0, exact_value_to_float(v).value_float, 0); - case ExactValue_Float: - return exact_value_quaternion(0, 0, v.value_float, 0); - default: - GB_PANIC("Expected an integer or float type for 'exact_value_make_imag'"); - } - ExactValue r = {ExactValue_Invalid}; - return r; -} - -gb_internal ExactValue exact_value_make_kmag(ExactValue v) { - switch (v.kind) { - case ExactValue_Integer: - return exact_value_quaternion(0, 0, 0, exact_value_to_float(v).value_float); - case ExactValue_Float: - return exact_value_quaternion(0, 0, 0, v.value_float); - default: - GB_PANIC("Expected an integer or float type for 'exact_value_make_imag'"); - } - ExactValue r = {ExactValue_Invalid}; - return r; -} +// gb_internal ExactValue exact_value_make_imag(ExactValue v) { +// switch (v.kind) { +// case ExactValue_Integer: +// return exact_value_complex(0, exact_value_to_float(v).value_float); +// case ExactValue_Float: +// return exact_value_complex(0, v.value_float); +// default: +// GB_PANIC("Expected an integer or float type for 'exact_value_make_imag'"); +// } +// ExactValue r = {ExactValue_Invalid}; +// return r; +// } + +// gb_internal ExactValue exact_value_make_jmag(ExactValue v) { +// switch (v.kind) { +// case ExactValue_Integer: +// return exact_value_quaternion(0, 0, exact_value_to_float(v).value_float, 0); +// case ExactValue_Float: +// return exact_value_quaternion(0, 0, v.value_float, 0); +// default: +// GB_PANIC("Expected an integer or float type for 'exact_value_make_jmag'"); +// } +// ExactValue r = {ExactValue_Invalid}; +// return r; +// } + +// gb_internal ExactValue exact_value_make_kmag(ExactValue v) { +// switch (v.kind) { +// case ExactValue_Integer: +// return exact_value_quaternion(0, 0, 0, exact_value_to_float(v).value_float); +// case ExactValue_Float: +// return exact_value_quaternion(0, 0, 0, v.value_float); +// default: +// GB_PANIC("Expected an integer or float type for 'exact_value_make_kmag'"); +// } +// ExactValue r = {ExactValue_Invalid}; +// return r; +// } gb_internal i64 exact_value_to_i64(ExactValue v) { v = exact_value_to_integer(v); diff --git a/src/llvm_backend.cpp b/src/llvm_backend.cpp index ca4b3b683..c5bc96eb9 100644 --- a/src/llvm_backend.cpp +++ b/src/llvm_backend.cpp @@ -605,11 +605,11 @@ gb_internal lbValue lb_map_get_proc_for_type(lbModule *m, Type *type) { return {p->value, p->type}; } -gb_internal void lb_debug_print(lbProcedure *p, String const &str) { - auto args = array_make(heap_allocator(), 1); - args[0] = lb_const_string(p->module, str); - lb_emit_runtime_call(p, "print_string", args); -} +// gb_internal void lb_debug_print(lbProcedure *p, String const &str) { +// auto args = array_make(heap_allocator(), 1); +// args[0] = lb_const_string(p->module, str); +// lb_emit_runtime_call(p, "print_string", args); +// } gb_internal lbValue lb_map_set_proc_for_type(lbModule *m, Type *type) { GB_ASSERT(build_context.use_static_map_calls); diff --git a/src/llvm_backend_debug.cpp b/src/llvm_backend_debug.cpp index 849416579..55c4370a2 100644 --- a/src/llvm_backend_debug.cpp +++ b/src/llvm_backend_debug.cpp @@ -14,12 +14,6 @@ gb_internal void lb_set_llvm_metadata(lbModule *m, void *key, LLVMMetadataRef va } } -gb_internal LLVMMetadataRef lb_get_llvm_file_metadata_from_node(lbModule *m, Ast *node) { - if (node == nullptr) { - return nullptr; - } - return lb_get_llvm_metadata(m, node->file()); -} gb_internal LLVMMetadataRef lb_get_current_debug_scope(lbProcedure *p) { GB_ASSERT_MSG(p->debug_info != nullptr, "missing debug information for %.*s", LIT(p->name)); diff --git a/src/llvm_backend_general.cpp b/src/llvm_backend_general.cpp index f30038da8..e5aa95f10 100644 --- a/src/llvm_backend_general.cpp +++ b/src/llvm_backend_general.cpp @@ -272,12 +272,6 @@ gb_internal lbValue lb_emit_epi(lbModule *m, lbValue const &value, isize index) gb_internal LLVMValueRef llvm_zero(lbModule *m) { return LLVMConstInt(lb_type(m, t_int), 0, false); } -gb_internal LLVMValueRef llvm_zero32(lbModule *m) { - return LLVMConstInt(lb_type(m, t_i32), 0, false); -} -gb_internal LLVMValueRef llvm_one(lbModule *m) { - return LLVMConstInt(lb_type(m, t_i32), 1, false); -} gb_internal LLVMValueRef llvm_alloca(lbProcedure *p, LLVMTypeRef llvm_type, isize alignment, char const *name) { LLVMPositionBuilderAtEnd(p->builder, p->decl_block->block); @@ -874,14 +868,6 @@ gb_internal void lb_addr_store(lbProcedure *p, lbAddr addr, lbValue value) { lb_emit_store(p, addr.addr, value); } -gb_internal void lb_const_store(lbValue ptr, lbValue value) { - GB_ASSERT(lb_is_const(ptr)); - GB_ASSERT(lb_is_const(value)); - GB_ASSERT(is_type_pointer(ptr.type)); - LLVMSetInitializer(ptr.value, value.value); -} - - gb_internal bool lb_is_type_proc_recursive(Type *t) { for (;;) { if (t == nullptr) { @@ -1327,21 +1313,6 @@ gb_internal void lb_clone_struct_type(LLVMTypeRef dst, LLVMTypeRef src) { LLVMStructSetBody(dst, fields, field_count, LLVMIsPackedStruct(src)); } -gb_internal LLVMTypeRef lb_alignment_prefix_type_hack(lbModule *m, i64 alignment) { - switch (alignment) { - case 1: - return LLVMArrayType(lb_type(m, t_u8), 0); - case 2: - return LLVMArrayType(lb_type(m, t_u16), 0); - case 4: - return LLVMArrayType(lb_type(m, t_u32), 0); - case 8: - return LLVMArrayType(lb_type(m, t_u64), 0); - default: case 16: - return LLVMArrayType(LLVMVectorType(lb_type(m, t_u32), 4), 0); - } -} - gb_internal String lb_mangle_name(lbModule *m, Entity *e) { String name = e->token.string; @@ -2202,9 +2173,6 @@ gb_internal void lb_add_member(lbModule *m, String const &name, lbValue val) { string_map_set(&m->members, name, val); } } -gb_internal void lb_add_member(lbModule *m, StringHashKey const &key, lbValue val) { - string_map_set(&m->members, key, val); -} gb_internal void lb_add_procedure_value(lbModule *m, lbProcedure *p) { if (p->entity != nullptr) { map_set(&m->procedure_values, p->value, p->entity); @@ -2493,42 +2461,6 @@ gb_internal lbValue lb_find_or_add_entity_string(lbModule *m, String const &str) return res; } -gb_internal lbValue lb_find_or_add_entity_string_byte_slice(lbModule *m, String const &str) { - LLVMValueRef indices[2] = {llvm_zero(m), llvm_zero(m)}; - LLVMValueRef data = LLVMConstStringInContext(m->ctx, - cast(char const *)str.text, - cast(unsigned)str.len, - false); - - - char *name = nullptr; - { - isize max_len = 7+8+1; - name = gb_alloc_array(permanent_allocator(), char, max_len); - u32 id = m->gen->global_array_index.fetch_add(1); - isize len = gb_snprintf(name, max_len, "csbs$%x", id); - len -= 1; - } - LLVMTypeRef type = LLVMTypeOf(data); - LLVMValueRef global_data = LLVMAddGlobal(m->mod, type, name); - LLVMSetInitializer(global_data, data); - lb_make_global_private_const(global_data); - LLVMSetAlignment(global_data, 1); - - LLVMValueRef ptr = nullptr; - if (str.len != 0) { - ptr = LLVMConstInBoundsGEP2(type, global_data, indices, 2); - } else { - ptr = LLVMConstNull(lb_type(m, t_u8_ptr)); - } - LLVMValueRef len = LLVMConstInt(lb_type(m, t_int), str.len, true); - LLVMValueRef values[2] = {ptr, len}; - - lbValue res = {}; - res.value = llvm_const_named_struct(m, t_u8_slice, values, 2); - res.type = t_u8_slice; - return res; -} gb_internal lbValue lb_find_or_add_entity_string_byte_slice_with_type(lbModule *m, String const &str, Type *slice_type) { GB_ASSERT(is_type_slice(slice_type)); LLVMValueRef indices[2] = {llvm_zero(m), llvm_zero(m)}; diff --git a/src/llvm_backend_opt.cpp b/src/llvm_backend_opt.cpp index 533264e62..fd6d94361 100644 --- a/src/llvm_backend_opt.cpp +++ b/src/llvm_backend_opt.cpp @@ -37,16 +37,16 @@ gb_internal void lb_add_function_simplifcation_passes(LLVMPassManagerRef mpm, i3 gb_internal void lb_populate_module_pass_manager(LLVMTargetMachineRef target_machine, LLVMPassManagerRef mpm, i32 optimization_level); gb_internal void lb_populate_function_pass_manager_specific(lbModule *m, LLVMPassManagerRef fpm, i32 optimization_level); -gb_internal LLVMBool lb_must_preserve_predicate_callback(LLVMValueRef value, void *user_data) { - lbModule *m = cast(lbModule *)user_data; - if (m == nullptr) { - return false; - } - if (value == nullptr) { - return false; - } - return LLVMIsAAllocaInst(value) != nullptr; -} +// gb_internal LLVMBool lb_must_preserve_predicate_callback(LLVMValueRef value, void *user_data) { +// lbModule *m = cast(lbModule *)user_data; +// if (m == nullptr) { +// return false; +// } +// if (value == nullptr) { +// return false; +// } +// return LLVMIsAAllocaInst(value) != nullptr; +// } #if LLVM_VERSION_MAJOR < 12 diff --git a/src/llvm_backend_proc.cpp b/src/llvm_backend_proc.cpp index 0789fb2c1..384d29ca7 100644 --- a/src/llvm_backend_proc.cpp +++ b/src/llvm_backend_proc.cpp @@ -383,46 +383,46 @@ gb_internal lbProcedure *lb_create_dummy_procedure(lbModule *m, String link_name } -gb_internal lbValue lb_value_param(lbProcedure *p, Entity *e, Type *abi_type, i32 index, lbParamPasskind *kind_) { - lbParamPasskind kind = lbParamPass_Value; - - if (e != nullptr && !are_types_identical(abi_type, e->type)) { - if (is_type_pointer(abi_type)) { - GB_ASSERT(e->kind == Entity_Variable); - Type *av = core_type(type_deref(abi_type)); - if (are_types_identical(av, core_type(e->type))) { - kind = lbParamPass_Pointer; - if (e->flags&EntityFlag_Value) { - kind = lbParamPass_ConstRef; - } - } else { - kind = lbParamPass_BitCast; - } - } else if (is_type_integer(abi_type)) { - kind = lbParamPass_Integer; - } else if (abi_type == t_llvm_bool) { - kind = lbParamPass_Value; - } else if (is_type_boolean(abi_type)) { - kind = lbParamPass_Integer; - } else if (is_type_simd_vector(abi_type)) { - kind = lbParamPass_BitCast; - } else if (is_type_float(abi_type)) { - kind = lbParamPass_BitCast; - } else if (is_type_tuple(abi_type)) { - kind = lbParamPass_Tuple; - } else if (is_type_proc(abi_type)) { - kind = lbParamPass_Value; - } else { - GB_PANIC("Invalid abi type pass kind %s", type_to_string(abi_type)); - } - } - - if (kind_) *kind_ = kind; - lbValue res = {}; - res.value = LLVMGetParam(p->value, cast(unsigned)index); - res.type = abi_type; - return res; -} +// gb_internal lbValue lb_value_param(lbProcedure *p, Entity *e, Type *abi_type, i32 index, lbParamPasskind *kind_) { +// lbParamPasskind kind = lbParamPass_Value; + +// if (e != nullptr && !are_types_identical(abi_type, e->type)) { +// if (is_type_pointer(abi_type)) { +// GB_ASSERT(e->kind == Entity_Variable); +// Type *av = core_type(type_deref(abi_type)); +// if (are_types_identical(av, core_type(e->type))) { +// kind = lbParamPass_Pointer; +// if (e->flags&EntityFlag_Value) { +// kind = lbParamPass_ConstRef; +// } +// } else { +// kind = lbParamPass_BitCast; +// } +// } else if (is_type_integer(abi_type)) { +// kind = lbParamPass_Integer; +// } else if (abi_type == t_llvm_bool) { +// kind = lbParamPass_Value; +// } else if (is_type_boolean(abi_type)) { +// kind = lbParamPass_Integer; +// } else if (is_type_simd_vector(abi_type)) { +// kind = lbParamPass_BitCast; +// } else if (is_type_float(abi_type)) { +// kind = lbParamPass_BitCast; +// } else if (is_type_tuple(abi_type)) { +// kind = lbParamPass_Tuple; +// } else if (is_type_proc(abi_type)) { +// kind = lbParamPass_Value; +// } else { +// GB_PANIC("Invalid abi type pass kind %s", type_to_string(abi_type)); +// } +// } + +// if (kind_) *kind_ = kind; +// lbValue res = {}; +// res.value = LLVMGetParam(p->value, cast(unsigned)index); +// res.type = abi_type; +// return res; +// } @@ -1165,14 +1165,6 @@ gb_internal lbValue lb_emit_call(lbProcedure *p, lbValue value, Array c return result; } -gb_internal LLVMValueRef llvm_splat_float(i64 count, LLVMTypeRef type, f64 value) { - LLVMValueRef v = LLVMConstReal(type, value); - LLVMValueRef *values = gb_alloc_array(temporary_allocator(), LLVMValueRef, count); - for (i64 i = 0; i < count; i++) { - values[i] = v; - } - return LLVMConstVector(values, cast(unsigned)count); -} gb_internal LLVMValueRef llvm_splat_int(i64 count, LLVMTypeRef type, i64 value, bool is_signed=false) { LLVMValueRef v = LLVMConstInt(type, value, is_signed); LLVMValueRef *values = gb_alloc_array(temporary_allocator(), LLVMValueRef, count); diff --git a/src/llvm_backend_stmt.cpp b/src/llvm_backend_stmt.cpp index 66c422071..6400a8a9d 100644 --- a/src/llvm_backend_stmt.cpp +++ b/src/llvm_backend_stmt.cpp @@ -378,16 +378,6 @@ gb_internal lbValue lb_map_cell_index_static(lbProcedure *p, Type *type, lbValue return lb_emit_ptr_offset(p, elems_ptr, data_index); } -gb_internal void lb_map_kvh_data_static(lbProcedure *p, lbValue map_value, lbValue *ks_, lbValue *vs_, lbValue *hs_) { - lbValue capacity = lb_map_cap(p, map_value); - lbValue ks = lb_map_data_uintptr(p, map_value); - lbValue vs = {}; - lbValue hs = {}; - if (ks_) *ks_ = ks; - if (vs_) *vs_ = vs; - if (hs_) *hs_ = hs; -} - gb_internal lbValue lb_map_hash_is_valid(lbProcedure *p, lbValue hash) { // N :: size_of(uintptr)*8 - 1 // (hash != 0) & (hash>>N == 0) diff --git a/src/llvm_backend_utility.cpp b/src/llvm_backend_utility.cpp index 94b900278..dbed32b82 100644 --- a/src/llvm_backend_utility.cpp +++ b/src/llvm_backend_utility.cpp @@ -599,14 +599,6 @@ gb_internal lbValue lb_emit_reverse_bits(lbProcedure *p, lbValue x, Type *type) } -gb_internal lbValue lb_emit_bit_set_card(lbProcedure *p, lbValue x) { - GB_ASSERT(is_type_bit_set(x.type)); - Type *underlying = bit_set_to_int(x.type); - lbValue card = lb_emit_count_ones(p, x, underlying); - return lb_emit_conv(p, card, t_int); -} - - gb_internal lbValue lb_emit_union_cast_only_ok_check(lbProcedure *p, lbValue value, Type *type, TokenPos pos) { GB_ASSERT(is_type_tuple(type)); lbModule *m = p->module; @@ -1493,10 +1485,6 @@ gb_internal lbValue lb_dynamic_array_cap(lbProcedure *p, lbValue da) { GB_ASSERT(is_type_dynamic_array(da.type)); return lb_emit_struct_ev(p, da, 2); } -gb_internal lbValue lb_dynamic_array_allocator(lbProcedure *p, lbValue da) { - GB_ASSERT(is_type_dynamic_array(da.type)); - return lb_emit_struct_ev(p, da, 3); -} gb_internal lbValue lb_map_len(lbProcedure *p, lbValue value) { GB_ASSERT_MSG(is_type_map(value.type) || are_types_identical(value.type, t_raw_map), "%s", type_to_string(value.type)); diff --git a/src/main.cpp b/src/main.cpp index 614130bb6..c7250aa8b 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -3,7 +3,14 @@ #include "common.cpp" #include "timings.cpp" #include "tokenizer.cpp" +#if defined(GB_SYSTEM_WINDOWS) + #pragma warning(push) + #pragma warning(disable: 4505) +#endif #include "big_int.cpp" +#if defined(GB_SYSTEM_WINDOWS) + #pragma warning(pop) +#endif #include "exact_value.cpp" #include "build_settings.cpp" @@ -58,7 +65,6 @@ gb_global Timings global_timings = {0}; #endif #endif -#include "query_data.cpp" #include "bug_report.cpp" // NOTE(bill): 'name' is used in debugging and profiling modes @@ -573,7 +579,6 @@ gb_internal void usage(String argv0) { print_usage_line(1, " one must contain the program's entry point, all must be in the same package."); print_usage_line(1, "run same as 'build', but also then runs the newly compiled executable."); print_usage_line(1, "check parse, and type check a directory of .odin files"); - print_usage_line(1, "query parse, type check, and output a .json file containing information about the program"); print_usage_line(1, "strip-semicolon parse, type check, and remove unneeded semicolons from the entire program"); print_usage_line(1, "test build and runs procedures with the attribute @(test) in the initial package"); print_usage_line(1, "doc generate documentation on a directory of .odin files"); @@ -817,12 +822,6 @@ gb_internal bool parse_build_flags(Array args) { add_flag(&build_flags, BuildFlag_UseStaticMapCalls, str_lit("use-static-map-calls"), BuildFlagParam_None, Command__does_check); - - add_flag(&build_flags, BuildFlag_Compact, str_lit("compact"), BuildFlagParam_None, Command_query); - add_flag(&build_flags, BuildFlag_GlobalDefinitions, str_lit("global-definitions"), BuildFlagParam_None, Command_query); - add_flag(&build_flags, BuildFlag_GoToDefinitions, str_lit("go-to-definitions"), BuildFlagParam_None, Command_query); - - add_flag(&build_flags, BuildFlag_Short, str_lit("short"), BuildFlagParam_None, Command_doc); add_flag(&build_flags, BuildFlag_AllPackages, str_lit("all-packages"), BuildFlagParam_None, Command_doc); add_flag(&build_flags, BuildFlag_DocFormat, str_lit("doc-format"), BuildFlagParam_None, Command_doc); @@ -1445,39 +1444,6 @@ gb_internal bool parse_build_flags(Array args) { build_context.strict_style_init_only = true; break; } - case BuildFlag_Compact: { - if (!build_context.query_data_set_settings.ok) { - gb_printf_err("Invalid use of -compact flag, only allowed with 'odin query'\n"); - bad_flags = true; - } else { - build_context.query_data_set_settings.compact = true; - } - break; - } - case BuildFlag_GlobalDefinitions: { - if (!build_context.query_data_set_settings.ok) { - gb_printf_err("Invalid use of -global-definitions flag, only allowed with 'odin query'\n"); - bad_flags = true; - } else if (build_context.query_data_set_settings.kind != QueryDataSet_Invalid) { - gb_printf_err("Invalid use of -global-definitions flag, a previous flag for 'odin query' was set\n"); - bad_flags = true; - } else { - build_context.query_data_set_settings.kind = QueryDataSet_GlobalDefinitions; - } - break; - } - case BuildFlag_GoToDefinitions: { - if (!build_context.query_data_set_settings.ok) { - gb_printf_err("Invalid use of -go-to-definitions flag, only allowed with 'odin query'\n"); - bad_flags = true; - } else if (build_context.query_data_set_settings.kind != QueryDataSet_Invalid) { - gb_printf_err("Invalid use of -global-definitions flag, a previous flag for 'odin query' was set\n"); - bad_flags = true; - } else { - build_context.query_data_set_settings.kind = QueryDataSet_GoToDefinitions; - } - break; - } case BuildFlag_Short: build_context.cmd_doc_flags |= CmdDocFlag_Short; break; @@ -1638,16 +1604,6 @@ gb_internal bool parse_build_flags(Array args) { gb_printf_err("`-export-timings:` requires `-show-timings` or `-show-more-timings` to be present\n"); bad_flags = true; } - - if (build_context.query_data_set_settings.ok) { - if (build_context.query_data_set_settings.kind == QueryDataSet_Invalid) { - gb_printf_err("'odin query' requires a flag determining the kind of query data set to be returned\n"); - gb_printf_err("\t-global-definitions : outputs a JSON file of global definitions\n"); - gb_printf_err("\t-go-to-definitions : outputs a OGTD binary file of go to definitions for identifiers within an Odin project\n"); - bad_flags = true; - } - } - return !bad_flags; } @@ -1931,8 +1887,6 @@ gb_internal void print_show_help(String const arg0, String const &command) { print_usage_line(3, "odin check filename.odin -file # Type check single-file package, must contain entry point."); } else if (command == "test") { print_usage_line(1, "test Build ands runs procedures with the attribute @(test) in the initial package"); - } else if (command == "query") { - print_usage_line(1, "query [experimental] Parse, type check, and output a .json file containing information about the program"); } else if (command == "doc") { print_usage_line(1, "doc generate documentation from a directory of .odin files"); print_usage_line(2, "Examples:"); @@ -2627,15 +2581,6 @@ int main(int arg_count, char const **arg_ptr) { build_context.command_kind = Command_strip_semicolon; build_context.no_output_files = true; init_filename = args[2]; - } else if (command == "query") { - if (args.count < 3) { - usage(args[0]); - return 1; - } - build_context.command_kind = Command_query; - build_context.no_output_files = true; - build_context.query_data_set_settings.ok = true; - init_filename = args[2]; } else if (command == "doc") { if (args.count < 3) { usage(args[0]); @@ -2824,12 +2769,8 @@ int main(int arg_count, char const **arg_ptr) { print_show_unused(checker); } - if (build_context.query_data_set_settings.ok) { - generate_and_print_query_data(checker, &global_timings); - } else { - if (build_context.show_timings) { - show_timings(checker, &global_timings); - } + if (build_context.show_timings) { + show_timings(checker, &global_timings); } if (global_error_collector.count != 0) { diff --git a/src/parser.cpp b/src/parser.cpp index 1606f5b47..2ccdac7fa 100644 --- a/src/parser.cpp +++ b/src/parser.cpp @@ -237,9 +237,6 @@ gb_internal Ast *clone_ast(Ast *node) { case Ast_ExprStmt: n->ExprStmt.expr = clone_ast(n->ExprStmt.expr); break; - case Ast_TagStmt: - n->TagStmt.stmt = clone_ast(n->TagStmt.stmt); - break; case Ast_AssignStmt: n->AssignStmt.lhs = clone_ast_array(n->AssignStmt.lhs); n->AssignStmt.rhs = clone_ast_array(n->AssignStmt.rhs); @@ -497,14 +494,6 @@ gb_internal Ast *ast_tag_expr(AstFile *f, Token token, Token name, Ast *expr) { return result; } -gb_internal Ast *ast_tag_stmt(AstFile *f, Token token, Token name, Ast *stmt) { - Ast *result = alloc_ast_node(f, Ast_TagStmt); - result->TagStmt.token = token; - result->TagStmt.name = name; - result->TagStmt.stmt = stmt; - return result; -} - gb_internal Ast *ast_unary_expr(AstFile *f, Token op, Ast *expr) { Ast *result = alloc_ast_node(f, Ast_UnaryExpr); result->UnaryExpr.op = op; @@ -1308,16 +1297,6 @@ gb_internal Token advance_token(AstFile *f) { return prev; } -gb_internal bool peek_token_kind(AstFile *f, TokenKind kind) { - for (isize i = f->curr_token_index+1; i < f->tokens.count; i++) { - Token tok = f->tokens[i]; - if (kind != Token_Comment && tok.kind == Token_Comment) { - continue; - } - return tok.kind == kind; - } - return false; -} gb_internal Token peek_token(AstFile *f) { for (isize i = f->curr_token_index+1; i < f->tokens.count; i++) { @@ -1440,17 +1419,6 @@ gb_internal Token expect_operator(AstFile *f) { return prev; } -gb_internal Token expect_keyword(AstFile *f) { - Token prev = f->curr_token; - if (!gb_is_between(prev.kind, Token__KeywordBegin+1, Token__KeywordEnd-1)) { - String p = token_to_string(prev); - syntax_error(f->curr_token, "Expected a keyword, got '%.*s'", - LIT(p)); - } - advance_token(f); - return prev; -} - gb_internal bool allow_token(AstFile *f, TokenKind kind) { Token prev = f->curr_token; if (prev.kind == kind) { @@ -1957,10 +1925,6 @@ gb_internal bool ast_on_same_line(Token const &x, Ast *yp) { return x.pos.line == y.pos.line; } -gb_internal bool ast_on_same_line(Ast *x, Ast *y) { - return ast_on_same_line(ast_token(x), y); -} - gb_internal Ast *parse_force_inlining_operand(AstFile *f, Token token) { Ast *expr = parse_unary_expr(f, false); Ast *e = strip_or_return_expr(expr); diff --git a/src/parser.hpp b/src/parser.hpp index a2d2c038e..f7b3e51ae 100644 --- a/src/parser.hpp +++ b/src/parser.hpp @@ -457,11 +457,6 @@ AST_KIND(_StmtBegin, "", bool) \ AST_KIND(BadStmt, "bad statement", struct { Token begin, end; }) \ AST_KIND(EmptyStmt, "empty statement", struct { Token token; }) \ AST_KIND(ExprStmt, "expression statement", struct { Ast *expr; } ) \ - AST_KIND(TagStmt, "tag statement", struct { \ - Token token; \ - Token name; \ - Ast * stmt; \ - }) \ AST_KIND(AssignStmt, "assign statement", struct { \ Token op; \ Slice lhs, rhs; \ diff --git a/src/parser_pos.cpp b/src/parser_pos.cpp index 19a525e2e..fb7f0c9c2 100644 --- a/src/parser_pos.cpp +++ b/src/parser_pos.cpp @@ -53,7 +53,6 @@ gb_internal Token ast_token(Ast *node) { case Ast_BadStmt: return node->BadStmt.begin; case Ast_EmptyStmt: return node->EmptyStmt.token; case Ast_ExprStmt: return ast_token(node->ExprStmt.expr); - case Ast_TagStmt: return node->TagStmt.token; case Ast_AssignStmt: return node->AssignStmt.op; case Ast_BlockStmt: return node->BlockStmt.open; case Ast_IfStmt: return node->IfStmt.token; @@ -197,7 +196,6 @@ Token ast_end_token(Ast *node) { case Ast_BadStmt: return node->BadStmt.end; case Ast_EmptyStmt: return node->EmptyStmt.token; case Ast_ExprStmt: return ast_end_token(node->ExprStmt.expr); - case Ast_TagStmt: return ast_end_token(node->TagStmt.stmt); case Ast_AssignStmt: if (node->AssignStmt.rhs.count > 0) { return ast_end_token(node->AssignStmt.rhs[node->AssignStmt.rhs.count-1]); diff --git a/src/query_data.cpp b/src/query_data.cpp deleted file mode 100644 index 86487a058..000000000 --- a/src/query_data.cpp +++ /dev/null @@ -1,1030 +0,0 @@ -struct QueryValue; -struct QueryValuePair; - -gb_global gbAllocator query_value_allocator = {}; - -enum QueryKind { - Query_Invalid, - Query_String, - Query_Boolean, - Query_Integer, - Query_Float, - Query_Array, - Query_Map, -}; - -struct QueryValuePair { - String key; - QueryValue *value; -}; - - -struct QueryValue { - QueryKind kind; - bool packed; -}; - -struct QueryValueString : QueryValue { - QueryValueString(String const &v) { - kind = Query_String; - value = v; - packed = false; - } - String value; -}; - -struct QueryValueBoolean : QueryValue { - QueryValueBoolean(bool v) { - kind = Query_Boolean; - value = v; - packed = false; - } - bool value; -}; - -struct QueryValueInteger : QueryValue { - QueryValueInteger(i64 v) { - kind = Query_Integer; - value = v; - packed = false; - } - i64 value; -}; - -struct QueryValueFloat : QueryValue { - QueryValueFloat(f64 v) { - kind = Query_Float; - value = v; - packed = false; - } - f64 value; -}; - -struct QueryValueArray : QueryValue { - QueryValueArray() { - kind = Query_Array; - array_init(&value, query_value_allocator); - packed = false; - } - QueryValueArray(Array const &v) { - kind = Query_Array; - value = v; - packed = false; - } - Array value; - - void reserve(isize cap) { - array_reserve(&value, cap); - } - void add(QueryValue *v) { - array_add(&value, v); - } - void add(char const *v) { - add(make_string_c(cast(char *)v)); - } - void add(String const &v) { - auto val = gb_alloc_item(query_value_allocator, QueryValueString); - *val = QueryValueString(v); - add(val); - } - void add(bool v) { - auto val = gb_alloc_item(query_value_allocator, QueryValueBoolean); - *val = QueryValueBoolean(v); - add(val); - } - void add(i64 v) { - auto val = gb_alloc_item(query_value_allocator, QueryValueInteger); - *val = QueryValueInteger(v); - add(val); - } - void add(f64 v) { - auto val = gb_alloc_item(query_value_allocator, QueryValueFloat); - *val = QueryValueFloat(v); - add(val); - } -}; - -struct QueryValueMap : QueryValue { - QueryValueMap() { - kind = Query_Map; - array_init(&value, query_value_allocator); - packed = false; - } - QueryValueMap(Array const &v) { - kind = Query_Map; - value = v; - packed = false; - } - Array value; - - - void reserve(isize cap) { - array_reserve(&value, cap); - } - void add(char const *k, QueryValue *v) { - add(make_string_c(cast(char *)k), v); - } - void add(String const &k, QueryValue *v) { - QueryValuePair kv = {k, v}; - array_add(&value, kv); - } - - void add(char const *k, String const &v) { - auto val = gb_alloc_item(query_value_allocator, QueryValueString); - *val = QueryValueString(v); - add(k, val); - } - void add(char const *k, char const *v) { - add(k, make_string_c(cast(char *)v)); - } - void add(char const *k, bool v) { - auto val = gb_alloc_item(query_value_allocator, QueryValueBoolean); - *val = QueryValueBoolean(v); - add(k, val); - } - void add(char const *k, i64 v) { - auto val = gb_alloc_item(query_value_allocator, QueryValueInteger); - *val = QueryValueInteger(v); - add(k, val); - } - void add(char const *k, f64 v) { - auto val = gb_alloc_item(query_value_allocator, QueryValueFloat); - *val = QueryValueFloat(v); - add(k, val); - } - void add(String const &k, String const &v) { - auto val = gb_alloc_item(query_value_allocator, QueryValueString); - *val = QueryValueString(v); - add(k, val); - } - void add(String const &k, char const *v) { - add(k, make_string_c(cast(char *)v)); - } - void add(String const &k, bool v) { - auto val = gb_alloc_item(query_value_allocator, QueryValueBoolean); - *val = QueryValueBoolean(v); - add(k, val); - } - void add(String const &k, i64 v) { - auto val = gb_alloc_item(query_value_allocator, QueryValueInteger); - *val = QueryValueInteger(v); - add(k, val); - } - void add(String const &k, f64 v) { - auto val = gb_alloc_item(query_value_allocator, QueryValueFloat); - *val = QueryValueFloat(v); - add(k, val); - } -}; - - -#define DEF_QUERY_PROC(TYPE, VALUETYPE, NAME) TYPE *NAME(VALUETYPE value) { \ - auto v = gb_alloc_item(query_value_allocator, TYPE); \ - *v = TYPE(value); \ - return v; \ -} -#define DEF_QUERY_PROC0(TYPE, NAME) TYPE *NAME() { \ - auto v = gb_alloc_item(query_value_allocator, TYPE); \ - *v = TYPE(); \ - return v; \ -} - -gb_internal DEF_QUERY_PROC(QueryValueString, String const &, query_value_string); -gb_internal DEF_QUERY_PROC(QueryValueBoolean, bool, query_value_boolean); -gb_internal DEF_QUERY_PROC(QueryValueInteger, i64, query_value_integer); -gb_internal DEF_QUERY_PROC(QueryValueFloat, f64, query_value_float); -gb_internal DEF_QUERY_PROC(QueryValueArray, Array const &, query_value_array); -gb_internal DEF_QUERY_PROC(QueryValueMap, Array const &, query_value_map); -gb_internal DEF_QUERY_PROC0(QueryValueArray, query_value_array); -gb_internal DEF_QUERY_PROC0(QueryValueMap, query_value_map); - -gb_internal isize qprintf(bool format, isize indent, char const *fmt, ...) { - if (format) while (indent --> 0) { - gb_printf("\t"); - } - va_list va; - va_start(va, fmt); - isize res = gb_printf_va(fmt, va); - va_end(va); - return res; -} - -gb_internal bool qv_valid_char(u8 c) { - if (c >= 0x80) { - return false; - } - - switch (c) { - case '\"': - case '\n': - case '\r': - case '\t': - case '\v': - case '\f': - return false; - } - - return true; -} - -gb_internal void print_query_data_as_json(QueryValue *value, bool format = true, isize indent = 0) { - if (value == nullptr) { - gb_printf("null"); - return; - } - switch (value->kind) { - case Query_String: { - auto v = cast(QueryValueString *)value; - String name = v->value; - isize extra = 0; - for (isize i = 0; i < name.len; i++) { - u8 c = name[i]; - if (!qv_valid_char(c)) { - extra += 5; - } - } - - if (extra == 0) { - gb_printf("\"%.*s\"", LIT(name)); - return; - } - - char const hex_table[] = "0123456789ABCDEF"; - isize buf_len = name.len + extra + 2 + 1; - - u8 *buf = gb_alloc_array(temporary_allocator(), u8, buf_len); - - isize j = 0; - - for (isize i = 0; i < name.len; i++) { - u8 c = name[i]; - if (qv_valid_char(c)) { - buf[j+0] = c; - j += 1; - } else if (c == '"') { - buf[j+0] = '\\'; - buf[j+1] = '\"'; - j += 2; - } else { - switch (c) { - case '\n': buf[j+0] = '\\'; buf[j+1] = 'n'; j += 2; break; - case '\r': buf[j+0] = '\\'; buf[j+1] = 'r'; j += 2; break; - case '\t': buf[j+0] = '\\'; buf[j+1] = 't'; j += 2; break; - case '\v': buf[j+0] = '\\'; buf[j+1] = 'v'; j += 2; break; - case '\f': - default: - buf[j+0] = '\\'; - buf[j+1] = hex_table[0]; - buf[j+2] = hex_table[0]; - buf[j+3] = hex_table[c >> 4]; - buf[j+4] = hex_table[c & 0x0f]; - j += 5; - break; - } - } - } - - gb_printf("\"%s\"", buf); - return; - } - case Query_Boolean: { - auto v = cast(QueryValueBoolean *)value; - if (v->value) { - gb_printf("true"); - } else { - gb_printf("false"); - } - return; - } - case Query_Integer: { - auto v = cast(QueryValueInteger *)value; - gb_printf("%lld", cast(long long)v->value); - return; - } - case Query_Float: { - auto v = cast(QueryValueFloat *)value; - gb_printf("%f", v->value); - return; - } - case Query_Array: { - auto v = cast(QueryValueArray *)value; - if (v->value.count > 0) { - bool ff = format && !v->packed; - gb_printf("["); - if (ff) gb_printf("\n"); - for_array(i, v->value) { - qprintf(ff, indent+1, ""); - print_query_data_as_json(v->value[i], ff, indent+1); - if (i < v->value.count-1) { - gb_printf(","); - if (!ff && format) { - gb_printf(" "); - } - } - if (ff) gb_printf("\n"); - } - qprintf(ff, indent, "]"); - } else { - gb_printf("[]"); - } - return; - } - case Query_Map: { - auto v = cast(QueryValueMap *)value; - if (v->value.count > 0) { - bool ff = format && !v->packed; - gb_printf("{"); - if (ff) gb_printf("\n"); - for_array(i, v->value) { - auto kv = v->value[i]; - qprintf(ff, indent+1, "\"%.*s\":", LIT(kv.key)); - if (format) gb_printf(" "); - print_query_data_as_json(kv.value, ff, indent+1); - if (i < v->value.count-1) { - gb_printf(","); - if (!ff && format) { - gb_printf(" "); - } - } - if (ff) gb_printf("\n"); - } - qprintf(ff, indent, "}"); - } else { - gb_printf("{}"); - } - return; - } - } -} - - - -gb_internal int query_data_package_compare(void const *a, void const *b) { - AstPackage *x = *cast(AstPackage *const *)a; - AstPackage *y = *cast(AstPackage *const *)b; - - if (x == y) { - return 0; - } - - if (x != nullptr && y != nullptr) { - return string_compare(x->name, y->name); - } else if (x != nullptr && y == nullptr) { - return -1; - } else if (x == nullptr && y != nullptr) { - return +1; - } - return 0; -} - -gb_internal int query_data_definition_compare(void const *a, void const *b) { - Entity *x = *cast(Entity *const *)a; - Entity *y = *cast(Entity *const *)b; - - if (x == y) { - return 0; - } else if (x != nullptr && y == nullptr) { - return -1; - } else if (x == nullptr && y != nullptr) { - return +1; - } - - if (x->pkg != y->pkg) { - i32 res = query_data_package_compare(&x->pkg, &y->pkg); - if (res != 0) { - return res; - } - } - - return string_compare(x->token.string, y->token.string); -} - -gb_internal int entity_name_compare(void const *a, void const *b) { - Entity *x = *cast(Entity *const *)a; - Entity *y = *cast(Entity *const *)b; - if (x == y) { - return 0; - } else if (x != nullptr && y == nullptr) { - return -1; - } else if (x == nullptr && y != nullptr) { - return +1; - } - return string_compare(x->token.string, y->token.string); -} - - -gb_internal void generate_and_print_query_data_global_definitions(Checker *c, Timings *timings); -gb_internal void generate_and_print_query_data_go_to_definitions(Checker *c); - -gb_internal void generate_and_print_query_data(Checker *c, Timings *timings) { - query_value_allocator = heap_allocator(); - switch (build_context.query_data_set_settings.kind) { - case QueryDataSet_GlobalDefinitions: - generate_and_print_query_data_global_definitions(c, timings); - return; - case QueryDataSet_GoToDefinitions: - generate_and_print_query_data_go_to_definitions(c); - return; - } -} - - -gb_internal void generate_and_print_query_data_global_definitions(Checker *c, Timings *timings) { - auto *root = query_value_map(); - - if (global_error_collector.errors.count > 0) { - auto *errors = query_value_array(); - root->add("errors", errors); - for_array(i, global_error_collector.errors) { - String err = string_trim_whitespace(global_error_collector.errors[i]); - errors->add(err); - } - - } - - { // Packages - auto *packages = query_value_array(); - root->add("packages", packages); - - auto sorted_packages = array_make(query_value_allocator, 0, c->info.packages.entries.count); - defer (array_free(&sorted_packages)); - - for (auto const &entry : c->info.packages) { - AstPackage *pkg = entry.value; - if (pkg != nullptr) { - array_add(&sorted_packages, pkg); - } - } - gb_sort_array(sorted_packages.data, sorted_packages.count, query_data_package_compare); - packages->reserve(sorted_packages.count); - - for_array(i, sorted_packages) { - AstPackage *pkg = sorted_packages[i]; - String name = pkg->name; - String fullpath = pkg->fullpath; - - auto *files = query_value_array(); - files->reserve(pkg->files.count); - for_array(j, pkg->files) { - AstFile *f = pkg->files[j]; - files->add(f->fullpath); - } - - auto *package = query_value_map(); - package->reserve(3); - packages->add(package); - - package->add("name", pkg->name); - package->add("fullpath", pkg->fullpath); - package->add("files", files); - } - } - - if (c->info.definitions.count > 0) { - auto *definitions = query_value_array(); - root->add("definitions", definitions); - - auto sorted_definitions = array_make(query_value_allocator, 0, c->info.definitions.count); - defer (array_free(&sorted_definitions)); - - for_array(i, c->info.definitions) { - Entity *e = c->info.definitions[i]; - String name = e->token.string; - if (is_blank_ident(name)) { - continue; - } - if ((e->scope->flags & (ScopeFlag_Pkg|ScopeFlag_File)) == 0) { - continue; - } - if (e->parent_proc_decl != nullptr) { - continue; - } - switch (e->kind) { - case Entity_Builtin: - case Entity_Nil: - case Entity_Label: - continue; - } - if (e->pkg == nullptr) { - continue; - } - if (e->token.pos.line == 0) { - continue; - } - if (e->kind == Entity_Procedure) { - Type *t = base_type(e->type); - if (t->kind != Type_Proc) { - continue; - } - if (t->Proc.is_poly_specialized) { - continue; - } - } - if (e->kind == Entity_TypeName) { - Type *t = base_type(e->type); - if (t->kind == Type_Struct) { - if (t->Struct.is_poly_specialized) { - continue; - } - } - if (t->kind == Type_Union) { - if (t->Union.is_poly_specialized) { - continue; - } - } - } - - array_add(&sorted_definitions, e); - } - - gb_sort_array(sorted_definitions.data, sorted_definitions.count, query_data_definition_compare); - definitions->reserve(sorted_definitions.count); - - for_array(i, sorted_definitions) { - Entity *e = sorted_definitions[i]; - String name = e->token.string; - - auto *def = query_value_map(); - def->reserve(16); - definitions->add(def); - - def->add("package", e->pkg->name); - def->add("name", name); - def->add("filepath", get_file_path_string(e->token.pos.file_id)); - def->add("line", cast(i64)e->token.pos.line); - def->add("column", cast(i64)e->token.pos.column); - def->add("file_offset", cast(i64)e->token.pos.offset); - - switch (e->kind) { - case Entity_Constant: def->add("kind", str_lit("constant")); break; - case Entity_Variable: def->add("kind", str_lit("variable")); break; - case Entity_TypeName: def->add("kind", str_lit("type name")); break; - case Entity_Procedure: def->add("kind", str_lit("procedure")); break; - case Entity_ProcGroup: def->add("kind", str_lit("procedure group")); break; - case Entity_ImportName: def->add("kind", str_lit("import name")); break; - case Entity_LibraryName: def->add("kind", str_lit("library name")); break; - default: GB_PANIC("Invalid entity kind to be added"); - } - - - if (e->type != nullptr && e->type != t_invalid) { - Type *t = e->type; - Type *bt = t; - - switch (e->kind) { - case Entity_TypeName: - if (!e->TypeName.is_type_alias) { - bt = base_type(t); - } - break; - } - - { - gbString str = type_to_string(t); - String type_str = make_string(cast(u8 *)str, gb_string_length(str)); - def->add("type", type_str); - } - if (t != bt) { - gbString str = type_to_string(bt); - String type_str = make_string(cast(u8 *)str, gb_string_length(str)); - def->add("base_type", type_str); - } - { - String type_kind = {}; - Type *bt = base_type(t); - switch (bt->kind) { - case Type_Pointer: type_kind = str_lit("pointer"); break; - case Type_Array: type_kind = str_lit("array"); break; - case Type_Slice: type_kind = str_lit("slice"); break; - case Type_DynamicArray: type_kind = str_lit("dynamic array"); break; - case Type_Map: type_kind = str_lit("map"); break; - case Type_Struct: type_kind = str_lit("struct"); break; - case Type_Union: type_kind = str_lit("union"); break; - case Type_Enum: type_kind = str_lit("enum"); break; - case Type_Proc: type_kind = str_lit("procedure"); break; - case Type_BitSet: type_kind = str_lit("bit set"); break; - case Type_SimdVector: type_kind = str_lit("simd vector"); break; - - case Type_Generic: - case Type_Tuple: - GB_PANIC("Invalid definition type"); - break; - } - if (type_kind.len > 0) { - def->add("type_kind", type_kind); - } - } - } - - if (e->kind == Entity_TypeName) { - def->add("size", type_size_of(e->type)); - def->add("align", type_align_of(e->type)); - - - if (is_type_struct(e->type)) { - auto *data = query_value_map(); - data->reserve(6); - - def->add("data", data); - - Type *t = base_type(e->type); - GB_ASSERT(t->kind == Type_Struct); - - if (t->Struct.is_polymorphic) { - data->add("polymorphic", cast(bool)t->Struct.is_polymorphic); - } - if (t->Struct.is_poly_specialized) { - data->add("polymorphic_specialized", cast(bool)t->Struct.is_poly_specialized); - } - if (t->Struct.is_packed) { - data->add("packed", cast(bool)t->Struct.is_packed); - } - if (t->Struct.is_raw_union) { - data->add("raw_union", cast(bool)t->Struct.is_raw_union); - } - - auto *fields = query_value_array(); - data->add("fields", fields); - fields->reserve(t->Struct.fields.count); - fields->packed = true; - - for_array(j, t->Struct.fields) { - Entity *e = t->Struct.fields[j]; - String name = e->token.string; - if (is_blank_ident(name)) { - continue; - } - - fields->add(name); - } - } else if (is_type_union(e->type)) { - auto *data = query_value_map(); - data->reserve(4); - - def->add("data", data); - Type *t = base_type(e->type); - GB_ASSERT(t->kind == Type_Union); - - if (t->Union.is_polymorphic) { - data->add("polymorphic", cast(bool)t->Union.is_polymorphic); - } - if (t->Union.is_poly_specialized) { - data->add("polymorphic_specialized", cast(bool)t->Union.is_poly_specialized); - } - - auto *variants = query_value_array(); - variants->reserve(t->Union.variants.count); - data->add("variants", variants); - - for_array(j, t->Union.variants) { - Type *vt = t->Union.variants[j]; - - gbString str = type_to_string(vt); - String type_str = make_string(cast(u8 *)str, gb_string_length(str)); - variants->add(type_str); - } - } - } - - if (e->kind == Entity_Procedure) { - Type *t = base_type(e->type); - GB_ASSERT(t->kind == Type_Proc); - - bool is_polymorphic = t->Proc.is_polymorphic; - bool is_poly_specialized = t->Proc.is_poly_specialized; - bool ok = is_polymorphic || is_poly_specialized; - if (ok) { - auto *data = query_value_map(); - data->reserve(4); - - def->add("data", data); - if (is_polymorphic) { - data->add("polymorphic", cast(bool)is_polymorphic); - } - if (is_poly_specialized) { - data->add("polymorphic_specialized", cast(bool)is_poly_specialized); - } - } - } - - if (e->kind == Entity_ProcGroup) { - auto *procedures = query_value_array(); - procedures->reserve(e->ProcGroup.entities.count); - - for_array(j, e->ProcGroup.entities) { - Entity *p = e->ProcGroup.entities[j]; - - auto *procedure = query_value_map(); - procedure->reserve(2); - procedure->packed = true; - - procedures->add(procedure); - - procedure->add("package", p->pkg->name); - procedure->add("name", p->token.string); - } - def->add("procedures", procedures); - } - - DeclInfo *di = e->decl_info; - if (di != nullptr) { - if (di->is_using) { - def->add("using", query_value_boolean(true)); - } - } - } - } - - if (build_context.show_timings) { - Timings *t = timings; - timings__stop_current_section(t); - t->total.finish = time_stamp_time_now(); - isize max_len = gb_min(36, t->total.label.len); - for_array(i, t->sections) { - TimeStamp ts = t->sections[i]; - max_len = gb_max(max_len, ts.label.len); - } - t->total_time_seconds = time_stamp_as_s(t->total, t->freq); - - auto *tims = query_value_map(); - tims->reserve(8); - root->add("timings", tims); - tims->add("time_unit", str_lit("s")); - - tims->add(t->total.label, cast(f64)t->total_time_seconds); - - - Parser *p = c->parser; - if (p != nullptr) { - isize lines = p->total_line_count; - isize tokens = p->total_token_count; - isize files = 0; - isize packages = p->packages.count; - isize total_file_size = 0; - for_array(i, p->packages) { - files += p->packages[i]->files.count; - for_array(j, p->packages[i]->files) { - AstFile *file = p->packages[i]->files[j]; - total_file_size += file->tokenizer.end - file->tokenizer.start; - } - } - - tims->add("total_lines", cast(i64)lines); - tims->add("total_tokens", cast(i64)tokens); - tims->add("total_files", cast(i64)files); - tims->add("total_packages", cast(i64)packages); - tims->add("total_file_size", cast(i64)total_file_size); - - auto *sections = query_value_map(); - sections->reserve(t->sections.count); - tims->add("sections", sections); - for_array(i, t->sections) { - TimeStamp ts = t->sections[i]; - f64 section_time = time_stamp_as_s(ts, t->freq); - - auto *section = query_value_map(); - section->reserve(2); - sections->add(ts.label, section); - section->add("time", cast(f64)section_time); - section->add("total_fraction", cast(f64)(section_time/t->total_time_seconds)); - } - } - } - - - print_query_data_as_json(root, !build_context.query_data_set_settings.compact); - gb_printf("\n"); -} - - - -template -struct BinaryArray { - u32 offset; // Offset in bytes from the top of the file - u32 length; // Number of elements in array of type T -}; - -template -gb_internal Array binary_array_from_data(BinaryArray ba, void *data) { - Array res = {}; - res.data = cast(T *)(cast(u8 *)data + ba.offset); - res.count = ba.length; - res.capacity = ba.length; - return res; -} - -typedef BinaryArray BinaryString; - -struct GoToDefIdent { - u64 use_offset; // offset of identifier use in bytes from the start of the file that contains it - u32 len; // length in bytes of the identifier - u32 def_file_id; - u64 def_offset; // offset of entity definition in bytes from the start of the file that contains it -}; - -struct GoToDefFile { - u32 id; - BinaryString path; - BinaryArray idents; -}; - -struct GoToDefHeader { - u8 magic[4]; // ogtd (odin-go-to-definitions) - u32 version; // 1 - BinaryArray files; -}; - -struct GoToDefFileMap { - AstFile *f; - u32 id; - Array idents; -}; - - -gb_internal int go_to_def_file_map_compare(void const *a, void const *b) { - GoToDefFileMap const *x = cast(GoToDefFileMap const *)a; - GoToDefFileMap const *y = cast(GoToDefFileMap const *)b; - if (x == y) { - return 0; - } else if (x != nullptr && y == nullptr) { - return -1; - } else if (x == nullptr && y != nullptr) { - return +1; - } - if (x->f->id < y->f->id) { - return -1; - } else if (x->f->id > y->f->id) { - return +1; - } - return 0; -} - -gb_internal int quick_ident_compare(void const *a, void const *b) { - Ast *x = *cast(Ast **)a; - Ast *y = *cast(Ast **)b; - - // NOTE(bill): This assumes that the file is same - if (x->Ident.token.pos.offset < y->Ident.token.pos.offset) { - return -1; - } else if (x->Ident.token.pos.offset > y->Ident.token.pos.offset) { - return +1; - } - return 0; -} - - -gb_internal void generate_and_print_query_data_go_to_definitions(Checker *c) { - GB_ASSERT(c->info.allow_identifier_uses); - - gbAllocator a = query_value_allocator; - - isize file_path_memory_needed = 0; - auto files = array_make(a, 0, c->info.files.entries.count); - for (auto const &entry : c->info.files) { - AstFile *f = entry.value; - file_path_memory_needed += f->fullpath.len+1; // add NUL terminator - - - GoToDefFileMap x = {}; - x.f = f; - array_init(&x.idents, a); - array_add(&files, x); - } - gb_sort_array(files.data, files.count, go_to_def_file_map_compare); - - auto file_id_map_to_index = array_make(a, files[files.count-1].f->id + 1); - for_array(i, file_id_map_to_index) { - file_id_map_to_index[i] = -1; - } - for_array(i, files) { - file_id_map_to_index[files[i].f->id] = i; - } - - - - for_array(i, c->info.identifier_uses) { - Ast *ast = c->info.identifier_uses[i]; - GB_ASSERT(ast->kind == Ast_Ident); - TokenPos pos = ast->Ident.token.pos; - Entity *e = ast->Ident.entity; - if (e == nullptr) { - continue; - } - - - AstFile **use_file_found = string_map_get(&c->info.files, get_file_path_string(pos.file_id)); - GB_ASSERT(use_file_found != nullptr); - AstFile *use_file = *use_file_found; - GB_ASSERT(use_file != nullptr); - - if (e->scope == nullptr) { - GB_ASSERT(e->flags & EntityFlag_Field); - continue; - } - if (e->scope->flags & ScopeFlag_Global) { - continue; - } - - isize idx = file_id_map_to_index[use_file->id]; - if (idx >= 0) { - array_add(&files[idx].idents, ast); - } else { - // TODO(bill): Handle invalid map case? - } - } - - for_array(i, files) { - GoToDefFileMap *f = &files[i]; - gb_sort_array(f->idents.data, f->idents.count, quick_ident_compare); - // gb_printf_err("%lld %.*s -> %lld\n", f->f->id, LIT(f->f->fullpath), f->idents.count); - } - - - - isize data_min_size = 0; - - u32 header_offset = cast(u32)data_min_size; gb_unused(header_offset); - data_min_size += gb_size_of(GoToDefHeader); - data_min_size = align_formula_isize(data_min_size, 8); - - u32 file_offset = cast(u32)data_min_size; - data_min_size += gb_size_of(GoToDefFile) * files.count; - data_min_size = align_formula_isize(data_min_size, 8); - - u32 file_path_offset = cast(u32)data_min_size; - data_min_size += file_path_memory_needed; - data_min_size = align_formula_isize(data_min_size, 8); - - u32 idents_offset = cast(u32)data_min_size; - data_min_size += gb_size_of(GoToDefIdent) * c->info.identifier_uses.count; - - - auto data = array_make(a, 0, data_min_size); - defer (array_free(&data)); - - GoToDefHeader header = {}; - gb_memmove(header.magic, "ogtd", 4); - header.version = 1; - header.files.length = cast(u32)files.count; - header.files.offset = file_offset; - - array_add_elems(&data, cast(u8 *)&header, gb_size_of(header)); - - array_resize(&data, data_min_size); - - auto binary_files = binary_array_from_data(header.files, data.data); - - u32 file_path_offset_index = file_path_offset; - u32 idents_offset_index = idents_offset; - for_array(i, files) { - GoToDefFileMap *f_map = &files[i]; - AstFile *f = f_map->f; - binary_files[i].id = cast(u32)f->id; - - binary_files[i].path.offset = file_path_offset_index; - binary_files[i].path.length = cast(u32)f->fullpath.len; - - binary_files[i].idents.offset = idents_offset_index; - binary_files[i].idents.length = cast(u32)f_map->idents.count; - - auto path = binary_array_from_data(binary_files[i].path, data.data); - gb_memmove(path.data, f->fullpath.text, f->fullpath.len); - path.data[f->fullpath.len] = 0; - - - auto idents = binary_array_from_data(binary_files[i].idents, data.data); - for_array(j, f_map->idents) { - Ast *ast = f_map->idents[j]; - GB_ASSERT(ast->kind == Ast_Ident); - - Entity *e = ast->Ident.entity; - TokenPos def = e->token.pos; - AstFile *def_file = e->file; - - if (def_file == nullptr) { - auto *def_file_found = string_map_get(&c->info.files, get_file_path_string(e->token.pos.file_id)); - if (def_file_found == nullptr) { - continue; - } - def_file = *def_file_found; - } - - isize file_index = file_id_map_to_index[def_file->id]; - GB_ASSERT(file_index >= 0); - - idents[j].use_offset = cast(u64)ast->Ident.token.pos.offset; - idents[j].len = cast(u32)ast->Ident.token.string.len; - idents[j].def_file_id = cast(u32)def_file->id; - idents[j].def_offset = cast(u64)e->token.pos.offset; - - // gb_printf_err("%llu %llu %llu %llu\n", idents[j].len, idents[j].use_offset, idents[j].def_file_id, idents[j].def_offset); - } - - file_path_offset_index += cast(u32)(f->fullpath.len + 1); - idents_offset_index += cast(u32)(f_map->idents.count * gb_size_of(GoToDefIdent)); - } - - - gb_file_write(gb_file_get_standard(gbFileStandard_Output), data.data, data.count*gb_size_of(*data.data)); -} - diff --git a/src/range_cache.cpp b/src/range_cache.cpp index 1f98c4b9e..fc85e2a2e 100644 --- a/src/range_cache.cpp +++ b/src/range_cache.cpp @@ -59,12 +59,12 @@ gb_internal bool range_cache_add_range(RangeCache *c, i64 lo, i64 hi) { } -gb_internal bool range_cache_index_exists(RangeCache *c, i64 index) { - for_array(i, c->ranges) { - RangeValue v = c->ranges[i]; - if (v.lo <= index && index <= v.hi) { - return true; - } - } - return false; -} +// gb_internal bool range_cache_index_exists(RangeCache *c, i64 index) { +// for_array(i, c->ranges) { +// RangeValue v = c->ranges[i]; +// if (v.lo <= index && index <= v.hi) { +// return true; +// } +// } +// return false; +// } diff --git a/src/string.cpp b/src/string.cpp index aeb31c7b0..8cce0f1ef 100644 --- a/src/string.cpp +++ b/src/string.cpp @@ -89,14 +89,6 @@ gb_internal char *alloc_cstring(gbAllocator a, String s) { return c_str; } -gb_internal char *cstring_duplicate(gbAllocator a, char const *s) { - isize len = gb_strlen(s); - char *c_str = gb_alloc_array(a, char, len+1); - gb_memmove(c_str, s, len); - c_str[len] = '\0'; - return c_str; -} - gb_internal gb_inline bool str_eq_ignore_case(String const &a, String const &b) { @@ -166,12 +158,6 @@ gb_internal isize string_index_byte(String const &s, u8 x) { return -1; } -gb_internal GB_COMPARE_PROC(string_cmp_proc) { - String x = *(String *)a; - String y = *(String *)b; - return string_compare(x, y); -} - gb_internal gb_inline bool str_eq(String const &a, String const &b) { if (a.len != b.len) return false; return memcmp(a.text, b.text, a.len) == 0; diff --git a/src/string_map.cpp b/src/string_map.cpp index e289d4c9b..9f9374ece 100644 --- a/src/string_map.cpp +++ b/src/string_map.cpp @@ -18,8 +18,6 @@ gb_internal gb_inline bool string_hash_key_equal(StringHashKey const &a, StringH } return false; } -gb_internal bool operator==(StringHashKey const &a, StringHashKey const &b) { return string_hash_key_equal(a, b); } -gb_internal bool operator!=(StringHashKey const &a, StringHashKey const &b) { return !string_hash_key_equal(a, b); } template struct StringMapEntry { diff --git a/src/threading.cpp b/src/threading.cpp index 511d1b477..b74d087b4 100644 --- a/src/threading.cpp +++ b/src/threading.cpp @@ -1,6 +1,10 @@ #if defined(GB_SYSTEM_LINUX) #include #endif +#if defined(GB_SYSTEM_WINDOWS) + #pragma warning(push) + #pragma warning(disable: 4505) +#endif struct BlockingMutex; struct RecursiveMutex; @@ -269,48 +273,6 @@ struct MutexGuard { } #endif - - -struct Barrier { - BlockingMutex mutex; - Condition cond; - isize index; - isize generation_id; - isize thread_count; -}; - -gb_internal void barrier_init(Barrier *b, isize thread_count) { - mutex_init(&b->mutex); - condition_init(&b->cond); - b->index = 0; - b->generation_id = 0; - b->thread_count = 0; -} - -gb_internal void barrier_destroy(Barrier *b) { - condition_destroy(&b->cond); - mutex_destroy(&b->mutex); -} - -// Returns true if it is the leader -gb_internal bool barrier_wait(Barrier *b) { - mutex_lock(&b->mutex); - defer (mutex_unlock(&b->mutex)); - isize local_gen = b->generation_id; - b->index += 1; - if (b->index < b->thread_count) { - while (local_gen == b->generation_id && b->index < b->thread_count) { - condition_wait(&b->cond, &b->mutex); - } - return false; - } - b->index = 0; - b->generation_id += 1; - condition_broadcast(&b->cond); - return true; -} - - gb_internal u32 thread_current_id(void) { @@ -494,3 +456,7 @@ gb_internal void thread_set_name(Thread *t, char const *name) { #endif } + +#if defined(GB_SYSTEM_WINDOWS) + #pragma warning(pop) +#endif \ No newline at end of file diff --git a/src/types.cpp b/src/types.cpp index c8e24f01d..b1d3883c6 100644 --- a/src/types.cpp +++ b/src/types.cpp @@ -430,15 +430,6 @@ gb_internal Selection sub_selection(Selection const &sel, isize offset) { return res; } -gb_internal Selection sub_selection_with_length(Selection const &sel, isize offset, isize len) { - Selection res = {}; - res.index.data = sel.index.data + offset; - res.index.count = gb_max(len, gb_max(sel.index.count - offset, 0)); - res.index.capacity = res.index.count; - return res; -} - - gb_global Type basic_types[] = { {Type_Basic, {Basic_Invalid, 0, 0, STR_LIT("invalid type")}}, @@ -1089,15 +1080,6 @@ gb_internal Type *alloc_type_proc(Scope *scope, Type *params, isize param_count, gb_internal bool is_type_valid_for_keys(Type *t); -gb_internal Type *alloc_type_map(i64 count, Type *key, Type *value) { - if (key != nullptr) { - GB_ASSERT(value != nullptr); - } - Type *t = alloc_type(Type_Map); - t->Map.key = key; - t->Map.value = value; - return t; -} gb_internal Type *alloc_type_bit_set() { Type *t = alloc_type(Type_BitSet); @@ -1152,19 +1134,6 @@ gb_internal bool is_type_named(Type *t) { } return t->kind == Type_Named; } -gb_internal bool is_type_named_alias(Type *t) { - if (!is_type_named(t)) { - return false; - } - Entity *e = t->Named.type_name; - if (e == nullptr) { - return false; - } - if (e->kind != Entity_TypeName) { - return false; - } - return e->TypeName.is_type_alias; -} gb_internal bool is_type_boolean(Type *t) { // t = core_type(t); @@ -1329,27 +1298,6 @@ gb_internal bool is_type_complex_or_quaternion(Type *t) { } return false; } -gb_internal bool is_type_f16(Type *t) { - t = core_type(t); - if (t->kind == Type_Basic) { - return t->Basic.kind == Basic_f16; - } - return false; -} -gb_internal bool is_type_f32(Type *t) { - t = core_type(t); - if (t->kind == Type_Basic) { - return t->Basic.kind == Basic_f32; - } - return false; -} -gb_internal bool is_type_f64(Type *t) { - t = core_type(t); - if (t->kind == Type_Basic) { - return t->Basic.kind == Basic_f64; - } - return false; -} gb_internal bool is_type_pointer(Type *t) { t = base_type(t); if (t->kind == Type_Basic) { @@ -1550,10 +1498,6 @@ gb_internal bool is_type_asm_proc(Type *t) { t = base_type(t); return t->kind == Type_Proc && t->Proc.calling_convention == ProcCC_InlineAsm; } -gb_internal bool is_type_poly_proc(Type *t) { - t = base_type(t); - return t->kind == Type_Proc && t->Proc.is_polymorphic; -} gb_internal bool is_type_simd_vector(Type *t) { t = base_type(t); return t->kind == Type_SimdVector; @@ -1915,11 +1859,6 @@ gb_internal bool is_type_empty_union(Type *t) { t = base_type(t); return t->kind == Type_Union && t->Union.variants.count == 0; } -gb_internal bool is_type_empty_struct(Type *t) { - t = base_type(t); - return t->kind == Type_Struct && !t->Struct.is_raw_union && t->Struct.fields.count == 0; -} - gb_internal bool is_type_valid_for_keys(Type *t) { t = core_type(t); @@ -4051,20 +3990,6 @@ gb_internal Type *reduce_tuple_to_single_type(Type *original_type) { return original_type; } - -gb_internal Type *alloc_type_struct_from_field_types(Type **field_types, isize field_count, bool is_packed) { - Type *t = alloc_type_struct(); - t->Struct.fields = slice_make(heap_allocator(), field_count); - - Scope *scope = nullptr; - for_array(i, t->Struct.fields) { - t->Struct.fields[i] = alloc_entity_field(scope, blank_token, field_types[i], false, cast(i32)i, EntityState_Resolved); - } - t->Struct.is_packed = is_packed; - - return t; -} - gb_internal Type *alloc_type_tuple_from_field_types(Type **field_types, isize field_count, bool is_packed, bool must_be_tuple) { if (field_count == 0) { return nullptr; -- cgit v1.2.3 From a13e2f4578eb5557afb8bc6b21930032bedbbb43 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Mon, 19 Dec 2022 00:29:40 +0000 Subject: Fix minor race condition --- src/checker.cpp | 48 ++++++++++++++++++++++++++++++++++++++---------- src/checker.hpp | 5 +++++ 2 files changed, 43 insertions(+), 10 deletions(-) (limited to 'src/checker.cpp') diff --git a/src/checker.cpp b/src/checker.cpp index f130a965f..7cafcea2e 100644 --- a/src/checker.cpp +++ b/src/checker.cpp @@ -184,6 +184,7 @@ gb_internal void init_decl_info(DeclInfo *d, Scope *scope, DeclInfo *parent) { ptr_set_init(&d->deps, heap_allocator()); ptr_set_init(&d->type_info_deps, heap_allocator()); array_init (&d->labels, heap_allocator()); + mutex_init(&d->proc_checked_mutex); } gb_internal DeclInfo *make_decl_info(Scope *scope, DeclInfo *parent) { @@ -193,6 +194,7 @@ gb_internal DeclInfo *make_decl_info(Scope *scope, DeclInfo *parent) { } // gb_internal void destroy_declaration_info(DeclInfo *d) { +// mutex_destroy(&d->proc_checked_mutex); // ptr_set_destroy(&d->deps); // array_free(&d->labels); // } @@ -1200,30 +1202,51 @@ gb_internal CheckerContext make_checker_context(Checker *c) { ctx.type_path = new_checker_type_path(); ctx.type_level = 0; + mutex_init(&ctx.mutex); return ctx; } gb_internal void destroy_checker_context(CheckerContext *ctx) { + mutex_destroy(&ctx->mutex); destroy_checker_type_path(ctx->type_path); } -gb_internal void add_curr_ast_file(CheckerContext *ctx, AstFile *file) { +gb_internal bool add_curr_ast_file(CheckerContext *ctx, AstFile *file) { if (file != nullptr) { ctx->file = file; ctx->decl = file->pkg->decl_info; ctx->scope = file->scope; ctx->pkg = file->pkg; + return true; } + return false; } gb_internal void reset_checker_context(CheckerContext *ctx, AstFile *file, UntypedExprInfoMap *untyped) { if (ctx == nullptr) { return; } - destroy_checker_context(ctx); + GB_ASSERT(ctx->checker != nullptr); + mutex_lock(&ctx->mutex); + auto *queue = ctx->procs_to_check_queue; - *ctx = make_checker_context(ctx->checker); + auto type_path = ctx->type_path; + array_clear(type_path); + + zero_size(&ctx->pkg, gb_size_of(CheckerContext) - gb_offset_of(CheckerContext, pkg)); + + ctx->file = nullptr; + ctx->scope = builtin_pkg->scope; + ctx->pkg = builtin_pkg; + ctx->decl = nullptr; + + ctx->type_path = type_path; + ctx->type_level = 0; + add_curr_ast_file(ctx, file); + ctx->procs_to_check_queue = queue; ctx->untyped = untyped; + + mutex_unlock(&ctx->mutex); } @@ -5067,11 +5090,14 @@ gb_internal bool check_proc_info(Checker *c, ProcInfo *pi, UntypedExprInfoMap *u return false; } Entity *e = pi->decl->entity; - if (pi->decl->proc_checked) { - if (e != nullptr) { - GB_ASSERT(e->flags & EntityFlag_ProcBodyChecked); + + MUTEX_GUARD_BLOCK(&pi->decl->proc_checked_mutex) { + if (pi->decl->proc_checked) { + if (e != nullptr) { + GB_ASSERT(e->flags & EntityFlag_ProcBodyChecked); + } + return true; } - return true; } CheckerContext ctx = make_checker_context(c); @@ -5128,10 +5154,12 @@ gb_internal bool check_proc_info(Checker *c, ProcInfo *pi, UntypedExprInfoMap *u } check_proc_body(&ctx, pi->token, pi->decl, pi->type, pi->body); - if (e != nullptr) { - e->flags |= EntityFlag_ProcBodyChecked; + MUTEX_GUARD_BLOCK(&pi->decl->proc_checked_mutex) { + if (e != nullptr) { + e->flags |= EntityFlag_ProcBodyChecked; + } + pi->decl->proc_checked = true; } - pi->decl->proc_checked = true; add_untyped_expressions(&c->info, ctx.untyped); return true; } diff --git a/src/checker.hpp b/src/checker.hpp index 58f6a027c..6799503cd 100644 --- a/src/checker.hpp +++ b/src/checker.hpp @@ -158,6 +158,7 @@ struct DeclInfo { bool is_using; bool where_clauses_evaluated; bool proc_checked; + BlockingMutex proc_checked_mutex; isize defer_used; bool defer_use_checked; @@ -377,13 +378,17 @@ struct CheckerInfo { }; struct CheckerContext { + // Order matters here + BlockingMutex mutex; Checker * checker; CheckerInfo * info; + AstPackage * pkg; AstFile * file; Scope * scope; DeclInfo * decl; + // Order doesn't matter after this u32 state_flags; bool in_defer; // TODO(bill): Actually handle correctly Type * type_hint; -- cgit v1.2.3 From 8fc9566a837fbd3fe52f3f1b5e766e122b3c2de2 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Tue, 20 Dec 2022 14:19:55 +0000 Subject: Use `*_set_update` where possible --- src/check_builtin.cpp | 4 +--- src/check_stmt.cpp | 3 +-- src/checker.cpp | 7 ++----- src/parser.cpp | 3 +-- src/string_set.cpp | 52 +++++++++++++++++++++++++-------------------------- src/types.cpp | 2 +- 6 files changed, 32 insertions(+), 39 deletions(-) (limited to 'src/checker.cpp') diff --git a/src/check_builtin.cpp b/src/check_builtin.cpp index 859fbea28..1c13b6b5e 100644 --- a/src/check_builtin.cpp +++ b/src/check_builtin.cpp @@ -3126,13 +3126,11 @@ gb_internal bool check_builtin_procedure(CheckerContext *c, Operand *operand, As } - if (string_set_exists(&name_set, name)) { + if (string_set_update(&name_set, name)) { error(op.expr, "Field argument name '%.*s' already exists", LIT(name)); } else { array_add(&types, arg_type->Slice.elem); array_add(&names, name); - - string_set_add(&name_set, name); } } diff --git a/src/check_stmt.cpp b/src/check_stmt.cpp index 73adbed8b..cf111e84c 100644 --- a/src/check_stmt.cpp +++ b/src/check_stmt.cpp @@ -1237,7 +1237,7 @@ gb_internal void check_type_switch_stmt(CheckerContext *ctx, Ast *node, u32 mod_ GB_PANIC("Unknown type to type switch statement"); } - if (type_ptr_set_exists(&seen, y.type)) { + if (type_ptr_set_update(&seen, y.type)) { TokenPos pos = cc->token.pos; gbString expr_str = expr_to_string(y.expr); error(y.expr, @@ -1248,7 +1248,6 @@ gb_internal void check_type_switch_stmt(CheckerContext *ctx, Ast *node, u32 mod_ gb_string_free(expr_str); break; } - ptr_set_add(&seen, y.type); } } diff --git a/src/checker.cpp b/src/checker.cpp index 7cafcea2e..14a0e5f4c 100644 --- a/src/checker.cpp +++ b/src/checker.cpp @@ -3414,11 +3414,9 @@ gb_internal void check_decl_attributes(CheckerContext *c, Array const &at continue; } - if (string_set_exists(&set, name)) { + if (string_set_update(&set, name)) { error(elem, "Previous declaration of '%.*s'", LIT(name)); continue; - } else { - string_set_add(&set, name); } if (!proc(c, elem, name, value, ac)) { @@ -4969,10 +4967,9 @@ gb_internal Array find_entity_path(Entity *start, Entity *end, PtrSet< Array empty_path = {}; - if (ptr_set_exists(visited, start)) { + if (ptr_set_update(visited, start)) { return empty_path; } - ptr_set_add(visited, start); DeclInfo *decl = start->decl_info; if (decl) { diff --git a/src/parser.cpp b/src/parser.cpp index eb006cb24..ad22ce5ff 100644 --- a/src/parser.cpp +++ b/src/parser.cpp @@ -4967,10 +4967,9 @@ gb_internal AstPackage *try_add_import_path(Parser *p, String const &path, Strin String const FILE_EXT = str_lit(".odin"); MUTEX_GUARD_BLOCK(&p->import_mutex) { - if (string_set_exists(&p->imported_files, path)) { + if (string_set_update(&p->imported_files, path)) { return nullptr; } - string_set_add(&p->imported_files, path); } AstPackage *pkg = gb_alloc_item(permanent_allocator(), AstPackage); diff --git a/src/string_set.cpp b/src/string_set.cpp index fce98ec75..1c97d253e 100644 --- a/src/string_set.cpp +++ b/src/string_set.cpp @@ -10,18 +10,18 @@ struct StringSet { }; -void string_set_init (StringSet *s, gbAllocator a, isize capacity = 16); -void string_set_destroy(StringSet *s); -void string_set_add (StringSet *s, String const &str); -bool string_set_update (StringSet *s, String const &str); // returns true if it previously existed -bool string_set_exists (StringSet *s, String const &str); -void string_set_remove (StringSet *s, String const &str); -void string_set_clear (StringSet *s); -void string_set_grow (StringSet *s); -void string_set_rehash (StringSet *s, isize new_count); - - -gb_inline void string_set_init(StringSet *s, gbAllocator a, isize capacity) { +gb_internal void string_set_init (StringSet *s, gbAllocator a, isize capacity = 16); +gb_internal void string_set_destroy(StringSet *s); +gb_internal void string_set_add (StringSet *s, String const &str); +gb_internal bool string_set_update (StringSet *s, String const &str); // returns true if it previously existed +gb_internal bool string_set_exists (StringSet *s, String const &str); +gb_internal void string_set_remove (StringSet *s, String const &str); +gb_internal void string_set_clear (StringSet *s); +gb_internal void string_set_grow (StringSet *s); +gb_internal void string_set_rehash (StringSet *s, isize new_count); + + +gb_internal gb_inline void string_set_init(StringSet *s, gbAllocator a, isize capacity) { capacity = next_pow2_isize(gb_max(16, capacity)); slice_init(&s->hashes, a, capacity); @@ -31,7 +31,7 @@ gb_inline void string_set_init(StringSet *s, gbAllocator a, isize capacity) { } } -gb_inline void string_set_destroy(StringSet *s) { +gb_internal gb_inline void string_set_destroy(StringSet *s) { slice_free(&s->hashes, s->entries.allocator); array_free(&s->entries); } @@ -82,13 +82,13 @@ gb_internal b32 string_set__full(StringSet *s) { return 0.75f * s->hashes.count <= s->entries.count; } -gb_inline void string_set_grow(StringSet *s) { +gb_internal gb_inline void string_set_grow(StringSet *s) { isize new_count = gb_max(s->hashes.count<<1, 16); string_set_rehash(s, new_count); } -void string_set_reset_entries(StringSet *s) { +gb_internal void string_set_reset_entries(StringSet *s) { for (isize i = 0; i < s->hashes.count; i++) { s->hashes.data[i] = MAP_SENTINEL; } @@ -105,7 +105,7 @@ void string_set_reset_entries(StringSet *s) { } } -void string_set_reserve(StringSet *s, isize cap) { +gb_internal void string_set_reserve(StringSet *s, isize cap) { array_reserve(&s->entries, cap); if (s->entries.count*2 < s->hashes.count) { return; @@ -115,7 +115,7 @@ void string_set_reserve(StringSet *s, isize cap) { } -void string_set_rehash(StringSet *s, isize new_count) { +gb_internal void string_set_rehash(StringSet *s, isize new_count) { string_set_reserve(s, new_count); } @@ -125,7 +125,7 @@ gb_inline bool string_set_exists(StringSet *s, String const &str) { return index != MAP_SENTINEL; } -void string_set_add(StringSet *s, String const &str) { +gb_internal void string_set_add(StringSet *s, String const &str) { MapIndex index; MapFindResult fr; StringHashKey key = string_hash_string(str); @@ -150,7 +150,7 @@ void string_set_add(StringSet *s, String const &str) { } } -bool string_set_update(StringSet *s, String const &str) { +gb_internal bool string_set_update(StringSet *s, String const &str) { bool exists = false; MapIndex index; MapFindResult fr; @@ -179,7 +179,7 @@ bool string_set_update(StringSet *s, String const &str) { } -void string_set__erase(StringSet *s, MapFindResult fr) { +gb_internal void string_set__erase(StringSet *s, MapFindResult fr) { MapFindResult last; if (fr.entry_prev == MAP_SENTINEL) { s->hashes[fr.hash_index] = s->entries[fr.entry_index].next; @@ -201,7 +201,7 @@ void string_set__erase(StringSet *s, MapFindResult fr) { } } -void string_set_remove(StringSet *s, String const &str) { +gb_internal void string_set_remove(StringSet *s, String const &str) { StringHashKey key = string_hash_string(str); MapFindResult fr = string_set__find(s, key); if (fr.entry_index != MAP_SENTINEL) { @@ -209,7 +209,7 @@ void string_set_remove(StringSet *s, String const &str) { } } -gb_inline void string_set_clear(StringSet *s) { +gb_internal gb_inline void string_set_clear(StringSet *s) { array_clear(&s->entries); for_array(i, s->hashes) { s->hashes.data[i] = MAP_SENTINEL; @@ -218,18 +218,18 @@ gb_inline void string_set_clear(StringSet *s) { -StringSetEntry *begin(StringSet &m) { +gb_internal StringSetEntry *begin(StringSet &m) { return m.entries.data; } -StringSetEntry const *begin(StringSet const &m) { +gb_internal StringSetEntry const *begin(StringSet const &m) { return m.entries.data; } -StringSetEntry *end(StringSet &m) { +gb_internal StringSetEntry *end(StringSet &m) { return m.entries.data + m.entries.count; } -StringSetEntry const *end(StringSet const &m) { +gb_internal StringSetEntry const *end(StringSet const &m) { return m.entries.data + m.entries.count; } \ No newline at end of file diff --git a/src/types.cpp b/src/types.cpp index b1d3883c6..890098ad0 100644 --- a/src/types.cpp +++ b/src/types.cpp @@ -812,7 +812,7 @@ gb_internal void init_type_mutex(void) { mutex_init(&g_type_mutex); } -gb_internal bool type_ptr_set_exists(PtrSet *s, Type *t) { +gb_internal bool type_ptr_set_update(PtrSet *s, Type *t) { if (ptr_set_exists(s, t)) { return true; } -- cgit v1.2.3 From e98f1a28e68e82753728f58b3465793192b74f9d Mon Sep 17 00:00:00 2001 From: gingerBill Date: Thu, 22 Dec 2022 11:53:13 +0000 Subject: Change `tav` to be a pointer internally --- src/check_expr.cpp | 68 ++++++++++++++++++++++---------------------- src/check_stmt.cpp | 10 +++---- src/check_type.cpp | 4 +-- src/checker.cpp | 22 +++++++------- src/llvm_backend_const.cpp | 56 ++++++++++++++++++------------------ src/llvm_backend_expr.cpp | 32 ++++++++++----------- src/llvm_backend_proc.cpp | 20 ++++++------- src/llvm_backend_stmt.cpp | 34 +++++++++++----------- src/llvm_backend_utility.cpp | 12 ++++---- src/parser.cpp | 8 ++++-- src/parser.hpp | 7 +++-- 11 files changed, 140 insertions(+), 133 deletions(-) (limited to 'src/checker.cpp') diff --git a/src/check_expr.cpp b/src/check_expr.cpp index ed1ddd1f1..654dec051 100644 --- a/src/check_expr.cpp +++ b/src/check_expr.cpp @@ -2119,7 +2119,7 @@ gb_internal bool check_is_not_addressable(CheckerContext *c, Operand *o) { return true; } ast_node(ta, TypeAssertion, expr); - TypeAndValue tv = ta->expr->tav; + TypeAndValue tv = ta->expr->tav(); if (is_type_pointer(tv.type)) { return false; } @@ -2590,7 +2590,7 @@ gb_internal void check_shift(CheckerContext *c, Operand *x, Operand *y, Ast *nod TokenPos pos = ast_token(x->expr).pos; if (x_is_untyped) { if (x->expr != nullptr) { - x->expr->tav.is_lhs = true; + x->expr->tav().is_lhs = true; } x->mode = Addressing_Value; if (type_hint) { @@ -3567,9 +3567,9 @@ gb_internal Operand make_operand_from_node(Ast *node) { GB_ASSERT(node != nullptr); Operand x = {}; x.expr = node; - x.mode = node->tav.mode; - x.type = node->tav.type; - x.value = node->tav.value; + x.mode = node->tav().mode; + x.type = node->tav().type; + x.value = node->tav().value; return x; } @@ -3579,8 +3579,8 @@ gb_internal void update_untyped_expr_type(CheckerContext *c, Ast *e, Type *type, ExprInfo *old = check_get_expr_info(c, e); if (old == nullptr) { if (type != nullptr && type != t_invalid) { - if (e->tav.type == nullptr || e->tav.type == t_invalid) { - add_type_and_value(c->info, e, e->tav.mode, type ? type : e->tav.type, e->tav.value); + if (e->tav().type == nullptr || e->tav().type == t_invalid) { + add_type_and_value(c->info, e, e->tav().mode, type ? type : e->tav().type, e->tav().value); if (e->kind == Ast_TernaryIfExpr) { update_untyped_expr_type(c, e->TernaryIfExpr.x, type, final); update_untyped_expr_type(c, e->TernaryIfExpr.y, type, final); @@ -4146,7 +4146,7 @@ gb_internal ExactValue get_constant_field_single(CheckerContext *c, ExactValue v } if (cl->elems[0]->kind == Ast_FieldValue) { - if (is_type_struct(node->tav.type)) { + if (is_type_struct(node->tav().type)) { bool found = false; for_array(i, cl->elems) { Ast *elem = cl->elems[i]; @@ -4155,10 +4155,10 @@ gb_internal ExactValue get_constant_field_single(CheckerContext *c, ExactValue v } ast_node(fv, FieldValue, elem); String name = fv->field->Ident.token.string; - Selection sub_sel = lookup_field(node->tav.type, name, false); + Selection sub_sel = lookup_field(node->tav().type, name, false); defer (array_free(&sub_sel.index)); if (sub_sel.index[0] == index) { - value = fv->value->tav.value; + value = fv->value->tav().value; found = true; break; } @@ -4167,7 +4167,7 @@ gb_internal ExactValue get_constant_field_single(CheckerContext *c, ExactValue v // Use the zero value if it is not found value = {}; } - } else if (is_type_array(node->tav.type) || is_type_enumerated_array(node->tav.type)) { + } else if (is_type_array(node->tav().type) || is_type_enumerated_array(node->tav().type)) { for_array(i, cl->elems) { Ast *elem = cl->elems[i]; if (elem->kind != Ast_FieldValue) { @@ -4176,8 +4176,8 @@ gb_internal ExactValue get_constant_field_single(CheckerContext *c, ExactValue v ast_node(fv, FieldValue, elem); if (is_ast_range(fv->field)) { ast_node(ie, BinaryExpr, fv->field); - TypeAndValue lo_tav = ie->left->tav; - TypeAndValue hi_tav = ie->right->tav; + TypeAndValue lo_tav = ie->left->tav(); + TypeAndValue hi_tav = ie->right->tav(); GB_ASSERT(lo_tav.mode == Addressing_Constant); GB_ASSERT(hi_tav.mode == Addressing_Constant); @@ -4187,39 +4187,39 @@ gb_internal ExactValue get_constant_field_single(CheckerContext *c, ExactValue v i64 corrected_index = index; - if (is_type_enumerated_array(node->tav.type)) { - Type *bt = base_type(node->tav.type); + if (is_type_enumerated_array(node->tav().type)) { + Type *bt = base_type(node->tav().type); GB_ASSERT(bt->kind == Type_EnumeratedArray); corrected_index = index + exact_value_to_i64(*bt->EnumeratedArray.min_value); } if (op != Token_RangeHalf) { if (lo <= corrected_index && corrected_index <= hi) { - TypeAndValue tav = fv->value->tav; + TypeAndValue tav = fv->value->tav(); if (success_) *success_ = true; if (finish_) *finish_ = false; return tav.value; } } else { if (lo <= corrected_index && corrected_index < hi) { - TypeAndValue tav = fv->value->tav; + TypeAndValue tav = fv->value->tav(); if (success_) *success_ = true; if (finish_) *finish_ = false; return tav.value; } } } else { - TypeAndValue index_tav = fv->field->tav; + TypeAndValue index_tav = fv->field->tav(); GB_ASSERT(index_tav.mode == Addressing_Constant); ExactValue index_value = index_tav.value; - if (is_type_enumerated_array(node->tav.type)) { - Type *bt = base_type(node->tav.type); + if (is_type_enumerated_array(node->tav().type)) { + Type *bt = base_type(node->tav().type); GB_ASSERT(bt->kind == Type_EnumeratedArray); index_value = exact_value_sub(index_value, *bt->EnumeratedArray.min_value); } i64 field_index = exact_value_to_i64(index_value); if (index == field_index) { - TypeAndValue tav = fv->value->tav; + TypeAndValue tav = fv->value->tav(); if (success_) *success_ = true; if (finish_) *finish_ = false; return tav.value;; @@ -4241,7 +4241,7 @@ gb_internal ExactValue get_constant_field_single(CheckerContext *c, ExactValue v return value; } - TypeAndValue tav = cl->elems[index]->tav; + TypeAndValue tav = cl->elems[index]->tav(); if (tav.mode == Addressing_Constant) { if (success_) *success_ = true; if (finish_) *finish_ = false; @@ -8663,7 +8663,7 @@ gb_internal ExprKind check_compound_literal(CheckerContext *c, Operand *o, Ast * Ast *e = cl->elems[i]; GB_ASSERT(e->kind != Ast_FieldValue); - TypeAndValue tav = e->tav; + TypeAndValue tav = e->tav(); if (tav.mode != Addressing_Constant) { continue; } @@ -8863,9 +8863,9 @@ gb_internal ExprKind check_selector_call_expr(CheckerContext *c, Operand *o, Ast if (se->modified_call) { // Prevent double evaluation o->expr = node; - o->type = node->tav.type; - o->value = node->tav.value; - o->mode = node->tav.mode; + o->type = node->tav().type; + o->value = node->tav().value; + o->mode = node->tav().mode; return Expr_Expr; } @@ -8927,9 +8927,9 @@ gb_internal ExprKind check_selector_call_expr(CheckerContext *c, Operand *o, Ast } Operand y = {}; - y.mode = first_arg->tav.mode; - y.type = first_arg->tav.type; - y.value = first_arg->tav.value; + y.mode = first_arg->tav().mode; + y.type = first_arg->tav().type; + y.value = first_arg->tav().value; if (check_is_assignable_to(c, &y, first_type)) { // Do nothing, it's valid @@ -9385,7 +9385,7 @@ gb_internal ExprKind check_expr_base_internal(CheckerContext *c, Operand *o, Ast case_ast_node(bl, BasicLit, node); Type *t = t_invalid; - switch (node->tav.value.kind) { + switch (node->tav().value.kind) { case ExactValue_String: t = t_untyped_string; break; case ExactValue_Float: t = t_untyped_float; break; case ExactValue_Complex: t = t_untyped_complex; break; @@ -9403,7 +9403,7 @@ gb_internal ExprKind check_expr_base_internal(CheckerContext *c, Operand *o, Ast o->mode = Addressing_Constant; o->type = t; - o->value = node->tav.value; + o->value = node->tav().value; case_end; case_ast_node(bd, BasicDirective, node); @@ -9859,12 +9859,12 @@ gb_internal bool is_exact_value_zero(ExactValue const &v) { } else { for_array(i, cl->elems) { Ast *elem = cl->elems[i]; - if (elem->tav.mode != Addressing_Constant) { - // if (elem->tav.value.kind != ExactValue_Invalid) { + if (elem->tav().mode != Addressing_Constant) { + // if (elem->tav().value.kind != ExactValue_Invalid) { return false; // } } - if (!is_exact_value_zero(elem->tav.value)) { + if (!is_exact_value_zero(elem->tav().value)) { return false; } } diff --git a/src/check_stmt.cpp b/src/check_stmt.cpp index cf111e84c..7ba23ac67 100644 --- a/src/check_stmt.cpp +++ b/src/check_stmt.cpp @@ -8,7 +8,7 @@ gb_internal bool is_diverging_expr(Ast *expr) { return name == "panic"; } Ast *proc = unparen_expr(expr->CallExpr.proc); - TypeAndValue tv = proc->tav; + TypeAndValue tv = proc->tav(); if (tv.mode == Addressing_Builtin) { Entity *e = entity_of_node(proc); BuiltinProcId id = BuiltinProc_Invalid; @@ -250,7 +250,7 @@ gb_internal bool check_is_terminating(Ast *node, String const &label) { case_ast_node(ws, WhenStmt, node); // TODO(bill): Is this logic correct for when statements? - auto const &tv = ws->cond->tav; + auto const &tv = ws->cond->tav(); if (tv.mode != Addressing_Constant) { // NOTE(bill): Check the things regardless as a bug occurred earlier if (ws->else_stmt != nullptr) { @@ -411,7 +411,7 @@ gb_internal Type *check_assignment_variable(CheckerContext *ctx, Operand *lhs, O Ast *ln = unparen_expr(lhs->expr); if (ln->kind == Ast_IndexExpr) { Ast *x = ln->IndexExpr.expr; - TypeAndValue tav = x->tav; + TypeAndValue tav = x->tav(); GB_ASSERT(tav.mode != Addressing_Invalid); if (tav.mode != Addressing_Variable) { if (!is_type_pointer(tav.type)) { @@ -1497,7 +1497,7 @@ gb_internal void check_stmt_internal(CheckerContext *ctx, Ast *node, u32 flags) break; } - switch (be->left->tav.mode) { + switch (be->left->tav().mode) { case Addressing_Context: case Addressing_Variable: case Addressing_MapIndex: @@ -2331,7 +2331,7 @@ gb_internal void check_stmt_internal(CheckerContext *ctx, Ast *node, u32 flags) error(e->token, "A static variable declaration with a default value must be constant"); } else { Ast *value = vd->values[i]; - if (value->tav.mode != Addressing_Constant) { + if (value->tav().mode != Addressing_Constant) { error(e->token, "A static variable declaration with a default value must be constant"); } } diff --git a/src/check_type.cpp b/src/check_type.cpp index 4634e1fbe..3d4bab3e2 100644 --- a/src/check_type.cpp +++ b/src/check_type.cpp @@ -2569,8 +2569,8 @@ gb_internal bool check_type_internal(CheckerContext *ctx, Ast *e, Type **type, T case_end; case_ast_node(tt, TypeidType, e); - e->tav.mode = Addressing_Type; - e->tav.type = t_typeid; + e->tav().mode = Addressing_Type; + e->tav().type = t_typeid; *type = t_typeid; set_base_type(named_type, *type); return true; diff --git a/src/checker.cpp b/src/checker.cpp index 14a0e5f4c..0f64c6ae9 100644 --- a/src/checker.cpp +++ b/src/checker.cpp @@ -1287,13 +1287,13 @@ gb_internal void destroy_checker(Checker *c) { gb_internal TypeAndValue type_and_value_of_expr(Ast *expr) { TypeAndValue tav = {}; if (expr != nullptr) { - tav = expr->tav; + tav = expr->tav(); } return tav; } gb_internal Type *type_of_expr(Ast *expr) { - TypeAndValue tav = expr->tav; + TypeAndValue tav = expr->tav(); if (tav.mode != Addressing_Invalid) { return tav.type; } @@ -1462,20 +1462,20 @@ gb_internal void add_type_and_value(CheckerInfo *i, Ast *expr, AddressingMode mo Ast *prev_expr = nullptr; while (prev_expr != expr) { prev_expr = expr; - expr->tav.mode = mode; - if (type != nullptr && expr->tav.type != nullptr && - is_type_any(type) && is_type_untyped(expr->tav.type)) { + expr->tav().mode = mode; + if (type != nullptr && expr->tav().type != nullptr && + is_type_any(type) && is_type_untyped(expr->tav().type)) { // ignore } else { - expr->tav.type = type; + expr->tav().type = type; } if (mode == Addressing_Constant || mode == Addressing_Invalid) { - expr->tav.value = value; + expr->tav().value = value; } else if (mode == Addressing_Value && is_type_typeid(type)) { - expr->tav.value = value; + expr->tav().value = value; } else if (mode == Addressing_Value && is_type_proc(type)) { - expr->tav.value = value; + expr->tav().value = value; } expr = unparen_expr(expr); @@ -3635,8 +3635,8 @@ gb_internal void check_collect_value_decl(CheckerContext *c, Ast *decl) { if (value != nullptr) { if (value->kind == Ast_BasicLit && value->BasicLit.token.kind == Token_String) { String v = {}; - if (value->tav.value.kind == ExactValue_String) { - v = value->tav.value.value_string; + if (value->tav().value.kind == ExactValue_String) { + v = value->tav().value.value_string; } if (v == "file") { kind = EntityVisiblity_PrivateToFile; diff --git a/src/llvm_backend_const.cpp b/src/llvm_backend_const.cpp index ee564bbf1..6c5bb153f 100644 --- a/src/llvm_backend_const.cpp +++ b/src/llvm_backend_const.cpp @@ -57,7 +57,7 @@ gb_internal bool lb_is_const_nil(lbValue value) { gb_internal bool lb_is_expr_constant_zero(Ast *expr) { GB_ASSERT(expr != nullptr); - auto v = exact_value_to_integer(expr->tav.value); + auto v = exact_value_to_integer(expr->tav().value); if (v.kind == ExactValue_Integer) { return big_int_cmp_zero(&v.value_integer) == 0; } @@ -720,8 +720,8 @@ gb_internal lbValue lb_const_value(lbModule *m, Type *type, ExactValue value, bo ast_node(fv, FieldValue, elem); if (is_ast_range(fv->field)) { ast_node(ie, BinaryExpr, fv->field); - TypeAndValue lo_tav = ie->left->tav; - TypeAndValue hi_tav = ie->right->tav; + TypeAndValue lo_tav = ie->left->tav(); + TypeAndValue hi_tav = ie->right->tav(); GB_ASSERT(lo_tav.mode == Addressing_Constant); GB_ASSERT(hi_tav.mode == Addressing_Constant); @@ -732,7 +732,7 @@ gb_internal lbValue lb_const_value(lbModule *m, Type *type, ExactValue value, bo hi += 1; } if (lo == i) { - TypeAndValue tav = fv->value->tav; + TypeAndValue tav = fv->value->tav(); LLVMValueRef val = lb_const_value(m, elem_type, tav.value, allow_local).value; for (i64 k = lo; k < hi; k++) { values[value_index++] = val; @@ -743,11 +743,11 @@ gb_internal lbValue lb_const_value(lbModule *m, Type *type, ExactValue value, bo break; } } else { - TypeAndValue index_tav = fv->field->tav; + TypeAndValue index_tav = fv->field->tav(); GB_ASSERT(index_tav.mode == Addressing_Constant); i64 index = exact_value_to_i64(index_tav.value); if (index == i) { - TypeAndValue tav = fv->value->tav; + TypeAndValue tav = fv->value->tav(); LLVMValueRef val = lb_const_value(m, elem_type, tav.value, allow_local).value; values[value_index++] = val; found = true; @@ -769,7 +769,7 @@ gb_internal lbValue lb_const_value(lbModule *m, Type *type, ExactValue value, bo LLVMValueRef *values = gb_alloc_array(temporary_allocator(), LLVMValueRef, cast(isize)type->Array.count); for (isize i = 0; i < elem_count; i++) { - TypeAndValue tav = cl->elems[i]->tav; + TypeAndValue tav = cl->elems[i]->tav(); GB_ASSERT(tav.mode != Addressing_Invalid); values[i] = lb_const_value(m, elem_type, tav.value, allow_local).value; } @@ -804,8 +804,8 @@ gb_internal lbValue lb_const_value(lbModule *m, Type *type, ExactValue value, bo ast_node(fv, FieldValue, elem); if (is_ast_range(fv->field)) { ast_node(ie, BinaryExpr, fv->field); - TypeAndValue lo_tav = ie->left->tav; - TypeAndValue hi_tav = ie->right->tav; + TypeAndValue lo_tav = ie->left->tav(); + TypeAndValue hi_tav = ie->right->tav(); GB_ASSERT(lo_tav.mode == Addressing_Constant); GB_ASSERT(hi_tav.mode == Addressing_Constant); @@ -816,7 +816,7 @@ gb_internal lbValue lb_const_value(lbModule *m, Type *type, ExactValue value, bo hi += 1; } if (lo == i) { - TypeAndValue tav = fv->value->tav; + TypeAndValue tav = fv->value->tav(); LLVMValueRef val = lb_const_value(m, elem_type, tav.value, allow_local).value; for (i64 k = lo; k < hi; k++) { values[value_index++] = val; @@ -827,11 +827,11 @@ gb_internal lbValue lb_const_value(lbModule *m, Type *type, ExactValue value, bo break; } } else { - TypeAndValue index_tav = fv->field->tav; + TypeAndValue index_tav = fv->field->tav(); GB_ASSERT(index_tav.mode == Addressing_Constant); i64 index = exact_value_to_i64(index_tav.value); if (index == i) { - TypeAndValue tav = fv->value->tav; + TypeAndValue tav = fv->value->tav(); LLVMValueRef val = lb_const_value(m, elem_type, tav.value, allow_local).value; values[value_index++] = val; found = true; @@ -853,7 +853,7 @@ gb_internal lbValue lb_const_value(lbModule *m, Type *type, ExactValue value, bo LLVMValueRef *values = gb_alloc_array(temporary_allocator(), LLVMValueRef, cast(isize)type->EnumeratedArray.count); for (isize i = 0; i < elem_count; i++) { - TypeAndValue tav = cl->elems[i]->tav; + TypeAndValue tav = cl->elems[i]->tav(); GB_ASSERT(tav.mode != Addressing_Invalid); values[i] = lb_const_value(m, elem_type, tav.value, allow_local).value; } @@ -887,8 +887,8 @@ gb_internal lbValue lb_const_value(lbModule *m, Type *type, ExactValue value, bo ast_node(fv, FieldValue, elem); if (is_ast_range(fv->field)) { ast_node(ie, BinaryExpr, fv->field); - TypeAndValue lo_tav = ie->left->tav; - TypeAndValue hi_tav = ie->right->tav; + TypeAndValue lo_tav = ie->left->tav(); + TypeAndValue hi_tav = ie->right->tav(); GB_ASSERT(lo_tav.mode == Addressing_Constant); GB_ASSERT(hi_tav.mode == Addressing_Constant); @@ -899,7 +899,7 @@ gb_internal lbValue lb_const_value(lbModule *m, Type *type, ExactValue value, bo hi += 1; } if (lo == i) { - TypeAndValue tav = fv->value->tav; + TypeAndValue tav = fv->value->tav(); LLVMValueRef val = lb_const_value(m, elem_type, tav.value, allow_local).value; for (i64 k = lo; k < hi; k++) { values[value_index++] = val; @@ -910,11 +910,11 @@ gb_internal lbValue lb_const_value(lbModule *m, Type *type, ExactValue value, bo break; } } else { - TypeAndValue index_tav = fv->field->tav; + TypeAndValue index_tav = fv->field->tav(); GB_ASSERT(index_tav.mode == Addressing_Constant); i64 index = exact_value_to_i64(index_tav.value); if (index == i) { - TypeAndValue tav = fv->value->tav; + TypeAndValue tav = fv->value->tav(); LLVMValueRef val = lb_const_value(m, elem_type, tav.value, allow_local).value; values[value_index++] = val; found = true; @@ -932,7 +932,7 @@ gb_internal lbValue lb_const_value(lbModule *m, Type *type, ExactValue value, bo return res; } else { for (isize i = 0; i < elem_count; i++) { - TypeAndValue tav = cl->elems[i]->tav; + TypeAndValue tav = cl->elems[i]->tav(); GB_ASSERT(tav.mode != Addressing_Invalid); values[i] = lb_const_value(m, elem_type, tav.value, allow_local).value; } @@ -974,7 +974,7 @@ gb_internal lbValue lb_const_value(lbModule *m, Type *type, ExactValue value, bo ast_node(fv, FieldValue, cl->elems[i]); String name = fv->field->Ident.token.string; - TypeAndValue tav = fv->value->tav; + TypeAndValue tav = fv->value->tav(); GB_ASSERT(tav.mode != Addressing_Invalid); Selection sel = lookup_field(type, name, false); @@ -989,7 +989,7 @@ gb_internal lbValue lb_const_value(lbModule *m, Type *type, ExactValue value, bo } else { for_array(i, cl->elems) { Entity *f = type->Struct.fields[i]; - TypeAndValue tav = cl->elems[i]->tav; + TypeAndValue tav = cl->elems[i]->tav(); ExactValue val = {}; if (tav.mode != Addressing_Invalid) { val = tav.value; @@ -1073,7 +1073,7 @@ gb_internal lbValue lb_const_value(lbModule *m, Type *type, ExactValue value, bo Ast *e = cl->elems[i]; GB_ASSERT(e->kind != Ast_FieldValue); - TypeAndValue tav = e->tav; + TypeAndValue tav = e->tav(); if (tav.mode != Addressing_Constant) { continue; } @@ -1106,8 +1106,8 @@ gb_internal lbValue lb_const_value(lbModule *m, Type *type, ExactValue value, bo ast_node(fv, FieldValue, elem); if (is_ast_range(fv->field)) { ast_node(ie, BinaryExpr, fv->field); - TypeAndValue lo_tav = ie->left->tav; - TypeAndValue hi_tav = ie->right->tav; + TypeAndValue lo_tav = ie->left->tav(); + TypeAndValue hi_tav = ie->right->tav(); GB_ASSERT(lo_tav.mode == Addressing_Constant); GB_ASSERT(hi_tav.mode == Addressing_Constant); @@ -1122,7 +1122,7 @@ gb_internal lbValue lb_const_value(lbModule *m, Type *type, ExactValue value, bo GB_ASSERT(lo <= hi); - TypeAndValue tav = fv->value->tav; + TypeAndValue tav = fv->value->tav(); LLVMValueRef val = lb_const_value(m, elem_type, tav.value, allow_local).value; for (i64 k = lo; k < hi; k++) { i64 offset = matrix_row_major_index_to_offset(type, k); @@ -1130,11 +1130,11 @@ gb_internal lbValue lb_const_value(lbModule *m, Type *type, ExactValue value, bo values[offset] = val; } } else { - TypeAndValue index_tav = fv->field->tav; + TypeAndValue index_tav = fv->field->tav(); GB_ASSERT(index_tav.mode == Addressing_Constant); i64 index = exact_value_to_i64(index_tav.value); GB_ASSERT(index < max_count); - TypeAndValue tav = fv->value->tav; + TypeAndValue tav = fv->value->tav(); LLVMValueRef val = lb_const_value(m, elem_type, tav.value, allow_local).value; i64 offset = matrix_row_major_index_to_offset(type, index); GB_ASSERT(values[offset] == nullptr); @@ -1156,7 +1156,7 @@ gb_internal lbValue lb_const_value(lbModule *m, Type *type, ExactValue value, bo LLVMValueRef *values = gb_alloc_array(temporary_allocator(), LLVMValueRef, cast(isize)total_count); for_array(i, cl->elems) { - TypeAndValue tav = cl->elems[i]->tav; + TypeAndValue tav = cl->elems[i]->tav(); GB_ASSERT(tav.mode != Addressing_Invalid); i64 offset = matrix_row_major_index_to_offset(type, i); values[offset] = lb_const_value(m, elem_type, tav.value, allow_local).value; diff --git a/src/llvm_backend_expr.cpp b/src/llvm_backend_expr.cpp index d574caf4c..794ed7720 100644 --- a/src/llvm_backend_expr.cpp +++ b/src/llvm_backend_expr.cpp @@ -1330,7 +1330,7 @@ gb_internal lbValue lb_build_binary_expr(lbProcedure *p, Ast *expr) { TypeAndValue tv = type_and_value_of_expr(expr); - if (is_type_matrix(be->left->tav.type) || is_type_matrix(be->right->tav.type)) { + if (is_type_matrix(be->left->tav().type) || is_type_matrix(be->right->tav().type)) { lbValue left = lb_build_expr(p, be->left); lbValue right = lb_build_expr(p, be->right); return lb_emit_arith_matrix(p, be->op.kind, left, right, default_type(tv.type), false); @@ -1372,12 +1372,12 @@ gb_internal lbValue lb_build_binary_expr(lbProcedure *p, Ast *expr) { case Token_CmpEq: case Token_NotEq: - if (is_type_untyped_nil(be->right->tav.type)) { + if (is_type_untyped_nil(be->right->tav().type)) { lbValue left = lb_build_expr(p, be->left); lbValue cmp = lb_emit_comp_against_nil(p, be->op.kind, left); Type *type = default_type(tv.type); return lb_emit_conv(p, cmp, type); - } else if (is_type_untyped_nil(be->left->tav.type)) { + } else if (is_type_untyped_nil(be->left->tav().type)) { lbValue right = lb_build_expr(p, be->right); lbValue cmp = lb_emit_comp_against_nil(p, be->op.kind, right); Type *type = default_type(tv.type); @@ -1392,11 +1392,11 @@ gb_internal lbValue lb_build_binary_expr(lbProcedure *p, Ast *expr) { lbValue left = {}; lbValue right = {}; - if (be->left->tav.mode == Addressing_Type) { - left = lb_typeid(p->module, be->left->tav.type); + if (be->left->tav().mode == Addressing_Type) { + left = lb_typeid(p->module, be->left->tav().type); } - if (be->right->tav.mode == Addressing_Type) { - right = lb_typeid(p->module, be->right->tav.type); + if (be->right->tav().mode == Addressing_Type) { + right = lb_typeid(p->module, be->right->tav().type); } if (left.value == nullptr) left = lb_build_expr(p, be->left); if (right.value == nullptr) right = lb_build_expr(p, be->right); @@ -3093,7 +3093,7 @@ gb_internal lbValue lb_build_expr_internal(lbProcedure *p, Ast *expr) { if (tv.value.kind != ExactValue_Invalid) { // NOTE(bill): The commented out code below is just for debug purposes only // if (is_type_untyped(type)) { - // gb_printf_err("%s %s : %s @ %p\n", token_pos_to_string(expr_pos), expr_to_string(expr), type_to_string(expr->tav.type), expr); + // gb_printf_err("%s %s : %s @ %p\n", token_pos_to_string(expr_pos), expr_to_string(expr), type_to_string(expr->tav().type), expr); // GB_PANIC("%s\n", type_to_string(tv.type)); // } @@ -3514,8 +3514,8 @@ gb_internal void lb_build_addr_compound_lit_populate(lbProcedure *p, Slicefield)) { ast_node(ie, BinaryExpr, fv->field); - TypeAndValue lo_tav = ie->left->tav; - TypeAndValue hi_tav = ie->right->tav; + TypeAndValue lo_tav = ie->left->tav(); + TypeAndValue hi_tav = ie->right->tav(); GB_ASSERT(lo_tav.mode == Addressing_Constant); GB_ASSERT(hi_tav.mode == Addressing_Constant); @@ -3556,7 +3556,7 @@ gb_internal void lb_build_addr_compound_lit_populate(lbProcedure *p, Slicefield->tav; + auto tav = fv->field->tav(); GB_ASSERT(tav.mode == Addressing_Constant); i64 index = exact_value_to_i64(tav.value); @@ -3632,7 +3632,7 @@ gb_internal lbAddr lb_build_addr_index_expr(lbProcedure *p, Ast *expr) { return lb_addr_soa_variable(val, index, ie->index); } - if (ie->expr->tav.mode == Addressing_SoaVariable) { + if (ie->expr->tav().mode == Addressing_SoaVariable) { // SOA Structures for slices/dynamic arrays GB_ASSERT(is_type_pointer(type_of_expr(ie->expr))); @@ -4451,8 +4451,8 @@ gb_internal lbAddr lb_build_addr_internal(lbProcedure *p, Ast *expr) { a = lb_addr_get_ptr(p, addr); } - GB_ASSERT(is_type_array(expr->tav.type)); - return lb_addr_swizzle(a, expr->tav.type, swizzle_count, swizzle_indices); + GB_ASSERT(is_type_array(expr->tav().type)); + return lb_addr_swizzle(a, expr->tav().type, swizzle_count, swizzle_indices); } Selection sel = lookup_field(type, selector, false); @@ -4621,7 +4621,7 @@ gb_internal lbAddr lb_build_addr_internal(lbProcedure *p, Ast *expr) { case_ast_node(ce, CallExpr, expr); BuiltinProcId builtin_id = BuiltinProc_Invalid; - if (ce->proc->tav.mode == Addressing_Builtin) { + if (ce->proc->tav().mode == Addressing_Builtin) { Entity *e = entity_of_node(ce->proc); if (e != nullptr) { builtin_id = cast(BuiltinProcId)e->Builtin.id; @@ -4629,7 +4629,7 @@ gb_internal lbAddr lb_build_addr_internal(lbProcedure *p, Ast *expr) { builtin_id = BuiltinProc_DIRECTIVE; } } - auto const &tv = expr->tav; + auto const &tv = expr->tav(); if (builtin_id == BuiltinProc_swizzle && is_type_array(tv.type)) { // NOTE(bill, 2021-08-09): `swizzle` has some bizarre semantics so it needs to be diff --git a/src/llvm_backend_proc.cpp b/src/llvm_backend_proc.cpp index 384d29ca7..546d49027 100644 --- a/src/llvm_backend_proc.cpp +++ b/src/llvm_backend_proc.cpp @@ -1516,7 +1516,7 @@ gb_internal lbValue lb_build_builtin_simd_proc(lbProcedure *p, Ast *expr, TypeAn BigInt bi_count = {}; big_int_from_i64(&bi_count, count); - TypeAndValue const &tv = ce->args[1]->tav; + TypeAndValue const &tv = ce->args[1]->tav(); ExactValue val = exact_value_to_integer(tv.value); GB_ASSERT(val.kind == ExactValue_Integer); BigInt *bi = &val.value_integer; @@ -2428,16 +2428,16 @@ gb_internal lbValue lb_build_builtin_proc(lbProcedure *p, Ast *expr, TypeAndValu case BuiltinProc_type_equal_proc: - return lb_equal_proc_for_type(p->module, ce->args[0]->tav.type); + return lb_equal_proc_for_type(p->module, ce->args[0]->tav().type); case BuiltinProc_type_hasher_proc: - return lb_hasher_proc_for_type(p->module, ce->args[0]->tav.type); + return lb_hasher_proc_for_type(p->module, ce->args[0]->tav().type); case BuiltinProc_type_map_info: - return lb_gen_map_info_ptr(p->module, ce->args[0]->tav.type); + return lb_gen_map_info_ptr(p->module, ce->args[0]->tav().type); case BuiltinProc_type_map_cell_info: - return lb_gen_map_cell_info_ptr(p->module, ce->args[0]->tav.type); + return lb_gen_map_cell_info_ptr(p->module, ce->args[0]->tav().type); case BuiltinProc_fixed_point_mul: @@ -2505,7 +2505,7 @@ gb_internal lbValue lb_build_builtin_proc(lbProcedure *p, Ast *expr, TypeAndValu case BuiltinProc_prefetch_write_data: { lbValue ptr = lb_emit_conv(p, lb_build_expr(p, ce->args[0]), t_rawptr); - unsigned long long locality = cast(unsigned long long)exact_value_to_i64(ce->args[1]->tav.value); + unsigned long long locality = cast(unsigned long long)exact_value_to_i64(ce->args[1]->tav().value); unsigned long long rw = 0; unsigned long long cache = 0; switch (id) { @@ -3060,8 +3060,8 @@ gb_internal lbValue lb_build_call_expr_internal(lbProcedure *p, Ast *expr) { } } - if (proc_expr->tav.mode == Addressing_Constant) { - ExactValue v = proc_expr->tav.value; + if (proc_expr->tav().mode == Addressing_Constant) { + ExactValue v = proc_expr->tav().value; switch (v.kind) { case ExactValue_Integer: { @@ -3070,7 +3070,7 @@ gb_internal lbValue lb_build_call_expr_internal(lbProcedure *p, Ast *expr) { x.value = LLVMConstInt(lb_type(m, t_uintptr), u, false); x.type = t_uintptr; x = lb_emit_conv(p, x, t_rawptr); - value = lb_emit_conv(p, x, proc_expr->tav.type); + value = lb_emit_conv(p, x, proc_expr->tav().type); break; } case ExactValue_Pointer: @@ -3080,7 +3080,7 @@ gb_internal lbValue lb_build_call_expr_internal(lbProcedure *p, Ast *expr) { x.value = LLVMConstInt(lb_type(m, t_uintptr), u, false); x.type = t_uintptr; x = lb_emit_conv(p, x, t_rawptr); - value = lb_emit_conv(p, x, proc_expr->tav.type); + value = lb_emit_conv(p, x, proc_expr->tav().type); break; } } diff --git a/src/llvm_backend_stmt.cpp b/src/llvm_backend_stmt.cpp index 6400a8a9d..e0e991b4d 100644 --- a/src/llvm_backend_stmt.cpp +++ b/src/llvm_backend_stmt.cpp @@ -952,11 +952,11 @@ gb_internal void lb_build_unroll_range_stmt(lbProcedure *p, AstUnrollRangeStmt * TokenKind op = expr->BinaryExpr.op.kind; Ast *start_expr = expr->BinaryExpr.left; Ast *end_expr = expr->BinaryExpr.right; - GB_ASSERT(start_expr->tav.mode == Addressing_Constant); - GB_ASSERT(end_expr->tav.mode == Addressing_Constant); + GB_ASSERT(start_expr->tav().mode == Addressing_Constant); + GB_ASSERT(end_expr->tav().mode == Addressing_Constant); - ExactValue start = start_expr->tav.value; - ExactValue end = end_expr->tav.value; + ExactValue start = start_expr->tav().value; + ExactValue end = end_expr->tav().value; if (op != Token_RangeHalf) { // .. [start, end] (or ..=) ExactValue index = exact_value_i64(0); for (ExactValue val = start; @@ -1006,16 +1006,16 @@ gb_internal void lb_build_unroll_range_stmt(lbProcedure *p, AstUnrollRangeStmt * if (val0_type) val0_addr = lb_build_addr(p, rs->val0); if (val1_type) val1_addr = lb_build_addr(p, rs->val1); - GB_ASSERT(expr->tav.mode == Addressing_Constant); + GB_ASSERT(expr->tav().mode == Addressing_Constant); - Type *t = base_type(expr->tav.type); + Type *t = base_type(expr->tav().type); switch (t->kind) { case Type_Basic: GB_ASSERT(is_type_string(t)); { - ExactValue value = expr->tav.value; + ExactValue value = expr->tav().value; GB_ASSERT(value.kind == ExactValue_String); String str = value.value_string; Rune codepoint = 0; @@ -1109,7 +1109,7 @@ gb_internal bool lb_switch_stmt_can_be_trivial_jump_table(AstSwitchStmt *ss, boo if (is_ast_range(expr)) { return false; } - if (expr->tav.mode == Addressing_Type) { + if (expr->tav().mode == Addressing_Type) { GB_ASSERT(is_typeid); continue; } @@ -1209,12 +1209,12 @@ gb_internal void lb_build_switch_stmt(lbProcedure *p, AstSwitchStmt *ss, Scope * if (switch_instr != nullptr) { lbValue on_val = {}; - if (expr->tav.mode == Addressing_Type) { + if (expr->tav().mode == Addressing_Type) { GB_ASSERT(is_type_typeid(tag.type)); - lbValue e = lb_typeid(p->module, expr->tav.type); + lbValue e = lb_typeid(p->module, expr->tav().type); on_val = lb_emit_conv(p, e, tag.type); } else { - GB_ASSERT(expr->tav.mode == Addressing_Constant); + GB_ASSERT(expr->tav().mode == Addressing_Constant); GB_ASSERT(!is_ast_range(expr)); on_val = lb_build_expr(p, expr); @@ -1245,9 +1245,9 @@ gb_internal void lb_build_switch_stmt(lbProcedure *p, AstSwitchStmt *ss, Scope * lbValue cond_rhs = lb_emit_comp(p, op, tag, rhs); cond = lb_emit_arith(p, Token_And, cond_lhs, cond_rhs, t_bool); } else { - if (expr->tav.mode == Addressing_Type) { + if (expr->tav().mode == Addressing_Type) { GB_ASSERT(is_type_typeid(tag.type)); - lbValue e = lb_typeid(p->module, expr->tav.type); + lbValue e = lb_typeid(p->module, expr->tav().type); e = lb_emit_conv(p, e, tag.type); cond = lb_emit_comp(p, Token_CmpEq, tag, e); } else { @@ -1476,11 +1476,11 @@ gb_internal void lb_build_static_variables(lbProcedure *p, AstValueDecl *vd) { if (vd->values.count > 0) { GB_ASSERT(vd->names.count == vd->values.count); Ast *ast_value = vd->values[i]; - GB_ASSERT(ast_value->tav.mode == Addressing_Constant || - ast_value->tav.mode == Addressing_Invalid); + GB_ASSERT(ast_value->tav().mode == Addressing_Constant || + ast_value->tav().mode == Addressing_Invalid); bool allow_local = false; - value = lb_const_value(p->module, ast_value->tav.type, ast_value->tav.value, allow_local); + value = lb_const_value(p->module, ast_value->tav().type, ast_value->tav().value, allow_local); } Ast *ident = vd->names[i]; @@ -2068,7 +2068,7 @@ gb_internal void lb_build_assign_stmt(lbProcedure *p, AstAssignStmt *as) { op_ += Token_Add - Token_AddEq; // Convert += to + TokenKind op = cast(TokenKind)op_; if (op == Token_CmpAnd || op == Token_CmpOr) { - Type *type = as->lhs[0]->tav.type; + Type *type = as->lhs[0]->tav().type; lbValue new_value = lb_emit_logical_binary_expr(p, op, as->lhs[0], as->rhs[0], type); lbAddr lhs = lb_build_addr(p, as->lhs[0]); diff --git a/src/llvm_backend_utility.cpp b/src/llvm_backend_utility.cpp index dbed32b82..6abcdfc04 100644 --- a/src/llvm_backend_utility.cpp +++ b/src/llvm_backend_utility.cpp @@ -1929,7 +1929,7 @@ gb_internal lbAddr lb_handle_objc_find_or_register_selector(lbProcedure *p, Stri gb_internal lbValue lb_handle_objc_find_selector(lbProcedure *p, Ast *expr) { ast_node(ce, CallExpr, expr); - auto tav = ce->args[0]->tav; + auto tav = ce->args[0]->tav(); GB_ASSERT(tav.value.kind == ExactValue_String); String name = tav.value.value_string; return lb_addr_load(p, lb_handle_objc_find_or_register_selector(p, name)); @@ -1939,7 +1939,7 @@ gb_internal lbValue lb_handle_objc_register_selector(lbProcedure *p, Ast *expr) ast_node(ce, CallExpr, expr); lbModule *m = p->module; - auto tav = ce->args[0]->tav; + auto tav = ce->args[0]->tav(); GB_ASSERT(tav.value.kind == ExactValue_String); String name = tav.value.value_string; lbAddr dst = lb_handle_objc_find_or_register_selector(p, name); @@ -1975,7 +1975,7 @@ gb_internal lbAddr lb_handle_objc_find_or_register_class(lbProcedure *p, String gb_internal lbValue lb_handle_objc_find_class(lbProcedure *p, Ast *expr) { ast_node(ce, CallExpr, expr); - auto tav = ce->args[0]->tav; + auto tav = ce->args[0]->tav(); GB_ASSERT(tav.value.kind == ExactValue_String); String name = tav.value.value_string; return lb_addr_load(p, lb_handle_objc_find_or_register_class(p, name)); @@ -1985,7 +1985,7 @@ gb_internal lbValue lb_handle_objc_register_class(lbProcedure *p, Ast *expr) { ast_node(ce, CallExpr, expr); lbModule *m = p->module; - auto tav = ce->args[0]->tav; + auto tav = ce->args[0]->tav(); GB_ASSERT(tav.value.kind == ExactValue_String); String name = tav.value.value_string; lbAddr dst = lb_handle_objc_find_or_register_class(p, name); @@ -2045,8 +2045,8 @@ gb_internal lbValue lb_handle_objc_send(lbProcedure *p, Ast *expr) { lbValue id = lb_handle_objc_id(p, ce->args[1]); Ast *sel_expr = ce->args[2]; - GB_ASSERT(sel_expr->tav.value.kind == ExactValue_String); - lbValue sel = lb_addr_load(p, lb_handle_objc_find_or_register_selector(p, sel_expr->tav.value.value_string)); + GB_ASSERT(sel_expr->tav().value.kind == ExactValue_String); + lbValue sel = lb_addr_load(p, lb_handle_objc_find_or_register_selector(p, sel_expr->tav().value.value_string)); array_add(&args, id); array_add(&args, sel); diff --git a/src/parser.cpp b/src/parser.cpp index 436498c51..42d8f62cf 100644 --- a/src/parser.cpp +++ b/src/parser.cpp @@ -71,6 +71,7 @@ gb_internal Ast *alloc_ast_node(AstFile *f, AstKind kind) { Ast *node = cast(Ast *)gb_alloc(a, size); node->kind = kind; node->file_id = f ? f->id : 0; + node->tav_ = gb_alloc_item(a, TypeAndValue); global_total_node_memory_allocated.fetch_add(size); @@ -106,6 +107,9 @@ gb_internal Ast *clone_ast(Ast *node) { AstFile *f = node->thread_safe_file(); Ast *n = alloc_ast_node(f, node->kind); gb_memmove(n, node, ast_node_size(node->kind)); + TypeAndValue *new_tav = gb_alloc_item(ast_allocator(f), TypeAndValue); + *new_tav = *node->tav_; + n->tav_ = new_tav; switch (n->kind) { default: GB_PANIC("Unhandled Ast %.*s", LIT(ast_strings[n->kind])); break; @@ -650,8 +654,8 @@ gb_internal String string_value_from_token(AstFile *f, Token const &token) { gb_internal Ast *ast_basic_lit(AstFile *f, Token basic_lit) { Ast *result = alloc_ast_node(f, Ast_BasicLit); result->BasicLit.token = basic_lit; - result->tav.mode = Addressing_Constant; - result->tav.value = exact_value_from_token(f, basic_lit); + result->tav().mode = Addressing_Constant; + result->tav().value = exact_value_from_token(f, basic_lit); return result; } diff --git a/src/parser.hpp b/src/parser.hpp index 7d292ffce..e3d6b42d8 100644 --- a/src/parser.hpp +++ b/src/parser.hpp @@ -754,7 +754,7 @@ struct AstCommonStuff { u8 state_flags; u8 viral_state_flags; i32 file_id; - TypeAndValue tav; // TODO(bill): Make this a pointer to minimize 'Ast' size + TypeAndValue *tav_; // TODO(bill): Make this a pointer to minimize 'Ast' size }; struct Ast { @@ -762,7 +762,7 @@ struct Ast { u8 state_flags; u8 viral_state_flags; i32 file_id; - TypeAndValue tav; // TODO(bill): Make this a pointer to minimize 'Ast' size + TypeAndValue *tav_; // TODO(bill): Make this a pointer to minimize 'Ast' size // IMPORTANT NOTE(bill): This must be at the end since the AST is allocated to be size of the variant union { @@ -771,6 +771,9 @@ struct Ast { #undef AST_KIND }; + gb_inline TypeAndValue &tav() const { + return *this->tav_; + } // NOTE(bill): I know I dislike methods but this is hopefully a temporary thing // for refactoring purposes -- cgit v1.2.3 From 9b278db9934913367a8e186b9c6aa9c03017f3d4 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Thu, 22 Dec 2022 12:01:41 +0000 Subject: Revert "Change `tav` to be a pointer internally" This reverts commit e98f1a28e68e82753728f58b3465793192b74f9d. --- src/check_expr.cpp | 68 ++++++++++++++++++++++---------------------- src/check_stmt.cpp | 10 +++---- src/check_type.cpp | 4 +-- src/checker.cpp | 22 +++++++------- src/llvm_backend_const.cpp | 56 ++++++++++++++++++------------------ src/llvm_backend_expr.cpp | 32 ++++++++++----------- src/llvm_backend_proc.cpp | 20 ++++++------- src/llvm_backend_stmt.cpp | 34 +++++++++++----------- src/llvm_backend_utility.cpp | 12 ++++---- src/parser.cpp | 8 ++---- src/parser.hpp | 7 ++--- 11 files changed, 133 insertions(+), 140 deletions(-) (limited to 'src/checker.cpp') diff --git a/src/check_expr.cpp b/src/check_expr.cpp index 654dec051..ed1ddd1f1 100644 --- a/src/check_expr.cpp +++ b/src/check_expr.cpp @@ -2119,7 +2119,7 @@ gb_internal bool check_is_not_addressable(CheckerContext *c, Operand *o) { return true; } ast_node(ta, TypeAssertion, expr); - TypeAndValue tv = ta->expr->tav(); + TypeAndValue tv = ta->expr->tav; if (is_type_pointer(tv.type)) { return false; } @@ -2590,7 +2590,7 @@ gb_internal void check_shift(CheckerContext *c, Operand *x, Operand *y, Ast *nod TokenPos pos = ast_token(x->expr).pos; if (x_is_untyped) { if (x->expr != nullptr) { - x->expr->tav().is_lhs = true; + x->expr->tav.is_lhs = true; } x->mode = Addressing_Value; if (type_hint) { @@ -3567,9 +3567,9 @@ gb_internal Operand make_operand_from_node(Ast *node) { GB_ASSERT(node != nullptr); Operand x = {}; x.expr = node; - x.mode = node->tav().mode; - x.type = node->tav().type; - x.value = node->tav().value; + x.mode = node->tav.mode; + x.type = node->tav.type; + x.value = node->tav.value; return x; } @@ -3579,8 +3579,8 @@ gb_internal void update_untyped_expr_type(CheckerContext *c, Ast *e, Type *type, ExprInfo *old = check_get_expr_info(c, e); if (old == nullptr) { if (type != nullptr && type != t_invalid) { - if (e->tav().type == nullptr || e->tav().type == t_invalid) { - add_type_and_value(c->info, e, e->tav().mode, type ? type : e->tav().type, e->tav().value); + if (e->tav.type == nullptr || e->tav.type == t_invalid) { + add_type_and_value(c->info, e, e->tav.mode, type ? type : e->tav.type, e->tav.value); if (e->kind == Ast_TernaryIfExpr) { update_untyped_expr_type(c, e->TernaryIfExpr.x, type, final); update_untyped_expr_type(c, e->TernaryIfExpr.y, type, final); @@ -4146,7 +4146,7 @@ gb_internal ExactValue get_constant_field_single(CheckerContext *c, ExactValue v } if (cl->elems[0]->kind == Ast_FieldValue) { - if (is_type_struct(node->tav().type)) { + if (is_type_struct(node->tav.type)) { bool found = false; for_array(i, cl->elems) { Ast *elem = cl->elems[i]; @@ -4155,10 +4155,10 @@ gb_internal ExactValue get_constant_field_single(CheckerContext *c, ExactValue v } ast_node(fv, FieldValue, elem); String name = fv->field->Ident.token.string; - Selection sub_sel = lookup_field(node->tav().type, name, false); + Selection sub_sel = lookup_field(node->tav.type, name, false); defer (array_free(&sub_sel.index)); if (sub_sel.index[0] == index) { - value = fv->value->tav().value; + value = fv->value->tav.value; found = true; break; } @@ -4167,7 +4167,7 @@ gb_internal ExactValue get_constant_field_single(CheckerContext *c, ExactValue v // Use the zero value if it is not found value = {}; } - } else if (is_type_array(node->tav().type) || is_type_enumerated_array(node->tav().type)) { + } else if (is_type_array(node->tav.type) || is_type_enumerated_array(node->tav.type)) { for_array(i, cl->elems) { Ast *elem = cl->elems[i]; if (elem->kind != Ast_FieldValue) { @@ -4176,8 +4176,8 @@ gb_internal ExactValue get_constant_field_single(CheckerContext *c, ExactValue v ast_node(fv, FieldValue, elem); if (is_ast_range(fv->field)) { ast_node(ie, BinaryExpr, fv->field); - TypeAndValue lo_tav = ie->left->tav(); - TypeAndValue hi_tav = ie->right->tav(); + TypeAndValue lo_tav = ie->left->tav; + TypeAndValue hi_tav = ie->right->tav; GB_ASSERT(lo_tav.mode == Addressing_Constant); GB_ASSERT(hi_tav.mode == Addressing_Constant); @@ -4187,39 +4187,39 @@ gb_internal ExactValue get_constant_field_single(CheckerContext *c, ExactValue v i64 corrected_index = index; - if (is_type_enumerated_array(node->tav().type)) { - Type *bt = base_type(node->tav().type); + if (is_type_enumerated_array(node->tav.type)) { + Type *bt = base_type(node->tav.type); GB_ASSERT(bt->kind == Type_EnumeratedArray); corrected_index = index + exact_value_to_i64(*bt->EnumeratedArray.min_value); } if (op != Token_RangeHalf) { if (lo <= corrected_index && corrected_index <= hi) { - TypeAndValue tav = fv->value->tav(); + TypeAndValue tav = fv->value->tav; if (success_) *success_ = true; if (finish_) *finish_ = false; return tav.value; } } else { if (lo <= corrected_index && corrected_index < hi) { - TypeAndValue tav = fv->value->tav(); + TypeAndValue tav = fv->value->tav; if (success_) *success_ = true; if (finish_) *finish_ = false; return tav.value; } } } else { - TypeAndValue index_tav = fv->field->tav(); + TypeAndValue index_tav = fv->field->tav; GB_ASSERT(index_tav.mode == Addressing_Constant); ExactValue index_value = index_tav.value; - if (is_type_enumerated_array(node->tav().type)) { - Type *bt = base_type(node->tav().type); + if (is_type_enumerated_array(node->tav.type)) { + Type *bt = base_type(node->tav.type); GB_ASSERT(bt->kind == Type_EnumeratedArray); index_value = exact_value_sub(index_value, *bt->EnumeratedArray.min_value); } i64 field_index = exact_value_to_i64(index_value); if (index == field_index) { - TypeAndValue tav = fv->value->tav(); + TypeAndValue tav = fv->value->tav; if (success_) *success_ = true; if (finish_) *finish_ = false; return tav.value;; @@ -4241,7 +4241,7 @@ gb_internal ExactValue get_constant_field_single(CheckerContext *c, ExactValue v return value; } - TypeAndValue tav = cl->elems[index]->tav(); + TypeAndValue tav = cl->elems[index]->tav; if (tav.mode == Addressing_Constant) { if (success_) *success_ = true; if (finish_) *finish_ = false; @@ -8663,7 +8663,7 @@ gb_internal ExprKind check_compound_literal(CheckerContext *c, Operand *o, Ast * Ast *e = cl->elems[i]; GB_ASSERT(e->kind != Ast_FieldValue); - TypeAndValue tav = e->tav(); + TypeAndValue tav = e->tav; if (tav.mode != Addressing_Constant) { continue; } @@ -8863,9 +8863,9 @@ gb_internal ExprKind check_selector_call_expr(CheckerContext *c, Operand *o, Ast if (se->modified_call) { // Prevent double evaluation o->expr = node; - o->type = node->tav().type; - o->value = node->tav().value; - o->mode = node->tav().mode; + o->type = node->tav.type; + o->value = node->tav.value; + o->mode = node->tav.mode; return Expr_Expr; } @@ -8927,9 +8927,9 @@ gb_internal ExprKind check_selector_call_expr(CheckerContext *c, Operand *o, Ast } Operand y = {}; - y.mode = first_arg->tav().mode; - y.type = first_arg->tav().type; - y.value = first_arg->tav().value; + y.mode = first_arg->tav.mode; + y.type = first_arg->tav.type; + y.value = first_arg->tav.value; if (check_is_assignable_to(c, &y, first_type)) { // Do nothing, it's valid @@ -9385,7 +9385,7 @@ gb_internal ExprKind check_expr_base_internal(CheckerContext *c, Operand *o, Ast case_ast_node(bl, BasicLit, node); Type *t = t_invalid; - switch (node->tav().value.kind) { + switch (node->tav.value.kind) { case ExactValue_String: t = t_untyped_string; break; case ExactValue_Float: t = t_untyped_float; break; case ExactValue_Complex: t = t_untyped_complex; break; @@ -9403,7 +9403,7 @@ gb_internal ExprKind check_expr_base_internal(CheckerContext *c, Operand *o, Ast o->mode = Addressing_Constant; o->type = t; - o->value = node->tav().value; + o->value = node->tav.value; case_end; case_ast_node(bd, BasicDirective, node); @@ -9859,12 +9859,12 @@ gb_internal bool is_exact_value_zero(ExactValue const &v) { } else { for_array(i, cl->elems) { Ast *elem = cl->elems[i]; - if (elem->tav().mode != Addressing_Constant) { - // if (elem->tav().value.kind != ExactValue_Invalid) { + if (elem->tav.mode != Addressing_Constant) { + // if (elem->tav.value.kind != ExactValue_Invalid) { return false; // } } - if (!is_exact_value_zero(elem->tav().value)) { + if (!is_exact_value_zero(elem->tav.value)) { return false; } } diff --git a/src/check_stmt.cpp b/src/check_stmt.cpp index 7ba23ac67..cf111e84c 100644 --- a/src/check_stmt.cpp +++ b/src/check_stmt.cpp @@ -8,7 +8,7 @@ gb_internal bool is_diverging_expr(Ast *expr) { return name == "panic"; } Ast *proc = unparen_expr(expr->CallExpr.proc); - TypeAndValue tv = proc->tav(); + TypeAndValue tv = proc->tav; if (tv.mode == Addressing_Builtin) { Entity *e = entity_of_node(proc); BuiltinProcId id = BuiltinProc_Invalid; @@ -250,7 +250,7 @@ gb_internal bool check_is_terminating(Ast *node, String const &label) { case_ast_node(ws, WhenStmt, node); // TODO(bill): Is this logic correct for when statements? - auto const &tv = ws->cond->tav(); + auto const &tv = ws->cond->tav; if (tv.mode != Addressing_Constant) { // NOTE(bill): Check the things regardless as a bug occurred earlier if (ws->else_stmt != nullptr) { @@ -411,7 +411,7 @@ gb_internal Type *check_assignment_variable(CheckerContext *ctx, Operand *lhs, O Ast *ln = unparen_expr(lhs->expr); if (ln->kind == Ast_IndexExpr) { Ast *x = ln->IndexExpr.expr; - TypeAndValue tav = x->tav(); + TypeAndValue tav = x->tav; GB_ASSERT(tav.mode != Addressing_Invalid); if (tav.mode != Addressing_Variable) { if (!is_type_pointer(tav.type)) { @@ -1497,7 +1497,7 @@ gb_internal void check_stmt_internal(CheckerContext *ctx, Ast *node, u32 flags) break; } - switch (be->left->tav().mode) { + switch (be->left->tav.mode) { case Addressing_Context: case Addressing_Variable: case Addressing_MapIndex: @@ -2331,7 +2331,7 @@ gb_internal void check_stmt_internal(CheckerContext *ctx, Ast *node, u32 flags) error(e->token, "A static variable declaration with a default value must be constant"); } else { Ast *value = vd->values[i]; - if (value->tav().mode != Addressing_Constant) { + if (value->tav.mode != Addressing_Constant) { error(e->token, "A static variable declaration with a default value must be constant"); } } diff --git a/src/check_type.cpp b/src/check_type.cpp index 3d4bab3e2..4634e1fbe 100644 --- a/src/check_type.cpp +++ b/src/check_type.cpp @@ -2569,8 +2569,8 @@ gb_internal bool check_type_internal(CheckerContext *ctx, Ast *e, Type **type, T case_end; case_ast_node(tt, TypeidType, e); - e->tav().mode = Addressing_Type; - e->tav().type = t_typeid; + e->tav.mode = Addressing_Type; + e->tav.type = t_typeid; *type = t_typeid; set_base_type(named_type, *type); return true; diff --git a/src/checker.cpp b/src/checker.cpp index 0f64c6ae9..14a0e5f4c 100644 --- a/src/checker.cpp +++ b/src/checker.cpp @@ -1287,13 +1287,13 @@ gb_internal void destroy_checker(Checker *c) { gb_internal TypeAndValue type_and_value_of_expr(Ast *expr) { TypeAndValue tav = {}; if (expr != nullptr) { - tav = expr->tav(); + tav = expr->tav; } return tav; } gb_internal Type *type_of_expr(Ast *expr) { - TypeAndValue tav = expr->tav(); + TypeAndValue tav = expr->tav; if (tav.mode != Addressing_Invalid) { return tav.type; } @@ -1462,20 +1462,20 @@ gb_internal void add_type_and_value(CheckerInfo *i, Ast *expr, AddressingMode mo Ast *prev_expr = nullptr; while (prev_expr != expr) { prev_expr = expr; - expr->tav().mode = mode; - if (type != nullptr && expr->tav().type != nullptr && - is_type_any(type) && is_type_untyped(expr->tav().type)) { + expr->tav.mode = mode; + if (type != nullptr && expr->tav.type != nullptr && + is_type_any(type) && is_type_untyped(expr->tav.type)) { // ignore } else { - expr->tav().type = type; + expr->tav.type = type; } if (mode == Addressing_Constant || mode == Addressing_Invalid) { - expr->tav().value = value; + expr->tav.value = value; } else if (mode == Addressing_Value && is_type_typeid(type)) { - expr->tav().value = value; + expr->tav.value = value; } else if (mode == Addressing_Value && is_type_proc(type)) { - expr->tav().value = value; + expr->tav.value = value; } expr = unparen_expr(expr); @@ -3635,8 +3635,8 @@ gb_internal void check_collect_value_decl(CheckerContext *c, Ast *decl) { if (value != nullptr) { if (value->kind == Ast_BasicLit && value->BasicLit.token.kind == Token_String) { String v = {}; - if (value->tav().value.kind == ExactValue_String) { - v = value->tav().value.value_string; + if (value->tav.value.kind == ExactValue_String) { + v = value->tav.value.value_string; } if (v == "file") { kind = EntityVisiblity_PrivateToFile; diff --git a/src/llvm_backend_const.cpp b/src/llvm_backend_const.cpp index 6c5bb153f..ee564bbf1 100644 --- a/src/llvm_backend_const.cpp +++ b/src/llvm_backend_const.cpp @@ -57,7 +57,7 @@ gb_internal bool lb_is_const_nil(lbValue value) { gb_internal bool lb_is_expr_constant_zero(Ast *expr) { GB_ASSERT(expr != nullptr); - auto v = exact_value_to_integer(expr->tav().value); + auto v = exact_value_to_integer(expr->tav.value); if (v.kind == ExactValue_Integer) { return big_int_cmp_zero(&v.value_integer) == 0; } @@ -720,8 +720,8 @@ gb_internal lbValue lb_const_value(lbModule *m, Type *type, ExactValue value, bo ast_node(fv, FieldValue, elem); if (is_ast_range(fv->field)) { ast_node(ie, BinaryExpr, fv->field); - TypeAndValue lo_tav = ie->left->tav(); - TypeAndValue hi_tav = ie->right->tav(); + TypeAndValue lo_tav = ie->left->tav; + TypeAndValue hi_tav = ie->right->tav; GB_ASSERT(lo_tav.mode == Addressing_Constant); GB_ASSERT(hi_tav.mode == Addressing_Constant); @@ -732,7 +732,7 @@ gb_internal lbValue lb_const_value(lbModule *m, Type *type, ExactValue value, bo hi += 1; } if (lo == i) { - TypeAndValue tav = fv->value->tav(); + TypeAndValue tav = fv->value->tav; LLVMValueRef val = lb_const_value(m, elem_type, tav.value, allow_local).value; for (i64 k = lo; k < hi; k++) { values[value_index++] = val; @@ -743,11 +743,11 @@ gb_internal lbValue lb_const_value(lbModule *m, Type *type, ExactValue value, bo break; } } else { - TypeAndValue index_tav = fv->field->tav(); + TypeAndValue index_tav = fv->field->tav; GB_ASSERT(index_tav.mode == Addressing_Constant); i64 index = exact_value_to_i64(index_tav.value); if (index == i) { - TypeAndValue tav = fv->value->tav(); + TypeAndValue tav = fv->value->tav; LLVMValueRef val = lb_const_value(m, elem_type, tav.value, allow_local).value; values[value_index++] = val; found = true; @@ -769,7 +769,7 @@ gb_internal lbValue lb_const_value(lbModule *m, Type *type, ExactValue value, bo LLVMValueRef *values = gb_alloc_array(temporary_allocator(), LLVMValueRef, cast(isize)type->Array.count); for (isize i = 0; i < elem_count; i++) { - TypeAndValue tav = cl->elems[i]->tav(); + TypeAndValue tav = cl->elems[i]->tav; GB_ASSERT(tav.mode != Addressing_Invalid); values[i] = lb_const_value(m, elem_type, tav.value, allow_local).value; } @@ -804,8 +804,8 @@ gb_internal lbValue lb_const_value(lbModule *m, Type *type, ExactValue value, bo ast_node(fv, FieldValue, elem); if (is_ast_range(fv->field)) { ast_node(ie, BinaryExpr, fv->field); - TypeAndValue lo_tav = ie->left->tav(); - TypeAndValue hi_tav = ie->right->tav(); + TypeAndValue lo_tav = ie->left->tav; + TypeAndValue hi_tav = ie->right->tav; GB_ASSERT(lo_tav.mode == Addressing_Constant); GB_ASSERT(hi_tav.mode == Addressing_Constant); @@ -816,7 +816,7 @@ gb_internal lbValue lb_const_value(lbModule *m, Type *type, ExactValue value, bo hi += 1; } if (lo == i) { - TypeAndValue tav = fv->value->tav(); + TypeAndValue tav = fv->value->tav; LLVMValueRef val = lb_const_value(m, elem_type, tav.value, allow_local).value; for (i64 k = lo; k < hi; k++) { values[value_index++] = val; @@ -827,11 +827,11 @@ gb_internal lbValue lb_const_value(lbModule *m, Type *type, ExactValue value, bo break; } } else { - TypeAndValue index_tav = fv->field->tav(); + TypeAndValue index_tav = fv->field->tav; GB_ASSERT(index_tav.mode == Addressing_Constant); i64 index = exact_value_to_i64(index_tav.value); if (index == i) { - TypeAndValue tav = fv->value->tav(); + TypeAndValue tav = fv->value->tav; LLVMValueRef val = lb_const_value(m, elem_type, tav.value, allow_local).value; values[value_index++] = val; found = true; @@ -853,7 +853,7 @@ gb_internal lbValue lb_const_value(lbModule *m, Type *type, ExactValue value, bo LLVMValueRef *values = gb_alloc_array(temporary_allocator(), LLVMValueRef, cast(isize)type->EnumeratedArray.count); for (isize i = 0; i < elem_count; i++) { - TypeAndValue tav = cl->elems[i]->tav(); + TypeAndValue tav = cl->elems[i]->tav; GB_ASSERT(tav.mode != Addressing_Invalid); values[i] = lb_const_value(m, elem_type, tav.value, allow_local).value; } @@ -887,8 +887,8 @@ gb_internal lbValue lb_const_value(lbModule *m, Type *type, ExactValue value, bo ast_node(fv, FieldValue, elem); if (is_ast_range(fv->field)) { ast_node(ie, BinaryExpr, fv->field); - TypeAndValue lo_tav = ie->left->tav(); - TypeAndValue hi_tav = ie->right->tav(); + TypeAndValue lo_tav = ie->left->tav; + TypeAndValue hi_tav = ie->right->tav; GB_ASSERT(lo_tav.mode == Addressing_Constant); GB_ASSERT(hi_tav.mode == Addressing_Constant); @@ -899,7 +899,7 @@ gb_internal lbValue lb_const_value(lbModule *m, Type *type, ExactValue value, bo hi += 1; } if (lo == i) { - TypeAndValue tav = fv->value->tav(); + TypeAndValue tav = fv->value->tav; LLVMValueRef val = lb_const_value(m, elem_type, tav.value, allow_local).value; for (i64 k = lo; k < hi; k++) { values[value_index++] = val; @@ -910,11 +910,11 @@ gb_internal lbValue lb_const_value(lbModule *m, Type *type, ExactValue value, bo break; } } else { - TypeAndValue index_tav = fv->field->tav(); + TypeAndValue index_tav = fv->field->tav; GB_ASSERT(index_tav.mode == Addressing_Constant); i64 index = exact_value_to_i64(index_tav.value); if (index == i) { - TypeAndValue tav = fv->value->tav(); + TypeAndValue tav = fv->value->tav; LLVMValueRef val = lb_const_value(m, elem_type, tav.value, allow_local).value; values[value_index++] = val; found = true; @@ -932,7 +932,7 @@ gb_internal lbValue lb_const_value(lbModule *m, Type *type, ExactValue value, bo return res; } else { for (isize i = 0; i < elem_count; i++) { - TypeAndValue tav = cl->elems[i]->tav(); + TypeAndValue tav = cl->elems[i]->tav; GB_ASSERT(tav.mode != Addressing_Invalid); values[i] = lb_const_value(m, elem_type, tav.value, allow_local).value; } @@ -974,7 +974,7 @@ gb_internal lbValue lb_const_value(lbModule *m, Type *type, ExactValue value, bo ast_node(fv, FieldValue, cl->elems[i]); String name = fv->field->Ident.token.string; - TypeAndValue tav = fv->value->tav(); + TypeAndValue tav = fv->value->tav; GB_ASSERT(tav.mode != Addressing_Invalid); Selection sel = lookup_field(type, name, false); @@ -989,7 +989,7 @@ gb_internal lbValue lb_const_value(lbModule *m, Type *type, ExactValue value, bo } else { for_array(i, cl->elems) { Entity *f = type->Struct.fields[i]; - TypeAndValue tav = cl->elems[i]->tav(); + TypeAndValue tav = cl->elems[i]->tav; ExactValue val = {}; if (tav.mode != Addressing_Invalid) { val = tav.value; @@ -1073,7 +1073,7 @@ gb_internal lbValue lb_const_value(lbModule *m, Type *type, ExactValue value, bo Ast *e = cl->elems[i]; GB_ASSERT(e->kind != Ast_FieldValue); - TypeAndValue tav = e->tav(); + TypeAndValue tav = e->tav; if (tav.mode != Addressing_Constant) { continue; } @@ -1106,8 +1106,8 @@ gb_internal lbValue lb_const_value(lbModule *m, Type *type, ExactValue value, bo ast_node(fv, FieldValue, elem); if (is_ast_range(fv->field)) { ast_node(ie, BinaryExpr, fv->field); - TypeAndValue lo_tav = ie->left->tav(); - TypeAndValue hi_tav = ie->right->tav(); + TypeAndValue lo_tav = ie->left->tav; + TypeAndValue hi_tav = ie->right->tav; GB_ASSERT(lo_tav.mode == Addressing_Constant); GB_ASSERT(hi_tav.mode == Addressing_Constant); @@ -1122,7 +1122,7 @@ gb_internal lbValue lb_const_value(lbModule *m, Type *type, ExactValue value, bo GB_ASSERT(lo <= hi); - TypeAndValue tav = fv->value->tav(); + TypeAndValue tav = fv->value->tav; LLVMValueRef val = lb_const_value(m, elem_type, tav.value, allow_local).value; for (i64 k = lo; k < hi; k++) { i64 offset = matrix_row_major_index_to_offset(type, k); @@ -1130,11 +1130,11 @@ gb_internal lbValue lb_const_value(lbModule *m, Type *type, ExactValue value, bo values[offset] = val; } } else { - TypeAndValue index_tav = fv->field->tav(); + TypeAndValue index_tav = fv->field->tav; GB_ASSERT(index_tav.mode == Addressing_Constant); i64 index = exact_value_to_i64(index_tav.value); GB_ASSERT(index < max_count); - TypeAndValue tav = fv->value->tav(); + TypeAndValue tav = fv->value->tav; LLVMValueRef val = lb_const_value(m, elem_type, tav.value, allow_local).value; i64 offset = matrix_row_major_index_to_offset(type, index); GB_ASSERT(values[offset] == nullptr); @@ -1156,7 +1156,7 @@ gb_internal lbValue lb_const_value(lbModule *m, Type *type, ExactValue value, bo LLVMValueRef *values = gb_alloc_array(temporary_allocator(), LLVMValueRef, cast(isize)total_count); for_array(i, cl->elems) { - TypeAndValue tav = cl->elems[i]->tav(); + TypeAndValue tav = cl->elems[i]->tav; GB_ASSERT(tav.mode != Addressing_Invalid); i64 offset = matrix_row_major_index_to_offset(type, i); values[offset] = lb_const_value(m, elem_type, tav.value, allow_local).value; diff --git a/src/llvm_backend_expr.cpp b/src/llvm_backend_expr.cpp index 794ed7720..d574caf4c 100644 --- a/src/llvm_backend_expr.cpp +++ b/src/llvm_backend_expr.cpp @@ -1330,7 +1330,7 @@ gb_internal lbValue lb_build_binary_expr(lbProcedure *p, Ast *expr) { TypeAndValue tv = type_and_value_of_expr(expr); - if (is_type_matrix(be->left->tav().type) || is_type_matrix(be->right->tav().type)) { + if (is_type_matrix(be->left->tav.type) || is_type_matrix(be->right->tav.type)) { lbValue left = lb_build_expr(p, be->left); lbValue right = lb_build_expr(p, be->right); return lb_emit_arith_matrix(p, be->op.kind, left, right, default_type(tv.type), false); @@ -1372,12 +1372,12 @@ gb_internal lbValue lb_build_binary_expr(lbProcedure *p, Ast *expr) { case Token_CmpEq: case Token_NotEq: - if (is_type_untyped_nil(be->right->tav().type)) { + if (is_type_untyped_nil(be->right->tav.type)) { lbValue left = lb_build_expr(p, be->left); lbValue cmp = lb_emit_comp_against_nil(p, be->op.kind, left); Type *type = default_type(tv.type); return lb_emit_conv(p, cmp, type); - } else if (is_type_untyped_nil(be->left->tav().type)) { + } else if (is_type_untyped_nil(be->left->tav.type)) { lbValue right = lb_build_expr(p, be->right); lbValue cmp = lb_emit_comp_against_nil(p, be->op.kind, right); Type *type = default_type(tv.type); @@ -1392,11 +1392,11 @@ gb_internal lbValue lb_build_binary_expr(lbProcedure *p, Ast *expr) { lbValue left = {}; lbValue right = {}; - if (be->left->tav().mode == Addressing_Type) { - left = lb_typeid(p->module, be->left->tav().type); + if (be->left->tav.mode == Addressing_Type) { + left = lb_typeid(p->module, be->left->tav.type); } - if (be->right->tav().mode == Addressing_Type) { - right = lb_typeid(p->module, be->right->tav().type); + if (be->right->tav.mode == Addressing_Type) { + right = lb_typeid(p->module, be->right->tav.type); } if (left.value == nullptr) left = lb_build_expr(p, be->left); if (right.value == nullptr) right = lb_build_expr(p, be->right); @@ -3093,7 +3093,7 @@ gb_internal lbValue lb_build_expr_internal(lbProcedure *p, Ast *expr) { if (tv.value.kind != ExactValue_Invalid) { // NOTE(bill): The commented out code below is just for debug purposes only // if (is_type_untyped(type)) { - // gb_printf_err("%s %s : %s @ %p\n", token_pos_to_string(expr_pos), expr_to_string(expr), type_to_string(expr->tav().type), expr); + // gb_printf_err("%s %s : %s @ %p\n", token_pos_to_string(expr_pos), expr_to_string(expr), type_to_string(expr->tav.type), expr); // GB_PANIC("%s\n", type_to_string(tv.type)); // } @@ -3514,8 +3514,8 @@ gb_internal void lb_build_addr_compound_lit_populate(lbProcedure *p, Slicefield)) { ast_node(ie, BinaryExpr, fv->field); - TypeAndValue lo_tav = ie->left->tav(); - TypeAndValue hi_tav = ie->right->tav(); + TypeAndValue lo_tav = ie->left->tav; + TypeAndValue hi_tav = ie->right->tav; GB_ASSERT(lo_tav.mode == Addressing_Constant); GB_ASSERT(hi_tav.mode == Addressing_Constant); @@ -3556,7 +3556,7 @@ gb_internal void lb_build_addr_compound_lit_populate(lbProcedure *p, Slicefield->tav(); + auto tav = fv->field->tav; GB_ASSERT(tav.mode == Addressing_Constant); i64 index = exact_value_to_i64(tav.value); @@ -3632,7 +3632,7 @@ gb_internal lbAddr lb_build_addr_index_expr(lbProcedure *p, Ast *expr) { return lb_addr_soa_variable(val, index, ie->index); } - if (ie->expr->tav().mode == Addressing_SoaVariable) { + if (ie->expr->tav.mode == Addressing_SoaVariable) { // SOA Structures for slices/dynamic arrays GB_ASSERT(is_type_pointer(type_of_expr(ie->expr))); @@ -4451,8 +4451,8 @@ gb_internal lbAddr lb_build_addr_internal(lbProcedure *p, Ast *expr) { a = lb_addr_get_ptr(p, addr); } - GB_ASSERT(is_type_array(expr->tav().type)); - return lb_addr_swizzle(a, expr->tav().type, swizzle_count, swizzle_indices); + GB_ASSERT(is_type_array(expr->tav.type)); + return lb_addr_swizzle(a, expr->tav.type, swizzle_count, swizzle_indices); } Selection sel = lookup_field(type, selector, false); @@ -4621,7 +4621,7 @@ gb_internal lbAddr lb_build_addr_internal(lbProcedure *p, Ast *expr) { case_ast_node(ce, CallExpr, expr); BuiltinProcId builtin_id = BuiltinProc_Invalid; - if (ce->proc->tav().mode == Addressing_Builtin) { + if (ce->proc->tav.mode == Addressing_Builtin) { Entity *e = entity_of_node(ce->proc); if (e != nullptr) { builtin_id = cast(BuiltinProcId)e->Builtin.id; @@ -4629,7 +4629,7 @@ gb_internal lbAddr lb_build_addr_internal(lbProcedure *p, Ast *expr) { builtin_id = BuiltinProc_DIRECTIVE; } } - auto const &tv = expr->tav(); + auto const &tv = expr->tav; if (builtin_id == BuiltinProc_swizzle && is_type_array(tv.type)) { // NOTE(bill, 2021-08-09): `swizzle` has some bizarre semantics so it needs to be diff --git a/src/llvm_backend_proc.cpp b/src/llvm_backend_proc.cpp index 546d49027..384d29ca7 100644 --- a/src/llvm_backend_proc.cpp +++ b/src/llvm_backend_proc.cpp @@ -1516,7 +1516,7 @@ gb_internal lbValue lb_build_builtin_simd_proc(lbProcedure *p, Ast *expr, TypeAn BigInt bi_count = {}; big_int_from_i64(&bi_count, count); - TypeAndValue const &tv = ce->args[1]->tav(); + TypeAndValue const &tv = ce->args[1]->tav; ExactValue val = exact_value_to_integer(tv.value); GB_ASSERT(val.kind == ExactValue_Integer); BigInt *bi = &val.value_integer; @@ -2428,16 +2428,16 @@ gb_internal lbValue lb_build_builtin_proc(lbProcedure *p, Ast *expr, TypeAndValu case BuiltinProc_type_equal_proc: - return lb_equal_proc_for_type(p->module, ce->args[0]->tav().type); + return lb_equal_proc_for_type(p->module, ce->args[0]->tav.type); case BuiltinProc_type_hasher_proc: - return lb_hasher_proc_for_type(p->module, ce->args[0]->tav().type); + return lb_hasher_proc_for_type(p->module, ce->args[0]->tav.type); case BuiltinProc_type_map_info: - return lb_gen_map_info_ptr(p->module, ce->args[0]->tav().type); + return lb_gen_map_info_ptr(p->module, ce->args[0]->tav.type); case BuiltinProc_type_map_cell_info: - return lb_gen_map_cell_info_ptr(p->module, ce->args[0]->tav().type); + return lb_gen_map_cell_info_ptr(p->module, ce->args[0]->tav.type); case BuiltinProc_fixed_point_mul: @@ -2505,7 +2505,7 @@ gb_internal lbValue lb_build_builtin_proc(lbProcedure *p, Ast *expr, TypeAndValu case BuiltinProc_prefetch_write_data: { lbValue ptr = lb_emit_conv(p, lb_build_expr(p, ce->args[0]), t_rawptr); - unsigned long long locality = cast(unsigned long long)exact_value_to_i64(ce->args[1]->tav().value); + unsigned long long locality = cast(unsigned long long)exact_value_to_i64(ce->args[1]->tav.value); unsigned long long rw = 0; unsigned long long cache = 0; switch (id) { @@ -3060,8 +3060,8 @@ gb_internal lbValue lb_build_call_expr_internal(lbProcedure *p, Ast *expr) { } } - if (proc_expr->tav().mode == Addressing_Constant) { - ExactValue v = proc_expr->tav().value; + if (proc_expr->tav.mode == Addressing_Constant) { + ExactValue v = proc_expr->tav.value; switch (v.kind) { case ExactValue_Integer: { @@ -3070,7 +3070,7 @@ gb_internal lbValue lb_build_call_expr_internal(lbProcedure *p, Ast *expr) { x.value = LLVMConstInt(lb_type(m, t_uintptr), u, false); x.type = t_uintptr; x = lb_emit_conv(p, x, t_rawptr); - value = lb_emit_conv(p, x, proc_expr->tav().type); + value = lb_emit_conv(p, x, proc_expr->tav.type); break; } case ExactValue_Pointer: @@ -3080,7 +3080,7 @@ gb_internal lbValue lb_build_call_expr_internal(lbProcedure *p, Ast *expr) { x.value = LLVMConstInt(lb_type(m, t_uintptr), u, false); x.type = t_uintptr; x = lb_emit_conv(p, x, t_rawptr); - value = lb_emit_conv(p, x, proc_expr->tav().type); + value = lb_emit_conv(p, x, proc_expr->tav.type); break; } } diff --git a/src/llvm_backend_stmt.cpp b/src/llvm_backend_stmt.cpp index e0e991b4d..6400a8a9d 100644 --- a/src/llvm_backend_stmt.cpp +++ b/src/llvm_backend_stmt.cpp @@ -952,11 +952,11 @@ gb_internal void lb_build_unroll_range_stmt(lbProcedure *p, AstUnrollRangeStmt * TokenKind op = expr->BinaryExpr.op.kind; Ast *start_expr = expr->BinaryExpr.left; Ast *end_expr = expr->BinaryExpr.right; - GB_ASSERT(start_expr->tav().mode == Addressing_Constant); - GB_ASSERT(end_expr->tav().mode == Addressing_Constant); + GB_ASSERT(start_expr->tav.mode == Addressing_Constant); + GB_ASSERT(end_expr->tav.mode == Addressing_Constant); - ExactValue start = start_expr->tav().value; - ExactValue end = end_expr->tav().value; + ExactValue start = start_expr->tav.value; + ExactValue end = end_expr->tav.value; if (op != Token_RangeHalf) { // .. [start, end] (or ..=) ExactValue index = exact_value_i64(0); for (ExactValue val = start; @@ -1006,16 +1006,16 @@ gb_internal void lb_build_unroll_range_stmt(lbProcedure *p, AstUnrollRangeStmt * if (val0_type) val0_addr = lb_build_addr(p, rs->val0); if (val1_type) val1_addr = lb_build_addr(p, rs->val1); - GB_ASSERT(expr->tav().mode == Addressing_Constant); + GB_ASSERT(expr->tav.mode == Addressing_Constant); - Type *t = base_type(expr->tav().type); + Type *t = base_type(expr->tav.type); switch (t->kind) { case Type_Basic: GB_ASSERT(is_type_string(t)); { - ExactValue value = expr->tav().value; + ExactValue value = expr->tav.value; GB_ASSERT(value.kind == ExactValue_String); String str = value.value_string; Rune codepoint = 0; @@ -1109,7 +1109,7 @@ gb_internal bool lb_switch_stmt_can_be_trivial_jump_table(AstSwitchStmt *ss, boo if (is_ast_range(expr)) { return false; } - if (expr->tav().mode == Addressing_Type) { + if (expr->tav.mode == Addressing_Type) { GB_ASSERT(is_typeid); continue; } @@ -1209,12 +1209,12 @@ gb_internal void lb_build_switch_stmt(lbProcedure *p, AstSwitchStmt *ss, Scope * if (switch_instr != nullptr) { lbValue on_val = {}; - if (expr->tav().mode == Addressing_Type) { + if (expr->tav.mode == Addressing_Type) { GB_ASSERT(is_type_typeid(tag.type)); - lbValue e = lb_typeid(p->module, expr->tav().type); + lbValue e = lb_typeid(p->module, expr->tav.type); on_val = lb_emit_conv(p, e, tag.type); } else { - GB_ASSERT(expr->tav().mode == Addressing_Constant); + GB_ASSERT(expr->tav.mode == Addressing_Constant); GB_ASSERT(!is_ast_range(expr)); on_val = lb_build_expr(p, expr); @@ -1245,9 +1245,9 @@ gb_internal void lb_build_switch_stmt(lbProcedure *p, AstSwitchStmt *ss, Scope * lbValue cond_rhs = lb_emit_comp(p, op, tag, rhs); cond = lb_emit_arith(p, Token_And, cond_lhs, cond_rhs, t_bool); } else { - if (expr->tav().mode == Addressing_Type) { + if (expr->tav.mode == Addressing_Type) { GB_ASSERT(is_type_typeid(tag.type)); - lbValue e = lb_typeid(p->module, expr->tav().type); + lbValue e = lb_typeid(p->module, expr->tav.type); e = lb_emit_conv(p, e, tag.type); cond = lb_emit_comp(p, Token_CmpEq, tag, e); } else { @@ -1476,11 +1476,11 @@ gb_internal void lb_build_static_variables(lbProcedure *p, AstValueDecl *vd) { if (vd->values.count > 0) { GB_ASSERT(vd->names.count == vd->values.count); Ast *ast_value = vd->values[i]; - GB_ASSERT(ast_value->tav().mode == Addressing_Constant || - ast_value->tav().mode == Addressing_Invalid); + GB_ASSERT(ast_value->tav.mode == Addressing_Constant || + ast_value->tav.mode == Addressing_Invalid); bool allow_local = false; - value = lb_const_value(p->module, ast_value->tav().type, ast_value->tav().value, allow_local); + value = lb_const_value(p->module, ast_value->tav.type, ast_value->tav.value, allow_local); } Ast *ident = vd->names[i]; @@ -2068,7 +2068,7 @@ gb_internal void lb_build_assign_stmt(lbProcedure *p, AstAssignStmt *as) { op_ += Token_Add - Token_AddEq; // Convert += to + TokenKind op = cast(TokenKind)op_; if (op == Token_CmpAnd || op == Token_CmpOr) { - Type *type = as->lhs[0]->tav().type; + Type *type = as->lhs[0]->tav.type; lbValue new_value = lb_emit_logical_binary_expr(p, op, as->lhs[0], as->rhs[0], type); lbAddr lhs = lb_build_addr(p, as->lhs[0]); diff --git a/src/llvm_backend_utility.cpp b/src/llvm_backend_utility.cpp index 6abcdfc04..dbed32b82 100644 --- a/src/llvm_backend_utility.cpp +++ b/src/llvm_backend_utility.cpp @@ -1929,7 +1929,7 @@ gb_internal lbAddr lb_handle_objc_find_or_register_selector(lbProcedure *p, Stri gb_internal lbValue lb_handle_objc_find_selector(lbProcedure *p, Ast *expr) { ast_node(ce, CallExpr, expr); - auto tav = ce->args[0]->tav(); + auto tav = ce->args[0]->tav; GB_ASSERT(tav.value.kind == ExactValue_String); String name = tav.value.value_string; return lb_addr_load(p, lb_handle_objc_find_or_register_selector(p, name)); @@ -1939,7 +1939,7 @@ gb_internal lbValue lb_handle_objc_register_selector(lbProcedure *p, Ast *expr) ast_node(ce, CallExpr, expr); lbModule *m = p->module; - auto tav = ce->args[0]->tav(); + auto tav = ce->args[0]->tav; GB_ASSERT(tav.value.kind == ExactValue_String); String name = tav.value.value_string; lbAddr dst = lb_handle_objc_find_or_register_selector(p, name); @@ -1975,7 +1975,7 @@ gb_internal lbAddr lb_handle_objc_find_or_register_class(lbProcedure *p, String gb_internal lbValue lb_handle_objc_find_class(lbProcedure *p, Ast *expr) { ast_node(ce, CallExpr, expr); - auto tav = ce->args[0]->tav(); + auto tav = ce->args[0]->tav; GB_ASSERT(tav.value.kind == ExactValue_String); String name = tav.value.value_string; return lb_addr_load(p, lb_handle_objc_find_or_register_class(p, name)); @@ -1985,7 +1985,7 @@ gb_internal lbValue lb_handle_objc_register_class(lbProcedure *p, Ast *expr) { ast_node(ce, CallExpr, expr); lbModule *m = p->module; - auto tav = ce->args[0]->tav(); + auto tav = ce->args[0]->tav; GB_ASSERT(tav.value.kind == ExactValue_String); String name = tav.value.value_string; lbAddr dst = lb_handle_objc_find_or_register_class(p, name); @@ -2045,8 +2045,8 @@ gb_internal lbValue lb_handle_objc_send(lbProcedure *p, Ast *expr) { lbValue id = lb_handle_objc_id(p, ce->args[1]); Ast *sel_expr = ce->args[2]; - GB_ASSERT(sel_expr->tav().value.kind == ExactValue_String); - lbValue sel = lb_addr_load(p, lb_handle_objc_find_or_register_selector(p, sel_expr->tav().value.value_string)); + GB_ASSERT(sel_expr->tav.value.kind == ExactValue_String); + lbValue sel = lb_addr_load(p, lb_handle_objc_find_or_register_selector(p, sel_expr->tav.value.value_string)); array_add(&args, id); array_add(&args, sel); diff --git a/src/parser.cpp b/src/parser.cpp index 42d8f62cf..436498c51 100644 --- a/src/parser.cpp +++ b/src/parser.cpp @@ -71,7 +71,6 @@ gb_internal Ast *alloc_ast_node(AstFile *f, AstKind kind) { Ast *node = cast(Ast *)gb_alloc(a, size); node->kind = kind; node->file_id = f ? f->id : 0; - node->tav_ = gb_alloc_item(a, TypeAndValue); global_total_node_memory_allocated.fetch_add(size); @@ -107,9 +106,6 @@ gb_internal Ast *clone_ast(Ast *node) { AstFile *f = node->thread_safe_file(); Ast *n = alloc_ast_node(f, node->kind); gb_memmove(n, node, ast_node_size(node->kind)); - TypeAndValue *new_tav = gb_alloc_item(ast_allocator(f), TypeAndValue); - *new_tav = *node->tav_; - n->tav_ = new_tav; switch (n->kind) { default: GB_PANIC("Unhandled Ast %.*s", LIT(ast_strings[n->kind])); break; @@ -654,8 +650,8 @@ gb_internal String string_value_from_token(AstFile *f, Token const &token) { gb_internal Ast *ast_basic_lit(AstFile *f, Token basic_lit) { Ast *result = alloc_ast_node(f, Ast_BasicLit); result->BasicLit.token = basic_lit; - result->tav().mode = Addressing_Constant; - result->tav().value = exact_value_from_token(f, basic_lit); + result->tav.mode = Addressing_Constant; + result->tav.value = exact_value_from_token(f, basic_lit); return result; } diff --git a/src/parser.hpp b/src/parser.hpp index e3d6b42d8..7d292ffce 100644 --- a/src/parser.hpp +++ b/src/parser.hpp @@ -754,7 +754,7 @@ struct AstCommonStuff { u8 state_flags; u8 viral_state_flags; i32 file_id; - TypeAndValue *tav_; // TODO(bill): Make this a pointer to minimize 'Ast' size + TypeAndValue tav; // TODO(bill): Make this a pointer to minimize 'Ast' size }; struct Ast { @@ -762,7 +762,7 @@ struct Ast { u8 state_flags; u8 viral_state_flags; i32 file_id; - TypeAndValue *tav_; // TODO(bill): Make this a pointer to minimize 'Ast' size + TypeAndValue tav; // TODO(bill): Make this a pointer to minimize 'Ast' size // IMPORTANT NOTE(bill): This must be at the end since the AST is allocated to be size of the variant union { @@ -771,9 +771,6 @@ struct Ast { #undef AST_KIND }; - gb_inline TypeAndValue &tav() const { - return *this->tav_; - } // NOTE(bill): I know I dislike methods but this is hopefully a temporary thing // for refactoring purposes -- cgit v1.2.3 From ffa14c3aad5472aab32711c2500c67df9a368601 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Thu, 22 Dec 2022 12:58:23 +0000 Subject: Remove need the MPMC in single threaded case --- src/checker.cpp | 20 +++++++++++--------- src/parser.cpp | 2 +- src/parser.hpp | 5 ++--- 3 files changed, 14 insertions(+), 13 deletions(-) (limited to 'src/checker.cpp') diff --git a/src/checker.cpp b/src/checker.cpp index 14a0e5f4c..29e4b6667 100644 --- a/src/checker.cpp +++ b/src/checker.cpp @@ -3941,7 +3941,7 @@ gb_internal void check_collect_entities(CheckerContext *c, Slice const &n if (c->collect_delayed_decls) { if (decl->state_flags & StateFlag_BeenHandled) return; decl->state_flags |= StateFlag_BeenHandled; - mpmc_enqueue(&curr_file->delayed_decls_queues[AstDelayQueue_Expr], expr); + array_add(&curr_file->delayed_decls_queues[AstDelayQueue_Expr], expr); } continue; } @@ -3969,7 +3969,7 @@ gb_internal void check_collect_entities(CheckerContext *c, Slice const &n continue; } // Will be handled later - mpmc_enqueue(&curr_file->delayed_decls_queues[AstDelayQueue_Import], decl); + array_add(&curr_file->delayed_decls_queues[AstDelayQueue_Import], decl); case_end; case_ast_node(fl, ForeignImportDecl, decl); @@ -4607,7 +4607,7 @@ gb_internal bool collect_file_decl(CheckerContext *ctx, Ast *decl) { if (es->expr->kind == Ast_CallExpr) { ast_node(ce, CallExpr, es->expr); if (ce->proc->kind == Ast_BasicDirective) { - mpmc_enqueue(&curr_file->delayed_decls_queues[AstDelayQueue_Expr], es->expr); + array_add(&curr_file->delayed_decls_queues[AstDelayQueue_Expr], es->expr); } } case_end; @@ -4861,9 +4861,10 @@ gb_internal void check_import_entities(Checker *c) { ctx.collect_delayed_decls = true; // Check import declarations first to simplify things - for (Ast *id = nullptr; mpmc_dequeue(&f->delayed_decls_queues[AstDelayQueue_Import], &id); /**/) { - check_add_import_decl(&ctx, id); + for (Ast *decl : f->delayed_decls_queues[AstDelayQueue_Import]) { + check_add_import_decl(&ctx, decl); } + array_clear(&f->delayed_decls_queues[AstDelayQueue_Import]); if (collect_file_decls(&ctx, f->decls)) { check_export_entities_in_pkg(&ctx, pkg, &untyped); @@ -4889,10 +4890,10 @@ gb_internal void check_import_entities(Checker *c) { AstFile *f = pkg->files[i]; reset_checker_context(&ctx, f, &untyped); - auto *q = &f->delayed_decls_queues[AstDelayQueue_Import]; - for (Ast *decl = nullptr; mpmc_dequeue(q, &decl); /**/) { + for (Ast *decl : f->delayed_decls_queues[AstDelayQueue_Import]) { check_add_import_decl(&ctx, decl); } + array_clear(&f->delayed_decls_queues[AstDelayQueue_Import]); add_untyped_expressions(ctx.info, &untyped); } @@ -4908,11 +4909,12 @@ gb_internal void check_import_entities(Checker *c) { AstFile *f = pkg->files[i]; reset_checker_context(&ctx, f, &untyped); - auto *q = &f->delayed_decls_queues[AstDelayQueue_Expr]; - for (Ast *expr = nullptr; mpmc_dequeue(q, &expr); /**/) { + for (Ast *expr : f->delayed_decls_queues[AstDelayQueue_Expr]) { Operand o = {}; check_expr(&ctx, &o, expr); } + array_clear(&f->delayed_decls_queues[AstDelayQueue_Expr]); + add_untyped_expressions(ctx.info, &untyped); } } diff --git a/src/parser.cpp b/src/parser.cpp index cb9713985..e07f26004 100644 --- a/src/parser.cpp +++ b/src/parser.cpp @@ -5651,7 +5651,7 @@ gb_internal bool parse_file(Parser *p, AstFile *f) { f->time_to_parse = cast(f64)(end-start)/cast(f64)time_stamp__freq(); for (int i = 0; i < AstDelayQueue_COUNT; i++) { - mpmc_init(f->delayed_decls_queues+i, heap_allocator(), f->delayed_decl_count); + array_init(f->delayed_decls_queues+i, heap_allocator(), 0, f->delayed_decl_count); } diff --git a/src/parser.hpp b/src/parser.hpp index 4357573c9..c33739ebe 100644 --- a/src/parser.hpp +++ b/src/parser.hpp @@ -132,9 +132,8 @@ struct AstFile { CommentGroup *docs; // current docs Array comments; // All the comments! - // TODO(bill): make this a basic queue as it does not require - // any multiple thread capabilities - MPMCQueue delayed_decls_queues[AstDelayQueue_COUNT]; + // This is effectively a queue but does not require any multi-threading capabilities + Array delayed_decls_queues[AstDelayQueue_COUNT]; #define PARSER_MAX_FIX_COUNT 6 isize fix_count; -- cgit v1.2.3 From 00823ca88c870d49186dbcaa21c54384c0b9364f Mon Sep 17 00:00:00 2001 From: gingerBill Date: Thu, 22 Dec 2022 13:03:34 +0000 Subject: Remove a few `TODO`s --- src/build_settings.cpp | 3 +-- src/check_builtin.cpp | 7 ++----- src/check_decl.cpp | 8 -------- src/checker.cpp | 9 ++------- src/checker.hpp | 4 ++-- 5 files changed, 7 insertions(+), 24 deletions(-) (limited to 'src/checker.cpp') diff --git a/src/build_settings.cpp b/src/build_settings.cpp index 630cec601..080e9dddc 100644 --- a/src/build_settings.cpp +++ b/src/build_settings.cpp @@ -394,7 +394,7 @@ gb_global TargetMetrics target_darwin_arm64 = { TargetArch_arm64, 8, 8, 16, str_lit("arm64-apple-macosx11.0.0"), - str_lit("e-m:o-i64:64-i128:128-n32:64-S128"), // TODO(bill): Is this correct? + str_lit("e-m:o-i64:64-i128:128-n32:64-S128"), }; gb_global TargetMetrics target_freebsd_i386 = { @@ -585,7 +585,6 @@ struct LibraryCollections { gb_global Array library_collections = {0}; gb_internal void add_library_collection(String name, String path) { - // TODO(bill): Check the path is valid and a directory LibraryCollections lc = {name, string_trim_whitespace(path)}; array_add(&library_collections, lc); } diff --git a/src/check_builtin.cpp b/src/check_builtin.cpp index 1c13b6b5e..99d956f5e 100644 --- a/src/check_builtin.cpp +++ b/src/check_builtin.cpp @@ -89,7 +89,6 @@ gb_internal void check_or_else_split_types(CheckerContext *c, Operand *x, String gb_internal void check_or_else_expr_no_value_error(CheckerContext *c, String const &name, Operand const &x, Type *type_hint) { - // TODO(bill): better error message gbString t = type_to_string(x.type); error(x.expr, "'%.*s' does not return a value, value is of type %s", LIT(name), t); if (is_type_union(type_deref(x.type))) { @@ -2559,7 +2558,7 @@ gb_internal bool check_builtin_procedure(CheckerContext *c, Operand *operand, As if (is_type_struct(type)) { isize variable_count = type->Struct.fields.count; slice_init(&tuple->Tuple.variables, a, variable_count); - // TODO(bill): Should I copy each of the entities or is this good enough? + // NOTE(bill): don't copy the entities, this should be good enough gb_memmove_array(tuple->Tuple.variables.data, type->Struct.fields.data, variable_count); } else if (is_type_array(type)) { isize variable_count = cast(isize)type->Array.count; @@ -3766,9 +3765,7 @@ gb_internal bool check_builtin_procedure(CheckerContext *c, Operand *operand, As mp_err err = mp_pack(rop, max_count, &written, MP_LSB_FIRST, size, endian, nails, &x.value.value_integer); GB_ASSERT(err == MP_OKAY); - if (id == BuiltinProc_reverse_bits) { - // TODO(bill): Should this even be allowed at compile time? - } else { + if (id != BuiltinProc_reverse_bits) { u64 v = 0; switch (id) { case BuiltinProc_count_ones: diff --git a/src/check_decl.cpp b/src/check_decl.cpp index d982a69fc..59beae56d 100644 --- a/src/check_decl.cpp +++ b/src/check_decl.cpp @@ -10,7 +10,6 @@ gb_internal Type *check_init_variable(CheckerContext *ctx, Entity *e, Operand *o gbString expr_str = expr_to_string(operand->expr); // TODO(bill): is this a good enough error message? - // TODO(bill): Actually allow built in procedures to be passed around and thus be created on use error(operand->expr, "Cannot assign built-in procedure '%s' in %.*s", expr_str, @@ -122,13 +121,6 @@ gb_internal void check_init_variables(CheckerContext *ctx, Entity **lhs, isize l check_unpack_arguments(ctx, lhs, lhs_count, &operands, inits, true, false); isize rhs_count = operands.count; - for_array(i, operands) { - if (operands[i].mode == Addressing_Invalid) { - // TODO(bill): Should I ignore invalid parameters? - // rhs_count--; - } - } - isize max = gb_min(lhs_count, rhs_count); for (isize i = 0; i < max; i++) { Entity *e = lhs[i]; diff --git a/src/checker.cpp b/src/checker.cpp index 29e4b6667..b78da2827 100644 --- a/src/checker.cpp +++ b/src/checker.cpp @@ -404,7 +404,6 @@ gb_internal void scope_lookup_parent(Scope *scope, String const &name, Scope **s if (found) { Entity *e = *found; if (gone_thru_proc) { - // IMPORTANT TODO(bill): Is this correct?! if (e->kind == Entity_Label) { continue; } @@ -1409,8 +1408,7 @@ gb_internal isize type_info_index(CheckerInfo *info, Type *type, bool error_on_f entry_index = *found_entry_index; } if (entry_index < 0) { - // NOTE(bill): Do manual search - // TODO(bill): This is O(n) and can be very slow + // 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; @@ -2350,7 +2348,7 @@ gb_internal void generate_minimum_dependency_set(Checker *c, Entity *start) { for_array(i, c->info.definitions) { Entity *e = c->info.definitions[i]; - if (e->scope == builtin_pkg->scope) { // TODO(bill): is the check enough? + if (e->scope == builtin_pkg->scope) { if (e->type == nullptr) { add_dependency_to_set(c, e); } @@ -3965,7 +3963,6 @@ gb_internal void check_collect_entities(CheckerContext *c, Slice const &n if (curr_file == nullptr) { error(decl, "import declarations are only allowed in the file scope"); // NOTE(bill): _Should_ be caught by the parser - // TODO(bill): Better error handling if it isn't continue; } // Will be handled later @@ -3976,7 +3973,6 @@ gb_internal void check_collect_entities(CheckerContext *c, Slice const &n if ((c->scope->flags&ScopeFlag_File) == 0) { error(decl, "%.*s declarations are only allowed in the file scope", LIT(fl->token.string)); // NOTE(bill): _Should_ be caught by the parser - // TODO(bill): Better error handling if it isn't continue; } check_add_foreign_import_decl(c, decl); @@ -4167,7 +4163,6 @@ gb_internal void add_import_dependency_node(Checker *c, Ast *decl, PtrMapsucc, m); import_graph_node_set_add(&m->pred, n); ptr_set_add(&m->scope->imported, n->scope); diff --git a/src/checker.hpp b/src/checker.hpp index 6799503cd..1d6019b79 100644 --- a/src/checker.hpp +++ b/src/checker.hpp @@ -390,7 +390,7 @@ struct CheckerContext { // Order doesn't matter after this u32 state_flags; - bool in_defer; // TODO(bill): Actually handle correctly + bool in_defer; Type * type_hint; String proc_name; @@ -401,7 +401,7 @@ struct CheckerContext { ForeignContext foreign_context; CheckerTypePath *type_path; - isize type_level; // TODO(bill): Actually handle correctly + isize type_level; UntypedExprInfoMap *untyped; -- cgit v1.2.3 From 5c519f0e8dada6b15166a257d22a07f2316a394f Mon Sep 17 00:00:00 2001 From: gingerBill Date: Sun, 1 Jan 2023 16:19:21 +0000 Subject: Remove the synchronization primitive init/destroy calls --- src/build_settings.cpp | 1 - src/checker.cpp | 36 ------------------------------------ src/common_memory.cpp | 2 -- src/entity.cpp | 1 - src/error.cpp | 4 ---- src/llvm_backend_general.cpp | 1 - src/main.cpp | 5 ----- src/parser.cpp | 11 ----------- src/queue.cpp | 2 -- src/string.cpp | 5 ----- src/thread_pool.cpp | 5 ----- src/threading.cpp | 35 +---------------------------------- src/types.cpp | 4 ---- 13 files changed, 1 insertion(+), 111 deletions(-) (limited to 'src/checker.cpp') diff --git a/src/build_settings.cpp b/src/build_settings.cpp index 080e9dddc..97b512b81 100644 --- a/src/build_settings.cpp +++ b/src/build_settings.cpp @@ -1363,7 +1363,6 @@ gb_internal bool init_build_paths(String init_filename) { array_init(&bc->build_paths, permanent_allocator(), BuildPathCOUNT); string_set_init(&bc->target_features_set, heap_allocator(), 1024); - mutex_init(&bc->target_features_mutex); // [BuildPathMainPackage] Turn given init path into a `Path`, which includes normalizing it into a full path. bc->build_paths[BuildPath_Main_Package] = path_from_string(ha, init_filename); diff --git a/src/checker.cpp b/src/checker.cpp index b78da2827..7141b0698 100644 --- a/src/checker.cpp +++ b/src/checker.cpp @@ -184,7 +184,6 @@ gb_internal void init_decl_info(DeclInfo *d, Scope *scope, DeclInfo *parent) { ptr_set_init(&d->deps, heap_allocator()); ptr_set_init(&d->type_info_deps, heap_allocator()); array_init (&d->labels, heap_allocator()); - mutex_init(&d->proc_checked_mutex); } gb_internal DeclInfo *make_decl_info(Scope *scope, DeclInfo *parent) { @@ -225,7 +224,6 @@ gb_internal Scope *create_scope(CheckerInfo *info, Scope *parent, isize init_ele s->parent = parent; string_map_init(&s->elements, heap_allocator(), init_elements_capacity); ptr_set_init(&s->imported, heap_allocator(), 0); - mutex_init(&s->mutex); if (parent != nullptr && parent != builtin_pkg->scope) { Scope *prev_head_child = parent->head_child.exchange(s, std::memory_order_acq_rel); @@ -306,7 +304,6 @@ gb_internal void destroy_scope(Scope *scope) { string_map_destroy(&scope->elements); ptr_set_destroy(&scope->imported); - mutex_destroy(&scope->mutex); // NOTE(bill): No need to free scope as it "should" be allocated in an arena (except for the global scope) } @@ -1134,24 +1131,9 @@ gb_internal void init_checker_info(CheckerInfo *i) { TIME_SECTION("checker info: mutexes"); - mutex_init(&i->gen_procs_mutex); - mutex_init(&i->gen_types_mutex); - mutex_init(&i->lazy_mutex); - mutex_init(&i->builtin_mutex); - mutex_init(&i->global_untyped_mutex); - mutex_init(&i->type_info_mutex); - mutex_init(&i->deps_mutex); - mutex_init(&i->type_and_value_mutex); - mutex_init(&i->identifier_uses_mutex); - mutex_init(&i->foreign_mutex); - - semaphore_init(&i->collect_semaphore); - mpmc_init(&i->intrinsics_entry_point_usage, a, 1<<10); // just waste some memory here, even if it probably never used - mutex_init(&i->objc_types_mutex); map_init(&i->objc_msgSend_types, a); - mutex_init(&i->load_file_mutex); string_map_init(&i->load_file_cache, a); } @@ -1175,20 +1157,7 @@ gb_internal void destroy_checker_info(CheckerInfo *i) { mpmc_destroy(&i->required_global_variable_queue); mpmc_destroy(&i->required_foreign_imports_through_force_queue); - mutex_destroy(&i->gen_procs_mutex); - mutex_destroy(&i->gen_types_mutex); - mutex_destroy(&i->lazy_mutex); - mutex_destroy(&i->builtin_mutex); - mutex_destroy(&i->global_untyped_mutex); - mutex_destroy(&i->type_info_mutex); - mutex_destroy(&i->deps_mutex); - mutex_destroy(&i->type_and_value_mutex); - mutex_destroy(&i->identifier_uses_mutex); - mutex_destroy(&i->foreign_mutex); - - mutex_destroy(&i->objc_types_mutex); map_destroy(&i->objc_msgSend_types); - mutex_init(&i->load_file_mutex); string_map_destroy(&i->load_file_cache); } @@ -1201,11 +1170,9 @@ gb_internal CheckerContext make_checker_context(Checker *c) { ctx.type_path = new_checker_type_path(); ctx.type_level = 0; - mutex_init(&ctx.mutex); return ctx; } gb_internal void destroy_checker_context(CheckerContext *ctx) { - mutex_destroy(&ctx->mutex); destroy_checker_type_path(ctx->type_path); } @@ -1264,7 +1231,6 @@ gb_internal void init_checker(Checker *c) { // NOTE(bill): 1 Mi elements should be enough on average mpmc_init(&c->procs_to_check_queue, heap_allocator(), 1<<20); - semaphore_init(&c->procs_to_check_semaphore); mpmc_init(&c->global_untyped_queue, a, 1<<20); @@ -1277,8 +1243,6 @@ gb_internal void destroy_checker(Checker *c) { destroy_checker_context(&c->builtin_ctx); mpmc_destroy(&c->procs_to_check_queue); - semaphore_destroy(&c->procs_to_check_semaphore); - mpmc_destroy(&c->global_untyped_queue); } diff --git a/src/common_memory.cpp b/src/common_memory.cpp index c8a62756a..2022554cf 100644 --- a/src/common_memory.cpp +++ b/src/common_memory.cpp @@ -42,8 +42,6 @@ gb_global BlockingMutex global_memory_allocator_mutex; gb_internal void platform_virtual_memory_init(void); gb_internal void virtual_memory_init(void) { - mutex_init(&global_memory_block_mutex); - mutex_init(&global_memory_allocator_mutex); platform_virtual_memory_init(); } diff --git a/src/entity.cpp b/src/entity.cpp index 0605a293a..f82a2fb05 100644 --- a/src/entity.cpp +++ b/src/entity.cpp @@ -154,7 +154,6 @@ struct TypeNameObjCMetadata { gb_internal TypeNameObjCMetadata *create_type_name_obj_c_metadata() { TypeNameObjCMetadata *md = gb_alloc_item(permanent_allocator(), TypeNameObjCMetadata); md->mutex = gb_alloc_item(permanent_allocator(), BlockingMutex); - mutex_init(md->mutex); array_init(&md->type_entries, heap_allocator()); array_init(&md->value_entries, heap_allocator()); return md; diff --git a/src/error.cpp b/src/error.cpp index 085e1a8dd..a0bb4ad5b 100644 --- a/src/error.cpp +++ b/src/error.cpp @@ -22,10 +22,6 @@ gb_internal bool any_errors(void) { } gb_internal void init_global_error_collector(void) { - mutex_init(&global_error_collector.mutex); - mutex_init(&global_error_collector.block_mutex); - mutex_init(&global_error_collector.error_out_mutex); - mutex_init(&global_error_collector.string_mutex); array_init(&global_error_collector.errors, heap_allocator()); array_init(&global_error_collector.error_buffer, heap_allocator()); array_init(&global_file_path_strings, heap_allocator(), 1, 4096); diff --git a/src/llvm_backend_general.cpp b/src/llvm_backend_general.cpp index e5aa95f10..0508c6171 100644 --- a/src/llvm_backend_general.cpp +++ b/src/llvm_backend_general.cpp @@ -132,7 +132,6 @@ gb_internal bool lb_init_generator(lbGenerator *gen, Checker *c) { map_init(&gen->anonymous_proc_lits, heap_allocator(), 1024); - mutex_init(&gen->foreign_mutex); array_init(&gen->foreign_libraries, heap_allocator(), 0, 1024); ptr_set_init(&gen->foreign_libraries_set, heap_allocator(), 1024); diff --git a/src/main.cpp b/src/main.cpp index 6d910c7bf..184ab471e 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -2498,15 +2498,10 @@ int main(int arg_count, char const **arg_ptr) { MAIN_TIME_SECTION("initialization"); virtual_memory_init(); - mutex_init(&fullpath_mutex); - mutex_init(&hash_exact_value_mutex); - mutex_init(&global_type_name_objc_metadata_mutex); - init_string_buffer_memory(); init_string_interner(); init_global_error_collector(); init_keyword_hash_table(); - init_type_mutex(); if (!check_env()) { return 1; diff --git a/src/parser.cpp b/src/parser.cpp index e07f26004..344dcb20d 100644 --- a/src/parser.cpp +++ b/src/parser.cpp @@ -4858,10 +4858,6 @@ gb_internal bool init_parser(Parser *p) { GB_ASSERT(p != nullptr); string_set_init(&p->imported_files, heap_allocator()); array_init(&p->packages, heap_allocator()); - mutex_init(&p->imported_files_mutex); - mutex_init(&p->file_decl_mutex); - mutex_init(&p->packages_mutex); - mutex_init(&p->file_error_mutex); return true; } @@ -4878,10 +4874,6 @@ gb_internal void destroy_parser(Parser *p) { } array_free(&p->packages); string_set_destroy(&p->imported_files); - mutex_destroy(&p->imported_files_mutex); - mutex_destroy(&p->file_decl_mutex); - mutex_destroy(&p->packages_mutex); - mutex_destroy(&p->file_error_mutex); } @@ -4978,9 +4970,6 @@ gb_internal AstPackage *try_add_import_path(Parser *p, String const &path, Strin pkg->fullpath = path; array_init(&pkg->files, heap_allocator()); pkg->foreign_files.allocator = heap_allocator(); - mutex_init(&pkg->files_mutex); - mutex_init(&pkg->foreign_files_mutex); - // NOTE(bill): Single file initial package if (kind == Package_Init && string_ends_with(path, FILE_EXT)) { diff --git a/src/queue.cpp b/src/queue.cpp index 4de5ac5e5..8f279bb21 100644 --- a/src/queue.cpp +++ b/src/queue.cpp @@ -52,7 +52,6 @@ gb_internal void mpmc_init(MPMCQueue *q, gbAllocator a, isize size_i) { size = next_pow2(size); GB_ASSERT(gb_is_power_of_two(size)); - mutex_init(&q->mutex); q->mask = size-1; q->allocator = a; q->nodes = gb_alloc_array(a, T, size); @@ -65,7 +64,6 @@ gb_internal void mpmc_init(MPMCQueue *q, gbAllocator a, isize size_i) { template gb_internal void mpmc_destroy(MPMCQueue *q) { - mutex_destroy(&q->mutex); gb_free(q->allocator, q->nodes); gb_free(q->allocator, q->indices); } diff --git a/src/string.cpp b/src/string.cpp index 8cce0f1ef..a2254d100 100644 --- a/src/string.cpp +++ b/src/string.cpp @@ -1,10 +1,5 @@ gb_global BlockingMutex string_buffer_mutex = {}; -gb_internal void init_string_buffer_memory(void) { - mutex_init(&string_buffer_mutex); -} - - // NOTE(bill): Used for UTF-8 strings struct String { u8 * text; diff --git a/src/thread_pool.cpp b/src/thread_pool.cpp index 57ed5e3c5..522b96d09 100644 --- a/src/thread_pool.cpp +++ b/src/thread_pool.cpp @@ -23,9 +23,6 @@ struct ThreadPool { }; gb_internal void thread_pool_init(ThreadPool *pool, gbAllocator const &a, isize thread_count, char const *worker_name) { - mutex_init(&pool->task_lock); - condition_init(&pool->tasks_available); - pool->allocator = a; slice_init(&pool->threads, a, thread_count + 1); @@ -54,8 +51,6 @@ gb_internal void thread_pool_destroy(ThreadPool *pool) { } gb_free(pool->allocator, pool->threads.data); - mutex_destroy(&pool->task_lock); - condition_destroy(&pool->tasks_available); } void thread_pool_queue_push(Thread *thread, WorkerTask task) { diff --git a/src/threading.cpp b/src/threading.cpp index 7dd1247e7..fb71a2c29 100644 --- a/src/threading.cpp +++ b/src/threading.cpp @@ -48,30 +48,22 @@ gb_internal void futex_wait(Futex *addr, Footex val); gb_internal void futex_signal(Futex *addr); gb_internal void futex_broadcast(Futex *addr); -gb_internal void mutex_init (BlockingMutex *m); -gb_internal void mutex_destroy (BlockingMutex *m); gb_internal void mutex_lock (BlockingMutex *m); gb_internal bool mutex_try_lock(BlockingMutex *m); gb_internal void mutex_unlock (BlockingMutex *m); -gb_internal void mutex_init (RecursiveMutex *m); -gb_internal void mutex_destroy (RecursiveMutex *m); + gb_internal void mutex_lock (RecursiveMutex *m); gb_internal bool mutex_try_lock(RecursiveMutex *m); gb_internal void mutex_unlock (RecursiveMutex *m); -gb_internal void semaphore_init (Semaphore *s); -gb_internal void semaphore_destroy(Semaphore *s); gb_internal void semaphore_post (Semaphore *s, i32 count); gb_internal void semaphore_wait (Semaphore *s); gb_internal void semaphore_release(Semaphore *s) { semaphore_post(s, 1); } -gb_internal void condition_init(Condition *c); -gb_internal void condition_destroy(Condition *c); gb_internal void condition_broadcast(Condition *c); gb_internal void condition_signal(Condition *c); gb_internal void condition_wait(Condition *c, BlockingMutex *m); -gb_internal void condition_wait_with_timeout(Condition *c, BlockingMutex *m, u32 timeout_in_ms); gb_internal u32 thread_current_id(void); @@ -122,12 +114,7 @@ struct RecursiveMutex { Futex owner; i32 recursion; }; -gb_internal void mutex_init(RecursiveMutex *m) { - -} -gb_internal void mutex_destroy(RecursiveMutex *m) { -} gb_internal void mutex_lock(RecursiveMutex *m) { Futex tid = cast(i32)thread_current_id(); for (;;) { @@ -166,12 +153,6 @@ struct Semaphore { Futex count; }; -gb_internal void semaphore_init(Semaphore *s) { - -} -gb_internal void semaphore_destroy(Semaphore *s) { - -} gb_internal void semaphore_post(Semaphore *s, i32 count) { s->count.fetch_add(count, std::memory_order_release); if (s->count == 1) { @@ -198,10 +179,6 @@ gb_internal void semaphore_wait(Semaphore *s) { struct BlockingMutex { SRWLOCK srwlock; }; - gb_internal void mutex_init(BlockingMutex *m) { - } - gb_internal void mutex_destroy(BlockingMutex *m) { - } gb_internal void mutex_lock(BlockingMutex *m) { AcquireSRWLockExclusive(&m->srwlock); } @@ -229,10 +206,6 @@ gb_internal void semaphore_wait(Semaphore *s) { gb_internal void condition_wait(Condition *c, BlockingMutex *m) { SleepConditionVariableSRW(&c->cond, &m->srwlock, INFINITE, 0); } - gb_internal void condition_wait_with_timeout(Condition *c, BlockingMutex *m, u32 timeout_in_ms) { - SleepConditionVariableSRW(&c->cond, &m->srwlock, timeout_in_ms, 0); - } - #else enum Internal_Mutex_State : i32 { Internal_Mutex_State_Unlocked = 0, @@ -251,9 +224,6 @@ gb_internal void semaphore_wait(Semaphore *s) { } }; - gb_internal void mutex_init(BlockingMutex *m) {}; - gb_internal void mutex_destroy(BlockingMutex *m) {}; - gb_no_inline gb_internal void mutex_lock_slow(BlockingMutex *m, i32 curr_state) { i32 new_state = curr_state; for (i32 spin = 0; spin < 100; spin++) { @@ -323,9 +293,6 @@ gb_internal void semaphore_wait(Semaphore *s) { } }; - gb_internal void condition_init(Condition *c) {} - gb_internal void condition_destroy(Condition *c) {} - gb_internal void condition_broadcast(Condition *c) { c->state().fetch_add(1, std::memory_order_release); futex_broadcast(&c->state()); diff --git a/src/types.cpp b/src/types.cpp index 5bddfc79e..afe0b7d5d 100644 --- a/src/types.cpp +++ b/src/types.cpp @@ -808,10 +808,6 @@ gb_internal void type_path_pop(TypePath *tp) { #define FAILURE_SIZE 0 #define FAILURE_ALIGNMENT 0 -gb_internal void init_type_mutex(void) { - mutex_init(&g_type_mutex); -} - gb_internal bool type_ptr_set_update(PtrSet *s, Type *t) { if (ptr_set_exists(s, t)) { return true; -- cgit v1.2.3 From 3c90a059571cb879a468a00c0ca26c9a35090c38 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Mon, 2 Jan 2023 00:26:17 +0000 Subject: Replace condition+mutex with futex --- src/checker.cpp | 3 ++- src/thread_pool.cpp | 72 +++++++++++++++++++++++++---------------------------- src/threading.cpp | 4 ++- 3 files changed, 39 insertions(+), 40 deletions(-) (limited to 'src/checker.cpp') diff --git a/src/checker.cpp b/src/checker.cpp index 7141b0698..03ff901eb 100644 --- a/src/checker.cpp +++ b/src/checker.cpp @@ -1935,7 +1935,7 @@ gb_internal void add_type_info_type_internal(CheckerContext *c, Type *t) { -gb_global bool global_procedure_body_in_worker_queue = false; +gb_global std::atomic global_procedure_body_in_worker_queue = false; gb_internal void check_procedure_later(CheckerContext *c, ProcInfo *info) { GB_ASSERT(info != nullptr); @@ -5264,6 +5264,7 @@ gb_internal WORKER_TASK_PROC(thread_proc_body) { gb_internal void check_procedure_bodies(Checker *c) { GB_ASSERT(c != nullptr); + u32 thread_count = cast(u32)gb_max(build_context.thread_count, 1); u32 worker_count = thread_count-1; // NOTE(bill): The main thread will also be used for work if (!build_context.threaded_checker) { diff --git a/src/thread_pool.cpp b/src/thread_pool.cpp index 522b96d09..768a92645 100644 --- a/src/thread_pool.cpp +++ b/src/thread_pool.cpp @@ -16,8 +16,7 @@ struct ThreadPool { Slice threads; std::atomic running; - BlockingMutex task_lock; - Condition tasks_available; + Futex tasks_available; Futex tasks_left; }; @@ -43,27 +42,25 @@ gb_internal void thread_pool_destroy(ThreadPool *pool) { for_array_off(i, 1, pool->threads) { Thread *t = &pool->threads[i]; - condition_broadcast(&pool->tasks_available); + pool->tasks_available.fetch_add(1, std::memory_order_release); + futex_broadcast(&pool->tasks_available); thread_join_and_destroy(t); } - for_array(i, pool->threads) { - free(pool->threads[i].queue); - } gb_free(pool->allocator, pool->threads.data); } void thread_pool_queue_push(Thread *thread, WorkerTask task) { - uint64_t capture; - uint64_t new_capture; + u64 capture; + u64 new_capture; do { capture = thread->head_and_tail.load(); - uint64_t mask = thread->capacity - 1; - uint64_t head = (capture >> 32) & mask; - uint64_t tail = ((uint32_t)capture) & mask; + u64 mask = thread->capacity - 1; + u64 head = (capture >> 32) & mask; + u64 tail = ((u32)capture) & mask; - uint64_t new_head = (head + 1) & mask; + u64 new_head = (head + 1) & mask; if (new_head == tail) { GB_PANIC("Thread Queue Full!\n"); } @@ -73,21 +70,22 @@ void thread_pool_queue_push(Thread *thread, WorkerTask task) { new_capture = (new_head << 32) | tail; } while (!thread->head_and_tail.compare_exchange_weak(capture, new_capture)); - thread->pool->tasks_left.fetch_add(1); - condition_broadcast(&thread->pool->tasks_available); + thread->pool->tasks_left.fetch_add(1, std::memory_order_release); + thread->pool->tasks_available.fetch_add(1, std::memory_order_release); + futex_broadcast(&thread->pool->tasks_available); } bool thread_pool_queue_pop(Thread *thread, WorkerTask *task) { - uint64_t capture; - uint64_t new_capture; + u64 capture; + u64 new_capture; do { capture = thread->head_and_tail.load(); - uint64_t mask = thread->capacity - 1; - uint64_t head = (capture >> 32) & mask; - uint64_t tail = ((uint32_t)capture) & mask; + u64 mask = thread->capacity - 1; + u64 head = (capture >> 32) & mask; + u64 tail = ((u32)capture) & mask; - uint64_t new_tail = (tail + 1) & mask; + u64 new_tail = (tail + 1) & mask; if (tail == head) { return false; } @@ -113,12 +111,11 @@ gb_internal bool thread_pool_add_task(ThreadPool *pool, WorkerTaskProc *proc, vo gb_internal void thread_pool_wait(ThreadPool *pool) { WorkerTask task; - while (pool->tasks_left) { - + while (pool->tasks_left.load()) { // if we've got tasks on our queue, run them while (thread_pool_queue_pop(current_thread, &task)) { task.do_work(task.data); - pool->tasks_left.fetch_sub(1); + pool->tasks_left.fetch_sub(1, std::memory_order_release); } @@ -127,8 +124,8 @@ gb_internal void thread_pool_wait(ThreadPool *pool) { // if rem_tasks has changed since we checked last, otherwise the program // will permanently sleep Footex rem_tasks = pool->tasks_left.load(); - if (!rem_tasks) { - break; + if (rem_tasks == 0) { + return; } futex_wait(&pool->tasks_left, rem_tasks); @@ -147,37 +144,37 @@ work_start: } // If we've got tasks to process, work through them - size_t finished_tasks = 0; + usize finished_tasks = 0; while (thread_pool_queue_pop(current_thread, &task)) { task.do_work(task.data); - pool->tasks_left.fetch_sub(1); + pool->tasks_left.fetch_sub(1, std::memory_order_release); finished_tasks += 1; } - if (finished_tasks > 0 && !pool->tasks_left) { + if (finished_tasks > 0 && pool->tasks_left.load() == 0) { futex_signal(&pool->tasks_left); } // If there's still work somewhere and we don't have it, steal it - if (pool->tasks_left) { - isize idx = current_thread->idx; + if (pool->tasks_left.load()) { + usize idx = cast(usize)current_thread->idx; for_array(i, pool->threads) { - if (!pool->tasks_left) { + if (pool->tasks_left.load() == 0) { break; } - idx = (idx + 1) % pool->threads.count; - Thread *thread = &pool->threads[idx]; + idx = (idx + 1) % cast(usize)pool->threads.count; + Thread *thread = &pool->threads.data[idx]; WorkerTask task; if (!thread_pool_queue_pop(thread, &task)) { continue; } task.do_work(task.data); - pool->tasks_left.fetch_sub(1); + pool->tasks_left.fetch_sub(1, std::memory_order_release); - if (!pool->tasks_left) { + if (pool->tasks_left.load() == 0) { futex_signal(&pool->tasks_left); } @@ -186,9 +183,8 @@ work_start: } // if we've done all our work, and there's nothing to steal, go to sleep - mutex_lock(&pool->task_lock); - condition_wait(&pool->tasks_available, &pool->task_lock); - mutex_unlock(&pool->task_lock); + i32 state = pool->tasks_available.load(); + futex_wait(&pool->tasks_available, state); } return 0; diff --git a/src/threading.cpp b/src/threading.cpp index fb71a2c29..e3f26a8a0 100644 --- a/src/threading.cpp +++ b/src/threading.cpp @@ -393,7 +393,7 @@ gb_internal void thread_init(ThreadPool *pool, Thread *t, isize idx) { #endif t->capacity = 1 << 14; // must be a power of 2 - t->queue = (WorkerTask *)calloc(sizeof(WorkerTask), t->capacity); + t->queue = gb_alloc_array(heap_allocator(), WorkerTask, t->capacity); t->head_and_tail = 0; t->pool = pool; t->idx = idx; @@ -429,6 +429,8 @@ gb_internal void thread_join_and_destroy(Thread *t) { pthread_join(t->posix_handle, NULL); t->posix_handle = 0; #endif + + gb_free(heap_allocator(), t->queue); } gb_internal void thread_set_name(Thread *t, char const *name) { -- cgit v1.2.3 From 54f89dd84baaf296f7f744e1d2702b2ec867b5ae Mon Sep 17 00:00:00 2001 From: gingerBill Date: Mon, 2 Jan 2023 00:53:11 +0000 Subject: Multithread `check_collect_entities_all` using new thread pool --- src/checker.cpp | 71 ++++++++++++++++++++++++++++++++++++++------------------- 1 file changed, 48 insertions(+), 23 deletions(-) (limited to 'src/checker.cpp') diff --git a/src/checker.cpp b/src/checker.cpp index 03ff901eb..e70643940 100644 --- a/src/checker.cpp +++ b/src/checker.cpp @@ -4660,40 +4660,65 @@ gb_internal void check_with_workers(Checker *c, WorkerTaskProc *proc, isize tota semaphore_wait(&c->info.collect_semaphore); } +struct CollectEntityWorkerData { + Checker *c; + CheckerContext ctx; + UntypedExprInfoMap untyped; +}; -gb_internal WORKER_TASK_PROC(thread_proc_collect_entities) { - auto *cs = cast(ThreadProcCheckerSection *)data; - Checker *c = cs->checker; - CheckerContext collect_entity_ctx = make_checker_context(c); - defer (destroy_checker_context(&collect_entity_ctx)); - - CheckerContext *ctx = &collect_entity_ctx; - - UntypedExprInfoMap untyped = {}; - map_init(&untyped, heap_allocator()); +gb_global CollectEntityWorkerData *collect_entity_worker_data; - isize offset = cs->offset; - isize file_end = gb_min(offset+cs->count, c->info.files.entries.count); +WORKER_TASK_PROC(check_collect_entities_all_worker_proc) { + isize thread_idx = 0; + if (current_thread) { + thread_idx = current_thread->idx; + } + CollectEntityWorkerData *wd = &collect_entity_worker_data[thread_idx]; - for (isize i = offset; i < file_end; i++) { - AstFile *f = c->info.files.entries[i].value; - reset_checker_context(ctx, f, &untyped); + Checker *c = wd->c; + CheckerContext *ctx = &wd->ctx; + UntypedExprInfoMap *untyped = &wd->untyped; - check_collect_entities(ctx, f->decls); - GB_ASSERT(ctx->collect_delayed_decls == false); + AstFile *f = cast(AstFile *)data; + reset_checker_context(ctx, f, untyped); - add_untyped_expressions(&c->info, ctx->untyped); - } + check_collect_entities(ctx, f->decls); + GB_ASSERT(ctx->collect_delayed_decls == false); - map_destroy(&untyped); + add_untyped_expressions(&c->info, ctx->untyped); - semaphore_release(&c->info.collect_semaphore); return 0; } - gb_internal void check_collect_entities_all(Checker *c) { - check_with_workers(c, thread_proc_collect_entities, c->info.files.entries.count); + isize thread_count = global_thread_pool.threads.count; + + collect_entity_worker_data = gb_alloc_array(permanent_allocator(), CollectEntityWorkerData, thread_count); + for (isize i = 0; i < thread_count; i++) { + auto *wd = &collect_entity_worker_data[i]; + wd->c = c; + wd->ctx = make_checker_context(c); + map_init(&wd->untyped, heap_allocator()); + } + + if (build_context.threaded_checker) { + for (auto const &entry : c->info.files.entries) { + AstFile *f = entry.value; + global_thread_pool_add_task(check_collect_entities_all_worker_proc, f); + } + global_thread_pool_wait(); + } else { + for (auto const &entry : c->info.files.entries) { + AstFile *f = entry.value; + check_collect_entities_all_worker_proc(f); + } + } + + for (isize i = 0; i < thread_count; i++) { + auto *wd = &collect_entity_worker_data[i]; + map_destroy(&wd->untyped); + destroy_checker_context(&wd->ctx); + } } gb_internal void check_export_entities_in_pkg(CheckerContext *ctx, AstPackage *pkg, UntypedExprInfoMap *untyped) { -- cgit v1.2.3 From bfdcf900ef25566e57e46ec46683f8b6f2a9515a Mon Sep 17 00:00:00 2001 From: gingerBill Date: Mon, 2 Jan 2023 00:56:06 +0000 Subject: Remove `global_` prefix from `global_thread_pool_*` procedures --- src/checker.cpp | 12 ++++++------ src/llvm_backend.cpp | 2 +- src/main.cpp | 4 ++-- src/parser.cpp | 6 +++--- 4 files changed, 12 insertions(+), 12 deletions(-) (limited to 'src/checker.cpp') diff --git a/src/checker.cpp b/src/checker.cpp index e70643940..a25d78d3d 100644 --- a/src/checker.cpp +++ b/src/checker.cpp @@ -4654,9 +4654,9 @@ gb_internal void check_with_workers(Checker *c, WorkerTaskProc *proc, isize tota for (isize i = 0; i < thread_count; i++) { - global_thread_pool_add_task(proc, thread_data+i); + thread_pool_add_task(proc, thread_data+i); } - global_thread_pool_wait(); + thread_pool_wait(); semaphore_wait(&c->info.collect_semaphore); } @@ -4704,9 +4704,9 @@ gb_internal void check_collect_entities_all(Checker *c) { if (build_context.threaded_checker) { for (auto const &entry : c->info.files.entries) { AstFile *f = entry.value; - global_thread_pool_add_task(check_collect_entities_all_worker_proc, f); + thread_pool_add_task(check_collect_entities_all_worker_proc, f); } - global_thread_pool_wait(); + thread_pool_wait(); } else { for (auto const &entry : c->info.files.entries) { AstFile *f = entry.value; @@ -5350,9 +5350,9 @@ gb_internal void check_procedure_bodies(Checker *c) { semaphore_post(&c->procs_to_check_semaphore, cast(i32)thread_count); for (isize i = 0; i < thread_count; i++) { - global_thread_pool_add_task(thread_proc_body, thread_data+i); + thread_pool_add_task(thread_proc_body, thread_data+i); } - global_thread_pool_wait(); + thread_pool_wait(); semaphore_wait(&c->procs_to_check_semaphore); isize global_remaining = c->procs_to_check_queue.count.load(std::memory_order_relaxed); diff --git a/src/llvm_backend.cpp b/src/llvm_backend.cpp index 146cb2944..1c401552e 100644 --- a/src/llvm_backend.cpp +++ b/src/llvm_backend.cpp @@ -2272,7 +2272,7 @@ gb_internal void lb_generate_code(lbGenerator *gen) { wd->code_gen_file_type = code_gen_file_type; wd->filepath_obj = filepath_obj; wd->m = m; - global_thread_pool_add_task(lb_llvm_emit_worker_proc, wd); + thread_pool_add_task(lb_llvm_emit_worker_proc, wd); } thread_pool_wait(&global_thread_pool); diff --git a/src/main.cpp b/src/main.cpp index 184ab471e..3ad0e160f 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -20,10 +20,10 @@ gb_internal void init_global_thread_pool(void) { 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"); } -gb_internal bool global_thread_pool_add_task(WorkerTaskProc *proc, void *data) { +gb_internal bool thread_pool_add_task(WorkerTaskProc *proc, void *data) { return thread_pool_add_task(&global_thread_pool, proc, data); } -gb_internal void global_thread_pool_wait(void) { +gb_internal void thread_pool_wait(void) { thread_pool_wait(&global_thread_pool); } diff --git a/src/parser.cpp b/src/parser.cpp index 4a5ba78a9..4d2a8ecf4 100644 --- a/src/parser.cpp +++ b/src/parser.cpp @@ -4910,7 +4910,7 @@ gb_internal void parser_add_file_to_process(Parser *p, AstPackage *pkg, FileInfo auto wd = gb_alloc_item(permanent_allocator(), ParserWorkerData); wd->parser = p; wd->imported_file = f; - global_thread_pool_add_task(parser_worker_proc, wd); + thread_pool_add_task(parser_worker_proc, wd); } gb_internal WORKER_TASK_PROC(foreign_file_worker_proc) { @@ -4948,7 +4948,7 @@ gb_internal void parser_add_foreign_file_to_process(Parser *p, AstPackage *pkg, wd->parser = p; wd->imported_file = f; wd->foreign_kind = kind; - global_thread_pool_add_task(foreign_file_worker_proc, wd); + thread_pool_add_task(foreign_file_worker_proc, wd); } @@ -5798,7 +5798,7 @@ gb_internal ParseFileError parse_packages(Parser *p, String init_filename) { } } - global_thread_pool_wait(); + thread_pool_wait(); for (ParseFileErrorNode *node = p->file_error_head; node != nullptr; node = node->next) { if (node->err != ParseFile_None) { -- cgit v1.2.3 From a5ce8a8c0bc33afb6a4cf7baa16528c0a551d8e0 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Mon, 2 Jan 2023 01:31:14 +0000 Subject: Multi thread `check_export_entities` --- src/checker.cpp | 190 ++++++++++++++++++++++++++------------------------------ 1 file changed, 88 insertions(+), 102 deletions(-) (limited to 'src/checker.cpp') diff --git a/src/checker.cpp b/src/checker.cpp index a25d78d3d..1e40f04a6 100644 --- a/src/checker.cpp +++ b/src/checker.cpp @@ -1,3 +1,5 @@ +#define MULTITHREAD_CHECKER 1 + #include "entity.cpp" #include "types.cpp" @@ -1937,16 +1939,22 @@ gb_internal void add_type_info_type_internal(CheckerContext *c, Type *t) { gb_global std::atomic global_procedure_body_in_worker_queue = false; +gb_internal WORKER_TASK_PROC(check_proc_info_worker_proc); + gb_internal void check_procedure_later(CheckerContext *c, ProcInfo *info) { GB_ASSERT(info != nullptr); GB_ASSERT(info->decl != nullptr); - if (build_context.threaded_checker && global_procedure_body_in_worker_queue) { - GB_ASSERT(c->procs_to_check_queue != nullptr); - } + if (MULTITHREAD_CHECKER && global_procedure_body_in_worker_queue) { + thread_pool_add_task(check_proc_info_worker_proc, info); + } else { + if (build_context.threaded_checker && global_procedure_body_in_worker_queue) { + GB_ASSERT(c->procs_to_check_queue != nullptr); + } - auto *queue = c->procs_to_check_queue ? c->procs_to_check_queue : &c->checker->procs_to_check_queue; - mpmc_enqueue(queue, info); + auto *queue = c->procs_to_check_queue ? c->procs_to_check_queue : &c->checker->procs_to_check_queue; + mpmc_enqueue(queue, info); + } } gb_internal void check_procedure_later(CheckerContext *c, AstFile *file, Token token, DeclInfo *decl, Type *type, Ast *body, u64 tags) { @@ -4623,7 +4631,7 @@ struct ThreadProcCheckerSection { gb_internal void check_with_workers(Checker *c, WorkerTaskProc *proc, isize total_count) { - isize thread_count = gb_max(build_context.thread_count, 1); + isize thread_count = global_thread_pool.threads.count; isize worker_count = thread_count-1; // NOTE(bill): The main thread will also be used for work if (!build_context.threaded_checker) { worker_count = 0; @@ -4668,7 +4676,7 @@ struct CollectEntityWorkerData { gb_global CollectEntityWorkerData *collect_entity_worker_data; -WORKER_TASK_PROC(check_collect_entities_all_worker_proc) { +gb_internal WORKER_TASK_PROC(check_collect_entities_all_worker_proc) { isize thread_idx = 0; if (current_thread) { thread_idx = current_thread->idx; @@ -4701,7 +4709,7 @@ gb_internal void check_collect_entities_all(Checker *c) { map_init(&wd->untyped, heap_allocator()); } - if (build_context.threaded_checker) { + if (MULTITHREAD_CHECKER || build_context.threaded_checker) { for (auto const &entry : c->info.files.entries) { AstFile *f = entry.value; thread_pool_add_task(check_collect_entities_all_worker_proc, f); @@ -4713,12 +4721,6 @@ gb_internal void check_collect_entities_all(Checker *c) { check_collect_entities_all_worker_proc(f); } } - - for (isize i = 0; i < thread_count; i++) { - auto *wd = &collect_entity_worker_data[i]; - map_destroy(&wd->untyped); - destroy_checker_context(&wd->ctx); - } } gb_internal void check_export_entities_in_pkg(CheckerContext *ctx, AstPackage *pkg, UntypedExprInfoMap *untyped) { @@ -4735,30 +4737,32 @@ gb_internal void check_export_entities_in_pkg(CheckerContext *ctx, AstPackage *p } } -gb_internal WORKER_TASK_PROC(thread_proc_check_export_entities) { - auto cs = cast(ThreadProcCheckerSection *)data; - Checker *c = cs->checker; +gb_internal WORKER_TASK_PROC(check_export_entities_worker_proc) { + isize thread_idx = current_thread ? current_thread->idx : 0; - CheckerContext ctx = make_checker_context(c); - defer (destroy_checker_context(&ctx)); + AstPackage *pkg = (AstPackage *)data; + auto *wd = &collect_entity_worker_data[thread_idx]; + check_export_entities_in_pkg(&wd->ctx, pkg, &wd->untyped); + return 0; +} - UntypedExprInfoMap untyped = {}; - map_init(&untyped, heap_allocator()); - isize end = gb_min(cs->offset + cs->count, c->info.packages.entries.count); - for (isize i = cs->offset; i < end; i++) { - AstPackage *pkg = c->info.packages.entries[i].value; - check_export_entities_in_pkg(&ctx, pkg, &untyped); - } +gb_internal void check_export_entities(Checker *c) { + isize thread_count = global_thread_pool.threads.count; - map_destroy(&untyped); + // NOTE(bill): reuse `collect_entity_worker_data` - semaphore_release(&c->info.collect_semaphore); - return 0; -} + for (isize i = 0; i < thread_count; i++) { + auto *wd = &collect_entity_worker_data[i]; + map_clear(&wd->untyped); + wd->ctx = make_checker_context(c); + } -gb_internal void check_export_entities(Checker *c) { - check_with_workers(c, thread_proc_check_export_entities, c->info.packages.entries.count); + for (auto const &entry : c->info.packages.entries) { + AstPackage *pkg = entry.value; + thread_pool_add_task(check_export_entities_worker_proc, pkg); + } + thread_pool_wait(); } gb_internal void check_import_entities(Checker *c) { @@ -5087,8 +5091,10 @@ gb_internal bool check_proc_info(Checker *c, ProcInfo *pi, UntypedExprInfoMap *u defer (destroy_checker_context(&ctx)); reset_checker_context(&ctx, pi->file, untyped); ctx.decl = pi->decl; + + GB_ASSERT(procs_to_check_queue != nullptr || MULTITHREAD_CHECKER); + ctx.procs_to_check_queue = procs_to_check_queue; - GB_ASSERT(procs_to_check_queue != nullptr); GB_ASSERT(pi->type->kind == Type_Proc); TypeProc *pt = &pi->type->Proc; @@ -5201,6 +5207,7 @@ gb_internal void check_unchecked_bodies(Checker *c) { } } + thread_pool_wait(); } gb_internal void check_test_procedures(Checker *c) { @@ -5258,106 +5265,85 @@ gb_internal bool consume_proc_info_queue(Checker *c, ProcInfo *pi, ProcBodyQueue return ok; } -struct ThreadProcBodyData { - Checker *checker; - ProcBodyQueue *queue; - u32 thread_index; - u32 thread_count; - ThreadProcBodyData *all_data; +struct CheckProcedureBodyWorkerData { + Checker *c; + UntypedExprInfoMap untyped; }; -gb_internal WORKER_TASK_PROC(thread_proc_body) { - ThreadProcBodyData *bd = cast(ThreadProcBodyData *)data; - Checker *c = bd->checker; - GB_ASSERT(c != nullptr); - ProcBodyQueue *this_queue = bd->queue; +gb_global CheckProcedureBodyWorkerData *check_procedure_bodies_worker_data; - UntypedExprInfoMap untyped = {}; - map_init(&untyped, heap_allocator()); - - for (ProcInfo *pi; mpmc_dequeue(this_queue, &pi); /**/) { - consume_proc_info_queue(c, pi, this_queue, &untyped); +gb_internal WORKER_TASK_PROC(check_proc_info_worker_proc) { + isize thread_idx = 0; + if (current_thread) { + thread_idx = current_thread->idx; } + UntypedExprInfoMap *untyped = &check_procedure_bodies_worker_data[thread_idx].untyped; + Checker *c = check_procedure_bodies_worker_data[thread_idx].c; - map_destroy(&untyped); - - semaphore_release(&c->procs_to_check_semaphore); + ProcInfo *pi = cast(ProcInfo *)data; - return 0; + GB_ASSERT(pi->decl != nullptr); + if (pi->decl->parent && pi->decl->parent->entity) { + Entity *parent = pi->decl->parent->entity; + // NOTE(bill): Only check a nested procedure if its parent's body has been checked first + // This is prevent any possible race conditions in evaluation when multithreaded + // NOTE(bill): In single threaded mode, this should never happen + if (parent->kind == Entity_Procedure && (parent->flags & EntityFlag_ProcBodyChecked) == 0) { + thread_pool_add_task(check_proc_info_worker_proc, pi); + return 1; + } + } + map_clear(untyped); + bool ok = check_proc_info(c, pi, untyped, nullptr); + total_bodies_checked.fetch_add(1, std::memory_order_relaxed); + return !ok; } + gb_internal void check_procedure_bodies(Checker *c) { GB_ASSERT(c != nullptr); - u32 thread_count = cast(u32)gb_max(build_context.thread_count, 1); - u32 worker_count = thread_count-1; // NOTE(bill): The main thread will also be used for work + u32 thread_count = cast(u32)global_thread_pool.threads.count; if (!build_context.threaded_checker) { - worker_count = 0; + thread_count = 1; } - if (worker_count == 0) { + + check_procedure_bodies_worker_data = gb_alloc_array(permanent_allocator(), CheckProcedureBodyWorkerData, thread_count); + + for (isize i = 0; i < thread_count; i++) { + check_procedure_bodies_worker_data[i].c = c; + map_init(&check_procedure_bodies_worker_data[i].untyped, heap_allocator()); + } + + defer (for (isize i = 0; i < thread_count; i++) { + map_destroy(&check_procedure_bodies_worker_data[i].untyped); + }); + + if (thread_count == 1) { auto *this_queue = &c->procs_to_check_queue; - UntypedExprInfoMap untyped = {}; - map_init(&untyped, heap_allocator()); + UntypedExprInfoMap *untyped = &check_procedure_bodies_worker_data[0].untyped; for (ProcInfo *pi = nullptr; mpmc_dequeue(this_queue, &pi); /**/) { - consume_proc_info_queue(c, pi, this_queue, &untyped); + consume_proc_info_queue(c, pi, this_queue, untyped); } - map_destroy(&untyped); - debugf("Total Procedure Bodies Checked: %td\n", total_bodies_checked.load(std::memory_order_relaxed)); return; } global_procedure_body_in_worker_queue = true; - isize original_queue_count = c->procs_to_check_queue.count.load(std::memory_order_relaxed); - isize load_count = (original_queue_count+thread_count-1)/thread_count; - - ThreadProcBodyData *thread_data = gb_alloc_array(permanent_allocator(), ThreadProcBodyData, thread_count); - for (u32 i = 0; i < thread_count; i++) { - ThreadProcBodyData *data = thread_data + i; - data->checker = c; - data->queue = gb_alloc_item(permanent_allocator(), ProcBodyQueue); - data->thread_index = i; - data->thread_count = thread_count; - data->all_data = thread_data; - // NOTE(bill) 2x the amount assumes on average only 1 nested procedure - // TODO(bill): Determine a good heuristic - mpmc_init(data->queue, heap_allocator(), next_pow2_isize(load_count*2)); - } - - // Distibute the work load into multiple queues - for (isize j = 0; j < load_count; j++) { - for (isize i = 0; i < thread_count; i++) { - ProcBodyQueue *queue = thread_data[i].queue; - ProcInfo *pi = nullptr; - if (!mpmc_dequeue(&c->procs_to_check_queue, &pi)) { - break; - } - mpmc_enqueue(queue, pi); - } - } - isize total_queued = 0; - for (isize i = 0; i < thread_count; i++) { - ProcBodyQueue *queue = thread_data[i].queue; - total_queued += queue->count.load(); - } - GB_ASSERT(total_queued == original_queue_count); - - semaphore_post(&c->procs_to_check_semaphore, cast(i32)thread_count); - - for (isize i = 0; i < thread_count; i++) { - thread_pool_add_task(thread_proc_body, thread_data+i); + for (ProcInfo *pi = nullptr; mpmc_dequeue(&c->procs_to_check_queue, &pi); /**/) { + thread_pool_add_task(check_proc_info_worker_proc, pi); } - thread_pool_wait(); - semaphore_wait(&c->procs_to_check_semaphore); isize global_remaining = c->procs_to_check_queue.count.load(std::memory_order_relaxed); GB_ASSERT(global_remaining == 0); + thread_pool_wait(); + debugf("Total Procedure Bodies Checked: %td\n", total_bodies_checked.load(std::memory_order_relaxed)); -- cgit v1.2.3 From 015fe924b8f9a1d8cb78d307a4f8ef6791402bea Mon Sep 17 00:00:00 2001 From: gingerBill Date: Mon, 2 Jan 2023 12:28:38 +0000 Subject: Remove use of queues for procedure checking. --- src/check_decl.cpp | 2 +- src/check_expr.cpp | 10 ++--- src/checker.cpp | 108 ++++++++++++++++++++-------------------------------- src/checker.hpp | 6 +-- src/thread_pool.cpp | 4 ++ 5 files changed, 52 insertions(+), 78 deletions(-) (limited to 'src/checker.cpp') diff --git a/src/check_decl.cpp b/src/check_decl.cpp index 59beae56d..4e3c1b405 100644 --- a/src/check_decl.cpp +++ b/src/check_decl.cpp @@ -986,7 +986,7 @@ gb_internal void check_proc_decl(CheckerContext *ctx, Entity *e, DeclInfo *d) { GB_ASSERT(pl->body->kind == Ast_BlockStmt); if (!pt->is_polymorphic) { - check_procedure_later(ctx, ctx->file, e->token, d, proc_type, pl->body, pl->tags); + check_procedure_later(ctx->checker, ctx->file, e->token, d, proc_type, pl->body, pl->tags); } } else if (!is_foreign) { if (e->Procedure.is_export) { diff --git a/src/check_expr.cpp b/src/check_expr.cpp index ed1ddd1f1..eb9f76547 100644 --- a/src/check_expr.cpp +++ b/src/check_expr.cpp @@ -417,8 +417,6 @@ gb_internal bool find_or_generate_polymorphic_procedure(CheckerContext *old_c, E CheckerContext nctx = *old_c; - nctx.procs_to_check_queue = old_c->procs_to_check_queue; - Scope *scope = create_scope(info, base_entity->scope); scope->flags |= ScopeFlag_Proc; nctx.scope = scope; @@ -566,7 +564,7 @@ gb_internal bool find_or_generate_polymorphic_procedure(CheckerContext *old_c, E } // NOTE(bill): Check the newly generated procedure body - check_procedure_later(&nctx, proc_info); + check_procedure_later(nctx.checker, proc_info); return true; } @@ -6187,7 +6185,7 @@ gb_internal CallArgumentData check_call_arguments(CheckerContext *c, Operand *op decl->where_clauses_evaluated = true; if (ok && (data.gen_entity->flags & EntityFlag_ProcBodyChecked) == 0) { - check_procedure_later(c, e->file, e->token, decl, e->type, decl->proc_lit->ProcLit.body, decl->proc_lit->ProcLit.tags); + check_procedure_later(c->checker, e->file, e->token, decl, e->type, decl->proc_lit->ProcLit.body, decl->proc_lit->ProcLit.tags); } } return data; @@ -6225,7 +6223,7 @@ gb_internal CallArgumentData check_call_arguments(CheckerContext *c, Operand *op decl->where_clauses_evaluated = true; if (ok && (data.gen_entity->flags & EntityFlag_ProcBodyChecked) == 0) { - check_procedure_later(c, e->file, e->token, decl, e->type, decl->proc_lit->ProcLit.body, decl->proc_lit->ProcLit.tags); + check_procedure_later(c->checker, e->file, e->token, decl, e->type, decl->proc_lit->ProcLit.body, decl->proc_lit->ProcLit.tags); } } return data; @@ -9447,7 +9445,7 @@ gb_internal ExprKind check_expr_base_internal(CheckerContext *c, Operand *o, Ast } pl->decl = decl; - check_procedure_later(&ctx, ctx.file, empty_token, decl, type, pl->body, pl->tags); + check_procedure_later(ctx.checker, ctx.file, empty_token, decl, type, pl->body, pl->tags); } check_close_scope(&ctx); diff --git a/src/checker.cpp b/src/checker.cpp index 1e40f04a6..30e7409f9 100644 --- a/src/checker.cpp +++ b/src/checker.cpp @@ -1195,7 +1195,6 @@ gb_internal void reset_checker_context(CheckerContext *ctx, AstFile *file, Untyp GB_ASSERT(ctx->checker != nullptr); mutex_lock(&ctx->mutex); - auto *queue = ctx->procs_to_check_queue; auto type_path = ctx->type_path; array_clear(type_path); @@ -1211,7 +1210,6 @@ gb_internal void reset_checker_context(CheckerContext *ctx, AstFile *file, Untyp add_curr_ast_file(ctx, file); - ctx->procs_to_check_queue = queue; ctx->untyped = untyped; mutex_unlock(&ctx->mutex); @@ -1232,7 +1230,7 @@ gb_internal void init_checker(Checker *c) { mpmc_init(&c->procs_with_deferred_to_check, a, 1<<10); // NOTE(bill): 1 Mi elements should be enough on average - mpmc_init(&c->procs_to_check_queue, heap_allocator(), 1<<20); + array_init(&c->procs_to_check, heap_allocator(), 0, 1<<20); mpmc_init(&c->global_untyped_queue, a, 1<<20); @@ -1244,7 +1242,7 @@ gb_internal void destroy_checker(Checker *c) { destroy_checker_context(&c->builtin_ctx); - mpmc_destroy(&c->procs_to_check_queue); + array_free(&c->procs_to_check); mpmc_destroy(&c->global_untyped_queue); } @@ -1941,23 +1939,19 @@ gb_global std::atomic global_procedure_body_in_worker_queue = false; gb_internal WORKER_TASK_PROC(check_proc_info_worker_proc); -gb_internal void check_procedure_later(CheckerContext *c, ProcInfo *info) { +gb_internal void check_procedure_later(Checker *c, ProcInfo *info) { GB_ASSERT(info != nullptr); GB_ASSERT(info->decl != nullptr); if (MULTITHREAD_CHECKER && global_procedure_body_in_worker_queue) { thread_pool_add_task(check_proc_info_worker_proc, info); } else { - if (build_context.threaded_checker && global_procedure_body_in_worker_queue) { - GB_ASSERT(c->procs_to_check_queue != nullptr); - } - - auto *queue = c->procs_to_check_queue ? c->procs_to_check_queue : &c->checker->procs_to_check_queue; - mpmc_enqueue(queue, info); + GB_ASSERT(global_procedure_body_in_worker_queue == false); + array_add(&c->procs_to_check, info); } } -gb_internal void check_procedure_later(CheckerContext *c, AstFile *file, Token token, DeclInfo *decl, Type *type, Ast *body, u64 tags) { +gb_internal void check_procedure_later(Checker *c, AstFile *file, Token token, DeclInfo *decl, Type *type, Ast *body, u64 tags) { ProcInfo *info = gb_alloc_item(permanent_allocator(), ProcInfo); info->file = file; info->token = token; @@ -4677,11 +4671,7 @@ struct CollectEntityWorkerData { gb_global CollectEntityWorkerData *collect_entity_worker_data; gb_internal WORKER_TASK_PROC(check_collect_entities_all_worker_proc) { - isize thread_idx = 0; - if (current_thread) { - thread_idx = current_thread->idx; - } - CollectEntityWorkerData *wd = &collect_entity_worker_data[thread_idx]; + CollectEntityWorkerData *wd = &collect_entity_worker_data[current_thread_index()]; Checker *c = wd->c; CheckerContext *ctx = &wd->ctx; @@ -4738,10 +4728,8 @@ gb_internal void check_export_entities_in_pkg(CheckerContext *ctx, AstPackage *p } gb_internal WORKER_TASK_PROC(check_export_entities_worker_proc) { - isize thread_idx = current_thread ? current_thread->idx : 0; - AstPackage *pkg = (AstPackage *)data; - auto *wd = &collect_entity_worker_data[thread_idx]; + auto *wd = &collect_entity_worker_data[current_thread_index()]; check_export_entities_in_pkg(&wd->ctx, pkg, &wd->untyped); return 0; } @@ -5069,7 +5057,7 @@ gb_internal void calculate_global_init_order(Checker *c) { } -gb_internal bool check_proc_info(Checker *c, ProcInfo *pi, UntypedExprInfoMap *untyped, ProcBodyQueue *procs_to_check_queue) { +gb_internal bool check_proc_info(Checker *c, ProcInfo *pi, UntypedExprInfoMap *untyped) { if (pi == nullptr) { return false; } @@ -5085,17 +5073,16 @@ gb_internal bool check_proc_info(Checker *c, ProcInfo *pi, UntypedExprInfoMap *u } return true; } + if (e != nullptr && (e->flags & EntityFlag_ProcBodyChecked) != 0) { + GB_ASSERT(pi->decl->proc_checked); + return true; + } + pi->decl->proc_checked = true; + if (e != nullptr) { + e->flags |= EntityFlag_ProcBodyChecked; + } } - CheckerContext ctx = make_checker_context(c); - defer (destroy_checker_context(&ctx)); - reset_checker_context(&ctx, pi->file, untyped); - ctx.decl = pi->decl; - - GB_ASSERT(procs_to_check_queue != nullptr || MULTITHREAD_CHECKER); - - ctx.procs_to_check_queue = procs_to_check_queue; - GB_ASSERT(pi->type->kind == Type_Proc); TypeProc *pt = &pi->type->Proc; String name = pi->token.string; @@ -5116,6 +5103,12 @@ gb_internal bool check_proc_info(Checker *c, ProcInfo *pi, UntypedExprInfoMap *u } } + + CheckerContext ctx = make_checker_context(c); + defer (destroy_checker_context(&ctx)); + reset_checker_context(&ctx, pi->file, untyped); + ctx.decl = pi->decl; + bool bounds_check = (pi->tags & ProcTag_bounds_check) != 0; bool no_bounds_check = (pi->tags & ProcTag_no_bounds_check) != 0; @@ -5138,24 +5131,14 @@ gb_internal bool check_proc_info(Checker *c, ProcInfo *pi, UntypedExprInfoMap *u ctx.state_flags &= ~StateFlag_type_assert; } - if (pi->body != nullptr && e != nullptr) { - GB_ASSERT((e->flags & EntityFlag_ProcBodyChecked) == 0); - } - check_proc_body(&ctx, pi->token, pi->decl, pi->type, pi->body); - MUTEX_GUARD_BLOCK(&pi->decl->proc_checked_mutex) { - if (e != nullptr) { - e->flags |= EntityFlag_ProcBodyChecked; - } - pi->decl->proc_checked = true; - } add_untyped_expressions(&c->info, ctx.untyped); return true; } GB_STATIC_ASSERT(sizeof(isize) == sizeof(void *)); -gb_internal bool consume_proc_info_queue(Checker *c, ProcInfo *pi, ProcBodyQueue *q, UntypedExprInfoMap *untyped); +gb_internal bool consume_proc_info_queue(Checker *c, ProcInfo *pi, UntypedExprInfoMap *untyped); gb_internal void check_unchecked_bodies(Checker *c) { // NOTE(2021-02-26, bill): Sanity checker @@ -5193,15 +5176,13 @@ gb_internal void check_unchecked_bodies(Checker *c) { } debugf("unchecked: %.*s\n", LIT(e->token.string)); - mpmc_enqueue(&c->procs_to_check_queue, pi); + array_add(&c->procs_to_check, pi); } } - auto *q = &c->procs_to_check_queue; - ProcInfo *pi = nullptr; - while (mpmc_dequeue(q, &pi)) { + for (ProcInfo *pi : c->procs_to_check) { Entity *e = pi->decl->entity; - if (consume_proc_info_queue(c, pi, q, &untyped)) { + if (consume_proc_info_queue(c, pi, &untyped)) { add_dependency_to_set(c, e); GB_ASSERT(e->flags & EntityFlag_ProcBodyChecked); } @@ -5245,7 +5226,7 @@ gb_internal void check_test_procedures(Checker *c) { gb_global std::atomic total_bodies_checked; -gb_internal bool consume_proc_info_queue(Checker *c, ProcInfo *pi, ProcBodyQueue *q, UntypedExprInfoMap *untyped) { +gb_internal bool consume_proc_info_queue(Checker *c, ProcInfo *pi, UntypedExprInfoMap *untyped) { GB_ASSERT(pi->decl != nullptr); if (pi->decl->parent && pi->decl->parent->entity) { Entity *parent = pi->decl->parent->entity; @@ -5253,14 +5234,14 @@ gb_internal bool consume_proc_info_queue(Checker *c, ProcInfo *pi, ProcBodyQueue // This is prevent any possible race conditions in evaluation when multithreaded // NOTE(bill): In single threaded mode, this should never happen if (parent->kind == Entity_Procedure && (parent->flags & EntityFlag_ProcBodyChecked) == 0) { - mpmc_enqueue(q, pi); + check_procedure_later(c, pi); return false; } } if (untyped) { map_clear(untyped); } - bool ok = check_proc_info(c, pi, untyped, q); + bool ok = check_proc_info(c, pi, untyped); total_bodies_checked.fetch_add(1, std::memory_order_relaxed); return ok; } @@ -5273,12 +5254,9 @@ struct CheckProcedureBodyWorkerData { gb_global CheckProcedureBodyWorkerData *check_procedure_bodies_worker_data; gb_internal WORKER_TASK_PROC(check_proc_info_worker_proc) { - isize thread_idx = 0; - if (current_thread) { - thread_idx = current_thread->idx; - } - UntypedExprInfoMap *untyped = &check_procedure_bodies_worker_data[thread_idx].untyped; - Checker *c = check_procedure_bodies_worker_data[thread_idx].c; + auto *wd = &check_procedure_bodies_worker_data[current_thread_index()]; + UntypedExprInfoMap *untyped = &wd->untyped; + Checker *c = wd->c; ProcInfo *pi = cast(ProcInfo *)data; @@ -5294,7 +5272,7 @@ gb_internal WORKER_TASK_PROC(check_proc_info_worker_proc) { } } map_clear(untyped); - bool ok = check_proc_info(c, pi, untyped, nullptr); + bool ok = check_proc_info(c, pi, untyped); total_bodies_checked.fetch_add(1, std::memory_order_relaxed); return !ok; } @@ -5321,13 +5299,11 @@ gb_internal void check_procedure_bodies(Checker *c) { }); if (thread_count == 1) { - auto *this_queue = &c->procs_to_check_queue; - UntypedExprInfoMap *untyped = &check_procedure_bodies_worker_data[0].untyped; - - for (ProcInfo *pi = nullptr; mpmc_dequeue(this_queue, &pi); /**/) { - consume_proc_info_queue(c, pi, this_queue, untyped); + for_array(i, c->procs_to_check) { + consume_proc_info_queue(c, c->procs_to_check[i], untyped); } + array_clear(&c->procs_to_check); debugf("Total Procedure Bodies Checked: %td\n", total_bodies_checked.load(std::memory_order_relaxed)); return; @@ -5335,12 +5311,12 @@ gb_internal void check_procedure_bodies(Checker *c) { global_procedure_body_in_worker_queue = true; - for (ProcInfo *pi = nullptr; mpmc_dequeue(&c->procs_to_check_queue, &pi); /**/) { - thread_pool_add_task(check_proc_info_worker_proc, pi); + isize prev_procs_to_check_count = c->procs_to_check.count; + for_array(i, c->procs_to_check) { + thread_pool_add_task(check_proc_info_worker_proc, c->procs_to_check[i]); } - - isize global_remaining = c->procs_to_check_queue.count.load(std::memory_order_relaxed); - GB_ASSERT(global_remaining == 0); + GB_ASSERT(prev_procs_to_check_count == c->procs_to_check.count); + array_clear(&c->procs_to_check); thread_pool_wait(); diff --git a/src/checker.hpp b/src/checker.hpp index 1d6019b79..eaad1fa63 100644 --- a/src/checker.hpp +++ b/src/checker.hpp @@ -418,8 +418,6 @@ struct CheckerContext { Scope * polymorphic_scope; Ast *assignment_lhs_hint; - - ProcBodyQueue *procs_to_check_queue; }; @@ -430,9 +428,7 @@ struct Checker { CheckerContext builtin_ctx; MPMCQueue procs_with_deferred_to_check; - - ProcBodyQueue procs_to_check_queue; - Semaphore procs_to_check_semaphore; + Array procs_to_check; // TODO(bill): Technically MPSC queue MPMCQueue global_untyped_queue; diff --git a/src/thread_pool.cpp b/src/thread_pool.cpp index 9ac1af039..939d3c533 100644 --- a/src/thread_pool.cpp +++ b/src/thread_pool.cpp @@ -21,6 +21,10 @@ struct ThreadPool { Futex tasks_left; }; +gb_internal isize current_thread_index(void) { + return current_thread ? current_thread->idx : 0; +} + gb_internal void thread_pool_init(ThreadPool *pool, gbAllocator const &a, isize thread_count, char const *worker_name) { pool->allocator = a; slice_init(&pool->threads, a, thread_count + 1); -- cgit v1.2.3 From f01cff7ff0d61a4bd222be159243775b5d9bf3e7 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Mon, 2 Jan 2023 12:31:00 +0000 Subject: Multithread checker --- src/checker.cpp | 64 +++++---------------------------------------------------- 1 file changed, 5 insertions(+), 59 deletions(-) (limited to 'src/checker.cpp') diff --git a/src/checker.cpp b/src/checker.cpp index 30e7409f9..d3a9c3d2c 100644 --- a/src/checker.cpp +++ b/src/checker.cpp @@ -1,5 +1,3 @@ -#define MULTITHREAD_CHECKER 1 - #include "entity.cpp" #include "types.cpp" @@ -1943,7 +1941,7 @@ gb_internal void check_procedure_later(Checker *c, ProcInfo *info) { GB_ASSERT(info != nullptr); GB_ASSERT(info->decl != nullptr); - if (MULTITHREAD_CHECKER && global_procedure_body_in_worker_queue) { + if (global_procedure_body_in_worker_queue) { thread_pool_add_task(check_proc_info_worker_proc, info); } else { GB_ASSERT(global_procedure_body_in_worker_queue == false); @@ -4617,51 +4615,6 @@ gb_internal void check_create_file_scopes(Checker *c) { } } -struct ThreadProcCheckerSection { - Checker *checker; - isize offset; - isize count; -}; - - -gb_internal void check_with_workers(Checker *c, WorkerTaskProc *proc, isize total_count) { - isize thread_count = global_thread_pool.threads.count; - isize worker_count = thread_count-1; // NOTE(bill): The main thread will also be used for work - if (!build_context.threaded_checker) { - worker_count = 0; - } - - semaphore_post(&c->info.collect_semaphore, cast(i32)thread_count); - if (worker_count == 0) { - ThreadProcCheckerSection section_all = {}; - section_all.checker = c; - section_all.offset = 0; - section_all.count = total_count; - proc(§ion_all); - return; - } - - isize file_load_count = (total_count+thread_count-1)/thread_count; - isize remaining_count = total_count; - - ThreadProcCheckerSection *thread_data = gb_alloc_array(permanent_allocator(), ThreadProcCheckerSection, thread_count); - for (isize i = 0; i < thread_count; i++) { - ThreadProcCheckerSection *data = thread_data + i; - data->checker = c; - data->offset = total_count-remaining_count; - data->count = file_load_count; - remaining_count -= file_load_count; - } - GB_ASSERT(remaining_count <= 0); - - - for (isize i = 0; i < thread_count; i++) { - thread_pool_add_task(proc, thread_data+i); - } - thread_pool_wait(); - semaphore_wait(&c->info.collect_semaphore); -} - struct CollectEntityWorkerData { Checker *c; CheckerContext ctx; @@ -4699,18 +4652,11 @@ gb_internal void check_collect_entities_all(Checker *c) { map_init(&wd->untyped, heap_allocator()); } - if (MULTITHREAD_CHECKER || build_context.threaded_checker) { - for (auto const &entry : c->info.files.entries) { - AstFile *f = entry.value; - thread_pool_add_task(check_collect_entities_all_worker_proc, f); - } - thread_pool_wait(); - } else { - for (auto const &entry : c->info.files.entries) { - AstFile *f = entry.value; - check_collect_entities_all_worker_proc(f); - } + for (auto const &entry : c->info.files.entries) { + AstFile *f = entry.value; + thread_pool_add_task(check_collect_entities_all_worker_proc, f); } + thread_pool_wait(); } gb_internal void check_export_entities_in_pkg(CheckerContext *ctx, AstPackage *pkg, UntypedExprInfoMap *untyped) { -- cgit v1.2.3 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/build_settings.cpp | 1 + src/check_decl.cpp | 25 ++--- src/check_expr.cpp | 23 ++++- src/checker.cpp | 224 ++++++++++++++++++++++++++++++++++--------- src/checker.hpp | 21 +++- src/llvm_backend.cpp | 6 ++ src/llvm_backend.hpp | 1 + src/llvm_backend_expr.cpp | 6 +- src/llvm_backend_general.cpp | 5 +- src/llvm_backend_proc.cpp | 3 +- src/llvm_backend_stmt.cpp | 6 +- src/main.cpp | 5 + 12 files changed, 260 insertions(+), 66 deletions(-) (limited to 'src/checker.cpp') diff --git a/src/build_settings.cpp b/src/build_settings.cpp index 97b512b81..f59b5c0f7 100644 --- a/src/build_settings.cpp +++ b/src/build_settings.cpp @@ -291,6 +291,7 @@ struct BuildContext { bool show_error_line; bool ignore_lazy; + bool ignore_llvm_build; bool use_subsystem_windows; bool ignore_microsoft_magic; diff --git a/src/check_decl.cpp b/src/check_decl.cpp index 4e3c1b405..8f95c1a49 100644 --- a/src/check_decl.cpp +++ b/src/check_decl.cpp @@ -1419,9 +1419,9 @@ struct ProcUsingVar { }; -gb_internal void check_proc_body(CheckerContext *ctx_, Token token, DeclInfo *decl, Type *type, Ast *body) { +gb_internal bool check_proc_body(CheckerContext *ctx_, Token token, DeclInfo *decl, Type *type, Ast *body) { if (body == nullptr) { - return; + return false; } GB_ASSERT(body->kind == Ast_BlockStmt); @@ -1502,7 +1502,7 @@ gb_internal void 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; - Entity *prev = scope_insert(ctx->scope, uvar, false); + 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)); error_line("%.*s != %.*s\n", LIT(uvar->token.string), LIT(prev->token.string)); @@ -1514,7 +1514,7 @@ gb_internal void check_proc_body(CheckerContext *ctx_, Token token, DeclInfo *de bool where_clause_ok = evaluate_where_clauses(ctx, nullptr, decl->scope, &decl->proc_lit->ProcLit.where_clauses, !decl->where_clauses_evaluated); if (!where_clause_ok) { // NOTE(bill, 2019-08-31): Don't check the body as the where clauses failed - return; + return false; } check_open_scope(ctx, body); @@ -1526,7 +1526,12 @@ gb_internal void check_proc_body(CheckerContext *ctx_, Token token, DeclInfo *de // NOTE(bill): Don't err here } - GB_ASSERT(decl->defer_use_checked == false); + GB_ASSERT(decl->proc_checked_state != ProcCheckedState_Checked); + if (decl->defer_use_checked) { + GB_ASSERT(is_type_polymorphic(type, true)); + error(token, "Defer Use Checked: %.*s", LIT(decl->entity->token.string)); + GB_ASSERT(decl->defer_use_checked == false); + } check_stmt_list(ctx, bs->stmts, Stmt_CheckScopeDecls); @@ -1575,10 +1580,8 @@ gb_internal void check_proc_body(CheckerContext *ctx_, Token token, DeclInfo *de if (decl->parent != nullptr) { Scope *ps = decl->parent->scope; if (ps->flags & (ScopeFlag_File & ScopeFlag_Pkg & ScopeFlag_Global)) { - return; - } else { - mutex_lock(&ctx->info->deps_mutex); - + return true; + } else MUTEX_GUARD_BLOCK(&ctx->info->deps_mutex) { // NOTE(bill): Add the dependencies from the procedure literal (lambda) // But only at the procedure level for (auto const &entry : decl->deps) { @@ -1589,8 +1592,8 @@ gb_internal void check_proc_body(CheckerContext *ctx_, Token token, DeclInfo *de Type *t = entry.ptr; ptr_set_add(&decl->parent->type_info_deps, t); } - - mutex_unlock(&ctx->info->deps_mutex); } } + + return true; } diff --git a/src/check_expr.cpp b/src/check_expr.cpp index eb9f76547..5445e73c7 100644 --- a/src/check_expr.cpp +++ b/src/check_expr.cpp @@ -86,7 +86,6 @@ gb_internal Entity * find_polymorphic_record_entity (CheckerContext *c, Type *or gb_internal void check_not_tuple (CheckerContext *c, Operand *operand); gb_internal void convert_to_typed (CheckerContext *c, Operand *operand, Type *target_type); gb_internal gbString expr_to_string (Ast *expression); -gb_internal void check_proc_body (CheckerContext *c, Token token, DeclInfo *decl, Type *type, Ast *body); gb_internal void update_untyped_expr_type (CheckerContext *c, Ast *e, Type *type, bool final); gb_internal bool check_is_terminating (Ast *node, String const &label); gb_internal bool check_has_break (Ast *stmt, String const &label, bool implicit); @@ -478,6 +477,22 @@ gb_internal bool find_or_generate_polymorphic_procedure(CheckerContext *old_c, E 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); + } + return true; } } @@ -518,7 +533,8 @@ gb_internal bool find_or_generate_polymorphic_procedure(CheckerContext *old_c, E d->gen_proc_type = final_proc_type; d->type_expr = pl->type; d->proc_lit = proc_lit; - d->proc_checked = false; + d->proc_checked_state = ProcCheckedState_Unchecked; + d->defer_use_checked = false; Entity *entity = alloc_entity_procedure(nullptr, token, final_proc_type, tags); entity->identifier = ident; @@ -528,7 +544,8 @@ gb_internal bool find_or_generate_polymorphic_procedure(CheckerContext *old_c, E entity->scope = scope->parent; entity->file = base_entity->file; entity->pkg = base_entity->pkg; - entity->flags &= ~EntityFlag_ProcBodyChecked; + entity->flags = 0; + d->entity = entity; AstFile *file = nullptr; { diff --git a/src/checker.cpp b/src/checker.cpp index d3a9c3d2c..f4c9b6822 100644 --- a/src/checker.cpp +++ b/src/checker.cpp @@ -1,3 +1,5 @@ +#define DEBUG_CHECK_ALL_PROCEDURES 1 + #include "entity.cpp" #include "types.cpp" @@ -179,6 +181,7 @@ gb_internal void import_graph_node_swap(ImportGraphNode **data, isize i, isize j gb_internal void init_decl_info(DeclInfo *d, Scope *scope, DeclInfo *parent) { + gb_zero_item(d); d->parent = parent; d->scope = scope; ptr_set_init(&d->deps, heap_allocator()); @@ -438,9 +441,44 @@ gb_internal Entity *scope_lookup(Scope *s, String const &name) { return entity; } +gb_internal Entity *scope_insert_with_name_no_mutex(Scope *s, String const &name, Entity *entity) { + if (name == "") { + return nullptr; + } + StringHashKey key = string_hash_string(name); + Entity **found = nullptr; + Entity *result = nullptr; + + found = string_map_get(&s->elements, key); + + if (found) { + if (entity != *found) { + result = *found; + } + goto end; + } + if (s->parent != nullptr && (s->parent->flags & ScopeFlag_Proc) != 0) { + found = string_map_get(&s->parent->elements, key); + if (found) { + if ((*found)->flags & EntityFlag_Result) { + if (entity != *found) { + result = *found; + } + goto end; + } + } + } + + string_map_set(&s->elements, key, entity); + if (entity->scope == nullptr) { + entity->scope = s; + } +end:; + return result; +} -gb_internal Entity *scope_insert_with_name(Scope *s, String const &name, Entity *entity, bool use_mutex=true) { +gb_internal Entity *scope_insert_with_name(Scope *s, String const &name, Entity *entity) { if (name == "") { return nullptr; } @@ -448,9 +486,8 @@ gb_internal Entity *scope_insert_with_name(Scope *s, String const &name, Entity Entity **found = nullptr; Entity *result = nullptr; - if (use_mutex) mutex_lock(&s->mutex); - defer (if (use_mutex) mutex_unlock(&s->mutex)); - + MUTEX_GUARD(&s->mutex); + found = string_map_get(&s->elements, key); if (found) { @@ -479,9 +516,14 @@ end:; return result; } -gb_internal Entity *scope_insert(Scope *s, Entity *entity, bool use_mutex) { +gb_internal Entity *scope_insert(Scope *s, Entity *entity) { String name = entity->token.string; - return scope_insert_with_name(s, name, entity, use_mutex); + return scope_insert_with_name(s, name, entity); +} + +gb_internal Entity *scope_insert_no_mutex(Scope *s, Entity *entity) { + String name = entity->token.string; + return scope_insert_with_name_no_mutex(s, name, entity); } @@ -1135,6 +1177,9 @@ gb_internal void init_checker_info(CheckerInfo *i) { map_init(&i->objc_msgSend_types, a); string_map_init(&i->load_file_cache, a); + + array_init(&i->all_procedures, heap_allocator()); + } gb_internal void destroy_checker_info(CheckerInfo *i) { @@ -1934,6 +1979,7 @@ gb_internal void add_type_info_type_internal(CheckerContext *c, Type *t) { gb_global std::atomic global_procedure_body_in_worker_queue = false; +gb_global std::atomic global_after_checking_procedure_bodies = false; gb_internal WORKER_TASK_PROC(check_proc_info_worker_proc); @@ -1941,12 +1987,24 @@ gb_internal void check_procedure_later(Checker *c, ProcInfo *info) { GB_ASSERT(info != nullptr); GB_ASSERT(info->decl != nullptr); - if (global_procedure_body_in_worker_queue) { + if (global_after_checking_procedure_bodies) { + Entity *e = info->decl->entity; + debugf("CHECK PROCEDURE LATER! %.*s :: %s {...}\n", LIT(e->token.string), type_to_string(e->type)); + } + + if (global_procedure_body_in_worker_queue.load()) { thread_pool_add_task(check_proc_info_worker_proc, info); } else { - GB_ASSERT(global_procedure_body_in_worker_queue == false); array_add(&c->procs_to_check, info); } + + if (DEBUG_CHECK_ALL_PROCEDURES) { + MUTEX_GUARD_BLOCK(&c->info.all_procedures_mutex) { + GB_ASSERT(info != nullptr); + GB_ASSERT(info->decl != nullptr); + array_add(&c->info.all_procedures, info); + } + } } gb_internal void check_procedure_later(Checker *c, AstFile *file, Token token, DeclInfo *decl, Type *type, Ast *body, u64 tags) { @@ -5010,24 +5068,26 @@ gb_internal bool check_proc_info(Checker *c, ProcInfo *pi, UntypedExprInfoMap *u if (pi->type == nullptr) { return false; } - Entity *e = pi->decl->entity; - MUTEX_GUARD_BLOCK(&pi->decl->proc_checked_mutex) { - if (pi->decl->proc_checked) { - if (e != nullptr) { - GB_ASSERT(e->flags & EntityFlag_ProcBodyChecked); - } - return true; - } - if (e != nullptr && (e->flags & EntityFlag_ProcBodyChecked) != 0) { - GB_ASSERT(pi->decl->proc_checked); - return true; + MUTEX_GUARD(&pi->decl->proc_checked_mutex); + + Entity *e = pi->decl->entity; + switch (pi->decl->proc_checked_state.load()) { + case ProcCheckedState_InProgress: + if (e) { + GB_ASSERT(global_procedure_body_in_worker_queue.load()); } - pi->decl->proc_checked = true; + return false; + case ProcCheckedState_Checked: if (e != nullptr) { - e->flags |= EntityFlag_ProcBodyChecked; + GB_ASSERT(e->flags & EntityFlag_ProcBodyChecked); } + return true; + case ProcCheckedState_Unchecked: + // okay + break; } + pi->decl->proc_checked_state.store(ProcCheckedState_InProgress); GB_ASSERT(pi->type->kind == Type_Proc); TypeProc *pt = &pi->type->Proc; @@ -5039,17 +5099,21 @@ gb_internal bool check_proc_info(Checker *c, ProcInfo *pi, UntypedExprInfoMap *u token = ast_token(pi->poly_def_node); } error(token, "Unspecialized polymorphic procedure '%.*s'", LIT(name)); + pi->decl->proc_checked_state.store(ProcCheckedState_Unchecked); return false; } if (pt->is_polymorphic && pt->is_poly_specialized) { + Entity *e = pi->decl->entity; + GB_ASSERT(e != nullptr); if ((e->flags & EntityFlag_Used) == 0) { // NOTE(bill, 2019-08-31): It was never used, don't check + // NOTE(bill, 2023-01-02): This may need to be checked again if it is used elsewhere? + pi->decl->proc_checked_state.store(ProcCheckedState_Unchecked); return false; } } - CheckerContext ctx = make_checker_context(c); defer (destroy_checker_context(&ctx)); reset_checker_context(&ctx, pi->file, untyped); @@ -5077,14 +5141,34 @@ gb_internal bool check_proc_info(Checker *c, ProcInfo *pi, UntypedExprInfoMap *u ctx.state_flags &= ~StateFlag_type_assert; } - check_proc_body(&ctx, pi->token, pi->decl, pi->type, pi->body); + bool body_was_checked = check_proc_body(&ctx, pi->token, pi->decl, pi->type, pi->body); + + if (body_was_checked) { + pi->decl->proc_checked_state.store(ProcCheckedState_Checked); + if (pi->body) { + Entity *e = pi->decl->entity; + if (e != nullptr) { + e->flags |= EntityFlag_ProcBodyChecked; + } + } + } else { + pi->decl->proc_checked_state.store(ProcCheckedState_Unchecked); + if (pi->body) { + Entity *e = pi->decl->entity; + if (e != nullptr) { + e->flags &= ~EntityFlag_ProcBodyChecked; + } + } + } + add_untyped_expressions(&c->info, ctx.untyped); + return true; } GB_STATIC_ASSERT(sizeof(isize) == sizeof(void *)); -gb_internal bool consume_proc_info_queue(Checker *c, ProcInfo *pi, UntypedExprInfoMap *untyped); +gb_internal bool consume_proc_info(Checker *c, ProcInfo *pi, UntypedExprInfoMap *untyped); gb_internal void check_unchecked_bodies(Checker *c) { // NOTE(2021-02-26, bill): Sanity checker @@ -5092,10 +5176,15 @@ gb_internal void check_unchecked_bodies(Checker *c) { // even ones which should not exist, due to the multithreaded nature of the parser // HACK TODO(2021-02-26, bill): Actually fix this race condition + GB_ASSERT(c->procs_to_check.count == 0); + UntypedExprInfoMap untyped = {}; map_init(&untyped, heap_allocator()); defer (map_destroy(&untyped)); + // use the `procs_to_check` array + global_procedure_body_in_worker_queue = false; + for (auto const &entry : c->info.minimum_dependency_set) { Entity *e = entry.ptr; if (e == nullptr || e->kind != Entity_Procedure) { @@ -5122,19 +5211,22 @@ gb_internal void check_unchecked_bodies(Checker *c) { } debugf("unchecked: %.*s\n", LIT(e->token.string)); - array_add(&c->procs_to_check, pi); + check_procedure_later(c, pi); } } - for (ProcInfo *pi : c->procs_to_check) { - Entity *e = pi->decl->entity; - if (consume_proc_info_queue(c, pi, &untyped)) { - add_dependency_to_set(c, e); - GB_ASSERT(e->flags & EntityFlag_ProcBodyChecked); + if (!global_procedure_body_in_worker_queue) { + for_array(i, c->procs_to_check) { + ProcInfo *pi = c->procs_to_check[i]; + consume_proc_info(c, pi, &untyped); } + array_clear(&c->procs_to_check); + } else { + thread_pool_wait(); } - thread_pool_wait(); + global_procedure_body_in_worker_queue = false; + global_after_checking_procedure_bodies = true; } gb_internal void check_test_procedures(Checker *c) { @@ -5172,8 +5264,15 @@ gb_internal void check_test_procedures(Checker *c) { gb_global std::atomic total_bodies_checked; -gb_internal bool consume_proc_info_queue(Checker *c, ProcInfo *pi, UntypedExprInfoMap *untyped) { +gb_internal bool consume_proc_info(Checker *c, ProcInfo *pi, UntypedExprInfoMap *untyped) { GB_ASSERT(pi->decl != nullptr); + switch (pi->decl->proc_checked_state.load()) { + case ProcCheckedState_InProgress: + return false; + case ProcCheckedState_Checked: + return true; + } + if (pi->decl->parent && pi->decl->parent->entity) { Entity *parent = pi->decl->parent->entity; // NOTE(bill): Only check a nested procedure if its parent's body has been checked first @@ -5187,9 +5286,11 @@ gb_internal bool consume_proc_info_queue(Checker *c, ProcInfo *pi, UntypedExprIn if (untyped) { map_clear(untyped); } - bool ok = check_proc_info(c, pi, untyped); - total_bodies_checked.fetch_add(1, std::memory_order_relaxed); - return ok; + if (check_proc_info(c, pi, untyped)) { + total_bodies_checked.fetch_add(1, std::memory_order_relaxed); + return true; + } + return false; } struct CheckProcedureBodyWorkerData { @@ -5218,9 +5319,11 @@ gb_internal WORKER_TASK_PROC(check_proc_info_worker_proc) { } } map_clear(untyped); - bool ok = check_proc_info(c, pi, untyped); - total_bodies_checked.fetch_add(1, std::memory_order_relaxed); - return !ok; + if (check_proc_info(c, pi, untyped)) { + total_bodies_checked.fetch_add(1, std::memory_order_relaxed); + return 0; + } + return 1; } @@ -5247,7 +5350,7 @@ gb_internal void check_procedure_bodies(Checker *c) { if (thread_count == 1) { UntypedExprInfoMap *untyped = &check_procedure_bodies_worker_data[0].untyped; for_array(i, c->procs_to_check) { - consume_proc_info_queue(c, c->procs_to_check[i], untyped); + consume_proc_info(c, c->procs_to_check[i], untyped); } array_clear(&c->procs_to_check); @@ -5266,9 +5369,6 @@ gb_internal void check_procedure_bodies(Checker *c) { thread_pool_wait(); - debugf("Total Procedure Bodies Checked: %td\n", total_bodies_checked.load(std::memory_order_relaxed)); - - global_procedure_body_in_worker_queue = false; } gb_internal void add_untyped_expressions(CheckerInfo *cinfo, UntypedExprInfoMap *untyped) { @@ -5662,9 +5762,6 @@ gb_internal void check_parsed_files(Checker *c) { TIME_SECTION("check test procedures"); check_test_procedures(c); - TIME_SECTION("check bodies have all been checked"); - check_unchecked_bodies(c); - TIME_SECTION("add type info for type definitions"); add_type_info_for_type_definitions(c); check_merge_queues_into_arrays(c); @@ -5672,6 +5769,12 @@ gb_internal void check_parsed_files(Checker *c) { TIME_SECTION("generate minimum dependency set"); generate_minimum_dependency_set(c, c->info.entry_point); + TIME_SECTION("check bodies have all been checked"); + check_unchecked_bodies(c); + + check_merge_queues_into_arrays(c); + + TIME_SECTION("check entry point"); if (build_context.build_mode == BuildMode_Executable && !build_context.no_entry_point && build_context.command_kind != Command_test) { Scope *s = c->info.init_scope; @@ -5694,11 +5797,39 @@ gb_internal void check_parsed_files(Checker *c) { } } + thread_pool_wait(); + GB_ASSERT(c->procs_to_check.count == 0); + + if (DEBUG_CHECK_ALL_PROCEDURES) { + UntypedExprInfoMap untyped = {}; + map_init(&untyped, heap_allocator()); + defer (map_destroy(&untyped)); + + for_array(i, c->info.all_procedures) { + ProcInfo *pi = c->info.all_procedures[i]; + GB_ASSERT(pi != nullptr); + GB_ASSERT(pi->decl != nullptr); + Entity *e = pi->decl->entity; + auto proc_checked_state = pi->decl->proc_checked_state.load(); + if (e && ((e->flags & EntityFlag_ProcBodyChecked) == 0)) { + if ((e->flags & EntityFlag_Used) != 0) { + debugf("%.*s :: %s\n", LIT(e->token.string), type_to_string(e->type)); + debugf("proc body unchecked\n"); + debugf("Checked State: %s\n\n", ProcCheckedState_strings[proc_checked_state]); + + consume_proc_info(c, pi, &untyped); + } + } + } + } + + debugf("Total Procedure Bodies Checked: %td\n", total_bodies_checked.load(std::memory_order_relaxed)); + TIME_SECTION("check unique package names"); check_unique_package_names(c); - TIME_SECTION("sanity checks"); + check_merge_queues_into_arrays(c); GB_ASSERT(c->info.entity_queue.count.load(std::memory_order_relaxed) == 0); GB_ASSERT(c->info.definition_queue.count.load(std::memory_order_relaxed) == 0); @@ -5717,5 +5848,6 @@ gb_internal void check_parsed_files(Checker *c) { } } + TIME_SECTION("type check finish"); } diff --git a/src/checker.hpp b/src/checker.hpp index eaad1fa63..37aff41b1 100644 --- a/src/checker.hpp +++ b/src/checker.hpp @@ -142,6 +142,20 @@ typedef DECL_ATTRIBUTE_PROC(DeclAttributeProc); gb_internal void check_decl_attributes(CheckerContext *c, Array const &attributes, DeclAttributeProc *proc, AttributeContext *ac); +enum ProcCheckedState : u8 { + ProcCheckedState_Unchecked, + ProcCheckedState_InProgress, + ProcCheckedState_Checked, + + ProcCheckedState_COUNT +}; + +char const *ProcCheckedState_strings[ProcCheckedState_COUNT] { + "Unchecked", + "In Progress", + "Checked", +}; + // DeclInfo is used to store information of certain declarations to allow for "any order" usage struct DeclInfo { DeclInfo * parent; // NOTE(bill): only used for procedure literals at the moment @@ -157,7 +171,7 @@ struct DeclInfo { Type * gen_proc_type; // Precalculated bool is_using; bool where_clauses_evaluated; - bool proc_checked; + std::atomic proc_checked_state; BlockingMutex proc_checked_mutex; isize defer_used; bool defer_use_checked; @@ -375,6 +389,9 @@ struct CheckerInfo { BlockingMutex load_file_mutex; StringMap load_file_cache; + + BlockingMutex all_procedures_mutex;; + Array all_procedures; }; struct CheckerContext { @@ -458,7 +475,7 @@ gb_internal Entity *entity_of_node(Ast *expr); gb_internal Entity *scope_lookup_current(Scope *s, String const &name); gb_internal Entity *scope_lookup (Scope *s, String const &name); gb_internal void scope_lookup_parent (Scope *s, String const &name, Scope **scope_, Entity **entity_); -gb_internal Entity *scope_insert (Scope *s, Entity *entity, bool use_mutex=true); +gb_internal Entity *scope_insert (Scope *s, Entity *entity); gb_internal void add_type_and_value (CheckerInfo *i, Ast *expression, AddressingMode mode, Type *type, ExactValue value); diff --git a/src/llvm_backend.cpp b/src/llvm_backend.cpp index 1c401552e..3e62f678a 100644 --- a/src/llvm_backend.cpp +++ b/src/llvm_backend.cpp @@ -2255,6 +2255,12 @@ gb_internal void lb_generate_code(lbGenerator *gen) { } } + if (build_context.ignore_llvm_build) { + gb_printf_err("LLVM SUCCESS!\n"); + gb_exit(1); + return; + } + if (do_threading && non_empty_module_count > 1) { for (auto const &entry : gen->modules) { lbModule *m = entry.value; diff --git a/src/llvm_backend.hpp b/src/llvm_backend.hpp index 9f7caa3bb..50fb5701f 100644 --- a/src/llvm_backend.hpp +++ b/src/llvm_backend.hpp @@ -301,6 +301,7 @@ 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 d574caf4c..28a68b065 100644 --- a/src/llvm_backend_expr.cpp +++ b/src/llvm_backend_expr.cpp @@ -3404,7 +3404,11 @@ gb_internal lbAddr lb_build_addr_from_entity(lbProcedure *p, Entity *e, Ast *exp lbValue v = {}; - lbValue *found = map_get(&p->module->values, e); + lbValue *found = nullptr; + found = map_get(&p->local_entity_map, e); + if (found == nullptr) { + 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 0508c6171..940c94a13 100644 --- a/src/llvm_backend_general.cpp +++ b/src/llvm_backend_general.cpp @@ -2714,7 +2714,6 @@ gb_internal lbValue lb_find_value_from_entity(lbModule *m, Entity *e) { return g; } } - GB_PANIC("\n\tError in: %s, missing value '%.*s'\n", token_pos_to_string(e->token.pos), LIT(e->token.string)); return {}; } @@ -2845,6 +2844,10 @@ 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 384d29ca7..9691afebc 100644 --- a/src/llvm_backend_proc.cpp +++ b/src/llvm_backend_proc.cpp @@ -68,7 +68,7 @@ gb_internal lbProcedure *lb_create_procedure(lbModule *m, Entity *entity, bool i GB_ASSERT(entity != nullptr); GB_ASSERT(entity->kind == Entity_Procedure); if (!entity->Procedure.is_foreign) { - GB_ASSERT_MSG(entity->flags & EntityFlag_ProcBodyChecked, "%.*s :: %s", LIT(entity->token.string), type_to_string(entity->type)); + GB_ASSERT_MSG(entity->flags & EntityFlag_ProcBodyChecked, "%.*s :: %s (was parapoly: %d)", LIT(entity->token.string), type_to_string(entity->type), is_type_polymorphic(entity->type, true)); } String link_name = {}; @@ -487,6 +487,7 @@ 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 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; diff --git a/src/main.cpp b/src/main.cpp index 3ad0e160f..42d6f8e87 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -660,6 +660,7 @@ enum BuildFlagKind { // internal use only BuildFlag_InternalIgnoreLazy, + BuildFlag_InternalIgnoreLLVMBuild, #if defined(GB_SYSTEM_WINDOWS) BuildFlag_IgnoreVsSearch, @@ -832,6 +833,7 @@ gb_internal bool parse_build_flags(Array args) { add_flag(&build_flags, BuildFlag_ErrorPosStyle, str_lit("error-pos-style"), BuildFlagParam_String, Command_all); add_flag(&build_flags, BuildFlag_InternalIgnoreLazy, str_lit("internal-ignore-lazy"), BuildFlagParam_None, Command_all); + add_flag(&build_flags, BuildFlag_InternalIgnoreLLVMBuild, str_lit("internal-ignore-llvm-build"),BuildFlagParam_None, Command_all); #if defined(GB_SYSTEM_WINDOWS) add_flag(&build_flags, BuildFlag_IgnoreVsSearch, str_lit("ignore-vs-search"), BuildFlagParam_None, Command__does_build); @@ -1491,6 +1493,9 @@ gb_internal bool parse_build_flags(Array args) { case BuildFlag_InternalIgnoreLazy: build_context.ignore_lazy = true; break; + case BuildFlag_InternalIgnoreLLVMBuild: + build_context.ignore_llvm_build = true; + break; #if defined(GB_SYSTEM_WINDOWS) case BuildFlag_IgnoreVsSearch: { GB_ASSERT(value.kind == ExactValue_Invalid); -- cgit v1.2.3 From ad52003077d579600d810b1337ca4d7904a1fc9b Mon Sep 17 00:00:00 2001 From: gingerBill Date: Mon, 2 Jan 2023 17:15:29 +0000 Subject: Remove some unneeded checks --- src/checker.cpp | 4 ++-- src/thread_pool.cpp | 4 +++- 2 files changed, 5 insertions(+), 3 deletions(-) (limited to 'src/checker.cpp') diff --git a/src/checker.cpp b/src/checker.cpp index f4c9b6822..c9e84a35b 100644 --- a/src/checker.cpp +++ b/src/checker.cpp @@ -1978,8 +1978,8 @@ gb_internal void add_type_info_type_internal(CheckerContext *c, Type *t) { -gb_global std::atomic global_procedure_body_in_worker_queue = false; -gb_global std::atomic global_after_checking_procedure_bodies = false; +gb_global std::atomic global_procedure_body_in_worker_queue; +gb_global std::atomic global_after_checking_procedure_bodies; gb_internal WORKER_TASK_PROC(check_proc_info_worker_proc); diff --git a/src/thread_pool.cpp b/src/thread_pool.cpp index 12a2f9292..f1f19b275 100644 --- a/src/thread_pool.cpp +++ b/src/thread_pool.cpp @@ -142,6 +142,8 @@ gb_internal THREAD_PROC(thread_pool_thread_proc) { while (pool->running.load()) { // If we've got tasks to process, work through them usize finished_tasks = 0; + i32 state; + while (thread_pool_queue_pop(current_thread, &task)) { task.do_work(task.data); pool->tasks_left.fetch_sub(1, std::memory_order_release); @@ -180,7 +182,7 @@ gb_internal THREAD_PROC(thread_pool_thread_proc) { } // if we've done all our work, and there's nothing to steal, go to sleep - i32 state = pool->tasks_available.load(); + state = pool->tasks_available.load(); futex_wait(&pool->tasks_available, state); main_loop_continue:; -- cgit v1.2.3 From 0d87b2e8db045b33cc6da18f5c53d8c3266c12b3 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Mon, 2 Jan 2023 19:39:35 +0000 Subject: Use local mutexes rather than a global one for the dependency insertion --- src/checker.cpp | 30 ++++++------------------------ src/checker.hpp | 11 +++++------ 2 files changed, 11 insertions(+), 30 deletions(-) (limited to 'src/checker.cpp') diff --git a/src/checker.cpp b/src/checker.cpp index c9e84a35b..daebe0d31 100644 --- a/src/checker.cpp +++ b/src/checker.cpp @@ -743,21 +743,17 @@ gb_internal void check_scope_usage(Checker *c, Scope *scope) { gb_internal void add_dependency(CheckerInfo *info, DeclInfo *d, Entity *e) { - mutex_lock(&info->deps_mutex); + mutex_lock(&d->deps_mutex); ptr_set_add(&d->deps, e); - mutex_unlock(&info->deps_mutex); + mutex_unlock(&d->deps_mutex); } -gb_internal void add_type_info_dependency(CheckerInfo *info, DeclInfo *d, Type *type, bool require_mutex) { +gb_internal void add_type_info_dependency(CheckerInfo *info, DeclInfo *d, Type *type) { if (d == nullptr) { return; } - if (require_mutex) { - mutex_lock(&info->deps_mutex); - } + mutex_lock(&d->type_info_deps_mutex); ptr_set_add(&d->type_info_deps, type); - if (require_mutex) { - mutex_unlock(&info->deps_mutex); - } + mutex_unlock(&d->type_info_deps_mutex); } gb_internal AstPackage *get_core_package(CheckerInfo *info, String name) { @@ -1157,13 +1153,6 @@ gb_internal void init_checker_info(CheckerInfo *i) { array_init(&i->required_foreign_imports_through_force, a, 0, 0); - - i->allow_identifier_uses = false; - if (i->allow_identifier_uses) { - array_init(&i->identifier_uses, a); - } - - TIME_SECTION("checker info: mpmc queues"); mpmc_init(&i->entity_queue, a, 1<<20); @@ -1194,7 +1183,6 @@ gb_internal void destroy_checker_info(CheckerInfo *i) { string_map_destroy(&i->files); string_map_destroy(&i->packages); array_free(&i->variable_init_order); - array_free(&i->identifier_uses); array_free(&i->required_foreign_imports_through_force); mpmc_destroy(&i->entity_queue); @@ -1597,12 +1585,6 @@ gb_internal void add_entity_use(CheckerContext *c, Ast *identifier, Entity *enti identifier->Ident.entity = entity; - if (c->info->allow_identifier_uses) { - mutex_lock(&c->info->identifier_uses_mutex); - array_add(&c->info->identifier_uses, identifier); - mutex_unlock(&c->info->identifier_uses_mutex); - } - String dmsg = entity->deprecated_message; if (dmsg.len > 0) { warning(identifier, "%.*s is deprecated: %.*s", LIT(entity->token.string), LIT(dmsg)); @@ -1767,7 +1749,7 @@ gb_internal void add_type_info_type_internal(CheckerContext *c, Type *t) { return; } - add_type_info_dependency(c->info, c->decl, t, false); + add_type_info_dependency(c->info, c->decl, t); auto found = map_get(&c->info->type_info_map, t); if (found != nullptr) { diff --git a/src/checker.hpp b/src/checker.hpp index 56f8707d3..62f655f95 100644 --- a/src/checker.hpp +++ b/src/checker.hpp @@ -179,8 +179,12 @@ struct DeclInfo { CommentGroup *comment; CommentGroup *docs; - PtrSet deps; + BlockingMutex deps_mutex; + PtrSet deps; + + BlockingMutex type_info_deps_mutex; PtrSet type_info_deps; + Array labels; }; @@ -375,11 +379,6 @@ struct CheckerInfo { BlockingMutex foreign_mutex; // NOT recursive StringMap foreigns; - // only used by 'odin query' - bool allow_identifier_uses; - BlockingMutex identifier_uses_mutex; - Array identifier_uses; - // NOTE(bill): These are actually MPSC queues // TODO(bill): Convert them to be MPSC queues MPMCQueue definition_queue; -- cgit v1.2.3 From 09c26e6be006cb285aed4b0780bee368516fd272 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Mon, 2 Jan 2023 20:38:37 +0000 Subject: Narrow type info mutex usage --- src/checker.cpp | 53 ++++++++++++++++++++++++++--------------------------- 1 file changed, 26 insertions(+), 27 deletions(-) (limited to 'src/checker.cpp') diff --git a/src/checker.cpp b/src/checker.cpp index daebe0d31..dc6a49bcf 100644 --- a/src/checker.cpp +++ b/src/checker.cpp @@ -1731,10 +1731,7 @@ gb_internal void add_type_info_type(CheckerContext *c, Type *t) { if (build_context.disallow_rtti) { return; } - - mutex_lock(&c->info->type_info_mutex); add_type_info_type_internal(c, t); - mutex_unlock(&c->info->type_info_mutex); } gb_internal void add_type_info_type_internal(CheckerContext *c, Type *t) { @@ -1751,33 +1748,35 @@ gb_internal void add_type_info_type_internal(CheckerContext *c, Type *t) { add_type_info_dependency(c->info, c->decl, t); - auto found = map_get(&c->info->type_info_map, t); - if (found != nullptr) { - // Types have already been added - return; - } + MUTEX_GUARD_BLOCK(&c->info->type_info_mutex) { + auto found = map_get(&c->info->type_info_map, t); + if (found != nullptr) { + // Types have already been added + return; + } - bool prev = false; - isize ti_index = -1; - for (auto const &e : c->info->type_info_map) { - if (are_types_identical_unique_tuples(t, e.key)) { - // Duplicate entry - ti_index = e.value; - prev = true; - break; + bool prev = false; + isize ti_index = -1; + for (auto const &e : c->info->type_info_map) { + if (are_types_identical_unique_tuples(t, e.key)) { + // Duplicate entry + ti_index = e.value; + prev = true; + break; + } } - } - if (ti_index < 0) { - // 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); - } - map_set(&c->checker->info.type_info_map, t, ti_index); + if (ti_index < 0) { + // 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); + } + map_set(&c->checker->info.type_info_map, t, ti_index); - if (prev) { - // NOTE(bill): If a previous one exists already, no need to continue - return; + if (prev) { + // NOTE(bill): If a previous one exists already, no need to continue + return; + } } // Add nested types -- cgit v1.2.3 From df2767311f11255da311a23bc240077fa8f933b1 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Mon, 2 Jan 2023 20:42:22 +0000 Subject: Use `mutex_try_lock` in `check_proc_info` --- src/checker.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'src/checker.cpp') diff --git a/src/checker.cpp b/src/checker.cpp index dc6a49bcf..f80ea9e4c 100644 --- a/src/checker.cpp +++ b/src/checker.cpp @@ -5050,7 +5050,10 @@ gb_internal bool check_proc_info(Checker *c, ProcInfo *pi, UntypedExprInfoMap *u return false; } - MUTEX_GUARD(&pi->decl->proc_checked_mutex); + if (!mutex_try_lock(&pi->decl->proc_checked_mutex)) { + return false; + } + defer (mutex_unlock(&pi->decl->proc_checked_mutex)); Entity *e = pi->decl->entity; switch (pi->decl->proc_checked_state.load()) { -- cgit v1.2.3 From 318d92f9a8651e75da2e0846e0e5d60a4a137a25 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Mon, 2 Jan 2023 21:37:21 +0000 Subject: Comment out `type_and_value_mutex` usage --- src/checker.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/checker.cpp') diff --git a/src/checker.cpp b/src/checker.cpp index f80ea9e4c..e78a4f65f 100644 --- a/src/checker.cpp +++ b/src/checker.cpp @@ -1451,7 +1451,7 @@ gb_internal void add_type_and_value(CheckerInfo *i, Ast *expr, AddressingMode mo return; } - mutex_lock(&i->type_and_value_mutex); + // mutex_lock(&i->type_and_value_mutex); Ast *prev_expr = nullptr; while (prev_expr != expr) { prev_expr = expr; @@ -1473,7 +1473,7 @@ gb_internal void add_type_and_value(CheckerInfo *i, Ast *expr, AddressingMode mo expr = unparen_expr(expr); } - mutex_unlock(&i->type_and_value_mutex); + // mutex_unlock(&i->type_and_value_mutex); } gb_internal void add_entity_definition(CheckerInfo *i, Ast *identifier, Entity *entity) { -- cgit v1.2.3 From d36c3c2590d28bbfc8bc887b9dd0aebc3ac92667 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Mon, 2 Jan 2023 22:06:05 +0000 Subject: Re enable `type_and_value_mutex` --- src/checker.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/checker.cpp') diff --git a/src/checker.cpp b/src/checker.cpp index e78a4f65f..f80ea9e4c 100644 --- a/src/checker.cpp +++ b/src/checker.cpp @@ -1451,7 +1451,7 @@ gb_internal void add_type_and_value(CheckerInfo *i, Ast *expr, AddressingMode mo return; } - // mutex_lock(&i->type_and_value_mutex); + mutex_lock(&i->type_and_value_mutex); Ast *prev_expr = nullptr; while (prev_expr != expr) { prev_expr = expr; @@ -1473,7 +1473,7 @@ gb_internal void add_type_and_value(CheckerInfo *i, Ast *expr, AddressingMode mo expr = unparen_expr(expr); } - // mutex_unlock(&i->type_and_value_mutex); + mutex_unlock(&i->type_and_value_mutex); } gb_internal void add_entity_definition(CheckerInfo *i, Ast *identifier, Entity *entity) { -- cgit v1.2.3 From 69b075782bac981ceeea5eea8f544e346f0fe6b5 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Mon, 2 Jan 2023 22:40:28 +0000 Subject: Use a package local mutex for `add_type_and_value` --- src/check_decl.cpp | 9 ++++++--- src/check_expr.cpp | 56 +++++++++++++++++++++++++++--------------------------- src/check_type.cpp | 2 +- src/checker.cpp | 13 +++++++++---- src/checker.hpp | 2 +- src/parser.hpp | 1 + 6 files changed, 46 insertions(+), 37 deletions(-) (limited to 'src/checker.cpp') diff --git a/src/check_decl.cpp b/src/check_decl.cpp index 2b6868f05..e3486924c 100644 --- a/src/check_decl.cpp +++ b/src/check_decl.cpp @@ -45,7 +45,7 @@ gb_internal Type *check_init_variable(CheckerContext *ctx, Entity *e, Operand *o if (operand->mode == Addressing_Type) { if (e->type != nullptr && is_type_typeid(e->type)) { add_type_info_type(ctx, operand->type); - add_type_and_value(ctx->info, operand->expr, Addressing_Value, e->type, exact_value_typeid(operand->type)); + add_type_and_value(ctx, operand->expr, Addressing_Value, e->type, exact_value_typeid(operand->type)); return e->type; } else { gbString t = type_to_string(operand->type); @@ -1585,13 +1585,16 @@ gb_internal bool check_proc_body(CheckerContext *ctx_, Token token, DeclInfo *de // NOTE(bill): Add the dependencies from the procedure literal (lambda) // But only at the procedure level - MUTEX_GUARD_BLOCK(decl->deps_mutex) MUTEX_GUARD_BLOCK(decl->parent->deps_mutex) { + MUTEX_GUARD_BLOCK(decl->deps_mutex) + MUTEX_GUARD_BLOCK(decl->parent->deps_mutex) { for (auto const &entry : decl->deps) { Entity *e = entry.ptr; ptr_set_add(&decl->parent->deps, e); } } - MUTEX_GUARD_BLOCK(decl->type_info_deps_mutex) MUTEX_GUARD_BLOCK(decl->parent->type_info_deps_mutex) { + + MUTEX_GUARD_BLOCK(decl->type_info_deps_mutex) + MUTEX_GUARD_BLOCK(decl->parent->type_info_deps_mutex) { for (auto const &entry : decl->type_info_deps) { Type *t = entry.ptr; ptr_set_add(&decl->parent->type_info_deps, t); diff --git a/src/check_expr.cpp b/src/check_expr.cpp index b40c48459..9feac93ea 100644 --- a/src/check_expr.cpp +++ b/src/check_expr.cpp @@ -852,7 +852,7 @@ gb_internal i64 check_distance_between_types(CheckerContext *c, Operand *operand PolyProcData poly_proc_data = {}; if (check_polymorphic_procedure_assignment(c, operand, type, operand->expr, &poly_proc_data)) { Entity *e = poly_proc_data.gen_entity; - add_type_and_value(c->info, operand->expr, Addressing_Value, e->type, {}); + add_type_and_value(c, operand->expr, Addressing_Value, e->type, {}); add_entity_use(c, operand->expr, e); return 4; } @@ -1082,7 +1082,7 @@ gb_internal void check_assignment(CheckerContext *c, Operand *operand, Type *typ if (check_is_assignable_to(c, operand, type)) { if (operand->mode == Addressing_Type && is_type_typeid(type)) { add_type_info_type(c, operand->type); - add_type_and_value(c->info, operand->expr, Addressing_Value, type, exact_value_typeid(operand->type)); + add_type_and_value(c, operand->expr, Addressing_Value, type, exact_value_typeid(operand->type)); } } else { gbString expr_str = expr_to_string(operand->expr); @@ -2374,7 +2374,7 @@ gb_internal void check_comparison(CheckerContext *c, Operand *x, Operand *y, Tok if (x->mode == Addressing_Type && is_type_typeid(y->type)) { add_type_info_type(c, x->type); add_type_info_type(c, y->type); - add_type_and_value(c->info, x->expr, Addressing_Value, y->type, exact_value_typeid(x->type)); + add_type_and_value(c, x->expr, Addressing_Value, y->type, exact_value_typeid(x->type)); x->mode = Addressing_Value; x->type = t_untyped_bool; @@ -2382,7 +2382,7 @@ gb_internal void check_comparison(CheckerContext *c, Operand *x, Operand *y, Tok } else if (is_type_typeid(x->type) && y->mode == Addressing_Type) { add_type_info_type(c, x->type); add_type_info_type(c, y->type); - add_type_and_value(c->info, y->expr, Addressing_Value, x->type, exact_value_typeid(y->type)); + add_type_and_value(c, y->expr, Addressing_Value, x->type, exact_value_typeid(y->type)); x->mode = Addressing_Value; x->type = t_untyped_bool; @@ -3615,7 +3615,7 @@ gb_internal void update_untyped_expr_type(CheckerContext *c, Ast *e, Type *type, if (old == nullptr) { if (type != nullptr && type != t_invalid) { if (e->tav.type == nullptr || e->tav.type == t_invalid) { - add_type_and_value(c->info, e, e->tav.mode, type ? type : e->tav.type, e->tav.value); + add_type_and_value(c, e, e->tav.mode, type ? type : e->tav.type, e->tav.value); if (e->kind == Ast_TernaryIfExpr) { update_untyped_expr_type(c, e->TernaryIfExpr.x, type, final); update_untyped_expr_type(c, e->TernaryIfExpr.y, type, final); @@ -3721,7 +3721,7 @@ gb_internal void update_untyped_expr_type(CheckerContext *c, Ast *e, Type *type, return; } - add_type_and_value(c->info, e, old->mode, type, old->value); + add_type_and_value(c, e, old->mode, type, old->value); } gb_internal void update_untyped_expr_value(CheckerContext *c, Ast *e, ExactValue value) { @@ -4569,7 +4569,7 @@ gb_internal Entity *check_selector(CheckerContext *c, Operand *operand, Ast *nod operand->mode = Addressing_ProcGroup; operand->proc_group = entity; - add_type_and_value(c->info, operand->expr, operand->mode, operand->type, operand->value); + add_type_and_value(c, operand->expr, operand->mode, operand->type, operand->value); return entity; } GB_ASSERT_MSG(entity->type != nullptr, "%.*s (%.*s)", LIT(entity->token.string), LIT(entity_strings[entity->kind])); @@ -4738,7 +4738,7 @@ gb_internal Entity *check_selector(CheckerContext *c, Operand *operand, Ast *nod } Entity *swizzle_entity = alloc_entity_variable(nullptr, make_token_ident(field_name), operand->type, EntityState_Resolved); - add_type_and_value(c->info, operand->expr, operand->mode, operand->type, operand->value); + add_type_and_value(c, operand->expr, operand->mode, operand->type, operand->value); return swizzle_entity; } end_of_array_selector_swizzle:; @@ -4782,7 +4782,7 @@ gb_internal Entity *check_selector(CheckerContext *c, Operand *operand, Ast *nod operand->value = field_value; operand->type = entity->type; add_entity_use(c, selector, entity); - add_type_and_value(c->info, operand->expr, operand->mode, operand->type, operand->value); + add_type_and_value(c, operand->expr, operand->mode, operand->type, operand->value); return entity; } @@ -4807,7 +4807,7 @@ gb_internal Entity *check_selector(CheckerContext *c, Operand *operand, Ast *nod operand->value = field_value; operand->type = entity->type; add_entity_use(c, selector, entity); - add_type_and_value(c->info, operand->expr, operand->mode, operand->type, operand->value); + add_type_and_value(c, operand->expr, operand->mode, operand->type, operand->value); return entity; } @@ -4895,7 +4895,7 @@ gb_internal Entity *check_selector(CheckerContext *c, Operand *operand, Ast *nod break; } - add_type_and_value(c->info, operand->expr, operand->mode, operand->type, operand->value); + add_type_and_value(c, operand->expr, operand->mode, operand->type, operand->value); return entity; } @@ -5361,7 +5361,7 @@ gb_internal CALL_ARGUMENT_CHECKER(check_call_arguments_internal) { if (o.mode == Addressing_Type && is_type_typeid(e->type)) { add_type_info_type(c, o.type); - add_type_and_value(c->info, o.expr, Addressing_Value, e->type, exact_value_typeid(o.type)); + add_type_and_value(c, o.expr, Addressing_Value, e->type, exact_value_typeid(o.type)); } else if (show_error && is_type_untyped(o.type)) { update_untyped_expr_type(c, o.expr, t, true); } @@ -5412,7 +5412,7 @@ gb_internal CALL_ARGUMENT_CHECKER(check_call_arguments_internal) { } if (o.mode == Addressing_Type && is_type_typeid(t)) { add_type_info_type(c, o.type); - add_type_and_value(c->info, o.expr, Addressing_Value, t, exact_value_typeid(o.type)); + add_type_and_value(c, o.expr, Addressing_Value, t, exact_value_typeid(o.type)); } else if (show_error && is_type_untyped(o.type)) { update_untyped_expr_type(c, o.expr, t, true); } @@ -5425,7 +5425,7 @@ gb_internal CALL_ARGUMENT_CHECKER(check_call_arguments_internal) { data->score = score; data->result_type = final_proc_type->Proc.results; data->gen_entity = gen_entity; - add_type_and_value(c->info, ce->proc, Addressing_Value, final_proc_type, {}); + add_type_and_value(c, ce->proc, Addressing_Value, final_proc_type, {}); } return err; @@ -5625,7 +5625,7 @@ gb_internal CALL_ARGUMENT_CHECKER(check_named_call_arguments) { if (o->mode == Addressing_Type && is_type_typeid(e->type)) { add_type_info_type(c, o->type); - add_type_and_value(c->info, o->expr, Addressing_Value, e->type, exact_value_typeid(o->type)); + add_type_and_value(c, o->expr, Addressing_Value, e->type, exact_value_typeid(o->type)); } } @@ -5633,7 +5633,7 @@ gb_internal CALL_ARGUMENT_CHECKER(check_named_call_arguments) { data->score = score; data->result_type = pt->results; data->gen_entity = gen_entity; - add_type_and_value(c->info, ce->proc, Addressing_Value, proc_type, {}); + add_type_and_value(c, ce->proc, Addressing_Value, proc_type, {}); } return err; @@ -6635,7 +6635,7 @@ gb_internal ExprKind check_call_expr(CheckerContext *c, Operand *operand, Ast *c operand->builtin_id = BuiltinProc_DIRECTIVE; operand->expr = proc; operand->type = t_invalid; - add_type_and_value(c->info, proc, operand->mode, operand->type, operand->value); + add_type_and_value(c, proc, operand->mode, operand->type, operand->value); } else { error(proc, "Unknown directive: #%.*s", LIT(name)); operand->expr = proc; @@ -6713,7 +6713,7 @@ gb_internal ExprKind check_call_expr(CheckerContext *c, Operand *operand, Ast *c GB_ASSERT(ot->kind == Type_Named); Entity *e = ot->Named.type_name; add_entity_use(c, ident, e); - add_type_and_value(c->info, call, Addressing_Type, ot, empty_exact_value); + add_type_and_value(c, call, Addressing_Type, ot, empty_exact_value); } else { operand->mode = Addressing_Invalid; operand->type = t_invalid; @@ -6885,7 +6885,7 @@ gb_internal ExprKind check_call_expr(CheckerContext *c, Operand *operand, Ast *c } } - // add_type_and_value(c->info, operand->expr, operand->mode, operand->type, operand->value); + // add_type_and_value(c, operand->expr, operand->mode, operand->type, operand->value); return Expr_Expr; } @@ -7129,8 +7129,8 @@ gb_internal bool check_range(CheckerContext *c, Ast *node, Operand *x, Operand * return false; } - add_type_and_value(c->info, ie->left, x->mode, x->type, x->value); - add_type_and_value(c->info, ie->right, y->mode, y->type, y->value); + add_type_and_value(c, ie->left, x->mode, x->type, x->value); + add_type_and_value(c, ie->right, y->mode, y->type, y->value); return true; } @@ -7146,7 +7146,7 @@ gb_internal bool check_is_operand_compound_lit_constant(CheckerContext *c, Opera return true; } if (expr->kind == Ast_ProcLit) { - add_type_and_value(c->info, expr, Addressing_Constant, type_of_expr(expr), exact_value_procedure(expr)); + add_type_and_value(c, expr, Addressing_Constant, type_of_expr(expr), exact_value_procedure(expr)); return true; } } @@ -7255,7 +7255,7 @@ gb_internal void check_promote_optional_ok(CheckerContext *c, Operand *x, Type * Type *pt = base_type(type_of_expr(expr->CallExpr.proc)); if (is_type_proc(pt)) { Type *tuple = pt->Proc.results; - add_type_and_value(c->info, x->expr, x->mode, tuple, x->value); + add_type_and_value(c, x->expr, x->mode, tuple, x->value); if (pt->Proc.result_count >= 2) { if (ok_type_) *ok_type_ = tuple->Tuple.variables[1]->type; @@ -7268,7 +7268,7 @@ gb_internal void check_promote_optional_ok(CheckerContext *c, Operand *x, Type * Type *tuple = make_optional_ok_type(x->type); if (ok_type_) *ok_type_ = tuple->Tuple.variables[1]->type; - add_type_and_value(c->info, x->expr, x->mode, tuple, x->value); + add_type_and_value(c, x->expr, x->mode, tuple, x->value); x->type = tuple; GB_ASSERT(is_type_tuple(type_of_expr(x->expr))); } @@ -7688,7 +7688,7 @@ gb_internal ExprKind check_or_else_expr(CheckerContext *c, Operand *o, Ast *node Type *left_type = nullptr; Type *right_type = nullptr; check_or_else_split_types(c, &x, name, &left_type, &right_type); - add_type_and_value(&c->checker->info, arg, x.mode, x.type, x.value); + add_type_and_value(c, arg, x.mode, x.type, x.value); if (left_type != nullptr) { if (!y_is_diverging) { @@ -7723,7 +7723,7 @@ gb_internal ExprKind check_or_return_expr(CheckerContext *c, Operand *o, Ast *no Type *left_type = nullptr; Type *right_type = nullptr; check_or_return_split_types(c, &x, name, &left_type, &right_type); - add_type_and_value(&c->checker->info, re->expr, x.mode, x.type, x.value); + add_type_and_value(c, re->expr, x.mode, x.type, x.value); if (right_type == nullptr) { check_or_else_expr_no_value_error(c, name, x, type_hint); @@ -8149,7 +8149,7 @@ gb_internal ExprKind check_compound_literal(CheckerContext *c, Operand *o, Ast * error(elem, "Expected a constant integer as an array field"); continue; } - // add_type_and_value(c->info, op_index.expr, op_index.mode, op_index.type, op_index.value); + // add_type_and_value(c, op_index.expr, op_index.mode, op_index.type, op_index.value); i64 index = exact_value_to_i64(op_index.value); @@ -9783,7 +9783,7 @@ gb_internal ExprKind check_expr_base(CheckerContext *c, Operand *o, Ast *node, T } check_rtti_type_disallowed(node, o->type, "An expression is using a type, %s, which has been disallowed"); - add_type_and_value(c->info, node, o->mode, o->type, o->value); + add_type_and_value(c, node, o->mode, o->type, o->value); return kind; } diff --git a/src/check_type.cpp b/src/check_type.cpp index 4634e1fbe..05fdbf4d3 100644 --- a/src/check_type.cpp +++ b/src/check_type.cpp @@ -3045,7 +3045,7 @@ gb_internal Type *check_type_expr(CheckerContext *ctx, Ast *e, Type *named_type) #endif if (is_type_typed(type)) { - add_type_and_value(ctx->info, e, Addressing_Type, type, empty_exact_value); + add_type_and_value(ctx, e, Addressing_Type, type, empty_exact_value); } else { gbString name = type_to_string(type); error(e, "Invalid type definition of %s", name); diff --git a/src/checker.cpp b/src/checker.cpp index f80ea9e4c..e48142c82 100644 --- a/src/checker.cpp +++ b/src/checker.cpp @@ -1440,7 +1440,7 @@ gb_internal void add_untyped(CheckerContext *c, Ast *expr, AddressingMode mode, check_set_expr_info(c, expr, mode, type, value); } -gb_internal void add_type_and_value(CheckerInfo *i, Ast *expr, AddressingMode mode, Type *type, ExactValue value) { +gb_internal void add_type_and_value(CheckerContext *ctx, Ast *expr, AddressingMode mode, Type *type, ExactValue value) { if (expr == nullptr) { return; } @@ -1451,7 +1451,12 @@ gb_internal void add_type_and_value(CheckerInfo *i, Ast *expr, AddressingMode mo return; } - mutex_lock(&i->type_and_value_mutex); + BlockingMutex *mutex = &ctx->info->type_and_value_mutex; + if (ctx->pkg) { + mutex = &ctx->pkg->type_and_value_mutex; + } + + mutex_lock(mutex); Ast *prev_expr = nullptr; while (prev_expr != expr) { prev_expr = expr; @@ -1473,7 +1478,7 @@ gb_internal void add_type_and_value(CheckerInfo *i, Ast *expr, AddressingMode mo expr = unparen_expr(expr); } - mutex_unlock(&i->type_and_value_mutex); + mutex_unlock(mutex); } gb_internal void add_entity_definition(CheckerInfo *i, Ast *identifier, Entity *entity) { @@ -5701,7 +5706,7 @@ gb_internal void check_parsed_files(Checker *c) { if (is_type_typed(u.info->type)) { compiler_error("%s (type %s) is typed!", expr_to_string(u.expr), type_to_string(u.info->type)); } - add_type_and_value(&c->info, u.expr, u.info->mode, u.info->type, u.info->value); + add_type_and_value(&c->builtin_ctx, u.expr, u.info->mode, u.info->type, u.info->value); } diff --git a/src/checker.hpp b/src/checker.hpp index 62f655f95..04cb1e311 100644 --- a/src/checker.hpp +++ b/src/checker.hpp @@ -482,7 +482,7 @@ gb_internal void scope_lookup_parent (Scope *s, String const &name, Scope **s gb_internal Entity *scope_insert (Scope *s, Entity *entity); -gb_internal void add_type_and_value (CheckerInfo *i, Ast *expression, AddressingMode mode, Type *type, ExactValue value); +gb_internal void add_type_and_value (CheckerContext *c, Ast *expression, AddressingMode mode, Type *type, ExactValue value); gb_internal ExprInfo *check_get_expr_info (CheckerContext *c, Ast *expr); gb_internal void add_untyped (CheckerContext *c, Ast *expression, AddressingMode mode, Type *basic_type, ExactValue value); gb_internal void add_entity_use (CheckerContext *c, Ast *identifier, Entity *entity); diff --git a/src/parser.hpp b/src/parser.hpp index c33739ebe..b492cfa85 100644 --- a/src/parser.hpp +++ b/src/parser.hpp @@ -174,6 +174,7 @@ struct AstPackage { BlockingMutex files_mutex; BlockingMutex foreign_files_mutex; + BlockingMutex type_and_value_mutex; MPMCQueue exported_entity_queue; -- cgit v1.2.3 From fd62ee14cdfe48be93b041aeadaf4d5eedce0447 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Mon, 2 Jan 2023 23:31:38 +0000 Subject: Code moving around --- src/checker.cpp | 47 +++++++++++++++++++++++++++-------------------- 1 file changed, 27 insertions(+), 20 deletions(-) (limited to 'src/checker.cpp') diff --git a/src/checker.cpp b/src/checker.cpp index e48142c82..c2cd1163a 100644 --- a/src/checker.cpp +++ b/src/checker.cpp @@ -5218,6 +5218,31 @@ gb_internal void check_unchecked_bodies(Checker *c) { global_after_checking_procedure_bodies = true; } +gb_internal void check_safety_all_procedures_for_unchecked(Checker *c) { + GB_ASSERT(DEBUG_CHECK_ALL_PROCEDURES); + UntypedExprInfoMap untyped = {}; + map_init(&untyped, heap_allocator()); + defer (map_destroy(&untyped)); + + + for_array(i, c->info.all_procedures) { + ProcInfo *pi = c->info.all_procedures[i]; + GB_ASSERT(pi != nullptr); + GB_ASSERT(pi->decl != nullptr); + Entity *e = pi->decl->entity; + auto proc_checked_state = pi->decl->proc_checked_state.load(); + if (e && ((e->flags & EntityFlag_ProcBodyChecked) == 0)) { + if ((e->flags & EntityFlag_Used) != 0) { + debugf("%.*s :: %s\n", LIT(e->token.string), type_to_string(e->type)); + debugf("proc body unchecked\n"); + debugf("Checked State: %s\n\n", ProcCheckedState_strings[proc_checked_state]); + + consume_proc_info(c, pi, &untyped); + } + } + } +} + gb_internal void check_test_procedures(Checker *c) { if (build_context.test_names.entries.count == 0) { return; @@ -5790,26 +5815,8 @@ gb_internal void check_parsed_files(Checker *c) { GB_ASSERT(c->procs_to_check.count == 0); if (DEBUG_CHECK_ALL_PROCEDURES) { - UntypedExprInfoMap untyped = {}; - map_init(&untyped, heap_allocator()); - defer (map_destroy(&untyped)); - - for_array(i, c->info.all_procedures) { - ProcInfo *pi = c->info.all_procedures[i]; - GB_ASSERT(pi != nullptr); - GB_ASSERT(pi->decl != nullptr); - Entity *e = pi->decl->entity; - auto proc_checked_state = pi->decl->proc_checked_state.load(); - if (e && ((e->flags & EntityFlag_ProcBodyChecked) == 0)) { - if ((e->flags & EntityFlag_Used) != 0) { - debugf("%.*s :: %s\n", LIT(e->token.string), type_to_string(e->type)); - debugf("proc body unchecked\n"); - debugf("Checked State: %s\n\n", ProcCheckedState_strings[proc_checked_state]); - - consume_proc_info(c, pi, &untyped); - } - } - } + TIME_SECTION("check unchecked (safety measure)"); + check_safety_all_procedures_for_unchecked(c); } debugf("Total Procedure Bodies Checked: %td\n", total_bodies_checked.load(std::memory_order_relaxed)); -- cgit v1.2.3 From e10fe91ebacdf6256608672a805de9d376e698fe Mon Sep 17 00:00:00 2001 From: gingerBill Date: Mon, 2 Jan 2023 23:50:48 +0000 Subject: Narrow global `gen_procs_mutex` further --- src/check_expr.cpp | 9 +++------ src/checker.cpp | 1 + src/thread_pool.cpp | 2 +- 3 files changed, 5 insertions(+), 7 deletions(-) (limited to 'src/checker.cpp') diff --git a/src/check_expr.cpp b/src/check_expr.cpp index 65a411dc1..e3c55870c 100644 --- a/src/check_expr.cpp +++ b/src/check_expr.cpp @@ -439,7 +439,6 @@ gb_internal bool find_or_generate_polymorphic_procedure(CheckerContext *old_c, E // @@GPM ////////////////////////// mutex_lock(&info->gen_procs_mutex); /////////////////////////////////// - auto *found = map_get(&info->gen_procs, base_entity->identifier.load()); if (found) { gen_procs = *found; @@ -462,6 +461,9 @@ gb_internal bool find_or_generate_polymorphic_procedure(CheckerContext *old_c, E gen_procs->procs.allocator = heap_allocator(); map_set(&info->gen_procs, base_entity->identifier.load(), gen_procs); } + // @@GPM //////////////////////////// + mutex_unlock(&info->gen_procs_mutex); + ///////////////////////////////////// { // LEAK TODO(bill): This is technically a memory leak as it has to generate the type twice @@ -475,11 +477,6 @@ 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) { return false; } diff --git a/src/checker.cpp b/src/checker.cpp index c2cd1163a..ccd0f3627 100644 --- a/src/checker.cpp +++ b/src/checker.cpp @@ -51,6 +51,7 @@ gb_internal bool check_rtti_type_disallowed(Ast *expr, Type *type, char const *f gb_internal void scope_reset(Scope *scope) { if (scope == nullptr) return; + MUTEX_GUARD(&scope->mutex); scope->head_child.store(nullptr, std::memory_order_relaxed); string_map_clear(&scope->elements); ptr_set_clear(&scope->imported); diff --git a/src/thread_pool.cpp b/src/thread_pool.cpp index b89e00454..07ab3d323 100644 --- a/src/thread_pool.cpp +++ b/src/thread_pool.cpp @@ -167,7 +167,7 @@ gb_internal THREAD_PROC(thread_pool_thread_proc) { idx = (idx + 1) % cast(usize)pool->threads.count; Thread *thread = &pool->threads.data[idx]; - WorkerTask task, another_task; + WorkerTask task; if (!thread_pool_queue_pop(thread, &task)) { continue; } -- cgit v1.2.3 From 600f2b7284b8974a18827242c18e790dab0cf06a Mon Sep 17 00:00:00 2001 From: gingerBill Date: Tue, 3 Jan 2023 11:53:59 +0000 Subject: Use heap_allocator for all hash set types --- src/build_settings.cpp | 2 +- src/check_builtin.cpp | 2 +- src/check_decl.cpp | 2 +- src/check_expr.cpp | 1 - src/check_stmt.cpp | 1 - src/checker.cpp | 24 +++++++----------------- src/llvm_backend_general.cpp | 2 +- src/llvm_backend_type.cpp | 2 +- src/main.cpp | 8 ++++---- src/parser.cpp | 2 +- src/ptr_set.cpp | 21 +++++++++++++++------ src/string_set.cpp | 18 +++++++++++++----- 12 files changed, 45 insertions(+), 40 deletions(-) (limited to 'src/checker.cpp') diff --git a/src/build_settings.cpp b/src/build_settings.cpp index 04d1ada93..75615a901 100644 --- a/src/build_settings.cpp +++ b/src/build_settings.cpp @@ -1369,7 +1369,7 @@ gb_internal bool init_build_paths(String init_filename) { // NOTE(Jeroen): We're pre-allocating BuildPathCOUNT slots so that certain paths are always at the same enumerated index. array_init(&bc->build_paths, permanent_allocator(), BuildPathCOUNT); - string_set_init(&bc->target_features_set, heap_allocator(), 1024); + string_set_init(&bc->target_features_set, 1024); // [BuildPathMainPackage] Turn given init path into a `Path`, which includes normalizing it into a full path. bc->build_paths[BuildPath_Main_Package] = path_from_string(ha, init_filename); diff --git a/src/check_builtin.cpp b/src/check_builtin.cpp index 99d956f5e..36dc9b7a1 100644 --- a/src/check_builtin.cpp +++ b/src/check_builtin.cpp @@ -3086,7 +3086,7 @@ gb_internal bool check_builtin_procedure(CheckerContext *c, Operand *operand, As } } StringSet name_set = {}; - string_set_init(&name_set, heap_allocator(), 2*ce->args.count); + string_set_init(&name_set, 2*ce->args.count); for_array(i, ce->args) { String name = {}; diff --git a/src/check_decl.cpp b/src/check_decl.cpp index e3486924c..0c1a7c325 100644 --- a/src/check_decl.cpp +++ b/src/check_decl.cpp @@ -1235,7 +1235,7 @@ gb_internal void check_proc_group_decl(CheckerContext *ctx, Entity *&pg_entity, pg_entity->type = t_invalid; PtrSet entity_set = {}; - ptr_set_init(&entity_set, heap_allocator(), 2*pg->args.count); + ptr_set_init(&entity_set, 2*pg->args.count); for_array(i, pg->args) { Ast *arg = pg->args[i]; diff --git a/src/check_expr.cpp b/src/check_expr.cpp index 3c998fc44..7a00b5353 100644 --- a/src/check_expr.cpp +++ b/src/check_expr.cpp @@ -196,7 +196,6 @@ gb_internal void check_did_you_mean_objc_entity(String const &name, Entity *e, b MUTEX_GUARD(objc_metadata->mutex); StringSet set = {}; - string_set_init(&set, heap_allocator()); defer (string_set_destroy(&set)); populate_check_did_you_mean_objc_entity(&set, e, is_type); diff --git a/src/check_stmt.cpp b/src/check_stmt.cpp index cf111e84c..945ba8f02 100644 --- a/src/check_stmt.cpp +++ b/src/check_stmt.cpp @@ -1185,7 +1185,6 @@ gb_internal void check_type_switch_stmt(CheckerContext *ctx, Ast *node, u32 mod_ } PtrSet seen = {}; - ptr_set_init(&seen, heap_allocator()); defer (ptr_set_destroy(&seen)); for_array(i, bs->stmts) { diff --git a/src/checker.cpp b/src/checker.cpp index ccd0f3627..8da659461 100644 --- a/src/checker.cpp +++ b/src/checker.cpp @@ -72,7 +72,7 @@ gb_internal void entity_graph_node_set_destroy(EntityGraphNodeSet *s) { gb_internal void entity_graph_node_set_add(EntityGraphNodeSet *s, EntityGraphNode *n) { if (s->hashes.data == nullptr) { - ptr_set_init(s, heap_allocator()); + ptr_set_init(s); } ptr_set_add(s, n); } @@ -118,15 +118,10 @@ gb_internal void entity_graph_node_swap(EntityGraphNode **data, isize i, isize j gb_internal void import_graph_node_set_destroy(ImportGraphNodeSet *s) { - if (s->hashes.data != nullptr) { - ptr_set_destroy(s); - } + ptr_set_destroy(s); } gb_internal void import_graph_node_set_add(ImportGraphNodeSet *s, ImportGraphNode *n) { - if (s->hashes.data == nullptr) { - ptr_set_init(s, heap_allocator()); - } ptr_set_add(s, n); } @@ -185,8 +180,8 @@ gb_internal void init_decl_info(DeclInfo *d, Scope *scope, DeclInfo *parent) { gb_zero_item(d); d->parent = parent; d->scope = scope; - ptr_set_init(&d->deps, heap_allocator()); - ptr_set_init(&d->type_info_deps, heap_allocator()); + ptr_set_init(&d->deps); + ptr_set_init(&d->type_info_deps); array_init (&d->labels, heap_allocator()); } @@ -227,7 +222,7 @@ gb_internal Scope *create_scope(CheckerInfo *info, Scope *parent, isize init_ele Scope *s = gb_alloc_item(permanent_allocator(), Scope); s->parent = parent; string_map_init(&s->elements, heap_allocator(), init_elements_capacity); - ptr_set_init(&s->imported, heap_allocator(), 0); + ptr_set_init(&s->imported, 0); if (parent != nullptr && parent != builtin_pkg->scope) { Scope *prev_head_child = parent->head_child.exchange(s, std::memory_order_acq_rel); @@ -2270,8 +2265,8 @@ gb_internal void generate_minimum_dependency_set(Checker *c, Entity *start) { isize entity_count = c->info.entities.count; isize min_dep_set_cap = next_pow2_isize(entity_count*4); // empirically determined factor - ptr_set_init(&c->info.minimum_dependency_set, heap_allocator(), min_dep_set_cap); - ptr_set_init(&c->info.minimum_dependency_type_info_set, heap_allocator()); + ptr_set_init(&c->info.minimum_dependency_set, min_dep_set_cap); + ptr_set_init(&c->info.minimum_dependency_type_info_set); #define FORCE_ADD_RUNTIME_ENTITIES(condition, ...) do { \ if (condition) { \ @@ -3388,7 +3383,6 @@ gb_internal void check_decl_attributes(CheckerContext *c, Array const &at } StringSet set = {}; - string_set_init(&set, heap_allocator()); defer (string_set_destroy(&set)); for_array(i, attributes) { @@ -4759,7 +4753,6 @@ gb_internal void check_import_entities(Checker *c) { auto pq = priority_queue_create(dep_graph, import_graph_node_cmp, import_graph_node_swap); PtrSet emitted = {}; - ptr_set_init(&emitted, heap_allocator()); defer (ptr_set_destroy(&emitted)); Array package_order = {}; @@ -4773,7 +4766,6 @@ gb_internal void check_import_entities(Checker *c) { if (n->dep_count > 0) { PtrSet visited = {}; - ptr_set_init(&visited, heap_allocator()); defer (ptr_set_destroy(&visited)); auto path = find_import_path(c, pkg, pkg, &visited); @@ -4927,7 +4919,6 @@ gb_internal Array find_entity_path(Entity *start, Entity *end, PtrSet< bool made_visited = false; if (visited == nullptr) { made_visited = true; - ptr_set_init(&visited_, heap_allocator()); visited = &visited_; } defer (if (made_visited) { @@ -4990,7 +4981,6 @@ gb_internal void calculate_global_init_order(Checker *c) { auto pq = priority_queue_create(dep_graph, entity_graph_node_cmp, entity_graph_node_swap); PtrSet emitted = {}; - ptr_set_init(&emitted, heap_allocator()); defer (ptr_set_destroy(&emitted)); TIME_SECTION("calculate_global_init_order: queue sort"); diff --git a/src/llvm_backend_general.cpp b/src/llvm_backend_general.cpp index 22628e895..75675474a 100644 --- a/src/llvm_backend_general.cpp +++ b/src/llvm_backend_general.cpp @@ -133,7 +133,7 @@ gb_internal bool lb_init_generator(lbGenerator *gen, Checker *c) { array_init(&gen->foreign_libraries, heap_allocator(), 0, 1024); - ptr_set_init(&gen->foreign_libraries_set, heap_allocator(), 1024); + ptr_set_init(&gen->foreign_libraries_set, 1024); if (USE_SEPARATE_MODULES) { for (auto const &entry : gen->info->packages) { diff --git a/src/llvm_backend_type.cpp b/src/llvm_backend_type.cpp index 26bb614e6..c306cdead 100644 --- a/src/llvm_backend_type.cpp +++ b/src/llvm_backend_type.cpp @@ -2,7 +2,7 @@ gb_internal isize lb_type_info_index(CheckerInfo *info, Type *type, bool err_on_ auto *set = &info->minimum_dependency_type_info_set; isize index = type_info_index(info, type, err_on_not_found); if (index >= 0) { - isize i = ptr_entry_index(set, index); + isize i = ptr_set_entry_index(set, index); if (i >= 0) { return i+1; } diff --git a/src/main.cpp b/src/main.cpp index ad9d6b0ef..91dcbdb01 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -212,11 +212,11 @@ gb_internal i32 linker_stage(lbGenerator *gen) { StringSet libs = {}; - string_set_init(&libs, heap_allocator(), 64); + string_set_init(&libs, 64); defer (string_set_destroy(&libs)); StringSet asm_files = {}; - string_set_init(&asm_files, heap_allocator(), 64); + string_set_init(&asm_files, 64); defer (string_set_destroy(&asm_files)); for_array(j, gen->foreign_libraries) { @@ -371,7 +371,7 @@ gb_internal i32 linker_stage(lbGenerator *gen) { defer (gb_string_free(lib_str)); StringSet libs = {}; - string_set_init(&libs, heap_allocator(), 64); + string_set_init(&libs, 64); defer (string_set_destroy(&libs)); for_array(j, gen->foreign_libraries) { @@ -2518,7 +2518,7 @@ int main(int arg_count, char const **arg_ptr) { map_init(&build_context.defined_values, heap_allocator()); build_context.extra_packages.allocator = heap_allocator(); - string_set_init(&build_context.test_names, heap_allocator()); + string_set_init(&build_context.test_names); Array args = setup_args(arg_count, arg_ptr); diff --git a/src/parser.cpp b/src/parser.cpp index 4d2a8ecf4..046469c16 100644 --- a/src/parser.cpp +++ b/src/parser.cpp @@ -4854,7 +4854,7 @@ gb_internal void destroy_ast_file(AstFile *f) { gb_internal bool init_parser(Parser *p) { GB_ASSERT(p != nullptr); - string_set_init(&p->imported_files, heap_allocator()); + string_set_init(&p->imported_files); array_init(&p->packages, heap_allocator()); return true; } diff --git a/src/ptr_set.cpp b/src/ptr_set.cpp index 9ecf1043e..affde5c2f 100644 --- a/src/ptr_set.cpp +++ b/src/ptr_set.cpp @@ -6,11 +6,11 @@ struct PtrSetEntry { template struct PtrSet { - Slice hashes; + Slice hashes; Array> entries; }; -template gb_internal void ptr_set_init (PtrSet *s, gbAllocator a, isize capacity = 16); +template gb_internal void ptr_set_init (PtrSet *s, isize capacity = 16); template gb_internal void ptr_set_destroy(PtrSet *s); template gb_internal T ptr_set_add (PtrSet *s, T ptr); template gb_internal bool ptr_set_update (PtrSet *s, T ptr); // returns true if it previously existed @@ -21,15 +21,18 @@ template gb_internal void ptr_set_grow (PtrSet *s); template gb_internal void ptr_set_rehash (PtrSet *s, isize new_count); template gb_internal void ptr_set_reserve(PtrSet *h, isize cap); +gb_internal gbAllocator ptr_set_allocator(void) { + return heap_allocator(); +} template -gb_internal void ptr_set_init(PtrSet *s, gbAllocator a, isize capacity) { +gb_internal void ptr_set_init(PtrSet *s, isize capacity) { if (capacity != 0) { capacity = next_pow2_isize(gb_max(16, capacity)); } - slice_init(&s->hashes, a, capacity); - array_init(&s->entries, a, 0, capacity); + slice_init(&s->hashes, ptr_set_allocator(), capacity); + array_init(&s->entries, ptr_set_allocator(), 0, capacity); for (isize i = 0; i < capacity; i++) { s->hashes.data[i] = MAP_SENTINEL; } @@ -37,6 +40,9 @@ gb_internal void ptr_set_init(PtrSet *s, gbAllocator a, isize capacity) { template gb_internal void ptr_set_destroy(PtrSet *s) { + if (s->entries.allocator.proc == nullptr) { + s->entries.allocator = ptr_set_allocator(); + } slice_free(&s->hashes, s->entries.allocator); array_free(&s->entries); } @@ -118,6 +124,9 @@ gb_internal void ptr_set_reset_entries(PtrSet *s) { template gb_internal void ptr_set_reserve(PtrSet *s, isize cap) { + if (s->entries.allocator.proc == nullptr) { + s->entries.allocator = ptr_set_allocator(); + } array_reserve(&s->entries, cap); if (s->entries.count*2 < s->hashes.count) { return; @@ -139,7 +148,7 @@ gb_internal gb_inline bool ptr_set_exists(PtrSet *s, T ptr) { } template -gb_internal gb_inline isize ptr_entry_index(PtrSet *s, T ptr) { +gb_internal gb_inline isize ptr_set_entry_index(PtrSet *s, T ptr) { isize index = ptr_set__find(s, ptr).entry_index; if (index != MAP_SENTINEL) { return index; diff --git a/src/string_set.cpp b/src/string_set.cpp index 1c97d253e..753afa9bf 100644 --- a/src/string_set.cpp +++ b/src/string_set.cpp @@ -10,7 +10,7 @@ struct StringSet { }; -gb_internal void string_set_init (StringSet *s, gbAllocator a, isize capacity = 16); +gb_internal void string_set_init (StringSet *s, isize capacity = 16); gb_internal void string_set_destroy(StringSet *s); gb_internal void string_set_add (StringSet *s, String const &str); gb_internal bool string_set_update (StringSet *s, String const &str); // returns true if it previously existed @@ -20,18 +20,24 @@ gb_internal void string_set_clear (StringSet *s); gb_internal void string_set_grow (StringSet *s); gb_internal void string_set_rehash (StringSet *s, isize new_count); +gb_internal gbAllocator string_set_allocator(void) { + return heap_allocator(); +} -gb_internal gb_inline void string_set_init(StringSet *s, gbAllocator a, isize capacity) { +gb_internal gb_inline void string_set_init(StringSet *s, isize capacity) { capacity = next_pow2_isize(gb_max(16, capacity)); - slice_init(&s->hashes, a, capacity); - array_init(&s->entries, a, 0, capacity); + slice_init(&s->hashes, string_set_allocator(), capacity); + array_init(&s->entries, string_set_allocator(), 0, capacity); for (isize i = 0; i < capacity; i++) { s->hashes.data[i] = MAP_SENTINEL; } } gb_internal gb_inline void string_set_destroy(StringSet *s) { + if (s->entries.allocator.proc == nullptr) { + s->entries.allocator = string_set_allocator(); + } slice_free(&s->hashes, s->entries.allocator); array_free(&s->entries); } @@ -106,6 +112,9 @@ gb_internal void string_set_reset_entries(StringSet *s) { } gb_internal void string_set_reserve(StringSet *s, isize cap) { + if (s->entries.allocator.proc == nullptr) { + s->entries.allocator = string_set_allocator(); + } array_reserve(&s->entries, cap); if (s->entries.count*2 < s->hashes.count) { return; @@ -217,7 +226,6 @@ gb_internal gb_inline void string_set_clear(StringSet *s) { } - gb_internal StringSetEntry *begin(StringSet &m) { return m.entries.data; } -- cgit v1.2.3 From 252be0fb417f9cdde5e9c4b348cd995a20433aea Mon Sep 17 00:00:00 2001 From: gingerBill Date: Tue, 3 Jan 2023 11:59:52 +0000 Subject: Make all maps use heap allocator implicitly --- src/check_builtin.cpp | 2 +- src/check_expr.cpp | 3 +-- src/check_stmt.cpp | 1 - src/checker.cpp | 33 +++++++++++++++------------------ src/common.cpp | 2 +- src/docs_writer.cpp | 11 +++++------ src/llvm_backend_general.cpp | 44 ++++++++++++++++++++++---------------------- src/llvm_backend_proc.cpp | 10 +++++----- src/main.cpp | 2 +- src/ptr_map.cpp | 18 ++++++++++++++---- src/string_map.cpp | 18 ++++++++++++++---- 11 files changed, 79 insertions(+), 65 deletions(-) (limited to 'src/checker.cpp') diff --git a/src/check_builtin.cpp b/src/check_builtin.cpp index 36dc9b7a1..af196234e 100644 --- a/src/check_builtin.cpp +++ b/src/check_builtin.cpp @@ -1110,7 +1110,7 @@ gb_internal bool cache_load_file_directive(CheckerContext *c, Ast *call, String new_cache->path = path; new_cache->data = data; new_cache->file_error = file_error; - string_map_init(&new_cache->hashes, heap_allocator(), 32); + string_map_init(&new_cache->hashes, 32); string_map_set(&c->info->load_file_cache, path, new_cache); if (cache_) *cache_ = new_cache; } else { diff --git a/src/check_expr.cpp b/src/check_expr.cpp index 7a00b5353..030bfb8e6 100644 --- a/src/check_expr.cpp +++ b/src/check_expr.cpp @@ -5753,7 +5753,7 @@ gb_internal CallArgumentData check_call_arguments(CheckerContext *c, Operand *op // in order to improve the type inference system StringMap type_hint_map = {}; // Key: String - string_map_init(&type_hint_map, heap_allocator(), 2*args.count); + string_map_init(&type_hint_map, 2*args.count); defer (string_map_destroy(&type_hint_map)); Type *ptype = nullptr; @@ -8283,7 +8283,6 @@ gb_internal ExprKind check_compound_literal(CheckerContext *c, Operand *o, Ast * bool is_partial = cl->tag && (cl->tag->BasicDirective.name.string == "partial"); SeenMap seen = {}; // NOTE(bill): Multimap, Key: ExactValue - map_init(&seen, heap_allocator()); defer (map_destroy(&seen)); if (cl->elems.count > 0 && cl->elems[0]->kind == Ast_FieldValue) { diff --git a/src/check_stmt.cpp b/src/check_stmt.cpp index 945ba8f02..7192b16b5 100644 --- a/src/check_stmt.cpp +++ b/src/check_stmt.cpp @@ -929,7 +929,6 @@ gb_internal void check_switch_stmt(CheckerContext *ctx, Ast *node, u32 mod_flags } SeenMap seen = {}; // NOTE(bill): Multimap, Key: ExactValue - map_init(&seen, heap_allocator()); defer (map_destroy(&seen)); for_array(stmt_index, bs->stmts) { diff --git a/src/checker.cpp b/src/checker.cpp index 8da659461..8779d9d45 100644 --- a/src/checker.cpp +++ b/src/checker.cpp @@ -221,7 +221,7 @@ gb_internal DeclInfo *make_decl_info(Scope *scope, DeclInfo *parent) { gb_internal Scope *create_scope(CheckerInfo *info, Scope *parent, isize init_elements_capacity=DEFAULT_SCOPE_CAPACITY) { Scope *s = gb_alloc_item(permanent_allocator(), Scope); s->parent = parent; - string_map_init(&s->elements, heap_allocator(), init_elements_capacity); + string_map_init(&s->elements, init_elements_capacity); ptr_set_init(&s->imported, 0); if (parent != nullptr && parent != builtin_pkg->scope) { @@ -1135,14 +1135,14 @@ gb_internal void init_checker_info(CheckerInfo *i) { array_init(&i->definitions, a); array_init(&i->entities, a); - map_init(&i->global_untyped, a); - string_map_init(&i->foreigns, a); - map_init(&i->gen_procs, a); - map_init(&i->gen_types, a); + map_init(&i->global_untyped); + 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, a); - string_map_init(&i->files, a); - string_map_init(&i->packages, a); + map_init(&i->type_info_map); + string_map_init(&i->files); + string_map_init(&i->packages); array_init(&i->variable_init_order, a); array_init(&i->testing_procedures, a, 0, 0); array_init(&i->init_procedures, a, 0, 0); @@ -1160,8 +1160,8 @@ gb_internal void init_checker_info(CheckerInfo *i) { mpmc_init(&i->intrinsics_entry_point_usage, a, 1<<10); // just waste some memory here, even if it probably never used - map_init(&i->objc_msgSend_types, a); - string_map_init(&i->load_file_cache, a); + map_init(&i->objc_msgSend_types); + string_map_init(&i->load_file_cache); array_init(&i->all_procedures, heap_allocator()); @@ -2490,7 +2490,7 @@ gb_internal bool is_entity_a_dependency(Entity *e) { gb_internal Array generate_entity_dependency_graph(CheckerInfo *info, gbAllocator allocator) { PtrMap M = {}; - map_init(&M, allocator, info->entities.count); + map_init(&M, info->entities.count); defer (map_destroy(&M)); for_array(i, info->entities) { Entity *e = info->entities[i]; @@ -4200,7 +4200,7 @@ gb_internal void add_import_dependency_node(Checker *c, Ast *decl, PtrMap generate_import_dependency_graph(Checker *c) { PtrMap M = {}; - map_init(&M, heap_allocator(), 2*c->parser->packages.count); + map_init(&M, 2*c->parser->packages.count); defer (map_destroy(&M)); for_array(i, c->parser->packages) { @@ -4688,7 +4688,7 @@ gb_internal void check_collect_entities_all(Checker *c) { auto *wd = &collect_entity_worker_data[i]; wd->c = c; wd->ctx = make_checker_context(c); - map_init(&wd->untyped, heap_allocator()); + map_init(&wd->untyped); } for (auto const &entry : c->info.files.entries) { @@ -4804,7 +4804,6 @@ gb_internal void check_import_entities(Checker *c) { CheckerContext ctx = make_checker_context(c); UntypedExprInfoMap untyped = {}; - map_init(&untyped, heap_allocator()); defer (map_destroy(&untyped)); isize min_pkg_index = 0; @@ -5159,7 +5158,6 @@ gb_internal void check_unchecked_bodies(Checker *c) { GB_ASSERT(c->procs_to_check.count == 0); UntypedExprInfoMap untyped = {}; - map_init(&untyped, heap_allocator()); defer (map_destroy(&untyped)); // use the `procs_to_check` array @@ -5212,7 +5210,6 @@ gb_internal void check_unchecked_bodies(Checker *c) { gb_internal void check_safety_all_procedures_for_unchecked(Checker *c) { GB_ASSERT(DEBUG_CHECK_ALL_PROCEDURES); UntypedExprInfoMap untyped = {}; - map_init(&untyped, heap_allocator()); defer (map_destroy(&untyped)); @@ -5345,7 +5342,7 @@ gb_internal void check_procedure_bodies(Checker *c) { for (isize i = 0; i < thread_count; i++) { check_procedure_bodies_worker_data[i].c = c; - map_init(&check_procedure_bodies_worker_data[i].untyped, heap_allocator()); + map_init(&check_procedure_bodies_worker_data[i].untyped); } defer (for (isize i = 0; i < thread_count; i++) { @@ -5545,7 +5542,7 @@ gb_internal void check_deferred_procedures(Checker *c) { gb_internal void check_unique_package_names(Checker *c) { StringMap pkgs = {}; // Key: package name - string_map_init(&pkgs, heap_allocator(), 2*c->info.packages.entries.count); + string_map_init(&pkgs, 2*c->info.packages.entries.count); defer (string_map_destroy(&pkgs)); for (auto const &entry : c->info.packages) { diff --git a/src/common.cpp b/src/common.cpp index 3b6ea59e8..199a263a1 100644 --- a/src/common.cpp +++ b/src/common.cpp @@ -373,7 +373,7 @@ gb_internal char const *string_intern(String const &string) { } gb_internal void init_string_interner(void) { - map_init(&string_intern_map, heap_allocator()); + map_init(&string_intern_map); } diff --git a/src/docs_writer.cpp b/src/docs_writer.cpp index bab97158d..2aefe29eb 100644 --- a/src/docs_writer.cpp +++ b/src/docs_writer.cpp @@ -53,13 +53,12 @@ gb_internal void odin_doc_writer_item_tracker_init(OdinDocWriterItemTracker * gb_internal void odin_doc_writer_prepare(OdinDocWriter *w) { w->state = OdinDocWriterState_Preparing; - gbAllocator a = heap_allocator(); - string_map_init(&w->string_cache, a); + string_map_init(&w->string_cache); - map_init(&w->file_cache, a); - map_init(&w->pkg_cache, a); - map_init(&w->entity_cache, a); - map_init(&w->type_cache, a); + map_init(&w->file_cache); + map_init(&w->pkg_cache); + map_init(&w->entity_cache); + map_init(&w->type_cache); odin_doc_writer_item_tracker_init(&w->files, 1); odin_doc_writer_item_tracker_init(&w->pkgs, 1); diff --git a/src/llvm_backend_general.cpp b/src/llvm_backend_general.cpp index 75675474a..a849929f0 100644 --- a/src/llvm_backend_general.cpp +++ b/src/llvm_backend_general.cpp @@ -55,30 +55,30 @@ gb_internal void lb_init_module(lbModule *m, Checker *c) { } gbAllocator a = heap_allocator(); - map_init(&m->types, a); - map_init(&m->func_raw_types, a); - map_init(&m->struct_field_remapping, a); - map_init(&m->values, a); - map_init(&m->soa_values, a); - string_map_init(&m->members, a); - map_init(&m->procedure_values, a); - string_map_init(&m->procedures, a); - string_map_init(&m->const_strings, a); - map_init(&m->function_type_map, a); - map_init(&m->equal_procs, a); - map_init(&m->hasher_procs, a); - map_init(&m->map_get_procs, a); - map_init(&m->map_set_procs, a); + map_init(&m->types); + map_init(&m->func_raw_types); + map_init(&m->struct_field_remapping); + map_init(&m->values); + map_init(&m->soa_values); + string_map_init(&m->members); + map_init(&m->procedure_values); + 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); array_init(&m->procedures_to_generate, a, 0, 1024); array_init(&m->missing_procedures_to_check, a, 0, 16); - map_init(&m->debug_values, a); + map_init(&m->debug_values); array_init(&m->debug_incomplete_types, a, 0, 1024); - string_map_init(&m->objc_classes, a); - string_map_init(&m->objc_selectors, a); + string_map_init(&m->objc_classes); + string_map_init(&m->objc_selectors); - map_init(&m->map_info_map, a, 0); - map_init(&m->map_cell_info_map, a, 0); + map_init(&m->map_info_map, 0); + map_init(&m->map_cell_info_map, 0); } @@ -127,9 +127,9 @@ gb_internal bool lb_init_generator(lbGenerator *gen, Checker *c) { gen->info = &c->info; - map_init(&gen->modules, permanent_allocator(), gen->info->packages.entries.count*2); - map_init(&gen->modules_through_ctx, permanent_allocator(), gen->info->packages.entries.count*2); - map_init(&gen->anonymous_proc_lits, heap_allocator(), 1024); + map_init(&gen->modules, gen->info->packages.entries.count*2); + map_init(&gen->modules_through_ctx, gen->info->packages.entries.count*2); + map_init(&gen->anonymous_proc_lits, 1024); array_init(&gen->foreign_libraries, heap_allocator(), 0, 1024); diff --git a/src/llvm_backend_proc.cpp b/src/llvm_backend_proc.cpp index 7245bdd80..c66462bc1 100644 --- a/src/llvm_backend_proc.cpp +++ b/src/llvm_backend_proc.cpp @@ -119,9 +119,9 @@ gb_internal lbProcedure *lb_create_procedure(lbModule *m, Entity *entity, bool i p->branch_blocks.allocator = a; p->context_stack.allocator = a; p->scope_stack.allocator = a; - map_init(&p->selector_values, a, 0); - map_init(&p->selector_addr, a, 0); - map_init(&p->tuple_fix_map, a, 0); + map_init(&p->selector_values, 0); + map_init(&p->selector_addr, 0); + map_init(&p->tuple_fix_map, 0); if (p->is_foreign) { lb_add_foreign_library_path(p->module, entity->Procedure.foreign_library); @@ -345,7 +345,7 @@ gb_internal lbProcedure *lb_create_dummy_procedure(lbModule *m, String link_name p->blocks.allocator = a; p->branch_blocks.allocator = a; p->context_stack.allocator = a; - map_init(&p->tuple_fix_map, a, 0); + map_init(&p->tuple_fix_map, 0); char *c_link_name = alloc_cstring(permanent_allocator(), p->name); @@ -486,7 +486,7 @@ gb_internal void lb_begin_procedure_body(lbProcedure *p) { p->entry_block = lb_create_block(p, "entry", true); lb_start_block(p, p->entry_block); - map_init(&p->direct_parameters, heap_allocator()); + map_init(&p->direct_parameters); GB_ASSERT(p->type != nullptr); diff --git a/src/main.cpp b/src/main.cpp index 91dcbdb01..7ac78241e 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -2516,7 +2516,7 @@ int main(int arg_count, char const **arg_ptr) { add_library_collection(str_lit("core"), get_fullpath_relative(heap_allocator(), odin_root_dir(), str_lit("core"))); add_library_collection(str_lit("vendor"), get_fullpath_relative(heap_allocator(), odin_root_dir(), str_lit("vendor"))); - map_init(&build_context.defined_values, heap_allocator()); + map_init(&build_context.defined_values); build_context.extra_packages.allocator = heap_allocator(); string_set_init(&build_context.test_names); diff --git a/src/ptr_map.cpp b/src/ptr_map.cpp index 434680e91..083cd6697 100644 --- a/src/ptr_map.cpp +++ b/src/ptr_map.cpp @@ -46,7 +46,7 @@ gb_internal gb_inline u32 ptr_map_hash_key(void const *key) { } -template gb_internal void map_init (PtrMap *h, gbAllocator a, isize capacity = 16); +template gb_internal void map_init (PtrMap *h, isize capacity = 16); template gb_internal void map_destroy (PtrMap *h); template gb_internal V * map_get (PtrMap *h, K key); template gb_internal void map_set (PtrMap *h, K key, V const &value); @@ -68,11 +68,15 @@ template gb_internal void multi_map_remove (PtrMap< template gb_internal void multi_map_remove_all(PtrMap *h, K key); #endif +gb_internal gbAllocator map_allocator(void) { + return heap_allocator(); +} + template -gb_internal gb_inline void map_init(PtrMap *h, gbAllocator a, isize capacity) { +gb_internal gb_inline void map_init(PtrMap *h, isize capacity) { capacity = next_pow2_isize(capacity); - slice_init(&h->hashes, a, capacity); - array_init(&h->entries, a, 0, capacity); + slice_init(&h->hashes, map_allocator(), capacity); + array_init(&h->entries, map_allocator(), 0, capacity); for (isize i = 0; i < capacity; i++) { h->hashes.data[i] = MAP_SENTINEL; } @@ -80,6 +84,9 @@ gb_internal gb_inline void map_init(PtrMap *h, gbAllocator a, isize capaci template gb_internal gb_inline void map_destroy(PtrMap *h) { + if (h->entries.allocator.proc == nullptr) { + h->entries.allocator = map_allocator(); + } slice_free(&h->hashes, h->entries.allocator); array_free(&h->entries); } @@ -162,6 +169,9 @@ gb_internal void map_reset_entries(PtrMap *h) { template gb_internal void map_reserve(PtrMap *h, isize cap) { + if (h->entries.allocator.proc == nullptr) { + h->entries.allocator = map_allocator(); + } array_reserve(&h->entries, cap); if (h->entries.count*2 < h->hashes.count) { return; diff --git a/src/string_map.cpp b/src/string_map.cpp index 9f9374ece..b5db63e90 100644 --- a/src/string_map.cpp +++ b/src/string_map.cpp @@ -35,7 +35,7 @@ struct StringMap { }; -template gb_internal void string_map_init (StringMap *h, gbAllocator a, isize capacity = 16); +template gb_internal void string_map_init (StringMap *h, isize capacity = 16); template gb_internal void string_map_destroy (StringMap *h); template gb_internal T * string_map_get (StringMap *h, char const *key); @@ -56,11 +56,15 @@ template gb_internal void string_map_grow (StringMap template gb_internal void string_map_rehash (StringMap *h, isize new_count); template gb_internal void string_map_reserve (StringMap *h, isize cap); +gb_internal gbAllocator string_map_allocator(void) { + return heap_allocator(); +} + template -gb_internal gb_inline void string_map_init(StringMap *h, gbAllocator a, isize capacity) { +gb_internal gb_inline void string_map_init(StringMap *h, isize capacity) { capacity = next_pow2_isize(capacity); - slice_init(&h->hashes, a, capacity); - array_init(&h->entries, a, 0, capacity); + slice_init(&h->hashes, string_map_allocator(), capacity); + array_init(&h->entries, string_map_allocator(), 0, capacity); for (isize i = 0; i < capacity; i++) { h->hashes.data[i] = MAP_SENTINEL; } @@ -68,6 +72,9 @@ gb_internal gb_inline void string_map_init(StringMap *h, gbAllocator a, isize template gb_internal gb_inline void string_map_destroy(StringMap *h) { + if (h->entries.allocator.proc == nullptr) { + h->entries.allocator = string_map_allocator(); + } slice_free(&h->hashes, h->entries.allocator); array_free(&h->entries); } @@ -147,6 +154,9 @@ gb_internal void string_map_reset_entries(StringMap *h) { template gb_internal void string_map_reserve(StringMap *h, isize cap) { + if (h->entries.allocator.proc == nullptr) { + h->entries.allocator = string_map_allocator(); + } array_reserve(&h->entries, cap); if (h->entries.count*2 < h->hashes.count) { return; -- cgit v1.2.3 From 747a11a954824da7960a247299986f56d1316773 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Tue, 3 Jan 2023 12:18:35 +0000 Subject: Allow all set entry types to be implicitly cast to their key/value type to allow for easier iteration --- src/build_settings.cpp | 6 ++---- src/check_decl.cpp | 6 ++---- src/check_expr.cpp | 7 +++---- src/checker.cpp | 38 +++++++++++++------------------------- src/ptr_set.cpp | 12 ++++++++---- src/string_map.cpp | 13 ++++++++++--- src/string_set.cpp | 15 +++++++++++---- src/types.cpp | 3 +-- 8 files changed, 50 insertions(+), 50 deletions(-) (limited to 'src/checker.cpp') diff --git a/src/build_settings.cpp b/src/build_settings.cpp index 75615a901..1dff5f43e 100644 --- a/src/build_settings.cpp +++ b/src/build_settings.cpp @@ -1332,11 +1332,10 @@ gb_internal void enable_target_feature(TokenPos pos, String const &target_featur gb_internal char const *target_features_set_to_cstring(gbAllocator allocator, bool with_quotes) { isize len = 0; isize i = 0; - for (auto const &entry : build_context.target_features_set) { + for (String const &feature : build_context.target_features_set) { if (i != 0) { len += 1; } - String feature = entry.value; len += feature.len; if (with_quotes) len += 2; i += 1; @@ -1344,13 +1343,12 @@ gb_internal char const *target_features_set_to_cstring(gbAllocator allocator, bo char *features = gb_alloc_array(allocator, char, len+1); len = 0; i = 0; - for (auto const &entry : build_context.target_features_set) { + for (String const &feature : build_context.target_features_set) { if (i != 0) { features[len++] = ','; } if (with_quotes) features[len++] = '"'; - String feature = entry.value; gb_memmove(features + len, feature.text, feature.len); len += feature.len; if (with_quotes) features[len++] = '"'; diff --git a/src/check_decl.cpp b/src/check_decl.cpp index 0c1a7c325..7b229db08 100644 --- a/src/check_decl.cpp +++ b/src/check_decl.cpp @@ -1587,16 +1587,14 @@ gb_internal bool check_proc_body(CheckerContext *ctx_, Token token, DeclInfo *de MUTEX_GUARD_BLOCK(decl->deps_mutex) MUTEX_GUARD_BLOCK(decl->parent->deps_mutex) { - for (auto const &entry : decl->deps) { - Entity *e = entry.ptr; + for (Entity *e : decl->deps) { ptr_set_add(&decl->parent->deps, e); } } MUTEX_GUARD_BLOCK(decl->type_info_deps_mutex) MUTEX_GUARD_BLOCK(decl->parent->type_info_deps_mutex) { - for (auto const &entry : decl->type_info_deps) { - Type *t = entry.ptr; + for (Type *t : decl->type_info_deps) { ptr_set_add(&decl->parent->type_info_deps, t); } } diff --git a/src/check_expr.cpp b/src/check_expr.cpp index 030bfb8e6..2924f9d13 100644 --- a/src/check_expr.cpp +++ b/src/check_expr.cpp @@ -202,8 +202,8 @@ gb_internal void check_did_you_mean_objc_entity(String const &name, Entity *e, b DidYouMeanAnswers d = did_you_mean_make(heap_allocator(), set.entries.count, name); defer (did_you_mean_destroy(&d)); - for (auto const &entry : set) { - did_you_mean_append(&d, entry.value); + for (String const &target : set) { + did_you_mean_append(&d, target); } check_did_you_mean_print(&d, prefix); } @@ -4942,8 +4942,7 @@ gb_internal isize add_dependencies_from_unpacking(CheckerContext *c, Entity **lh if (e != nullptr) { DeclInfo *decl = decl_info_of_entity(e); if (decl != nullptr) { - for (auto const &entry : decl->deps) { - Entity *dep = entry.ptr; + for (Entity *dep : decl->deps) { ptr_set_add(&c->decl->deps, dep); } } diff --git a/src/checker.cpp b/src/checker.cpp index 8779d9d45..0075fa543 100644 --- a/src/checker.cpp +++ b/src/checker.cpp @@ -2222,12 +2222,11 @@ gb_internal void add_dependency_to_set(Checker *c, Entity *entity) { return; } - for (auto const &entry : decl->type_info_deps) { - add_min_dep_type_info(c, entry.ptr); + for (Type *t : decl->type_info_deps) { + add_min_dep_type_info(c, t); } - for (auto const &entry : decl->deps) { - Entity *e = entry.ptr; + for (Entity *e : decl->deps) { add_dependency_to_set(c, e); if (e->kind == Entity_Procedure && e->Procedure.is_foreign) { Entity *fl = e->Procedure.foreign_library; @@ -2510,8 +2509,7 @@ gb_internal Array generate_entity_dependency_graph(CheckerInf DeclInfo *decl = decl_info_of_entity(e); GB_ASSERT(decl != nullptr); - for (auto const &entry : decl->deps) { - Entity *dep = entry.ptr; + for (Entity *dep : decl->deps) { if (dep->flags & EntityFlag_Field) { continue; } @@ -2537,15 +2535,12 @@ gb_internal Array generate_entity_dependency_graph(CheckerInf if (e->kind == Entity_Procedure) { // Connect each pred 'p' of 'n' with each succ 's' and from // the procedure node - for (auto const &p_entry : n->pred) { - EntityGraphNode *p = p_entry.ptr; - + for (EntityGraphNode *p : n->pred) { // Ignore self-cycles if (p != n) { // Each succ 's' of 'n' becomes a succ of 'p', and // each pred 'p' of 'n' becomes a pred of 's' - for (auto const &s_entry : n->succ) { - EntityGraphNode *s = s_entry.ptr; + for (EntityGraphNode *s : n->succ) { // Ignore self-cycles if (s != n) { if (p->entity->kind == Entity_Procedure && @@ -4784,8 +4779,7 @@ gb_internal void check_import_entities(Checker *c) { } } - for (auto const &entry : n->pred) { - ImportGraphNode *p = entry.ptr; + for (ImportGraphNode *p : n->pred) { p->dep_count = gb_max(p->dep_count-1, 0); priority_queue_fix(&pq, p->index); } @@ -4893,8 +4887,7 @@ gb_internal bool find_entity_path_tuple(Type *tuple, Entity *end, PtrSetdeps) { - Entity *dep = entry.ptr; + for (Entity *dep : var_decl->deps) { if (dep == end) { auto path = array_make(heap_allocator()); array_add(&path, dep); @@ -4944,8 +4937,7 @@ gb_internal Array find_entity_path(Entity *start, Entity *end, PtrSet< return path; } } else { - for (auto const &entry : decl->deps) { - Entity *dep = entry.ptr; + for (Entity *dep : decl->deps) { if (dep == end) { auto path = array_make(heap_allocator()); array_add(&path, dep); @@ -5002,8 +4994,7 @@ gb_internal void calculate_global_init_order(Checker *c) { } } - for (auto const &entry : n->pred) { - EntityGraphNode *p = entry.ptr; + for (EntityGraphNode *p : n->pred) { p->dep_count -= 1; p->dep_count = gb_max(p->dep_count, 0); priority_queue_fix(&pq, p->index); @@ -5163,8 +5154,7 @@ gb_internal void check_unchecked_bodies(Checker *c) { // use the `procs_to_check` array global_procedure_body_in_worker_queue = false; - for (auto const &entry : c->info.minimum_dependency_set) { - Entity *e = entry.ptr; + for (Entity *e : c->info.minimum_dependency_set) { if (e == nullptr || e->kind != Entity_Procedure) { continue; } @@ -5239,8 +5229,7 @@ gb_internal void check_test_procedures(Checker *c) { AstPackage *pkg = c->info.init_package; Scope *s = pkg->scope; - for (auto const &entry : build_context.test_names) { - String name = entry.value; + for (String const &name : build_context.test_names) { Entity *e = scope_lookup(s, name); if (e == nullptr) { Token tok = {}; @@ -5744,8 +5733,7 @@ gb_internal void check_parsed_files(Checker *c) { DeclInfo *decl = e->decl_info; ast_node(pl, ProcLit, decl->proc_lit); if (pl->inlining == ProcInlining_inline) { - for (auto const &entry : decl->deps) { - Entity *dep = entry.ptr; + for (Entity *dep : decl->deps) { if (dep == e) { error(e->token, "Cannot inline recursive procedure '%.*s'", LIT(e->token.string)); break; diff --git a/src/ptr_set.cpp b/src/ptr_set.cpp index affde5c2f..303bde07e 100644 --- a/src/ptr_set.cpp +++ b/src/ptr_set.cpp @@ -2,6 +2,10 @@ template struct PtrSetEntry { T ptr; MapIndex next; + + operator T() const noexcept { + return this->ptr; + } }; template @@ -245,21 +249,21 @@ gb_internal gb_inline void ptr_set_clear(PtrSet *s) { template -gb_internal PtrSetEntry *begin(PtrSet &m) { +gb_internal PtrSetEntry *begin(PtrSet &m) noexcept { return m.entries.data; } template -gb_internal PtrSetEntry const *begin(PtrSet const &m) { +gb_internal PtrSetEntry const *begin(PtrSet const &m) noexcept { return m.entries.data; } template -gb_internal PtrSetEntry *end(PtrSet &m) { +gb_internal PtrSetEntry *end(PtrSet &m) noexcept { return m.entries.data + m.entries.count; } template -gb_internal PtrSetEntry const *end(PtrSet const &m) { +gb_internal PtrSetEntry const *end(PtrSet const &m) noexcept { return m.entries.data + m.entries.count; } \ No newline at end of file diff --git a/src/string_map.cpp b/src/string_map.cpp index b5db63e90..74a16de73 100644 --- a/src/string_map.cpp +++ b/src/string_map.cpp @@ -1,6 +1,13 @@ struct StringHashKey { u32 hash; String string; + + operator String() const noexcept { + return this->string; + } + operator String const &() const noexcept { + return this->string; + } }; gb_internal gb_inline StringHashKey string_hash_string(String const &s) { @@ -283,11 +290,11 @@ gb_internal gb_inline void string_map_clear(StringMap *h) { template -gb_internal StringMapEntry *begin(StringMap &m) { +gb_internal StringMapEntry *begin(StringMap &m) noexcept { return m.entries.data; } template -gb_internal StringMapEntry const *begin(StringMap const &m) { +gb_internal StringMapEntry const *begin(StringMap const &m) noexcept { return m.entries.data; } @@ -298,6 +305,6 @@ gb_internal StringMapEntry *end(StringMap &m) { } template -gb_internal StringMapEntry const *end(StringMap const &m) { +gb_internal StringMapEntry const *end(StringMap const &m) noexcept { return m.entries.data + m.entries.count; } \ No newline at end of file diff --git a/src/string_set.cpp b/src/string_set.cpp index 753afa9bf..fb4640c20 100644 --- a/src/string_set.cpp +++ b/src/string_set.cpp @@ -2,6 +2,13 @@ struct StringSetEntry { u32 hash; MapIndex next; String value; + + operator String const() const noexcept { + return this->value; + } + operator String const &() const noexcept { + return this->value; + } }; struct StringSet { @@ -226,18 +233,18 @@ gb_internal gb_inline void string_set_clear(StringSet *s) { } -gb_internal StringSetEntry *begin(StringSet &m) { +gb_internal StringSetEntry *begin(StringSet &m) noexcept { return m.entries.data; } -gb_internal StringSetEntry const *begin(StringSet const &m) { +gb_internal StringSetEntry const *begin(StringSet const &m) noexcept { return m.entries.data; } -gb_internal StringSetEntry *end(StringSet &m) { +gb_internal StringSetEntry *end(StringSet &m) noexcept { return m.entries.data + m.entries.count; } -gb_internal StringSetEntry const *end(StringSet const &m) { +gb_internal StringSetEntry const *end(StringSet const &m) noexcept { return m.entries.data + m.entries.count; } \ No newline at end of file diff --git a/src/types.cpp b/src/types.cpp index 1e2d85ac6..d33c36e94 100644 --- a/src/types.cpp +++ b/src/types.cpp @@ -823,8 +823,7 @@ gb_internal bool type_ptr_set_exists(PtrSet *s, Type *t) { // TODO(bill, 2019-10-05): This is very slow and it's probably a lot // faster to cache types correctly - for (auto const &entry : *s) { - Type *f = entry.ptr; + for (Type *f : *s) { if (are_types_identical(t, f)) { ptr_set_add(s, t); return true; -- cgit v1.2.3 From c7a704d345e9bda38da18807a1d7cd5bc5accc17 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Tue, 3 Jan 2023 15:26:47 +0000 Subject: Use `RwMutex` for the `Scope` --- src/check_decl.cpp | 12 ++++--- src/check_expr.cpp | 4 ++- src/check_stmt.cpp | 5 ++- src/checker.cpp | 21 +++++++----- src/checker.hpp | 2 +- src/thread_pool.cpp | 27 ++++++++------- src/threading.cpp | 96 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 7 files changed, 138 insertions(+), 29 deletions(-) (limited to 'src/checker.cpp') diff --git a/src/check_decl.cpp b/src/check_decl.cpp index 66f16546c..4afde6e51 100644 --- a/src/check_decl.cpp +++ b/src/check_decl.cpp @@ -381,8 +381,8 @@ gb_internal void override_entity_in_scope(Entity *original_entity, Entity *new_e if (found_scope == nullptr) { return; } - mutex_lock(&found_scope->mutex); - defer (mutex_unlock(&found_scope->mutex)); + rw_mutex_lock(&found_scope->mutex); + defer (rw_mutex_unlock(&found_scope->mutex)); // IMPORTANT NOTE(bill, 2021-04-10): Overriding behaviour was flawed in that the // original entity was still used check checked, but the checking was only @@ -1478,7 +1478,8 @@ gb_internal bool check_proc_body(CheckerContext *ctx_, Token token, DeclInfo *de if (t->kind == Type_Struct) { Scope *scope = t->Struct.scope; GB_ASSERT(scope != nullptr); - MUTEX_GUARD_BLOCK(scope->mutex) for (auto const &entry : scope->elements) { + rw_mutex_lock(&scope->mutex); + for (auto const &entry : scope->elements) { Entity *f = entry.value; if (f->kind == Entity_Variable) { Entity *uvar = alloc_entity_using_variable(e, f->token, f->type, nullptr); @@ -1488,6 +1489,7 @@ gb_internal bool check_proc_body(CheckerContext *ctx_, Token token, DeclInfo *de array_add(&using_entities, puv); } } + rw_mutex_unlock(&scope->mutex); } else { error(e->token, "'using' can only be applied to variables of type struct"); break; @@ -1496,7 +1498,8 @@ gb_internal bool check_proc_body(CheckerContext *ctx_, Token token, DeclInfo *de } } - MUTEX_GUARD_BLOCK(ctx->scope->mutex) for (auto const &entry : using_entities) { + rw_mutex_lock(&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); @@ -1506,6 +1509,7 @@ gb_internal bool check_proc_body(CheckerContext *ctx_, Token token, DeclInfo *de break; } } + rw_mutex_unlock(&ctx->scope->mutex); bool where_clause_ok = evaluate_where_clauses(ctx, nullptr, decl->scope, &decl->proc_lit->ProcLit.where_clauses, !decl->where_clauses_evaluated); diff --git a/src/check_expr.cpp b/src/check_expr.cpp index c1787e7b6..d9ab328cb 100644 --- a/src/check_expr.cpp +++ b/src/check_expr.cpp @@ -236,10 +236,12 @@ gb_internal void check_did_you_mean_scope(String const &name, Scope *scope, char DidYouMeanAnswers d = did_you_mean_make(heap_allocator(), scope->elements.entries.count, name); defer (did_you_mean_destroy(&d)); - MUTEX_GUARD_BLOCK(&scope->mutex) for (auto const &entry : scope->elements) { + rw_mutex_shared_lock(&scope->mutex); + for (auto const &entry : scope->elements) { Entity *e = entry.value; did_you_mean_append(&d, e->token.string); } + rw_mutex_shared_unlock(&scope->mutex); check_did_you_mean_print(&d, prefix); } diff --git a/src/check_stmt.cpp b/src/check_stmt.cpp index e075297a4..6e84d0789 100644 --- a/src/check_stmt.cpp +++ b/src/check_stmt.cpp @@ -622,7 +622,10 @@ gb_internal bool check_using_stmt_entity(CheckerContext *ctx, AstUsingStmt *us, case Entity_ImportName: { Scope *scope = e->ImportName.scope; - MUTEX_GUARD_BLOCK(scope->mutex) for (auto const &entry : scope->elements) { + rw_mutex_lock(&scope->mutex); + defer (rw_mutex_unlock(&scope->mutex)); + + for (auto const &entry : scope->elements) { String name = entry.key.string; Entity *decl = entry.value; if (!is_entity_exported(decl)) continue; diff --git a/src/checker.cpp b/src/checker.cpp index 0075fa543..1d536074d 100644 --- a/src/checker.cpp +++ b/src/checker.cpp @@ -51,10 +51,11 @@ gb_internal bool check_rtti_type_disallowed(Ast *expr, Type *type, char const *f gb_internal void scope_reset(Scope *scope) { if (scope == nullptr) return; - MUTEX_GUARD(&scope->mutex); + rw_mutex_lock(&scope->mutex); scope->head_child.store(nullptr, std::memory_order_relaxed); string_map_clear(&scope->elements); ptr_set_clear(&scope->imported); + rw_mutex_unlock(&scope->mutex); } gb_internal void scope_reserve(Scope *scope, isize capacity) { @@ -180,9 +181,9 @@ gb_internal void init_decl_info(DeclInfo *d, Scope *scope, DeclInfo *parent) { gb_zero_item(d); d->parent = parent; d->scope = scope; - ptr_set_init(&d->deps); - ptr_set_init(&d->type_info_deps); - array_init (&d->labels, heap_allocator()); + ptr_set_init(&d->deps, 0); + ptr_set_init(&d->type_info_deps, 0); + d->labels.allocator = heap_allocator(); } gb_internal DeclInfo *make_decl_info(Scope *scope, DeclInfo *parent) { @@ -394,9 +395,9 @@ gb_internal void scope_lookup_parent(Scope *scope, String const &name, Scope **s StringHashKey key = string_hash_string(name); for (Scope *s = scope; s != nullptr; s = s->parent) { Entity **found = nullptr; - mutex_lock(&s->mutex); + rw_mutex_shared_lock(&s->mutex); found = string_map_get(&s->elements, key); - mutex_unlock(&s->mutex); + rw_mutex_shared_unlock(&s->mutex); if (found) { Entity *e = *found; if (gone_thru_proc) { @@ -482,7 +483,7 @@ gb_internal Entity *scope_insert_with_name(Scope *s, String const &name, Entity Entity **found = nullptr; Entity *result = nullptr; - MUTEX_GUARD(&s->mutex); + rw_mutex_lock(&s->mutex); found = string_map_get(&s->elements, key); @@ -509,6 +510,8 @@ gb_internal Entity *scope_insert_with_name(Scope *s, String const &name, Entity entity->scope = s; } end:; + rw_mutex_unlock(&s->mutex); + return result; } @@ -669,7 +672,8 @@ gb_internal void check_scope_usage(Checker *c, Scope *scope) { Array vetted_entities = {}; array_init(&vetted_entities, heap_allocator()); - MUTEX_GUARD_BLOCK(scope->mutex) for (auto const &entry : scope->elements) { + rw_mutex_shared_lock(&scope->mutex); + for (auto const &entry : scope->elements) { Entity *e = entry.value; if (e == nullptr) continue; VettedEntity ve_unused = {}; @@ -686,6 +690,7 @@ gb_internal void check_scope_usage(Checker *c, Scope *scope) { array_add(&vetted_entities, ve_shadowed); } } + rw_mutex_shared_unlock(&scope->mutex); gb_sort(vetted_entities.data, vetted_entities.count, gb_size_of(VettedEntity), vetted_entity_variable_pos_cmp); diff --git a/src/checker.hpp b/src/checker.hpp index cc92fce28..53052d5cd 100644 --- a/src/checker.hpp +++ b/src/checker.hpp @@ -224,7 +224,7 @@ struct Scope { std::atomic next; std::atomic head_child; - BlockingMutex mutex; + RwMutex mutex; StringMap elements; PtrSet imported; diff --git a/src/thread_pool.cpp b/src/thread_pool.cpp index 276e93dff..2c369eaad 100644 --- a/src/thread_pool.cpp +++ b/src/thread_pool.cpp @@ -47,7 +47,7 @@ gb_internal void thread_pool_destroy(ThreadPool *pool) { for_array_off(i, 1, pool->threads) { Thread *t = &pool->threads[i]; - pool->tasks_available.fetch_add(1, std::memory_order_release); + pool->tasks_available.fetch_add(1, std::memory_order_relaxed); futex_broadcast(&pool->tasks_available); thread_join_and_destroy(t); } @@ -74,7 +74,7 @@ void thread_pool_queue_push(Thread *thread, WorkerTask task) { } while (!thread->head_and_tail.compare_exchange_weak(capture, new_capture)); thread->pool->tasks_left.fetch_add(1, std::memory_order_release); - thread->pool->tasks_available.fetch_add(1, std::memory_order_release); + thread->pool->tasks_available.fetch_add(1, std::memory_order_relaxed); futex_broadcast(&thread->pool->tasks_available); } @@ -82,7 +82,7 @@ bool thread_pool_queue_pop(Thread *thread, WorkerTask *task) { u64 capture; u64 new_capture; do { - capture = thread->head_and_tail.load(); + capture = thread->head_and_tail.load(std::memory_order_acquire); u64 mask = thread->capacity - 1; u64 head = (capture >> 32) & mask; @@ -97,7 +97,7 @@ bool thread_pool_queue_pop(Thread *thread, WorkerTask *task) { *task = thread->queue[tail]; new_capture = (head << 32) | new_tail; - } while (!thread->head_and_tail.compare_exchange_weak(capture, new_capture)); + } while (!thread->head_and_tail.compare_exchange_weak(capture, new_capture, std::memory_order_release)); return true; } @@ -168,22 +168,21 @@ gb_internal THREAD_PROC(thread_pool_thread_proc) { Thread *thread = &pool->threads.data[idx]; WorkerTask task; - if (!thread_pool_queue_pop(thread, &task)) { - continue; - } - task.do_work(task.data); - pool->tasks_left.fetch_sub(1, std::memory_order_release); + if (thread_pool_queue_pop(thread, &task)) { + task.do_work(task.data); + pool->tasks_left.fetch_sub(1, std::memory_order_release); - if (pool->tasks_left.load(std::memory_order_acquire) == 0) { - futex_signal(&pool->tasks_left); - } + if (pool->tasks_left.load(std::memory_order_acquire) == 0) { + futex_signal(&pool->tasks_left); + } - goto main_loop_continue; + goto main_loop_continue; + } } } // if we've done all our work, and there's nothing to steal, go to sleep - state = pool->tasks_available.load(); + state = pool->tasks_available.load(std::memory_order_acquire); futex_wait(&pool->tasks_available, state); main_loop_continue:; diff --git a/src/threading.cpp b/src/threading.cpp index 78943150e..27a17112e 100644 --- a/src/threading.cpp +++ b/src/threading.cpp @@ -8,10 +8,12 @@ struct BlockingMutex; struct RecursiveMutex; +struct RwMutex; struct Semaphore; struct Condition; struct Thread; struct ThreadPool; +struct Parker; #define THREAD_PROC(name) isize name(struct Thread *thread) gb_internal THREAD_PROC(thread_pool_thread_proc); @@ -56,6 +58,13 @@ gb_internal void mutex_lock (RecursiveMutex *m); gb_internal bool mutex_try_lock(RecursiveMutex *m); gb_internal void mutex_unlock (RecursiveMutex *m); +gb_internal void rw_mutex_lock (RwMutex *m); +gb_internal bool rw_mutex_try_lock (RwMutex *m); +gb_internal void rw_mutex_unlock (RwMutex *m); +gb_internal void rw_mutex_shared_lock (RwMutex *m); +gb_internal bool rw_mutex_try_shared_lock(RwMutex *m); +gb_internal void rw_mutex_shared_unlock (RwMutex *m); + gb_internal void semaphore_post (Semaphore *s, i32 count); gb_internal void semaphore_wait (Semaphore *s); gb_internal void semaphore_release(Semaphore *s) { semaphore_post(s, 1); } @@ -65,6 +74,10 @@ gb_internal void condition_broadcast(Condition *c); gb_internal void condition_signal(Condition *c); gb_internal void condition_wait(Condition *c, BlockingMutex *m); +gb_internal void park(Parker *p); +gb_internal void unpark_one(Parker *p); +gb_internal void unpark_all(Parker *p); + gb_internal u32 thread_current_id(void); gb_internal void thread_init (ThreadPool *pool, Thread *t, isize idx); @@ -205,6 +218,30 @@ gb_internal void semaphore_wait(Semaphore *s) { gb_internal void condition_wait(Condition *c, BlockingMutex *m) { SleepConditionVariableSRW(&c->cond, &m->srwlock, INFINITE, 0); } + + struct RwMutex { + SRWLOCK srwlock; + }; + + gb_internal void rw_mutex_lock(RwMutex *m) { + AcquireSRWLockExclusive(&m->srwlock); + } + gb_internal bool rw_mutex_try_lock(RwMutex *m) { + return !!TryAcquireSRWLockExclusive(&m->srwlock); + } + gb_internal void rw_mutex_unlock(RwMutex *m) { + ReleaseSRWLockExclusive(&m->srwlock); + } + + gb_internal void rw_mutex_shared_lock(RwMutex *m) { + AcquireSRWLockShared(&m->srwlock); + } + gb_internal bool rw_mutex_try_shared_lock(RwMutex *m) { + return !!TryAcquireSRWLockShared(&m->srwlock); + } + gb_internal void rw_mutex_shared_unlock(RwMutex *m) { + ReleaseSRWLockShared(&m->srwlock); + } #else enum Internal_Mutex_State : i32 { Internal_Mutex_State_Unlocked = 0, @@ -306,8 +343,67 @@ gb_internal void semaphore_wait(Semaphore *s) { futex_wait(&c->state(), state); mutex_lock(m); } + + struct RwMutex { + // TODO(bill): make this a proper RW mutex + BlockingMutex mutex; + }; + + gb_internal void rw_mutex_lock(RwMutex *m) { + mutex_lock(&m->mutex); + } + gb_internal bool rw_mutex_try_lock(RwMutex *m) { + return mutex_try_lock(&m->mutex); + } + gb_internal void rw_mutex_unlock(RwMutex *m) { + mutex_unlock(&m->mutex); + } + + gb_internal void rw_mutex_shared_lock(RwMutex *m) { + mutex_lock(&m->mutex); + } + gb_internal bool rw_mutex_try_shared_lock(RwMutex *m) { + return mutex_try_lock(&m->mutex); + } + gb_internal void rw_mutex_shared_unlock(RwMutex *m) { + mutex_unlock(&m->mutex); + } #endif +struct Parker { + Futex state; +}; +enum ParkerState : u32 { + ParkerState_Empty = 0, + ParkerState_Notified = 1, + ParkerState_Parked = UINT32_MAX, +}; + +gb_internal void park(Parker *p) { + if (p->state.fetch_sub(1, std::memory_order_acquire) == ParkerState_Notified) { + return; + } + for (;;) { + futex_wait(&p->state, ParkerState_Parked); + i32 notified = ParkerState_Empty; + if (p->state.compare_exchange_strong(notified, ParkerState_Empty, std::memory_order_acquire, std::memory_order_acquire)) { + return; + } + } +} + +gb_internal void unpark_one(Parker *p) { + if (p->state.exchange(ParkerState_Notified, std::memory_order_release) == ParkerState_Parked) { + futex_signal(&p->state); + } +} + +gb_internal void unpark_all(Parker *p) { + if (p->state.exchange(ParkerState_Notified, std::memory_order_release) == ParkerState_Parked) { + futex_broadcast(&p->state); + } +} + gb_internal u32 thread_current_id(void) { u32 thread_id; -- cgit v1.2.3 From 3dee3205b299b2a2e803a3bc248f0a9ffdcce69e Mon Sep 17 00:00:00 2001 From: gingerBill Date: Tue, 3 Jan 2023 15:34:52 +0000 Subject: Use `RwMutex` for `DeclInfo` `deps --- src/check_decl.cpp | 27 +++++++++++++++++---------- src/check_expr.cpp | 6 ++++-- src/checker.cpp | 8 ++++---- src/checker.hpp | 4 ++-- 4 files changed, 27 insertions(+), 18 deletions(-) (limited to 'src/checker.cpp') diff --git a/src/check_decl.cpp b/src/check_decl.cpp index 4afde6e51..72c69b5dc 100644 --- a/src/check_decl.cpp +++ b/src/check_decl.cpp @@ -1584,19 +1584,26 @@ gb_internal bool check_proc_body(CheckerContext *ctx_, Token token, DeclInfo *de // NOTE(bill): Add the dependencies from the procedure literal (lambda) // But only at the procedure level - MUTEX_GUARD_BLOCK(decl->deps_mutex) - MUTEX_GUARD_BLOCK(decl->parent->deps_mutex) { - for (Entity *e : decl->deps) { - ptr_set_add(&decl->parent->deps, e); - } + rw_mutex_shared_lock(&decl->deps_mutex); + rw_mutex_lock(&decl->parent->deps_mutex); + + for (Entity *e : decl->deps) { + ptr_set_add(&decl->parent->deps, e); } - MUTEX_GUARD_BLOCK(decl->type_info_deps_mutex) - MUTEX_GUARD_BLOCK(decl->parent->type_info_deps_mutex) { - for (Type *t : decl->type_info_deps) { - ptr_set_add(&decl->parent->type_info_deps, t); - } + rw_mutex_unlock(&decl->parent->deps_mutex); + rw_mutex_shared_unlock(&decl->deps_mutex); + + + rw_mutex_shared_lock(&decl->type_info_deps_mutex); + rw_mutex_lock(&decl->parent->type_info_deps_mutex); + + for (Type *t : decl->type_info_deps) { + ptr_set_add(&decl->parent->type_info_deps, t); } + + rw_mutex_unlock(&decl->parent->type_info_deps_mutex); + rw_mutex_shared_unlock(&decl->type_info_deps_mutex); } } diff --git a/src/check_expr.cpp b/src/check_expr.cpp index d9ab328cb..e3cd66db6 100644 --- a/src/check_expr.cpp +++ b/src/check_expr.cpp @@ -4928,21 +4928,23 @@ gb_internal bool check_identifier_exists(Scope *s, Ast *node, bool nested = fals gb_internal isize add_dependencies_from_unpacking(CheckerContext *c, Entity **lhs, isize lhs_count, isize tuple_index, isize tuple_count) { if (lhs != nullptr && c->decl != nullptr) { - mutex_lock(&c->info->deps_mutex); + // mutex_lock(&c->info->deps_mutex); for (isize j = 0; (tuple_index + j) < lhs_count && j < tuple_count; j++) { Entity *e = lhs[tuple_index + j]; if (e != nullptr) { DeclInfo *decl = decl_info_of_entity(e); if (decl != nullptr) { + rw_mutex_lock(&c->decl->deps_mutex); for (Entity *dep : decl->deps) { ptr_set_add(&c->decl->deps, dep); } + rw_mutex_unlock(&c->decl->deps_mutex); } } } - mutex_unlock(&c->info->deps_mutex); + // mutex_unlock(&c->info->deps_mutex); } return tuple_count; } diff --git a/src/checker.cpp b/src/checker.cpp index 1d536074d..fd80d07de 100644 --- a/src/checker.cpp +++ b/src/checker.cpp @@ -744,17 +744,17 @@ gb_internal void check_scope_usage(Checker *c, Scope *scope) { gb_internal void add_dependency(CheckerInfo *info, DeclInfo *d, Entity *e) { - mutex_lock(&d->deps_mutex); + rw_mutex_lock(&d->deps_mutex); ptr_set_add(&d->deps, e); - mutex_unlock(&d->deps_mutex); + rw_mutex_unlock(&d->deps_mutex); } gb_internal void add_type_info_dependency(CheckerInfo *info, DeclInfo *d, Type *type) { if (d == nullptr) { return; } - mutex_lock(&d->type_info_deps_mutex); + rw_mutex_lock(&d->type_info_deps_mutex); ptr_set_add(&d->type_info_deps, type); - mutex_unlock(&d->type_info_deps_mutex); + rw_mutex_unlock(&d->type_info_deps_mutex); } gb_internal AstPackage *get_core_package(CheckerInfo *info, String name) { diff --git a/src/checker.hpp b/src/checker.hpp index 53052d5cd..50f4a204c 100644 --- a/src/checker.hpp +++ b/src/checker.hpp @@ -179,10 +179,10 @@ struct DeclInfo { CommentGroup *comment; CommentGroup *docs; - BlockingMutex deps_mutex; + RwMutex deps_mutex; PtrSet deps; - BlockingMutex type_info_deps_mutex; + RwMutex type_info_deps_mutex; PtrSet type_info_deps; Array labels; -- 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/checker.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 bb80c1b05922a1d1a76e96f0bc5edba09292b1e9 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Tue, 3 Jan 2023 17:07:53 +0000 Subject: Add `type_and_value_mutex` to `DeclInfo` --- src/checker.cpp | 8 ++++++-- src/checker.hpp | 2 ++ 2 files changed, 8 insertions(+), 2 deletions(-) (limited to 'src/checker.cpp') diff --git a/src/checker.cpp b/src/checker.cpp index 3f5c2892f..11e0dfa47 100644 --- a/src/checker.cpp +++ b/src/checker.cpp @@ -1453,7 +1453,9 @@ gb_internal void add_type_and_value(CheckerContext *ctx, Ast *expr, AddressingMo } BlockingMutex *mutex = &ctx->info->type_and_value_mutex; - if (ctx->pkg) { + if (ctx->decl) { + mutex = &ctx->decl->type_and_value_mutex; + } else if (ctx->pkg) { // TODO(bill): is a per package mutex is a good idea here? mutex = &ctx->pkg->type_and_value_mutex; } @@ -1749,7 +1751,7 @@ gb_internal void add_type_info_type_internal(CheckerContext *c, Type *t) { if (is_type_untyped(t)) { return; // Could be nil } - if (is_type_polymorphic(base_type(t))) { + if (is_type_polymorphic(t)) { return; } @@ -1764,6 +1766,8 @@ gb_internal void add_type_info_type_internal(CheckerContext *c, Type *t) { bool prev = false; isize ti_index = -1; + // NOTE(bill): this is a linear lookup, and is most likely very costly + // as this map keeps growing linearly for (auto const &e : c->info->type_info_map) { if (are_types_identical_unique_tuples(t, e.key)) { // Duplicate entry diff --git a/src/checker.hpp b/src/checker.hpp index d647cd67f..60800349b 100644 --- a/src/checker.hpp +++ b/src/checker.hpp @@ -185,6 +185,8 @@ struct DeclInfo { RwMutex type_info_deps_mutex; PtrSet type_info_deps; + BlockingMutex type_and_value_mutex; + Array labels; }; -- cgit v1.2.3 From ec69101101d56e90ee183e449eb5bb3605e3afbe Mon Sep 17 00:00:00 2001 From: gingerBill Date: Tue, 3 Jan 2023 18:39:37 +0000 Subject: Convert `minimum_dependency_type_info_set` to use a `PtrMap` --- src/checker.cpp | 19 +++++++------------ src/checker.hpp | 2 +- src/llvm_backend_type.cpp | 7 ++++--- src/ptr_map.cpp | 1 - src/ptr_set.cpp | 10 ---------- 5 files changed, 12 insertions(+), 27 deletions(-) (limited to 'src/checker.cpp') diff --git a/src/checker.cpp b/src/checker.cpp index 11e0dfa47..78f96e47f 100644 --- a/src/checker.cpp +++ b/src/checker.cpp @@ -1153,6 +1153,9 @@ gb_internal void init_checker_info(CheckerInfo *i) { array_init(&i->init_procedures, a, 0, 0); array_init(&i->required_foreign_imports_through_force, a, 0, 0); + map_init(&i->objc_msgSend_types); + string_map_init(&i->load_file_cache); + array_init(&i->all_procedures, heap_allocator()); TIME_SECTION("checker info: mpmc queues"); @@ -1160,16 +1163,7 @@ gb_internal void init_checker_info(CheckerInfo *i) { mpmc_init(&i->definition_queue, a, 1<<20); mpmc_init(&i->required_global_variable_queue, a, 1<<10); mpmc_init(&i->required_foreign_imports_through_force_queue, a, 1<<10); - - TIME_SECTION("checker info: mutexes"); - mpmc_init(&i->intrinsics_entry_point_usage, a, 1<<10); // just waste some memory here, even if it probably never used - - map_init(&i->objc_msgSend_types); - string_map_init(&i->load_file_cache); - - array_init(&i->all_procedures, heap_allocator()); - } gb_internal void destroy_checker_info(CheckerInfo *i) { @@ -2031,10 +2025,11 @@ gb_internal void add_min_dep_type_info(Checker *c, Type *t) { ti_index = type_info_index(&c->info, t, false); } GB_ASSERT(ti_index >= 0); - if (ptr_set_update(set, ti_index)) { - // Type Already exists + if (map_get(set, ti_index)) { + // Type already exists; return; } + map_set(set, ti_index, set->entries.count); // Add nested types if (t->kind == Type_Named) { @@ -2275,7 +2270,7 @@ 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); - ptr_set_init(&c->info.minimum_dependency_type_info_set); + map_init(&c->info.minimum_dependency_type_info_set); #define FORCE_ADD_RUNTIME_ENTITIES(condition, ...) do { \ if (condition) { \ diff --git a/src/checker.hpp b/src/checker.hpp index 60800349b..bb870e077 100644 --- a/src/checker.hpp +++ b/src/checker.hpp @@ -336,7 +336,7 @@ struct CheckerInfo { Scope * init_scope; Entity * entry_point; PtrSet minimum_dependency_set; - PtrSet minimum_dependency_type_info_set; + PtrMap minimum_dependency_type_info_set; diff --git a/src/llvm_backend_type.cpp b/src/llvm_backend_type.cpp index c306cdead..b9b450404 100644 --- a/src/llvm_backend_type.cpp +++ b/src/llvm_backend_type.cpp @@ -2,9 +2,10 @@ gb_internal isize lb_type_info_index(CheckerInfo *info, Type *type, bool err_on_ auto *set = &info->minimum_dependency_type_info_set; isize index = type_info_index(info, type, err_on_not_found); if (index >= 0) { - isize i = ptr_set_entry_index(set, index); - if (i >= 0) { - return i+1; + auto *found = map_get(set, index); + if (found) { + GB_ASSERT(*found >= 0); + return *found + 1; } } if (err_on_not_found) { diff --git a/src/ptr_map.cpp b/src/ptr_map.cpp index 264136881..ae3cd4b40 100644 --- a/src/ptr_map.cpp +++ b/src/ptr_map.cpp @@ -229,7 +229,6 @@ gb_internal void map_set(PtrMap *h, K key, V const &value) { } } - template gb_internal void map__erase(PtrMap *h, MapFindResult const &fr) { MapFindResult last; diff --git a/src/ptr_set.cpp b/src/ptr_set.cpp index 9b8b678f8..f730a47ff 100644 --- a/src/ptr_set.cpp +++ b/src/ptr_set.cpp @@ -12,7 +12,6 @@ struct PtrSetEntry { template struct PtrSet { - Slice hashes; Array> entries; }; @@ -154,15 +153,6 @@ gb_internal gb_inline bool ptr_set_exists(PtrSet *s, T ptr) { return index != MAP_SENTINEL; } -template -gb_internal gb_inline isize ptr_set_entry_index(PtrSet *s, T ptr) { - isize index = ptr_set__find(s, ptr).entry_index; - if (index != MAP_SENTINEL) { - return index; - } - return -1; -} - // Returns true if it already exists template gb_internal T ptr_set_add(PtrSet *s, T ptr) { -- cgit v1.2.3 From d06a0e7093c3f06a474a040385f1b9dfdfce29ad Mon Sep 17 00:00:00 2001 From: gingerBill Date: Wed, 4 Jan 2023 13:30:27 +0000 Subject: Improve the `PtrSet` to be as simple and small as possible --- src/check_stmt.cpp | 1 + src/checker.cpp | 33 +++--- src/ptr_map.cpp | 2 +- src/ptr_set.cpp | 303 +++++++++++++++++++++++------------------------------ src/threading.cpp | 20 ++-- 5 files changed, 157 insertions(+), 202 deletions(-) (limited to 'src/checker.cpp') diff --git a/src/check_stmt.cpp b/src/check_stmt.cpp index 9547035d0..b4dd4cd7d 100644 --- a/src/check_stmt.cpp +++ b/src/check_stmt.cpp @@ -1289,6 +1289,7 @@ gb_internal void check_type_switch_stmt(CheckerContext *ctx, Ast *node, u32 mod_ for (Type *t : variants) { if (!type_ptr_set_exists(&seen, t)) { array_add(&unhandled, t); + gb_printf_err("HERE: %p %s\n", t, type_to_string(t)); } } diff --git a/src/checker.cpp b/src/checker.cpp index 78f96e47f..b8709f15e 100644 --- a/src/checker.cpp +++ b/src/checker.cpp @@ -66,15 +66,10 @@ gb_internal void scope_reserve(Scope *scope, isize capacity) { } gb_internal void entity_graph_node_set_destroy(EntityGraphNodeSet *s) { - if (s->hashes.data != nullptr) { - ptr_set_destroy(s); - } + ptr_set_destroy(s); } gb_internal void entity_graph_node_set_add(EntityGraphNodeSet *s, EntityGraphNode *n) { - if (s->hashes.data == nullptr) { - ptr_set_init(s); - } ptr_set_add(s, n); } @@ -2556,7 +2551,6 @@ gb_internal Array generate_entity_dependency_graph(CheckerInf } // IMPORTANT NOTE/TODO(bill, 2020-11-15): These three calls take the majority of the // the time to process - entity_graph_node_set_add(&p->succ, s); entity_graph_node_set_add(&s->pred, p); // Remove edge to 'n' @@ -2577,7 +2571,7 @@ gb_internal Array generate_entity_dependency_graph(CheckerInf for_array(i, G) { EntityGraphNode *n = G[i]; n->index = i; - n->dep_count = n->succ.entries.count; + n->dep_count = n->succ.count; GB_ASSERT(n->dep_count >= 0); } @@ -4228,7 +4222,7 @@ gb_internal Array generate_import_dependency_graph(Checker *c for (auto const &entry : M) { auto n = entry.value; n->index = i++; - n->dep_count = n->succ.entries.count; + n->dep_count = n->succ.count; GB_ASSERT(n->dep_count >= 0); array_add(&G, n); } @@ -5706,17 +5700,6 @@ gb_internal void check_parsed_files(Checker *c) { check_scope_usage(c, f->scope); } - TIME_SECTION("add untyped expression values"); - // Add untyped expression values - for (UntypedExprInfo u = {}; mpmc_dequeue(&c->global_untyped_queue, &u); /**/) { - GB_ASSERT(u.expr != nullptr && u.info != nullptr); - if (is_type_typed(u.info->type)) { - compiler_error("%s (type %s) is typed!", expr_to_string(u.expr), type_to_string(u.info->type)); - } - add_type_and_value(&c->builtin_ctx, u.expr, u.info->mode, u.info->type, u.info->value); - } - - TIME_SECTION("add basic type information"); // Add "Basic" type information for (isize i = 0; i < Basic_COUNT; i++) { @@ -5810,6 +5793,16 @@ gb_internal void check_parsed_files(Checker *c) { GB_ASSERT(c->info.entity_queue.count.load(std::memory_order_relaxed) == 0); GB_ASSERT(c->info.definition_queue.count.load(std::memory_order_relaxed) == 0); + TIME_SECTION("add untyped expression values"); + // Add untyped expression values + for (UntypedExprInfo u = {}; mpmc_dequeue(&c->global_untyped_queue, &u); /**/) { + GB_ASSERT(u.expr != nullptr && u.info != nullptr); + if (is_type_typed(u.info->type)) { + compiler_error("%s (type %s) is typed!", expr_to_string(u.expr), type_to_string(u.info->type)); + } + add_type_and_value(&c->builtin_ctx, u.expr, u.info->mode, u.info->type, u.info->value); + } + TIME_SECTION("sort init procedures"); check_sort_init_procedures(c); diff --git a/src/ptr_map.cpp b/src/ptr_map.cpp index ae3cd4b40..8869bf3fe 100644 --- a/src/ptr_map.cpp +++ b/src/ptr_map.cpp @@ -41,7 +41,7 @@ gb_internal gb_inline u32 ptr_map_hash_key(uintptr key) { u32 word = ((state >> ((state >> 28u) + 4u)) ^ state) * 277803737u; res = (word >> 22u) ^ word; #endif - return res ^ (res == MAP_SENTINEL); + return res; } gb_internal gb_inline u32 ptr_map_hash_key(void const *key) { return ptr_map_hash_key((uintptr)key); diff --git a/src/ptr_set.cpp b/src/ptr_set.cpp index e2b3f2372..8be2b0524 100644 --- a/src/ptr_set.cpp +++ b/src/ptr_set.cpp @@ -1,19 +1,22 @@ template -struct PtrSetEntry { - static_assert(sizeof(T) == sizeof(void *), "Key size must be pointer size"); - - T ptr; - MapIndex next; +struct TypeIsPointer { + enum {value = false}; +}; - operator T() const noexcept { - return this->ptr; - } +template +struct TypeIsPointer { + enum {value = true}; }; + template struct PtrSet { - Slice hashes; - Array> entries; + static_assert(TypeIsPointer::value, "PtrSet::T must be a pointer"); + static constexpr T TOMBSTONE = (T)(~uintptr(0)); + + T * keys; + usize count; + usize capacity; }; template gb_internal void ptr_set_init (PtrSet *s, isize capacity = 16); @@ -30,225 +33,183 @@ gb_internal gbAllocator ptr_set_allocator(void) { template gb_internal void ptr_set_init(PtrSet *s, isize capacity) { + GB_ASSERT(s->keys == nullptr); if (capacity != 0) { capacity = next_pow2_isize(gb_max(16, capacity)); + s->keys = gb_alloc_array(ptr_set_allocator(), T, capacity); + // This memory will be zeroed, no need to explicitly zero it } - - slice_init(&s->hashes, ptr_set_allocator(), capacity); - array_init(&s->entries, ptr_set_allocator(), 0, capacity); - for (isize i = 0; i < capacity; i++) { - s->hashes.data[i] = MAP_SENTINEL; - } + s->count = 0; + s->capacity = capacity; } template gb_internal void ptr_set_destroy(PtrSet *s) { - if (s->entries.allocator.proc == nullptr) { - s->entries.allocator = ptr_set_allocator(); - } - slice_free(&s->hashes, s->entries.allocator); - array_free(&s->entries); + gb_free(ptr_set_allocator(), s->keys); + s->keys = nullptr; + s->count = 0; + s->capacity = 0; } template -gb_internal MapIndex ptr_set__add_entry(PtrSet *s, T ptr) { - PtrSetEntry e = {}; - e.ptr = ptr; - e.next = MAP_SENTINEL; - array_add(&s->entries, e); - return cast(MapIndex)(s->entries.count-1); -} - - -template -gb_internal MapFindResult ptr_set__find(PtrSet *s, T ptr) { - MapFindResult fr = {MAP_SENTINEL, MAP_SENTINEL, MAP_SENTINEL}; - if (s->hashes.count != 0) { - u32 hash = ptr_map_hash_key(ptr); - fr.hash_index = cast(MapIndex)(hash & (s->hashes.count-1)); - fr.entry_index = s->hashes.data[fr.hash_index]; - while (fr.entry_index != MAP_SENTINEL) { - if (s->entries.data[fr.entry_index].ptr == ptr) { - return fr; +gb_internal isize ptr_set__find(PtrSet *s, T ptr) { + GB_ASSERT(ptr != nullptr); + if (s->count != 0) { + #if 0 + for (usize i = 0; i < s->capacity; i++) { + if (s->keys[i] == ptr) { + return i; } - fr.entry_prev = fr.entry_index; - fr.entry_index = s->entries.data[fr.entry_index].next; } - } - return fr; -} - -template -gb_internal MapFindResult ptr_set__find_from_entry(PtrSet *s, PtrSetEntry *e) { - MapFindResult fr = {MAP_SENTINEL, MAP_SENTINEL, MAP_SENTINEL}; - if (s->hashes.count != 0) { - u32 hash = ptr_map_hash_key(e->ptr); - fr.hash_index = cast(MapIndex)(hash & (s->hashes.count-1)); - fr.entry_index = s->hashes.data[fr.hash_index]; - while (fr.entry_index != MAP_SENTINEL) { - if (&s->entries.data[fr.entry_index] == e) { - return fr; + #else + u32 hash = ptr_map_hash_key(ptr); + usize mask = s->capacity-1; + usize hash_index = cast(usize)hash & mask; + for (usize i = 0; i < s->capacity; i++) { + T key = s->keys[hash_index]; + if (key == ptr) { + return hash_index; + } else if (key == nullptr) { + return -1; } - fr.entry_prev = fr.entry_index; - fr.entry_index = s->entries.data[fr.entry_index].next; + hash_index = (hash_index+1)&mask; } + #endif } - return fr; + return -1; } template gb_internal bool ptr_set__full(PtrSet *s) { - return 0.75f * s->hashes.count <= s->entries.count; + return 0.75f * s->capacity <= s->count; } template -gb_internal void ptr_set_reset_entries(PtrSet *s) { - for (isize i = 0; i < s->hashes.count; i++) { - s->hashes.data[i] = MAP_SENTINEL; - } - for (isize i = 0; i < s->entries.count; i++) { - MapFindResult fr; - PtrSetEntry *e = &s->entries.data[i]; - e->next = MAP_SENTINEL; - fr = ptr_set__find_from_entry(s, e); - if (fr.entry_prev == MAP_SENTINEL) { - s->hashes[fr.hash_index] = cast(MapIndex)i; - } else { - s->entries[fr.entry_prev].next = cast(MapIndex)i; - } +gb_internal gb_inline void ptr_set_grow(PtrSet *old_set) { + if (old_set->capacity == 0) { + ptr_set_init(old_set); + return; } -} -template -gb_internal void ptr_set_reserve(PtrSet *s, isize cap) { - if (s->entries.allocator.proc == nullptr) { - s->entries.allocator = ptr_set_allocator(); - } - array_reserve(&s->entries, cap); - if (s->entries.count*2 < s->hashes.count) { - return; + PtrSet new_set = {}; + ptr_set_init(&new_set, gb_max(old_set->capacity<<1, 16)); + + for (T ptr : *old_set) { + bool was_new = ptr_set_update(&new_set, ptr); + GB_ASSERT(!was_new); } - slice_resize(&s->hashes, s->entries.allocator, cap*2); - ptr_set_reset_entries(s); -} + GB_ASSERT(old_set->count == new_set.count); -template -gb_internal gb_inline void ptr_set_grow(PtrSet *s) { - isize new_count = gb_max(s->hashes.count<<1, 16); - ptr_set_reserve(s, new_count); + ptr_set_destroy(old_set); + + *old_set = new_set; } template gb_internal gb_inline bool ptr_set_exists(PtrSet *s, T ptr) { - isize index = ptr_set__find(s, ptr).entry_index; - return index != MAP_SENTINEL; + return ptr_set__find(s, ptr) >= 0; } -// Returns true if it already exists -template -gb_internal T ptr_set_add(PtrSet *s, T ptr) { - MapIndex index; - MapFindResult fr; - if (s->hashes.count == 0) { - ptr_set_grow(s); - } - fr = ptr_set__find(s, ptr); - if (fr.entry_index == MAP_SENTINEL) { - index = ptr_set__add_entry(s, ptr); - if (fr.entry_prev != MAP_SENTINEL) { - s->entries.data[fr.entry_prev].next = index; - } else { - s->hashes.data[fr.hash_index] = index; - } - } - if (ptr_set__full(s)) { - ptr_set_grow(s); - } - return ptr; -} template gb_internal bool ptr_set_update(PtrSet *s, T ptr) { // returns true if it previously existsed - bool exists = false; - MapIndex index; - MapFindResult fr; - if (s->hashes.count == 0) { + if (ptr_set_exists(s, ptr)) { + return true; + } + + if (s->keys == nullptr) { + ptr_set_init(s); + } else if (ptr_set__full(s)) { ptr_set_grow(s); } - fr = ptr_set__find(s, ptr); - if (fr.entry_index != MAP_SENTINEL) { - exists = true; - } else { - index = ptr_set__add_entry(s, ptr); - if (fr.entry_prev != MAP_SENTINEL) { - s->entries.data[fr.entry_prev].next = index; - } else { - s->hashes.data[fr.hash_index] = index; + GB_ASSERT(s->count < s->capacity); + GB_ASSERT(s->capacity >= 0); + + usize mask = s->capacity-1; + u32 hash = ptr_map_hash_key(ptr); + usize hash_index = (cast(usize)hash) & mask; + GB_ASSERT(hash_index < s->capacity); + for (usize i = 0; i < s->capacity; i++) { + T *key = &s->keys[hash_index]; + GB_ASSERT(*key != ptr); + if (*key == PtrSet::TOMBSTONE || *key == nullptr) { + *key = ptr; + s->count++; + return false; } + hash_index = (hash_index+1)&mask; } - if (ptr_set__full(s)) { - ptr_set_grow(s); - } - return exists; -} - + GB_PANIC("ptr set out of memory"); + return false; +} template -gb_internal void ptr_set__erase(PtrSet *s, MapFindResult fr) { - MapFindResult last; - if (fr.entry_prev == MAP_SENTINEL) { - s->hashes.data[fr.hash_index] = s->entries.data[fr.entry_index].next; - } else { - s->entries.data[fr.entry_prev].next = s->entries.data[fr.entry_index].next; - } - if (cast(isize)fr.entry_index == s->entries.count-1) { - array_pop(&s->entries); - return; - } - s->entries.data[fr.entry_index] = s->entries.data[s->entries.count-1]; - last = ptr_set__find(s, s->entries.data[fr.entry_index].ptr); - if (last.entry_prev != MAP_SENTINEL) { - s->entries.data[last.entry_prev].next = fr.entry_index; - } else { - s->hashes.data[last.hash_index] = fr.entry_index; - } +gb_internal T ptr_set_add(PtrSet *s, T ptr) { + ptr_set_update(s, ptr); + return ptr; } + template gb_internal void ptr_set_remove(PtrSet *s, T ptr) { - MapFindResult fr = ptr_set__find(s, ptr); - if (fr.entry_index != MAP_SENTINEL) { - ptr_set__erase(s, fr); + isize index = ptr_set__find(s, ptr); + if (index >= 0) { + GB_ASSERT(s->count > 0); + s->keys[index] = PtrSet::TOMBSTONE; + s->count--; } } template gb_internal gb_inline void ptr_set_clear(PtrSet *s) { - array_clear(&s->entries); - for (isize i = 0; i < s->hashes.count; i++) { - s->hashes.data[i] = MAP_SENTINEL; - } + s->count = 0; + gb_zero_size(s->keys, s->capacity*gb_size_of(T)); } - -template -gb_internal PtrSetEntry *begin(PtrSet &m) noexcept { - return m.entries.data; -} template -gb_internal PtrSetEntry const *begin(PtrSet const &m) noexcept { - return m.entries.data; -} +struct PtrSetIterator { + PtrSet *set; + usize index; + + PtrSetIterator &operator++() noexcept { + for (;;) { + ++index; + if (set->capacity == index) { + return *this; + } + T key = set->keys[index]; + if (key != nullptr && key != PtrSet::TOMBSTONE) { + return *this; + } + } + } + + bool operator==(PtrSetIterator const &other) const noexcept { + return this->set == other.set && this->index == other.index; + } + + + operator T *() const { + return &set->keys[index]; + } +}; template -gb_internal PtrSetEntry *end(PtrSet &m) noexcept { - return m.entries.data + m.entries.count; +gb_internal PtrSetIterator begin(PtrSet &set) noexcept { + usize index = 0; + while (index < set.capacity) { + T key = set.keys[index]; + if (key != nullptr && key != PtrSet::TOMBSTONE) { + break; + } + index++; + } + return PtrSetIterator{&set, index}; } - template -gb_internal PtrSetEntry const *end(PtrSet const &m) noexcept { - return m.entries.data + m.entries.count; +gb_internal PtrSetIterator end(PtrSet &set) noexcept { + return PtrSetIterator{&set, set.capacity}; } \ No newline at end of file diff --git a/src/threading.cpp b/src/threading.cpp index 27a17112e..bf298e024 100644 --- a/src/threading.cpp +++ b/src/threading.cpp @@ -699,13 +699,13 @@ extern "C" int __ulock_wake(uint32_t operation, void *addr, uint64_t wake_value) gb_internal void futex_signal(Futex *f) { for (;;) { int ret = __ulock_wake(UL_COMPARE_AND_WAIT | ULF_NO_ERRNO, f, 0); - if (ret >= 0) { + if (ret == 0) { return; } - if (ret == EINTR || ret == EFAULT) { + if (ret == -EINTR || ret == -EFAULT) { continue; } - if (ret == ENOENT) { + if (ret == -ENOENT) { return; } GB_PANIC("Failed in futex wake!\n"); @@ -716,13 +716,13 @@ gb_internal void futex_broadcast(Futex *f) { for (;;) { enum { ULF_WAKE_ALL = 0x00000100 }; int ret = __ulock_wake(UL_COMPARE_AND_WAIT | ULF_NO_ERRNO | ULF_WAKE_ALL, f, 0); - if (ret >= 0) { + if (ret == 0) { return; } - if (ret == EINTR || ret == EFAULT) { + if (ret == -EINTR || ret == -EFAULT) { continue; } - if (ret == ENOENT) { + if (ret == -ENOENT) { return; } GB_PANIC("Failed in futex wake!\n"); @@ -732,16 +732,16 @@ gb_internal void futex_broadcast(Futex *f) { gb_internal void futex_wait(Futex *f, Footex val) { for (;;) { int ret = __ulock_wait(UL_COMPARE_AND_WAIT | ULF_NO_ERRNO, f, val, 0); - if (ret >= 0) { + if (ret == 0) { if (*f != val) { return; } continue; } - if (ret == EINTR || ret == EFAULT) { - continue; + if (ret == -EINTR || ret == -EFAULT) { + -continue; } - if (ret == ENOENT) { + if (ret == -ENOENT) { return; } -- cgit v1.2.3 From d4e18109da5fa051d689be84a6ecf1e77348c74e Mon Sep 17 00:00:00 2001 From: gingerBill Date: Wed, 4 Jan 2023 13:52:38 +0000 Subject: Move walking of dependencies for procedures to just before calculating the min dep set --- src/check_builtin.cpp | 3 +- src/check_decl.cpp | 31 --------------------- src/checker.cpp | 76 +++++++++++++++++++++++++++++++++++++++++++-------- src/checker.hpp | 5 ++++ 4 files changed, 71 insertions(+), 44 deletions(-) (limited to 'src/checker.cpp') diff --git a/src/check_builtin.cpp b/src/check_builtin.cpp index 606283c32..294bc7da8 100644 --- a/src/check_builtin.cpp +++ b/src/check_builtin.cpp @@ -1118,8 +1118,7 @@ gb_internal bool cache_load_file_directive(CheckerContext *c, Ast *call, String } }); - char *c_str = alloc_cstring(heap_allocator(), path); - defer (gb_free(heap_allocator(), c_str)); + char *c_str = alloc_cstring(temporary_allocator(), path); gbFile f = {}; if (cache == nullptr) { diff --git a/src/check_decl.cpp b/src/check_decl.cpp index 72c69b5dc..07b547feb 100644 --- a/src/check_decl.cpp +++ b/src/check_decl.cpp @@ -1576,36 +1576,5 @@ gb_internal bool check_proc_body(CheckerContext *ctx_, Token token, DeclInfo *de check_scope_usage(ctx->checker, ctx->scope); - if (decl->parent != nullptr) { - Scope *ps = decl->parent->scope; - if (ps->flags & (ScopeFlag_File & ScopeFlag_Pkg & ScopeFlag_Global)) { - return true; - } else { - // NOTE(bill): Add the dependencies from the procedure literal (lambda) - // But only at the procedure level - - rw_mutex_shared_lock(&decl->deps_mutex); - rw_mutex_lock(&decl->parent->deps_mutex); - - for (Entity *e : decl->deps) { - ptr_set_add(&decl->parent->deps, e); - } - - rw_mutex_unlock(&decl->parent->deps_mutex); - rw_mutex_shared_unlock(&decl->deps_mutex); - - - rw_mutex_shared_lock(&decl->type_info_deps_mutex); - rw_mutex_lock(&decl->parent->type_info_deps_mutex); - - for (Type *t : decl->type_info_deps) { - ptr_set_add(&decl->parent->type_info_deps, t); - } - - rw_mutex_unlock(&decl->parent->type_info_deps_mutex); - rw_mutex_shared_unlock(&decl->type_info_deps_mutex); - } - } - return true; } diff --git a/src/checker.cpp b/src/checker.cpp index b8709f15e..5fc9a5551 100644 --- a/src/checker.cpp +++ b/src/checker.cpp @@ -174,6 +174,12 @@ gb_internal void import_graph_node_swap(ImportGraphNode **data, isize i, isize j gb_internal void init_decl_info(DeclInfo *d, Scope *scope, DeclInfo *parent) { gb_zero_item(d); + if (parent) { + mutex_lock(&parent->next_mutex); + d->next_sibling = parent->next_child; + parent->next_child = d; + mutex_unlock(&parent->next_mutex); + } d->parent = parent; d->scope = scope; ptr_set_init(&d->deps, 0); @@ -5316,15 +5322,8 @@ gb_internal WORKER_TASK_PROC(check_proc_info_worker_proc) { return 1; } - -gb_internal void check_procedure_bodies(Checker *c) { - GB_ASSERT(c != nullptr); - - +gb_internal void check_init_worker_data(Checker *c) { u32 thread_count = cast(u32)global_thread_pool.threads.count; - if (!build_context.threaded_checker) { - thread_count = 1; - } check_procedure_bodies_worker_data = gb_alloc_array(permanent_allocator(), CheckProcedureBodyWorkerData, thread_count); @@ -5332,10 +5331,15 @@ gb_internal void check_procedure_bodies(Checker *c) { check_procedure_bodies_worker_data[i].c = c; map_init(&check_procedure_bodies_worker_data[i].untyped); } +} - defer (for (isize i = 0; i < thread_count; i++) { - map_destroy(&check_procedure_bodies_worker_data[i].untyped); - }); +gb_internal void check_procedure_bodies(Checker *c) { + GB_ASSERT(c != nullptr); + + u32 thread_count = cast(u32)global_thread_pool.threads.count; + if (!build_context.threaded_checker) { + thread_count = 1; + } if (thread_count == 1) { UntypedExprInfoMap *untyped = &check_procedure_bodies_worker_data[0].untyped; @@ -5636,6 +5640,50 @@ gb_internal void add_type_info_for_type_definitions(Checker *c) { } } +gb_internal void check_walk_all_dependencies(DeclInfo *decl) { + if (decl == nullptr) { + return; + } + for (DeclInfo *child = decl->next_child; child != nullptr; child = child->next_sibling) { + check_walk_all_dependencies(child); + } + if (decl->parent && decl->parent->entity && decl->parent->entity->kind == Entity_Procedure) { + Scope *ps = decl->parent->scope; + if (ps->flags & (ScopeFlag_File & ScopeFlag_Pkg & ScopeFlag_Global)) { + return; + } else { + // NOTE(bill): Add the dependencies from the procedure literal (lambda) + // But only at the procedure level + rw_mutex_shared_lock(&decl->deps_mutex); + rw_mutex_lock(&decl->parent->deps_mutex); + + for (Entity *e : decl->deps) { + ptr_set_add(&decl->parent->deps, e); + } + + rw_mutex_unlock(&decl->parent->deps_mutex); + rw_mutex_shared_unlock(&decl->deps_mutex); + + rw_mutex_shared_lock(&decl->type_info_deps_mutex); + rw_mutex_lock(&decl->parent->type_info_deps_mutex); + + for (Type *t : decl->type_info_deps) { + ptr_set_add(&decl->parent->type_info_deps, t); + } + + rw_mutex_unlock(&decl->parent->type_info_deps_mutex); + rw_mutex_shared_unlock(&decl->type_info_deps_mutex); + } + } +} + +gb_internal void check_update_dependency_tree_for_procedures(Checker *c) { + for (Entity *e : c->info.entities) { + DeclInfo *decl = e->decl_info; + check_walk_all_dependencies(decl); + } +} + gb_internal void check_parsed_files(Checker *c) { TIME_SECTION("map full filepaths to scope"); add_type_info_type(&c->builtin_ctx, t_invalid); @@ -5657,6 +5705,9 @@ gb_internal void check_parsed_files(Checker *c) { } } + TIME_SECTION("init worker data"); + check_init_worker_data(c); + TIME_SECTION("create file scopes"); check_create_file_scopes(c); @@ -5744,6 +5795,9 @@ gb_internal void check_parsed_files(Checker *c) { add_type_info_for_type_definitions(c); check_merge_queues_into_arrays(c); + TIME_SECTION("update dependency tree for procedures"); + check_update_dependency_tree_for_procedures(c); + TIME_SECTION("generate minimum dependency set"); generate_minimum_dependency_set(c, c->info.entry_point); diff --git a/src/checker.hpp b/src/checker.hpp index bb870e077..821d43922 100644 --- a/src/checker.hpp +++ b/src/checker.hpp @@ -159,6 +159,11 @@ char const *ProcCheckedState_strings[ProcCheckedState_COUNT] { // DeclInfo is used to store information of certain declarations to allow for "any order" usage struct DeclInfo { DeclInfo * parent; // NOTE(bill): only used for procedure literals at the moment + + BlockingMutex next_mutex; + DeclInfo * next_child; + DeclInfo * next_sibling; + Scope * scope; Entity *entity; -- 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/checker.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 9455918eec18f3101d040adea09a628f684563f9 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Wed, 4 Jan 2023 22:20:18 +0000 Subject: Fix min dep type info problem caused by const ref of `map_set` --- src/check_decl.cpp | 29 +++++++++++++++++++++++++++++ src/checker.cpp | 5 ++++- src/llvm_backend_type.cpp | 2 +- 3 files changed, 34 insertions(+), 2 deletions(-) (limited to 'src/checker.cpp') diff --git a/src/check_decl.cpp b/src/check_decl.cpp index 07b547feb..644771dcd 100644 --- a/src/check_decl.cpp +++ b/src/check_decl.cpp @@ -1576,5 +1576,34 @@ gb_internal bool check_proc_body(CheckerContext *ctx_, Token token, DeclInfo *de check_scope_usage(ctx->checker, ctx->scope); + // if (decl->parent) { + // Scope *ps = decl->parent->scope; + // if (ps->flags & (ScopeFlag_File & ScopeFlag_Pkg & ScopeFlag_Global)) { + // return true; + // } else { + // // NOTE(bill): Add the dependencies from the procedure literal (lambda) + // // But only at the procedure level + // rw_mutex_shared_lock(&decl->deps_mutex); + // rw_mutex_lock(&decl->parent->deps_mutex); + + // for (Entity *e : decl->deps) { + // ptr_set_add(&decl->parent->deps, e); + // } + + // rw_mutex_unlock(&decl->parent->deps_mutex); + // rw_mutex_shared_unlock(&decl->deps_mutex); + + // rw_mutex_shared_lock(&decl->type_info_deps_mutex); + // rw_mutex_lock(&decl->parent->type_info_deps_mutex); + + // for (Type *t : decl->type_info_deps) { + // ptr_set_add(&decl->parent->type_info_deps, t); + // } + + // rw_mutex_unlock(&decl->parent->type_info_deps_mutex); + // rw_mutex_shared_unlock(&decl->type_info_deps_mutex); + // } + // } + return true; } diff --git a/src/checker.cpp b/src/checker.cpp index 0bebce232..8cb6ea99d 100644 --- a/src/checker.cpp +++ b/src/checker.cpp @@ -2030,7 +2030,10 @@ gb_internal void add_min_dep_type_info(Checker *c, Type *t) { // Type already exists; return; } - map_set(set, ti_index, set->entries.count); + // IMPORTANT NOTE(bill): this must be copied as `map_set` takes a const ref + // and effectively assigns the `+1` of the value + isize const count = set->entries.count; + map_set(set, ti_index, count); // Add nested types if (t->kind == Type_Named) { diff --git a/src/llvm_backend_type.cpp b/src/llvm_backend_type.cpp index b9b450404..e2b5c9dd0 100644 --- a/src/llvm_backend_type.cpp +++ b/src/llvm_backend_type.cpp @@ -186,7 +186,7 @@ gb_internal void lb_setup_type_info_data(lbProcedure *p) { // NOTE(bill): Setup if (entry_index <= 0) { continue; } - + if (entries_handled[entry_index]) { continue; } -- cgit v1.2.3 From 1517f1d7793c8985664600a820e3434dfdf83810 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Thu, 5 Jan 2023 11:54:21 +0000 Subject: Add uncomment `add_type_info_type` calls for type assertions --- src/check_decl.cpp | 60 ++++++++++++++++++++++++++++------------------------ src/check_expr.cpp | 8 +++---- src/checker.cpp | 38 +++++---------------------------- src/llvm_backend.cpp | 1 + src/ptr_map.cpp | 29 +++++++++++++++++++++++++ 5 files changed, 71 insertions(+), 65 deletions(-) (limited to 'src/checker.cpp') diff --git a/src/check_decl.cpp b/src/check_decl.cpp index 644771dcd..d4ae9c59d 100644 --- a/src/check_decl.cpp +++ b/src/check_decl.cpp @@ -1411,6 +1411,37 @@ end:; } +gb_internal void add_deps_from_child_to_parent(DeclInfo *decl) { + if (decl && decl->parent) { + Scope *ps = decl->parent->scope; + if (ps->flags & (ScopeFlag_File & ScopeFlag_Pkg & ScopeFlag_Global)) { + return; + } else { + // NOTE(bill): Add the dependencies from the procedure literal (lambda) + // But only at the procedure level + rw_mutex_shared_lock(&decl->deps_mutex); + rw_mutex_lock(&decl->parent->deps_mutex); + + for (Entity *e : decl->deps) { + ptr_set_add(&decl->parent->deps, e); + } + + rw_mutex_unlock(&decl->parent->deps_mutex); + rw_mutex_shared_unlock(&decl->deps_mutex); + + rw_mutex_shared_lock(&decl->type_info_deps_mutex); + rw_mutex_lock(&decl->parent->type_info_deps_mutex); + + for (Type *t : decl->type_info_deps) { + ptr_set_add(&decl->parent->type_info_deps, t); + } + + rw_mutex_unlock(&decl->parent->type_info_deps_mutex); + rw_mutex_shared_unlock(&decl->type_info_deps_mutex); + } + } +} + struct ProcUsingVar { Entity *e; Entity *uvar; @@ -1576,34 +1607,7 @@ gb_internal bool check_proc_body(CheckerContext *ctx_, Token token, DeclInfo *de check_scope_usage(ctx->checker, ctx->scope); - // if (decl->parent) { - // Scope *ps = decl->parent->scope; - // if (ps->flags & (ScopeFlag_File & ScopeFlag_Pkg & ScopeFlag_Global)) { - // return true; - // } else { - // // NOTE(bill): Add the dependencies from the procedure literal (lambda) - // // But only at the procedure level - // rw_mutex_shared_lock(&decl->deps_mutex); - // rw_mutex_lock(&decl->parent->deps_mutex); - - // for (Entity *e : decl->deps) { - // ptr_set_add(&decl->parent->deps, e); - // } - - // rw_mutex_unlock(&decl->parent->deps_mutex); - // rw_mutex_shared_unlock(&decl->deps_mutex); - - // rw_mutex_shared_lock(&decl->type_info_deps_mutex); - // rw_mutex_lock(&decl->parent->type_info_deps_mutex); - - // for (Type *t : decl->type_info_deps) { - // ptr_set_add(&decl->parent->type_info_deps, t); - // } - - // rw_mutex_unlock(&decl->parent->type_info_deps_mutex); - // rw_mutex_shared_unlock(&decl->type_info_deps_mutex); - // } - // } + add_deps_from_child_to_parent(decl); return true; } diff --git a/src/check_expr.cpp b/src/check_expr.cpp index e9e61486e..e0519d26b 100644 --- a/src/check_expr.cpp +++ b/src/check_expr.cpp @@ -8777,8 +8777,8 @@ gb_internal ExprKind check_type_assertion(CheckerContext *c, Operand *o, Ast *no return kind; } - // add_type_info_type(c, o->type); - // add_type_info_type(c, bsrc->Union.variants[0]); + add_type_info_type(c, o->type); + add_type_info_type(c, bsrc->Union.variants[0]); o->type = bsrc->Union.variants[0]; o->mode = Addressing_OptionalOk; @@ -8810,8 +8810,8 @@ gb_internal ExprKind check_type_assertion(CheckerContext *c, Operand *o, Ast *no return kind; } - // add_type_info_type(c, o->type); - // add_type_info_type(c, t); + add_type_info_type(c, o->type); + add_type_info_type(c, t); o->type = t; o->mode = Addressing_OptionalOk; diff --git a/src/checker.cpp b/src/checker.cpp index 8cb6ea99d..a2ed73119 100644 --- a/src/checker.cpp +++ b/src/checker.cpp @@ -2026,14 +2026,13 @@ gb_internal void add_min_dep_type_info(Checker *c, Type *t) { ti_index = type_info_index(&c->info, t, false); } GB_ASSERT(ti_index >= 0); - if (map_get(set, ti_index)) { - // Type already exists; - return; - } // IMPORTANT NOTE(bill): this must be copied as `map_set` takes a const ref // and effectively assigns the `+1` of the value isize const count = set->entries.count; - map_set(set, ti_index, count); + if (map_set_if_not_previously_exists(set, ti_index, count)) { + // Type already exists; + return; + } // Add nested types if (t->kind == Type_Named) { @@ -5650,34 +5649,7 @@ gb_internal void check_walk_all_dependencies(DeclInfo *decl) { for (DeclInfo *child = decl->next_child; child != nullptr; child = child->next_sibling) { check_walk_all_dependencies(child); } - if (decl->parent && decl->parent->entity && decl->parent->entity->kind == Entity_Procedure) { - Scope *ps = decl->parent->scope; - if (ps->flags & (ScopeFlag_File & ScopeFlag_Pkg & ScopeFlag_Global)) { - return; - } else { - // NOTE(bill): Add the dependencies from the procedure literal (lambda) - // But only at the procedure level - rw_mutex_shared_lock(&decl->deps_mutex); - rw_mutex_lock(&decl->parent->deps_mutex); - - for (Entity *e : decl->deps) { - ptr_set_add(&decl->parent->deps, e); - } - - rw_mutex_unlock(&decl->parent->deps_mutex); - rw_mutex_shared_unlock(&decl->deps_mutex); - - rw_mutex_shared_lock(&decl->type_info_deps_mutex); - rw_mutex_lock(&decl->parent->type_info_deps_mutex); - - for (Type *t : decl->type_info_deps) { - ptr_set_add(&decl->parent->type_info_deps, t); - } - - rw_mutex_unlock(&decl->parent->type_info_deps_mutex); - rw_mutex_shared_unlock(&decl->type_info_deps_mutex); - } - } + add_deps_from_child_to_parent(decl); } gb_internal void check_update_dependency_tree_for_procedures(Checker *c) { diff --git a/src/llvm_backend.cpp b/src/llvm_backend.cpp index 304e5ef36..192e5cc56 100644 --- a/src/llvm_backend.cpp +++ b/src/llvm_backend.cpp @@ -1920,6 +1920,7 @@ gb_internal void lb_generate_code(lbGenerator *gen) { if (!ptr_set_exists(min_dep_set, e)) { continue; } + DeclInfo *decl = decl_info_of_entity(e); if (decl == nullptr) { continue; diff --git a/src/ptr_map.cpp b/src/ptr_map.cpp index c33bf9ffb..89d2cbf9d 100644 --- a/src/ptr_map.cpp +++ b/src/ptr_map.cpp @@ -52,6 +52,7 @@ template gb_internal void map_init (PtrMap< template gb_internal void map_destroy (PtrMap *h); template gb_internal V * map_get (PtrMap *h, K key); template gb_internal void map_set (PtrMap *h, K key, V const &value); +template gb_internal bool map_set_if_not_previously_exists(PtrMap *h, K key, V const &value); // returns true if it previously existed template gb_internal void map_remove (PtrMap *h, K key); template gb_internal void map_clear (PtrMap *h); template gb_internal void map_grow (PtrMap *h); @@ -240,6 +241,34 @@ gb_internal void map_set(PtrMap *h, K key, V const &value) { } } +// returns true if it previously existed +template +gb_internal bool map_set_if_not_previously_exists(PtrMap *h, K key, V const &value) { + MapIndex index; + MapFindResult fr; + if (h->hashes.count == 0) { + map_grow(h); + } + fr = map__find(h, key); + if (fr.entry_index != MAP_SENTINEL) { + return true; + } else { + index = map__add_entry(h, key); + if (fr.entry_prev != MAP_SENTINEL) { + h->entries.data[fr.entry_prev].next = index; + } else { + h->hashes.data[fr.hash_index] = index; + } + } + h->entries.data[index].value = value; + + if (map__full(h)) { + map_grow(h); + } + return false; +} + + template gb_internal void map__erase(PtrMap *h, MapFindResult const &fr) { MapFindResult last; -- cgit v1.2.3 From 6ec014e98066beeff6b95cac95bfda6c459a01a1 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Wed, 11 Jan 2023 17:27:06 +0000 Subject: Make `-threaded-checker` the default not (opt out with `-no-threaded-checker`) --- src/build_settings.cpp | 2 +- src/checker.cpp | 2 +- src/main.cpp | 16 +--------------- 3 files changed, 3 insertions(+), 17 deletions(-) (limited to 'src/checker.cpp') diff --git a/src/build_settings.cpp b/src/build_settings.cpp index 76a73b0e8..609a010de 100644 --- a/src/build_settings.cpp +++ b/src/build_settings.cpp @@ -298,7 +298,7 @@ struct BuildContext { bool linker_map_file; bool use_separate_modules; - bool threaded_checker; + bool no_threaded_checker; bool show_debug_messages; diff --git a/src/checker.cpp b/src/checker.cpp index a2ed73119..4e8d19016 100644 --- a/src/checker.cpp +++ b/src/checker.cpp @@ -5339,7 +5339,7 @@ gb_internal void check_procedure_bodies(Checker *c) { GB_ASSERT(c != nullptr); u32 thread_count = cast(u32)global_thread_pool.threads.count; - if (!build_context.threaded_checker) { + if (build_context.no_threaded_checker) { thread_count = 1; } diff --git a/src/main.cpp b/src/main.cpp index a7e5677e9..4e8dfaf75 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -617,7 +617,6 @@ enum BuildFlagKind { BuildFlag_NoEntryPoint, BuildFlag_UseLLD, BuildFlag_UseSeparateModules, - BuildFlag_ThreadedChecker, BuildFlag_NoThreadedChecker, BuildFlag_ShowDebugMessages, BuildFlag_Vet, @@ -793,7 +792,6 @@ gb_internal bool parse_build_flags(Array args) { add_flag(&build_flags, BuildFlag_NoEntryPoint, str_lit("no-entry-point"), BuildFlagParam_None, Command__does_check &~ Command_test); add_flag(&build_flags, BuildFlag_UseLLD, str_lit("lld"), BuildFlagParam_None, Command__does_build); add_flag(&build_flags, BuildFlag_UseSeparateModules, str_lit("use-separate-modules"), BuildFlagParam_None, Command__does_build); - add_flag(&build_flags, BuildFlag_ThreadedChecker, str_lit("threaded-checker"), BuildFlagParam_None, Command__does_check); add_flag(&build_flags, BuildFlag_NoThreadedChecker, str_lit("no-threaded-checker"), BuildFlagParam_None, Command__does_check); add_flag(&build_flags, BuildFlag_ShowDebugMessages, str_lit("show-debug-messages"), BuildFlagParam_None, Command_all); add_flag(&build_flags, BuildFlag_Vet, str_lit("vet"), BuildFlagParam_None, Command__does_check); @@ -1311,20 +1309,8 @@ gb_internal bool parse_build_flags(Array args) { case BuildFlag_UseSeparateModules: build_context.use_separate_modules = true; break; - case BuildFlag_ThreadedChecker: { - #if defined(DEFAULT_TO_THREADED_CHECKER) - gb_printf_err("-threaded-checker is the default on this platform\n"); - bad_flags = true; - #endif - build_context.threaded_checker = true; - break; - } case BuildFlag_NoThreadedChecker: { - #if !defined(DEFAULT_TO_THREADED_CHECKER) - gb_printf_err("-no-threaded-checker is the default on this platform\n"); - bad_flags = true; - #endif - build_context.threaded_checker = false; + build_context.no_threaded_checker = true; break; } case BuildFlag_ShowDebugMessages: -- cgit v1.2.3 From 7124d541a132fc94b2c66c54bd73eb0d103ce3d3 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Wed, 11 Jan 2023 18:10:27 +0000 Subject: General optimizations --- src/check_type.cpp | 3 ++- src/checker.cpp | 15 ++++++++------- src/checker.hpp | 2 +- src/ptr_map.cpp | 36 ++++++++++++++++++++++++++++++++++++ src/types.cpp | 54 ++++++++++++++++++++++++++++++++++++++++++++++++++++-- 5 files changed, 99 insertions(+), 11 deletions(-) (limited to 'src/checker.cpp') diff --git a/src/check_type.cpp b/src/check_type.cpp index fd4e965d4..0863af967 100644 --- a/src/check_type.cpp +++ b/src/check_type.cpp @@ -2405,7 +2405,8 @@ gb_internal Type *make_soa_struct_internal(CheckerContext *ctx, Ast *array_typ_e } soa_struct->Struct.soa_count = cast(i32)count; - scope = create_scope(ctx->info, ctx->scope, 8); + scope = create_scope(ctx->info, ctx->scope); + string_map_init(&scope->elements, 8); soa_struct->Struct.scope = scope; String params_xyzw[4] = { diff --git a/src/checker.cpp b/src/checker.cpp index 4e8d19016..473af7128 100644 --- a/src/checker.cpp +++ b/src/checker.cpp @@ -220,11 +220,9 @@ gb_internal DeclInfo *make_decl_info(Scope *scope, DeclInfo *parent) { -gb_internal Scope *create_scope(CheckerInfo *info, Scope *parent, isize init_elements_capacity=DEFAULT_SCOPE_CAPACITY) { +gb_internal Scope *create_scope(CheckerInfo *info, Scope *parent) { Scope *s = gb_alloc_item(permanent_allocator(), Scope); s->parent = parent; - string_map_init(&s->elements, init_elements_capacity); - ptr_set_init(&s->imported, 0); if (parent != nullptr && parent != builtin_pkg->scope) { Scope *prev_head_child = parent->head_child.exchange(s, std::memory_order_acq_rel); @@ -246,7 +244,8 @@ gb_internal Scope *create_scope_from_file(CheckerInfo *info, AstFile *f) { GB_ASSERT(f->pkg->scope != nullptr); isize init_elements_capacity = gb_max(DEFAULT_SCOPE_CAPACITY, 2*f->total_file_decl_count); - Scope *s = create_scope(info, f->pkg->scope, init_elements_capacity); + Scope *s = create_scope(info, f->pkg->scope); + string_map_init(&s->elements, init_elements_capacity); s->flags |= ScopeFlag_File; @@ -265,7 +264,8 @@ gb_internal Scope *create_scope_from_package(CheckerContext *c, AstPackage *pkg) } isize init_elements_capacity = gb_max(DEFAULT_SCOPE_CAPACITY, 2*total_pkg_decl_count); - Scope *s = create_scope(c->info, builtin_pkg->scope, init_elements_capacity); + Scope *s = create_scope(c->info, builtin_pkg->scope); + string_map_init(&s->elements, init_elements_capacity); s->flags |= ScopeFlag_Pkg; s->pkg = pkg; @@ -1753,7 +1753,8 @@ gb_internal void add_type_info_type_internal(CheckerContext *c, Type *t) { add_type_info_dependency(c->info, c->decl, t); MUTEX_GUARD_BLOCK(&c->info->type_info_mutex) { - auto found = map_get(&c->info->type_info_map, t); + MapFindResult fr; + auto found = map_try_get(&c->info->type_info_map, t, &fr); if (found != nullptr) { // Types have already been added return; @@ -1777,7 +1778,7 @@ gb_internal void add_type_info_type_internal(CheckerContext *c, Type *t) { ti_index = c->info->type_info_types.count; array_add(&c->info->type_info_types, t); } - map_set(&c->checker->info.type_info_map, t, ti_index); + map_set_internal_from_try_get(&c->checker->info.type_info_map, t, ti_index, fr); if (prev) { // NOTE(bill): If a previous one exists already, no need to continue diff --git a/src/checker.hpp b/src/checker.hpp index 8b8819d97..806eb2e51 100644 --- a/src/checker.hpp +++ b/src/checker.hpp @@ -223,7 +223,7 @@ enum ScopeFlag : i32 { ScopeFlag_ContextDefined = 1<<16, }; -enum { DEFAULT_SCOPE_CAPACITY = 29 }; +enum { DEFAULT_SCOPE_CAPACITY = 32 }; struct Scope { Ast * node; diff --git a/src/ptr_map.cpp b/src/ptr_map.cpp index 89d2cbf9d..598904906 100644 --- a/src/ptr_map.cpp +++ b/src/ptr_map.cpp @@ -192,6 +192,26 @@ gb_internal void map_rehash(PtrMap *h, isize new_count) { template gb_internal V *map_get(PtrMap *h, K key) { + MapIndex hash_index = MAP_SENTINEL; + MapIndex entry_prev = MAP_SENTINEL; + MapIndex entry_index = MAP_SENTINEL; + if (h->hashes.count != 0) { + u32 hash = ptr_map_hash_key(key); + hash_index = cast(MapIndex)(hash & (h->hashes.count-1)); + entry_index = h->hashes.data[hash_index]; + while (entry_index != MAP_SENTINEL) { + auto *entry = &h->entries.data[entry_index]; + if (entry->key == key) { + return &entry->value; + } + entry_prev = entry_index; + entry_index = entry->next; + } + } + return nullptr; +} +template +gb_internal V *map_try_get(PtrMap *h, K key, MapFindResult *fr_) { MapFindResult fr = {MAP_SENTINEL, MAP_SENTINEL, MAP_SENTINEL}; if (h->hashes.count != 0) { u32 hash = ptr_map_hash_key(key); @@ -206,9 +226,25 @@ gb_internal V *map_get(PtrMap *h, K key) { fr.entry_index = entry->next; } } + if (h->hashes.count == 0 || map__full(h)) { + map_grow(h); + } + if (fr_) *fr_ = fr; return nullptr; } + +template +gb_internal void map_set_internal_from_try_get(PtrMap *h, K key, V const &value, MapFindResult const &fr) { + MapIndex index = map__add_entry(h, key); + if (fr.entry_prev != MAP_SENTINEL) { + h->entries.data[fr.entry_prev].next = index; + } else { + h->hashes.data[fr.hash_index] = index; + } + h->entries.data[index].value = value; +} + template gb_internal V &map_must_get(PtrMap *h, K key) { V *ptr = map_get(h, key); diff --git a/src/types.cpp b/src/types.cpp index 99f393cc5..69c1ebe68 100644 --- a/src/types.cpp +++ b/src/types.cpp @@ -2528,9 +2528,58 @@ gb_internal bool lookup_subtype_polymorphic_selection(Type *dst, Type *src, Sele gb_internal bool are_types_identical_internal(Type *x, Type *y, bool check_tuple_names); gb_internal bool are_types_identical(Type *x, Type *y) { + if (x == y) { + return true; + } + + if ((x == nullptr && y != nullptr) || + (x != nullptr && y == nullptr)) { + return false; + } + + if (x->kind == Type_Named) { + Entity *e = x->Named.type_name; + if (e->TypeName.is_type_alias) { + x = x->Named.base; + } + } + if (y->kind == Type_Named) { + Entity *e = y->Named.type_name; + if (e->TypeName.is_type_alias) { + y = y->Named.base; + } + } + if (x->kind != y->kind) { + return false; + } + return are_types_identical_internal(x, y, false); } gb_internal bool are_types_identical_unique_tuples(Type *x, Type *y) { + if (x == y) { + return true; + } + + if (!x | !y) { + return false; + } + + if (x->kind == Type_Named) { + Entity *e = x->Named.type_name; + if (e->TypeName.is_type_alias) { + x = x->Named.base; + } + } + if (y->kind == Type_Named) { + Entity *e = y->Named.type_name; + if (e->TypeName.is_type_alias) { + y = y->Named.base; + } + } + if (x->kind != y->kind) { + return false; + } + return are_types_identical_internal(x, y, true); } @@ -2540,11 +2589,11 @@ gb_internal bool are_types_identical_internal(Type *x, Type *y, bool check_tuple return true; } - if ((x == nullptr && y != nullptr) || - (x != nullptr && y == nullptr)) { + if (!x | !y) { return false; } + #if 0 if (x->kind == Type_Named) { Entity *e = x->Named.type_name; if (e->TypeName.is_type_alias) { @@ -2560,6 +2609,7 @@ gb_internal bool are_types_identical_internal(Type *x, Type *y, bool check_tuple if (x->kind != y->kind) { return false; } + #endif switch (x->kind) { case Type_Generic: -- cgit v1.2.3 From 7f2ef2ac67ca226c365b19b53f2442a2d3002f0e Mon Sep 17 00:00:00 2001 From: gingerBill Date: Wed, 11 Jan 2023 21:52:04 +0000 Subject: Move check for type info above --- src/checker.cpp | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) (limited to 'src/checker.cpp') diff --git a/src/checker.cpp b/src/checker.cpp index 473af7128..053bb0e17 100644 --- a/src/checker.cpp +++ b/src/checker.cpp @@ -1735,10 +1735,6 @@ gb_internal void add_type_info_type(CheckerContext *c, Type *t) { if (build_context.disallow_rtti) { return; } - add_type_info_type_internal(c, t); -} - -gb_internal void add_type_info_type_internal(CheckerContext *c, Type *t) { if (t == nullptr) { return; } @@ -1750,6 +1746,14 @@ gb_internal void add_type_info_type_internal(CheckerContext *c, Type *t) { return; } + add_type_info_type_internal(c, t); +} + +gb_internal void add_type_info_type_internal(CheckerContext *c, Type *t) { + if (t == nullptr) { + return; + } + add_type_info_dependency(c->info, c->decl, t); MUTEX_GUARD_BLOCK(&c->info->type_info_mutex) { -- cgit v1.2.3 From c15db051999e51f5c8ecc45fb084e6fb76c9b5c2 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Thu, 12 Jan 2023 12:41:53 +0000 Subject: Implement `MPSCQueue` --- src/checker.cpp | 8 +++--- src/checker.hpp | 3 +-- src/queue.cpp | 82 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 87 insertions(+), 6 deletions(-) (limited to 'src/checker.cpp') diff --git a/src/checker.cpp b/src/checker.cpp index 053bb0e17..5ffdfab55 100644 --- a/src/checker.cpp +++ b/src/checker.cpp @@ -1161,7 +1161,7 @@ gb_internal void init_checker_info(CheckerInfo *i) { TIME_SECTION("checker info: mpmc queues"); mpmc_init(&i->entity_queue, a, 1<<20); - mpmc_init(&i->definition_queue, a, 1<<20); + mpsc_init(&i->definition_queue, a); //, 1<<20); mpmc_init(&i->required_global_variable_queue, a, 1<<10); mpmc_init(&i->required_foreign_imports_through_force_queue, a, 1<<10); mpmc_init(&i->intrinsics_entry_point_usage, a, 1<<10); // just waste some memory here, even if it probably never used @@ -1182,7 +1182,7 @@ gb_internal void destroy_checker_info(CheckerInfo *i) { array_free(&i->required_foreign_imports_through_force); mpmc_destroy(&i->entity_queue); - mpmc_destroy(&i->definition_queue); + mpsc_destroy(&i->definition_queue); mpmc_destroy(&i->required_global_variable_queue); mpmc_destroy(&i->required_foreign_imports_through_force_queue); @@ -1493,7 +1493,7 @@ gb_internal void add_entity_definition(CheckerInfo *i, Ast *identifier, Entity * GB_ASSERT(entity != nullptr); identifier->Ident.entity = entity; entity->identifier = identifier; - mpmc_enqueue(&i->definition_queue, entity); + mpsc_enqueue(&i->definition_queue, entity); } gb_internal bool redeclaration_error(String name, Entity *prev, Entity *found) { @@ -5583,7 +5583,7 @@ gb_internal void check_add_entities_from_queues(Checker *c) { gb_internal void check_add_definitions_from_queues(Checker *c) { isize cap = c->info.definitions.count + c->info.definition_queue.count.load(std::memory_order_relaxed); array_reserve(&c->info.definitions, cap); - for (Entity *e; mpmc_dequeue(&c->info.definition_queue, &e); /**/) { + for (Entity *e; mpsc_dequeue(&c->info.definition_queue, &e); /**/) { array_add(&c->info.definitions, e); } } diff --git a/src/checker.hpp b/src/checker.hpp index 806eb2e51..356dd1fc8 100644 --- a/src/checker.hpp +++ b/src/checker.hpp @@ -303,7 +303,6 @@ struct UntypedExprInfo { }; typedef PtrMap UntypedExprInfoMap; -typedef MPMCQueue ProcBodyQueue; enum ObjcMsgKind : u32 { ObjcMsg_normal, @@ -380,7 +379,7 @@ struct CheckerInfo { // NOTE(bill): These are actually MPSC queues // TODO(bill): Convert them to be MPSC queues - MPMCQueue definition_queue; + MPSCQueue definition_queue; MPMCQueue entity_queue; MPMCQueue required_global_variable_queue; MPMCQueue required_foreign_imports_through_force_queue; diff --git a/src/queue.cpp b/src/queue.cpp index 8f279bb21..845f87310 100644 --- a/src/queue.cpp +++ b/src/queue.cpp @@ -1,3 +1,85 @@ +template +struct MPSCNode { + std::atomic *> next; + T value; +}; + +// +// Multiple Producer Single Consumer Lockless Queue +// URL: https://www.1024cores.net +// +template +struct MPSCQueue { + std::atomic *> head; + std::atomic *> tail; + std::atomic count; + MPSCNode sentinel; + gbAllocator allocator; +}; + +template gb_internal void mpsc_init (MPSCQueue *q, gbAllocator const &allocator); +template gb_internal void mpsc_destroy(MPSCQueue *q); +template gb_internal isize mpsc_enqueue(MPSCQueue *q, T const &value); +template gb_internal bool mpsc_dequeue(MPSCQueue *q, T *value_); +template gb_internal MPSCNode *mpsc_tail (MPSCQueue *q); + +template +gb_internal void mpsc_init(MPSCQueue *q, gbAllocator const &allocator) { + q->allocator = allocator; + q->count.store(0, std::memory_order_relaxed); + q->head.store(&q->sentinel, std::memory_order_relaxed); + q->tail.store(&q->sentinel, std::memory_order_relaxed); + q->sentinel.next.store(nullptr, std::memory_order_relaxed); +} + +template +gb_internal void mpsc_destroy(MPSCQueue *q) { + while (mpsc_dequeue(q, (T *)nullptr)) {} + // DO NOTHING for the time being +} + + +template +gb_internal MPSCNode *mpsc_alloc_node(MPSCQueue *q, T const &value) { + auto node = gb_alloc_item(q->allocator, MPSCNode); + node->value = value; + return node; +} + +template +gb_internal isize mpsc_enqueue(MPSCQueue *q, MPSCNode *node) { + node->next.store(nullptr, std::memory_order_relaxed); + auto prev = q->head.exchange(node, std::memory_order_acq_rel); + prev->next.store(node, std::memory_order_release); + isize count = 1 + q->count.fetch_add(1, std::memory_order_acq_rel); + return count; +} + +template +gb_internal isize mpsc_enqueue(MPSCQueue *q, T const &value) { + auto node = mpsc_alloc_node(q, value); + return mpsc_enqueue(q, node); +} + + +template +gb_internal bool mpsc_dequeue(MPSCQueue *q, T *value_) { + auto tail = q->tail.load(std::memory_order_relaxed); + auto next = tail->next.load(std::memory_order_relaxed); + if (next) { + q->tail.store(next, std::memory_order_relaxed); + // `tail` is now "dead" and needs to be "freed" + if (*value_) *value_ = next->value; + q->count.fetch_sub(1, std::memory_order_acq_rel); + return true; + } + return false; +} + +//////////////////////////// + + + #define MPMC_CACHE_LINE_SIZE 64 typedef std::atomic MPMCQueueAtomicIdx; -- cgit v1.2.3 From b470ceb4705477ef42a1efc2c8beb5e3ceef2f88 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Thu, 12 Jan 2023 12:59:09 +0000 Subject: Correct `mpsc_dequeue` --- src/check_builtin.cpp | 2 +- src/check_decl.cpp | 2 +- src/checker.cpp | 30 ++++++++++++++++-------------- src/checker.hpp | 8 ++++---- src/common.cpp | 12 +++++++++++- src/ptr_set.cpp | 11 ----------- src/queue.cpp | 5 ++++- 7 files changed, 37 insertions(+), 33 deletions(-) (limited to 'src/checker.cpp') diff --git a/src/check_builtin.cpp b/src/check_builtin.cpp index a7d5536e7..290b1b8cd 100644 --- a/src/check_builtin.cpp +++ b/src/check_builtin.cpp @@ -1687,7 +1687,7 @@ gb_internal bool check_builtin_procedure(CheckerContext *c, Operand *operand, As case BuiltinProc___entry_point: operand->mode = Addressing_NoValue; operand->type = nullptr; - mpmc_enqueue(&c->info->intrinsics_entry_point_usage, call); + mpsc_enqueue(&c->info->intrinsics_entry_point_usage, call); break; case BuiltinProc_DIRECTIVE: diff --git a/src/check_decl.cpp b/src/check_decl.cpp index 8f4534fb9..a21461454 100644 --- a/src/check_decl.cpp +++ b/src/check_decl.cpp @@ -1124,7 +1124,7 @@ gb_internal void check_global_variable_decl(CheckerContext *ctx, Entity *&e, Ast if (ac.require_declaration) { e->flags |= EntityFlag_Require; - mpmc_enqueue(&ctx->info->required_global_variable_queue, e); + mpsc_enqueue(&ctx->info->required_global_variable_queue, e); } diff --git a/src/checker.cpp b/src/checker.cpp index 5ffdfab55..354e033aa 100644 --- a/src/checker.cpp +++ b/src/checker.cpp @@ -1160,11 +1160,11 @@ gb_internal void init_checker_info(CheckerInfo *i) { TIME_SECTION("checker info: mpmc queues"); - mpmc_init(&i->entity_queue, a, 1<<20); - mpsc_init(&i->definition_queue, a); //, 1<<20); - mpmc_init(&i->required_global_variable_queue, a, 1<<10); - mpmc_init(&i->required_foreign_imports_through_force_queue, a, 1<<10); - mpmc_init(&i->intrinsics_entry_point_usage, a, 1<<10); // just waste some memory here, even if it probably never used + mpsc_init(&i->entity_queue, a); // 1<<20); + mpsc_init(&i->definition_queue, a); //); // 1<<20); + mpsc_init(&i->required_global_variable_queue, a); // 1<<10); + mpsc_init(&i->required_foreign_imports_through_force_queue, a); // 1<<10); + mpsc_init(&i->intrinsics_entry_point_usage, a); // 1<<10); // just waste some memory here, even if it probably never used } gb_internal void destroy_checker_info(CheckerInfo *i) { @@ -1181,10 +1181,10 @@ gb_internal void destroy_checker_info(CheckerInfo *i) { array_free(&i->variable_init_order); array_free(&i->required_foreign_imports_through_force); - mpmc_destroy(&i->entity_queue); + mpsc_destroy(&i->entity_queue); mpsc_destroy(&i->definition_queue); - mpmc_destroy(&i->required_global_variable_queue); - mpmc_destroy(&i->required_foreign_imports_through_force_queue); + mpsc_destroy(&i->required_global_variable_queue); + mpsc_destroy(&i->required_foreign_imports_through_force_queue); map_destroy(&i->objc_msgSend_types); string_map_destroy(&i->load_file_cache); @@ -1711,7 +1711,8 @@ gb_internal void add_entity_and_decl_info(CheckerContext *c, Ast *identifier, En is_lazy = (e->flags & EntityFlag_Lazy) == EntityFlag_Lazy; if (!is_lazy) { - queue_count = mpmc_enqueue(&info->entity_queue, e); + GB_ASSERT(e != nullptr); + queue_count = mpsc_enqueue(&info->entity_queue, e); } if (e->token.pos.file_id != 0) { @@ -2375,12 +2376,12 @@ gb_internal void generate_minimum_dependency_set(Checker *c, Entity *start) { } } - for (Entity *e; mpmc_dequeue(&c->info.required_foreign_imports_through_force_queue, &e); /**/) { + for (Entity *e; mpsc_dequeue(&c->info.required_foreign_imports_through_force_queue, &e); /**/) { array_add(&c->info.required_foreign_imports_through_force, e); add_dependency_to_set(c, e); } - for (Entity *e; mpmc_dequeue(&c->info.required_global_variable_queue, &e); /**/) { + for (Entity *e; mpsc_dequeue(&c->info.required_global_variable_queue, &e); /**/) { e->flags |= EntityFlag_Used; add_dependency_to_set(c, e); } @@ -4058,6 +4059,7 @@ gb_internal void check_all_global_entities(Checker *c) { // Don't bother trying for_array(i, c->info.entities) { Entity *e = c->info.entities[i]; + GB_ASSERT(e != nullptr); if (e->flags & EntityFlag_Lazy) { continue; } @@ -4461,7 +4463,7 @@ gb_internal void check_add_foreign_import_decl(CheckerContext *ctx, Ast *decl) { AttributeContext ac = {}; check_decl_attributes(ctx, fl->attributes, foreign_import_decl_attribute, &ac); if (ac.require_declaration) { - mpmc_enqueue(&ctx->info->required_foreign_imports_through_force_queue, e); + mpsc_enqueue(&ctx->info->required_foreign_imports_through_force_queue, e); add_entity_use(ctx, nullptr, e); } if (ac.foreign_import_priority_index != 0) { @@ -5575,7 +5577,7 @@ gb_internal void check_unique_package_names(Checker *c) { gb_internal void check_add_entities_from_queues(Checker *c) { isize cap = c->info.entities.count + c->info.entity_queue.count.load(std::memory_order_relaxed); array_reserve(&c->info.entities, cap); - for (Entity *e; mpmc_dequeue(&c->info.entity_queue, &e); /**/) { + for (Entity *e; mpsc_dequeue(&c->info.entity_queue, &e); /**/) { array_add(&c->info.entities, e); } } @@ -5843,7 +5845,7 @@ gb_internal void check_parsed_files(Checker *c) { if (c->info.intrinsics_entry_point_usage.count > 0) { TIME_SECTION("check intrinsics.__entry_point usage"); Ast *node = nullptr; - while (mpmc_dequeue(&c->info.intrinsics_entry_point_usage, &node)) { + while (mpsc_dequeue(&c->info.intrinsics_entry_point_usage, &node)) { if (c->info.entry_point == nullptr && node != nullptr) { if (node->file()->pkg->kind != Package_Runtime) { warning(node, "usage of intrinsics.__entry_point will be a no-op"); diff --git a/src/checker.hpp b/src/checker.hpp index 356dd1fc8..7c545a716 100644 --- a/src/checker.hpp +++ b/src/checker.hpp @@ -380,11 +380,11 @@ struct CheckerInfo { // NOTE(bill): These are actually MPSC queues // TODO(bill): Convert them to be MPSC queues MPSCQueue definition_queue; - MPMCQueue entity_queue; - MPMCQueue required_global_variable_queue; - MPMCQueue required_foreign_imports_through_force_queue; + MPSCQueue entity_queue; + MPSCQueue required_global_variable_queue; + MPSCQueue required_foreign_imports_through_force_queue; - MPMCQueue intrinsics_entry_point_usage; + MPSCQueue intrinsics_entry_point_usage; BlockingMutex objc_types_mutex; PtrMap objc_msgSend_types; diff --git a/src/common.cpp b/src/common.cpp index 6a6019482..68d99ef02 100644 --- a/src/common.cpp +++ b/src/common.cpp @@ -43,11 +43,21 @@ gb_internal void debugf(char const *fmt, ...); #error Odin on Windows requires a 64-bit build-system. The 'Developer Command Prompt' for VS still defaults to 32-bit shell. The 64-bit shell can be found under the name 'x64 Native Tools Command Prompt' for VS. For more information, please see https://odin-lang.org/docs/install/#for-windows #endif +template +struct TypeIsPointer { + enum {value = false}; +}; + +template +struct TypeIsPointer { + enum {value = true}; +}; + #include "unicode.cpp" #include "array.cpp" #include "threading.cpp" -#include "queue.cpp" #include "common_memory.cpp" +#include "queue.cpp" #include "string.cpp" #include "range_cache.cpp" diff --git a/src/ptr_set.cpp b/src/ptr_set.cpp index 019ede8a5..2b8f38fef 100644 --- a/src/ptr_set.cpp +++ b/src/ptr_set.cpp @@ -1,14 +1,3 @@ -template -struct TypeIsPointer { - enum {value = false}; -}; - -template -struct TypeIsPointer { - enum {value = true}; -}; - - template struct PtrSet { static_assert(TypeIsPointer::value, "PtrSet::T must be a pointer"); diff --git a/src/queue.cpp b/src/queue.cpp index 845f87310..d3fd69c52 100644 --- a/src/queue.cpp +++ b/src/queue.cpp @@ -69,10 +69,13 @@ gb_internal bool mpsc_dequeue(MPSCQueue *q, T *value_) { if (next) { q->tail.store(next, std::memory_order_relaxed); // `tail` is now "dead" and needs to be "freed" - if (*value_) *value_ = next->value; + tail->value = next->value; + T value = tail->value; + if (value_) *value_ = value; q->count.fetch_sub(1, std::memory_order_acq_rel); return true; } + GB_ASSERT(q->count.load(std::memory_order_acquire) == 0); return false; } -- cgit v1.2.3 From cbe3791b422728b3ae692009b32836e30c37c9d5 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Thu, 12 Jan 2023 13:11:17 +0000 Subject: Replace all queues with MPSCQueue where possible --- src/check_decl.cpp | 2 +- src/checker.cpp | 14 +++++++------- src/checker.hpp | 5 ++--- src/parser.hpp | 1 + src/queue.cpp | 24 +++++++++++++++--------- 5 files changed, 26 insertions(+), 20 deletions(-) (limited to 'src/checker.cpp') diff --git a/src/check_decl.cpp b/src/check_decl.cpp index a21461454..f0059424e 100644 --- a/src/check_decl.cpp +++ b/src/check_decl.cpp @@ -1010,7 +1010,7 @@ gb_internal void check_proc_decl(CheckerContext *ctx, Entity *e, DeclInfo *d) { if (ac.deferred_procedure.entity != nullptr) { e->Procedure.deferred_procedure = ac.deferred_procedure; - mpmc_enqueue(&ctx->checker->procs_with_deferred_to_check, e); + mpsc_enqueue(&ctx->checker->procs_with_deferred_to_check, e); } if (is_foreign) { diff --git a/src/checker.cpp b/src/checker.cpp index 354e033aa..8d6462f8b 100644 --- a/src/checker.cpp +++ b/src/checker.cpp @@ -1254,12 +1254,12 @@ gb_internal void init_checker(Checker *c) { c->info.checker = c; TIME_SECTION("init proc queues"); - mpmc_init(&c->procs_with_deferred_to_check, a, 1<<10); + mpsc_init(&c->procs_with_deferred_to_check, a); //, 1<<10); // NOTE(bill): 1 Mi elements should be enough on average array_init(&c->procs_to_check, heap_allocator(), 0, 1<<20); - mpmc_init(&c->global_untyped_queue, a, 1<<20); + mpsc_init(&c->global_untyped_queue, a); // , 1<<20); c->builtin_ctx = make_checker_context(c); } @@ -1270,7 +1270,7 @@ gb_internal void destroy_checker(Checker *c) { destroy_checker_context(&c->builtin_ctx); array_free(&c->procs_to_check); - mpmc_destroy(&c->global_untyped_queue); + mpsc_destroy(&c->global_untyped_queue); } @@ -4647,10 +4647,10 @@ gb_internal GB_COMPARE_PROC(sort_file_by_name) { gb_internal void check_create_file_scopes(Checker *c) { for_array(i, c->parser->packages) { AstPackage *pkg = c->parser->packages[i]; - isize total_pkg_decl_count = 0; gb_sort_array(pkg->files.data, pkg->files.count, sort_file_by_name); + isize total_pkg_decl_count = 0; for_array(j, pkg->files) { AstFile *f = pkg->files[j]; string_map_set(&c->info.files, f->fullpath, f); @@ -5382,14 +5382,14 @@ gb_internal void add_untyped_expressions(CheckerInfo *cinfo, UntypedExprInfoMap Ast *expr = entry.key; ExprInfo *info = entry.value; if (expr != nullptr && info != nullptr) { - mpmc_enqueue(&cinfo->checker->global_untyped_queue, UntypedExprInfo{expr, info}); + mpsc_enqueue(&cinfo->checker->global_untyped_queue, UntypedExprInfo{expr, info}); } } map_clear(untyped); } gb_internal void check_deferred_procedures(Checker *c) { - for (Entity *src = nullptr; mpmc_dequeue(&c->procs_with_deferred_to_check, &src); /**/) { + for (Entity *src = nullptr; mpsc_dequeue(&c->procs_with_deferred_to_check, &src); /**/) { GB_ASSERT(src->kind == Entity_Procedure); DeferredProcedureKind dst_kind = src->Procedure.deferred_procedure.kind; @@ -5831,7 +5831,7 @@ gb_internal void check_parsed_files(Checker *c) { TIME_SECTION("add untyped expression values"); // Add untyped expression values - for (UntypedExprInfo u = {}; mpmc_dequeue(&c->global_untyped_queue, &u); /**/) { + for (UntypedExprInfo u = {}; mpsc_dequeue(&c->global_untyped_queue, &u); /**/) { GB_ASSERT(u.expr != nullptr && u.info != nullptr); if (is_type_typed(u.info->type)) { compiler_error("%s (type %s) is typed!", expr_to_string(u.expr), type_to_string(u.info->type)); diff --git a/src/checker.hpp b/src/checker.hpp index 7c545a716..595618e1d 100644 --- a/src/checker.hpp +++ b/src/checker.hpp @@ -446,11 +446,10 @@ struct Checker { CheckerContext builtin_ctx; - MPMCQueue procs_with_deferred_to_check; + MPSCQueue procs_with_deferred_to_check; Array procs_to_check; - // TODO(bill): Technically MPSC queue - MPMCQueue global_untyped_queue; + MPSCQueue global_untyped_queue; }; diff --git a/src/parser.hpp b/src/parser.hpp index d81194831..6782a9248 100644 --- a/src/parser.hpp +++ b/src/parser.hpp @@ -176,6 +176,7 @@ struct AstPackage { BlockingMutex foreign_files_mutex; BlockingMutex type_and_value_mutex; + // NOTE(bill): This must be a MPMCQueue MPMCQueue exported_entity_queue; // NOTE(bill): Created/set in checker diff --git a/src/queue.cpp b/src/queue.cpp index d3fd69c52..5585b772f 100644 --- a/src/queue.cpp +++ b/src/queue.cpp @@ -10,11 +10,12 @@ struct MPSCNode { // template struct MPSCQueue { + gbAllocator allocator; + std::atomic count; + std::atomic *> head; std::atomic *> tail; - std::atomic count; MPSCNode sentinel; - gbAllocator allocator; }; template gb_internal void mpsc_init (MPSCQueue *q, gbAllocator const &allocator); @@ -29,6 +30,7 @@ gb_internal void mpsc_init(MPSCQueue *q, gbAllocator const &allocator) { q->count.store(0, std::memory_order_relaxed); q->head.store(&q->sentinel, std::memory_order_relaxed); q->tail.store(&q->sentinel, std::memory_order_relaxed); + q->sentinel.next.store(nullptr, std::memory_order_relaxed); } @@ -36,14 +38,20 @@ template gb_internal void mpsc_destroy(MPSCQueue *q) { while (mpsc_dequeue(q, (T *)nullptr)) {} // DO NOTHING for the time being + // free the nodes later } template gb_internal MPSCNode *mpsc_alloc_node(MPSCQueue *q, T const &value) { - auto node = gb_alloc_item(q->allocator, MPSCNode); - node->value = value; - return node; + auto new_node = gb_alloc_item(q->allocator, MPSCNode); + new_node->value = value; + return new_node; +} + +template +gb_internal void mpsc_free_node(MPSCQueue *q, MPSCNode *node) { + // TODO(bill): reuse the free nodes } template @@ -68,10 +76,8 @@ gb_internal bool mpsc_dequeue(MPSCQueue *q, T *value_) { auto next = tail->next.load(std::memory_order_relaxed); if (next) { q->tail.store(next, std::memory_order_relaxed); - // `tail` is now "dead" and needs to be "freed" - tail->value = next->value; - T value = tail->value; - if (value_) *value_ = value; + if (value_) *value_ = next->value; + mpsc_free_node(q, tail); q->count.fetch_sub(1, std::memory_order_acq_rel); return true; } -- cgit v1.2.3 From d6c54148d93a649dbf8d75f97c5c487431b0c8fd Mon Sep 17 00:00:00 2001 From: gingerBill Date: Thu, 12 Jan 2023 15:23:59 +0000 Subject: Minor clean up --- src/checker.cpp | 3 --- src/queue.cpp | 29 ++++++++++++----------------- 2 files changed, 12 insertions(+), 20 deletions(-) (limited to 'src/checker.cpp') diff --git a/src/checker.cpp b/src/checker.cpp index 8d6462f8b..6d73348d1 100644 --- a/src/checker.cpp +++ b/src/checker.cpp @@ -1158,8 +1158,6 @@ gb_internal void init_checker_info(CheckerInfo *i) { string_map_init(&i->load_file_cache); array_init(&i->all_procedures, heap_allocator()); - TIME_SECTION("checker info: mpmc queues"); - mpsc_init(&i->entity_queue, a); // 1<<20); mpsc_init(&i->definition_queue, a); //); // 1<<20); mpsc_init(&i->required_global_variable_queue, a); // 1<<10); @@ -1711,7 +1709,6 @@ gb_internal void add_entity_and_decl_info(CheckerContext *c, Ast *identifier, En is_lazy = (e->flags & EntityFlag_Lazy) == EntityFlag_Lazy; if (!is_lazy) { - GB_ASSERT(e != nullptr); queue_count = mpsc_enqueue(&info->entity_queue, e); } diff --git a/src/queue.cpp b/src/queue.cpp index 5585b772f..05076cfbd 100644 --- a/src/queue.cpp +++ b/src/queue.cpp @@ -11,37 +11,32 @@ struct MPSCNode { template struct MPSCQueue { gbAllocator allocator; - std::atomic count; + MPSCNode sentinel; std::atomic *> head; std::atomic *> tail; - MPSCNode sentinel; + std::atomic count; }; -template gb_internal void mpsc_init (MPSCQueue *q, gbAllocator const &allocator); -template gb_internal void mpsc_destroy(MPSCQueue *q); -template gb_internal isize mpsc_enqueue(MPSCQueue *q, T const &value); -template gb_internal bool mpsc_dequeue(MPSCQueue *q, T *value_); -template gb_internal MPSCNode *mpsc_tail (MPSCQueue *q); +template gb_internal void mpsc_init (MPSCQueue *q, gbAllocator const &allocator); +template gb_internal void mpsc_destroy(MPSCQueue *q); +template gb_internal isize mpsc_enqueue(MPSCQueue *q, T const &value); +template gb_internal bool mpsc_dequeue(MPSCQueue *q, T *value_); template gb_internal void mpsc_init(MPSCQueue *q, gbAllocator const &allocator) { q->allocator = allocator; - q->count.store(0, std::memory_order_relaxed); + q->sentinel.next.store(nullptr, std::memory_order_relaxed); q->head.store(&q->sentinel, std::memory_order_relaxed); q->tail.store(&q->sentinel, std::memory_order_relaxed); - - q->sentinel.next.store(nullptr, std::memory_order_relaxed); + q->count.store(0, std::memory_order_relaxed); } template gb_internal void mpsc_destroy(MPSCQueue *q) { - while (mpsc_dequeue(q, (T *)nullptr)) {} - // DO NOTHING for the time being - // free the nodes later + GB_ASSERT(q->count.load() == 0); } - template gb_internal MPSCNode *mpsc_alloc_node(MPSCQueue *q, T const &value) { auto new_node = gb_alloc_item(q->allocator, MPSCNode); @@ -51,7 +46,7 @@ gb_internal MPSCNode *mpsc_alloc_node(MPSCQueue *q, T const &value) { template gb_internal void mpsc_free_node(MPSCQueue *q, MPSCNode *node) { - // TODO(bill): reuse the free nodes + // TODO(bill): determine a good way to handle the freed nodes rather than letting them leak } template @@ -59,7 +54,7 @@ gb_internal isize mpsc_enqueue(MPSCQueue *q, MPSCNode *node) { node->next.store(nullptr, std::memory_order_relaxed); auto prev = q->head.exchange(node, std::memory_order_acq_rel); prev->next.store(node, std::memory_order_release); - isize count = 1 + q->count.fetch_add(1, std::memory_order_acq_rel); + isize count = 1 + q->count.fetch_add(1, std::memory_order_relaxed); return count; } @@ -77,8 +72,8 @@ gb_internal bool mpsc_dequeue(MPSCQueue *q, T *value_) { if (next) { q->tail.store(next, std::memory_order_relaxed); if (value_) *value_ = next->value; + q->count.fetch_sub(1, std::memory_order_relaxed); mpsc_free_node(q, tail); - q->count.fetch_sub(1, std::memory_order_acq_rel); return true; } GB_ASSERT(q->count.load(std::memory_order_acquire) == 0); -- cgit v1.2.3 From e97bf2ef358eef4499dfee0dc1533bf785d923f2 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Thu, 12 Jan 2023 15:38:23 +0000 Subject: Minimize contention on the deps for decls --- src/check_decl.cpp | 5 ++++- src/check_expr.cpp | 3 +++ src/checker.cpp | 7 +++++++ src/checker.hpp | 4 ++++ 4 files changed, 18 insertions(+), 1 deletion(-) (limited to 'src/checker.cpp') diff --git a/src/check_decl.cpp b/src/check_decl.cpp index f0059424e..e28861fc6 100644 --- a/src/check_decl.cpp +++ b/src/check_decl.cpp @@ -1608,7 +1608,10 @@ gb_internal bool check_proc_body(CheckerContext *ctx_, Token token, DeclInfo *de check_scope_usage(ctx->checker, ctx->scope); - add_deps_from_child_to_parent(decl); + if (decl->entity == nullptr) { + // Only care about nested procedure literals + add_deps_from_child_to_parent(decl); + } return true; } diff --git a/src/check_expr.cpp b/src/check_expr.cpp index c1fa21dc4..52efd9a66 100644 --- a/src/check_expr.cpp +++ b/src/check_expr.cpp @@ -9455,6 +9455,9 @@ gb_internal ExprKind check_expr_base_internal(CheckerContext *c, Operand *o, Ast pl->decl = decl; check_procedure_later(ctx.checker, ctx.file, empty_token, decl, type, pl->body, pl->tags); + mutex_lock(&ctx.checker->nested_proc_lits_mutex); + array_add(&ctx.checker->nested_proc_lits, decl); + mutex_unlock(&ctx.checker->nested_proc_lits_mutex); } check_close_scope(&ctx); diff --git a/src/checker.cpp b/src/checker.cpp index 6d73348d1..7be3c71d1 100644 --- a/src/checker.cpp +++ b/src/checker.cpp @@ -1256,6 +1256,7 @@ gb_internal void init_checker(Checker *c) { // NOTE(bill): 1 Mi elements should be enough on average array_init(&c->procs_to_check, heap_allocator(), 0, 1<<20); + array_init(&c->nested_proc_lits, heap_allocator(), 0, 1<<20); mpsc_init(&c->global_untyped_queue, a); // , 1<<20); @@ -1267,6 +1268,7 @@ gb_internal void destroy_checker(Checker *c) { destroy_checker_context(&c->builtin_ctx); + array_free(&c->nested_proc_lits); array_free(&c->procs_to_check); mpsc_destroy(&c->global_untyped_queue); } @@ -5657,6 +5659,11 @@ gb_internal void check_walk_all_dependencies(DeclInfo *decl) { } gb_internal void check_update_dependency_tree_for_procedures(Checker *c) { + mutex_lock(&c->nested_proc_lits_mutex); + for (DeclInfo *decl : c->nested_proc_lits) { + check_walk_all_dependencies(decl); + } + mutex_unlock(&c->nested_proc_lits_mutex); for (Entity *e : c->info.entities) { DeclInfo *decl = e->decl_info; check_walk_all_dependencies(decl); diff --git a/src/checker.hpp b/src/checker.hpp index 595618e1d..d461b1f6e 100644 --- a/src/checker.hpp +++ b/src/checker.hpp @@ -449,6 +449,10 @@ struct Checker { MPSCQueue procs_with_deferred_to_check; Array procs_to_check; + BlockingMutex nested_proc_lits_mutex; + Array nested_proc_lits; + + MPSCQueue global_untyped_queue; }; -- cgit v1.2.3 From 402a165b60dc9de1ef047b44e47c2d38e5cbed6d Mon Sep 17 00:00:00 2001 From: gingerBill Date: Thu, 12 Jan 2023 16:59:16 +0000 Subject: Correct missing procedures in other build modules which cause a linkage problem --- src/checker.cpp | 2 +- src/llvm_backend.cpp | 11 +++-------- src/llvm_backend_general.cpp | 10 +++++++++- src/llvm_backend_proc.cpp | 14 ++++++++------ 4 files changed, 21 insertions(+), 16 deletions(-) (limited to 'src/checker.cpp') diff --git a/src/checker.cpp b/src/checker.cpp index 7be3c71d1..be3ce1a77 100644 --- a/src/checker.cpp +++ b/src/checker.cpp @@ -5092,7 +5092,7 @@ gb_internal bool check_proc_info(Checker *c, ProcInfo *pi, UntypedExprInfoMap *u if ((e->flags & EntityFlag_Used) == 0) { // NOTE(bill, 2019-08-31): It was never used, don't check // NOTE(bill, 2023-01-02): This may need to be checked again if it is used elsewhere? - pi->decl->proc_checked_state.store(ProcCheckedState_Unchecked); + pi->decl->proc_checked_state.store(ProcCheckedState_Unchecked); return false; } } diff --git a/src/llvm_backend.cpp b/src/llvm_backend.cpp index fef222817..4c954b58f 100644 --- a/src/llvm_backend.cpp +++ b/src/llvm_backend.cpp @@ -1852,6 +1852,7 @@ gb_internal bool lb_generate_code(lbGenerator *gen) { isize worker_count = thread_count-1; bool do_threading = !!(LLVMIsMultithreaded() && USE_SEPARATE_MODULES && MULTITHREAD_OBJECT_GENERATION && worker_count > 0); + do_threading = false; lbModule *default_module = &gen->default_module; CheckerInfo *info = gen->info; @@ -2067,9 +2068,7 @@ gb_internal bool lb_generate_code(lbGenerator *gen) { Type *t = alloc_type_array(t_type_info, max_type_info_count); LLVMValueRef g = LLVMAddGlobal(m->mod, lb_type(m, t), LB_TYPE_INFO_DATA_NAME); LLVMSetInitializer(g, LLVMConstNull(lb_type(m, t))); - if (!USE_SEPARATE_MODULES) { - LLVMSetLinkage(g, LLVMInternalLinkage); - } + LLVMSetLinkage(g, USE_SEPARATE_MODULES ? LLVMExternalLinkage : LLVMInternalLinkage); lbValue value = {}; value.value = g; @@ -2241,11 +2240,7 @@ gb_internal bool lb_generate_code(lbGenerator *gen) { LLVMSetLinkage(g.value, LLVMDLLExportLinkage); LLVMSetDLLStorageClass(g.value, LLVMDLLExportStorageClass); } else if (!is_foreign) { - if (USE_SEPARATE_MODULES) { - LLVMSetLinkage(g.value, LLVMExternalLinkage); - } else { - LLVMSetLinkage(g.value, LLVMInternalLinkage); - } + LLVMSetLinkage(g.value, USE_SEPARATE_MODULES ? LLVMExternalLinkage : LLVMInternalLinkage); } lb_set_linkage_from_entity_flags(m, g.value, e->flags); diff --git a/src/llvm_backend_general.cpp b/src/llvm_backend_general.cpp index dca8c829d..cae3ab1ee 100644 --- a/src/llvm_backend_general.cpp +++ b/src/llvm_backend_general.cpp @@ -2598,7 +2598,15 @@ gb_internal lbValue lb_find_procedure_value_from_entity(lbModule *m, Entity *e) ignore_body = other_module != m; lbProcedure *missing_proc = lb_create_procedure(m, e, ignore_body); - if (!ignore_body) { + if (ignore_body) { + mutex_lock(&other_module->values_mutex); + auto *found = map_get(&other_module->values, e); + if (found == nullptr) { + lbProcedure *missing_proc_in_other_module = lb_create_procedure(other_module, e, false); + array_add(&other_module->missing_procedures_to_check, missing_proc_in_other_module); + } + mutex_unlock(&other_module->values_mutex); + } else { array_add(&m->missing_procedures_to_check, missing_proc); } found = map_get(&m->values, e); diff --git a/src/llvm_backend_proc.cpp b/src/llvm_backend_proc.cpp index c66462bc1..fd654cec9 100644 --- a/src/llvm_backend_proc.cpp +++ b/src/llvm_backend_proc.cpp @@ -190,11 +190,6 @@ gb_internal lbProcedure *lb_create_procedure(lbModule *m, Entity *entity, bool i lb_add_attribute_to_proc(m, p->value, "cold"); } - lbValue proc_value = {p->value, p->type}; - lb_add_entity(m, entity, proc_value); - lb_add_member(m, p->name, proc_value); - lb_add_procedure_value(m, p); - if (p->is_export) { LLVMSetLinkage(p->value, LLVMDLLExportLinkage); LLVMSetDLLStorageClass(p->value, LLVMDLLExportStorageClass); @@ -202,7 +197,9 @@ gb_internal lbProcedure *lb_create_procedure(lbModule *m, Entity *entity, bool i lb_set_wasm_export_attributes(p->value, p->name); } else if (!p->is_foreign) { - if (!USE_SEPARATE_MODULES) { + if (USE_SEPARATE_MODULES) { + LLVMSetLinkage(p->value, LLVMExternalLinkage); + } else { LLVMSetLinkage(p->value, LLVMInternalLinkage); // NOTE(bill): if a procedure is defined in package runtime and uses a custom link name, @@ -316,6 +313,11 @@ gb_internal lbProcedure *lb_create_procedure(lbModule *m, Entity *entity, bool i } } + lbValue proc_value = {p->value, p->type}; + lb_add_entity(m, entity, proc_value); + lb_add_member(m, p->name, proc_value); + lb_add_procedure_value(m, p); + return p; } -- cgit v1.2.3 From 1064bcd0602c9ff86e2a304ecb46b8d86bb07d52 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Fri, 13 Jan 2023 12:12:41 +0000 Subject: Clean up use of `StringMap` --- src/checker.cpp | 11 +++---- src/llvm_backend.cpp | 1 + src/llvm_backend_general.cpp | 1 + src/string_map.cpp | 75 +++++++++++++++++++------------------------- 4 files changed, 39 insertions(+), 49 deletions(-) (limited to 'src/checker.cpp') diff --git a/src/checker.cpp b/src/checker.cpp index be3ce1a77..770e0d473 100644 --- a/src/checker.cpp +++ b/src/checker.cpp @@ -58,11 +58,8 @@ gb_internal void scope_reset(Scope *scope) { rw_mutex_unlock(&scope->mutex); } -gb_internal void scope_reserve(Scope *scope, isize capacity) { - isize cap = 2*capacity; - if (cap > scope->elements.hashes.count) { - string_map_rehash(&scope->elements, capacity); - } +gb_internal void scope_reserve(Scope *scope, isize count) { + string_map_reserve(&scope->elements, 2*count); } gb_internal void entity_graph_node_set_destroy(EntityGraphNodeSet *s) { @@ -4699,7 +4696,7 @@ gb_internal void check_collect_entities_all(Checker *c) { map_init(&wd->untyped); } - for (auto const &entry : c->info.files.entries) { + for (auto const &entry : c->info.files) { AstFile *f = entry.value; thread_pool_add_task(check_collect_entities_all_worker_proc, f); } @@ -4739,7 +4736,7 @@ gb_internal void check_export_entities(Checker *c) { wd->ctx = make_checker_context(c); } - for (auto const &entry : c->info.packages.entries) { + for (auto const &entry : c->info.packages) { AstPackage *pkg = entry.value; thread_pool_add_task(check_export_entities_worker_proc, pkg); } diff --git a/src/llvm_backend.cpp b/src/llvm_backend.cpp index aa49fd055..148511028 100644 --- a/src/llvm_backend.cpp +++ b/src/llvm_backend.cpp @@ -1625,6 +1625,7 @@ gb_internal bool lb_llvm_object_generation(lbGenerator *gen, bool do_threading) String filepath_ll = lb_filepath_ll_for_module(m); String filepath_obj = lb_filepath_obj_for_module(m); + gb_printf_err("%.*s\n", LIT(filepath_obj)); array_add(&gen->output_object_paths, filepath_obj); array_add(&gen->output_temp_paths, filepath_ll); diff --git a/src/llvm_backend_general.cpp b/src/llvm_backend_general.cpp index 15cb3f2be..c4f6ccc91 100644 --- a/src/llvm_backend_general.cpp +++ b/src/llvm_backend_general.cpp @@ -148,6 +148,7 @@ gb_internal bool lb_init_generator(lbGenerator *gen, Checker *c) { map_set(&gen->modules, cast(void *)pkg, m); lb_init_module(m, c); #else + // NOTE(bill): Probably per file is not a good idea, so leave this for later for (AstFile *file : pkg->files) { auto m = gb_alloc_item(permanent_allocator(), lbModule); m->file = file; diff --git a/src/string_map.cpp b/src/string_map.cpp index facd00bb0..f7ecc4acc 100644 --- a/src/string_map.cpp +++ b/src/string_map.cpp @@ -35,8 +35,6 @@ struct StringMapEntry { template struct StringMap { - using K = String; - using V = T; Slice hashes; Array > entries; }; @@ -53,15 +51,14 @@ template gb_internal T & string_map_must_get (StringMap template gb_internal T & string_map_must_get (StringMap *h, String const &key); template gb_internal T & string_map_must_get (StringMap *h, StringHashKey const &key); -template gb_internal void string_map_set (StringMap *h, StringHashKey const &key, T const &value); -template gb_internal void string_map_set (StringMap *h, String const &key, T const &value); template gb_internal void string_map_set (StringMap *h, char const *key, T const &value); +template gb_internal void string_map_set (StringMap *h, String const &key, T const &value); +template gb_internal void string_map_set (StringMap *h, StringHashKey const &key, T const &value); -template gb_internal void string_map_remove (StringMap *h, StringHashKey const &key); +// template gb_internal void string_map_remove (StringMap *h, StringHashKey const &key); template gb_internal void string_map_clear (StringMap *h); template gb_internal void string_map_grow (StringMap *h); -template gb_internal void string_map_rehash (StringMap *h, isize new_count); -template gb_internal void string_map_reserve (StringMap *h, isize cap); +template gb_internal void string_map_reserve (StringMap *h, isize new_count); gb_internal gbAllocator string_map_allocator(void) { return heap_allocator(); @@ -137,7 +134,7 @@ gb_internal b32 string_map__full(StringMap *h) { template gb_inline void string_map_grow(StringMap *h) { isize new_count = gb_max(h->hashes.count<<1, 16); - string_map_rehash(h, new_count); + string_map_reserve(h, new_count); } @@ -172,12 +169,6 @@ gb_internal void string_map_reserve(StringMap *h, isize cap) { string_map_reset_entries(h); } - -template -gb_internal void string_map_rehash(StringMap *h, isize new_count) { - string_map_reserve(h, new_count); -} - template gb_internal T *string_map_get(StringMap *h, StringHashKey const &key) { MapFindResult fr = {MAP_SENTINEL, MAP_SENTINEL, MAP_SENTINEL}; @@ -259,34 +250,34 @@ gb_internal gb_inline void string_map_set(StringMap *h, char const *key, T co } -template -gb_internal void string_map__erase(StringMap *h, MapFindResult const &fr) { - MapFindResult last; - if (fr.entry_prev == MAP_SENTINEL) { - h->hashes.data[fr.hash_index] = h->entries.data[fr.entry_index].next; - } else { - h->entries.data[fr.entry_prev].next = h->entries.data[fr.entry_index].next; - } - if (fr.entry_index == h->entries.count-1) { - array_pop(&h->entries); - return; - } - h->entries.data[fr.entry_index] = h->entries.data[h->entries.count-1]; - last = string_map__find(h, h->entries.data[fr.entry_index].key); - if (last.entry_prev != MAP_SENTINEL) { - h->entries.data[last.entry_prev].next = fr.entry_index; - } else { - h->hashes.data[last.hash_index] = fr.entry_index; - } -} - -template -gb_internal void string_map_remove(StringMap *h, StringHashKey const &key) { - MapFindResult fr = string_map__find(h, key); - if (fr.entry_index != MAP_SENTINEL) { - string_map__erase(h, fr); - } -} +// template +// gb_internal void string_map__erase(StringMap *h, MapFindResult const &fr) { +// MapFindResult last; +// if (fr.entry_prev == MAP_SENTINEL) { +// h->hashes.data[fr.hash_index] = h->entries.data[fr.entry_index].next; +// } else { +// h->entries.data[fr.entry_prev].next = h->entries.data[fr.entry_index].next; +// } +// if (fr.entry_index == h->entries.count-1) { +// array_pop(&h->entries); +// return; +// } +// h->entries.data[fr.entry_index] = h->entries.data[h->entries.count-1]; +// last = string_map__find(h, h->entries.data[fr.entry_index].key); +// if (last.entry_prev != MAP_SENTINEL) { +// h->entries.data[last.entry_prev].next = fr.entry_index; +// } else { +// h->hashes.data[last.hash_index] = fr.entry_index; +// } +// } + +// template +// gb_internal void string_map_remove(StringMap *h, StringHashKey const &key) { +// MapFindResult fr = string_map__find(h, key); +// if (fr.entry_index != MAP_SENTINEL) { +// string_map__erase(h, fr); +// } +// } template gb_internal gb_inline void string_map_clear(StringMap *h) { -- cgit v1.2.3 From 1ab90de4931f07ea61b1195de602f282a853568b Mon Sep 17 00:00:00 2001 From: gingerBill Date: Sat, 14 Jan 2023 12:33:42 +0000 Subject: Minimize `StringMap` structure usage --- src/check_expr.cpp | 2 +- src/check_stmt.cpp | 4 +- src/checker.cpp | 10 +- src/common_memory.cpp | 7 +- src/docs.cpp | 4 +- src/docs_writer.cpp | 4 +- src/llvm_backend.cpp | 4 +- src/llvm_backend_general.cpp | 4 +- src/string_map.cpp | 226 ++++++++++++++++++++++++------------------- 9 files changed, 146 insertions(+), 119 deletions(-) (limited to 'src/checker.cpp') diff --git a/src/check_expr.cpp b/src/check_expr.cpp index 52efd9a66..ff74a2547 100644 --- a/src/check_expr.cpp +++ b/src/check_expr.cpp @@ -234,7 +234,7 @@ gb_internal void check_did_you_mean_type(String const &name, Slice con gb_internal void check_did_you_mean_scope(String const &name, Scope *scope, char const *prefix = "") { ERROR_BLOCK(); - DidYouMeanAnswers d = did_you_mean_make(heap_allocator(), scope->elements.entries.count, name); + DidYouMeanAnswers d = did_you_mean_make(heap_allocator(), scope->elements.count, name); defer (did_you_mean_destroy(&d)); rw_mutex_shared_lock(&scope->mutex); diff --git a/src/check_stmt.cpp b/src/check_stmt.cpp index a2a688b13..21df1d0ea 100644 --- a/src/check_stmt.cpp +++ b/src/check_stmt.cpp @@ -626,7 +626,7 @@ gb_internal bool check_using_stmt_entity(CheckerContext *ctx, AstUsingStmt *us, defer (rw_mutex_unlock(&scope->mutex)); for (auto const &entry : scope->elements) { - String name = entry.key.string; + String name = entry.key; Entity *decl = entry.value; if (!is_entity_exported(decl)) continue; @@ -1323,7 +1323,7 @@ gb_internal void check_block_stmt_for_errors(CheckerContext *ctx, Ast *body) { ast_node(bs, BlockStmt, body); // NOTE(bill, 2020-09-23): This logic is prevent common erros with block statements // e.g. if cond { x := 123; } // this is an error - if (bs->scope != nullptr && bs->scope->elements.entries.count > 0) { + if (bs->scope != nullptr && bs->scope->elements.count > 0) { if (bs->scope->parent->node != nullptr) { switch (bs->scope->parent->node->kind) { case Ast_IfStmt: diff --git a/src/checker.cpp b/src/checker.cpp index 770e0d473..39a132060 100644 --- a/src/checker.cpp +++ b/src/checker.cpp @@ -765,7 +765,7 @@ gb_internal AstPackage *get_core_package(CheckerInfo *info, String name) { gb_printf_err("Fullpath: %.*s\n", LIT(path)); for (auto const &entry : info->packages) { - gb_printf_err("%.*s\n", LIT(entry.key.string)); + gb_printf_err("%.*s\n", LIT(entry.key)); } GB_ASSERT_MSG(found != nullptr, "Missing core package %.*s", LIT(name)); } @@ -3891,16 +3891,16 @@ gb_internal bool correct_single_type_alias(CheckerContext *c, Entity *e) { } gb_internal bool correct_type_alias_in_scope_backwards(CheckerContext *c, Scope *s) { - isize n = s->elements.entries.count; bool correction = false; - for (isize i = n-1; i >= 0; i--) { + u32 n = s->elements.count; + for (u32 i = n-1; i < n; i--) { correction |= correct_single_type_alias(c, s->elements.entries[i].value); } return correction; } gb_internal bool correct_type_alias_in_scope_forwards(CheckerContext *c, Scope *s) { - isize n = s->elements.entries.count; bool correction = false; + u32 n = s->elements.count; for (isize i = 0; i < n; i++) { correction |= correct_single_type_alias(c, s->elements.entries[i].value); } @@ -5539,7 +5539,7 @@ gb_internal void check_deferred_procedures(Checker *c) { gb_internal void check_unique_package_names(Checker *c) { StringMap pkgs = {}; // Key: package name - string_map_init(&pkgs, 2*c->info.packages.entries.count); + string_map_init(&pkgs, 2*c->info.packages.count); defer (string_map_destroy(&pkgs)); for (auto const &entry : c->info.packages) { diff --git a/src/common_memory.cpp b/src/common_memory.cpp index 7d5d1f27a..22b91d8cb 100644 --- a/src/common_memory.cpp +++ b/src/common_memory.cpp @@ -509,15 +509,15 @@ gb_internal GB_ALLOCATOR_PROC(heap_allocator_proc) { template -gb_internal void resize_array_raw(T **array, gbAllocator const &a, isize old_count, isize new_count) { +gb_internal isize resize_array_raw(T **array, gbAllocator const &a, isize old_count, isize new_count) { GB_ASSERT(new_count >= 0); if (new_count == 0) { gb_free(a, *array); *array = nullptr; - return; + return 0; } if (new_count < old_count) { - return; + return old_count; } isize old_size = old_count * gb_size_of(T); isize new_size = new_count * gb_size_of(T); @@ -525,5 +525,6 @@ gb_internal void resize_array_raw(T **array, gbAllocator const &a, isize old_cou auto new_data = cast(T *)gb_resize_align(a, *array, old_size, new_size, alignment); GB_ASSERT(new_data != nullptr); *array = new_data; + return new_count; } diff --git a/src/docs.cpp b/src/docs.cpp index b1efa2b46..54bb0c7a2 100644 --- a/src/docs.cpp +++ b/src/docs.cpp @@ -210,7 +210,7 @@ gb_internal void print_doc_package(CheckerInfo *info, AstPackage *pkg) { } if (pkg->scope != nullptr) { - auto entities = array_make(heap_allocator(), 0, pkg->scope->elements.entries.count); + auto entities = array_make(heap_allocator(), 0, pkg->scope->elements.count); defer (array_free(&entities)); for (auto const &entry : pkg->scope->elements) { Entity *e = entry.value; @@ -348,7 +348,7 @@ gb_internal void generate_documentation(Checker *c) { odin_doc_write(info, output_file_path); } else { - auto pkgs = array_make(permanent_allocator(), 0, info->packages.entries.count); + auto pkgs = array_make(permanent_allocator(), 0, info->packages.count); for (auto const &entry : info->packages) { AstPackage *pkg = entry.value; if (build_context.cmd_doc_flags & CmdDocFlag_AllPackages) { diff --git a/src/docs_writer.cpp b/src/docs_writer.cpp index 2aefe29eb..ea0946153 100644 --- a/src/docs_writer.cpp +++ b/src/docs_writer.cpp @@ -977,7 +977,7 @@ gb_internal OdinDocArray odin_doc_add_pkg_entries(OdinDocWrit defer (array_free(&entries)); for (auto const &element : pkg->scope->elements) { - String name = element.key.string; + String name = element.key; Entity *e = element.value; switch (e->kind) { case Entity_Invalid: @@ -1016,7 +1016,7 @@ gb_internal OdinDocArray odin_doc_add_pkg_entries(OdinDocWrit gb_internal void odin_doc_write_docs(OdinDocWriter *w) { - auto pkgs = array_make(heap_allocator(), 0, w->info->packages.entries.count); + auto pkgs = array_make(heap_allocator(), 0, w->info->packages.count); defer (array_free(&pkgs)); for (auto const &entry : w->info->packages) { AstPackage *pkg = entry.value; diff --git a/src/llvm_backend.cpp b/src/llvm_backend.cpp index 148511028..6cd224324 100644 --- a/src/llvm_backend.cpp +++ b/src/llvm_backend.cpp @@ -1035,14 +1035,14 @@ gb_internal void lb_finalize_objc_names(lbProcedure *p) { LLVMSetLinkage(p->value, LLVMInternalLinkage); lb_begin_procedure_body(p); for (auto const &entry : m->objc_classes) { - String name = entry.key.string; + 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); } for (auto const &entry : m->objc_selectors) { - String name = entry.key.string; + 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); diff --git a/src/llvm_backend_general.cpp b/src/llvm_backend_general.cpp index c4f6ccc91..e7c9a0985 100644 --- a/src/llvm_backend_general.cpp +++ b/src/llvm_backend_general.cpp @@ -130,8 +130,8 @@ gb_internal bool lb_init_generator(lbGenerator *gen, Checker *c) { gen->info = &c->info; - map_init(&gen->modules, gen->info->packages.entries.count*2); - map_init(&gen->modules_through_ctx, gen->info->packages.entries.count*2); + map_init(&gen->modules, gen->info->packages.count*2); + map_init(&gen->modules_through_ctx, gen->info->packages.count*2); map_init(&gen->anonymous_proc_lits, 1024); diff --git a/src/string_map.cpp b/src/string_map.cpp index f7ecc4acc..3bd08d09f 100644 --- a/src/string_map.cpp +++ b/src/string_map.cpp @@ -1,3 +1,5 @@ +GB_STATIC_ASSERT(sizeof(MapIndex) == sizeof(u32)); + struct StringHashKey { u32 hash; String string; @@ -9,101 +11,108 @@ struct StringHashKey { return this->string; } }; +gb_internal gb_inline u32 string_hash(String const &s) { + return fnv32a(s.text, s.len) & 0x7fffffff; +} gb_internal gb_inline StringHashKey string_hash_string(String const &s) { StringHashKey hash_key = {}; - hash_key.hash = fnv32a(s.text, s.len); + hash_key.hash = string_hash(s); hash_key.string = s; return hash_key; } - -gb_internal gb_inline bool string_hash_key_equal(StringHashKey const &a, StringHashKey const &b) { - if (a.hash == b.hash) { - // NOTE(bill): If two string's hashes collide, compare the strings themselves - return a.string == b.string; - } - return false; -} - template struct StringMapEntry { - StringHashKey key; + String key; + u32 hash; MapIndex next; T value; }; template struct StringMap { - Slice hashes; - Array > entries; + MapIndex * hashes; + usize hashes_count; + StringMapEntry *entries; + u32 count; + u32 entries_capacity; }; -template gb_internal void string_map_init (StringMap *h, isize capacity = 16); -template gb_internal void string_map_destroy (StringMap *h); +template gb_internal void string_map_init (StringMap *h, usize capacity = 16); +template gb_internal void string_map_destroy (StringMap *h); -template gb_internal T * string_map_get (StringMap *h, char const *key); -template gb_internal T * string_map_get (StringMap *h, String const &key); -template gb_internal T * string_map_get (StringMap *h, StringHashKey const &key); +template gb_internal T * string_map_get (StringMap *h, char const *key); +template gb_internal T * string_map_get (StringMap *h, String const &key); +template gb_internal T * string_map_get (StringMap *h, StringHashKey const &key); -template gb_internal T & string_map_must_get (StringMap *h, char const *key); -template gb_internal T & string_map_must_get (StringMap *h, String const &key); -template gb_internal T & string_map_must_get (StringMap *h, StringHashKey const &key); +template gb_internal T & string_map_must_get(StringMap *h, char const *key); +template gb_internal T & string_map_must_get(StringMap *h, String const &key); +template gb_internal T & string_map_must_get(StringMap *h, StringHashKey const &key); -template gb_internal void string_map_set (StringMap *h, char const *key, T const &value); -template gb_internal void string_map_set (StringMap *h, String const &key, T const &value); -template gb_internal void string_map_set (StringMap *h, StringHashKey const &key, T const &value); +template gb_internal void string_map_set (StringMap *h, char const *key, T const &value); +template gb_internal void string_map_set (StringMap *h, String const &key, T const &value); +template gb_internal void string_map_set (StringMap *h, StringHashKey const &key, T const &value); -// template gb_internal void string_map_remove (StringMap *h, StringHashKey const &key); -template gb_internal void string_map_clear (StringMap *h); -template gb_internal void string_map_grow (StringMap *h); -template gb_internal void string_map_reserve (StringMap *h, isize new_count); +// template gb_internal void string_map_remove (StringMap *h, StringHashKey const &key); +template gb_internal void string_map_clear (StringMap *h); +template gb_internal void string_map_grow (StringMap *h); +template gb_internal void string_map_reserve (StringMap *h, usize new_count); gb_internal gbAllocator string_map_allocator(void) { return heap_allocator(); } template -gb_internal gb_inline void string_map_init(StringMap *h, isize capacity) { +gb_internal gb_inline void string_map_init(StringMap *h, usize capacity) { capacity = next_pow2_isize(capacity); - slice_init(&h->hashes, string_map_allocator(), capacity); - array_init(&h->entries, string_map_allocator(), 0, capacity); - for (isize i = 0; i < capacity; i++) { - h->hashes.data[i] = MAP_SENTINEL; - } + string_map_reserve(h, capacity); } template gb_internal gb_inline void string_map_destroy(StringMap *h) { - if (h->entries.allocator.proc == nullptr) { - h->entries.allocator = string_map_allocator(); - } - slice_free(&h->hashes, h->entries.allocator); - array_free(&h->entries); + gb_free(string_map_allocator(), h->hashes); + gb_free(string_map_allocator(), h->entries); } + +template +gb_internal void string_map__resize_hashes(StringMap *h, usize count) { + h->hashes_count = cast(u32)resize_array_raw(&h->hashes, string_map_allocator(), h->hashes_count, count); +} + + +template +gb_internal void string_map__reserve_entries(StringMap *h, usize capacity) { + h->entries_capacity = cast(u32)resize_array_raw(&h->entries, string_map_allocator(), h->entries_capacity, capacity); +} + + template -gb_internal MapIndex string_map__add_entry(StringMap *h, StringHashKey const &key) { +gb_internal MapIndex string_map__add_entry(StringMap *h, u32 hash, String const &key) { StringMapEntry e = {}; e.key = key; + e.hash = hash; e.next = MAP_SENTINEL; - array_add(&h->entries, e); - return cast(MapIndex)(h->entries.count-1); + string_map__reserve_entries(h, h->count+1); + h->entries[h->count++] = e; + return cast(MapIndex)(h->count-1); } template -gb_internal MapFindResult string_map__find(StringMap *h, StringHashKey const &key) { +gb_internal MapFindResult string_map__find(StringMap *h, u32 hash, String const &key) { MapFindResult fr = {MAP_SENTINEL, MAP_SENTINEL, MAP_SENTINEL}; - if (h->hashes.count != 0) { - fr.hash_index = cast(MapIndex)(key.hash & (h->hashes.count-1)); - fr.entry_index = h->hashes.data[fr.hash_index]; + if (h->hashes_count != 0) { + fr.hash_index = cast(MapIndex)(hash & (h->hashes_count-1)); + fr.entry_index = h->hashes[fr.hash_index]; while (fr.entry_index != MAP_SENTINEL) { - if (string_hash_key_equal(h->entries.data[fr.entry_index].key, key)) { + auto *entry = &h->entries[fr.entry_index]; + if (entry->hash == hash && entry->key == key) { return fr; } fr.entry_prev = fr.entry_index; - fr.entry_index = h->entries.data[fr.entry_index].next; + fr.entry_index = entry->next; } } return fr; @@ -112,15 +121,16 @@ gb_internal MapFindResult string_map__find(StringMap *h, StringHashKey const template gb_internal MapFindResult string_map__find_from_entry(StringMap *h, StringMapEntry *e) { MapFindResult fr = {MAP_SENTINEL, MAP_SENTINEL, MAP_SENTINEL}; - if (h->hashes.count != 0) { - fr.hash_index = cast(MapIndex)(e->key.hash & (h->hashes.count-1)); - fr.entry_index = h->hashes.data[fr.hash_index]; + if (h->hashes_count != 0) { + fr.hash_index = cast(MapIndex)(e->hash & (h->hashes_count-1)); + fr.entry_index = h->hashes[fr.hash_index]; while (fr.entry_index != MAP_SENTINEL) { - if (&h->entries.data[fr.entry_index] == e) { + auto *entry = &h->entries[fr.entry_index]; + if (entry == e) { return fr; } fr.entry_prev = fr.entry_index; - fr.entry_index = h->entries.data[fr.entry_index].next; + fr.entry_index = entry->next; } } return fr; @@ -128,24 +138,24 @@ gb_internal MapFindResult string_map__find_from_entry(StringMap *h, StringMap template gb_internal b32 string_map__full(StringMap *h) { - return 0.75f * h->hashes.count <= h->entries.count; + return 0.75f * h->hashes_count <= h->count; } template gb_inline void string_map_grow(StringMap *h) { - isize new_count = gb_max(h->hashes.count<<1, 16); + isize new_count = gb_max(h->hashes_count<<1, 16); string_map_reserve(h, new_count); } template gb_internal void string_map_reset_entries(StringMap *h) { - for (isize i = 0; i < h->hashes.count; i++) { - h->hashes.data[i] = MAP_SENTINEL; + for (u32 i = 0; i < h->hashes_count; i++) { + h->hashes[i] = MAP_SENTINEL; } - for (isize i = 0; i < h->entries.count; i++) { + for (isize i = 0; i < h->count; i++) { MapFindResult fr; - StringMapEntry *e = &h->entries.data[i]; + StringMapEntry *e = &h->entries[i]; e->next = MAP_SENTINEL; fr = string_map__find_from_entry(h, e); if (fr.entry_prev == MAP_SENTINEL) { @@ -157,27 +167,24 @@ gb_internal void string_map_reset_entries(StringMap *h) { } template -gb_internal void string_map_reserve(StringMap *h, isize cap) { - if (h->entries.allocator.proc == nullptr) { - h->entries.allocator = string_map_allocator(); - } - array_reserve(&h->entries, cap); - if (h->entries.count*2 < h->hashes.count) { +gb_internal void string_map_reserve(StringMap *h, usize cap) { + if (h->count*2 < h->hashes_count) { return; } - slice_resize(&h->hashes, h->entries.allocator, cap*2); + string_map__reserve_entries(h, cap); + string_map__resize_hashes(h, cap*2); string_map_reset_entries(h); } template -gb_internal T *string_map_get(StringMap *h, StringHashKey const &key) { +gb_internal T *string_map_get(StringMap *h, u32 hash, String const &key) { MapFindResult fr = {MAP_SENTINEL, MAP_SENTINEL, MAP_SENTINEL}; - if (h->hashes.count != 0) { - fr.hash_index = cast(MapIndex)(key.hash & (h->hashes.count-1)); - fr.entry_index = h->hashes.data[fr.hash_index]; + if (h->hashes_count != 0) { + fr.hash_index = cast(MapIndex)(hash & (h->hashes_count-1)); + fr.entry_index = h->hashes[fr.hash_index]; while (fr.entry_index != MAP_SENTINEL) { - auto *entry = &h->entries.data[fr.entry_index]; - if (string_hash_key_equal(entry->key, key)) { + auto *entry = &h->entries[fr.entry_index]; + if (entry->hash == hash && entry->key == key) { return &entry->value; } fr.entry_prev = fr.entry_index; @@ -187,52 +194,65 @@ gb_internal T *string_map_get(StringMap *h, StringHashKey const &key) { return nullptr; } + +template +gb_internal gb_inline T *string_map_get(StringMap *h, StringHashKey const &key) { + return string_map_get(h, key.hash, key.string); +} + template gb_internal gb_inline T *string_map_get(StringMap *h, String const &key) { - return string_map_get(h, string_hash_string(key)); + return string_map_get(h, string_hash(key), key); } template gb_internal gb_inline T *string_map_get(StringMap *h, char const *key) { - return string_map_get(h, string_hash_string(make_string_c(key))); + String k = make_string_c(key); + return string_map_get(h, string_hash(k), k); } template -gb_internal T &string_map_must_get(StringMap *h, StringHashKey const &key) { - isize index = string_map__find(h, key).entry_index; +gb_internal T &string_map_must_get(StringMap *h, u32 hash, String const &key) { + isize index = string_map__find(h, hash, key).entry_index; GB_ASSERT(index != MAP_SENTINEL); - return h->entries.data[index].value; + return h->entries[index].value; +} + +template +gb_internal T &string_map_must_get(StringMap *h, StringHashKey const &key) { + return string_map_must_get(h, key.hash, key.string); } template gb_internal gb_inline T &string_map_must_get(StringMap *h, String const &key) { - return string_map_must_get(h, string_hash_string(key)); + return string_map_must_get(h, string_hash(key), key); } template gb_internal gb_inline T &string_map_must_get(StringMap *h, char const *key) { - return string_map_must_get(h, string_hash_string(make_string_c(key))); + String k = make_string_c(key); + return string_map_must_get(h, string_hash(k), k); } template -gb_internal void string_map_set(StringMap *h, StringHashKey const &key, T const &value) { +gb_internal void string_map_set(StringMap *h, u32 hash, String const &key, T const &value) { MapIndex index; MapFindResult fr; - if (h->hashes.count == 0) { + if (h->hashes_count == 0) { string_map_grow(h); } - fr = string_map__find(h, key); + fr = string_map__find(h, hash, key); if (fr.entry_index != MAP_SENTINEL) { index = fr.entry_index; } else { - index = string_map__add_entry(h, key); + index = string_map__add_entry(h, hash, key); if (fr.entry_prev != MAP_SENTINEL) { - h->entries.data[fr.entry_prev].next = index; + h->entries[fr.entry_prev].next = index; } else { - h->hashes.data[fr.hash_index] = index; + h->hashes[fr.hash_index] = index; } } - h->entries.data[index].value = value; + h->entries[index].value = value; if (string_map__full(h)) { string_map_grow(h); @@ -249,25 +269,31 @@ gb_internal gb_inline void string_map_set(StringMap *h, char const *key, T co string_map_set(h, string_hash_string(make_string_c(key)), value); } +template +gb_internal gb_inline void string_map_set(StringMap *h, StringHashKey const &key, T const &value) { + string_map_set(h, key.hash, key.string, value); +} + + // template // gb_internal void string_map__erase(StringMap *h, MapFindResult const &fr) { // MapFindResult last; // if (fr.entry_prev == MAP_SENTINEL) { -// h->hashes.data[fr.hash_index] = h->entries.data[fr.entry_index].next; +// h->hashes[fr.hash_index] = h->entries[fr.entry_index].next; // } else { -// h->entries.data[fr.entry_prev].next = h->entries.data[fr.entry_index].next; +// h->entries[fr.entry_prev].next = h->entries[fr.entry_index].next; // } -// if (fr.entry_index == h->entries.count-1) { +// if (fr.entry_index == h->count-1) { // array_pop(&h->entries); // return; // } -// h->entries.data[fr.entry_index] = h->entries.data[h->entries.count-1]; -// last = string_map__find(h, h->entries.data[fr.entry_index].key); +// h->entries[fr.entry_index] = h->entries[h->count-1]; +// last = string_map__find(h, h->entries[fr.entry_index].key); // if (last.entry_prev != MAP_SENTINEL) { -// h->entries.data[last.entry_prev].next = fr.entry_index; +// h->entries[last.entry_prev].next = fr.entry_index; // } else { -// h->hashes.data[last.hash_index] = fr.entry_index; +// h->hashes[last.hash_index] = fr.entry_index; // } // } @@ -281,9 +307,9 @@ gb_internal gb_inline void string_map_set(StringMap *h, char const *key, T co template gb_internal gb_inline void string_map_clear(StringMap *h) { - array_clear(&h->entries); - for (isize i = 0; i < h->hashes.count; i++) { - h->hashes.data[i] = MAP_SENTINEL; + h->count = 0; + for (u32 i = 0; i < h->hashes_count; i++) { + h->hashes[i] = MAP_SENTINEL; } } @@ -291,20 +317,20 @@ gb_internal gb_inline void string_map_clear(StringMap *h) { template gb_internal StringMapEntry *begin(StringMap &m) noexcept { - return m.entries.data; + return m.entries; } template gb_internal StringMapEntry const *begin(StringMap const &m) noexcept { - return m.entries.data; + return m.entries; } template gb_internal StringMapEntry *end(StringMap &m) { - return m.entries.data + m.entries.count; + return m.entries + m.count; } template gb_internal StringMapEntry const *end(StringMap const &m) noexcept { - return m.entries.data + m.entries.count; + return m.entries + m.count; } \ No newline at end of file -- cgit v1.2.3 From 518f30e52307e12fe184c34f0da8f197b976ced5 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Sat, 14 Jan 2023 13:23:17 +0000 Subject: Bring `PtrMap` inline with `StringMap` --- src/check_type.cpp | 12 ++-- src/checker.cpp | 8 +-- src/docs_writer.cpp | 4 +- src/llvm_backend.cpp | 10 +-- src/ptr_map.cpp | 175 +++++++++++++++++++++++++++------------------------ src/queue.cpp | 25 ++++---- src/string_map.cpp | 9 +-- 7 files changed, 126 insertions(+), 117 deletions(-) (limited to 'src/checker.cpp') diff --git a/src/check_type.cpp b/src/check_type.cpp index 9ce6585f2..0bd9af15f 100644 --- a/src/check_type.cpp +++ b/src/check_type.cpp @@ -2201,18 +2201,18 @@ gb_internal Type *make_optional_ok_type(Type *value, bool typed) { // IMPORTANT NOTE(bill): This must match the definition in dynamic_map_internal.odin enum : i64 { - MAP_CACHE_LINE_LOG2 = 6, - MAP_CACHE_LINE_SIZE = 1 << MAP_CACHE_LINE_LOG2 + MAP_CELL_CACHE_LINE_LOG2 = 6, + MAP_CELL_CACHE_LINE_SIZE = 1 << MAP_CELL_CACHE_LINE_LOG2, }; -GB_STATIC_ASSERT(MAP_CACHE_LINE_SIZE >= 64); +GB_STATIC_ASSERT(MAP_CELL_CACHE_LINE_SIZE >= 64); gb_internal void map_cell_size_and_len(Type *type, i64 *size_, i64 *len_) { i64 elem_sz = type_size_of(type); i64 len = 1; - if (0 < elem_sz && elem_sz < MAP_CACHE_LINE_SIZE) { - len = MAP_CACHE_LINE_SIZE / elem_sz; + if (0 < elem_sz && elem_sz < MAP_CELL_CACHE_LINE_SIZE) { + len = MAP_CELL_CACHE_LINE_SIZE / elem_sz; } - i64 size = align_formula(elem_sz * len, MAP_CACHE_LINE_SIZE); + i64 size = align_formula(elem_sz * len, MAP_CELL_CACHE_LINE_SIZE); if (size_) *size_ = size; if (len_) *len_ = len; } diff --git a/src/checker.cpp b/src/checker.cpp index 39a132060..01c232bff 100644 --- a/src/checker.cpp +++ b/src/checker.cpp @@ -2030,7 +2030,7 @@ gb_internal void add_min_dep_type_info(Checker *c, Type *t) { GB_ASSERT(ti_index >= 0); // IMPORTANT NOTE(bill): this must be copied as `map_set` takes a const ref // and effectively assigns the `+1` of the value - isize const count = set->entries.count; + isize const count = set->count; if (map_set_if_not_previously_exists(set, ti_index, count)) { // Type already exists; return; @@ -2536,7 +2536,7 @@ gb_internal Array generate_entity_dependency_graph(CheckerInf // This means that the entity graph node set will have to be thread safe TIME_SECTION("generate_entity_dependency_graph: Calculate edges for graph M - Part 2"); - auto G = array_make(allocator, 0, M.entries.count); + auto G = array_make(allocator, 0, M.count); for (auto const &m_entry : M) { auto *e = m_entry.key; @@ -4227,7 +4227,7 @@ gb_internal Array generate_import_dependency_graph(Checker *c } Array G = {}; - array_init(&G, heap_allocator(), 0, M.entries.count); + array_init(&G, heap_allocator(), 0, M.count); isize i = 0; for (auto const &entry : M) { @@ -4655,7 +4655,7 @@ gb_internal void check_create_file_scopes(Checker *c) { total_pkg_decl_count += f->total_file_decl_count; } - mpmc_init(&pkg->exported_entity_queue, heap_allocator(), total_pkg_decl_count); + mpmc_init(&pkg->exported_entity_queue, total_pkg_decl_count); } } diff --git a/src/docs_writer.cpp b/src/docs_writer.cpp index ea0946153..cb7fa0e1e 100644 --- a/src/docs_writer.cpp +++ b/src/docs_writer.cpp @@ -913,7 +913,7 @@ gb_internal OdinDocEntityIndex odin_doc_add_entity(OdinDocWriter *w, Entity *e) gb_internal void odin_doc_update_entities(OdinDocWriter *w) { { // NOTE(bill): Double pass, just in case entities are created on odin_doc_type - auto entities = array_make(heap_allocator(), 0, w->entity_cache.entries.count); + auto entities = array_make(heap_allocator(), 0, w->entity_cache.count); defer (array_free(&entities)); for (auto const &entry : w->entity_cache) { @@ -973,7 +973,7 @@ gb_internal OdinDocArray odin_doc_add_pkg_entries(OdinDocWrit return {}; } - auto entries = array_make(heap_allocator(), 0, w->entity_cache.entries.count); + auto entries = array_make(heap_allocator(), 0, w->entity_cache.count); defer (array_free(&entries)); for (auto const &element : pkg->scope->elements) { diff --git a/src/llvm_backend.cpp b/src/llvm_backend.cpp index 6cd224324..0df32329b 100644 --- a/src/llvm_backend.cpp +++ b/src/llvm_backend.cpp @@ -743,7 +743,7 @@ gb_internal lbValue lb_generate_anonymous_proc_lit(lbModule *m, String const &pr // parent$count isize name_len = prefix_name.len + 1 + 8 + 1; char *name_text = gb_alloc_array(permanent_allocator(), char, name_len); - i32 name_id = cast(i32)m->gen->anonymous_proc_lits.entries.count; + i32 name_id = cast(i32)m->gen->anonymous_proc_lits.count; name_len = gb_snprintf(name_text, name_len, "%.*s$anon-%d", LIT(prefix_name), name_id); String name = make_string((u8 *)name_text, name_len-1); @@ -1625,7 +1625,7 @@ gb_internal bool lb_llvm_object_generation(lbGenerator *gen, bool do_threading) String filepath_ll = lb_filepath_ll_for_module(m); String filepath_obj = lb_filepath_obj_for_module(m); - gb_printf_err("%.*s\n", LIT(filepath_obj)); + // gb_printf_err("%.*s\n", LIT(filepath_obj)); array_add(&gen->output_object_paths, filepath_obj); array_add(&gen->output_temp_paths, filepath_ll); @@ -1977,7 +1977,7 @@ gb_internal bool lb_generate_code(lbGenerator *gen) { // NOTE(bill): Target Machine Creation // NOTE(bill, 2021-05-04): Target machines must be unique to each module because they are not thread safe - auto target_machines = array_make(permanent_allocator(), 0, gen->modules.entries.count); + auto target_machines = array_make(permanent_allocator(), 0, gen->modules.count); // NOTE(dweiler): Dynamic libraries require position-independent code. LLVMRelocMode reloc_mode = LLVMRelocDefault; @@ -2073,7 +2073,7 @@ 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.entries.count+1; + isize max_type_info_count = info->minimum_dependency_type_info_set.count+1; // gb_printf_err("max_type_info_count: %td\n", max_type_info_count); Type *t = alloc_type_array(t_type_info, max_type_info_count); LLVMValueRef g = LLVMAddGlobal(m->mod, lb_type(m, t), LB_TYPE_INFO_DATA_NAME); @@ -2330,7 +2330,7 @@ gb_internal bool lb_generate_code(lbGenerator *gen) { } } - if (gen->modules.entries.count <= 1) { + if (gen->modules.count <= 1) { do_threading = false; } diff --git a/src/ptr_map.cpp b/src/ptr_map.cpp index 598904906..0a5c1e492 100644 --- a/src/ptr_map.cpp +++ b/src/ptr_map.cpp @@ -2,6 +2,13 @@ typedef u32 MapIndex; +enum { + MAP_CACHE_LINE_SIZE_POW = 6, + MAP_CACHE_LINE_SIZE = 1< struct PtrMap { - Slice hashes; - Array > entries; + MapIndex * hashes; + usize hashes_count; + PtrMapEntry *entries; + u32 count; + u32 entries_capacity; }; @@ -78,42 +88,48 @@ gb_internal gbAllocator map_allocator(void) { template gb_internal gb_inline void map_init(PtrMap *h, isize capacity) { capacity = next_pow2_isize(capacity); - slice_init(&h->hashes, map_allocator(), capacity); - array_init(&h->entries, map_allocator(), 0, capacity); - for (isize i = 0; i < capacity; i++) { - h->hashes.data[i] = MAP_SENTINEL; - } + map_reserve(h, capacity); } template gb_internal gb_inline void map_destroy(PtrMap *h) { - if (h->entries.allocator.proc == nullptr) { - h->entries.allocator = map_allocator(); - } - slice_free(&h->hashes, h->entries.allocator); - array_free(&h->entries); + gbAllocator a = map_allocator(); + gb_free(a, h->hashes); + gb_free(a, h->entries); } +template +gb_internal void map__resize_hashes(PtrMap *h, usize count) { + h->hashes_count = cast(u32)resize_array_raw(&h->hashes, string_map_allocator(), h->hashes_count, count, MAP_CACHE_LINE_SIZE); +} + +template +gb_internal void map__reserve_entries(PtrMap *h, usize capacity) { + h->entries_capacity = cast(u32)resize_array_raw(&h->entries, string_map_allocator(), h->entries_capacity, capacity, MAP_CACHE_LINE_SIZE); +} + + template gb_internal MapIndex map__add_entry(PtrMap *h, K key) { PtrMapEntry e = {}; e.key = key; e.next = MAP_SENTINEL; - array_add(&h->entries, e); - return cast(MapIndex)(h->entries.count-1); + map__reserve_entries(h, h->count+1); + h->entries[h->count++] = e; + return cast(MapIndex)(h->count-1); } template gb_internal MapFindResult map__find(PtrMap *h, K key) { MapFindResult fr = {MAP_SENTINEL, MAP_SENTINEL, MAP_SENTINEL}; - if (h->hashes.count == 0) { + if (h->hashes_count == 0) { return fr; } u32 hash = ptr_map_hash_key(key); - fr.hash_index = cast(MapIndex)(hash & (h->hashes.count-1)); - fr.entry_index = h->hashes.data[fr.hash_index]; + fr.hash_index = cast(MapIndex)(hash & (h->hashes_count-1)); + fr.entry_index = h->hashes[fr.hash_index]; while (fr.entry_index != MAP_SENTINEL) { - auto *entry = &h->entries.data[fr.entry_index]; + auto *entry = &h->entries[fr.entry_index]; if (entry->key == key) { return fr; } @@ -126,41 +142,41 @@ gb_internal MapFindResult map__find(PtrMap *h, K key) { template gb_internal MapFindResult map__find_from_entry(PtrMap *h, PtrMapEntry *e) { MapFindResult fr = {MAP_SENTINEL, MAP_SENTINEL, MAP_SENTINEL}; - if (h->hashes.count == 0) { + if (h->hashes_count == 0) { return fr; } u32 hash = ptr_map_hash_key(e->key); - fr.hash_index = cast(MapIndex)(hash & (h->hashes.count-1)); - fr.entry_index = h->hashes.data[fr.hash_index]; + fr.hash_index = cast(MapIndex)(hash & (h->hashes_count-1)); + fr.entry_index = h->hashes[fr.hash_index]; while (fr.entry_index != MAP_SENTINEL) { - if (&h->entries.data[fr.entry_index] == e) { + if (&h->entries[fr.entry_index] == e) { return fr; } fr.entry_prev = fr.entry_index; - fr.entry_index = h->entries.data[fr.entry_index].next; + fr.entry_index = h->entries[fr.entry_index].next; } return fr; } template gb_internal b32 map__full(PtrMap *h) { - return 0.75f * h->hashes.count <= h->entries.count; + return 0.75f * h->hashes_count <= h->count; } template gb_internal gb_inline void map_grow(PtrMap *h) { - isize new_count = gb_max(h->hashes.count<<1, 16); + isize new_count = gb_max(h->hashes_count<<1, 16); map_rehash(h, new_count); } template gb_internal void map_reset_entries(PtrMap *h) { - for (isize i = 0; i < h->hashes.count; i++) { - h->hashes.data[i] = MAP_SENTINEL; + for (usize i = 0; i < h->hashes_count; i++) { + h->hashes[i] = MAP_SENTINEL; } - for (isize i = 0; i < h->entries.count; i++) { + for (usize i = 0; i < h->count; i++) { MapFindResult fr; - PtrMapEntry *e = &h->entries.data[i]; + PtrMapEntry *e = &h->entries[i]; e->next = MAP_SENTINEL; fr = map__find_from_entry(h, e); if (fr.entry_prev == MAP_SENTINEL) { @@ -173,14 +189,11 @@ gb_internal void map_reset_entries(PtrMap *h) { template gb_internal void map_reserve(PtrMap *h, isize cap) { - if (h->entries.allocator.proc == nullptr) { - h->entries.allocator = map_allocator(); - } - array_reserve(&h->entries, cap); - if (h->entries.count*2 < h->hashes.count) { + if (h->count*2 < h->hashes_count) { return; } - slice_resize(&h->hashes, h->entries.allocator, cap*2); + map__reserve_entries(h, cap); + map__resize_hashes(h, cap*2); map_reset_entries(h); } @@ -195,12 +208,12 @@ gb_internal V *map_get(PtrMap *h, K key) { MapIndex hash_index = MAP_SENTINEL; MapIndex entry_prev = MAP_SENTINEL; MapIndex entry_index = MAP_SENTINEL; - if (h->hashes.count != 0) { + if (h->hashes_count != 0) { u32 hash = ptr_map_hash_key(key); - hash_index = cast(MapIndex)(hash & (h->hashes.count-1)); - entry_index = h->hashes.data[hash_index]; + hash_index = cast(MapIndex)(hash & (h->hashes_count-1)); + entry_index = h->hashes[hash_index]; while (entry_index != MAP_SENTINEL) { - auto *entry = &h->entries.data[entry_index]; + auto *entry = &h->entries[entry_index]; if (entry->key == key) { return &entry->value; } @@ -213,12 +226,12 @@ gb_internal V *map_get(PtrMap *h, K key) { template gb_internal V *map_try_get(PtrMap *h, K key, MapFindResult *fr_) { MapFindResult fr = {MAP_SENTINEL, MAP_SENTINEL, MAP_SENTINEL}; - if (h->hashes.count != 0) { + if (h->hashes_count != 0) { u32 hash = ptr_map_hash_key(key); - fr.hash_index = cast(MapIndex)(hash & (h->hashes.count-1)); - fr.entry_index = h->hashes.data[fr.hash_index]; + fr.hash_index = cast(MapIndex)(hash & (h->hashes_count-1)); + fr.entry_index = h->hashes[fr.hash_index]; while (fr.entry_index != MAP_SENTINEL) { - auto *entry = &h->entries.data[fr.entry_index]; + auto *entry = &h->entries[fr.entry_index]; if (entry->key == key) { return &entry->value; } @@ -226,7 +239,7 @@ gb_internal V *map_try_get(PtrMap *h, K key, MapFindResult *fr_) { fr.entry_index = entry->next; } } - if (h->hashes.count == 0 || map__full(h)) { + if (h->hashes_count == 0 || map__full(h)) { map_grow(h); } if (fr_) *fr_ = fr; @@ -238,11 +251,11 @@ template gb_internal void map_set_internal_from_try_get(PtrMap *h, K key, V const &value, MapFindResult const &fr) { MapIndex index = map__add_entry(h, key); if (fr.entry_prev != MAP_SENTINEL) { - h->entries.data[fr.entry_prev].next = index; + h->entries[fr.entry_prev].next = index; } else { - h->hashes.data[fr.hash_index] = index; + h->hashes[fr.hash_index] = index; } - h->entries.data[index].value = value; + h->entries[index].value = value; } template @@ -256,7 +269,7 @@ template gb_internal void map_set(PtrMap *h, K key, V const &value) { MapIndex index; MapFindResult fr; - if (h->hashes.count == 0) { + if (h->hashes_count == 0) { map_grow(h); } fr = map__find(h, key); @@ -265,12 +278,12 @@ gb_internal void map_set(PtrMap *h, K key, V const &value) { } else { index = map__add_entry(h, key); if (fr.entry_prev != MAP_SENTINEL) { - h->entries.data[fr.entry_prev].next = index; + h->entries[fr.entry_prev].next = index; } else { - h->hashes.data[fr.hash_index] = index; + h->hashes[fr.hash_index] = index; } } - h->entries.data[index].value = value; + h->entries[index].value = value; if (map__full(h)) { map_grow(h); @@ -282,7 +295,7 @@ template gb_internal bool map_set_if_not_previously_exists(PtrMap *h, K key, V const &value) { MapIndex index; MapFindResult fr; - if (h->hashes.count == 0) { + if (h->hashes_count == 0) { map_grow(h); } fr = map__find(h, key); @@ -291,12 +304,12 @@ gb_internal bool map_set_if_not_previously_exists(PtrMap *h, K key, V cons } else { index = map__add_entry(h, key); if (fr.entry_prev != MAP_SENTINEL) { - h->entries.data[fr.entry_prev].next = index; + h->entries[fr.entry_prev].next = index; } else { - h->hashes.data[fr.hash_index] = index; + h->hashes[fr.hash_index] = index; } } - h->entries.data[index].value = value; + h->entries[index].value = value; if (map__full(h)) { map_grow(h); @@ -309,22 +322,22 @@ template gb_internal void map__erase(PtrMap *h, MapFindResult const &fr) { MapFindResult last; if (fr.entry_prev == MAP_SENTINEL) { - h->hashes.data[fr.hash_index] = h->entries.data[fr.entry_index].next; + h->hashes[fr.hash_index] = h->entries[fr.entry_index].next; } else { - h->entries.data[fr.entry_prev].next = h->entries.data[fr.entry_index].next; + h->entries[fr.entry_prev].next = h->entries[fr.entry_index].next; } - if (fr.entry_index == h->entries.count-1) { - array_pop(&h->entries); + if (fr.entry_index == h->count-1) { + h->count--; return; } - h->entries.data[fr.entry_index] = h->entries.data[h->entries.count-1]; - array_pop(&h->entries); + h->entries[fr.entry_index] = h->entries[h->count-1]; + h->count--; - last = map__find(h, h->entries.data[fr.entry_index].key); + last = map__find(h, h->entries[fr.entry_index].key); if (last.entry_prev != MAP_SENTINEL) { - h->entries.data[last.entry_prev].next = fr.entry_index; + h->entries[last.entry_prev].next = fr.entry_index; } else { - h->hashes.data[last.hash_index] = fr.entry_index; + h->hashes[last.hash_index] = fr.entry_index; } } @@ -338,9 +351,9 @@ gb_internal void map_remove(PtrMap *h, K key) { template gb_internal gb_inline void map_clear(PtrMap *h) { - array_clear(&h->entries); - for (isize i = 0; i < h->hashes.count; i++) { - h->hashes.data[i] = MAP_SENTINEL; + h->count = 0; + for (usize i = 0; i < h->hashes_count; i++) { + h->hashes[i] = MAP_SENTINEL; } } @@ -352,17 +365,17 @@ gb_internal PtrMapEntry *multi_map_find_first(PtrMap *h, K key) { if (i == MAP_SENTINEL) { return nullptr; } - return &h->entries.data[i]; + return &h->entries[i]; } template gb_internal PtrMapEntry *multi_map_find_next(PtrMap *h, PtrMapEntry *e) { MapIndex i = e->next; while (i != MAP_SENTINEL) { - if (h->entries.data[i].key == e->key) { - return &h->entries.data[i]; + if (h->entries[i].key == e->key) { + return &h->entries[i]; } - i = h->entries.data[i].next; + i = h->entries[i].next; } return nullptr; } @@ -380,7 +393,7 @@ gb_internal isize multi_map_count(PtrMap *h, K key) { template gb_internal void multi_map_get_all(PtrMap *h, K key, V *items) { - isize i = 0; + usize i = 0; PtrMapEntry *e = multi_map_find_first(h, key); while (e != nullptr) { items[i++] = e->value; @@ -392,19 +405,19 @@ template gb_internal void multi_map_insert(PtrMap *h, K key, V const &value) { MapFindResult fr; MapIndex i; - if (h->hashes.count == 0) { + if (h->hashes_count == 0) { map_grow(h); } // Make fr = map__find(h, key); i = map__add_entry(h, key); if (fr.entry_prev == MAP_SENTINEL) { - h->hashes.data[fr.hash_index] = i; + h->hashes[fr.hash_index] = i; } else { - h->entries.data[fr.entry_prev].next = i; + h->entries[fr.entry_prev].next = i; } - h->entries.data[i].next = fr.entry_index; - h->entries.data[i].value = value; + h->entries[i].next = fr.entry_index; + h->entries[i].value = value; // Grow if needed if (map__full(h)) { map_grow(h); @@ -430,20 +443,20 @@ gb_internal void multi_map_remove_all(PtrMap *h, K key) { template gb_internal PtrMapEntry *begin(PtrMap &m) { - return m.entries.data; + return m.entries; } template gb_internal PtrMapEntry const *begin(PtrMap const &m) { - return m.entries.data; + return m.entries; } template gb_internal PtrMapEntry *end(PtrMap &m) { - return m.entries.data + m.entries.count; + return m.entries + m.count; } template gb_internal PtrMapEntry const *end(PtrMap const &m) { - return m.entries.data + m.entries.count; + return m.entries + m.count; } diff --git a/src/queue.cpp b/src/queue.cpp index 05076cfbd..2ad9cb29f 100644 --- a/src/queue.cpp +++ b/src/queue.cpp @@ -10,22 +10,19 @@ struct MPSCNode { // template struct MPSCQueue { - gbAllocator allocator; - MPSCNode sentinel; std::atomic *> head; std::atomic *> tail; std::atomic count; }; -template gb_internal void mpsc_init (MPSCQueue *q, gbAllocator const &allocator); +template gb_internal void mpsc_init (MPSCQueue *q); template gb_internal void mpsc_destroy(MPSCQueue *q); template gb_internal isize mpsc_enqueue(MPSCQueue *q, T const &value); template gb_internal bool mpsc_dequeue(MPSCQueue *q, T *value_); template gb_internal void mpsc_init(MPSCQueue *q, gbAllocator const &allocator) { - q->allocator = allocator; q->sentinel.next.store(nullptr, std::memory_order_relaxed); q->head.store(&q->sentinel, std::memory_order_relaxed); q->tail.store(&q->sentinel, std::memory_order_relaxed); @@ -39,7 +36,7 @@ gb_internal void mpsc_destroy(MPSCQueue *q) { template gb_internal MPSCNode *mpsc_alloc_node(MPSCQueue *q, T const &value) { - auto new_node = gb_alloc_item(q->allocator, MPSCNode); + auto new_node = gb_alloc_item(heap_allocator(), MPSCNode); new_node->value = value; return new_node; } @@ -95,7 +92,6 @@ struct MPMCQueue { T * nodes; MPMCQueueAtomicIdx *indices; - gbAllocator allocator; BlockingMutex mutex; MPMCQueueAtomicIdx count; i32 mask; // capacity-1, because capacity must be a power of 2 @@ -108,6 +104,9 @@ struct MPMCQueue { }; +gb_internal gbAllocator mpmc_allocator(void) { + return heap_allocator(); +} gb_internal void mpmc_internal_init_indices(MPMCQueueAtomicIdx *indices, i32 offset, i32 size) { GB_ASSERT(offset % 8 == 0); @@ -129,7 +128,7 @@ gb_internal void mpmc_internal_init_indices(MPMCQueueAtomicIdx *indices, i32 off template -gb_internal void mpmc_init(MPMCQueue *q, gbAllocator a, isize size_i) { +gb_internal void mpmc_init(MPMCQueue *q, isize size_i) { if (size_i < 8) { size_i = 8; } @@ -139,7 +138,7 @@ gb_internal void mpmc_init(MPMCQueue *q, gbAllocator a, isize size_i) { GB_ASSERT(gb_is_power_of_two(size)); q->mask = size-1; - q->allocator = a; + gbAllocator a = mpmc_allocator(); q->nodes = gb_alloc_array(a, T, size); q->indices = gb_alloc_array(a, MPMCQueueAtomicIdx, size); @@ -150,23 +149,25 @@ gb_internal void mpmc_init(MPMCQueue *q, gbAllocator a, isize size_i) { template gb_internal void mpmc_destroy(MPMCQueue *q) { - gb_free(q->allocator, q->nodes); - gb_free(q->allocator, q->indices); + gbAllocator a = mpmc_allocator(); + gb_free(a, q->nodes); + gb_free(a, q->indices); } template gb_internal bool mpmc_internal_grow(MPMCQueue *q) { + gbAllocator a = mpmc_allocator(); mutex_lock(&q->mutex); i32 old_size = q->mask+1; i32 new_size = old_size*2; - resize_array_raw(&q->nodes, q->allocator, old_size, new_size); + resize_array_raw(&q->nodes, a, old_size, new_size); if (q->nodes == nullptr) { GB_PANIC("Unable to resize enqueue: %td -> %td", old_size, new_size); mutex_unlock(&q->mutex); return false; } - resize_array_raw(&q->indices, q->allocator, old_size, new_size); + resize_array_raw(&q->indices, a, old_size, new_size); if (q->indices == nullptr) { GB_PANIC("Unable to resize enqueue: %td -> %td", old_size, new_size); mutex_unlock(&q->mutex); diff --git a/src/string_map.cpp b/src/string_map.cpp index 067adef28..bf1bbf6ca 100644 --- a/src/string_map.cpp +++ b/src/string_map.cpp @@ -1,10 +1,5 @@ GB_STATIC_ASSERT(sizeof(MapIndex) == sizeof(u32)); -enum { - STRING_MAP_CACHE_LINE_SIZE_POW = 6, - STRING_MAP_CACHE_LINE_SIZE = 1< *h) { template gb_internal void string_map__resize_hashes(StringMap *h, usize count) { - h->hashes_count = cast(u32)resize_array_raw(&h->hashes, string_map_allocator(), h->hashes_count, count, STRING_MAP_CACHE_LINE_SIZE); + h->hashes_count = cast(u32)resize_array_raw(&h->hashes, string_map_allocator(), h->hashes_count, count, MAP_CACHE_LINE_SIZE); } template gb_internal void string_map__reserve_entries(StringMap *h, usize capacity) { - h->entries_capacity = cast(u32)resize_array_raw(&h->entries, string_map_allocator(), h->entries_capacity, capacity, STRING_MAP_CACHE_LINE_SIZE); + h->entries_capacity = cast(u32)resize_array_raw(&h->entries, string_map_allocator(), h->entries_capacity, capacity, MAP_CACHE_LINE_SIZE); } -- cgit v1.2.3 From 9aa9429135930fcdb51c99c908c604d348443212 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Sat, 14 Jan 2023 13:42:04 +0000 Subject: Update `debugf` usage --- src/checker.cpp | 9 ++++----- src/llvm_backend.cpp | 3 ++- src/main.cpp | 4 ++++ 3 files changed, 10 insertions(+), 6 deletions(-) (limited to 'src/checker.cpp') diff --git a/src/checker.cpp b/src/checker.cpp index 01c232bff..1c9ac8d51 100644 --- a/src/checker.cpp +++ b/src/checker.cpp @@ -5187,8 +5187,6 @@ gb_internal void check_unchecked_bodies(Checker *c) { if (pi->body == nullptr) { continue; } - - debugf("unchecked: %.*s\n", LIT(e->token.string)); check_procedure_later(c, pi); } } @@ -5219,11 +5217,12 @@ gb_internal void check_safety_all_procedures_for_unchecked(Checker *c) { GB_ASSERT(pi->decl != nullptr); Entity *e = pi->decl->entity; auto proc_checked_state = pi->decl->proc_checked_state.load(); + gb_unused(proc_checked_state); if (e && ((e->flags & EntityFlag_ProcBodyChecked) == 0)) { if ((e->flags & EntityFlag_Used) != 0) { - debugf("%.*s :: %s\n", LIT(e->token.string), type_to_string(e->type)); - debugf("proc body unchecked\n"); - debugf("Checked State: %s\n\n", ProcCheckedState_strings[proc_checked_state]); + // debugf("%.*s :: %s\n", LIT(e->token.string), type_to_string(e->type)); + // debugf("proc body unchecked\n"); + // debugf("Checked State: %s\n\n", ProcCheckedState_strings[proc_checked_state]); consume_proc_info(c, pi, &untyped); } diff --git a/src/llvm_backend.cpp b/src/llvm_backend.cpp index 0df32329b..b3364b89e 100644 --- a/src/llvm_backend.cpp +++ b/src/llvm_backend.cpp @@ -1283,7 +1283,7 @@ gb_internal WORKER_TASK_PROC(lb_llvm_emit_worker_proc) { gb_printf_err("LLVM Error: %s\n", llvm_error); gb_exit(1); } - + debugf("Generated File: %.*s\n", LIT(wd->filepath_obj)); return 0; } @@ -1659,6 +1659,7 @@ gb_internal bool lb_llvm_object_generation(lbGenerator *gen, bool do_threading) gb_exit(1); return false; } + debugf("Generated File: %.*s\n", LIT(filepath_obj)); } } return true; diff --git a/src/main.cpp b/src/main.cpp index 60f27a5a7..de7fea344 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -27,13 +27,17 @@ gb_internal void thread_pool_wait(void) { } +gb_global BlockingMutex debugf_mutex; + gb_internal void debugf(char const *fmt, ...) { if (build_context.show_debug_messages) { + mutex_lock(&debugf_mutex); gb_printf_err("[DEBUG] "); va_list va; va_start(va, fmt); (void)gb_printf_err_va(fmt, va); va_end(va); + mutex_unlock(&debugf_mutex); } } -- cgit v1.2.3 From 88b578ca11a9042e1e35a4ab272f18debe6c7a79 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Mon, 30 Jan 2023 12:53:36 +0000 Subject: Add for C++ for loop uses --- src/build_settings.cpp | 12 +++++------- src/checker.cpp | 13 +++++-------- 2 files changed, 10 insertions(+), 15 deletions(-) (limited to 'src/checker.cpp') diff --git a/src/build_settings.cpp b/src/build_settings.cpp index 904428602..d18ca5603 100644 --- a/src/build_settings.cpp +++ b/src/build_settings.cpp @@ -596,9 +596,9 @@ gb_internal void add_library_collection(String name, String path) { } gb_internal bool find_library_collection_path(String name, String *path) { - for_array(i, library_collections) { - if (library_collections[i].name == name) { - if (path) *path = library_collections[i].path; + for (auto const &lc : library_collections) { + if (lc.name == name) { + if (path) *path = lc.path; return true; } } @@ -1307,8 +1307,7 @@ gb_internal bool check_target_feature_is_enabled(TokenPos pos, String const &tar auto items = split_by_comma(target_feature_list); array_free(&items); - for_array(i, items) { - String const &item = items.data[i]; + for (String const &item : items) { if (!check_target_feature_is_valid(pos, item)) { error(pos, "Target feature '%.*s' is not valid", LIT(item)); return false; @@ -1328,8 +1327,7 @@ gb_internal void enable_target_feature(TokenPos pos, String const &target_featur defer (mutex_unlock(&bc->target_features_mutex)); auto items = split_by_comma(target_feature_list); - for_array(i, items) { - String const &item = items.data[i]; + for (String const &item : items) { if (!check_target_feature_is_valid(pos, item)) { error(pos, "Target feature '%.*s' is not valid", LIT(item)); continue; diff --git a/src/checker.cpp b/src/checker.cpp index 1c9ac8d51..6b666a033 100644 --- a/src/checker.cpp +++ b/src/checker.cpp @@ -256,8 +256,8 @@ gb_internal Scope *create_scope_from_package(CheckerContext *c, AstPackage *pkg) GB_ASSERT(pkg != nullptr); isize total_pkg_decl_count = 0; - for_array(j, pkg->files) { - total_pkg_decl_count += pkg->files.data[j]->total_file_decl_count; + for (AstFile *file : pkg->files) { + total_pkg_decl_count += file->total_file_decl_count; } isize init_elements_capacity = gb_max(DEFAULT_SCOPE_CAPACITY, 2*total_pkg_decl_count); @@ -692,8 +692,7 @@ gb_internal void check_scope_usage(Checker *c, Scope *scope) { gb_sort(vetted_entities.data, vetted_entities.count, gb_size_of(VettedEntity), vetted_entity_variable_pos_cmp); - for_array(i, vetted_entities) { - auto ve = vetted_entities[i]; + for (auto const &ve : vetted_entities) { Entity *e = ve.entity; Entity *other = ve.other; String name = e->token.string; @@ -1617,11 +1616,9 @@ gb_internal bool could_entity_be_lazy(Entity *e, DeclInfo *d) { return false; } - for_array(i, d->attributes) { - Ast *attr = d->attributes[i]; + for (Ast *attr : d->attributes) { if (attr->kind != Ast_Attribute) continue; - for_array(j, attr->Attribute.elems) { - Ast *elem = attr->Attribute.elems[j]; + for (Ast *elem : attr->Attribute.elems) { String name = {}; switch (elem->kind) { -- cgit v1.2.3 From 2e4d6d257754b8f91790aac19574d8b7a3d27dc1 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Wed, 1 Feb 2023 23:41:13 +0000 Subject: Fix `when` within `foreign` blocks at the file scope --- src/checker.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'src/checker.cpp') diff --git a/src/checker.cpp b/src/checker.cpp index 6b666a033..d79069769 100644 --- a/src/checker.cpp +++ b/src/checker.cpp @@ -3924,6 +3924,7 @@ gb_internal void correct_type_aliases_in_scope(CheckerContext *c, Scope *s) { } } +gb_internal bool collect_file_decl(CheckerContext *ctx, Ast *decl); // NOTE(bill): If file_scopes == nullptr, this will act like a local scope gb_internal void check_collect_entities(CheckerContext *c, Slice const &nodes) { @@ -4005,6 +4006,13 @@ gb_internal void check_collect_entities(CheckerContext *c, Slice const &n check_collect_entities_from_when_stmt(c, &decl->WhenStmt); } } + } else if (c->foreign_context.curr_library) { + for_array(decl_index, nodes) { + Ast *decl = nodes[decl_index]; + if (decl->kind == Ast_WhenStmt) { + collect_file_decl(c, decl); + } + } } } -- cgit v1.2.3 From 4e70256109573f4c3fe1f0ce9fcf71a5eda43ab3 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Thu, 2 Feb 2023 00:22:54 +0000 Subject: Fix `when` within `foreign` block (again) --- src/checker.cpp | 22 +++++++++------------- 1 file changed, 9 insertions(+), 13 deletions(-) (limited to 'src/checker.cpp') diff --git a/src/checker.cpp b/src/checker.cpp index d79069769..06048e154 100644 --- a/src/checker.cpp +++ b/src/checker.cpp @@ -3851,10 +3851,9 @@ gb_internal void check_collect_value_decl(CheckerContext *c, Ast *decl) { } } -gb_internal void check_add_foreign_block_decl(CheckerContext *ctx, Ast *decl) { - if (decl->state_flags & StateFlag_BeenHandled) return; - decl->state_flags |= StateFlag_BeenHandled; +gb_internal bool collect_file_decls(CheckerContext *ctx, Slice const &decls); +gb_internal bool check_add_foreign_block_decl(CheckerContext *ctx, Ast *decl) { ast_node(fb, ForeignBlockDecl, decl); Ast *foreign_library = fb->foreign_library; @@ -3869,7 +3868,11 @@ gb_internal void check_add_foreign_block_decl(CheckerContext *ctx, Ast *decl) { check_decl_attributes(&c, fb->attributes, foreign_block_decl_attribute, nullptr); ast_node(block, BlockStmt, fb->body); + if (c.collect_delayed_decls && (c.scope->flags&ScopeFlag_File) != 0) { + return collect_file_decls(&c, block->stmts); + } check_collect_entities(&c, block->stmts); + return false; } gb_internal bool correct_single_type_alias(CheckerContext *c, Entity *e) { @@ -3924,8 +3927,6 @@ gb_internal void correct_type_aliases_in_scope(CheckerContext *c, Scope *s) { } } -gb_internal bool collect_file_decl(CheckerContext *ctx, Ast *decl); - // NOTE(bill): If file_scopes == nullptr, this will act like a local scope gb_internal void check_collect_entities(CheckerContext *c, Slice const &nodes) { AstFile *curr_file = nullptr; @@ -4006,13 +4007,6 @@ gb_internal void check_collect_entities(CheckerContext *c, Slice const &n check_collect_entities_from_when_stmt(c, &decl->WhenStmt); } } - } else if (c->foreign_context.curr_library) { - for_array(decl_index, nodes) { - Ast *decl = nodes[decl_index]; - if (decl->kind == Ast_WhenStmt) { - collect_file_decl(c, decl); - } - } } } @@ -4584,7 +4578,9 @@ gb_internal bool collect_file_decl(CheckerContext *ctx, Ast *decl) { case_end; case_ast_node(fb, ForeignBlockDecl, decl); - check_add_foreign_block_decl(ctx, decl); + if (check_add_foreign_block_decl(ctx, decl)) { + return true; + } case_end; case_ast_node(ws, WhenStmt, decl); -- cgit v1.2.3 From 6179d4feb1e7e7f1ca2fa418de75e3695318049f Mon Sep 17 00:00:00 2001 From: gingerBill Date: Wed, 8 Feb 2023 11:23:21 +0000 Subject: Rename to `Type_Info_Parameters` --- core/encoding/json/marshal.odin | 2 +- core/fmt/fmt.odin | 4 ++-- core/reflect/reflect.odin | 7 ++++--- core/reflect/types.odin | 16 +++++++++++----- core/runtime/core.odin | 10 ++++++---- core/runtime/print.odin | 4 ++-- src/checker.cpp | 4 ++-- src/llvm_backend_type.cpp | 3 +-- src/types.cpp | 4 ++-- 9 files changed, 31 insertions(+), 23 deletions(-) (limited to 'src/checker.cpp') diff --git a/core/encoding/json/marshal.odin b/core/encoding/json/marshal.odin index 1eb75d36a..f5914bc07 100644 --- a/core/encoding/json/marshal.odin +++ b/core/encoding/json/marshal.odin @@ -198,7 +198,7 @@ marshal_to_writer :: proc(w: io.Writer, v: any, opt: ^Marshal_Options) -> (err: case runtime.Type_Info_Procedure: return .Unsupported_Type - case runtime.Type_Info_Tuple: + case runtime.Type_Info_Parameters: return .Unsupported_Type case runtime.Type_Info_Simd_Vector: diff --git a/core/fmt/fmt.odin b/core/fmt/fmt.odin index 26ddca0dd..c52869daa 100644 --- a/core/fmt/fmt.odin +++ b/core/fmt/fmt.odin @@ -1783,8 +1783,8 @@ fmt_value :: proc(fi: ^Info, v: any, verb: rune) { type_info := type_info_of(v.id) switch info in type_info.variant { - case runtime.Type_Info_Any: // Ignore - case runtime.Type_Info_Tuple: // Ignore + case runtime.Type_Info_Any: // Ignore + case runtime.Type_Info_Parameters: // Ignore case runtime.Type_Info_Named: fmt_named(fi, v, verb, info) diff --git a/core/reflect/reflect.odin b/core/reflect/reflect.odin index 58f5f6aff..2abf450fa 100644 --- a/core/reflect/reflect.odin +++ b/core/reflect/reflect.odin @@ -25,7 +25,8 @@ Type_Info_Array :: runtime.Type_Info_Array Type_Info_Enumerated_Array :: runtime.Type_Info_Enumerated_Array Type_Info_Dynamic_Array :: runtime.Type_Info_Dynamic_Array Type_Info_Slice :: runtime.Type_Info_Slice -Type_Info_Tuple :: runtime.Type_Info_Tuple +Type_Info_Parameters :: runtime.Type_Info_Parameters +Type_Info_Tuple :: runtime.Type_Info_Parameters Type_Info_Struct :: runtime.Type_Info_Struct Type_Info_Union :: runtime.Type_Info_Union Type_Info_Enum :: runtime.Type_Info_Enum @@ -96,7 +97,7 @@ type_kind :: proc(T: typeid) -> Type_Kind { case Type_Info_Enumerated_Array: return .Enumerated_Array case Type_Info_Dynamic_Array: return .Dynamic_Array case Type_Info_Slice: return .Slice - case Type_Info_Tuple: return .Tuple + case Type_Info_Parameters: return .Tuple case Type_Info_Struct: return .Struct case Type_Info_Union: return .Union case Type_Info_Enum: return .Enum @@ -1438,7 +1439,7 @@ equal :: proc(a, b: any, including_indirect_array_recursion := false, recursion_ switch v in t.variant { case Type_Info_Named: unreachable() - case Type_Info_Tuple: + case Type_Info_Parameters: unreachable() case Type_Info_Any: if !including_indirect_array_recursion { diff --git a/core/reflect/types.odin b/core/reflect/types.odin index 1ee09af9d..bfe894733 100644 --- a/core/reflect/types.odin +++ b/core/reflect/types.odin @@ -101,8 +101,8 @@ are_types_identical :: proc(a, b: ^Type_Info) -> bool { y := b.variant.(Type_Info_Slice) or_return return are_types_identical(x.elem, y.elem) - case Type_Info_Tuple: - y := b.variant.(Type_Info_Tuple) or_return + case Type_Info_Parameters: + y := b.variant.(Type_Info_Parameters) or_return if len(x.types) != len(y.types) { return false } for _, i in x.types { xt, yt := x.types[i], y.types[i] @@ -335,9 +335,15 @@ is_slice :: proc(info: ^Type_Info) -> bool { return ok } @(require_results) +is_parameters :: proc(info: ^Type_Info) -> bool { + if info == nil { return false } + _, ok := type_info_base(info).variant.(Type_Info_Parameters) + return ok +} +@(require_results, deprecated="prefer is_parameters") is_tuple :: proc(info: ^Type_Info) -> bool { if info == nil { return false } - _, ok := type_info_base(info).variant.(Type_Info_Tuple) + _, ok := type_info_base(info).variant.(Type_Info_Parameters) return ok } @(require_results) @@ -490,7 +496,7 @@ write_type_writer :: proc(w: io.Writer, ti: ^Type_Info, n_written: ^int = nil) - if info.params == nil { io.write_string(w, "()", &n) or_return } else { - t := info.params.variant.(Type_Info_Tuple) + t := info.params.variant.(Type_Info_Parameters) io.write_string(w, "(", &n) or_return for t, i in t.types { if i > 0 { @@ -504,7 +510,7 @@ write_type_writer :: proc(w: io.Writer, ti: ^Type_Info, n_written: ^int = nil) - io.write_string(w, " -> ", &n) or_return write_type(w, info.results, &n) or_return } - case Type_Info_Tuple: + case Type_Info_Parameters: count := len(info.names) if count != 1 { io.write_string(w, "(", &n) or_return diff --git a/core/runtime/core.odin b/core/runtime/core.odin index a74bf4285..c64ab7d3b 100644 --- a/core/runtime/core.odin +++ b/core/runtime/core.odin @@ -83,8 +83,8 @@ Type_Info_Multi_Pointer :: struct { elem: ^Type_Info, } Type_Info_Procedure :: struct { - params: ^Type_Info, // Type_Info_Tuple - results: ^Type_Info, // Type_Info_Tuple + params: ^Type_Info, // Type_Info_Parameters + results: ^Type_Info, // Type_Info_Parameters variadic: bool, convention: Calling_Convention, } @@ -104,10 +104,12 @@ Type_Info_Enumerated_Array :: struct { } Type_Info_Dynamic_Array :: struct {elem: ^Type_Info, elem_size: int} Type_Info_Slice :: struct {elem: ^Type_Info, elem_size: int} -Type_Info_Tuple :: struct { // Only used for procedures parameters and results + +Type_Info_Parameters :: struct { // Only used for procedures parameters and results types: []^Type_Info, names: []string, } +Type_Info_Tuple :: Type_Info_Parameters // Will be removed eventually Type_Info_Struct :: struct { types: []^Type_Info, @@ -208,7 +210,7 @@ Type_Info :: struct { Type_Info_Enumerated_Array, Type_Info_Dynamic_Array, Type_Info_Slice, - Type_Info_Tuple, + Type_Info_Parameters, Type_Info_Struct, Type_Info_Union, Type_Info_Enum, diff --git a/core/runtime/print.odin b/core/runtime/print.odin index 1925587fd..819cd5796 100644 --- a/core/runtime/print.odin +++ b/core/runtime/print.odin @@ -303,7 +303,7 @@ print_type :: proc "contextless" (ti: ^Type_Info) { if info.params == nil { print_string("()") } else { - t := info.params.variant.(Type_Info_Tuple) + t := info.params.variant.(Type_Info_Parameters) print_byte('(') for t, i in t.types { if i > 0 { print_string(", ") } @@ -315,7 +315,7 @@ print_type :: proc "contextless" (ti: ^Type_Info) { print_string(" -> ") print_type(info.results) } - case Type_Info_Tuple: + case Type_Info_Parameters: count := len(info.names) if count != 1 { print_byte('(') } for name, i in info.names { diff --git a/src/checker.cpp b/src/checker.cpp index 06048e154..601c693a0 100644 --- a/src/checker.cpp +++ b/src/checker.cpp @@ -2744,7 +2744,7 @@ gb_internal void init_core_type_info(Checker *c) { t_type_info_enumerated_array = find_core_type(c, str_lit("Type_Info_Enumerated_Array")); t_type_info_dynamic_array = find_core_type(c, str_lit("Type_Info_Dynamic_Array")); t_type_info_slice = find_core_type(c, str_lit("Type_Info_Slice")); - t_type_info_tuple = find_core_type(c, str_lit("Type_Info_Tuple")); + t_type_info_parameters = find_core_type(c, str_lit("Type_Info_Parameters")); t_type_info_struct = find_core_type(c, str_lit("Type_Info_Struct")); t_type_info_union = find_core_type(c, str_lit("Type_Info_Union")); t_type_info_enum = find_core_type(c, str_lit("Type_Info_Enum")); @@ -2773,7 +2773,7 @@ gb_internal void init_core_type_info(Checker *c) { t_type_info_enumerated_array_ptr = alloc_type_pointer(t_type_info_enumerated_array); t_type_info_dynamic_array_ptr = alloc_type_pointer(t_type_info_dynamic_array); t_type_info_slice_ptr = alloc_type_pointer(t_type_info_slice); - t_type_info_tuple_ptr = alloc_type_pointer(t_type_info_tuple); + t_type_info_parameters_ptr = alloc_type_pointer(t_type_info_parameters); t_type_info_struct_ptr = alloc_type_pointer(t_type_info_struct); t_type_info_union_ptr = alloc_type_pointer(t_type_info_union); t_type_info_enum_ptr = alloc_type_pointer(t_type_info_enum); diff --git a/src/llvm_backend_type.cpp b/src/llvm_backend_type.cpp index e2b5c9dd0..e8d286fda 100644 --- a/src/llvm_backend_type.cpp +++ b/src/llvm_backend_type.cpp @@ -541,8 +541,7 @@ gb_internal void lb_setup_type_info_data(lbProcedure *p) { // NOTE(bill): Setup break; } case Type_Tuple: { - tag = lb_const_ptr_cast(m, variant_ptr, t_type_info_tuple_ptr); - + tag = lb_const_ptr_cast(m, variant_ptr, t_type_info_parameters_ptr); lbValue memory_types = lb_type_info_member_types_offset(p, t->Tuple.variables.count); lbValue memory_names = lb_type_info_member_names_offset(p, t->Tuple.variables.count); diff --git a/src/types.cpp b/src/types.cpp index 69c1ebe68..7a1f17a16 100644 --- a/src/types.cpp +++ b/src/types.cpp @@ -624,7 +624,7 @@ gb_global Type *t_type_info_array = nullptr; gb_global Type *t_type_info_enumerated_array = nullptr; gb_global Type *t_type_info_dynamic_array = nullptr; gb_global Type *t_type_info_slice = nullptr; -gb_global Type *t_type_info_tuple = nullptr; +gb_global Type *t_type_info_parameters = nullptr; gb_global Type *t_type_info_struct = nullptr; gb_global Type *t_type_info_union = nullptr; gb_global Type *t_type_info_enum = nullptr; @@ -653,7 +653,7 @@ gb_global Type *t_type_info_array_ptr = nullptr; gb_global Type *t_type_info_enumerated_array_ptr = nullptr; gb_global Type *t_type_info_dynamic_array_ptr = nullptr; gb_global Type *t_type_info_slice_ptr = nullptr; -gb_global Type *t_type_info_tuple_ptr = nullptr; +gb_global Type *t_type_info_parameters_ptr = nullptr; gb_global Type *t_type_info_struct_ptr = nullptr; gb_global Type *t_type_info_union_ptr = nullptr; gb_global Type *t_type_info_enum_ptr = nullptr; -- cgit v1.2.3 From 570b1278694e4c7fae7229027ce8984a6a58491b Mon Sep 17 00:00:00 2001 From: gingerBill Date: Wed, 8 Feb 2023 11:46:33 +0000 Subject: Fix crash when a variable declaration must be an identifier --- src/checker.cpp | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'src/checker.cpp') diff --git a/src/checker.cpp b/src/checker.cpp index 601c693a0..303a2449e 100644 --- a/src/checker.cpp +++ b/src/checker.cpp @@ -1478,10 +1478,9 @@ gb_internal void add_type_and_value(CheckerContext *ctx, Ast *expr, AddressingMo gb_internal void add_entity_definition(CheckerInfo *i, Ast *identifier, Entity *entity) { GB_ASSERT(identifier != nullptr); - GB_ASSERT(identifier->kind == Ast_Ident); - // if (is_blank_ident(identifier)) { - // return; - // } + if (identifier->kind != Ast_Ident) { + return; + } if (identifier->Ident.entity != nullptr) { // NOTE(bill): Identifier has already been handled return; -- cgit v1.2.3 From e6239ca3c26ecf5db53353a0495d8745ea612209 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Fri, 10 Feb 2023 13:17:04 +0000 Subject: Warn on 'expand_to_tuple' has been replaced with 'expand_values' --- src/check_expr.cpp | 4 ++++ src/checker.cpp | 7 +++++++ 2 files changed, 11 insertions(+) (limited to 'src/checker.cpp') diff --git a/src/check_expr.cpp b/src/check_expr.cpp index 58372f7a3..80a27bd79 100644 --- a/src/check_expr.cpp +++ b/src/check_expr.cpp @@ -6744,6 +6744,10 @@ gb_internal ExprKind check_call_expr(CheckerContext *c, Operand *operand, Ast *c if (operand->mode == Addressing_Builtin) { i32 id = operand->builtin_id; + Entity *e = entity_of_node(operand->expr); + if (e != nullptr && e->token.string == "expand_to_tuple") { + warning(operand->expr, "'expand_to_tuple' has been replaced with 'expand_values'"); + } if (!check_builtin_procedure(c, operand, call, id, type_hint)) { operand->mode = Addressing_Invalid; operand->type = t_invalid; diff --git a/src/checker.cpp b/src/checker.cpp index 303a2449e..bcaa11b8b 100644 --- a/src/checker.cpp +++ b/src/checker.cpp @@ -1070,6 +1070,13 @@ gb_internal void init_universal(void) { } } } + { + BuiltinProcId id = BuiltinProc_expand_values; + String name = str_lit("expand_to_tuple"); + Entity *entity = alloc_entity(Entity_Builtin, nullptr, make_token_ident(name), t_invalid); + entity->Builtin.id = id; + add_global_entity(entity, builtin_pkg->scope); + } bool defined_values_double_declaration = false; for (auto const &entry : bc->defined_values) { -- cgit v1.2.3 From 94c1331c071d4816bec44345393dfd07f75c97dc Mon Sep 17 00:00:00 2001 From: gingerBill Date: Wed, 15 Feb 2023 11:31:51 +0000 Subject: Implement `@(fini)` (opposite of `@(init)`) --- core/runtime/core.odin | 7 +--- core/runtime/default_temporary_allocator.odin | 6 +++ src/check_decl.cpp | 7 +++- src/checker.cpp | 53 ++++++++++++++++++++++++--- src/checker.hpp | 2 + src/entity.cpp | 1 + src/llvm_backend.cpp | 41 +++++++++++++++++++-- src/llvm_backend.hpp | 2 + 8 files changed, 103 insertions(+), 16 deletions(-) (limited to 'src/checker.cpp') diff --git a/core/runtime/core.odin b/core/runtime/core.odin index c64ab7d3b..2d20310ae 100644 --- a/core/runtime/core.odin +++ b/core/runtime/core.odin @@ -507,11 +507,8 @@ Odin_Endian_Type :: type_of(ODIN_ENDIAN) foreign { @(link_name="__$startup_runtime") _startup_runtime :: proc "odin" () --- -} - -@(link_name="__$cleanup_runtime") -_cleanup_runtime :: proc() { - default_temp_allocator_destroy(&global_default_temp_allocator_data) + @(link_name="__$cleanup_runtime") + _cleanup_runtime :: proc "odin" () --- } _cleanup_runtime_contextless :: proc "contextless" () { diff --git a/core/runtime/default_temporary_allocator.odin b/core/runtime/default_temporary_allocator.odin index b71cd103a..85e76df6c 100644 --- a/core/runtime/default_temporary_allocator.odin +++ b/core/runtime/default_temporary_allocator.odin @@ -198,3 +198,9 @@ default_temp_allocator :: proc(allocator: ^Default_Temp_Allocator) -> Allocator data = allocator, } } + +@(fini, private) +_destroy_temp_allocator_fini :: proc() { + default_temp_allocator_destroy(&global_default_temp_allocator_data) + print_string("fini") +} diff --git a/src/check_decl.cpp b/src/check_decl.cpp index f0059424e..63e6514e0 100644 --- a/src/check_decl.cpp +++ b/src/check_decl.cpp @@ -816,9 +816,14 @@ gb_internal void check_proc_decl(CheckerContext *ctx, Entity *e, DeclInfo *d) { if (ac.test) { e->flags |= EntityFlag_Test; } - if (ac.init) { + if (ac.init && ac.fini) { + error(e->token, "A procedure cannot be both declared as @(init) and @(fini)"); + } else if (ac.init) { e->flags |= EntityFlag_Init; + } else if (ac.fini) { + e->flags |= EntityFlag_Fini; } + if (ac.set_cold) { e->flags |= EntityFlag_Cold; } diff --git a/src/checker.cpp b/src/checker.cpp index 303a2449e..5163fe675 100644 --- a/src/checker.cpp +++ b/src/checker.cpp @@ -1148,6 +1148,7 @@ gb_internal void init_checker_info(CheckerInfo *i) { array_init(&i->variable_init_order, a); array_init(&i->testing_procedures, a, 0, 0); array_init(&i->init_procedures, a, 0, 0); + array_init(&i->fini_procedures, a, 0, 0); array_init(&i->required_foreign_imports_through_force, a, 0, 0); map_init(&i->objc_msgSend_types); @@ -1539,7 +1540,7 @@ gb_internal void add_entity_flags_from_file(CheckerContext *c, Entity *e, Scope AstPackage *pkg = c->file->pkg; if (pkg->kind == Package_Init && e->kind == Entity_Procedure && e->token.string == "main") { // Do nothing - } else if (e->flags & (EntityFlag_Test|EntityFlag_Init)) { + } else if (e->flags & (EntityFlag_Test|EntityFlag_Init|EntityFlag_Fini)) { // Do nothing } else { e->flags |= EntityFlag_Lazy; @@ -1607,7 +1608,7 @@ gb_internal bool could_entity_be_lazy(Entity *e, DeclInfo *d) { return false; } - if (e->flags & (EntityFlag_Test|EntityFlag_Init)) { + if (e->flags & (EntityFlag_Test|EntityFlag_Init|EntityFlag_Fini)) { return false; } else if (e->kind == Entity_Variable && e->Variable.is_export) { return false; @@ -2416,6 +2417,28 @@ gb_internal void generate_minimum_dependency_set(Checker *c, Entity *start) { add_dependency_to_set(c, e); array_add(&c->info.init_procedures, e); } + } else if (e->flags & EntityFlag_Fini) { + Type *t = base_type(e->type); + GB_ASSERT(t->kind == Type_Proc); + + bool is_fini = true; + + if (t->Proc.param_count != 0 || t->Proc.result_count != 0) { + gbString str = type_to_string(t); + error(e->token, "@(fini) procedures must have a signature type with no parameters nor results, got %s", str); + gb_string_free(str); + is_fini = false; + } + + if ((e->scope->flags & (ScopeFlag_File|ScopeFlag_Pkg)) == 0) { + error(e->token, "@(fini) procedures must be declared at the file scope"); + is_fini = false; + } + + if (is_fini) { + add_dependency_to_set(c, e); + array_add(&c->info.fini_procedures, e); + } } break; } @@ -2967,6 +2990,12 @@ gb_internal DECL_ATTRIBUTE_PROC(proc_decl_attribute) { } ac->init = true; return true; + } else if (name == "fini") { + if (value != nullptr) { + error(value, "'%.*s' expects no parameter, or a string literal containing \"file\" or \"package\"", LIT(name)); + } + ac->fini = true; + return true; } else if (name == "deferred") { if (value != nullptr) { Operand o = {}; @@ -3608,6 +3637,7 @@ gb_internal void check_collect_value_decl(CheckerContext *c, Ast *decl) { EntityVisiblityKind entity_visibility_kind = c->foreign_context.visibility_kind; bool is_test = false; bool is_init = false; + bool is_fini = false; for_array(i, vd->attributes) { Ast *attr = vd->attributes[i]; @@ -3667,6 +3697,8 @@ gb_internal void check_collect_value_decl(CheckerContext *c, Ast *decl) { is_test = true; } else if (name == "init") { is_init = true; + } else if (name == "fini") { + is_fini = true; } } } @@ -3800,8 +3832,12 @@ gb_internal void check_collect_value_decl(CheckerContext *c, Ast *decl) { if (is_test) { e->flags |= EntityFlag_Test; } - if (is_init) { + if (is_init && is_fini) { + error(name, "A procedure cannot be both declared as @(init) and @(fini)"); + } else if (is_init) { e->flags |= EntityFlag_Init; + } else if (is_fini) { + e->flags |= EntityFlag_Fini; } } else if (init->kind == Ast_ProcGroup) { ast_node(pg, ProcGroup, init); @@ -5627,9 +5663,14 @@ gb_internal GB_COMPARE_PROC(init_procedures_cmp) { return i32_cmp(x->token.pos.offset, y->token.pos.offset); } +gb_internal GB_COMPARE_PROC(fini_procedures_cmp) { + return init_procedures_cmp(b, a); +} + -gb_internal void check_sort_init_procedures(Checker *c) { +gb_internal void check_sort_init_and_fini_procedures(Checker *c) { gb_sort_array(c->info.init_procedures.data, c->info.init_procedures.count, init_procedures_cmp); + gb_sort_array(c->info.fini_procedures.data, c->info.fini_procedures.count, fini_procedures_cmp); } gb_internal void add_type_info_for_type_definitions(Checker *c) { @@ -5839,8 +5880,8 @@ 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("sort init procedures"); - check_sort_init_procedures(c); + TIME_SECTION("sort init and fini procedures"); + check_sort_init_and_fini_procedures(c); if (c->info.intrinsics_entry_point_usage.count > 0) { TIME_SECTION("check intrinsics.__entry_point usage"); diff --git a/src/checker.hpp b/src/checker.hpp index d461b1f6e..4c3b8725a 100644 --- a/src/checker.hpp +++ b/src/checker.hpp @@ -117,6 +117,7 @@ struct AttributeContext { bool disabled_proc : 1; bool test : 1; bool init : 1; + bool fini : 1; bool set_cold : 1; u32 optimization_mode; // ProcedureOptimizationMode i64 foreign_import_priority_index; @@ -351,6 +352,7 @@ struct CheckerInfo { Array testing_procedures; Array init_procedures; + Array fini_procedures; Array definitions; Array entities; diff --git a/src/entity.cpp b/src/entity.cpp index 4b0a6a3c8..0c3629b2b 100644 --- a/src/entity.cpp +++ b/src/entity.cpp @@ -75,6 +75,7 @@ enum EntityFlag : u64 { EntityFlag_Test = 1ull<<30, EntityFlag_Init = 1ull<<31, EntityFlag_Subtype = 1ull<<32, + EntityFlag_Fini = 1ull<<33, EntityFlag_CustomLinkName = 1ull<<40, EntityFlag_CustomLinkage_Internal = 1ull<<41, diff --git a/src/llvm_backend.cpp b/src/llvm_backend.cpp index 34c1ec9b4..6d35615a3 100644 --- a/src/llvm_backend.cpp +++ b/src/llvm_backend.cpp @@ -1161,6 +1161,34 @@ gb_internal lbProcedure *lb_create_startup_runtime(lbModule *main_module, lbProc return p; } +gb_internal lbProcedure *lb_create_cleanup_runtime(lbModule *main_module) { // Cleanup Runtime + Type *proc_type = alloc_type_proc(nullptr, nullptr, 0, nullptr, 0, false, ProcCC_Odin); + + lbProcedure *p = lb_create_dummy_procedure(main_module, str_lit(LB_CLEANUP_RUNTIME_PROC_NAME), proc_type); + p->is_startup = true; + + lb_begin_procedure_body(p); + + CheckerInfo *info = main_module->gen->info; + + for (Entity *e : info->fini_procedures) { + lbValue value = lb_find_procedure_value_from_entity(main_module, e); + lb_emit_call(p, value, {}, ProcInlining_none); + } + + lb_end_procedure_body(p); + + if (!main_module->debug_builder && LLVMVerifyFunction(p->value, LLVMReturnStatusAction)) { + gb_printf_err("LLVM CODE GEN FAILED FOR PROCEDURE: %s\n", "main"); + LLVMDumpValue(p->value); + gb_printf_err("\n\n\n\n"); + LLVMVerifyFunction(p->value, LLVMAbortProcessAction); + } + + return p; +} + + gb_internal WORKER_TASK_PROC(lb_generate_procedures_and_types_per_module) { lbModule *m = cast(lbModule *)data; for (Entity *e : m->global_procedures_and_types_to_create) { @@ -1328,6 +1356,7 @@ gb_internal WORKER_TASK_PROC(lb_llvm_function_pass_per_module) { if (m == &m->gen->default_module) { lb_llvm_function_pass_per_function_internal(m, m->gen->startup_type_info); lb_llvm_function_pass_per_function_internal(m, m->gen->startup_runtime); + lb_llvm_function_pass_per_function_internal(m, m->gen->cleanup_runtime); lb_llvm_function_pass_per_function_internal(m, m->gen->objc_names); } @@ -1674,7 +1703,7 @@ gb_internal bool lb_llvm_object_generation(lbGenerator *gen, bool do_threading) -gb_internal lbProcedure *lb_create_main_procedure(lbModule *m, lbProcedure *startup_runtime) { +gb_internal lbProcedure *lb_create_main_procedure(lbModule *m, lbProcedure *startup_runtime, lbProcedure *cleanup_runtime) { LLVMPassManagerRef default_function_pass_manager = LLVMCreateFunctionPassManagerForModule(m->mod); lb_populate_function_pass_manager(m, default_function_pass_manager, false, build_context.optimization_level); LLVMFinalizeFunctionPassManager(default_function_pass_manager); @@ -1793,7 +1822,7 @@ gb_internal lbProcedure *lb_create_main_procedure(lbModule *m, lbProcedure *star if (call_cleanup) { - lbValue cleanup_runtime_value = lb_find_runtime_value(m, str_lit("_cleanup_runtime")); + lbValue cleanup_runtime_value = {cleanup_runtime->value, cleanup_runtime->type}; lb_emit_call(p, cleanup_runtime_value, {}, ProcInlining_none); } @@ -2330,9 +2359,13 @@ gb_internal bool lb_generate_code(lbGenerator *gen) { gen->startup_type_info = lb_create_startup_type_info(default_module); gen->objc_names = lb_create_objc_names(default_module); - TIME_SECTION("LLVM Runtime Startup Creation (Global Variables)"); + TIME_SECTION("LLVM Runtime Startup Creation (Global Variables & @(init))"); gen->startup_runtime = lb_create_startup_runtime(default_module, gen->startup_type_info, gen->objc_names, global_variables); + TIME_SECTION("LLVM Runtime Cleanup Creation & @(fini)"); + gen->cleanup_runtime = lb_create_cleanup_runtime(default_module); + + if (build_context.ODIN_DEBUG) { for (auto const &entry : builtin_pkg->scope->elements) { Entity *e = entry.value; @@ -2352,7 +2385,7 @@ gb_internal bool lb_generate_code(lbGenerator *gen) { if (build_context.command_kind == Command_test && !already_has_entry_point) { TIME_SECTION("LLVM main"); - lb_create_main_procedure(default_module, gen->startup_runtime); + lb_create_main_procedure(default_module, gen->startup_runtime, gen->cleanup_runtime); } TIME_SECTION("LLVM Procedure Generation (missing)"); diff --git a/src/llvm_backend.hpp b/src/llvm_backend.hpp index 7bf287b49..0b3bc2a5a 100644 --- a/src/llvm_backend.hpp +++ b/src/llvm_backend.hpp @@ -208,6 +208,7 @@ struct lbGenerator { lbProcedure *startup_type_info; lbProcedure *startup_runtime; + lbProcedure *cleanup_runtime; lbProcedure *objc_names; }; @@ -540,6 +541,7 @@ gb_internal LLVMTypeRef OdinLLVMGetArrayElementType(LLVMTypeRef type); gb_internal LLVMTypeRef OdinLLVMGetVectorElementType(LLVMTypeRef type); #define LB_STARTUP_RUNTIME_PROC_NAME "__$startup_runtime" +#define LB_CLEANUP_RUNTIME_PROC_NAME "__$cleanup_runtime" #define LB_STARTUP_TYPE_INFO_PROC_NAME "__$startup_type_info" #define LB_TYPE_INFO_DATA_NAME "__$type_info_data" #define LB_TYPE_INFO_TYPES_NAME "__$type_info_types_data" -- cgit v1.2.3 From 8a2a70a3c2a7ac14687d100325e12b8d3d02256e Mon Sep 17 00:00:00 2001 From: gingerBill Date: Fri, 17 Feb 2023 13:00:37 +0000 Subject: Fix overriding procedure information for literals --- src/check_decl.cpp | 17 +++++++++++++++++ src/check_expr.cpp | 4 +++- src/check_type.cpp | 12 ++++++++---- src/checker.cpp | 4 ++-- src/checker.hpp | 4 ++-- src/llvm_backend_const.cpp | 1 - src/llvm_backend_expr.cpp | 2 +- 7 files changed, 33 insertions(+), 11 deletions(-) (limited to 'src/checker.cpp') diff --git a/src/check_decl.cpp b/src/check_decl.cpp index 63e6514e0..dc929cbca 100644 --- a/src/check_decl.cpp +++ b/src/check_decl.cpp @@ -1480,6 +1480,23 @@ gb_internal bool check_proc_body(CheckerContext *ctx_, Token token, DeclInfo *de ctx->curr_proc_sig = type; ctx->curr_proc_calling_convention = type->Proc.calling_convention; + if (ctx->proc_name == "sort") { + if (type->Proc.param_count > 0) { + TypeTuple *params = &type->Proc.params->Tuple; + for (Entity *e : params->variables) { + if (e->kind == Entity_Constant) { + Ast *ident = e->identifier.load(); + if (ident) { + add_entity(ctx, e->scope, ident, e); + ident->tav.mode = Addressing_Constant; + ident->tav.value = e->Constant.value; + ident->tav.type = e->type; + } + } + } + } + } + if (ctx->pkg->name != "runtime") { switch (type->Proc.calling_convention) { case ProcCC_None: diff --git a/src/check_expr.cpp b/src/check_expr.cpp index 58372f7a3..93db559f8 100644 --- a/src/check_expr.cpp +++ b/src/check_expr.cpp @@ -5418,7 +5418,9 @@ gb_internal CALL_ARGUMENT_CHECKER(check_call_arguments_internal) { data->score = score; data->result_type = final_proc_type->Proc.results; data->gen_entity = gen_entity; - add_type_and_value(c, ce->proc, Addressing_Value, final_proc_type, {}); + if (!are_types_identical(final_proc_type, ce->proc->tav.type)) { + add_type_and_value(c, ce->proc, Addressing_Value, final_proc_type, {}); + } } return err; diff --git a/src/check_type.cpp b/src/check_type.cpp index ec661134b..24ca8628e 100644 --- a/src/check_type.cpp +++ b/src/check_type.cpp @@ -1666,17 +1666,21 @@ gb_internal Type *check_get_params(CheckerContext *ctx, Scope *scope, Ast *_para if (is_poly_name) { bool valid = false; if (is_type_proc(op.type)) { - Entity *proc_entity = entity_from_expr(op.expr); - valid = (proc_entity != nullptr) && (op.value.kind == ExactValue_Procedure); - if (valid) { + Ast *expr = unparen_expr(op.expr); + Entity *proc_entity = entity_from_expr(expr); + if (proc_entity) { poly_const = exact_value_procedure(proc_entity->identifier.load() ? proc_entity->identifier.load() : op.expr); + valid = true; + } else if (expr->kind == Ast_ProcLit) { + poly_const = exact_value_procedure(expr); + valid = true; } } if (!valid) { if (op.mode == Addressing_Constant) { poly_const = op.value; } else { - error(op.expr, "Expected a constant value for this polymorphic name parameter"); + error(op.expr, "Expected a constant value for this polymorphic name parameter, got %s", expr_to_string(op.expr)); success = false; } } diff --git a/src/checker.cpp b/src/checker.cpp index 5163fe675..94bbb32e6 100644 --- a/src/checker.cpp +++ b/src/checker.cpp @@ -1416,7 +1416,7 @@ gb_internal isize type_info_index(CheckerInfo *info, Type *type, bool error_on_f } -gb_internal void add_untyped(CheckerContext *c, Ast *expr, AddressingMode mode, Type *type, ExactValue value) { +gb_internal void add_untyped(CheckerContext *c, Ast *expr, AddressingMode mode, Type *type, ExactValue const &value) { if (expr == nullptr) { return; } @@ -1433,7 +1433,7 @@ gb_internal void add_untyped(CheckerContext *c, Ast *expr, AddressingMode mode, check_set_expr_info(c, expr, mode, type, value); } -gb_internal void add_type_and_value(CheckerContext *ctx, Ast *expr, AddressingMode mode, Type *type, ExactValue value) { +gb_internal void add_type_and_value(CheckerContext *ctx, Ast *expr, AddressingMode mode, Type *type, ExactValue const &value) { if (expr == nullptr) { return; } diff --git a/src/checker.hpp b/src/checker.hpp index 4c3b8725a..b82612813 100644 --- a/src/checker.hpp +++ b/src/checker.hpp @@ -485,9 +485,9 @@ gb_internal void scope_lookup_parent (Scope *s, String const &name, Scope **s gb_internal Entity *scope_insert (Scope *s, Entity *entity); -gb_internal void add_type_and_value (CheckerContext *c, Ast *expression, AddressingMode mode, Type *type, ExactValue value); +gb_internal void add_type_and_value (CheckerContext *c, Ast *expression, AddressingMode mode, Type *type, ExactValue const &value); gb_internal ExprInfo *check_get_expr_info (CheckerContext *c, Ast *expr); -gb_internal void add_untyped (CheckerContext *c, Ast *expression, AddressingMode mode, Type *basic_type, ExactValue value); +gb_internal void add_untyped (CheckerContext *c, Ast *expression, AddressingMode mode, Type *basic_type, ExactValue const &value); gb_internal void add_entity_use (CheckerContext *c, Ast *identifier, Entity *entity); gb_internal void add_implicit_entity (CheckerContext *c, Ast *node, Entity *e); gb_internal void add_entity_and_decl_info(CheckerContext *c, Ast *identifier, Entity *e, DeclInfo *d, bool is_exported=true); diff --git a/src/llvm_backend_const.cpp b/src/llvm_backend_const.cpp index ee564bbf1..fc1598024 100644 --- a/src/llvm_backend_const.cpp +++ b/src/llvm_backend_const.cpp @@ -411,7 +411,6 @@ gb_internal lbValue lb_const_value(lbModule *m, Type *type, ExactValue value, bo Ast *expr = unparen_expr(value.value_procedure); if (expr->kind == Ast_ProcLit) { res = lb_generate_anonymous_proc_lit(m, str_lit("_proclit"), expr); - } else { Entity *e = entity_from_expr(expr); res = lb_find_procedure_value_from_entity(m, e); diff --git a/src/llvm_backend_expr.cpp b/src/llvm_backend_expr.cpp index 7cf8d56db..480831a68 100644 --- a/src/llvm_backend_expr.cpp +++ b/src/llvm_backend_expr.cpp @@ -3138,7 +3138,7 @@ gb_internal lbValue lb_build_expr_internal(lbProcedure *p, Ast *expr) { Entity *e = entity_from_expr(expr); e = strip_entity_wrapping(e); - GB_ASSERT_MSG(e != nullptr, "%s", expr_to_string(expr)); + GB_ASSERT_MSG(e != nullptr, "%s in %.*s %p", expr_to_string(expr), LIT(p->name), expr); if (e->kind == Entity_Builtin) { Token token = ast_token(expr); GB_PANIC("TODO(bill): lb_build_expr Entity_Builtin '%.*s'\n" -- cgit v1.2.3 From 2c4a478987e030e0891b4e317b47886ac6fd06fe Mon Sep 17 00:00:00 2001 From: gingerBill Date: Tue, 21 Mar 2023 13:30:58 +0000 Subject: Add `@(extra_linker_flags=)` --- src/checker.cpp | 12 ++++++++++++ src/checker.hpp | 1 + src/entity.cpp | 1 + src/main.cpp | 13 +++++++++++++ vendor/raylib/raylib.odin | 2 +- 5 files changed, 28 insertions(+), 1 deletion(-) (limited to 'src/checker.cpp') diff --git a/src/checker.cpp b/src/checker.cpp index 1bb437beb..696802e99 100644 --- a/src/checker.cpp +++ b/src/checker.cpp @@ -4447,6 +4447,14 @@ gb_internal DECL_ATTRIBUTE_PROC(foreign_import_decl_attribute) { ac->foreign_import_priority_index = exact_value_to_i64(ev); } return true; + } else if (name == "extra_linker_flags") { + ExactValue ev = check_decl_attribute_value(c, value); + if (ev.kind != ExactValue_String) { + error(elem, "Expected a string value for '%.*s'", LIT(name)); + } else { + ac->extra_linker_flags = ev.value_string; + } + return true; } return false; } @@ -4506,6 +4514,10 @@ gb_internal void check_add_foreign_import_decl(CheckerContext *ctx, Ast *decl) { if (ac.foreign_import_priority_index != 0) { e->LibraryName.priority_index = ac.foreign_import_priority_index; } + String extra_linker_flags = string_trim_whitespace(ac.extra_linker_flags); + if (extra_linker_flags.len != 0) { + e->LibraryName.extra_linker_flags = extra_linker_flags; + } if (has_asm_extension(fullpath)) { if (build_context.metrics.arch != TargetArch_amd64 || diff --git a/src/checker.hpp b/src/checker.hpp index b82612813..2918b7e83 100644 --- a/src/checker.hpp +++ b/src/checker.hpp @@ -121,6 +121,7 @@ struct AttributeContext { bool set_cold : 1; u32 optimization_mode; // ProcedureOptimizationMode i64 foreign_import_priority_index; + String extra_linker_flags; String objc_class; String objc_name; diff --git a/src/entity.cpp b/src/entity.cpp index 0c3629b2b..d6f4edece 100644 --- a/src/entity.cpp +++ b/src/entity.cpp @@ -259,6 +259,7 @@ struct Entity { Slice paths; String name; i64 priority_index; + String extra_linker_flags; } LibraryName; i32 Nil; struct { diff --git a/src/main.cpp b/src/main.cpp index 82c20cfe6..bbb28cdf8 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -278,6 +278,13 @@ gb_internal i32 linker_stage(lbGenerator *gen) { } } + for (Entity *e : gen->foreign_libraries) { + GB_ASSERT(e->kind == Entity_LibraryName); + if (e->LibraryName.extra_linker_flags.len != 0) { + lib_str = gb_string_append_fmt(lib_str, " %.*s", LIT(e->LibraryName.extra_linker_flags)); + } + } + if (build_context.build_mode == BuildMode_DynamicLibrary) { link_settings = gb_string_append_fmt(link_settings, " /DLL"); } else { @@ -449,6 +456,12 @@ gb_internal i32 linker_stage(lbGenerator *gen) { } } + for (Entity *e : gen->foreign_libraries) { + GB_ASSERT(e->kind == Entity_LibraryName); + if (e->LibraryName.extra_linker_flags.len != 0) { + lib_str = gb_string_append_fmt(lib_str, " %.*s", LIT(e->LibraryName.extra_linker_flags)); + } + } gbString object_files = gb_string_make(heap_allocator(), ""); defer (gb_string_free(object_files)); diff --git a/vendor/raylib/raylib.odin b/vendor/raylib/raylib.odin index 7e63d364d..661478b58 100644 --- a/vendor/raylib/raylib.odin +++ b/vendor/raylib/raylib.odin @@ -93,8 +93,8 @@ MAX_TEXT_BUFFER_LENGTH :: #config(RAYLIB_MAX_TEXT_BUFFER_LENGTH, 1024) #assert(size_of(rune) == size_of(c.int)) when ODIN_OS == .Windows { + @(extra_linker_flags="/NODEFAULTLIB:libcmt") foreign import lib { - "system:msvcrt.lib", "windows/raylib.lib", "system:Winmm.lib", "system:Gdi32.lib", -- cgit v1.2.3 From dc55e885888a9d036dafea2036c1907306e69d14 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Sat, 15 Apr 2023 16:04:04 +0100 Subject: Add `@(deferred_*_by_ptr=)` --- src/checker.cpp | 313 ++++++++++++++++++++++++++++++---------------- src/checker.hpp | 4 + src/llvm_backend_proc.cpp | 16 +++ 3 files changed, 222 insertions(+), 111 deletions(-) (limited to 'src/checker.cpp') diff --git a/src/checker.cpp b/src/checker.cpp index 696802e99..a6768d495 100644 --- a/src/checker.cpp +++ b/src/checker.cpp @@ -3081,6 +3081,54 @@ gb_internal DECL_ATTRIBUTE_PROC(proc_decl_attribute) { } error(elem, "Expected a procedure entity for '%.*s'", LIT(name)); return false; + } else if (name == "deferred_in_by_ptr") { + if (value != nullptr) { + Operand o = {}; + check_expr(c, &o, value); + Entity *e = entity_of_node(o.expr); + if (e != nullptr && e->kind == Entity_Procedure) { + if (ac->deferred_procedure.entity != nullptr) { + error(elem, "Previous usage of a 'deferred_*' attribute"); + } + ac->deferred_procedure.kind = DeferredProcedure_in_by_ptr; + ac->deferred_procedure.entity = e; + return true; + } + } + error(elem, "Expected a procedure entity for '%.*s'", LIT(name)); + return false; + } else if (name == "deferred_out_by_ptr") { + if (value != nullptr) { + Operand o = {}; + check_expr(c, &o, value); + Entity *e = entity_of_node(o.expr); + if (e != nullptr && e->kind == Entity_Procedure) { + if (ac->deferred_procedure.entity != nullptr) { + error(elem, "Previous usage of a 'deferred_*' attribute"); + } + ac->deferred_procedure.kind = DeferredProcedure_out_by_ptr; + ac->deferred_procedure.entity = e; + return true; + } + } + error(elem, "Expected a procedure entity for '%.*s'", LIT(name)); + return false; + } else if (name == "deferred_in_out_by_ptr") { + if (value != nullptr) { + Operand o = {}; + check_expr(c, &o, value); + Entity *e = entity_of_node(o.expr); + if (e != nullptr && e->kind == Entity_Procedure) { + if (ac->deferred_procedure.entity != nullptr) { + error(elem, "Previous usage of a 'deferred_*' attribute"); + } + ac->deferred_procedure.kind = DeferredProcedure_in_out_by_ptr; + ac->deferred_procedure.entity = e; + return true; + } + } + error(elem, "Expected a procedure entity for '%.*s'", LIT(name)); + return false; } else if (name == "link_name") { ExactValue ev = check_decl_attribute_value(c, value); @@ -5438,6 +5486,26 @@ gb_internal void add_untyped_expressions(CheckerInfo *cinfo, UntypedExprInfoMap map_clear(untyped); } +gb_internal Type *tuple_to_pointers(Type *ot) { + if (ot == nullptr) { + return nullptr; + } + GB_ASSERT(ot->kind == Type_Tuple); + + + Type *t = alloc_type_tuple(); + t->Tuple.variables = slice_make(heap_allocator(), ot->Tuple.variables.count); + + Scope *scope = nullptr; + for_array(i, t->Tuple.variables) { + Entity *e = ot->Tuple.variables[i]; + t->Tuple.variables[i] = alloc_entity_variable(scope, e->token, alloc_type_pointer(e->type)); + } + t->Tuple.is_packed = ot->Tuple.is_packed; + + return t; +} + gb_internal void check_deferred_procedures(Checker *c) { for (Entity *src = nullptr; mpsc_dequeue(&c->procs_with_deferred_to_check, &src); /**/) { GB_ASSERT(src->kind == Entity_Procedure); @@ -5449,18 +5517,13 @@ gb_internal void check_deferred_procedures(Checker *c) { char const *attribute = "deferred_none"; switch (dst_kind) { - case DeferredProcedure_none: - attribute = "deferred_none"; - break; - case DeferredProcedure_in: - attribute = "deferred_in"; - break; - case DeferredProcedure_out: - attribute = "deferred_out"; - break; - case DeferredProcedure_in_out: - attribute = "deferred_in_out"; - break; + case DeferredProcedure_none: attribute = "deferred_none"; break; + case DeferredProcedure_in: attribute = "deferred_in"; break; + case DeferredProcedure_out: attribute = "deferred_out"; break; + case DeferredProcedure_in_out: attribute = "deferred_in_out"; break; + case DeferredProcedure_in_by_ptr: attribute = "deferred_in_by_ptr"; break; + case DeferredProcedure_out_by_ptr: attribute = "deferred_out_by_ptr"; break; + case DeferredProcedure_in_out_by_ptr: attribute = "deferred_in_out_by_ptr"; break; } if (is_type_polymorphic(src->type) || is_type_polymorphic(dst->type)) { @@ -5474,118 +5537,146 @@ gb_internal void check_deferred_procedures(Checker *c) { Type *src_results = base_type(src->type)->Proc.results; Type *dst_params = base_type(dst->type)->Proc.params; - if (dst_kind == DeferredProcedure_none) { - if (dst_params == nullptr) { - // Okay - continue; - } + bool by_ptr = false; + switch (dst_kind) { + case DeferredProcedure_in_by_ptr: + by_ptr = true; + src_params = tuple_to_pointers(src_params); + break; + case DeferredProcedure_out_by_ptr: + by_ptr = true; + src_results = tuple_to_pointers(src_results); + break; + case DeferredProcedure_in_out_by_ptr: + by_ptr = true; + src_params = tuple_to_pointers(src_params); + src_results = tuple_to_pointers(src_results); + break; + } - error(src->token, "Deferred procedure '%.*s' must have no input parameters", LIT(dst->token.string)); - } else if (dst_kind == DeferredProcedure_in) { - if (src_params == nullptr && dst_params == nullptr) { - // Okay - continue; - } - if ((src_params == nullptr && dst_params != nullptr) || - (src_params != nullptr && dst_params == nullptr)) { - error(src->token, "Deferred procedure '%.*s' parameters do not match the inputs of initial procedure '%.*s'", LIT(src->token.string), LIT(dst->token.string)); - continue; - } + switch (dst_kind) { + case DeferredProcedure_none: + { + if (dst_params == nullptr) { + // Okay + continue; + } - GB_ASSERT(src_params->kind == Type_Tuple); - GB_ASSERT(dst_params->kind == Type_Tuple); + error(src->token, "Deferred procedure '%.*s' must have no input parameters", LIT(dst->token.string)); + } break; + case DeferredProcedure_in: + case DeferredProcedure_in_by_ptr: + { + if (src_params == nullptr && dst_params == nullptr) { + // Okay + continue; + } + if ((src_params == nullptr && dst_params != nullptr) || + (src_params != nullptr && dst_params == nullptr)) { + error(src->token, "Deferred procedure '%.*s' parameters do not match the inputs of initial procedure '%.*s'", LIT(src->token.string), LIT(dst->token.string)); + continue; + } - if (are_types_identical(src_params, dst_params)) { - // Okay! - } else { - gbString s = type_to_string(src_params); - gbString d = type_to_string(dst_params); - error(src->token, "Deferred procedure '%.*s' parameters do not match the inputs of initial procedure '%.*s':\n\t(%s) =/= (%s)", - LIT(src->token.string), LIT(dst->token.string), - s, d - ); - gb_string_free(d); - gb_string_free(s); - continue; - } + GB_ASSERT(src_params->kind == Type_Tuple); + GB_ASSERT(dst_params->kind == Type_Tuple); - } else if (dst_kind == DeferredProcedure_out) { - if (src_results == nullptr && dst_params == nullptr) { - // Okay - continue; - } - if ((src_results == nullptr && dst_params != nullptr) || - (src_results != nullptr && dst_params == nullptr)) { - error(src->token, "Deferred procedure '%.*s' parameters do not match the results of initial procedure '%.*s'", LIT(src->token.string), LIT(dst->token.string)); - continue; - } + if (are_types_identical(src_params, dst_params)) { + // Okay! + } else { + gbString s = type_to_string(src_params); + gbString d = type_to_string(dst_params); + error(src->token, "Deferred procedure '%.*s' parameters do not match the inputs of initial procedure '%.*s':\n\t(%s) =/= (%s)", + LIT(src->token.string), LIT(dst->token.string), + s, d + ); + gb_string_free(d); + gb_string_free(s); + continue; + } + } break; + case DeferredProcedure_out: + case DeferredProcedure_out_by_ptr: + { + if (src_results == nullptr && dst_params == nullptr) { + // Okay + continue; + } + if ((src_results == nullptr && dst_params != nullptr) || + (src_results != nullptr && dst_params == nullptr)) { + error(src->token, "Deferred procedure '%.*s' parameters do not match the results of initial procedure '%.*s'", LIT(src->token.string), LIT(dst->token.string)); + continue; + } - GB_ASSERT(src_results->kind == Type_Tuple); - GB_ASSERT(dst_params->kind == Type_Tuple); + GB_ASSERT(src_results->kind == Type_Tuple); + GB_ASSERT(dst_params->kind == Type_Tuple); - if (are_types_identical(src_results, dst_params)) { - // Okay! - } else { - gbString s = type_to_string(src_results); - gbString d = type_to_string(dst_params); - error(src->token, "Deferred procedure '%.*s' parameters do not match the results of initial procedure '%.*s':\n\t(%s) =/= (%s)", - LIT(src->token.string), LIT(dst->token.string), - s, d - ); - gb_string_free(d); - gb_string_free(s); - continue; - } - } else if (dst_kind == DeferredProcedure_in_out) { - if (src_params == nullptr && src_results == nullptr && dst_params == nullptr) { - // Okay - continue; - } + if (are_types_identical(src_results, dst_params)) { + // Okay! + } else { + gbString s = type_to_string(src_results); + gbString d = type_to_string(dst_params); + error(src->token, "Deferred procedure '%.*s' parameters do not match the results of initial procedure '%.*s':\n\t(%s) =/= (%s)", + LIT(src->token.string), LIT(dst->token.string), + s, d + ); + gb_string_free(d); + gb_string_free(s); + continue; + } + } break; + case DeferredProcedure_in_out: + case DeferredProcedure_in_out_by_ptr: + { + if (src_params == nullptr && src_results == nullptr && dst_params == nullptr) { + // Okay + continue; + } - GB_ASSERT(dst_params->kind == Type_Tuple); + GB_ASSERT(dst_params->kind == Type_Tuple); - Type *tsrc = alloc_type_tuple(); - auto &sv = tsrc->Tuple.variables; - auto const &dv = dst_params->Tuple.variables; - gb_unused(dv); + Type *tsrc = alloc_type_tuple(); + auto &sv = tsrc->Tuple.variables; + auto const &dv = dst_params->Tuple.variables; + gb_unused(dv); - isize len = 0; - if (src_params != nullptr) { - GB_ASSERT(src_params->kind == Type_Tuple); - len += src_params->Tuple.variables.count; - } - if (src_results != nullptr) { - GB_ASSERT(src_results->kind == Type_Tuple); - len += src_results->Tuple.variables.count; - } - slice_init(&sv, heap_allocator(), len); - isize offset = 0; - if (src_params != nullptr) { - for_array(i, src_params->Tuple.variables) { - sv[offset++] = src_params->Tuple.variables[i]; + isize len = 0; + if (src_params != nullptr) { + GB_ASSERT(src_params->kind == Type_Tuple); + len += src_params->Tuple.variables.count; } - } - if (src_results != nullptr) { - for_array(i, src_results->Tuple.variables) { - sv[offset++] = src_results->Tuple.variables[i]; + if (src_results != nullptr) { + GB_ASSERT(src_results->kind == Type_Tuple); + len += src_results->Tuple.variables.count; } - } - GB_ASSERT(offset == len); + slice_init(&sv, heap_allocator(), len); + isize offset = 0; + if (src_params != nullptr) { + for_array(i, src_params->Tuple.variables) { + sv[offset++] = src_params->Tuple.variables[i]; + } + } + if (src_results != nullptr) { + for_array(i, src_results->Tuple.variables) { + sv[offset++] = src_results->Tuple.variables[i]; + } + } + GB_ASSERT(offset == len); - if (are_types_identical(tsrc, dst_params)) { - // Okay! - } else { - gbString s = type_to_string(tsrc); - gbString d = type_to_string(dst_params); - error(src->token, "Deferred procedure '%.*s' parameters do not match the results of initial procedure '%.*s':\n\t(%s) =/= (%s)", - LIT(src->token.string), LIT(dst->token.string), - s, d - ); - gb_string_free(d); - gb_string_free(s); - continue; - } + if (are_types_identical(tsrc, dst_params)) { + // Okay! + } else { + gbString s = type_to_string(tsrc); + gbString d = type_to_string(dst_params); + error(src->token, "Deferred procedure '%.*s' parameters do not match the results of initial procedure '%.*s':\n\t(%s) =/= (%s)", + LIT(src->token.string), LIT(dst->token.string), + s, d + ); + gb_string_free(d); + gb_string_free(s); + continue; + } + } break; } } diff --git a/src/checker.hpp b/src/checker.hpp index 2918b7e83..1a95e2772 100644 --- a/src/checker.hpp +++ b/src/checker.hpp @@ -92,6 +92,10 @@ enum DeferredProcedureKind { DeferredProcedure_in, DeferredProcedure_out, DeferredProcedure_in_out, + + DeferredProcedure_in_by_ptr, + DeferredProcedure_out_by_ptr, + DeferredProcedure_in_out_by_ptr, }; struct DeferredProcedure { DeferredProcedureKind kind; diff --git a/src/llvm_backend_proc.cpp b/src/llvm_backend_proc.cpp index 02748663b..93c480e7f 100644 --- a/src/llvm_backend_proc.cpp +++ b/src/llvm_backend_proc.cpp @@ -1169,17 +1169,27 @@ gb_internal lbValue lb_emit_call(lbProcedure *p, lbValue value, Array c lbValue deferred = lb_find_procedure_value_from_entity(p->module, deferred_entity); + bool by_ptr = false; auto in_args = args; Array result_as_args = {}; switch (kind) { case DeferredProcedure_none: break; + case DeferredProcedure_in_by_ptr: + by_ptr = true; + /*fallthrough*/ case DeferredProcedure_in: result_as_args = array_clone(heap_allocator(), in_args); break; + case DeferredProcedure_out_by_ptr: + by_ptr = true; + /*fallthrough*/ case DeferredProcedure_out: result_as_args = lb_value_to_array(p, heap_allocator(), result); break; + case DeferredProcedure_in_out_by_ptr: + by_ptr = true; + /*fallthrough*/ case DeferredProcedure_in_out: { auto out_args = lb_value_to_array(p, heap_allocator(), result); @@ -1189,6 +1199,12 @@ gb_internal lbValue lb_emit_call(lbProcedure *p, lbValue value, Array c } break; } + if (by_ptr) { + for_array(i, result_as_args) { + lbValue arg_ptr = lb_address_from_load_or_generate_local(p, result_as_args[i]); + result_as_args[i] = arg_ptr; + } + } lb_add_defer_proc(p, p->scope_index, deferred, result_as_args); } -- cgit v1.2.3 From f5d9ca64f95ab47b6c2809275755ebca260c9448 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Thu, 20 Apr 2023 12:02:32 +0100 Subject: Begin work on new pseudo-architecture: wasm64p32 --- core/mem/alloc.odin | 2 +- core/runtime/core.odin | 2 +- core/runtime/entry_wasm.odin | 2 +- core/runtime/internal.odin | 2 +- core/runtime/procs.odin | 2 +- core/sync/futex_wasm.odin | 2 +- core/sync/primitives_wasm.odin | 2 +- src/build_settings.cpp | 53 +++++++++++++++++++++++++++++++----------- src/checker.cpp | 14 +++++------ src/llvm_abi.cpp | 2 +- src/llvm_backend.cpp | 2 +- src/llvm_backend_expr.cpp | 2 +- src/llvm_backend_utility.cpp | 2 +- vendor/wasm/js/dom.odin | 2 +- vendor/wasm/js/events.odin | 2 +- vendor/wasm/js/general.odin | 2 +- vendor/wasm/js/memory_js.odin | 2 +- 17 files changed, 62 insertions(+), 35 deletions(-) (limited to 'src/checker.cpp') diff --git a/core/mem/alloc.odin b/core/mem/alloc.odin index c7a21dcd4..e5b738af2 100644 --- a/core/mem/alloc.odin +++ b/core/mem/alloc.odin @@ -56,7 +56,7 @@ Allocator :: struct { DEFAULT_ALIGNMENT :: 2*align_of(rawptr) DEFAULT_PAGE_SIZE :: - 64 * 1024 when ODIN_ARCH == .wasm32 || ODIN_ARCH == .wasm64 else + 64 * 1024 when ODIN_ARCH == .wasm32 || ODIN_ARCH == .wasm64p32 else 16 * 1024 when ODIN_OS == .Darwin && ODIN_ARCH == .arm64 else 4 * 1024 diff --git a/core/runtime/core.odin b/core/runtime/core.odin index 4a3b6dcdb..058ca6161 100644 --- a/core/runtime/core.odin +++ b/core/runtime/core.odin @@ -471,7 +471,7 @@ Odin_OS_Type :: type_of(ODIN_OS) arm32, arm64, wasm32, - wasm64, + wasm64p32, } */ Odin_Arch_Type :: type_of(ODIN_ARCH) diff --git a/core/runtime/entry_wasm.odin b/core/runtime/entry_wasm.odin index 125abc756..235d5611b 100644 --- a/core/runtime/entry_wasm.odin +++ b/core/runtime/entry_wasm.odin @@ -1,5 +1,5 @@ //+private -//+build wasm32, wasm64 +//+build wasm32, wasm64p32 package runtime import "core:intrinsics" diff --git a/core/runtime/internal.odin b/core/runtime/internal.odin index 3c8cade39..ac3579490 100644 --- a/core/runtime/internal.odin +++ b/core/runtime/internal.odin @@ -3,7 +3,7 @@ package runtime import "core:intrinsics" @(private="file") -IS_WASM :: ODIN_ARCH == .wasm32 || ODIN_ARCH == .wasm64 +IS_WASM :: ODIN_ARCH == .wasm32 || ODIN_ARCH == .wasm64p32 @(private) RUNTIME_LINKAGE :: "strong" when ( diff --git a/core/runtime/procs.odin b/core/runtime/procs.odin index 510abcbb9..3a433c3bf 100644 --- a/core/runtime/procs.odin +++ b/core/runtime/procs.odin @@ -25,7 +25,7 @@ when ODIN_NO_CRT && ODIN_OS == .Windows { RtlMoveMemory(dst, src, len) return dst } -} else when ODIN_NO_CRT || (ODIN_ARCH == .wasm32 || ODIN_ARCH == .wasm64) { +} else when ODIN_NO_CRT || (ODIN_ARCH == .wasm32 || ODIN_ARCH == .wasm64p32) { @(link_name="memset", linkage="strong", require) memset :: proc "c" (ptr: rawptr, val: i32, len: int) -> rawptr { if ptr != nil && len != 0 { diff --git a/core/sync/futex_wasm.odin b/core/sync/futex_wasm.odin index 621f4edaa..248542836 100644 --- a/core/sync/futex_wasm.odin +++ b/core/sync/futex_wasm.odin @@ -1,5 +1,5 @@ //+private -//+build wasm32, wasm64 +//+build wasm32, wasm64p32 package sync import "core:intrinsics" diff --git a/core/sync/primitives_wasm.odin b/core/sync/primitives_wasm.odin index ac36404d9..f8d9ab657 100644 --- a/core/sync/primitives_wasm.odin +++ b/core/sync/primitives_wasm.odin @@ -1,5 +1,5 @@ //+private -//+build wasm32, wasm64 +//+build wasm32, wasm64p32 package sync _current_thread_id :: proc "contextless" () -> int { diff --git a/src/build_settings.cpp b/src/build_settings.cpp index b4a6f2a12..63997c2d1 100644 --- a/src/build_settings.cpp +++ b/src/build_settings.cpp @@ -35,7 +35,7 @@ enum TargetArchKind : u16 { TargetArch_arm32, TargetArch_arm64, TargetArch_wasm32, - TargetArch_wasm64, + TargetArch_wasm64p32, TargetArch_COUNT, }; @@ -81,7 +81,7 @@ gb_global String target_arch_names[TargetArch_COUNT] = { str_lit("arm32"), str_lit("arm64"), str_lit("wasm32"), - str_lit("wasm64"), + str_lit("wasm64p32"), }; gb_global String target_endian_names[TargetEndian_COUNT] = { @@ -475,14 +475,32 @@ gb_global TargetMetrics target_wasi_wasm32 = { }; -gb_global TargetMetrics target_js_wasm64 = { +gb_global TargetMetrics target_freestanding_wasm64p32 = { + TargetOs_freestanding, + TargetArch_wasm64p32, + 4, 8, 8, 16, + str_lit("wasm32-freestanding-js"), + str_lit("e-m:e-p:32:32-i64:64-n32:64-S128"), +}; + +gb_global TargetMetrics target_js_wasm64p32 = { TargetOs_js, - TargetArch_wasm64, - 8, 8, 8, 16, - str_lit("wasm64-js-js"), - str_lit(""), + TargetArch_wasm64p32, + 4, 8, 8, 16, + str_lit("wasm32-js-js"), + str_lit("e-m:e-p:32:32-i64:64-n32:64-S128"), }; +gb_global TargetMetrics target_wasi_wasm64p32 = { + TargetOs_wasi, + TargetArch_wasm32, + 4, 8, 8, 16, + str_lit("wasm32-wasi-js"), + str_lit("e-m:e-p:32:32-i64:64-n32:64-S128"), +}; + + + gb_global TargetMetrics target_freestanding_amd64_sysv = { TargetOs_freestanding, TargetArch_amd64, @@ -502,20 +520,29 @@ struct NamedTargetMetrics { gb_global NamedTargetMetrics named_targets[] = { { str_lit("darwin_amd64"), &target_darwin_amd64 }, { str_lit("darwin_arm64"), &target_darwin_arm64 }, + { str_lit("essence_amd64"), &target_essence_amd64 }, + { str_lit("linux_i386"), &target_linux_i386 }, { str_lit("linux_amd64"), &target_linux_amd64 }, { str_lit("linux_arm64"), &target_linux_arm64 }, { str_lit("linux_arm32"), &target_linux_arm32 }, + { str_lit("windows_i386"), &target_windows_i386 }, { str_lit("windows_amd64"), &target_windows_amd64 }, + { str_lit("freebsd_i386"), &target_freebsd_i386 }, { str_lit("freebsd_amd64"), &target_freebsd_amd64 }, + { str_lit("openbsd_amd64"), &target_openbsd_amd64 }, + { str_lit("freestanding_wasm32"), &target_freestanding_wasm32 }, { str_lit("wasi_wasm32"), &target_wasi_wasm32 }, { str_lit("js_wasm32"), &target_js_wasm32 }, - // { str_lit("js_wasm64"), &target_js_wasm64 }, + + { str_lit("freestanding_wasm64p32"), &target_freestanding_wasm64p32 }, + { str_lit("js_wasm64p32"), &target_js_wasm64p32 }, + { str_lit("wasi_wasm64p32"), &target_wasi_wasm64p32 }, { str_lit("freestanding_amd64_sysv"), &target_freestanding_amd64_sysv }, }; @@ -624,7 +651,7 @@ gb_internal bool find_library_collection_path(String name, String *path) { gb_internal bool is_arch_wasm(void) { switch (build_context.metrics.arch) { case TargetArch_wasm32: - case TargetArch_wasm64: + case TargetArch_wasm64p32: return true; } return false; @@ -642,7 +669,7 @@ gb_internal bool is_arch_x86(void) { gb_internal bool allow_check_foreign_filepath(void) { switch (build_context.metrics.arch) { case TargetArch_wasm32: - case TargetArch_wasm64: + case TargetArch_wasm64p32: return false; } return true; @@ -1266,9 +1293,9 @@ gb_internal void init_build_context(TargetMetrics *cross_target) { // link_flags = gb_string_appendc(link_flags, "--export-all "); // link_flags = gb_string_appendc(link_flags, "--export-table "); link_flags = gb_string_appendc(link_flags, "--allow-undefined "); - if (bc->metrics.arch == TargetArch_wasm64) { - link_flags = gb_string_appendc(link_flags, "-mwasm64 "); - } + // if (bc->metrics.arch == TargetArch_wasm64) { + // link_flags = gb_string_appendc(link_flags, "-mwasm64 "); + // } if (bc->no_entry_point) { link_flags = gb_string_appendc(link_flags, "--no-entry "); } diff --git a/src/checker.cpp b/src/checker.cpp index a6768d495..f820a1468 100644 --- a/src/checker.cpp +++ b/src/checker.cpp @@ -971,13 +971,13 @@ gb_internal void init_universal(void) { { GlobalEnumValue values[TargetArch_COUNT] = { - {"Unknown", TargetArch_Invalid}, - {"amd64", TargetArch_amd64}, - {"i386", TargetArch_i386}, - {"arm32", TargetArch_arm32}, - {"arm64", TargetArch_arm64}, - {"wasm32", TargetArch_wasm32}, - {"wasm64", TargetArch_wasm64}, + {"Unknown", TargetArch_Invalid}, + {"amd64", TargetArch_amd64}, + {"i386", TargetArch_i386}, + {"arm32", TargetArch_arm32}, + {"arm64", TargetArch_arm64}, + {"wasm32", TargetArch_wasm32}, + {"wasm64p32", TargetArch_wasm64p32}, }; auto fields = add_global_enum_type(str_lit("Odin_Arch_Type"), values, gb_count_of(values)); diff --git a/src/llvm_abi.cpp b/src/llvm_abi.cpp index dabdd6829..3fc68644d 100644 --- a/src/llvm_abi.cpp +++ b/src/llvm_abi.cpp @@ -1467,7 +1467,7 @@ gb_internal LB_ABI_INFO(lb_get_abi_info_internal) { case TargetArch_arm64: return lbAbiArm64::abi_info(c, arg_types, arg_count, return_type, return_is_defined, return_is_tuple, calling_convention); case TargetArch_wasm32: - case TargetArch_wasm64: + case TargetArch_wasm64p32: return lbAbiWasm::abi_info(c, arg_types, arg_count, return_type, return_is_defined, return_is_tuple, calling_convention); } diff --git a/src/llvm_backend.cpp b/src/llvm_backend.cpp index 4d8e13f0f..62fa52490 100644 --- a/src/llvm_backend.cpp +++ b/src/llvm_backend.cpp @@ -1975,7 +1975,7 @@ gb_internal bool lb_generate_code(lbGenerator *gen) { LLVMInitializeAArch64Disassembler(); break; case TargetArch_wasm32: - case TargetArch_wasm64: + case TargetArch_wasm64p32: LLVMInitializeWebAssemblyTargetInfo(); LLVMInitializeWebAssemblyTarget(); LLVMInitializeWebAssemblyTargetMC(); diff --git a/src/llvm_backend_expr.cpp b/src/llvm_backend_expr.cpp index 028e90f51..381c9d46a 100644 --- a/src/llvm_backend_expr.cpp +++ b/src/llvm_backend_expr.cpp @@ -528,7 +528,7 @@ gb_internal bool lb_is_matrix_simdable(Type *t) { return true; case TargetArch_i386: case TargetArch_wasm32: - case TargetArch_wasm64: + case TargetArch_wasm64p32: return false; } } diff --git a/src/llvm_backend_utility.cpp b/src/llvm_backend_utility.cpp index 99deca5e9..758657657 100644 --- a/src/llvm_backend_utility.cpp +++ b/src/llvm_backend_utility.cpp @@ -1685,7 +1685,7 @@ gb_internal lbValue lb_emit_mul_add(lbProcedure *p, lbValue a, lbValue b, lbValu break; case TargetArch_i386: case TargetArch_wasm32: - case TargetArch_wasm64: + case TargetArch_wasm64p32: is_possible = false; break; } diff --git a/vendor/wasm/js/dom.odin b/vendor/wasm/js/dom.odin index d650dd70a..2662c4201 100644 --- a/vendor/wasm/js/dom.odin +++ b/vendor/wasm/js/dom.odin @@ -1,4 +1,4 @@ -//+build js wasm32, js wasm64 +//+build js wasm32, js wasm64p32 package wasm_js_interface foreign import dom_lib "odin_dom" diff --git a/vendor/wasm/js/events.odin b/vendor/wasm/js/events.odin index 136c0610d..f14d7054e 100644 --- a/vendor/wasm/js/events.odin +++ b/vendor/wasm/js/events.odin @@ -1,4 +1,4 @@ -//+build js wasm32, js wasm64 +//+build js wasm32, js wasm64p32 package wasm_js_interface foreign import dom_lib "odin_dom" diff --git a/vendor/wasm/js/general.odin b/vendor/wasm/js/general.odin index 0f6a9589c..513c60a6f 100644 --- a/vendor/wasm/js/general.odin +++ b/vendor/wasm/js/general.odin @@ -1,4 +1,4 @@ -//+build js wasm32, js wasm64 +//+build js wasm32, js wasm64p32 package wasm_js_interface foreign import "odin_env" diff --git a/vendor/wasm/js/memory_js.odin b/vendor/wasm/js/memory_js.odin index efbf89445..cdeb58128 100644 --- a/vendor/wasm/js/memory_js.odin +++ b/vendor/wasm/js/memory_js.odin @@ -1,4 +1,4 @@ -//+build js wasm32, js wasm64 +//+build js wasm32, js wasm64p32 package wasm_js_interface import "core:mem" -- cgit v1.2.3 From f5dcbf517b88d7479fa12d5f3b59183a447cae6f Mon Sep 17 00:00:00 2001 From: Jon Lipstate Date: Sun, 30 Apr 2023 18:36:00 -0700 Subject: helpful errors custom-attrs --- src/checker.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'src/checker.cpp') diff --git a/src/checker.cpp b/src/checker.cpp index a6768d495..3e9b46407 100644 --- a/src/checker.cpp +++ b/src/checker.cpp @@ -3507,6 +3507,7 @@ gb_internal void check_decl_attributes(CheckerContext *c, Array const &at if (!proc(c, elem, name, value, ac)) { if (!build_context.ignore_unknown_attributes) { error(elem, "Unknown attribute element name '%.*s'", LIT(name)); + error_line("\tDid you forget to use build flag '-ignore-unknown-attributes'?\n"); } } } -- cgit v1.2.3 From 8bf32ac697ea21ff3b37e5b31fe0fc10e700c9a4 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Mon, 22 May 2023 12:53:29 +0100 Subject: Minor change to handling of propagation of errors with `---` as a value --- src/check_decl.cpp | 9 ++++----- src/check_expr.cpp | 45 +++++++++++++++++++++----------------------- src/check_type.cpp | 6 +++--- src/checker.cpp | 4 ++-- src/llvm_backend.cpp | 10 ++-------- src/llvm_backend_const.cpp | 2 +- src/llvm_backend_debug.cpp | 2 +- src/llvm_backend_expr.cpp | 16 ++++++++-------- src/llvm_backend_general.cpp | 4 ++-- src/llvm_backend_proc.cpp | 8 ++++---- src/parser.cpp | 14 +++++++------- src/parser.hpp | 2 +- src/parser_pos.cpp | 4 ++-- src/tokenizer.cpp | 6 +++--- src/types.cpp | 19 ++++++++----------- 15 files changed, 69 insertions(+), 82 deletions(-) (limited to 'src/checker.cpp') diff --git a/src/check_decl.cpp b/src/check_decl.cpp index b16215571..84b0d39d8 100644 --- a/src/check_decl.cpp +++ b/src/check_decl.cpp @@ -70,13 +70,12 @@ gb_internal Type *check_init_variable(CheckerContext *ctx, Entity *e, Operand *o // NOTE(bill): Use the type of the operand Type *t = operand->type; if (is_type_untyped(t)) { - if (t == t_invalid || is_type_untyped_nil(t)) { - error(e->token, "Invalid use of untyped nil in %.*s", LIT(context_name)); + if (is_type_untyped_uninit(t)) { + error(e->token, "Invalid use of --- in %.*s", LIT(context_name)); e->type = t_invalid; return nullptr; - } - if (t == t_invalid || is_type_untyped_undef(t)) { - error(e->token, "Invalid use of --- in %.*s", LIT(context_name)); + } else if (t == t_invalid || is_type_untyped_nil(t)) { + error(e->token, "Invalid use of untyped nil in %.*s", LIT(context_name)); e->type = t_invalid; return nullptr; } diff --git a/src/check_expr.cpp b/src/check_expr.cpp index 20a690e1e..830b5315d 100644 --- a/src/check_expr.cpp +++ b/src/check_expr.cpp @@ -646,11 +646,8 @@ gb_internal i64 check_distance_between_types(CheckerContext *c, Operand *operand Type *src = base_type(s); Type *dst = base_type(type); - if (is_type_untyped_undef(src)) { - if (type_has_undef(dst)) { - return 1; - } - return -1; + if (is_type_untyped_uninit(src)) { + return 1; } if (is_type_untyped_nil(src)) { @@ -993,13 +990,13 @@ gb_internal void check_assignment(CheckerContext *c, Operand *operand, Type *typ if (is_type_untyped(operand->type)) { Type *target_type = type; if (type == nullptr || is_type_any(type)) { - if (type == nullptr && is_type_untyped_nil(operand->type)) { - error(operand->expr, "Use of untyped nil in %.*s", LIT(context_name)); + if (type == nullptr && is_type_untyped_uninit(operand->type)) { + error(operand->expr, "Use of --- in %.*s", LIT(context_name)); operand->mode = Addressing_Invalid; return; } - if (type == nullptr && is_type_untyped_undef(operand->type)) { - error(operand->expr, "Use of --- in %.*s", LIT(context_name)); + if (type == nullptr && is_type_untyped_nil(operand->type)) { + error(operand->expr, "Use of untyped nil in %.*s", LIT(context_name)); operand->mode = Addressing_Invalid; return; } @@ -3969,7 +3966,7 @@ gb_internal void convert_to_typed(CheckerContext *c, Operand *operand, Type *tar case Type_Union: - if (!is_operand_nil(*operand) && !is_operand_undef(*operand)) { + if (!is_operand_nil(*operand) && !is_operand_uninit(*operand)) { TEMPORARY_ALLOCATOR_GUARD(); isize count = t->Union.variants.count; @@ -4036,8 +4033,8 @@ gb_internal void convert_to_typed(CheckerContext *c, Operand *operand, Type *tar error_line("\n\n"); return; - } else if (is_type_untyped_undef(operand->type) && type_has_undef(target_type)) { - target_type = t_untyped_undef; + } else if (is_type_untyped_uninit(operand->type)) { + target_type = t_untyped_uninit; } else if (!is_type_untyped_nil(operand->type) || !type_has_nil(target_type)) { begin_error_block(); defer (end_error_block()); @@ -4070,8 +4067,8 @@ gb_internal void convert_to_typed(CheckerContext *c, Operand *operand, Type *tar default: - if (is_type_untyped_undef(operand->type) && type_has_undef(target_type)) { - target_type = t_untyped_undef; + if (is_type_untyped_uninit(operand->type)) { + target_type = t_untyped_uninit; } else if (is_type_untyped_nil(operand->type) && type_has_nil(target_type)) { target_type = t_untyped_nil; } else { @@ -4083,8 +4080,8 @@ gb_internal void convert_to_typed(CheckerContext *c, Operand *operand, Type *tar } if (is_type_any(target_type) && is_type_untyped(operand->type)) { - if (is_type_untyped_nil(operand->type) && is_type_untyped_undef(operand->type)) { - + if (is_type_untyped_nil(operand->type) && is_type_untyped_uninit(operand->type)) { + } else { target_type = default_type(operand->type); } @@ -5197,9 +5194,9 @@ gb_internal bool check_unpack_arguments(CheckerContext *ctx, Entity **lhs, isize } Ast *rhs_expr = unparen_expr(rhs[i]); - if (allow_undef && rhs_expr != nullptr && rhs_expr->kind == Ast_Undef) { + if (allow_undef && rhs_expr != nullptr && rhs_expr->kind == Ast_Uninit) { // NOTE(bill): Just handle this very specific logic here - o.type = t_untyped_undef; + o.type = t_untyped_uninit; o.mode = Addressing_Value; o.expr = rhs[i]; add_type_and_value(c, rhs[i], o.mode, o.type, o.value); @@ -7167,11 +7164,11 @@ gb_internal bool check_set_index_data(Operand *o, Type *t, bool indirection, i64 } gb_internal bool ternary_compare_types(Type *x, Type *y) { - if (is_type_untyped_undef(x) && type_has_undef(y)) { + if (is_type_untyped_uninit(x)) { return true; } else if (is_type_untyped_nil(x) && type_has_nil(y)) { return true; - } else if (is_type_untyped_undef(y) && type_has_undef(x)) { + } else if (is_type_untyped_uninit(y)) { return true; } else if (is_type_untyped_nil(y) && type_has_nil(x)) { return true; @@ -7708,7 +7705,7 @@ gb_internal ExprKind check_ternary_if_expr(CheckerContext *c, Operand *o, Ast *n } o->type = x.type; - if (is_type_untyped_nil(o->type) || is_type_untyped_undef(o->type)) { + if (is_type_untyped_nil(o->type) || is_type_untyped_uninit(o->type)) { o->type = y.type; } @@ -9601,9 +9598,9 @@ gb_internal ExprKind check_expr_base_internal(CheckerContext *c, Operand *o, Ast check_ident(c, o, node, nullptr, type_hint, false); case_end; - case_ast_node(u, Undef, node); + case_ast_node(u, Uninit, node); o->mode = Addressing_Value; - o->type = t_untyped_undef; + o->type = t_untyped_uninit; error(node, "Use of --- outside of variable declaration"); case_end; @@ -10167,7 +10164,7 @@ gb_internal gbString write_expr_to_string(gbString str, Ast *node, bool shorthan str = string_append_string(str, bd->name.string); case_end; - case_ast_node(ud, Undef, node); + case_ast_node(ud, Uninit, node); str = gb_string_appendc(str, "---"); case_end; diff --git a/src/check_type.cpp b/src/check_type.cpp index dfe774f6b..bbfc25a12 100644 --- a/src/check_type.cpp +++ b/src/check_type.cpp @@ -135,7 +135,7 @@ gb_internal void check_struct_fields(CheckerContext *ctx, Ast *node, Slicemodule, var.var); - if (is_type_untyped_undef(init.type)) { - // LLVMSetInitializer(var.var.value, LLVMGetUndef(global_type)); - LLVMSetInitializer(var.var.value, LLVMConstNull(global_type)); - var.is_initialized = true; - continue; - } else if (is_type_untyped_nil(init.type)) { + if (is_type_untyped_nil(init.type)) { LLVMSetInitializer(var.var.value, LLVMConstNull(global_type)); var.is_initialized = true; continue; @@ -2363,8 +2358,7 @@ gb_internal bool lb_generate_code(lbGenerator *gen) { } } } - if (!var.is_initialized && - (is_type_untyped_nil(tav.type) || is_type_untyped_undef(tav.type))) { + if (!var.is_initialized && is_type_untyped_nil(tav.type)) { var.is_initialized = true; } } diff --git a/src/llvm_backend_const.cpp b/src/llvm_backend_const.cpp index 8db6e2a1f..ea25a4594 100644 --- a/src/llvm_backend_const.cpp +++ b/src/llvm_backend_const.cpp @@ -1,6 +1,6 @@ gb_internal bool lb_is_const(lbValue value) { LLVMValueRef v = value.value; - if (is_type_untyped_nil(value.type) || is_type_untyped_undef(value.type)) { + if (is_type_untyped_nil(value.type)) { // TODO(bill): Is this correct behaviour? return true; } diff --git a/src/llvm_backend_debug.cpp b/src/llvm_backend_debug.cpp index fd26c41a0..bec719a4a 100644 --- a/src/llvm_backend_debug.cpp +++ b/src/llvm_backend_debug.cpp @@ -282,7 +282,7 @@ gb_internal LLVMMetadataRef lb_debug_type_internal(lbModule *m, Type *type) { case Basic_UntypedString: GB_PANIC("Basic_UntypedString"); break; case Basic_UntypedRune: GB_PANIC("Basic_UntypedRune"); break; case Basic_UntypedNil: GB_PANIC("Basic_UntypedNil"); break; - case Basic_UntypedUndef: GB_PANIC("Basic_UntypedUndef"); break; + case Basic_UntypedUninit: GB_PANIC("Basic_UntypedUninit"); break; default: GB_PANIC("Basic Unhandled"); break; } diff --git a/src/llvm_backend_expr.cpp b/src/llvm_backend_expr.cpp index 69443c9a3..143e38a8d 100644 --- a/src/llvm_backend_expr.cpp +++ b/src/llvm_backend_expr.cpp @@ -1486,12 +1486,12 @@ gb_internal lbValue lb_emit_conv(lbProcedure *p, lbValue value, Type *t) { GB_ASSERT(src != nullptr); GB_ASSERT(dst != nullptr); + if (is_type_untyped_uninit(src)) { + return lb_const_undef(m, t); + } if (is_type_untyped_nil(src)) { return lb_const_nil(m, t); } - if (is_type_untyped_undef(src)) { - return lb_const_undef(m, t); - } if (LLVMIsConstant(value.value)) { if (is_type_any(dst)) { @@ -2132,12 +2132,12 @@ gb_internal lbValue lb_emit_conv(lbProcedure *p, lbValue value, Type *t) { if (is_type_any(dst)) { + if (is_type_untyped_uninit(src)) { + return lb_const_undef(p->module, t); + } if (is_type_untyped_nil(src)) { return lb_const_nil(p->module, t); } - if (is_type_untyped_undef(src)) { - return lb_const_undef(p->module, t); - } lbAddr result = lb_add_local_generated(p, t, true); @@ -3136,11 +3136,11 @@ gb_internal lbValue lb_build_expr_internal(lbProcedure *p, Ast *expr) { return lb_addr_load(p, lb_build_addr(p, expr)); case_end; - case_ast_node(u, Undef, expr) + case_ast_node(u, Uninit, expr) lbValue res = {}; if (is_type_untyped(type)) { res.value = nullptr; - res.type = t_untyped_undef; + res.type = t_untyped_uninit; } else { res.value = LLVMGetUndef(lb_type(m, type)); res.type = type; diff --git a/src/llvm_backend_general.cpp b/src/llvm_backend_general.cpp index 7d2f574fe..628c1e5fa 100644 --- a/src/llvm_backend_general.cpp +++ b/src/llvm_backend_general.cpp @@ -677,7 +677,7 @@ gb_internal void lb_addr_store(lbProcedure *p, lbAddr addr, lbValue value) { return; } GB_ASSERT(value.type != nullptr); - if (is_type_untyped_undef(value.type)) { + if (is_type_untyped_uninit(value.type)) { Type *t = lb_addr_type(addr); value.type = t; value.value = LLVMGetUndef(lb_type(p->module, t)); @@ -1828,7 +1828,7 @@ gb_internal LLVMTypeRef lb_type_internal(lbModule *m, Type *type) { case Basic_UntypedString: GB_PANIC("Basic_UntypedString"); break; case Basic_UntypedRune: GB_PANIC("Basic_UntypedRune"); break; case Basic_UntypedNil: GB_PANIC("Basic_UntypedNil"); break; - case Basic_UntypedUndef: GB_PANIC("Basic_UntypedUndef"); break; + case Basic_UntypedUninit: GB_PANIC("Basic_UntypedUninit"); break; } break; case Type_Named: diff --git a/src/llvm_backend_proc.cpp b/src/llvm_backend_proc.cpp index ddf058668..b8353a466 100644 --- a/src/llvm_backend_proc.cpp +++ b/src/llvm_backend_proc.cpp @@ -3218,10 +3218,10 @@ gb_internal lbValue lb_build_call_expr_internal(lbProcedure *p, Ast *expr) { Entity *e = params->variables[i]; if (args[i].type == nullptr) { continue; + } else if (is_type_untyped_uninit(args[i].type)) { + args[i] = lb_const_undef(m, e->type); } else if (is_type_untyped_nil(args[i].type)) { args[i] = lb_const_nil(m, e->type); - } else if (is_type_untyped_undef(args[i].type)) { - args[i] = lb_const_undef(m, e->type); } } @@ -3409,10 +3409,10 @@ gb_internal lbValue lb_build_call_expr_internal(lbProcedure *p, Ast *expr) { Entity *e = param_tuple->variables[i]; if (args[i].type == nullptr) { continue; + } else if (is_type_untyped_uninit(args[i].type)) { + args[i] = lb_const_undef(m, e->type); } else if (is_type_untyped_nil(args[i].type)) { args[i] = lb_const_nil(m, e->type); - } else if (is_type_untyped_undef(args[i].type)) { - args[i] = lb_const_undef(m, e->type); } } } diff --git a/src/parser.cpp b/src/parser.cpp index 698ba99ab..bb492fca9 100644 --- a/src/parser.cpp +++ b/src/parser.cpp @@ -115,7 +115,7 @@ gb_internal Ast *clone_ast(Ast *node, AstFile *f) { n->Ident.entity = nullptr; break; case Ast_Implicit: break; - case Ast_Undef: break; + case Ast_Uninit: break; case Ast_BasicLit: break; case Ast_BasicDirective: break; @@ -646,9 +646,9 @@ gb_internal Ast *ast_implicit(AstFile *f, Token token) { result->Implicit = token; return result; } -gb_internal Ast *ast_undef(AstFile *f, Token token) { - Ast *result = alloc_ast_node(f, Ast_Undef); - result->Undef = token; +gb_internal Ast *ast_uninit(AstFile *f, Token token) { + Ast *result = alloc_ast_node(f, Ast_Uninit); + result->Uninit = token; return result; } @@ -2092,8 +2092,8 @@ gb_internal Ast *parse_operand(AstFile *f, bool lhs) { case Token_Ident: return parse_ident(f); - case Token_Undef: - return ast_undef(f, expect_token(f, Token_Undef)); + case Token_Uninit: + return ast_uninit(f, expect_token(f, Token_Uninit)); case Token_context: return ast_implicit(f, expect_token(f, Token_context)); @@ -2292,7 +2292,7 @@ gb_internal Ast *parse_operand(AstFile *f, bool lhs) { skip_possible_newline_for_literal(f); - if (allow_token(f, Token_Undef)) { + if (allow_token(f, Token_Uninit)) { if (where_token.kind != Token_Invalid) { syntax_error(where_token, "'where' clauses are not allowed on procedure literals without a defined body (replaced with ---)"); } diff --git a/src/parser.hpp b/src/parser.hpp index aea3bbf21..d4883f287 100644 --- a/src/parser.hpp +++ b/src/parser.hpp @@ -373,7 +373,7 @@ gb_global char const *union_type_kind_strings[UnionType_COUNT] = { Entity *entity; \ }) \ AST_KIND(Implicit, "implicit", Token) \ - AST_KIND(Undef, "undef", Token) \ + AST_KIND(Uninit, "uninitialized value", Token) \ AST_KIND(BasicLit, "basic literal", struct { \ Token token; \ }) \ diff --git a/src/parser_pos.cpp b/src/parser_pos.cpp index 1274f05a0..52d49e897 100644 --- a/src/parser_pos.cpp +++ b/src/parser_pos.cpp @@ -2,7 +2,7 @@ gb_internal Token ast_token(Ast *node) { switch (node->kind) { case Ast_Ident: return node->Ident.token; case Ast_Implicit: return node->Implicit; - case Ast_Undef: return node->Undef; + case Ast_Uninit: return node->Uninit; case Ast_BasicLit: return node->BasicLit.token; case Ast_BasicDirective: return node->BasicDirective.token; case Ast_ProcGroup: return node->ProcGroup.token; @@ -137,7 +137,7 @@ Token ast_end_token(Ast *node) { return empty_token; case Ast_Ident: return node->Ident.token; case Ast_Implicit: return node->Implicit; - case Ast_Undef: return node->Undef; + case Ast_Uninit: return node->Uninit; case Ast_BasicLit: return node->BasicLit.token; case Ast_BasicDirective: return node->BasicDirective.token; case Ast_ProcGroup: return node->ProcGroup.close; diff --git a/src/tokenizer.cpp b/src/tokenizer.cpp index 547a864fb..17a396b9f 100644 --- a/src/tokenizer.cpp +++ b/src/tokenizer.cpp @@ -54,7 +54,7 @@ TOKEN_KIND(Token__AssignOpEnd, ""), \ TOKEN_KIND(Token_Increment, "++"), \ TOKEN_KIND(Token_Decrement, "--"), \ TOKEN_KIND(Token_ArrowRight,"->"), \ - TOKEN_KIND(Token_Undef, "---"), \ + TOKEN_KIND(Token_Uninit, "---"), \ \ TOKEN_KIND(Token__ComparisonBegin, ""), \ TOKEN_KIND(Token_CmpEq, "=="), \ @@ -917,7 +917,7 @@ gb_internal void tokenizer_get_token(Tokenizer *t, Token *token, int repeat=0) { token->kind = Token_Decrement; if (t->curr_rune == '-') { advance_to_next_rune(t); - token->kind = Token_Undef; + token->kind = Token_Uninit; } break; case '>': @@ -1078,7 +1078,7 @@ semicolon_check:; case Token_Imag: case Token_Rune: case Token_String: - case Token_Undef: + case Token_Uninit: /*fallthrough*/ case Token_Question: case Token_Pointer: diff --git a/src/types.cpp b/src/types.cpp index 70c4bcdbe..35fbb719b 100644 --- a/src/types.cpp +++ b/src/types.cpp @@ -83,7 +83,7 @@ enum BasicKind { Basic_UntypedString, Basic_UntypedRune, Basic_UntypedNil, - Basic_UntypedUndef, + Basic_UntypedUninit, Basic_COUNT, @@ -515,7 +515,7 @@ gb_global Type basic_types[] = { {Type_Basic, {Basic_UntypedString, BasicFlag_String | BasicFlag_Untyped, 0, STR_LIT("untyped string")}}, {Type_Basic, {Basic_UntypedRune, BasicFlag_Integer | BasicFlag_Untyped, 0, STR_LIT("untyped rune")}}, {Type_Basic, {Basic_UntypedNil, BasicFlag_Untyped, 0, STR_LIT("untyped nil")}}, - {Type_Basic, {Basic_UntypedUndef, BasicFlag_Untyped, 0, STR_LIT("untyped undefined")}}, + {Type_Basic, {Basic_UntypedUninit, BasicFlag_Untyped, 0, STR_LIT("untyped uninitialized")}}, }; // gb_global Type basic_type_aliases[] = { @@ -589,7 +589,7 @@ gb_global Type *t_untyped_quaternion = &basic_types[Basic_UntypedQuaternion]; gb_global Type *t_untyped_string = &basic_types[Basic_UntypedString]; gb_global Type *t_untyped_rune = &basic_types[Basic_UntypedRune]; gb_global Type *t_untyped_nil = &basic_types[Basic_UntypedNil]; -gb_global Type *t_untyped_undef = &basic_types[Basic_UntypedUndef]; +gb_global Type *t_untyped_uninit = &basic_types[Basic_UntypedUninit]; @@ -1866,14 +1866,15 @@ gb_internal bool is_type_typeid(Type *t) { } gb_internal bool is_type_untyped_nil(Type *t) { t = base_type(t); - return (t->kind == Type_Basic && t->Basic.kind == Basic_UntypedNil); + // NOTE(bill): checking for `nil` or `---` at once is just to improve the error handling + return (t->kind == Type_Basic && (t->Basic.kind == Basic_UntypedNil || t->Basic.kind == Basic_UntypedUninit)); } -gb_internal bool is_type_untyped_undef(Type *t) { +gb_internal bool is_type_untyped_uninit(Type *t) { t = base_type(t); - return (t->kind == Type_Basic && t->Basic.kind == Basic_UntypedUndef); + // NOTE(bill): checking for `nil` or `---` at once is just to improve the error handling + return (t->kind == Type_Basic && t->Basic.kind == Basic_UntypedUninit); } - gb_internal bool is_type_empty_union(Type *t) { t = base_type(t); return t->kind == Type_Union && t->Union.variants.count == 0; @@ -2206,10 +2207,6 @@ gb_internal bool is_type_polymorphic(Type *t, bool or_specialized=false) { } -gb_internal gb_inline bool type_has_undef(Type *t) { - return true; -} - gb_internal bool type_has_nil(Type *t) { t = base_type(t); switch (t->kind) { -- cgit v1.2.3 From 9d299143044f88c2c91dbc8c46cea17cf8de98df Mon Sep 17 00:00:00 2001 From: gingerBill Date: Tue, 30 May 2023 20:26:22 +0100 Subject: Don't strip `builtin` attribute form AST --- src/checker.cpp | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) (limited to 'src/checker.cpp') diff --git a/src/checker.cpp b/src/checker.cpp index c22ad1645..fd5f8e1e8 100644 --- a/src/checker.cpp +++ b/src/checker.cpp @@ -3469,6 +3469,8 @@ gb_internal void check_decl_attributes(CheckerContext *c, Array const &at StringSet set = {}; defer (string_set_destroy(&set)); + bool is_runtime = ((c->scope->parent->flags&(ScopeFlag_File|ScopeFlag_Pkg)) != 0 && c->scope->file->pkg->kind == Package_Runtime); + for_array(i, attributes) { Ast *attr = attributes[i]; if (attr->kind != Ast_Attribute) continue; @@ -3504,6 +3506,10 @@ gb_internal void check_decl_attributes(CheckerContext *c, Array const &at continue; } + if (name == "builtin" && is_runtime) { + continue; + } + if (!proc(c, elem, name, value, ac)) { if (!build_context.ignore_unknown_attributes) { error(elem, "Unknown attribute element name '%.*s'", LIT(name)); @@ -3663,9 +3669,9 @@ gb_internal void check_builtin_attributes(CheckerContext *ctx, Entity *e, Array< error(value, "'builtin' cannot have a field value"); } // Remove the builtin tag - attr->Attribute.elems[k] = attr->Attribute.elems[attr->Attribute.elems.count-1]; - attr->Attribute.elems.count -= 1; - k--; + // attr->Attribute.elems[k] = attr->Attribute.elems[attr->Attribute.elems.count-1]; + // attr->Attribute.elems.count -= 1; + // k--; mutex_unlock(&ctx->info->builtin_mutex); } -- cgit v1.2.3 From 2924e478ee0da20a8c07bf4581bf86a2c53b8eb1 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Tue, 30 May 2023 20:36:43 +0100 Subject: Improve `check_decl_attributes` logic for `is_runtime` --- src/checker.cpp | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) (limited to 'src/checker.cpp') diff --git a/src/checker.cpp b/src/checker.cpp index fd5f8e1e8..fc9a8f776 100644 --- a/src/checker.cpp +++ b/src/checker.cpp @@ -3469,7 +3469,18 @@ gb_internal void check_decl_attributes(CheckerContext *c, Array const &at StringSet set = {}; defer (string_set_destroy(&set)); - bool is_runtime = ((c->scope->parent->flags&(ScopeFlag_File|ScopeFlag_Pkg)) != 0 && c->scope->file->pkg->kind == Package_Runtime); + bool is_runtime = false; + if (c->scope && c->scope->file && (c->scope->flags & ScopeFlag_File) && + c->scope->file->pkg && + c->scope->file->pkg->kind == Package_Runtime) { + is_runtime = true; + } else if (c->scope && c->scope->parent && + (c->scope->flags & ScopeFlag_Proc) && + (c->scope->parent->flags & ScopeFlag_File) && + c->scope->parent->file->pkg && + c->scope->parent->file->pkg->kind == Package_Runtime) { + is_runtime = true; + } for_array(i, attributes) { Ast *attr = attributes[i]; -- cgit v1.2.3 From 24ed07b6d563373b2185196447f9afe2a9831483 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Tue, 6 Jun 2023 11:12:14 +0100 Subject: Add error requiring an explicit calling convention for foreign procedures --- core/runtime/os_specific_js.odin | 2 +- core/runtime/procs_wasm32.odin | 4 ++-- src/checker.cpp | 8 ++++++++ 3 files changed, 11 insertions(+), 3 deletions(-) (limited to 'src/checker.cpp') diff --git a/core/runtime/os_specific_js.odin b/core/runtime/os_specific_js.odin index a9ba871f9..246141d87 100644 --- a/core/runtime/os_specific_js.odin +++ b/core/runtime/os_specific_js.odin @@ -5,7 +5,7 @@ foreign import "odin_env" _os_write :: proc "contextless" (data: []byte) -> (int, _OS_Errno) { foreign odin_env { - write :: proc "c" (fd: u32, p: []byte) --- + write :: proc "contextless" (fd: u32, p: []byte) --- } write(1, data) return len(data), 0 diff --git a/core/runtime/procs_wasm32.odin b/core/runtime/procs_wasm32.odin index 2a4210c1e..3981cead0 100644 --- a/core/runtime/procs_wasm32.odin +++ b/core/runtime/procs_wasm32.odin @@ -8,7 +8,7 @@ ti_int :: struct #raw_union { } @(link_name="__ashlti3", linkage="strong") -__ashlti3 :: proc "c" (a: i128, b_: u32) -> i128 { +__ashlti3 :: proc "contextless" (a: i128, b_: u32) -> i128 { bits_in_dword :: size_of(u32)*8 b := u32(b_) @@ -29,7 +29,7 @@ __ashlti3 :: proc "c" (a: i128, b_: u32) -> i128 { @(link_name="__multi3", linkage="strong") -__multi3 :: proc "c" (a, b: i128) -> i128 { +__multi3 :: proc "contextless" (a, b: i128) -> i128 { x, y, r: ti_int x.all = a diff --git a/src/checker.cpp b/src/checker.cpp index a25d85fb8..49f2c4bb4 100644 --- a/src/checker.cpp +++ b/src/checker.cpp @@ -3889,6 +3889,14 @@ gb_internal void check_collect_value_decl(CheckerContext *c, Ast *decl) { GB_ASSERT(pl->type->kind == Ast_ProcType); auto cc = pl->type->ProcType.calling_convention; if (cc == ProcCC_ForeignBlockDefault) { + if (is_arch_wasm()) { + begin_error_block(); + error(init, "For wasm related targets, it is required that you either define the" + " @(default_calling_convention=) on the foreign block or" + " explicitly assign it on the procedure signature"); + error_line("\tSuggestion: when dealing with normal Odin code (e.g. js_wasm32), use \"contextless\"; when dealing with Emscripten like code, use \"c\"\n"); + end_error_block(); + } cc = ProcCC_CDecl; if (c->foreign_context.default_cc > 0) { cc = c->foreign_context.default_cc; -- cgit v1.2.3 From 356f66784f5fee819a29f1bff759fec93c9cdaed Mon Sep 17 00:00:00 2001 From: gingerBill Date: Tue, 6 Jun 2023 22:36:36 +0100 Subject: Fix `@(default_calling_convention)` check on wasm --- src/checker.cpp | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) (limited to 'src/checker.cpp') diff --git a/src/checker.cpp b/src/checker.cpp index 49f2c4bb4..a9893bca4 100644 --- a/src/checker.cpp +++ b/src/checker.cpp @@ -3889,7 +3889,10 @@ gb_internal void check_collect_value_decl(CheckerContext *c, Ast *decl) { GB_ASSERT(pl->type->kind == Ast_ProcType); auto cc = pl->type->ProcType.calling_convention; if (cc == ProcCC_ForeignBlockDefault) { - if (is_arch_wasm()) { + cc = ProcCC_CDecl; + if (c->foreign_context.default_cc > 0) { + cc = c->foreign_context.default_cc; + } else if (is_arch_wasm()) { begin_error_block(); error(init, "For wasm related targets, it is required that you either define the" " @(default_calling_convention=) on the foreign block or" @@ -3897,10 +3900,6 @@ gb_internal void check_collect_value_decl(CheckerContext *c, Ast *decl) { error_line("\tSuggestion: when dealing with normal Odin code (e.g. js_wasm32), use \"contextless\"; when dealing with Emscripten like code, use \"c\"\n"); end_error_block(); } - cc = ProcCC_CDecl; - if (c->foreign_context.default_cc > 0) { - cc = c->foreign_context.default_cc; - } } e->Procedure.link_prefix = c->foreign_context.link_prefix; -- cgit v1.2.3 From 7a1ab62987e2c980261f9d4fa10f5677d84dc4c9 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Wed, 7 Jun 2023 01:19:40 +0100 Subject: Fix endianness for wasm64p32 --- src/build_settings.cpp | 6 ++---- src/checker.cpp | 2 -- src/llvm_backend_type.cpp | 12 ++++++------ 3 files changed, 8 insertions(+), 12 deletions(-) (limited to 'src/checker.cpp') diff --git a/src/build_settings.cpp b/src/build_settings.cpp index 4aa552255..92e0df38b 100644 --- a/src/build_settings.cpp +++ b/src/build_settings.cpp @@ -41,8 +41,6 @@ enum TargetArchKind : u16 { }; enum TargetEndianKind : u8 { - TargetEndian_Invalid, - TargetEndian_Little, TargetEndian_Big, @@ -85,7 +83,6 @@ gb_global String target_arch_names[TargetArch_COUNT] = { }; gb_global String target_endian_names[TargetEndian_COUNT] = { - str_lit(""), str_lit("little"), str_lit("big"), }; @@ -97,7 +94,8 @@ gb_global String target_abi_names[TargetABI_COUNT] = { }; gb_global TargetEndianKind target_endians[TargetArch_COUNT] = { - TargetEndian_Invalid, + TargetEndian_Little, + TargetEndian_Little, TargetEndian_Little, TargetEndian_Little, TargetEndian_Little, diff --git a/src/checker.cpp b/src/checker.cpp index d09d735a5..6b5046f3d 100644 --- a/src/checker.cpp +++ b/src/checker.cpp @@ -1000,8 +1000,6 @@ gb_internal void init_universal(void) { { GlobalEnumValue values[TargetEndian_COUNT] = { - {"Unknown", TargetEndian_Invalid}, - {"Little", TargetEndian_Little}, {"Big", TargetEndian_Big}, }; diff --git a/src/llvm_backend_type.cpp b/src/llvm_backend_type.cpp index 0810ecd11..1e26fd6bd 100644 --- a/src/llvm_backend_type.cpp +++ b/src/llvm_backend_type.cpp @@ -72,17 +72,17 @@ gb_internal lbValue lb_typeid(lbModule *m, Type *type) { GB_ASSERT(id <= (1u<<24u)); data |= (id &~ (1u<<24)) << 0u; // index data |= (kind &~ (1u<<5)) << 24u; // kind - data |= (named &~ (1u<<1)) << 29u; // kind - data |= (special &~ (1u<<1)) << 30u; // kind - data |= (reserved &~ (1u<<1)) << 31u; // 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; // kind - data |= (special &~ (1ull<<1)) << 62ull; // kind - data |= (reserved &~ (1ull<<1)) << 63ull; // kind + data |= (named &~ (1ull<<1)) << 61ull; // named + data |= (special &~ (1ull<<1)) << 62ull; // special + data |= (reserved &~ (1ull<<1)) << 63ull; // reserved } lbValue res = {}; -- cgit v1.2.3 From ef944b903b25e4ddc30af1ff14beee9e349d3a5f Mon Sep 17 00:00:00 2001 From: gingerBill Date: Wed, 7 Jun 2023 12:13:20 +0100 Subject: "Fix" #2580 --- src/checker.cpp | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src/checker.cpp') diff --git a/src/checker.cpp b/src/checker.cpp index 6b5046f3d..c71546499 100644 --- a/src/checker.cpp +++ b/src/checker.cpp @@ -651,6 +651,9 @@ gb_internal bool check_vet_unused(Checker *c, Entity *e, VettedEntity *ve) { case Entity_Variable: if (e->scope->flags & (ScopeFlag_Global|ScopeFlag_Type|ScopeFlag_File)) { return false; + } else if (e->flags & EntityFlag_Static) { + // ignore these for the time being + return false; } case Entity_ImportName: case Entity_LibraryName: -- cgit v1.2.3 From 7dc09ed4501d0a7b256a05e6467cd86a262367ae Mon Sep 17 00:00:00 2001 From: gingerBill Date: Wed, 7 Jun 2023 15:49:12 +0100 Subject: Add `ODIN_COMPILE_TIMESTAMP` (unix timestamp in nanoseconds) --- src/checker.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'src/checker.cpp') diff --git a/src/checker.cpp b/src/checker.cpp index c71546499..a8227fc2e 100644 --- a/src/checker.cpp +++ b/src/checker.cpp @@ -915,6 +915,13 @@ gb_internal Type *add_global_type_name(Scope *scope, String const &type_name, Ty return named_type; } +gb_internal i64 odin_compile_timestamp(void) { + i64 us_after_1601 = cast(i64)gb_utc_time_now(); + i64 us_after_1970 = us_after_1601 - 11644473600000000ll; + i64 ns_after_1970 = us_after_1970*1000ll; + return ns_after_1970; +} + gb_internal void init_universal(void) { BuildContext *bc = &build_context; @@ -1051,6 +1058,7 @@ gb_internal void init_universal(void) { add_global_bool_constant("ODIN_VALGRIND_SUPPORT", bc->ODIN_VALGRIND_SUPPORT); + add_global_constant("ODIN_COMPILE_TIMESTAMP", t_untyped_integer, exact_value_i64(odin_compile_timestamp())); // Builtin Procedures -- cgit v1.2.3 From 296674e18b5ce3ba90013fb5d599251c66d8bd18 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Mon, 12 Jun 2023 14:53:05 +0100 Subject: Rename `ODIN_DISALLOW_RTTI` to `ODIN_NO_RTTI`; Remove dead command line flags --- core/reflect/reflect.odin | 2 +- core/runtime/core.odin | 2 +- core/runtime/error_checks.odin | 2 +- core/runtime/print.odin | 4 ++-- src/build_settings.cpp | 6 +++--- src/check_builtin.cpp | 4 ++-- src/checker.cpp | 8 ++++---- src/llvm_backend.cpp | 4 ++-- src/llvm_backend_expr.cpp | 6 +++--- src/llvm_backend_type.cpp | 6 +++--- src/llvm_backend_utility.cpp | 8 ++++---- src/main.cpp | 16 +--------------- 12 files changed, 27 insertions(+), 41 deletions(-) (limited to 'src/checker.cpp') diff --git a/core/reflect/reflect.odin b/core/reflect/reflect.odin index f8343ead2..2eb31c21b 100644 --- a/core/reflect/reflect.odin +++ b/core/reflect/reflect.odin @@ -132,7 +132,7 @@ type_info_core :: runtime.type_info_core type_info_base_without_enum :: type_info_core -when !ODIN_DISALLOW_RTTI { +when !ODIN_NO_RTTI { typeid_base :: runtime.typeid_base typeid_core :: runtime.typeid_core typeid_base_without_enum :: typeid_core diff --git a/core/runtime/core.odin b/core/runtime/core.odin index 058ca6161..83504c9ee 100644 --- a/core/runtime/core.odin +++ b/core/runtime/core.odin @@ -566,7 +566,7 @@ __type_info_of :: proc "contextless" (id: typeid) -> ^Type_Info #no_bounds_check return &type_table[n] } -when !ODIN_DISALLOW_RTTI { +when !ODIN_NO_RTTI { typeid_base :: proc "contextless" (id: typeid) -> typeid { ti := type_info_of(id) ti = type_info_base(ti) diff --git a/core/runtime/error_checks.odin b/core/runtime/error_checks.odin index 8539c724d..a667b9065 100644 --- a/core/runtime/error_checks.odin +++ b/core/runtime/error_checks.odin @@ -122,7 +122,7 @@ matrix_bounds_check_error :: proc "contextless" (file: string, line, column: i32 } -when ODIN_DISALLOW_RTTI { +when ODIN_NO_RTTI { type_assertion_check :: proc "contextless" (ok: bool, file: string, line, column: i32) { if ok { return diff --git a/core/runtime/print.odin b/core/runtime/print.odin index 326a29667..732ed9c12 100644 --- a/core/runtime/print.odin +++ b/core/runtime/print.odin @@ -5,7 +5,7 @@ _INTEGER_DIGITS :: "0123456789abcdefghijklmnopqrstuvwxyz" @(private="file") _INTEGER_DIGITS_VAR := _INTEGER_DIGITS -when !ODIN_DISALLOW_RTTI { +when !ODIN_NO_RTTI { print_any_single :: proc "contextless" (arg: any) { x := arg if loc, ok := x.(Source_Code_Location); ok { @@ -234,7 +234,7 @@ print_caller_location :: proc "contextless" (using loc: Source_Code_Location) { } } print_typeid :: proc "contextless" (id: typeid) { - when ODIN_DISALLOW_RTTI { + when ODIN_NO_RTTI { if id == nil { print_string("nil") } else { diff --git a/src/build_settings.cpp b/src/build_settings.cpp index 92e0df38b..866631f9a 100644 --- a/src/build_settings.cpp +++ b/src/build_settings.cpp @@ -309,7 +309,7 @@ struct BuildContext { bool copy_file_contents; - bool disallow_rtti; + bool no_rtti; bool dynamic_map_calls; @@ -1227,8 +1227,8 @@ gb_internal void init_build_context(TargetMetrics *cross_target) { if (bc->metrics.os == TargetOs_freestanding) { bc->no_entry_point = true; } else { - if (bc->disallow_rtti) { - gb_printf_err("-disallow-rtti is only allowed on freestanding targets\n"); + if (bc->no_rtti) { + gb_printf_err("-no-rtti is only allowed on freestanding targets\n"); gb_exit(1); } } diff --git a/src/check_builtin.cpp b/src/check_builtin.cpp index 46ee6b7f9..269a0ec48 100644 --- a/src/check_builtin.cpp +++ b/src/check_builtin.cpp @@ -2063,7 +2063,7 @@ gb_internal bool check_builtin_procedure(CheckerContext *c, Operand *operand, As if (c->scope->flags&ScopeFlag_Global) { compiler_error("'type_info_of' Cannot be declared within the runtime package due to how the internals of the compiler works"); } - if (build_context.disallow_rtti) { + if (build_context.no_rtti) { error(call, "'%.*s' has been disallowed", LIT(builtin_name)); return false; } @@ -2106,7 +2106,7 @@ gb_internal bool check_builtin_procedure(CheckerContext *c, Operand *operand, As if (c->scope->flags&ScopeFlag_Global) { compiler_error("'typeid_of' Cannot be declared within the runtime package due to how the internals of the compiler works"); } - if (build_context.disallow_rtti) { + if (build_context.no_rtti) { error(call, "'%.*s' has been disallowed", LIT(builtin_name)); return false; } diff --git a/src/checker.cpp b/src/checker.cpp index a8227fc2e..354cdadd3 100644 --- a/src/checker.cpp +++ b/src/checker.cpp @@ -32,7 +32,7 @@ gb_internal bool is_operand_uninit(Operand o) { } gb_internal bool check_rtti_type_disallowed(Token const &token, Type *type, char const *format) { - if (build_context.disallow_rtti && type) { + if (build_context.no_rtti && type) { if (is_type_any(type)) { gbString t = type_to_string(type); error(token, format, t); @@ -1054,7 +1054,7 @@ gb_internal void init_universal(void) { add_global_bool_constant("ODIN_TEST", bc->command_kind == Command_test); add_global_bool_constant("ODIN_NO_ENTRY_POINT", bc->no_entry_point); add_global_bool_constant("ODIN_FOREIGN_ERROR_PROCEDURES", bc->ODIN_FOREIGN_ERROR_PROCEDURES); - add_global_bool_constant("ODIN_DISALLOW_RTTI", bc->disallow_rtti); + add_global_bool_constant("ODIN_NO_RTTI", bc->no_rtti); add_global_bool_constant("ODIN_VALGRIND_SUPPORT", bc->ODIN_VALGRIND_SUPPORT); @@ -1742,7 +1742,7 @@ gb_internal void add_implicit_entity(CheckerContext *c, Ast *clause, Entity *e) gb_internal void add_type_info_type_internal(CheckerContext *c, Type *t); gb_internal void add_type_info_type(CheckerContext *c, Type *t) { - if (build_context.disallow_rtti) { + if (build_context.no_rtti) { return; } if (t == nullptr) { @@ -2343,7 +2343,7 @@ gb_internal void generate_minimum_dependency_set(Checker *c, Entity *start) { str_lit("__multi3"), ); - FORCE_ADD_RUNTIME_ENTITIES(!build_context.disallow_rtti, + FORCE_ADD_RUNTIME_ENTITIES(!build_context.no_rtti, // Odin types str_lit("Type_Info"), diff --git a/src/llvm_backend.cpp b/src/llvm_backend.cpp index 4fe8d4a00..525ac8a9d 100644 --- a/src/llvm_backend.cpp +++ b/src/llvm_backend.cpp @@ -1048,7 +1048,7 @@ struct lbGlobalVariable { }; gb_internal lbProcedure *lb_create_startup_type_info(lbModule *m) { - if (build_context.disallow_rtti) { + if (build_context.no_rtti) { return nullptr; } Type *proc_type = alloc_type_proc(nullptr, nullptr, 0, nullptr, 0, false, ProcCC_CDecl); @@ -2170,7 +2170,7 @@ gb_internal bool lb_generate_code(lbGenerator *gen) { TIME_SECTION("LLVM Global Variables"); - if (!build_context.disallow_rtti) { + if (!build_context.no_rtti) { lbModule *m = default_module; { // Add type info data diff --git a/src/llvm_backend_expr.cpp b/src/llvm_backend_expr.cpp index f95e351ce..619b40fda 100644 --- a/src/llvm_backend_expr.cpp +++ b/src/llvm_backend_expr.cpp @@ -2984,7 +2984,7 @@ gb_internal lbValue lb_build_unary_and(lbProcedure *p, Ast *expr) { isize arg_count = 6; - if (build_context.disallow_rtti) { + if (build_context.no_rtti) { arg_count = 4; } @@ -2996,7 +2996,7 @@ gb_internal lbValue lb_build_unary_and(lbProcedure *p, Ast *expr) { args[2] = lb_const_int(p->module, t_i32, pos.line); args[3] = lb_const_int(p->module, t_i32, pos.column); - if (!build_context.disallow_rtti) { + if (!build_context.no_rtti) { args[4] = lb_typeid(p->module, src_type); args[5] = lb_typeid(p->module, dst_type); } @@ -3012,7 +3012,7 @@ gb_internal lbValue lb_build_unary_and(lbProcedure *p, Ast *expr) { } lbValue data_ptr = lb_emit_struct_ev(p, v, 0); if ((p->state_flags & StateFlag_no_type_assert) == 0) { - GB_ASSERT(!build_context.disallow_rtti); + GB_ASSERT(!build_context.no_rtti); lbValue any_id = lb_emit_struct_ev(p, v, 1); diff --git a/src/llvm_backend_type.cpp b/src/llvm_backend_type.cpp index 1e26fd6bd..a54fde748 100644 --- a/src/llvm_backend_type.cpp +++ b/src/llvm_backend_type.cpp @@ -15,7 +15,7 @@ gb_internal isize lb_type_info_index(CheckerInfo *info, Type *type, bool err_on_ } gb_internal lbValue lb_typeid(lbModule *m, Type *type) { - GB_ASSERT(!build_context.disallow_rtti); + GB_ASSERT(!build_context.no_rtti); type = default_type(type); @@ -92,7 +92,7 @@ gb_internal lbValue lb_typeid(lbModule *m, Type *type) { } gb_internal lbValue lb_type_info(lbModule *m, Type *type) { - GB_ASSERT(!build_context.disallow_rtti); + GB_ASSERT(!build_context.no_rtti); type = default_type(type); @@ -141,7 +141,7 @@ gb_internal lbValue lb_type_info_member_tags_offset(lbProcedure *p, isize count) gb_internal void lb_setup_type_info_data(lbProcedure *p) { // NOTE(bill): Setup type_info data - if (build_context.disallow_rtti) { + if (build_context.no_rtti) { return; } diff --git a/src/llvm_backend_utility.cpp b/src/llvm_backend_utility.cpp index 0c26382ed..2ecad1703 100644 --- a/src/llvm_backend_utility.cpp +++ b/src/llvm_backend_utility.cpp @@ -721,7 +721,7 @@ gb_internal lbValue lb_emit_union_cast(lbProcedure *p, lbValue value, Type *type Type *dst_type = tuple->Tuple.variables[0]->type; isize arg_count = 7; - if (build_context.disallow_rtti) { + if (build_context.no_rtti) { arg_count = 4; } @@ -733,7 +733,7 @@ gb_internal lbValue lb_emit_union_cast(lbProcedure *p, lbValue value, Type *type args[2] = lb_const_int(m, t_i32, pos.line); args[3] = lb_const_int(m, t_i32, pos.column); - if (!build_context.disallow_rtti) { + if (!build_context.no_rtti) { args[4] = lb_typeid(m, src_type); args[5] = lb_typeid(m, dst_type); args[6] = lb_emit_conv(p, value_, t_rawptr); @@ -797,7 +797,7 @@ gb_internal lbAddr lb_emit_any_cast_addr(lbProcedure *p, lbValue value, Type *ty lbValue ok = lb_emit_load(p, lb_emit_struct_ep(p, v.addr, 1)); isize arg_count = 7; - if (build_context.disallow_rtti) { + if (build_context.no_rtti) { arg_count = 4; } auto args = array_make(permanent_allocator(), arg_count); @@ -807,7 +807,7 @@ gb_internal lbAddr lb_emit_any_cast_addr(lbProcedure *p, lbValue value, Type *ty args[2] = lb_const_int(m, t_i32, pos.line); args[3] = lb_const_int(m, t_i32, pos.column); - if (!build_context.disallow_rtti) { + if (!build_context.no_rtti) { args[4] = any_typeid; args[5] = dst_typeid; args[6] = lb_emit_struct_ev(p, value, 0); diff --git a/src/main.cpp b/src/main.cpp index 029c9f896..2198b4536 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -655,7 +655,6 @@ enum BuildFlagKind { BuildFlag_ShowDebugMessages, BuildFlag_Vet, BuildFlag_VetExtra, - BuildFlag_UseLLVMApi, BuildFlag_IgnoreUnknownAttributes, BuildFlag_ExtraLinkerFlags, BuildFlag_ExtraAssemblerFlags, @@ -671,7 +670,6 @@ enum BuildFlagKind { BuildFlag_DisallowDo, BuildFlag_DefaultToNilAllocator, - BuildFlag_InsertSemicolon, BuildFlag_StrictStyle, BuildFlag_StrictStyleInitOnly, BuildFlag_ForeignErrorProcedures, @@ -834,7 +832,6 @@ gb_internal bool parse_build_flags(Array args) { add_flag(&build_flags, BuildFlag_ShowDebugMessages, str_lit("show-debug-messages"), BuildFlagParam_None, Command_all); add_flag(&build_flags, BuildFlag_Vet, str_lit("vet"), BuildFlagParam_None, Command__does_check); add_flag(&build_flags, BuildFlag_VetExtra, str_lit("vet-extra"), BuildFlagParam_None, Command__does_check); - add_flag(&build_flags, BuildFlag_UseLLVMApi, str_lit("llvm-api"), BuildFlagParam_None, Command__does_build); add_flag(&build_flags, BuildFlag_IgnoreUnknownAttributes, str_lit("ignore-unknown-attributes"), BuildFlagParam_None, Command__does_check); add_flag(&build_flags, BuildFlag_ExtraLinkerFlags, str_lit("extra-linker-flags"), BuildFlagParam_String, Command__does_build); add_flag(&build_flags, BuildFlag_ExtraAssemblerFlags, str_lit("extra-assembler-flags"), BuildFlagParam_String, Command__does_build); @@ -849,7 +846,6 @@ gb_internal bool parse_build_flags(Array args) { add_flag(&build_flags, BuildFlag_DisallowDo, str_lit("disallow-do"), BuildFlagParam_None, Command__does_check); add_flag(&build_flags, BuildFlag_DefaultToNilAllocator, str_lit("default-to-nil-allocator"), BuildFlagParam_None, Command__does_check); - add_flag(&build_flags, BuildFlag_InsertSemicolon, str_lit("insert-semicolon"), BuildFlagParam_None, Command__does_check); add_flag(&build_flags, BuildFlag_StrictStyle, str_lit("strict-style"), BuildFlagParam_None, Command__does_check); add_flag(&build_flags, BuildFlag_StrictStyleInitOnly, str_lit("strict-style-init-only"), BuildFlagParam_None, Command__does_check); add_flag(&build_flags, BuildFlag_ForeignErrorProcedures, str_lit("foreign-error-procedures"), BuildFlagParam_None, Command__does_check); @@ -1373,11 +1369,6 @@ gb_internal bool parse_build_flags(Array args) { build_context.vet_extra = true; break; } - case BuildFlag_UseLLVMApi: { - gb_printf_err("-llvm-api flag is not required any more\n"); - bad_flags = true; - break; - } case BuildFlag_IgnoreUnknownAttributes: build_context.ignore_unknown_attributes = true; break; @@ -1454,7 +1445,7 @@ gb_internal bool parse_build_flags(Array args) { gb_printf_err("'-disallow-rtti' has been replaced with '-no-rtti'\n"); bad_flags = true; } - build_context.disallow_rtti = true; + build_context.no_rtti = true; break; case BuildFlag_DynamicMapCalls: build_context.dynamic_map_calls = true; @@ -1465,11 +1456,6 @@ gb_internal bool parse_build_flags(Array args) { case BuildFlag_ForeignErrorProcedures: build_context.ODIN_FOREIGN_ERROR_PROCEDURES = true; break; - case BuildFlag_InsertSemicolon: { - gb_printf_err("-insert-semicolon flag is not required any more\n"); - bad_flags = true; - break; - } case BuildFlag_StrictStyle: { if (build_context.strict_style_init_only) { gb_printf_err("-strict-style and -strict-style-init-only cannot be used together\n"); -- cgit v1.2.3