@@ -49,6 +49,11 @@ namespace_deps: std.AutoArrayHashMapUnmanaged(TrackedInst.Index, DepEntry.Index)
49
49
/// Dependencies on the (non-)existence of some name in a namespace.
50
50
/// Value is index into `dep_entries` of the first dependency on this name.
51
51
namespace_name_deps : std .AutoArrayHashMapUnmanaged (NamespaceNameKey , DepEntry .Index ),
52
+ // Dependencies on the value of fields memoized on `Zcu` (`panic_messages` etc).
53
+ // If set, these are indices into `dep_entries` of the first dependency on this state.
54
+ memoized_state_main_deps : DepEntry.Index.Optional ,
55
+ memoized_state_panic_deps : DepEntry.Index.Optional ,
56
+ memoized_state_va_list_deps : DepEntry.Index.Optional ,
52
57
53
58
/// Given a `Depender`, points to an entry in `dep_entries` whose `depender`
54
59
/// matches. The `next_dependee` field can be used to iterate all such entries
@@ -87,6 +92,9 @@ pub const empty: InternPool = .{
87
92
.interned_deps = .empty ,
88
93
.namespace_deps = .empty ,
89
94
.namespace_name_deps = .empty ,
95
+ .memoized_state_main_deps = .none ,
96
+ .memoized_state_panic_deps = .none ,
97
+ .memoized_state_va_list_deps = .none ,
90
98
.first_dependency = .empty ,
91
99
.dep_entries = .empty ,
92
100
.free_dep_entries = .empty ,
@@ -385,6 +393,7 @@ pub const AnalUnit = packed struct(u64) {
385
393
nav_ty ,
386
394
type ,
387
395
func ,
396
+ memoized_state ,
388
397
};
389
398
390
399
pub const Unwrapped = union (Kind ) {
@@ -399,6 +408,8 @@ pub const AnalUnit = packed struct(u64) {
399
408
type : InternPool .Index ,
400
409
/// This `AnalUnit` analyzes the body of the given runtime function.
401
410
func : InternPool.Index ,
411
+ /// This `AnalUnit` resolves all state which is memoized in fields on `Zcu`.
412
+ memoized_state : MemoizedStateStage ,
402
413
};
403
414
404
415
pub fn unwrap (au : AnalUnit ) Unwrapped {
@@ -434,6 +445,16 @@ pub const AnalUnit = packed struct(u64) {
434
445
};
435
446
};
436
447
448
+ pub const MemoizedStateStage = enum (u32 ) {
449
+ /// Everything other than panics and `VaList`.
450
+ main ,
451
+ /// Everything within `std.builtin.Panic`.
452
+ /// Since the panic handler is user-provided, this must be able to reference the other memoized state.
453
+ panic ,
454
+ /// Specifically `std.builtin.VaList`. See `Zcu.BuiltinDecl.stage`.
455
+ va_list ,
456
+ };
457
+
437
458
pub const ComptimeUnit = extern struct {
438
459
zir_index : TrackedInst.Index ,
439
460
namespace : NamespaceIndex ,
@@ -769,6 +790,7 @@ pub const Dependee = union(enum) {
769
790
interned : Index ,
770
791
namespace : TrackedInst.Index ,
771
792
namespace_name : NamespaceNameKey ,
793
+ memoized_state : MemoizedStateStage ,
772
794
};
773
795
774
796
pub fn removeDependenciesForDepender (ip : * InternPool , gpa : Allocator , depender : AnalUnit ) void {
@@ -819,6 +841,11 @@ pub fn dependencyIterator(ip: *const InternPool, dependee: Dependee) DependencyI
819
841
.interned = > | x | ip .interned_deps .get (x ),
820
842
.namespace = > | x | ip .namespace_deps .get (x ),
821
843
.namespace_name = > | x | ip .namespace_name_deps .get (x ),
844
+ .memoized_state = > | stage | switch (stage ) {
845
+ .main = > ip .memoized_state_main_deps .unwrap (),
846
+ .panic = > ip .memoized_state_panic_deps .unwrap (),
847
+ .va_list = > ip .memoized_state_va_list_deps .unwrap (),
848
+ },
822
849
} orelse return .{
823
850
.ip = ip ,
824
851
.next_entry = .none ,
@@ -848,6 +875,33 @@ pub fn addDependency(ip: *InternPool, gpa: Allocator, depender: AnalUnit, depend
848
875
// This block should allocate an entry and prepend it to the relevant `*_deps` list.
849
876
// The `next` field should be correctly initialized; all other fields may be undefined.
850
877
const new_index : DepEntry.Index = switch (dependee ) {
878
+ .memoized_state = > | stage | new_index : {
879
+ const deps = switch (stage ) {
880
+ .main = > & ip .memoized_state_main_deps ,
881
+ .panic = > & ip .memoized_state_panic_deps ,
882
+ .va_list = > & ip .memoized_state_va_list_deps ,
883
+ };
884
+
885
+ if (deps .unwrap ()) | first | {
886
+ if (ip .dep_entries .items [@intFromEnum (first )].depender == .none ) {
887
+ // Dummy entry, so we can reuse it rather than allocating a new one!
888
+ break :new_index first ;
889
+ }
890
+ }
891
+
892
+ // Prepend a new dependency.
893
+ const new_index : DepEntry.Index , const ptr = if (ip .free_dep_entries .popOrNull ()) | new_index | new : {
894
+ break :new .{ new_index , & ip .dep_entries .items [@intFromEnum (new_index )] };
895
+ } else .{ @enumFromInt (ip .dep_entries .items .len ), ip .dep_entries .addOneAssumeCapacity () };
896
+ if (deps .unwrap ()) | old_first | {
897
+ ptr .next = old_first .toOptional ();
898
+ ip .dep_entries .items [@intFromEnum (old_first )].prev = new_index .toOptional ();
899
+ } else {
900
+ ptr .next = .none ;
901
+ }
902
+ deps .* = new_index .toOptional ();
903
+ break :new_index new_index ;
904
+ },
851
905
inline else = > | dependee_payload , tag | new_index : {
852
906
const gop = try switch (tag ) {
853
907
.file = > ip .file_deps ,
@@ -857,6 +911,7 @@ pub fn addDependency(ip: *InternPool, gpa: Allocator, depender: AnalUnit, depend
857
911
.interned = > ip .interned_deps ,
858
912
.namespace = > ip .namespace_deps ,
859
913
.namespace_name = > ip .namespace_name_deps ,
914
+ .memoized_state = > comptime unreachable ,
860
915
}.getOrPut (gpa , dependee_payload );
861
916
862
917
if (gop .found_existing and ip .dep_entries .items [@intFromEnum (gop .value_ptr .* )].depender == .none ) {
@@ -2029,15 +2084,7 @@ pub const Key = union(enum) {
2029
2084
pub const NamespaceType = union (enum ) {
2030
2085
/// This type corresponds to an actual source declaration, e.g. `struct { ... }`.
2031
2086
/// It is hashed based on its ZIR instruction index and set of captures.
2032
- declared : struct {
2033
- /// A `struct_decl`, `union_decl`, `enum_decl`, or `opaque_decl` instruction.
2034
- zir_index : TrackedInst.Index ,
2035
- /// The captured values of this type. These values must be fully resolved per the language spec.
2036
- captures : union (enum ) {
2037
- owned : CaptureValue.Slice ,
2038
- external : []const CaptureValue ,
2039
- },
2040
- },
2087
+ declared : Declared ,
2041
2088
/// This type is an automatically-generated enum tag type for a union.
2042
2089
/// It is hashed based on the index of the union type it corresponds to.
2043
2090
generated_tag : struct {
@@ -2053,6 +2100,16 @@ pub const Key = union(enum) {
2053
2100
/// A hash of this type's attributes, fields, etc, generated by Sema.
2054
2101
type_hash : u64 ,
2055
2102
},
2103
+
2104
+ pub const Declared = struct {
2105
+ /// A `struct_decl`, `union_decl`, `enum_decl`, or `opaque_decl` instruction.
2106
+ zir_index : TrackedInst.Index ,
2107
+ /// The captured values of this type. These values must be fully resolved per the language spec.
2108
+ captures : union (enum ) {
2109
+ owned : CaptureValue.Slice ,
2110
+ external : []const CaptureValue ,
2111
+ },
2112
+ };
2056
2113
};
2057
2114
2058
2115
pub const FuncType = struct {
0 commit comments