From da24ea7f36d056cb49e8e91064f06cb724e46f67 Mon Sep 17 00:00:00 2001 From: Jacob Young Date: Fri, 2 Jun 2023 04:24:25 -0400 Subject: 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. --- src/value.zig | 71 ----------------------------------------------------------- 1 file changed, 71 deletions(-) (limited to 'src/value.zig') diff --git a/src/value.zig b/src/value.zig index 2c38852bf5..3958615214 100644 --- a/src/value.zig +++ b/src/value.zig @@ -1691,77 +1691,6 @@ pub const Value = struct { return (try orderAdvanced(a, b, mod, opt_sema)).compare(.eq); } - /// This is a more conservative hash function that produces equal hashes for values - /// that can coerce into each other. - /// This function is used by hash maps and so treats floating-point NaNs as equal - /// to each other, and not equal to other floating-point values. - pub fn hashUncoerced(val: Value, ty: Type, hasher: *std.hash.Wyhash, mod: *Module) void { - if (val.isUndef(mod)) return; - // The value is runtime-known and shouldn't affect the hash. - if (val.isRuntimeValue(mod)) return; - - if (val.ip_index != .none) { - // The InternPool data structure hashes based on Key to make interned objects - // unique. An Index can be treated simply as u32 value for the - // purpose of Type/Value hashing and equality. - std.hash.autoHash(hasher, val.toIntern()); - return; - } - - switch (ty.zigTypeTag(mod)) { - .Opaque => unreachable, // Cannot hash opaque types - .Void, - .NoReturn, - .Undefined, - .Null, - .Struct, // It sure would be nice to do something clever with structs. - => |zig_type_tag| std.hash.autoHash(hasher, zig_type_tag), - .Pointer => { - assert(ty.isSlice(mod)); - const slice = val.castTag(.slice).?.data; - const ptr_ty = ty.slicePtrFieldType(mod); - slice.ptr.hashUncoerced(ptr_ty, hasher, mod); - }, - .Type, - .Float, - .ComptimeFloat, - .Bool, - .Int, - .ComptimeInt, - .Fn, - .Optional, - .ErrorSet, - .ErrorUnion, - .Enum, - .EnumLiteral, - => unreachable, // handled above with the ip_index check - .Array, .Vector => { - const len = ty.arrayLen(mod); - const elem_ty = ty.childType(mod); - var index: usize = 0; - while (index < len) : (index += 1) { - const elem_val = val.elemValue(mod, index) catch |err| switch (err) { - // Will be solved when arrays and vectors get migrated to the intern pool. - error.OutOfMemory => @panic("OOM"), - }; - elem_val.hashUncoerced(elem_ty, hasher, mod); - } - }, - .Union => { - hasher.update(val.tagName(mod)); - switch (mod.intern_pool.indexToKey(val.toIntern())) { - .un => |un| { - const active_field_ty = ty.unionFieldType(un.tag.toValue(), mod); - un.val.toValue().hashUncoerced(active_field_ty, hasher, mod); - }, - else => std.hash.autoHash(hasher, std.builtin.TypeId.Void), - } - }, - .Frame => @panic("TODO implement hashing frame values"), - .AnyFrame => @panic("TODO implement hashing anyframe values"), - } - } - pub fn isComptimeMutablePtr(val: Value, mod: *Module) bool { return switch (mod.intern_pool.indexToKey(val.toIntern())) { .ptr => |ptr| switch (ptr.addr) { -- cgit v1.2.3