aboutsummaryrefslogtreecommitdiff
path: root/src/Module.zig
diff options
context:
space:
mode:
authorJacob Young <jacobly0@users.noreply.github.com>2023-06-02 04:24:25 -0400
committerAndrew Kelley <andrew@ziglang.org>2023-06-10 20:47:59 -0700
commitda24ea7f36d056cb49e8e91064f06cb724e46f67 (patch)
tree0b3920d68166cf664d4c72731d1260ea34a82d72 /src/Module.zig
parent04e66e6b4deb67aef9a4064decd82a678cb7ec82 (diff)
downloadzig-da24ea7f36d056cb49e8e91064f06cb724e46f67.tar.gz
zig-da24ea7f36d056cb49e8e91064f06cb724e46f67.zip
Sema: rewrite `monomorphed_funcs` usage
In an effort to delete `Value.hashUncoerced`, generic instantiation has been redesigned. Instead of just storing instantiations in `monomorphed_funcs`, partially instantiated generic argument types are also cached. This isn't quite the single `getOrPut` that it used to be, but one `get` per generic argument plus one get for the instantiation, with an equal number of `put`s per unique instantiation isn't bad.
Diffstat (limited to 'src/Module.zig')
-rw-r--r--src/Module.zig40
1 files changed, 27 insertions, 13 deletions
diff --git a/src/Module.zig b/src/Module.zig
index 1b64f9f72e..5f28f4f069 100644
--- a/src/Module.zig
+++ b/src/Module.zig
@@ -99,6 +99,7 @@ tmp_hack_arena: std.heap.ArenaAllocator,
/// This is currently only used for string literals.
memoized_decls: std.AutoHashMapUnmanaged(InternPool.Index, Decl.Index) = .{},
+monomorphed_func_keys: std.ArrayListUnmanaged(InternPool.Index) = .{},
/// The set of all the generic function instantiations. This is used so that when a generic
/// function is called twice with the same comptime parameter arguments, both calls dispatch
/// to the same function.
@@ -202,24 +203,40 @@ pub const CImportError = struct {
}
};
-const MonomorphedFuncsSet = std.HashMapUnmanaged(
- Fn.Index,
- void,
+pub const MonomorphedFuncKey = struct { func: Fn.Index, args_index: u32, args_len: u32 };
+
+pub const MonomorphedFuncAdaptedKey = struct { func: Fn.Index, args: []const InternPool.Index };
+
+pub const MonomorphedFuncsSet = std.HashMapUnmanaged(
+ MonomorphedFuncKey,
+ InternPool.Index,
MonomorphedFuncsContext,
std.hash_map.default_max_load_percentage,
);
-const MonomorphedFuncsContext = struct {
+pub const MonomorphedFuncsContext = struct {
+ mod: *Module,
+
+ pub fn eql(_: @This(), a: MonomorphedFuncKey, b: MonomorphedFuncKey) bool {
+ return std.meta.eql(a, b);
+ }
+
+ pub fn hash(ctx: @This(), key: MonomorphedFuncKey) u64 {
+ const key_args = ctx.mod.monomorphed_func_keys.items[key.args_index..][0..key.args_len];
+ return std.hash.Wyhash.hash(@enumToInt(key.func), std.mem.sliceAsBytes(key_args));
+ }
+};
+
+pub const MonomorphedFuncsAdaptedContext = struct {
mod: *Module,
- pub fn eql(ctx: @This(), a: Fn.Index, b: Fn.Index) bool {
- _ = ctx;
- return a == b;
+ pub fn eql(ctx: @This(), adapted_key: MonomorphedFuncAdaptedKey, other_key: MonomorphedFuncKey) bool {
+ const other_key_args = ctx.mod.monomorphed_func_keys.items[other_key.args_index..][0..other_key.args_len];
+ return adapted_key.func == other_key.func and std.mem.eql(InternPool.Index, adapted_key.args, other_key_args);
}
- /// Must match `Sema.GenericCallAdapter.hash`.
- pub fn hash(ctx: @This(), key: Fn.Index) u64 {
- return ctx.mod.funcPtr(key).hash;
+ pub fn hash(_: @This(), adapted_key: MonomorphedFuncAdaptedKey) u64 {
+ return std.hash.Wyhash.hash(@enumToInt(adapted_key.func), std.mem.sliceAsBytes(adapted_key.args));
}
};
@@ -571,9 +588,6 @@ pub const Decl = struct {
pub fn clearValues(decl: *Decl, mod: *Module) void {
if (decl.getOwnedFunctionIndex(mod).unwrap()) |func| {
_ = mod.align_stack_fns.remove(func);
- if (mod.funcPtr(func).comptime_args != null) {
- _ = mod.monomorphed_funcs.removeContext(func, .{ .mod = mod });
- }
mod.destroyFunc(func);
}
}