Browse Source

General optimizations

gingerBill 2 years ago
parent
commit
7124d541a1
5 changed files with 99 additions and 11 deletions
  1. 2 1
      src/check_type.cpp
  2. 8 7
      src/checker.cpp
  3. 1 1
      src/checker.hpp
  4. 36 0
      src/ptr_map.cpp
  5. 52 2
      src/types.cpp

+ 2 - 1
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] = {

+ 8 - 7
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

+ 1 - 1
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;

+ 36 - 0
src/ptr_map.cpp

@@ -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);

+ 52 - 2
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: