diff options
| author | Jacob Young <jacobly0@users.noreply.github.com> | 2023-06-02 04:24:25 -0400 |
|---|---|---|
| committer | Andrew Kelley <andrew@ziglang.org> | 2023-06-10 20:47:59 -0700 |
| commit | da24ea7f36d056cb49e8e91064f06cb724e46f67 (patch) | |
| tree | 0b3920d68166cf664d4c72731d1260ea34a82d72 /src/Module.zig | |
| parent | 04e66e6b4deb67aef9a4064decd82a678cb7ec82 (diff) | |
| download | zig-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.zig | 40 |
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); } } |
