authorgravatar for mlugg@mlugg.co.ukMatthew Lugg <mlugg@mlugg.co.uk> 2025-01-05 00:50:58+00:00
committergravatar for mlugg@mlugg.co.ukMatthew Lugg <mlugg@mlugg.co.uk> 2025-01-05 05:52:02+00:00
logb039a8b6155e1eddd9f447ff261d56771c12e038
tree0c6c6d44c4e8d6b89a260d61f4472ebc0c9186f5
parent136c5a916ed7e421461ac5839cc0e4c289b80f16

compiler: slightly simplify builtin decl memoization

Rather than `Zcu.BuiltinDecl.Memoized` being a struct with fields, it can instead just be an array, indexed by the enum. This allows runtime indexing, avoiding a few now-unnecessary `inline` switch cases.

4 files changed, 39 insertions(+), 31 deletions(-)

src/Sema.zig+13-18
......@@ -27612,13 +27612,8 @@ fn explainWhyTypeIsNotPacked(
2761227612fn preparePanicId(sema: *Sema, src: LazySrcLoc, panic_id: Zcu.PanicId) !InternPool.Index {
2761327613 const zcu = sema.pt.zcu;
2761427614 try sema.ensureMemoizedStateResolved(src, .panic);
27615 try zcu.ensureFuncBodyAnalysisQueued(zcu.builtin_decl_values.@"Panic.call");
27616 switch (panic_id) {
27617 inline else => |ct_panic_id| {
27618 const name = "Panic.messages." ++ @tagName(ct_panic_id);
27619 return @field(zcu.builtin_decl_values, name);
27620 },
27621 }
27615 try zcu.ensureFuncBodyAnalysisQueued(zcu.builtin_decl_values.get(.@"Panic.call"));
27616 return zcu.builtin_decl_values.get(panic_id.toBuiltin());
2762227617}
2762327618
2762427619fn addSafetyCheck(
......@@ -27723,9 +27718,9 @@ fn panicWithMsg(sema: *Sema, block: *Block, src: LazySrcLoc, msg_inst: Air.Inst.
2772327718 }
2772427719
2772527720 try sema.ensureMemoizedStateResolved(src, .panic);
27726 try zcu.ensureFuncBodyAnalysisQueued(zcu.builtin_decl_values.@"Panic.call");
27721 try zcu.ensureFuncBodyAnalysisQueued(zcu.builtin_decl_values.get(.@"Panic.call"));
2772727722
27728 const panic_fn = Air.internedToRef(zcu.builtin_decl_values.@"Panic.call");
27723 const panic_fn = Air.internedToRef(zcu.builtin_decl_values.get(.@"Panic.call"));
2772927724 const null_stack_trace = Air.internedToRef(zcu.null_stack_trace);
2773027725
2773127726 const opt_usize_ty = try pt.optionalType(.usize_type);
......@@ -38720,15 +38715,15 @@ const ComptimeLoadResult = @import("Sema/comptime_ptr_access.zig").ComptimeLoadR
3872038715const storeComptimePtr = @import("Sema/comptime_ptr_access.zig").storeComptimePtr;
3872138716const ComptimeStoreResult = @import("Sema/comptime_ptr_access.zig").ComptimeStoreResult;
3872238717
38723pub fn getBuiltinType(sema: *Sema, src: LazySrcLoc, comptime decl: Zcu.BuiltinDecl) SemaError!Type {
38724 comptime assert(decl.kind() == .type);
38718pub fn getBuiltinType(sema: *Sema, src: LazySrcLoc, decl: Zcu.BuiltinDecl) SemaError!Type {
38719 assert(decl.kind() == .type);
3872538720 try sema.ensureMemoizedStateResolved(src, decl.stage());
38726 return .fromInterned(@field(sema.pt.zcu.builtin_decl_values, @tagName(decl)));
38721 return .fromInterned(sema.pt.zcu.builtin_decl_values.get(decl));
3872738722}
38728pub fn getBuiltin(sema: *Sema, src: LazySrcLoc, comptime decl: Zcu.BuiltinDecl) SemaError!InternPool.Index {
38729 comptime assert(decl.kind() != .type);
38723pub fn getBuiltin(sema: *Sema, src: LazySrcLoc, decl: Zcu.BuiltinDecl) SemaError!InternPool.Index {
38724 assert(decl.kind() != .type);
3873038725 try sema.ensureMemoizedStateResolved(src, decl.stage());
38731 return @field(sema.pt.zcu.builtin_decl_values, @tagName(decl));
38726 return sema.pt.zcu.builtin_decl_values.get(decl);
3873238727}
3873338728
3873438729pub const NavPtrModifiers = struct {
......@@ -38810,7 +38805,7 @@ pub fn analyzeMemoizedState(sema: *Sema, block: *Block, src: LazySrcLoc, builtin
3881038805 const parent_ns: Zcu.Namespace.Index, const parent_name: []const u8, const name: []const u8 = switch (comptime builtin_decl.access()) {
3881138806 .direct => |name| .{ builtin_namespace, "std.builtin", name },
3881238807 .nested => |nested| access: {
38813 const parent_ty: Type = .fromInterned(@field(zcu.builtin_decl_values, @tagName(nested[0])));
38808 const parent_ty: Type = .fromInterned(zcu.builtin_decl_values.get(nested[0]));
3881438809 const parent_ns = parent_ty.getNamespace(zcu).unwrap() orelse {
3881538810 return sema.fail(block, src, "std.builtin.{s} is not a container type", .{@tagName(nested[0])});
3881638811 };
......@@ -38845,9 +38840,9 @@ pub fn analyzeMemoizedState(sema: *Sema, block: *Block, src: LazySrcLoc, builtin
3884538840 },
3884638841 }
3884738842
38848 const prev = @field(zcu.builtin_decl_values, @tagName(builtin_decl));
38843 const prev = zcu.builtin_decl_values.get(builtin_decl);
3884938844 if (val.toIntern() != prev) {
38850 @field(zcu.builtin_decl_values, @tagName(builtin_decl)) = val.toIntern();
38845 zcu.builtin_decl_values.set(builtin_decl, val.toIntern());
3885138846 any_changed = true;
3885238847 }
3885338848 }
src/Zcu.zig+18-3
......@@ -217,8 +217,8 @@ all_type_references: std.ArrayListUnmanaged(TypeReference) = .empty,
217217/// Freelist of indices in `all_type_references`.
218218free_type_references: std.ArrayListUnmanaged(u32) = .empty,
219219
220/// Populated by analysis of `AnalUnit.wrap(.{ .memoized_state = s })`, where `s` depends on the field.
221builtin_decl_values: BuiltinDecl.Memoized = .{},
220/// Populated by analysis of `AnalUnit.wrap(.{ .memoized_state = s })`, where `s` depends on the element.
221builtin_decl_values: BuiltinDecl.Memoized = .initFill(.none),
222222/// Populated by analysis of `AnalUnit.wrap(.{ .memoized_state = .panic })`.
223223null_stack_trace: InternPool.Index = .none,
224224
......@@ -420,7 +420,7 @@ pub const BuiltinDecl = enum {
420420 };
421421 }
422422
423 const Memoized = std.enums.EnumFieldStruct(BuiltinDecl, InternPool.Index, .none);
423 const Memoized = std.enums.EnumArray(BuiltinDecl, InternPool.Index);
424424};
425425
426426pub const PanicId = enum {
......@@ -444,6 +444,21 @@ pub const PanicId = enum {
444444 memcpy_len_mismatch,
445445 memcpy_alias,
446446 noreturn_returned,
447
448 pub fn toBuiltin(id: PanicId) BuiltinDecl {
449 const first_msg: PanicId = @enumFromInt(0);
450 const first_decl = @field(BuiltinDecl, "Panic.messages." ++ @tagName(first_msg));
451 comptime {
452 // Ensure that the messages are ordered the same in `BuiltinDecl` as they are here.
453 for (@typeInfo(PanicId).@"enum".fields) |panic_field| {
454 const expect_name = "Panic.messages." ++ panic_field.name;
455 const expect_idx = @intFromEnum(first_decl) + panic_field.value;
456 const actual_idx = @intFromEnum(@field(BuiltinDecl, expect_name));
457 assert(expect_idx == actual_idx);
458 }
459 }
460 return @enumFromInt(@intFromEnum(first_decl) + @intFromEnum(id));
461 }
447462};
448463
449464pub const GlobalErrorSet = std.AutoArrayHashMapUnmanaged(InternPool.NullTerminatedString, void);
src/Zcu/PerThread.zig+6-6
......@@ -590,13 +590,13 @@ pub fn ensureMemoizedStateUpToDate(pt: Zcu.PerThread, stage: InternPool.Memoized
590590 _ = zcu.transitive_failed_analysis.swapRemove(unit);
591591 } else {
592592 if (prev_failed) return error.AnalysisFail;
593 // We use an arbitrary field to check if the state has been resolved yet.
594 const val = switch (stage) {
595 .main => zcu.builtin_decl_values.Type,
596 .panic => zcu.builtin_decl_values.Panic,
597 .va_list => zcu.builtin_decl_values.VaList,
593 // We use an arbitrary element to check if the state has been resolved yet.
594 const to_check: Zcu.BuiltinDecl = switch (stage) {
595 .main => .Type,
596 .panic => .Panic,
597 .va_list => .VaList,
598598 };
599 if (val != .none) return;
599 if (zcu.builtin_decl_values.get(to_check) != .none) return;
600600 }
601601
602602 const any_changed: bool, const new_failed: bool = if (pt.analyzeMemoizedState(stage)) |any_changed|
src/codegen/llvm.zig+2-4
......@@ -5754,9 +5754,7 @@ pub const FuncGen = struct {
57545754 const o = fg.ng.object;
57555755 const zcu = o.pt.zcu;
57565756 const ip = &zcu.intern_pool;
5757 const panic_msg_val: InternPool.Index = switch (panic_id) {
5758 inline else => |ct_panic_id| @field(zcu.builtin_decl_values, "Panic.messages." ++ @tagName(ct_panic_id)),
5759 };
5757 const panic_msg_val = zcu.builtin_decl_values.get(panic_id.toBuiltin());
57605758 assert(panic_msg_val != .none);
57615759 const msg_len = Value.fromInterned(panic_msg_val).typeOf(zcu).childType(zcu).arrayLen(zcu);
57625760 const msg_ptr = try o.lowerValue(panic_msg_val);
......@@ -5770,7 +5768,7 @@ pub const FuncGen = struct {
57705768 // ptr null, ; stack trace
57715769 // ptr @2, ; addr (null ?usize)
57725770 // )
5773 const panic_func = zcu.funcInfo(zcu.builtin_decl_values.@"Panic.call");
5771 const panic_func = zcu.funcInfo(zcu.builtin_decl_values.get(.@"Panic.call"));
57745772 const panic_nav = ip.getNav(panic_func.owner_nav);
57755773 const fn_info = zcu.typeToFunc(Type.fromInterned(panic_nav.typeOf(ip))).?;
57765774 const panic_global = try o.resolveLlvmFunction(panic_func.owner_nav);