Commit bb526426e7

Andrew Kelley <andrew@ziglang.org>
2023-06-01 00:00:48
InternPool: remove memoized_decl
This is neither a type nor a value. Simplifies `addStrLit` as well as the many places that switch on `InternPool.Key`. This is a partial revert of bec29b9e498e08202679aa29a45dab2a06a69a1e.
1 parent 870e384
src/arch/wasm/CodeGen.zig
@@ -3255,9 +3255,7 @@ fn lowerConstant(func: *CodeGen, arg_val: Value, ty: Type) InnerError!WValue {
             else => unreachable,
         },
         .un => return func.fail("Wasm TODO: LowerConstant for {}", .{ty.fmt(mod)}),
-        .memoized_decl,
-        .memoized_call,
-        => unreachable,
+        .memoized_call => unreachable,
     }
 }
 
src/codegen/c.zig
@@ -925,7 +925,6 @@ pub const DeclGen = struct {
             .error_set_type,
             .inferred_error_set_type,
             // memoization, not values
-            .memoized_decl,
             .memoized_call,
             => unreachable,
 
src/codegen/llvm.zig
@@ -3796,9 +3796,7 @@ pub const DeclGen = struct {
                     return llvm_union_ty.constNamedStruct(&fields, fields_len);
                 }
             },
-            .memoized_decl,
-            .memoized_call,
-            => unreachable,
+            .memoized_call => unreachable,
         }
     }
 
src/codegen/spirv.zig
@@ -831,9 +831,7 @@ pub const DeclGen = struct {
 
                     try self.addUndef(layout.padding);
                 },
-                .memoized_decl,
-                .memoized_call,
-                => unreachable,
+                .memoized_call => unreachable,
             }
         }
     };
src/codegen.zig
@@ -610,9 +610,7 @@ pub fn generateSymbol(
                 }
             }
         },
-        .memoized_decl,
-        .memoized_call,
-        => unreachable,
+        .memoized_call => unreachable,
     }
     return .ok;
 }
src/InternPool.zig
@@ -221,8 +221,6 @@ pub const Key = union(enum) {
     /// An instance of a union.
     un: Union,
 
-    /// A declaration with a memoized value.
-    memoized_decl: MemoizedDecl,
     /// A comptime function call with a memoized result.
     memoized_call: Key.MemoizedCall,
 
@@ -639,11 +637,6 @@ pub const Key = union(enum) {
         };
     };
 
-    pub const MemoizedDecl = struct {
-        val: Index,
-        decl: Module.Decl.Index,
-    };
-
     pub const MemoizedCall = struct {
         func: Module.Fn.Index,
         arg_values: []const Index,
@@ -853,8 +846,6 @@ pub const Key = union(enum) {
                 return hasher.final();
             },
 
-            .memoized_decl => |x| WyhashKing.hash(seed, asBytes(&x.val)),
-
             .memoized_call => |memoized_call| {
                 var hasher = std.hash.Wyhash.init(seed);
                 std.hash.autoHash(&hasher, memoized_call.func);
@@ -1134,11 +1125,6 @@ pub const Key = union(enum) {
                     a_info.is_noinline == b_info.is_noinline;
             },
 
-            .memoized_decl => |a_info| {
-                const b_info = b.memoized_decl;
-                return a_info.val == b_info.val;
-            },
-
             .memoized_call => |a_info| {
                 const b_info = b.memoized_call;
                 return a_info.func == b_info.func and
@@ -1197,9 +1183,7 @@ pub const Key = union(enum) {
                 .generic_poison => .generic_poison_type,
             },
 
-            .memoized_decl,
-            .memoized_call,
-            => unreachable,
+            .memoized_call => unreachable,
         };
     }
 };
@@ -1481,7 +1465,6 @@ pub const Index = enum(u32) {
         },
         repeated: struct { data: *Repeated },
 
-        memoized_decl: struct { data: *Key.MemoizedDecl },
         memoized_call: struct {
             const @"data.args_len" = opaque {};
             data: *MemoizedCall,
@@ -1989,9 +1972,6 @@ pub const Tag = enum(u8) {
     /// data is extra index to `Repeated`.
     repeated,
 
-    /// A memoized declaration value.
-    /// data is extra index to `Key.MemoizedDecl`
-    memoized_decl,
     /// A memoized comptime function call result.
     /// data is extra index to `MemoizedCall`
     memoized_call,
@@ -2004,7 +1984,6 @@ pub const Tag = enum(u8) {
     const ExternFunc = Key.ExternFunc;
     const Func = Key.Func;
     const Union = Key.Union;
-    const MemoizedDecl = Key.MemoizedDecl;
     const TypePointer = Key.PtrType;
 
     fn Payload(comptime tag: Tag) type {
@@ -2082,7 +2061,6 @@ pub const Tag = enum(u8) {
             .bytes => Bytes,
             .aggregate => Aggregate,
             .repeated => Repeated,
-            .memoized_decl => MemoizedDecl,
             .memoized_call => MemoizedCall,
         };
     }
@@ -3000,7 +2978,6 @@ pub fn indexToKey(ip: *const InternPool, index: Index) Key {
         .enum_literal => .{ .enum_literal = @intToEnum(NullTerminatedString, data) },
         .enum_tag => .{ .enum_tag = ip.extraData(Tag.EnumTag, data) },
 
-        .memoized_decl => .{ .memoized_decl = ip.extraData(Key.MemoizedDecl, data) },
         .memoized_call => {
             const extra = ip.extraDataTrail(MemoizedCall, data);
             return .{ .memoized_call = .{
@@ -3995,14 +3972,6 @@ pub fn get(ip: *InternPool, gpa: Allocator, key: Key) Allocator.Error!Index {
             });
         },
 
-        .memoized_decl => |memoized_decl| {
-            assert(memoized_decl.val != .none);
-            ip.items.appendAssumeCapacity(.{
-                .tag = .memoized_decl,
-                .data = try ip.addExtra(gpa, memoized_decl),
-            });
-        },
-
         .memoized_call => |memoized_call| {
             for (memoized_call.arg_values) |arg| assert(arg != .none);
             try ip.extra.ensureUnusedCapacity(gpa, @typeInfo(MemoizedCall).Struct.fields.len +
@@ -5005,7 +4974,6 @@ fn dumpFallible(ip: *const InternPool, arena: Allocator) anyerror!void {
             .only_possible_value => 0,
             .union_value => @sizeOf(Key.Union),
 
-            .memoized_decl => @sizeOf(Key.MemoizedDecl),
             .memoized_call => b: {
                 const info = ip.extraData(MemoizedCall, data);
                 break :b @sizeOf(MemoizedCall) + (@sizeOf(Index) * info.args_len);
@@ -5383,7 +5351,6 @@ pub fn typeOf(ip: *const InternPool, index: Index) Index {
 
             .float_comptime_float => .comptime_float_type,
 
-            .memoized_decl => unreachable,
             .memoized_call => unreachable,
         },
 
@@ -5624,7 +5591,6 @@ pub fn zigTypeTagOrPoison(ip: *const InternPool, index: Index) error{GenericPois
             .aggregate,
             .repeated,
             // memoization, not types
-            .memoized_decl,
             .memoized_call,
             => unreachable,
         },
src/Module.zig
@@ -88,6 +88,9 @@ embed_table: std.StringHashMapUnmanaged(*EmbedFile) = .{},
 /// Stores all Type and Value objects; periodically garbage collected.
 intern_pool: InternPool = .{},
 
+/// This is currently only used for string literals.
+memoized_decls: std.AutoHashMapUnmanaged(InternPool.Index, Decl.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.
@@ -561,6 +564,7 @@ pub const Decl = struct {
             }
             mod.destroyFunc(func);
         }
+        _ = mod.memoized_decls.remove(decl.val.ip_index);
         if (decl.value_arena) |value_arena| {
             value_arena.deinit(gpa);
             decl.value_arena = null;
@@ -3285,6 +3289,7 @@ pub fn deinit(mod: *Module) void {
     mod.namespaces_free_list.deinit(gpa);
     mod.allocated_namespaces.deinit(gpa);
 
+    mod.memoized_decls.deinit(gpa);
     mod.intern_pool.deinit(gpa);
 }
 
src/Sema.zig
@@ -5183,33 +5183,26 @@ fn zirStr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Ins
 
 fn addStrLit(sema: *Sema, block: *Block, bytes: []const u8) CompileError!Air.Inst.Ref {
     const mod = sema.mod;
-    const memoized_decl_index = memoized: {
-        const ty = try mod.arrayType(.{
-            .len = bytes.len,
-            .child = .u8_type,
-            .sentinel = .zero_u8,
+    const gpa = sema.gpa;
+    const ty = try mod.arrayType(.{
+        .len = bytes.len,
+        .child = .u8_type,
+        .sentinel = .zero_u8,
+    });
+    const val = try mod.intern(.{ .aggregate = .{
+        .ty = ty.toIntern(),
+        .storage = .{ .bytes = bytes },
+    } });
+    const gop = try mod.memoized_decls.getOrPut(gpa, val);
+    if (!gop.found_existing) {
+        const new_decl_index = try mod.createAnonymousDecl(block, .{
+            .ty = ty,
+            .val = val.toValue(),
         });
-        const val = try mod.intern(.{ .aggregate = .{
-            .ty = ty.toIntern(),
-            .storage = .{ .bytes = bytes },
-        } });
-
-        _ = try sema.typeHasRuntimeBits(ty);
-        const new_decl_index = try mod.createAnonymousDecl(block, .{ .ty = ty, .val = val.toValue() });
-        errdefer mod.abortAnonDecl(new_decl_index);
-
-        const memoized_index = try mod.intern(.{ .memoized_decl = .{
-            .val = val,
-            .decl = new_decl_index,
-        } });
-        const memoized_decl_index = mod.intern_pool.indexToKey(memoized_index).memoized_decl.decl;
-        if (memoized_decl_index != new_decl_index)
-            mod.abortAnonDecl(new_decl_index)
-        else
-            try mod.finalizeAnonDecl(new_decl_index);
-        break :memoized memoized_decl_index;
-    };
-    return sema.analyzeDeclRef(memoized_decl_index);
+        gop.value_ptr.* = new_decl_index;
+        try mod.finalizeAnonDecl(new_decl_index);
+    }
+    return sema.analyzeDeclRef(gop.value_ptr.*);
 }
 
 fn zirInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
@@ -32156,7 +32149,6 @@ pub fn resolveTypeRequiresComptime(sema: *Sema, ty: Type) CompileError!bool {
             .aggregate,
             .un,
             // memoization, not types
-            .memoized_decl,
             .memoized_call,
             => unreachable,
         },
@@ -33666,7 +33658,6 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value {
             .aggregate,
             .un,
             // memoization, not types
-            .memoized_decl,
             .memoized_call,
             => unreachable,
         },
@@ -34155,7 +34146,6 @@ pub fn typeRequiresComptime(sema: *Sema, ty: Type) CompileError!bool {
             .aggregate,
             .un,
             // memoization, not types
-            .memoized_decl,
             .memoized_call,
             => unreachable,
         },
src/type.zig
@@ -446,7 +446,6 @@ pub const Type = struct {
             .aggregate,
             .un,
             // memoization, not types
-            .memoized_decl,
             .memoized_call,
             => unreachable,
         }
@@ -663,7 +662,6 @@ pub const Type = struct {
                 .aggregate,
                 .un,
                 // memoization, not types
-                .memoized_decl,
                 .memoized_call,
                 => unreachable,
             },
@@ -773,7 +771,6 @@ pub const Type = struct {
             .aggregate,
             .un,
             // memoization, not types
-            .memoized_decl,
             .memoized_call,
             => unreachable,
         };
@@ -1108,7 +1105,6 @@ pub const Type = struct {
                 .aggregate,
                 .un,
                 // memoization, not types
-                .memoized_decl,
                 .memoized_call,
                 => unreachable,
             },
@@ -1526,7 +1522,6 @@ pub const Type = struct {
                 .aggregate,
                 .un,
                 // memoization, not types
-                .memoized_decl,
                 .memoized_call,
                 => unreachable,
             },
@@ -1761,7 +1756,6 @@ pub const Type = struct {
             .aggregate,
             .un,
             // memoization, not types
-            .memoized_decl,
             .memoized_call,
             => unreachable,
         }
@@ -2315,7 +2309,6 @@ pub const Type = struct {
                 .aggregate,
                 .un,
                 // memoization, not types
-                .memoized_decl,
                 .memoized_call,
                 => unreachable,
             },
@@ -2666,7 +2659,6 @@ pub const Type = struct {
                 .aggregate,
                 .un,
                 // memoization, not types
-                .memoized_decl,
                 .memoized_call,
                 => unreachable,
             },
@@ -2812,7 +2804,6 @@ pub const Type = struct {
                 .aggregate,
                 .un,
                 // memoization, not types
-                .memoized_decl,
                 .memoized_call,
                 => unreachable,
             },
src/TypedValue.zig
@@ -279,9 +279,7 @@ pub fn print(
                 } else try writer.writeAll("...");
                 return writer.writeAll(" }");
             },
-            .memoized_decl,
-            .memoized_call,
-            => unreachable,
+            .memoized_call => unreachable,
         },
     };
 }
src/value.zig
@@ -478,9 +478,7 @@ pub const Value = struct {
                 .val = un.val.toValue(),
             }),
 
-            .memoized_decl,
-            .memoized_call,
-            => unreachable,
+            .memoized_call => unreachable,
         };
     }