mirror of
https://github.com/odin-lang/Odin.git
synced 2026-06-03 09:14:38 +00:00
General optimizations
This commit is contained in:
@@ -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] = {
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -192,6 +192,26 @@ gb_internal void map_rehash(PtrMap<K, V> *h, isize new_count) {
|
||||
|
||||
template <typename K, typename V>
|
||||
gb_internal V *map_get(PtrMap<K, V> *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 <typename K, typename V>
|
||||
gb_internal V *map_try_get(PtrMap<K, V> *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<K, V> *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 <typename K, typename V>
|
||||
gb_internal void map_set_internal_from_try_get(PtrMap<K, V> *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 <typename K, typename V>
|
||||
gb_internal V &map_must_get(PtrMap<K, V> *h, K key) {
|
||||
V *ptr = map_get(h, key);
|
||||
|
||||
@@ -2528,14 +2528,6 @@ 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) {
|
||||
return are_types_identical_internal(x, y, false);
|
||||
}
|
||||
gb_internal bool are_types_identical_unique_tuples(Type *x, Type *y) {
|
||||
return are_types_identical_internal(x, y, true);
|
||||
}
|
||||
|
||||
|
||||
gb_internal bool are_types_identical_internal(Type *x, Type *y, bool check_tuple_names) {
|
||||
if (x == y) {
|
||||
return true;
|
||||
}
|
||||
@@ -2561,6 +2553,64 @@ gb_internal bool are_types_identical_internal(Type *x, Type *y, bool check_tuple
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
gb_internal bool are_types_identical_internal(Type *x, Type *y, bool check_tuple_names) {
|
||||
if (x == y) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!x | !y) {
|
||||
return false;
|
||||
}
|
||||
|
||||
#if 0
|
||||
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;
|
||||
}
|
||||
#endif
|
||||
|
||||
switch (x->kind) {
|
||||
case Type_Generic:
|
||||
return are_types_identical(x->Generic.specialized, y->Generic.specialized);
|
||||
|
||||
Reference in New Issue
Block a user