| ... | ... | @@ -2,20 +2,20 @@ |
| 2 | 2 | //! This data structure is self-contained. |
| 3 | 3 | |
| 4 | 4 | /// One item per thread, indexed by `tid`, which is dense and unique per thread. |
| 5 | | locals: []Local = &.{}, |
| 5 | locals: []Local, |
| 6 | 6 | /// Length must be a power of two and represents the number of simultaneous |
| 7 | 7 | /// writers that can mutate any single sharded data structure. |
| 8 | | shards: []Shard = &.{}, |
| 8 | shards: []Shard, |
| 9 | 9 | /// Key is the error name, index is the error tag value. Index 0 has a length-0 string. |
| 10 | | global_error_set: GlobalErrorSet = GlobalErrorSet.empty, |
| 10 | global_error_set: GlobalErrorSet, |
| 11 | 11 | /// Cached number of active bits in a `tid`. |
| 12 | | tid_width: if (single_threaded) u0 else std.math.Log2Int(u32) = 0, |
| 12 | tid_width: if (single_threaded) u0 else std.math.Log2Int(u32), |
| 13 | 13 | /// Cached shift amount to put a `tid` in the top bits of a 30-bit value. |
| 14 | | tid_shift_30: if (single_threaded) u0 else std.math.Log2Int(u32) = if (single_threaded) 0 else 31, |
| 14 | tid_shift_30: if (single_threaded) u0 else std.math.Log2Int(u32), |
| 15 | 15 | /// Cached shift amount to put a `tid` in the top bits of a 31-bit value. |
| 16 | | tid_shift_31: if (single_threaded) u0 else std.math.Log2Int(u32) = if (single_threaded) 0 else 31, |
| 16 | tid_shift_31: if (single_threaded) u0 else std.math.Log2Int(u32), |
| 17 | 17 | /// Cached shift amount to put a `tid` in the top bits of a 32-bit value. |
| 18 | | tid_shift_32: if (single_threaded) u0 else std.math.Log2Int(u32) = if (single_threaded) 0 else 31, |
| 18 | tid_shift_32: if (single_threaded) u0 else std.math.Log2Int(u32), |
| 19 | 19 | |
| 20 | 20 | /// Dependencies on the source code hash associated with a ZIR instruction. |
| 21 | 21 | /// * For a `declaration`, this is the entire declaration body. |
| ... | ... | @@ -23,36 +23,36 @@ tid_shift_32: if (single_threaded) u0 else std.math.Log2Int(u32) = if (single_th |
| 23 | 23 | /// * For a `func`, this is the source of the full function signature. |
| 24 | 24 | /// These are also invalidated if tracking fails for this instruction. |
| 25 | 25 | /// Value is index into `dep_entries` of the first dependency on this hash. |
| 26 | | src_hash_deps: std.AutoArrayHashMapUnmanaged(TrackedInst.Index, DepEntry.Index) = .empty, |
| 26 | src_hash_deps: std.AutoArrayHashMapUnmanaged(TrackedInst.Index, DepEntry.Index), |
| 27 | 27 | /// Dependencies on the value of a Nav. |
| 28 | 28 | /// Value is index into `dep_entries` of the first dependency on this Nav value. |
| 29 | | nav_val_deps: std.AutoArrayHashMapUnmanaged(Nav.Index, DepEntry.Index) = .empty, |
| 29 | nav_val_deps: std.AutoArrayHashMapUnmanaged(Nav.Index, DepEntry.Index), |
| 30 | 30 | /// Dependencies on an interned value, either: |
| 31 | 31 | /// * a runtime function (invalidated when its IES changes) |
| 32 | 32 | /// * a container type requiring resolution (invalidated when the type must be recreated at a new index) |
| 33 | 33 | /// Value is index into `dep_entries` of the first dependency on this interned value. |
| 34 | | interned_deps: std.AutoArrayHashMapUnmanaged(Index, DepEntry.Index) = .empty, |
| 34 | interned_deps: std.AutoArrayHashMapUnmanaged(Index, DepEntry.Index), |
| 35 | 35 | /// Dependencies on the full set of names in a ZIR namespace. |
| 36 | 36 | /// Key refers to a `struct_decl`, `union_decl`, etc. |
| 37 | 37 | /// Value is index into `dep_entries` of the first dependency on this namespace. |
| 38 | | namespace_deps: std.AutoArrayHashMapUnmanaged(TrackedInst.Index, DepEntry.Index) = .empty, |
| 38 | namespace_deps: std.AutoArrayHashMapUnmanaged(TrackedInst.Index, DepEntry.Index), |
| 39 | 39 | /// Dependencies on the (non-)existence of some name in a namespace. |
| 40 | 40 | /// Value is index into `dep_entries` of the first dependency on this name. |
| 41 | | namespace_name_deps: std.AutoArrayHashMapUnmanaged(NamespaceNameKey, DepEntry.Index) = .empty, |
| 41 | namespace_name_deps: std.AutoArrayHashMapUnmanaged(NamespaceNameKey, DepEntry.Index), |
| 42 | 42 | |
| 43 | 43 | /// Given a `Depender`, points to an entry in `dep_entries` whose `depender` |
| 44 | 44 | /// matches. The `next_dependee` field can be used to iterate all such entries |
| 45 | 45 | /// and remove them from the corresponding lists. |
| 46 | | first_dependency: std.AutoArrayHashMapUnmanaged(AnalUnit, DepEntry.Index) = .empty, |
| 46 | first_dependency: std.AutoArrayHashMapUnmanaged(AnalUnit, DepEntry.Index), |
| 47 | 47 | |
| 48 | 48 | /// Stores dependency information. The hashmaps declared above are used to look |
| 49 | 49 | /// up entries in this list as required. This is not stored in `extra` so that |
| 50 | 50 | /// we can use `free_dep_entries` to track free indices, since dependencies are |
| 51 | 51 | /// removed frequently. |
| 52 | | dep_entries: std.ArrayListUnmanaged(DepEntry) = .empty, |
| 52 | dep_entries: std.ArrayListUnmanaged(DepEntry), |
| 53 | 53 | /// Stores unused indices in `dep_entries` which can be reused without a full |
| 54 | 54 | /// garbage collection pass. |
| 55 | | free_dep_entries: std.ArrayListUnmanaged(DepEntry.Index) = .empty, |
| 55 | free_dep_entries: std.ArrayListUnmanaged(DepEntry.Index), |
| 56 | 56 | |
| 57 | 57 | /// Whether a multi-threaded intern pool is useful. |
| 58 | 58 | /// Currently `false` until the intern pool is actually accessed |
| ... | ... | @@ -62,6 +62,24 @@ const want_multi_threaded = true; |
| 62 | 62 | /// Whether a single-threaded intern pool impl is in use. |
| 63 | 63 | pub const single_threaded = builtin.single_threaded or !want_multi_threaded; |
| 64 | 64 | |
| 65 | pub const empty: InternPool = .{ |
| 66 | .locals = &.{}, |
| 67 | .shards = &.{}, |
| 68 | .global_error_set = .empty, |
| 69 | .tid_width = 0, |
| 70 | .tid_shift_30 = if (single_threaded) 0 else 31, |
| 71 | .tid_shift_31 = if (single_threaded) 0 else 31, |
| 72 | .tid_shift_32 = if (single_threaded) 0 else 31, |
| 73 | .src_hash_deps = .empty, |
| 74 | .nav_val_deps = .empty, |
| 75 | .interned_deps = .empty, |
| 76 | .namespace_deps = .empty, |
| 77 | .namespace_name_deps = .empty, |
| 78 | .first_dependency = .empty, |
| 79 | .dep_entries = .empty, |
| 80 | .free_dep_entries = .empty, |
| 81 | }; |
| 82 | |
| 65 | 83 | /// A `TrackedInst.Index` provides a single, unchanging reference to a ZIR instruction across a whole |
| 66 | 84 | /// compilation. From this index, you can acquire a `TrackedInst`, which containss a reference to both |
| 67 | 85 | /// the file which the instruction lives in, and the instruction index itself, which is updated on |
| ... | ... | @@ -9858,7 +9876,7 @@ fn extraData(extra: Local.Extra, comptime T: type, index: u32) T { |
| 9858 | 9876 | test "basic usage" { |
| 9859 | 9877 | const gpa = std.testing.allocator; |
| 9860 | 9878 | |
| 9861 | | var ip: InternPool = .{}; |
| 9879 | var ip: InternPool = .empty; |
| 9862 | 9880 | defer ip.deinit(gpa); |
| 9863 | 9881 | |
| 9864 | 9882 | const i32_type = try ip.get(gpa, .main, .{ .int_type = .{ |