Simplify compiler's Map and create a StringMap specifically for strings

This commit is contained in:
gingerBill
2020-04-13 13:02:30 +01:00
parent 65a2125dba
commit f09b6a4c90
19 changed files with 524 additions and 277 deletions
+10 -10
View File
@@ -349,7 +349,7 @@ void override_entity_in_scope(Entity *original_entity, Entity *new_entity) {
// GB_ASSERT_MSG(found_entity == original_entity, "%.*s == %.*s", LIT(found_entity->token.string), LIT(new_entity->token.string));
map_set(&found_scope->elements, hash_string(original_name), new_entity);
string_map_set(&found_scope->elements, original_name, new_entity);
}
@@ -777,8 +777,8 @@ void check_proc_decl(CheckerContext *ctx, Entity *e, DeclInfo *d) {
init_entity_foreign_library(ctx, e);
auto *fp = &ctx->info->foreigns;
HashKey key = hash_string(name);
Entity **found = map_get(fp, key);
StringHashKey key = string_hash_string(name);
Entity **found = string_map_get(fp, key);
if (found) {
Entity *f = *found;
TokenPos pos = f->token.pos;
@@ -800,7 +800,7 @@ void check_proc_decl(CheckerContext *ctx, Entity *e, DeclInfo *d) {
} else if (name == "main") {
error(d->proc_lit, "The link name 'main' is reserved for internal use");
} else {
map_set(fp, key, e);
string_map_set(fp, key, e);
}
} else {
String name = e->token.string;
@@ -809,8 +809,8 @@ void check_proc_decl(CheckerContext *ctx, Entity *e, DeclInfo *d) {
}
if (e->Procedure.link_name.len > 0 || is_export) {
auto *fp = &ctx->info->foreigns;
HashKey key = hash_string(name);
Entity **found = map_get(fp, key);
StringHashKey key = string_hash_string(name);
Entity **found = string_map_get(fp, key);
if (found) {
Entity *f = *found;
TokenPos pos = f->token.pos;
@@ -822,7 +822,7 @@ void check_proc_decl(CheckerContext *ctx, Entity *e, DeclInfo *d) {
} else if (name == "main") {
error(d->proc_lit, "The link name 'main' is reserved for internal use");
} else {
map_set(fp, key, e);
string_map_set(fp, key, e);
}
}
}
@@ -898,8 +898,8 @@ void check_global_variable_decl(CheckerContext *ctx, Entity *e, Ast *type_expr,
}
auto *fp = &ctx->info->foreigns;
HashKey key = hash_string(name);
Entity **found = map_get(fp, key);
StringHashKey key = string_hash_string(name);
Entity **found = string_map_get(fp, key);
if (found) {
Entity *f = *found;
TokenPos pos = f->token.pos;
@@ -912,7 +912,7 @@ void check_global_variable_decl(CheckerContext *ctx, Entity *e, Ast *type_expr,
LIT(name), LIT(pos.file), pos.line, pos.column);
}
} else {
map_set(fp, key, e);
string_map_set(fp, key, e);
}
}
+9 -11
View File
@@ -1065,8 +1065,6 @@ Entity *check_ident(CheckerContext *c, Operand *o, Ast *n, Type *named_type, Typ
}
}
HashKey key = hash_string(e->token.string);
if (e->kind == Entity_ProcGroup) {
auto *pge = &e->ProcGroup;
@@ -6421,9 +6419,9 @@ CallArgumentData check_call_arguments(CheckerContext *c, Operand *operand, Type
// NOTE(bill): This is give type hints for the named parameters
// in order to improve the type inference system
Map<Type *> type_hint_map = {}; // Key: String
map_init(&type_hint_map, heap_allocator(), 2*ce->args.count);
defer (map_destroy(&type_hint_map));
StringMap<Type *> type_hint_map = {}; // Key: String
string_map_init(&type_hint_map, heap_allocator(), 2*ce->args.count);
defer (string_map_destroy(&type_hint_map));
Type *ptype = nullptr;
bool single_case = true;
@@ -6453,7 +6451,7 @@ CallArgumentData check_call_arguments(CheckerContext *c, Operand *operand, Type
if (is_blank_ident(e->token)) {
continue;
}
map_set(&type_hint_map, hash_string(e->token.string), e->type);
string_map_set(&type_hint_map, e->token.string, e->type);
}
}
}
@@ -6475,8 +6473,8 @@ CallArgumentData check_call_arguments(CheckerContext *c, Operand *operand, Type
if (is_blank_ident(e->token)) {
continue;
}
HashKey key = hash_string(e->token.string);
Type **found = map_get(&type_hint_map, key);
StringHashKey key = string_hash_string(e->token.string);
Type **found = string_map_get(&type_hint_map, key);
if (found) {
Type *t = *found;
if (t == nullptr) {
@@ -6487,10 +6485,10 @@ CallArgumentData check_call_arguments(CheckerContext *c, Operand *operand, Type
// NOTE(bill): No need to set again
} else {
// NOTE(bill): Ambiguous named parameter across all types so set it to a nullptr
map_set(&type_hint_map, key, cast(Type *)nullptr);
string_map_set(&type_hint_map, key, cast(Type *)nullptr);
}
} else {
map_set(&type_hint_map, key, e->type);
string_map_set(&type_hint_map, key, e->type);
}
}
}
@@ -6508,7 +6506,7 @@ CallArgumentData check_call_arguments(CheckerContext *c, Operand *operand, Type
if (field != nullptr && field->kind == Ast_Ident) {
String key = field->Ident.token.string;
Type **found = map_get(&type_hint_map, hash_string(key));
Type **found = string_map_get(&type_hint_map, key);
if (found) {
type_hint = *found;
}
+3 -3
View File
@@ -1959,8 +1959,8 @@ void check_stmt_internal(CheckerContext *ctx, Ast *node, u32 flags) {
init_entity_foreign_library(ctx, e);
auto *fp = &ctx->checker->info.foreigns;
HashKey key = hash_string(name);
Entity **found = map_get(fp, key);
StringHashKey key = string_hash_string(name);
Entity **found = string_map_get(fp, key);
if (found) {
Entity *f = *found;
TokenPos pos = f->token.pos;
@@ -1973,7 +1973,7 @@ void check_stmt_internal(CheckerContext *ctx, Ast *node, u32 flags) {
LIT(name), LIT(pos.file), pos.line, pos.column);
}
} else {
map_set(fp, key, e);
string_map_set(fp, key, e);
}
} else if (e->flags & EntityFlag_Static) {
if (vd->values.count > 0) {
+36 -44
View File
@@ -29,14 +29,14 @@ void scope_reset(Scope *scope) {
scope->first_child = nullptr;
scope->last_child = nullptr;
map_clear (&scope->elements);
string_map_clear(&scope->elements);
ptr_set_clear(&scope->imported);
}
void scope_reserve(Scope *scope, isize capacity) {
isize cap = 2*capacity;
if (cap > scope->elements.hashes.count) {
map_rehash(&scope->elements, capacity);
string_map_rehash(&scope->elements, capacity);
}
}
@@ -221,7 +221,7 @@ bool decl_info_has_init(DeclInfo *d) {
Scope *create_scope(Scope *parent, gbAllocator allocator, isize init_elements_capacity=16) {
Scope *s = gb_alloc_item(allocator, Scope);
s->parent = parent;
map_init(&s->elements, heap_allocator(), init_elements_capacity);
string_map_init(&s->elements, heap_allocator(), init_elements_capacity);
ptr_set_init(&s->imported, heap_allocator(), 0);
s->delayed_imports.allocator = heap_allocator();
@@ -295,7 +295,7 @@ void destroy_scope(Scope *scope) {
destroy_scope(child);
}
map_destroy(&scope->elements);
string_map_destroy(&scope->elements);
array_free(&scope->delayed_imports);
array_free(&scope->delayed_directives);
ptr_set_destroy(&scope->imported);
@@ -340,21 +340,20 @@ void check_close_scope(CheckerContext *c) {
}
Entity *scope_lookup_current(Scope *s, String name) {
HashKey key = hash_string(name);
Entity **found = map_get(&s->elements, key);
Entity *scope_lookup_current(Scope *s, String const &name) {
Entity **found = string_map_get(&s->elements, name);
if (found) {
return *found;
}
return nullptr;
}
void scope_lookup_parent(Scope *scope, String name, Scope **scope_, Entity **entity_) {
void scope_lookup_parent(Scope *scope, String const &name, Scope **scope_, Entity **entity_) {
bool gone_thru_proc = false;
bool gone_thru_package = false;
HashKey key = hash_string(name);
StringHashKey key = string_hash_string(name);
for (Scope *s = scope; s != nullptr; s = s->parent) {
Entity **found = map_get(&s->elements, key);
Entity **found = string_map_get(&s->elements, key);
if (found) {
Entity *e = *found;
if (gone_thru_proc) {
@@ -386,7 +385,7 @@ void scope_lookup_parent(Scope *scope, String name, Scope **scope_, Entity **ent
if (scope_) *scope_ = nullptr;
}
Entity *scope_lookup(Scope *s, String name) {
Entity *scope_lookup(Scope *s, String const &name) {
Entity *entity = nullptr;
scope_lookup_parent(s, name, nullptr, &entity);
return entity;
@@ -394,18 +393,18 @@ Entity *scope_lookup(Scope *s, String name) {
Entity *scope_insert_with_name(Scope *s, String name, Entity *entity) {
Entity *scope_insert_with_name(Scope *s, String const &name, Entity *entity) {
if (name == "") {
return nullptr;
}
HashKey key = hash_string(name);
Entity **found = map_get(&s->elements, key);
StringHashKey key = string_hash_string(name);
Entity **found = string_map_get(&s->elements, key);
if (found) {
return *found;
}
if (s->parent != nullptr && (s->parent->flags & ScopeFlag_Proc) != 0) {
Entity **found = map_get(&s->parent->elements, key);
Entity **found = string_map_get(&s->parent->elements, key);
if (found) {
if ((*found)->flags & EntityFlag_Result) {
return *found;
@@ -413,7 +412,7 @@ Entity *scope_insert_with_name(Scope *s, String name, Entity *entity) {
}
}
map_set(&s->elements, key, entity);
string_map_set(&s->elements, key, entity);
if (entity->scope == nullptr) {
entity->scope = s;
}
@@ -611,8 +610,7 @@ 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));
HashKey key = hash_string(path);
auto found = map_get(&info->packages, key);
auto found = string_map_get(&info->packages, path);
GB_ASSERT_MSG(found != nullptr, "Missing core package %.*s", LIT(name));
return *found;
}
@@ -744,7 +742,7 @@ void init_universal(void) {
bool defined_values_double_declaration = false;
for_array(i, bc->defined_values.entries) {
String name = bc->defined_values.entries[i].key.string;
char const *name = cast(char const *)cast(uintptr)bc->defined_values.entries[i].key.key;
ExactValue value = bc->defined_values.entries[i].value;
GB_ASSERT(value.kind != ExactValue_Invalid);
@@ -770,7 +768,7 @@ void init_universal(void) {
Entity *entity = alloc_entity_constant(nullptr, make_token_ident(name), type, value);
entity->state = EntityState_Resolved;
if (scope_insert(builtin_pkg->scope, entity)) {
error(entity->token, "'%.*s' defined as an argument is already declared at the global scope", LIT(name));
error(entity->token, "'%s' defined as an argument is already declared at the global scope", name);
defined_values_double_declaration = true;
// NOTE(bill): Just exit early before anything, even though the compiler will do that anyway
}
@@ -797,13 +795,13 @@ void init_checker_info(CheckerInfo *i) {
array_init(&i->definitions, a);
array_init(&i->entities, a);
map_init(&i->untyped, a);
map_init(&i->foreigns, a);
string_map_init(&i->foreigns, a);
map_init(&i->gen_procs, a);
map_init(&i->gen_types, a);
array_init(&i->type_info_types, a);
map_init(&i->type_info_map, a);
map_init(&i->files, a);
map_init(&i->packages, a);
string_map_init(&i->files, a);
string_map_init(&i->packages, a);
array_init(&i->variable_init_order, a);
array_init(&i->required_foreign_imports_through_force, a);
array_init(&i->required_global_variables, a);
@@ -818,13 +816,13 @@ void destroy_checker_info(CheckerInfo *i) {
array_free(&i->definitions);
array_free(&i->entities);
map_destroy(&i->untyped);
map_destroy(&i->foreigns);
string_map_destroy(&i->foreigns);
map_destroy(&i->gen_procs);
map_destroy(&i->gen_types);
array_free(&i->type_info_types);
map_destroy(&i->type_info_map);
map_destroy(&i->files);
map_destroy(&i->packages);
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);
@@ -956,7 +954,7 @@ DeclInfo *decl_info_of_ident(Ast *ident) {
}
AstFile *ast_file_of_filename(CheckerInfo *i, String filename) {
AstFile **found = map_get(&i->files, hash_string(filename));
AstFile **found = string_map_get(&i->files, filename);
if (found != nullptr) {
return *found;
}
@@ -994,7 +992,7 @@ isize type_info_index(CheckerInfo *info, Type *type, bool error_on_failure) {
// 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];
Type *prev_type = cast(Type *)e->key.ptr;
Type *prev_type = cast(Type *)cast(uintptr)e->key.key;
if (are_types_identical(prev_type, type)) {
entry_index = e->value;
// NOTE(bill): Add it to the search map
@@ -1234,7 +1232,7 @@ void add_type_info_type(CheckerContext *c, Type *t) {
isize ti_index = -1;
for_array(i, c->info->type_info_map.entries) {
auto *e = &c->info->type_info_map.entries[i];
Type *prev_type = cast(Type *)e->key.ptr;
Type *prev_type = cast(Type *)cast(uintptr)e->key.key;
if (are_types_identical(t, prev_type)) {
// Duplicate entry
ti_index = e->value;
@@ -1811,7 +1809,7 @@ Array<EntityGraphNode *> generate_entity_dependency_graph(CheckerInfo *info) {
TIME_SECTION("generate_entity_dependency_graph: Calculate edges for graph M - Part 1");
// Calculate edges for graph M
for_array(i, M.entries) {
Entity * e = cast(Entity *)M.entries[i].key.ptr;
Entity * e = cast(Entity *)cast(uintptr)M.entries[i].key.key;
EntityGraphNode *n = M.entries[i].value;
DeclInfo *decl = decl_info_of_entity(e);
@@ -1838,7 +1836,7 @@ Array<EntityGraphNode *> generate_entity_dependency_graph(CheckerInfo *info) {
for_array(i, M.entries) {
auto *entry = &M.entries[i];
auto *e = cast(Entity *)entry->key.ptr;
auto *e = cast(Entity *)cast(uintptr)entry->key.key;
EntityGraphNode *n = entry->value;
if (e->kind == Entity_Procedure) {
@@ -3072,8 +3070,7 @@ void add_import_dependency_node(Checker *c, Ast *decl, Map<ImportGraphNode *> *M
if (is_package_name_reserved(path)) {
return;
}
HashKey key = hash_string(path);
AstPackage **found = map_get(&c->info.packages, key);
AstPackage **found = string_map_get(&c->info.packages, path);
if (found == nullptr) {
for_array(pkg_index, c->info.packages.entries) {
AstPackage *pkg = c->info.packages.entries[pkg_index].value;
@@ -3185,8 +3182,7 @@ Array<ImportPathItem> find_import_path(Checker *c, AstPackage *start, AstPackage
String path = start->fullpath;
HashKey key = hash_string(path);
AstPackage **found = map_get(&c->info.packages, key);
AstPackage **found = string_map_get(&c->info.packages, path);
if (found) {
AstPackage *pkg = *found;
GB_ASSERT(pkg != nullptr);
@@ -3248,8 +3244,7 @@ void check_add_import_decl(CheckerContext *ctx, Ast *decl) {
scope = intrinsics_pkg->scope;
intrinsics_pkg->used = true;
} else {
HashKey key = hash_string(id->fullpath);
AstPackage **found = map_get(pkgs, key);
AstPackage **found = string_map_get(pkgs, id->fullpath);
if (found == nullptr) {
for_array(pkg_index, pkgs->entries) {
AstPackage *pkg = pkgs->entries[pkg_index].value;
@@ -3398,8 +3393,7 @@ bool collect_checked_packages_from_decl_list(Checker *c, Array<Ast *> const &dec
Ast *decl = decls[i];
switch (decl->kind) {
case_ast_node(id, ImportDecl, decl);
HashKey key = hash_string(id->fullpath);
AstPackage **found = map_get(&c->info.packages, key);
AstPackage **found = string_map_get(&c->info.packages, id->fullpath);
if (found == nullptr) {
continue;
}
@@ -3907,8 +3901,7 @@ void check_parsed_files(Checker *c) {
AstPackage *p = c->parser->packages[i];
Scope *scope = create_scope_from_package(&c->init_ctx, p);
p->decl_info = make_decl_info(c->allocator, scope, c->init_ctx.decl);
HashKey key = hash_string(p->fullpath);
map_set(&c->info.packages, key, p);
string_map_set(&c->info.packages, p->fullpath, p);
if (scope->flags&ScopeFlag_Init) {
c->info.init_scope = scope;
@@ -3932,8 +3925,7 @@ void check_parsed_files(Checker *c) {
for_array(j, pkg->files) {
AstFile *f = pkg->files[j];
create_scope_from_file(&ctx, f);
HashKey key = hash_string(f->fullpath);
map_set(&c->info.files, key, f);
string_map_set(&c->info.files, f->fullpath, f);
add_curr_ast_file(&ctx, f);
check_collect_entities(&ctx, f->decls);
@@ -3978,7 +3970,7 @@ void check_parsed_files(Checker *c) {
for_array(i, c->info.untyped.entries) {
auto *entry = &c->info.untyped.entries[i];
HashKey key = entry->key;
Ast *expr = cast(Ast *)key.ptr;
Ast *expr = cast(Ast *)cast(uintptr)key.key;
ExprInfo *info = &entry->value;
if (info != nullptr && expr != nullptr) {
if (is_type_typed(info->type)) {
+7 -7
View File
@@ -172,7 +172,7 @@ struct Scope {
Scope * next;
Scope * first_child;
Scope * last_child;
Map<Entity *> elements; // Key: String
StringMap<Entity *> elements;
Array<Ast *> delayed_directives;
Array<Ast *> delayed_imports;
@@ -238,9 +238,9 @@ struct CheckerInfo {
Map<ExprInfo> untyped; // Key: Ast * | Expression -> ExprInfo
// NOTE(bill): This needs to be a map and not on the Ast
// as it needs to be iterated across
Map<AstFile *> files; // Key: String (full path)
Map<AstPackage *> packages; // Key: String (full path)
Map<Entity *> foreigns; // Key: String
StringMap<AstFile *> files; // Key (full path)
StringMap<AstPackage *> packages; // Key (full path)
StringMap<Entity *> foreigns;
Array<Entity *> definitions;
Array<Entity *> entities;
Array<DeclInfo *> variable_init_order;
@@ -346,9 +346,9 @@ isize type_info_index (CheckerInfo *i, Type *type, bool error_on_f
Entity *entity_of_node(Ast *expr);
Entity *scope_lookup_current(Scope *s, String name);
Entity *scope_lookup (Scope *s, String name);
void scope_lookup_parent (Scope *s, String name, Scope **scope_, Entity **entity_);
Entity *scope_lookup_current(Scope *s, String const &name);
Entity *scope_lookup (Scope *s, String const &name);
void scope_lookup_parent (Scope *s, String const &name, Scope **scope_, Entity **entity_);
Entity *scope_insert (Scope *s, Entity *entity);
+51 -7
View File
@@ -340,13 +340,6 @@ void mul_overflow_u64(u64 x, u64 y, u64 *lo, u64 *hi) {
#include "map.cpp"
#include "ptr_set.cpp"
#include "string_set.cpp"
#include "priority_queue.cpp"
#include "thread_pool.cpp"
gb_global String global_module_path = {0};
gb_global bool global_module_path_set = false;
@@ -465,6 +458,57 @@ GB_ALLOCATOR_PROC(arena_allocator_proc) {
#include "string_map.cpp"
#include "map.cpp"
#include "ptr_set.cpp"
#include "string_set.cpp"
#include "priority_queue.cpp"
#include "thread_pool.cpp"
struct StringIntern {
isize len;
StringIntern *next;
char str[1];
};
Map<StringIntern *> string_intern_map = {}; // Key: u64
Arena string_intern_arena = {};
char const *string_intern(char const *text, isize len) {
u64 hash = gb_fnv64a(text, len);
u64 key = hash ? hash : 1;
StringIntern **found = map_get(&string_intern_map, hash_integer(key));
if (found) {
for (StringIntern *it = *found; it != nullptr; it = it->next) {
if (it->len == len && gb_strncmp(it->str, (char *)text, len) == 0) {
return it->str;
}
}
}
StringIntern *new_intern = cast(StringIntern *)arena_alloc(&string_intern_arena, gb_offset_of(StringIntern, str) + len + 1, gb_align_of(StringIntern));
new_intern->len = len;
new_intern->next = found ? *found : nullptr;
gb_memmove(new_intern->str, text, len);
new_intern->str[len] = 0;
map_set(&string_intern_map, hash_integer(key), new_intern);
return new_intern->str;
}
char const *string_intern(String const &string) {
return string_intern(cast(char const *)string.text, string.len);
}
void init_string_interner(void) {
map_init(&string_intern_map, heap_allocator());
arena_init(&string_intern_arena, heap_allocator());
}
i32 next_pow2(i32 n) {
if (n <= 0) {
return 0;
+4 -1
View File
@@ -69,7 +69,10 @@ HashKey hash_exact_value(ExactValue v) {
case ExactValue_Bool:
return hash_integer(u64(v.value_bool));
case ExactValue_String:
return hash_string(v.value_string);
{
char const *str = string_intern(v.value_string);
return hash_pointer(str);
}
case ExactValue_Integer:
{
HashKey key = hashing_proc(big_int_ptr(&v.value_integer), v.value_integer.len * gb_size_of(u64));
+43 -45
View File
@@ -20,7 +20,7 @@ struct irModule {
PtrSet<Entity *> min_dep_set;
Map<irValue *> values; // Key: Entity *
Map<irValue *> members; // Key: String
StringMap<irValue *> members;
Map<String> entity_names; // Key: Entity * of the typename
Map<irDebugInfo *> debug_info; // Key: Unique pointer
Map<irValue *> anonymous_proc_lits; // Key: Ast *
@@ -37,8 +37,8 @@ struct irModule {
// NOTE(bill): To prevent strings from being copied a lot
// Mainly used for file names
Map<irValue *> const_strings; // Key: String
Map<irValue *> const_string_byte_slices; // Key: String
StringMap<irValue *> const_strings;
StringMap<irValue *> const_string_byte_slices;
Map<irValue *> constant_value_to_global; // Key: irValue *
@@ -1509,7 +1509,7 @@ irValue *ir_generate_array(irModule *m, Type *elem_type, i64 count, String prefi
irValue *value = ir_value_global(e, nullptr);
value->Global.is_private = true;
ir_module_add_value(m, e, value);
map_set(&m->members, hash_string(s), value);
string_map_set(&m->members, s, value);
return value;
}
@@ -1626,7 +1626,7 @@ irValue *ir_add_module_constant(irModule *m, Type *type, ExactValue value) {
Entity *e = alloc_entity_constant(nullptr, make_token_ident(name), t, value);
irValue *g = ir_value_global(e, backing_array);
ir_module_add_value(m, e, g);
map_set(&m->members, hash_string(name), g);
string_map_set(&m->members, name, g);
return ir_value_constant_slice(type, g, count);
}
@@ -1639,8 +1639,7 @@ irValue *ir_add_global_string_array(irModule *m, String string) {
irValue *global_constant_value = nullptr;
{
HashKey key = hash_string(string);
irValue **found = map_get(&m->const_string_byte_slices, key);
irValue **found = string_map_get(&m->const_string_byte_slices, string);
if (found != nullptr) {
global_constant_value = *found;
@@ -1677,7 +1676,7 @@ irValue *ir_add_global_string_array(irModule *m, String string) {
ir_module_add_value(m, entity, g);
map_set(&m->members, hash_string(name), g);
string_map_set(&m->members, name, g);
return g;
}
@@ -1760,8 +1759,8 @@ irValue *ir_add_local_for_identifier(irProcedure *proc, Ast *ident, bool zero_in
name = e->Variable.link_name;
}
HashKey key = hash_string(name);
irValue **prev_value = map_get(&proc->module->members, key);
StringHashKey key = string_hash_string(name);
irValue **prev_value = string_map_get(&proc->module->members, key);
if (prev_value == nullptr) {
ir_add_foreign_library_path(proc->module, e->Variable.foreign_library);
// NOTE(bill): Don't do mutliple declarations in the IR
@@ -1769,7 +1768,7 @@ irValue *ir_add_local_for_identifier(irProcedure *proc, Ast *ident, bool zero_in
g->Global.name = name;
g->Global.is_foreign = true;
ir_module_add_value(proc->module, e, g);
map_set(&proc->module->members, key, g);
string_map_set(&proc->module->members, key, g);
return g;
} else {
return *prev_value;
@@ -1807,7 +1806,7 @@ irValue *ir_add_global_generated(irModule *m, Type *type, irValue *value) {
Entity *e = alloc_entity_variable(scope, make_token_ident(name), type);
irValue *g = ir_value_global(e, value);
ir_module_add_value(m, e, g);
map_set(&m->members, hash_string(name), g);
string_map_set(&m->members, name, g);
return g;
}
@@ -5162,26 +5161,26 @@ irValue *ir_add_local_slice(irProcedure *proc, Type *slice_type, irValue *base,
irValue *ir_find_or_add_entity_string(irModule *m, String str) {
HashKey key = hash_string(str);
irValue **found = map_get(&m->const_strings, key);
StringHashKey key = string_hash_string(str);
irValue **found = string_map_get(&m->const_strings, key);
if (found != nullptr) {
return *found;
}
irValue *v = ir_value_constant(t_string, exact_value_string(str));
map_set(&m->const_strings, key, v);
string_map_set(&m->const_strings, key, v);
return v;
}
irValue *ir_find_or_add_entity_string_byte_slice(irModule *m, String str) {
HashKey key = hash_string(str);
irValue **found = map_get(&m->const_string_byte_slices, key);
StringHashKey key = string_hash_string(str);
irValue **found = string_map_get(&m->const_string_byte_slices, key);
if (found != nullptr) {
return *found;
}
Type *t = t_u8_slice;
irValue *v = ir_value_constant(t, exact_value_string(str));
map_set(&m->const_string_byte_slices, key, v);
string_map_set(&m->const_string_byte_slices, key, v);
return v;
}
@@ -6337,7 +6336,7 @@ irValue *ir_gen_anonymous_proc_lit(irModule *m, String prefix_name, Ast *expr, i
if (proc != nullptr) {
array_add(&proc->children, &value->Proc);
} else {
map_set(&m->members, hash_string(name), value);
string_map_set(&m->members, name, value);
}
map_set(&m->anonymous_proc_lits, hash_pointer(expr), value);
@@ -6384,7 +6383,7 @@ void ir_gen_global_type_name(irModule *m, Entity *e, String name) {
}
irValue *t = ir_value_type_name(name, e->type);
ir_module_add_value(m, e, t);
map_set(&m->members, hash_string(name), t);
string_map_set(&m->members, name, t);
// if (bt->kind == Type_Struct) {
// Scope *s = bt->Struct.scope;
@@ -9196,8 +9195,8 @@ void ir_build_constant_value_decl(irProcedure *proc, AstValueDecl *vd) {
name = e->Procedure.link_name;
}
HashKey key = hash_string(name);
irValue **prev_value = map_get(&proc->module->members, key);
StringHashKey key = string_hash_string(name);
irValue **prev_value = string_map_get(&proc->module->members, key);
if (prev_value != nullptr) {
// NOTE(bill): Don't do mutliple declarations in the IR
return;
@@ -9210,7 +9209,7 @@ void ir_build_constant_value_decl(irProcedure *proc, AstValueDecl *vd) {
value->Proc.inlining = pl->inlining;
if (value->Proc.is_foreign || value->Proc.is_export) {
map_set(&proc->module->members, key, value);
string_map_set(&proc->module->members, key, value);
} else {
array_add(&proc->children, &value->Proc);
}
@@ -9721,7 +9720,6 @@ void ir_build_stmt_internal(irProcedure *proc, Ast *node) {
mangled_name.len = gb_string_length(str);
}
HashKey key = hash_string(mangled_name);
ir_add_entity_name(m, e, mangled_name);
irValue *g = ir_value_global(e, value);
@@ -9733,7 +9731,7 @@ void ir_build_stmt_internal(irProcedure *proc, Ast *node) {
g->Global.is_internal = true;
}
ir_module_add_value(proc->module, e, g);
map_set(&proc->module->members, key, g);
string_map_set(&proc->module->members, mangled_name, g);
}
return;
}
@@ -11083,15 +11081,15 @@ void ir_init_module(irModule *m, Checker *c) {
}
map_init(&m->values, heap_allocator());
map_init(&m->members, heap_allocator());
string_map_init(&m->members, heap_allocator());
map_init(&m->debug_info, heap_allocator());
map_init(&m->entity_names, heap_allocator());
map_init(&m->anonymous_proc_lits, heap_allocator());
array_init(&m->procs, heap_allocator());
array_init(&m->procs_to_generate, heap_allocator());
array_init(&m->foreign_library_paths, heap_allocator());
map_init(&m->const_strings, heap_allocator());
map_init(&m->const_string_byte_slices, heap_allocator());
string_map_init(&m->const_strings, heap_allocator());
string_map_init(&m->const_string_byte_slices, heap_allocator());
map_init(&m->constant_value_to_global, heap_allocator());
// Default states
@@ -11108,7 +11106,7 @@ void ir_init_module(irModule *m, Checker *c) {
irValue *g = ir_value_global(e, nullptr);
g->Global.is_private = true;
ir_module_add_value(m, e, g);
map_set(&m->members, hash_string(name), g);
string_map_set(&m->members, name, g);
ir_global_type_info_data = g;
}
@@ -11145,7 +11143,7 @@ void ir_init_module(irModule *m, Checker *c) {
alloc_type_array(t_type_info_ptr, count));
irValue *g = ir_value_global(e, nullptr);
ir_module_add_value(m, e, g);
map_set(&m->members, hash_string(name), g);
string_map_set(&m->members, name, g);
ir_global_type_info_member_types = g;
}
{
@@ -11154,7 +11152,7 @@ void ir_init_module(irModule *m, Checker *c) {
alloc_type_array(t_string, count));
irValue *g = ir_value_global(e, nullptr);
ir_module_add_value(m, e, g);
map_set(&m->members, hash_string(name), g);
string_map_set(&m->members, name, g);
ir_global_type_info_member_names = g;
}
{
@@ -11163,7 +11161,7 @@ void ir_init_module(irModule *m, Checker *c) {
alloc_type_array(t_uintptr, count));
irValue *g = ir_value_global(e, nullptr);
ir_module_add_value(m, e, g);
map_set(&m->members, hash_string(name), g);
string_map_set(&m->members, name, g);
ir_global_type_info_member_offsets = g;
}
@@ -11173,7 +11171,7 @@ void ir_init_module(irModule *m, Checker *c) {
alloc_type_array(t_bool, count));
irValue *g = ir_value_global(e, nullptr);
ir_module_add_value(m, e, g);
map_set(&m->members, hash_string(name), g);
string_map_set(&m->members, name, g);
ir_global_type_info_member_usings = g;
}
@@ -11183,7 +11181,7 @@ void ir_init_module(irModule *m, Checker *c) {
alloc_type_array(t_string, count));
irValue *g = ir_value_global(e, nullptr);
ir_module_add_value(m, e, g);
map_set(&m->members, hash_string(name), g);
string_map_set(&m->members, name, g);
ir_global_type_info_member_tags = g;
}
}
@@ -11226,12 +11224,12 @@ void ir_init_module(irModule *m, Checker *c) {
void ir_destroy_module(irModule *m) {
map_destroy(&m->values);
map_destroy(&m->members);
string_map_destroy(&m->members);
map_destroy(&m->entity_names);
map_destroy(&m->anonymous_proc_lits);
map_destroy(&m->debug_info);
map_destroy(&m->const_strings);
map_destroy(&m->const_string_byte_slices);
string_map_destroy(&m->const_strings);
string_map_destroy(&m->const_string_byte_slices);
map_destroy(&m->constant_value_to_global);
array_free(&m->procs);
array_free(&m->procs_to_generate);
@@ -12020,7 +12018,7 @@ void ir_gen_tree(irGen *s) {
array_add(&global_variables, var);
ir_module_add_value(m, e, g);
map_set(&m->members, hash_string(name), g);
string_map_set(&m->members, name, g);
}
for_array(i, info->entities) {
@@ -12110,9 +12108,9 @@ void ir_gen_tree(irGen *s) {
p->Proc.is_export = e->Procedure.is_export;
ir_module_add_value(m, e, p);
HashKey hash_name = hash_string(name);
if (map_get(&m->members, hash_name) == nullptr) {
map_set(&m->members, hash_name, p);
StringHashKey hash_name = string_hash_string(name);
if (string_map_get(&m->members, hash_name) == nullptr) {
string_map_set(&m->members, hash_name, p);
}
break;
}
@@ -12173,7 +12171,7 @@ void ir_gen_tree(irGen *s) {
p->Proc.is_startup = true;
map_set(&m->values, hash_entity(e), p);
map_set(&m->members, hash_string(name), p);
string_map_set(&m->members, name, p);
irProcedure *proc = &p->Proc;
proc->inlining = ProcInlining_no_inline; // TODO(bill): is no_inline a good idea?
@@ -12254,7 +12252,7 @@ void ir_gen_tree(irGen *s) {
p->Proc.is_startup = true;
map_set(&m->values, hash_entity(e), p);
map_set(&m->members, hash_string(name), p);
string_map_set(&m->members, name, p);
irProcedure *proc = &p->Proc;
proc->inlining = ProcInlining_no_inline; // TODO(bill): is no_inline a good idea?
@@ -12355,7 +12353,7 @@ void ir_gen_tree(irGen *s) {
m->entry_point_entity = e;
map_set(&m->values, hash_entity(e), p);
map_set(&m->members, hash_string(name), p);
string_map_set(&m->members, name, p);
irProcedure *proc = &p->Proc;
// proc->tags = ProcTag_no_inline; // TODO(bill): is no_inline a good idea?
@@ -12386,7 +12384,7 @@ void ir_gen_tree(irGen *s) {
p->Proc.is_startup = true;
map_set(&m->values, hash_entity(e), p);
map_set(&m->members, hash_string(name), p);
string_map_set(&m->members, name, p);
irProcedure *proc = &p->Proc;
+4 -4
View File
@@ -2651,16 +2651,16 @@ void print_llvm_ir(irGen *ir) {
ir_write_str_lit(f, "declare void @llvm.dbg.declare(metadata, metadata, metadata) #3 \n");
if (map_get(&m->members, hash_string(str_lit("llvm.bswap.i16"))) == nullptr) {
if (string_map_get(&m->members, str_lit("llvm.bswap.i16")) == nullptr) {
ir_write_str_lit(f, "declare i16 @llvm.bswap.i16(i16) \n");
}
if (map_get(&m->members, hash_string(str_lit("llvm.bswap.i32"))) == nullptr) {
if (string_map_get(&m->members, str_lit("llvm.bswap.i32")) == nullptr) {
ir_write_str_lit(f, "declare i32 @llvm.bswap.i32(i32) \n");
}
if (map_get(&m->members, hash_string(str_lit("llvm.bswap.i64"))) == nullptr) {
if (string_map_get(&m->members, str_lit("llvm.bswap.i64")) == nullptr) {
ir_write_str_lit(f, "declare i64 @llvm.bswap.i64(i64) \n");
}
if (map_get(&m->members, hash_string(str_lit("llvm.bswap.i128"))) == nullptr) {
if (string_map_get(&m->members, str_lit("llvm.bswap.i128")) == nullptr) {
ir_write_str_lit(f, "declare i128 @llvm.bswap.i128(i128) \n");
}
ir_write_byte(f, '\n');
+18 -20
View File
@@ -1630,17 +1630,17 @@ void lb_add_entity(lbModule *m, Entity *e, lbValue val) {
}
void lb_add_member(lbModule *m, String const &name, lbValue val) {
if (name.len > 0) {
map_set(&m->members, hash_string(name), val);
string_map_set(&m->members, name, val);
}
}
void lb_add_member(lbModule *m, HashKey const &key, lbValue val) {
map_set(&m->members, key, val);
void lb_add_member(lbModule *m, StringHashKey const &key, lbValue val) {
string_map_set(&m->members, key, val);
}
void lb_add_procedure_value(lbModule *m, lbProcedure *p) {
if (p->entity != nullptr) {
map_set(&m->procedure_values, hash_pointer(p->value), p->entity);
}
map_set(&m->procedures, hash_string(p->name), p);
string_map_set(&m->procedures, p->name, p);
}
@@ -1688,11 +1688,11 @@ lbProcedure *lb_create_procedure(lbModule *m, Entity *entity) {
String link_name = lb_get_entity_name(m, entity);
{
HashKey key = hash_string(link_name);
lbValue *found = map_get(&m->members, key);
StringHashKey key = string_hash_string(link_name);
lbValue *found = string_map_get(&m->members, key);
if (found) {
lb_add_entity(m, entity, *found);
lbProcedure **p_found = map_get(&m->procedures, key);
lbProcedure **p_found = string_map_get(&m->procedures, key);
GB_ASSERT(p_found != nullptr);
return *p_found;
}
@@ -1824,8 +1824,7 @@ lbProcedure *lb_create_procedure(lbModule *m, Entity *entity) {
lbProcedure *lb_create_dummy_procedure(lbModule *m, String link_name, Type *type) {
{
HashKey key = hash_string(link_name);
lbValue *found = map_get(&m->members, key);
lbValue *found = string_map_get(&m->members, link_name);
GB_ASSERT(found == nullptr);
}
@@ -2493,8 +2492,7 @@ void lb_build_constant_value_decl(lbProcedure *p, AstValueDecl *vd) {
name = e->Procedure.link_name;
}
HashKey key = hash_string(name);
lbValue *prev_value = map_get(&p->module->members, key);
lbValue *prev_value = string_map_get(&p->module->members, name);
if (prev_value != nullptr) {
// NOTE(bill): Don't do mutliple declarations in the IR
return;
@@ -2513,7 +2511,7 @@ void lb_build_constant_value_decl(lbProcedure *p, AstValueDecl *vd) {
if (p != nullptr) {
array_add(&p->children, nested_proc);
} else {
map_set(&p->module->members, hash_string(name), value);
string_map_set(&p->module->members, name, value);
}
}
}
@@ -4140,8 +4138,8 @@ lbValue lb_emit_clamp(lbProcedure *p, Type *t, lbValue x, lbValue min, lbValue m
LLVMValueRef lb_find_or_add_entity_string_ptr(lbModule *m, String const &str) {
HashKey key = hash_string(str);
LLVMValueRef *found = map_get(&m->const_strings, key);
StringHashKey key = string_hash_string(str);
LLVMValueRef *found = string_map_get(&m->const_strings, key);
if (found != nullptr) {
return *found;
} else {
@@ -4162,7 +4160,7 @@ LLVMValueRef lb_find_or_add_entity_string_ptr(lbModule *m, String const &str) {
LLVMSetInitializer(global_data, data);
LLVMValueRef ptr = LLVMConstInBoundsGEP(global_data, indices, 2);
map_set(&m->const_strings, key, ptr);
string_map_set(&m->const_strings, key, ptr);
return ptr;
}
}
@@ -8399,7 +8397,7 @@ lbValue lb_generate_anonymous_proc_lit(lbModule *m, String const &prefix_name, A
if (parent != nullptr) {
array_add(&parent->children, p);
} else {
map_set(&m->members, hash_string(name), value);
string_map_set(&m->members, name, value);
}
map_set(&m->anonymous_proc_lits, hash_pointer(expr), p);
@@ -10187,10 +10185,10 @@ void lb_init_module(lbModule *m, Checker *c) {
gbAllocator a = heap_allocator();
map_init(&m->types, a);
map_init(&m->values, a);
map_init(&m->members, a);
string_map_init(&m->members, a);
map_init(&m->procedure_values, a);
map_init(&m->procedures, a);
map_init(&m->const_strings, a);
string_map_init(&m->procedures, a);
string_map_init(&m->const_strings, a);
map_init(&m->anonymous_proc_lits, a);
array_init(&m->procedures_to_generate, a);
array_init(&m->foreign_library_paths, a);
@@ -10342,7 +10340,7 @@ lbValue lb_generate_array(lbModule *m, Type *elem_type, i64 count, String prefix
g.type = alloc_type_pointer(t);
LLVMSetInitializer(g.value, LLVMConstNull(lb_type(m, t)));
LLVMSetLinkage(g.value, LLVMInternalLinkage);
map_set(&m->members, hash_string(s), g);
string_map_set(&m->members, s, g);
return g;
}
+3 -3
View File
@@ -62,11 +62,11 @@ struct lbModule {
Map<LLVMTypeRef> types; // Key: Type *
Map<lbValue> values; // Key: Entity *
Map<lbValue> members; // Key: String
Map<lbProcedure *> procedures; // Key: String
StringMap<lbValue> members;
StringMap<lbProcedure *> procedures;
Map<Entity *> procedure_values; // Key: LLVMValueRef
Map<LLVMValueRef> const_strings; // Key: String
StringMap<LLVMValueRef> const_strings;
Map<lbProcedure *> anonymous_proc_lits; // Key: Ast *
+2 -1
View File
@@ -919,7 +919,7 @@ bool parse_build_flags(Array<String> args) {
break;
}
HashKey key = hash_string(name);
HashKey key = hash_pointer(string_intern(name));
if (map_get(&build_context.defined_values, key) != nullptr) {
gb_printf_err("Defined constant '%.*s' already exists\n", LIT(name));
@@ -1431,6 +1431,7 @@ int main(int arg_count, char const **arg_ptr) {
defer (timings_destroy(timings));
init_string_buffer_memory();
init_string_interner();
init_global_error_collector();
global_big_int_init();
arena_init(&global_ast_arena, heap_allocator());
+33 -82
View File
@@ -13,91 +13,42 @@ struct MapFindResult {
isize entry_index;
};
enum HashKeyKind {
HashKey_Default,
HashKey_String,
HashKey_Ptr,
HashKey_PtrAndId,
};
struct PtrAndId {
void *ptr;
u64 id;
};
struct HashKey {
HashKeyKind kind;
// u128 key;
u64 key;
union {
String string; // if String, s.len > 0
void * ptr;
PtrAndId ptr_and_id;
};
u64 key;
};
GB_STATIC_ASSERT(gb_size_of(u64) >= gb_size_of(void *));
gb_inline HashKey hashing_proc(void const *data, isize len) {
HashKey h = {HashKey_Default};
h.kind = HashKey_Default;
HashKey h = {};
// h.key = u128_from_u64(gb_fnv64a(data, len));
h.key = gb_fnv64a(data, len);
return h;
}
gb_inline HashKey hash_string(String s) {
HashKey h = hashing_proc(s.text, s.len);
h.kind = HashKey_String;
h.string = s;
gb_inline HashKey hash_pointer(void const *ptr) {
HashKey h = {};
h.key = cast(u64)cast(uintptr)ptr;
return h;
}
gb_inline HashKey hash_pointer(void *ptr) {
HashKey h = {HashKey_Ptr};
h.key = cast(u64)cast(uintptr)ptr;
// h.key = gb_fnv64a(&ptr, gb_size_of(void *));
h.ptr = ptr;
return h;
}
gb_inline HashKey hash_ptr_and_id(void *ptr, u64 id) {
HashKey h = {HashKey_PtrAndId};
h.key = cast(u64)cast(uintptr)ptr;
// h.key = gb_fnv64a(&ptr, gb_size_of(void *));
h.ptr_and_id.ptr = ptr;
h.ptr_and_id.id = id;
return h;
}
gb_inline HashKey hash_integer(u64 u) {
HashKey h = {HashKey_Default};
HashKey h = {};
h.key = u;
return h;
}
gb_inline HashKey hash_f64(f64 f) {
HashKey h = {HashKey_Default};
HashKey h = {};
h.key = bit_cast<u64>(f);
return h;
}
bool hash_key_equal(HashKey a, HashKey b) {
if (a.key == b.key) {
// NOTE(bill): If two string's hashes collide, compare the strings themselves
if (a.kind == HashKey_String) {
if (b.kind == HashKey_String) {
return a.string == b.string;
}
return false;
} else if (a.kind == HashKey_PtrAndId) {
if (b.kind == HashKey_PtrAndId) {
return a.ptr_and_id.id == b.ptr_and_id.id;
}
return false;
}
return true;
}
return false;
gb_inline bool hash_key_equal(HashKey a, HashKey b) {
return a.key == b.key;
}
bool operator==(HashKey a, HashKey b) { return hash_key_equal(a, b); }
bool operator!=(HashKey a, HashKey b) { return !hash_key_equal(a, b); }
gb_inline bool operator==(HashKey a, HashKey b) { return hash_key_equal(a, b); }
gb_inline bool operator!=(HashKey a, HashKey b) { return !hash_key_equal(a, b); }
#endif
@@ -117,23 +68,23 @@ struct Map {
template <typename T> void map_init (Map<T> *h, gbAllocator a, isize capacity = 16);
template <typename T> void map_destroy (Map<T> *h);
template <typename T> T * map_get (Map<T> *h, HashKey key);
template <typename T> void map_set (Map<T> *h, HashKey key, T const &value);
template <typename T> void map_remove (Map<T> *h, HashKey key);
template <typename T> T * map_get (Map<T> *h, HashKey const &key);
template <typename T> void map_set (Map<T> *h, HashKey const &key, T const &value);
template <typename T> void map_remove (Map<T> *h, HashKey const &key);
template <typename T> void map_clear (Map<T> *h);
template <typename T> void map_grow (Map<T> *h);
template <typename T> void map_rehash (Map<T> *h, isize new_count);
#if MAP_ENABLE_MULTI_MAP
// Mutlivalued map procedure
template <typename T> MapEntry<T> * multi_map_find_first(Map<T> *h, HashKey key);
template <typename T> MapEntry<T> * multi_map_find_first(Map<T> *h, HashKey const &key);
template <typename T> MapEntry<T> * multi_map_find_next (Map<T> *h, MapEntry<T> *e);
template <typename T> isize multi_map_count (Map<T> *h, HashKey key);
template <typename T> void multi_map_get_all (Map<T> *h, HashKey key, T *items);
template <typename T> void multi_map_insert (Map<T> *h, HashKey key, T const &value);
template <typename T> void multi_map_remove (Map<T> *h, HashKey key, MapEntry<T> *e);
template <typename T> void multi_map_remove_all(Map<T> *h, HashKey key);
template <typename T> isize multi_map_count (Map<T> *h, HashKey const &key);
template <typename T> void multi_map_get_all (Map<T> *h, HashKey const &key, T *items);
template <typename T> void multi_map_insert (Map<T> *h, HashKey const &key, T const &value);
template <typename T> void multi_map_remove (Map<T> *h, HashKey const &key, MapEntry<T> *e);
template <typename T> void multi_map_remove_all(Map<T> *h, HashKey const &key);
#endif
template <typename T>
@@ -149,7 +100,7 @@ gb_inline void map_destroy(Map<T> *h) {
}
template <typename T>
gb_internal isize map__add_entry(Map<T> *h, HashKey key) {
gb_internal isize map__add_entry(Map<T> *h, HashKey const &key) {
MapEntry<T> e = {};
e.key = key;
e.next = -1;
@@ -158,7 +109,7 @@ gb_internal isize map__add_entry(Map<T> *h, HashKey key) {
}
template <typename T>
gb_internal MapFindResult map__find(Map<T> *h, HashKey key) {
gb_internal MapFindResult map__find(Map<T> *h, HashKey const &key) {
MapFindResult fr = {-1, -1, -1};
if (h->hashes.count > 0) {
// fr.hash_index = u128_to_i64(key.key % u128_from_i64(h->hashes.count));
@@ -240,7 +191,7 @@ void map_rehash(Map<T> *h, isize new_count) {
}
template <typename T>
gb_inline T *map_get(Map<T> *h, HashKey key) {
T *map_get(Map<T> *h, HashKey const &key) {
isize index = map__find(h, key).entry_index;
if (index >= 0) {
return &h->entries[index].value;
@@ -249,7 +200,7 @@ gb_inline T *map_get(Map<T> *h, HashKey key) {
}
template <typename T>
void map_set(Map<T> *h, HashKey key, T const &value) {
void map_set(Map<T> *h, HashKey const &key, T const &value) {
isize index;
MapFindResult fr;
if (h->hashes.count == 0) {
@@ -275,7 +226,7 @@ void map_set(Map<T> *h, HashKey key, T const &value) {
template <typename T>
void map__erase(Map<T> *h, MapFindResult fr) {
void map__erase(Map<T> *h, MapFindResult const &fr) {
MapFindResult last;
if (fr.entry_prev < 0) {
h->hashes[fr.hash_index] = h->entries[fr.entry_index].next;
@@ -296,7 +247,7 @@ void map__erase(Map<T> *h, MapFindResult fr) {
}
template <typename T>
void map_remove(Map<T> *h, HashKey key) {
void map_remove(Map<T> *h, HashKey const &key) {
MapFindResult fr = map__find(h, key);
if (fr.entry_index >= 0) {
map__erase(h, fr);
@@ -312,7 +263,7 @@ gb_inline void map_clear(Map<T> *h) {
#if MAP_ENABLE_MULTI_MAP
template <typename T>
MapEntry<T> *multi_map_find_first(Map<T> *h, HashKey key) {
MapEntry<T> *multi_map_find_first(Map<T> *h, HashKey const &key) {
isize i = map__find(h, key).entry_index;
if (i < 0) {
return nullptr;
@@ -333,7 +284,7 @@ MapEntry<T> *multi_map_find_next(Map<T> *h, MapEntry<T> *e) {
}
template <typename T>
isize multi_map_count(Map<T> *h, HashKey key) {
isize multi_map_count(Map<T> *h, HashKey const &key) {
isize count = 0;
MapEntry<T> *e = multi_map_find_first(h, key);
while (e != nullptr) {
@@ -344,7 +295,7 @@ isize multi_map_count(Map<T> *h, HashKey key) {
}
template <typename T>
void multi_map_get_all(Map<T> *h, HashKey key, T *items) {
void multi_map_get_all(Map<T> *h, HashKey const &key, T *items) {
isize i = 0;
MapEntry<T> *e = multi_map_find_first(h, key);
while (e != nullptr) {
@@ -354,7 +305,7 @@ void multi_map_get_all(Map<T> *h, HashKey key, T *items) {
}
template <typename T>
void multi_map_insert(Map<T> *h, HashKey key, T const &value) {
void multi_map_insert(Map<T> *h, HashKey const &key, T const &value) {
MapFindResult fr;
isize i;
if (h->hashes.count == 0) {
@@ -377,7 +328,7 @@ void multi_map_insert(Map<T> *h, HashKey key, T const &value) {
}
template <typename T>
void multi_map_remove(Map<T> *h, HashKey key, MapEntry<T> *e) {
void multi_map_remove(Map<T> *h, HashKey const &key, MapEntry<T> *e) {
MapFindResult fr = map__find_from_entry(h, e);
if (fr.entry_index >= 0) {
map__erase(h, fr);
@@ -385,7 +336,7 @@ void multi_map_remove(Map<T> *h, HashKey key, MapEntry<T> *e) {
}
template <typename T>
void multi_map_remove_all(Map<T> *h, HashKey key) {
void multi_map_remove_all(Map<T> *h, HashKey const &key) {
while (map_get(h, key) != nullptr) {
map_remove(h, key);
}
+5 -5
View File
@@ -4310,7 +4310,7 @@ void destroy_ast_file(AstFile *f) {
bool init_parser(Parser *p) {
GB_ASSERT(p != nullptr);
string_set_init(&p->imported_files, heap_allocator());
map_init(&p->package_map, heap_allocator());
string_map_init(&p->package_map, heap_allocator());
array_init(&p->packages, heap_allocator());
array_init(&p->package_imports, heap_allocator());
gb_mutex_init(&p->file_add_mutex);
@@ -4336,7 +4336,7 @@ void destroy_parser(Parser *p) {
array_free(&p->packages);
array_free(&p->package_imports);
string_set_destroy(&p->imported_files);
map_destroy(&p->package_map);
string_map_destroy(&p->package_map);
gb_mutex_destroy(&p->file_add_mutex);
gb_mutex_destroy(&p->file_decl_mutex);
}
@@ -4346,8 +4346,8 @@ void parser_add_package(Parser *p, AstPackage *pkg) {
pkg->id = p->packages.count+1;
array_add(&p->packages, pkg);
if (pkg->name.len > 0) {
HashKey key = hash_string(pkg->name);
auto found = map_get(&p->package_map, key);
StringHashKey key = string_hash_string(pkg->name);
auto found = string_map_get(&p->package_map, key);
if (found) {
GB_ASSERT(pkg->files.count > 0);
AstFile *f = pkg->files[0];
@@ -4356,7 +4356,7 @@ void parser_add_package(Parser *p, AstPackage *pkg) {
TokenPos pos = (*found)->files[0]->package_token.pos;
error_line("\tpreviously declared at %.*s(%td:%td)\n", LIT(pos.file), pos.line, pos.column);
} else {
map_set(&p->package_map, key, pkg);
string_map_set(&p->package_map, key, pkg);
}
}
}
+10 -10
View File
@@ -131,16 +131,16 @@ struct AstPackage {
struct Parser {
String init_fullpath;
StringSet imported_files; // fullpath
Map<AstPackage *> package_map; // Key: String (package name)
Array<AstPackage *> packages;
Array<ImportedPackage> package_imports;
isize file_to_process_count;
isize total_token_count;
isize total_line_count;
gbMutex file_add_mutex;
gbMutex file_decl_mutex;
String init_fullpath;
StringSet imported_files; // fullpath
StringMap<AstPackage *> package_map; // Key(package name)
Array<AstPackage *> packages;
Array<ImportedPackage> package_imports;
isize file_to_process_count;
isize total_token_count;
isize total_line_count;
gbMutex file_add_mutex;
gbMutex file_decl_mutex;
};
+2 -2
View File
@@ -918,7 +918,7 @@ void generate_and_print_query_data_go_to_definitions(Checker *c) {
}
AstFile **use_file_found = map_get(&c->info.files, hash_string(pos.file));
AstFile **use_file_found = string_map_get(&c->info.files, pos.file);
GB_ASSERT(use_file_found != nullptr);
AstFile *use_file = *use_file_found;
GB_ASSERT(use_file != nullptr);
@@ -1008,7 +1008,7 @@ void generate_and_print_query_data_go_to_definitions(Checker *c) {
AstFile *def_file = e->file;
if (def_file == nullptr) {
auto *def_file_found = map_get(&c->info.files, hash_string(e->token.pos.file));
auto *def_file_found = string_map_get(&c->info.files, e->token.pos.file);
if (def_file_found == nullptr) {
continue;
}
+257
View File
@@ -0,0 +1,257 @@
// NOTE(bill): This util stuff is the same for every `Map`
struct StringMapFindResult {
isize hash_index;
isize entry_prev;
isize entry_index;
};
struct StringHashKey {
u64 hash;
String string;
};
StringHashKey string_hashing_proc(void const *data, isize len) {
StringHashKey h = {};
h.hash = gb_fnv64a(data, len);
h.string.text = (u8 *)data;
h.string.len = len;
return h;
}
gb_inline StringHashKey string_hash_string(String const &s) {
return string_hashing_proc(s.text, s.len);
}
bool string_hash_key_equal(StringHashKey a, StringHashKey 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;
}
bool operator==(StringHashKey a, StringHashKey b) { return string_hash_key_equal(a, b); }
bool operator!=(StringHashKey a, StringHashKey b) { return !string_hash_key_equal(a, b); }
template <typename T>
struct StringMapEntry {
StringHashKey key;
isize next;
T value;
};
template <typename T>
struct StringMap {
Array<isize> hashes;
Array<StringMapEntry<T> > entries;
};
template <typename T> void string_map_init (StringMap<T> *h, gbAllocator a, isize capacity = 16);
template <typename T> void string_map_destroy (StringMap<T> *h);
template <typename T> T * string_map_get (StringMap<T> *h, char const *key);
template <typename T> T * string_map_get (StringMap<T> *h, String const &key);
template <typename T> T * string_map_get (StringMap<T> *h, StringHashKey const &key);
template <typename T> void string_map_set (StringMap<T> *h, StringHashKey const &key, T const &value);
template <typename T> void string_map_set (StringMap<T> *h, String const &key, T const &value);
template <typename T> void string_map_set (StringMap<T> *h, char const *key, T const &value);
template <typename T> void string_map_remove (StringMap<T> *h, StringHashKey const &key);
template <typename T> void string_map_clear (StringMap<T> *h);
template <typename T> void string_map_grow (StringMap<T> *h);
template <typename T> void string_map_rehash (StringMap<T> *h, isize new_count);
template <typename T>
gb_inline void string_map_init(StringMap<T> *h, gbAllocator a, isize capacity) {
array_init(&h->hashes, a, 0, capacity);
array_init(&h->entries, a, 0, capacity);
}
template <typename T>
gb_inline void string_map_destroy(StringMap<T> *h) {
array_free(&h->entries);
array_free(&h->hashes);
}
template <typename T>
gb_internal isize string_map__add_entry(StringMap<T> *h, StringHashKey const &key) {
StringMapEntry<T> e = {};
e.key = key;
e.next = -1;
array_add(&h->entries, e);
return h->entries.count-1;
}
template <typename T>
gb_internal StringMapFindResult string_map__find(StringMap<T> *h, StringHashKey const &key) {
StringMapFindResult fr = {-1, -1, -1};
if (h->hashes.count > 0) {
fr.hash_index = key.hash % h->hashes.count;
fr.entry_index = h->hashes[fr.hash_index];
while (fr.entry_index >= 0) {
if (string_hash_key_equal(h->entries[fr.entry_index].key, key)) {
return fr;
}
fr.entry_prev = fr.entry_index;
fr.entry_index = h->entries[fr.entry_index].next;
}
}
return fr;
}
template <typename T>
gb_internal StringMapFindResult string_map__find_from_entry(StringMap<T> *h, StringMapEntry<T> *e) {
StringMapFindResult fr = {-1, -1, -1};
if (h->hashes.count > 0) {
fr.hash_index = e->key.hash % h->hashes.count;
fr.entry_index = h->hashes[fr.hash_index];
while (fr.entry_index >= 0) {
if (&h->entries[fr.entry_index] == e) {
return fr;
}
fr.entry_prev = fr.entry_index;
fr.entry_index = h->entries[fr.entry_index].next;
}
}
return fr;
}
template <typename T>
gb_internal b32 string_map__full(StringMap<T> *h) {
return 0.75f * h->hashes.count <= h->entries.count;
}
#define STRING_MAP_ARRAY_GROW_FORMULA(x) (4*(x) + 7)
GB_STATIC_ASSERT(STRING_MAP_ARRAY_GROW_FORMULA(0) > 0);
template <typename T>
gb_inline void string_map_grow(StringMap<T> *h) {
isize new_count = STRING_MAP_ARRAY_GROW_FORMULA(h->entries.count);
string_map_rehash(h, new_count);
}
template <typename T>
void string_map_rehash(StringMap<T> *h, isize new_count) {
isize i, j;
StringMap<T> nh = {};
string_map_init(&nh, h->hashes.allocator);
array_resize(&nh.hashes, new_count);
array_reserve(&nh.entries, h->entries.count);
for (i = 0; i < new_count; i++) {
nh.hashes[i] = -1;
}
for (i = 0; i < h->entries.count; i++) {
StringMapEntry<T> *e = &h->entries[i];
StringMapFindResult fr;
if (nh.hashes.count == 0) {
string_map_grow(&nh);
}
fr = string_map__find(&nh, e->key);
j = string_map__add_entry(&nh, e->key);
if (fr.entry_prev < 0) {
nh.hashes[fr.hash_index] = j;
} else {
nh.entries[fr.entry_prev].next = j;
}
nh.entries[j].next = fr.entry_index;
nh.entries[j].value = e->value;
if (string_map__full(&nh)) {
string_map_grow(&nh);
}
}
string_map_destroy(h);
*h = nh;
}
template <typename T>
T *string_map_get(StringMap<T> *h, StringHashKey const &key) {
isize index = string_map__find(h, key).entry_index;
if (index >= 0) {
return &h->entries[index].value;
}
return nullptr;
}
template <typename T>
gb_inline T *string_map_get(StringMap<T> *h, String const &key) {
return string_map_get(h, string_hash_string(key));
}
template <typename T>
gb_inline T *string_map_get(StringMap<T> *h, char const *key) {
return string_map_get(h, string_hash_string(make_string_c(key)));
}
template <typename T>
void string_map_set(StringMap<T> *h, StringHashKey const &key, T const &value) {
isize index;
StringMapFindResult fr;
if (h->hashes.count == 0) {
string_map_grow(h);
}
fr = string_map__find(h, key);
if (fr.entry_index >= 0) {
index = fr.entry_index;
} else {
index = string_map__add_entry(h, key);
if (fr.entry_prev >= 0) {
h->entries[fr.entry_prev].next = index;
} else {
h->hashes[fr.hash_index] = index;
}
}
h->entries[index].value = value;
if (string_map__full(h)) {
string_map_grow(h);
}
}
template <typename T>
gb_inline void string_map_set(StringMap<T> *h, String const &key, T const &value) {
string_map_set(h, string_hash_string(key), value);
}
template <typename T>
gb_inline void string_map_set(StringMap<T> *h, char const *key, T const &value) {
string_map_set(h, string_hash_string(make_string_c(key)), value);
}
template <typename T>
void string_map__erase(StringMap<T> *h, StringMapFindResult const &fr) {
StringMapFindResult last;
if (fr.entry_prev < 0) {
h->hashes[fr.hash_index] = h->entries[fr.entry_index].next;
} else {
h->entries[fr.entry_prev].next = h->entries[fr.entry_index].next;
}
if (fr.entry_index == h->entries.count-1) {
array_pop(&h->entries);
return;
}
h->entries[fr.entry_index] = h->entries[h->entries.count-1];
last = string_map__find(h, h->entries[fr.entry_index].key);
if (last.entry_prev >= 0) {
h->entries[last.entry_prev].next = fr.entry_index;
} else {
h->hashes[last.hash_index] = fr.entry_index;
}
}
template <typename T>
void string_map_remove(StringMap<T> *h, StringHashKey const &key) {
StringMapFindResult fr = string_map__find(h, key);
if (fr.entry_index >= 0) {
string_map__erase(h, fr);
}
}
template <typename T>
gb_inline void string_map_clear(StringMap<T> *h) {
array_clear(&h->hashes);
array_clear(&h->entries);
}
+26 -21
View File
@@ -5,9 +5,9 @@ struct StringSetFindResult {
};
struct StringSetEntry {
HashKey key;
isize next;
String value;
u64 hash;
isize next;
String value;
};
struct StringSet {
@@ -18,9 +18,9 @@ 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 str);
bool string_set_exists (StringSet *s, String str);
void string_set_remove (StringSet *s, String str);
void string_set_add (StringSet *s, String const &str);
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);
@@ -36,22 +36,24 @@ gb_inline void string_set_destroy(StringSet *s) {
array_free(&s->hashes);
}
gb_internal isize string_set__add_entry(StringSet *s, HashKey key) {
gb_internal isize string_set__add_entry(StringSet *s, StringHashKey const &key) {
StringSetEntry e = {};
e.key = key;
e.hash = key.hash;
e.next = -1;
e.value = key.string;
array_add(&s->entries, e);
return s->entries.count-1;
}
gb_internal StringSetFindResult string_set__find(StringSet *s, HashKey key) {
gb_internal StringSetFindResult string_set__find(StringSet *s, StringHashKey const &key) {
StringSetFindResult fr = {-1, -1, -1};
if (s->hashes.count > 0) {
// fr.hash_index = u128_to_i64(key.key % u128_from_i64(s->hashes.count));
fr.hash_index = key.key % s->hashes.count;
fr.hash_index = key.hash % s->hashes.count;
fr.entry_index = s->hashes[fr.hash_index];
while (fr.entry_index >= 0) {
if (hash_key_equal(s->entries[fr.entry_index].key, key)) {
auto const &entry = s->entries[fr.entry_index];
if (entry.hash == key.hash && entry.value == key.string) {
return fr;
}
fr.entry_prev = fr.entry_index;
@@ -85,8 +87,9 @@ void string_set_rehash(StringSet *s, isize new_count) {
if (ns.hashes.count == 0) {
string_set_grow(&ns);
}
fr = string_set__find(&ns, e->key);
j = string_set__add_entry(&ns, e->key);
StringHashKey key = {e->hash, e->value};
fr = string_set__find(&ns, key);
j = string_set__add_entry(&ns, key);
if (fr.entry_prev < 0) {
ns.hashes[fr.hash_index] = j;
} else {
@@ -102,16 +105,16 @@ void string_set_rehash(StringSet *s, isize new_count) {
*s = ns;
}
gb_inline bool string_set_exists(StringSet *s, String str) {
HashKey key = hash_string(str);
gb_inline bool string_set_exists(StringSet *s, String const &str) {
StringHashKey key = string_hash_string(str);
isize index = string_set__find(s, key).entry_index;
return index >= 0;
}
void string_set_add(StringSet *s, String str) {
void string_set_add(StringSet *s, String const &str) {
isize index;
StringSetFindResult fr;
HashKey key = hash_string(str);
StringHashKey key = string_hash_string(str);
if (s->hashes.count == 0) {
string_set_grow(s);
}
@@ -145,8 +148,10 @@ void string_set__erase(StringSet *s, StringSetFindResult fr) {
array_pop(&s->entries);
return;
}
s->entries[fr.entry_index] = s->entries[s->entries.count-1];
last = string_set__find(s, s->entries[fr.entry_index].key);
auto *entry = &s->entries[fr.entry_index];
*entry = s->entries[s->entries.count-1];
StringHashKey key = {entry->hash, entry->value};
last = string_set__find(s, key);
if (last.entry_prev >= 0) {
s->entries[last.entry_prev].next = fr.entry_index;
} else {
@@ -154,8 +159,8 @@ void string_set__erase(StringSet *s, StringSetFindResult fr) {
}
}
void string_set_remove(StringSet *s, String str) {
HashKey key = hash_string(str);
void string_set_remove(StringSet *s, String const &str) {
StringHashKey key = string_hash_string(str);
StringSetFindResult fr = string_set__find(s, key);
if (fr.entry_index >= 0) {
string_set__erase(s, fr);
+1 -1
View File
@@ -2254,7 +2254,7 @@ Selection lookup_field_from_index(Type *type, i64 index) {
}
Entity *scope_lookup_current(Scope *s, String name);
Entity *scope_lookup_current(Scope *s, String const &name);
Selection lookup_field_with_selection(Type *type_, String field_name, bool is_type, Selection sel, bool allow_blank_ident) {
GB_ASSERT(type_ != nullptr);