authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2024-07-08 16:00:28-04:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2024-07-08 16:00:28-04:00
logab4eeb770a0af411d525616dcdbfa4a8491f8ac0
treed19b6b0cdb71a7e0f6bc65379441992753979a4a
parent8f20e81b8816aadd8ceb1b04bd3727cc1d124464
parent65ced4a33436fa762de75e22a986ae08a8c0d9cc
signature Signed by PGP key B5690EEEBB952194

Merge pull request #20528 from jacobly0/tsip

InternPool: begin conversion to thread-safe data structure

61 files changed, 15011 insertions(+), 12550 deletions(-)

CMakeLists.txt+1
...@@ -525,6 +525,7 @@ set(ZIG_STAGE2_SOURCES...@@ -525,6 +525,7 @@ set(ZIG_STAGE2_SOURCES
525 src/Type.zig525 src/Type.zig
526 src/Value.zig526 src/Value.zig
527 src/Zcu.zig527 src/Zcu.zig
528 src/Zcu/PerThread.zig
528 src/arch/aarch64/CodeGen.zig529 src/arch/aarch64/CodeGen.zig
529 src/arch/aarch64/Emit.zig530 src/arch/aarch64/Emit.zig
530 src/arch/aarch64/Mir.zig531 src/arch/aarch64/Mir.zig
lib/std/Progress.zig+1-1
...@@ -282,7 +282,7 @@ pub const Node = struct {...@@ -282,7 +282,7 @@ pub const Node = struct {
282 }282 }
283283
284 fn init(free_index: Index, parent: Parent, name: []const u8, estimated_total_items: usize) Node {284 fn init(free_index: Index, parent: Parent, name: []const u8, estimated_total_items: usize) Node {
285 assert(parent != .unused);285 assert(parent == .none or @intFromEnum(parent) < node_storage_buffer_len);
286286
287 const storage = storageByIndex(free_index);287 const storage = storageByIndex(free_index);
288 storage.* = .{288 storage.* = .{
lib/std/Thread.zig+6-1
...@@ -280,12 +280,13 @@ pub fn getCurrentId() Id {...@@ -280,12 +280,13 @@ pub fn getCurrentId() Id {
280pub const CpuCountError = error{280pub const CpuCountError = error{
281 PermissionDenied,281 PermissionDenied,
282 SystemResources,282 SystemResources,
283 Unsupported,
283 Unexpected,284 Unexpected,
284};285};
285286
286/// Returns the platforms view on the number of logical CPU cores available.287/// Returns the platforms view on the number of logical CPU cores available.
287pub fn getCpuCount() CpuCountError!usize {288pub fn getCpuCount() CpuCountError!usize {
288 return Impl.getCpuCount();289 return try Impl.getCpuCount();
289}290}
290291
291/// Configuration options for hints on how to spawn threads.292/// Configuration options for hints on how to spawn threads.
...@@ -782,6 +783,10 @@ const WasiThreadImpl = struct {...@@ -782,6 +783,10 @@ const WasiThreadImpl = struct {
782 return tls_thread_id;783 return tls_thread_id;
783 }784 }
784785
786 fn getCpuCount() error{Unsupported}!noreturn {
787 return error.Unsupported;
788 }
789
785 fn getHandle(self: Impl) ThreadHandle {790 fn getHandle(self: Impl) ThreadHandle {
786 return self.thread.tid.load(.seq_cst);791 return self.thread.tid.load(.seq_cst);
787 }792 }
lib/std/Thread/Pool.zig+98-13
...@@ -8,18 +8,25 @@ cond: std.Thread.Condition = .{},...@@ -8,18 +8,25 @@ cond: std.Thread.Condition = .{},
8run_queue: RunQueue = .{},8run_queue: RunQueue = .{},
9is_running: bool = true,9is_running: bool = true,
10allocator: std.mem.Allocator,10allocator: std.mem.Allocator,
11threads: []std.Thread,11threads: if (builtin.single_threaded) [0]std.Thread else []std.Thread,
12ids: if (builtin.single_threaded) struct {
13 inline fn deinit(_: @This(), _: std.mem.Allocator) void {}
14 fn getIndex(_: @This(), _: std.Thread.Id) usize {
15 return 0;
16 }
17} else std.AutoArrayHashMapUnmanaged(std.Thread.Id, void),
1218
13const RunQueue = std.SinglyLinkedList(Runnable);19const RunQueue = std.SinglyLinkedList(Runnable);
14const Runnable = struct {20const Runnable = struct {
15 runFn: RunProto,21 runFn: RunProto,
16};22};
1723
18const RunProto = *const fn (*Runnable) void;24const RunProto = *const fn (*Runnable, id: ?usize) void;
1925
20pub const Options = struct {26pub const Options = struct {
21 allocator: std.mem.Allocator,27 allocator: std.mem.Allocator,
22 n_jobs: ?u32 = null,28 n_jobs: ?usize = null,
29 track_ids: bool = false,
23};30};
2431
25pub fn init(pool: *Pool, options: Options) !void {32pub fn init(pool: *Pool, options: Options) !void {
...@@ -27,7 +34,8 @@ pub fn init(pool: *Pool, options: Options) !void {...@@ -27,7 +34,8 @@ pub fn init(pool: *Pool, options: Options) !void {
2734
28 pool.* = .{35 pool.* = .{
29 .allocator = allocator,36 .allocator = allocator,
30 .threads = &[_]std.Thread{},37 .threads = if (builtin.single_threaded) .{} else &.{},
38 .ids = .{},
31 };39 };
3240
33 if (builtin.single_threaded) {41 if (builtin.single_threaded) {
...@@ -35,6 +43,10 @@ pub fn init(pool: *Pool, options: Options) !void {...@@ -35,6 +43,10 @@ pub fn init(pool: *Pool, options: Options) !void {
35 }43 }
3644
37 const thread_count = options.n_jobs orelse @max(1, std.Thread.getCpuCount() catch 1);45 const thread_count = options.n_jobs orelse @max(1, std.Thread.getCpuCount() catch 1);
46 if (options.track_ids) {
47 try pool.ids.ensureTotalCapacity(allocator, 1 + thread_count);
48 pool.ids.putAssumeCapacityNoClobber(std.Thread.getCurrentId(), {});
49 }
3850
39 // kill and join any threads we spawned and free memory on error.51 // kill and join any threads we spawned and free memory on error.
40 pool.threads = try allocator.alloc(std.Thread, thread_count);52 pool.threads = try allocator.alloc(std.Thread, thread_count);
...@@ -49,6 +61,7 @@ pub fn init(pool: *Pool, options: Options) !void {...@@ -49,6 +61,7 @@ pub fn init(pool: *Pool, options: Options) !void {
4961
50pub fn deinit(pool: *Pool) void {62pub fn deinit(pool: *Pool) void {
51 pool.join(pool.threads.len); // kill and join all threads.63 pool.join(pool.threads.len); // kill and join all threads.
64 pool.ids.deinit(pool.allocator);
52 pool.* = undefined;65 pool.* = undefined;
53}66}
5467
...@@ -96,7 +109,7 @@ pub fn spawnWg(pool: *Pool, wait_group: *WaitGroup, comptime func: anytype, args...@@ -96,7 +109,7 @@ pub fn spawnWg(pool: *Pool, wait_group: *WaitGroup, comptime func: anytype, args
96 run_node: RunQueue.Node = .{ .data = .{ .runFn = runFn } },109 run_node: RunQueue.Node = .{ .data = .{ .runFn = runFn } },
97 wait_group: *WaitGroup,110 wait_group: *WaitGroup,
98111
99 fn runFn(runnable: *Runnable) void {112 fn runFn(runnable: *Runnable, _: ?usize) void {
100 const run_node: *RunQueue.Node = @fieldParentPtr("data", runnable);113 const run_node: *RunQueue.Node = @fieldParentPtr("data", runnable);
101 const closure: *@This() = @alignCast(@fieldParentPtr("run_node", run_node));114 const closure: *@This() = @alignCast(@fieldParentPtr("run_node", run_node));
102 @call(.auto, func, closure.arguments);115 @call(.auto, func, closure.arguments);
...@@ -134,6 +147,70 @@ pub fn spawnWg(pool: *Pool, wait_group: *WaitGroup, comptime func: anytype, args...@@ -134,6 +147,70 @@ pub fn spawnWg(pool: *Pool, wait_group: *WaitGroup, comptime func: anytype, args
134 pool.cond.signal();147 pool.cond.signal();
135}148}
136149
150/// Runs `func` in the thread pool, calling `WaitGroup.start` beforehand, and
151/// `WaitGroup.finish` after it returns.
152///
153/// The first argument passed to `func` is a dense `usize` thread id, the rest
154/// of the arguments are passed from `args`. Requires the pool to have been
155/// initialized with `.track_ids = true`.
156///
157/// In the case that queuing the function call fails to allocate memory, or the
158/// target is single-threaded, the function is called directly.
159pub fn spawnWgId(pool: *Pool, wait_group: *WaitGroup, comptime func: anytype, args: anytype) void {
160 wait_group.start();
161
162 if (builtin.single_threaded) {
163 @call(.auto, func, .{0} ++ args);
164 wait_group.finish();
165 return;
166 }
167
168 const Args = @TypeOf(args);
169 const Closure = struct {
170 arguments: Args,
171 pool: *Pool,
172 run_node: RunQueue.Node = .{ .data = .{ .runFn = runFn } },
173 wait_group: *WaitGroup,
174
175 fn runFn(runnable: *Runnable, id: ?usize) void {
176 const run_node: *RunQueue.Node = @fieldParentPtr("data", runnable);
177 const closure: *@This() = @alignCast(@fieldParentPtr("run_node", run_node));
178 @call(.auto, func, .{id.?} ++ closure.arguments);
179 closure.wait_group.finish();
180
181 // The thread pool's allocator is protected by the mutex.
182 const mutex = &closure.pool.mutex;
183 mutex.lock();
184 defer mutex.unlock();
185
186 closure.pool.allocator.destroy(closure);
187 }
188 };
189
190 {
191 pool.mutex.lock();
192
193 const closure = pool.allocator.create(Closure) catch {
194 const id: ?usize = pool.ids.getIndex(std.Thread.getCurrentId());
195 pool.mutex.unlock();
196 @call(.auto, func, .{id.?} ++ args);
197 wait_group.finish();
198 return;
199 };
200 closure.* = .{
201 .arguments = args,
202 .pool = pool,
203 .wait_group = wait_group,
204 };
205
206 pool.run_queue.prepend(&closure.run_node);
207 pool.mutex.unlock();
208 }
209
210 // Notify waiting threads outside the lock to try and keep the critical section small.
211 pool.cond.signal();
212}
213
137pub fn spawn(pool: *Pool, comptime func: anytype, args: anytype) !void {214pub fn spawn(pool: *Pool, comptime func: anytype, args: anytype) !void {
138 if (builtin.single_threaded) {215 if (builtin.single_threaded) {
139 @call(.auto, func, args);216 @call(.auto, func, args);
...@@ -181,14 +258,16 @@ fn worker(pool: *Pool) void {...@@ -181,14 +258,16 @@ fn worker(pool: *Pool) void {
181 pool.mutex.lock();258 pool.mutex.lock();
182 defer pool.mutex.unlock();259 defer pool.mutex.unlock();
183260
261 const id: ?usize = if (pool.ids.count() > 0) @intCast(pool.ids.count()) else null;
262 if (id) |_| pool.ids.putAssumeCapacityNoClobber(std.Thread.getCurrentId(), {});
263
184 while (true) {264 while (true) {
185 while (pool.run_queue.popFirst()) |run_node| {265 while (pool.run_queue.popFirst()) |run_node| {
186 // Temporarily unlock the mutex in order to execute the run_node266 // Temporarily unlock the mutex in order to execute the run_node
187 pool.mutex.unlock();267 pool.mutex.unlock();
188 defer pool.mutex.lock();268 defer pool.mutex.lock();
189269
190 const runFn = run_node.data.runFn;270 run_node.data.runFn(&run_node.data, id);
191 runFn(&run_node.data);
192 }271 }
193272
194 // Stop executing instead of waiting if the thread pool is no longer running.273 // Stop executing instead of waiting if the thread pool is no longer running.
...@@ -201,17 +280,23 @@ fn worker(pool: *Pool) void {...@@ -201,17 +280,23 @@ fn worker(pool: *Pool) void {
201}280}
202281
203pub fn waitAndWork(pool: *Pool, wait_group: *WaitGroup) void {282pub fn waitAndWork(pool: *Pool, wait_group: *WaitGroup) void {
283 var id: ?usize = null;
284
204 while (!wait_group.isDone()) {285 while (!wait_group.isDone()) {
205 if (blk: {286 pool.mutex.lock();
206 pool.mutex.lock();287 if (pool.run_queue.popFirst()) |run_node| {
207 defer pool.mutex.unlock();288 id = id orelse pool.ids.getIndex(std.Thread.getCurrentId());
208 break :blk pool.run_queue.popFirst();289 pool.mutex.unlock();
209 }) |run_node| {290 run_node.data.runFn(&run_node.data, id);
210 run_node.data.runFn(&run_node.data);
211 continue;291 continue;
212 }292 }
213293
294 pool.mutex.unlock();
214 wait_group.wait();295 wait_group.wait();
215 return;296 return;
216 }297 }
217}298}
299
300pub fn getIdCount(pool: *Pool) usize {
301 return @intCast(1 + pool.threads.len);
302}
lib/std/multi_array_list.zig+1-1
...@@ -534,7 +534,7 @@ pub fn MultiArrayList(comptime T: type) type {...@@ -534,7 +534,7 @@ pub fn MultiArrayList(comptime T: type) type {
534 self.sortInternal(a, b, ctx, .unstable);534 self.sortInternal(a, b, ctx, .unstable);
535 }535 }
536536
537 fn capacityInBytes(capacity: usize) usize {537 pub fn capacityInBytes(capacity: usize) usize {
538 comptime var elem_bytes: usize = 0;538 comptime var elem_bytes: usize = 0;
539 inline for (sizes.bytes) |size| elem_bytes += size;539 inline for (sizes.bytes) |size| elem_bytes += size;
540 return elem_bytes * capacity;540 return elem_bytes * capacity;
src/Air.zig+2-2
...@@ -1563,12 +1563,12 @@ pub fn internedToRef(ip_index: InternPool.Index) Inst.Ref {...@@ -1563,12 +1563,12 @@ pub fn internedToRef(ip_index: InternPool.Index) Inst.Ref {
1563}1563}
15641564
1565/// Returns `null` if runtime-known.1565/// Returns `null` if runtime-known.
1566pub fn value(air: Air, inst: Inst.Ref, mod: *Module) !?Value {1566pub fn value(air: Air, inst: Inst.Ref, pt: Zcu.PerThread) !?Value {
1567 if (inst.toInterned()) |ip_index| {1567 if (inst.toInterned()) |ip_index| {
1568 return Value.fromInterned(ip_index);1568 return Value.fromInterned(ip_index);
1569 }1569 }
1570 const index = inst.toIndex().?;1570 const index = inst.toIndex().?;
1571 return air.typeOfIndex(index, &mod.intern_pool).onePossibleValue(mod);1571 return air.typeOfIndex(index, &pt.zcu.intern_pool).onePossibleValue(pt);
1572}1572}
15731573
1574pub fn nullTerminatedString(air: Air, index: usize) [:0]const u8 {1574pub fn nullTerminatedString(air: Air, index: usize) [:0]const u8 {
src/Compilation.zig+198-104
...@@ -29,8 +29,6 @@ const wasi_libc = @import("wasi_libc.zig");...@@ -29,8 +29,6 @@ const wasi_libc = @import("wasi_libc.zig");
29const fatal = @import("main.zig").fatal;29const fatal = @import("main.zig").fatal;
30const clangMain = @import("main.zig").clangMain;30const clangMain = @import("main.zig").clangMain;
31const Zcu = @import("Zcu.zig");31const Zcu = @import("Zcu.zig");
32/// Deprecated; use `Zcu`.
33const Module = Zcu;
34const Sema = @import("Sema.zig");32const Sema = @import("Sema.zig");
35const InternPool = @import("InternPool.zig");33const InternPool = @import("InternPool.zig");
36const Cache = std.Build.Cache;34const Cache = std.Build.Cache;
...@@ -50,7 +48,7 @@ gpa: Allocator,...@@ -50,7 +48,7 @@ gpa: Allocator,
50arena: Allocator,48arena: Allocator,
51/// Not every Compilation compiles .zig code! For example you could do `zig build-exe foo.o`.49/// Not every Compilation compiles .zig code! For example you could do `zig build-exe foo.o`.
52/// TODO: rename to zcu: ?*Zcu50/// TODO: rename to zcu: ?*Zcu
53module: ?*Module,51module: ?*Zcu,
54/// Contains different state depending on whether the Compilation uses52/// Contains different state depending on whether the Compilation uses
55/// incremental or whole cache mode.53/// incremental or whole cache mode.
56cache_use: CacheUse,54cache_use: CacheUse,
...@@ -105,6 +103,14 @@ lld_errors: std.ArrayListUnmanaged(LldError) = .{},...@@ -105,6 +103,14 @@ lld_errors: std.ArrayListUnmanaged(LldError) = .{},
105103
106work_queue: std.fifo.LinearFifo(Job, .Dynamic),104work_queue: std.fifo.LinearFifo(Job, .Dynamic),
107105
106codegen_work: if (InternPool.single_threaded) void else struct {
107 mutex: std.Thread.Mutex,
108 cond: std.Thread.Condition,
109 queue: std.fifo.LinearFifo(CodegenJob, .Dynamic),
110 job_error: ?JobError,
111 done: bool,
112},
113
108/// These jobs are to invoke the Clang compiler to create an object file, which114/// These jobs are to invoke the Clang compiler to create an object file, which
109/// gets linked with the Compilation.115/// gets linked with the Compilation.
110c_object_work_queue: std.fifo.LinearFifo(*CObject, .Dynamic),116c_object_work_queue: std.fifo.LinearFifo(*CObject, .Dynamic),
...@@ -120,7 +126,7 @@ astgen_work_queue: std.fifo.LinearFifo(Zcu.File.Index, .Dynamic),...@@ -120,7 +126,7 @@ astgen_work_queue: std.fifo.LinearFifo(Zcu.File.Index, .Dynamic),
120/// These jobs are to inspect the file system stat() and if the embedded file has changed126/// These jobs are to inspect the file system stat() and if the embedded file has changed
121/// on disk, mark the corresponding Decl outdated and queue up an `analyze_decl`127/// on disk, mark the corresponding Decl outdated and queue up an `analyze_decl`
122/// task for it.128/// task for it.
123embed_file_work_queue: std.fifo.LinearFifo(*Module.EmbedFile, .Dynamic),129embed_file_work_queue: std.fifo.LinearFifo(*Zcu.EmbedFile, .Dynamic),
124130
125/// The ErrorMsg memory is owned by the `CObject`, using Compilation's general purpose allocator.131/// The ErrorMsg memory is owned by the `CObject`, using Compilation's general purpose allocator.
126/// This data is accessed by multiple threads and is protected by `mutex`.132/// This data is accessed by multiple threads and is protected by `mutex`.
...@@ -252,7 +258,7 @@ pub const Emit = struct {...@@ -252,7 +258,7 @@ pub const Emit = struct {
252};258};
253259
254pub const default_stack_protector_buffer_size = target_util.default_stack_protector_buffer_size;260pub const default_stack_protector_buffer_size = target_util.default_stack_protector_buffer_size;
255pub const SemaError = Module.SemaError;261pub const SemaError = Zcu.SemaError;
256262
257pub const CRTFile = struct {263pub const CRTFile = struct {
258 lock: Cache.Lock,264 lock: Cache.Lock,
...@@ -364,6 +370,16 @@ const Job = union(enum) {...@@ -364,6 +370,16 @@ const Job = union(enum) {
364 windows_import_lib: usize,370 windows_import_lib: usize,
365};371};
366372
373const CodegenJob = union(enum) {
374 decl: InternPool.DeclIndex,
375 func: struct {
376 func: InternPool.Index,
377 /// This `Air` is owned by the `Job` and allocated with `gpa`.
378 /// It must be deinited when the job is processed.
379 air: Air,
380 },
381};
382
367pub const CObject = struct {383pub const CObject = struct {
368 /// Relative to cwd. Owned by arena.384 /// Relative to cwd. Owned by arena.
369 src: CSourceFile,385 src: CSourceFile,
...@@ -1138,7 +1154,7 @@ pub const CreateOptions = struct {...@@ -1138,7 +1154,7 @@ pub const CreateOptions = struct {
1138 pdb_source_path: ?[]const u8 = null,1154 pdb_source_path: ?[]const u8 = null,
1139 /// (Windows) PDB output path1155 /// (Windows) PDB output path
1140 pdb_out_path: ?[]const u8 = null,1156 pdb_out_path: ?[]const u8 = null,
1141 error_limit: ?Compilation.Module.ErrorInt = null,1157 error_limit: ?Zcu.ErrorInt = null,
1142 global_cc_argv: []const []const u8 = &.{},1158 global_cc_argv: []const []const u8 = &.{},
11431159
1144 pub const Entry = link.File.OpenOptions.Entry;1160 pub const Entry = link.File.OpenOptions.Entry;
...@@ -1344,7 +1360,7 @@ pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compil...@@ -1344,7 +1360,7 @@ pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compil
13441360
1345 const main_mod = options.main_mod orelse options.root_mod;1361 const main_mod = options.main_mod orelse options.root_mod;
1346 const comp = try arena.create(Compilation);1362 const comp = try arena.create(Compilation);
1347 const opt_zcu: ?*Module = if (have_zcu) blk: {1363 const opt_zcu: ?*Zcu = if (have_zcu) blk: {
1348 // Pre-open the directory handles for cached ZIR code so that it does not need1364 // Pre-open the directory handles for cached ZIR code so that it does not need
1349 // to redundantly happen for each AstGen operation.1365 // to redundantly happen for each AstGen operation.
1350 const zir_sub_dir = "z";1366 const zir_sub_dir = "z";
...@@ -1362,8 +1378,8 @@ pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compil...@@ -1362,8 +1378,8 @@ pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compil
1362 .path = try options.global_cache_directory.join(arena, &[_][]const u8{zir_sub_dir}),1378 .path = try options.global_cache_directory.join(arena, &[_][]const u8{zir_sub_dir}),
1363 };1379 };
13641380
1365 const emit_h: ?*Module.GlobalEmitH = if (options.emit_h) |loc| eh: {1381 const emit_h: ?*Zcu.GlobalEmitH = if (options.emit_h) |loc| eh: {
1366 const eh = try arena.create(Module.GlobalEmitH);1382 const eh = try arena.create(Zcu.GlobalEmitH);
1367 eh.* = .{ .loc = loc };1383 eh.* = .{ .loc = loc };
1368 break :eh eh;1384 break :eh eh;
1369 } else null;1385 } else null;
...@@ -1386,7 +1402,7 @@ pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compil...@@ -1386,7 +1402,7 @@ pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compil
1386 .builtin_modules = null, // `builtin_mod` is set1402 .builtin_modules = null, // `builtin_mod` is set
1387 });1403 });
13881404
1389 const zcu = try arena.create(Module);1405 const zcu = try arena.create(Zcu);
1390 zcu.* = .{1406 zcu.* = .{
1391 .gpa = gpa,1407 .gpa = gpa,
1392 .comp = comp,1408 .comp = comp,
...@@ -1399,7 +1415,7 @@ pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compil...@@ -1399,7 +1415,7 @@ pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compil
1399 .error_limit = error_limit,1415 .error_limit = error_limit,
1400 .llvm_object = null,1416 .llvm_object = null,
1401 };1417 };
1402 try zcu.init();1418 try zcu.init(options.thread_pool.getIdCount());
1403 break :blk zcu;1419 break :blk zcu;
1404 } else blk: {1420 } else blk: {
1405 if (options.emit_h != null) return error.NoZigModuleForCHeader;1421 if (options.emit_h != null) return error.NoZigModuleForCHeader;
...@@ -1431,10 +1447,17 @@ pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compil...@@ -1431,10 +1447,17 @@ pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compil
1431 .emit_llvm_ir = options.emit_llvm_ir,1447 .emit_llvm_ir = options.emit_llvm_ir,
1432 .emit_llvm_bc = options.emit_llvm_bc,1448 .emit_llvm_bc = options.emit_llvm_bc,
1433 .work_queue = std.fifo.LinearFifo(Job, .Dynamic).init(gpa),1449 .work_queue = std.fifo.LinearFifo(Job, .Dynamic).init(gpa),
1450 .codegen_work = if (InternPool.single_threaded) {} else .{
1451 .mutex = .{},
1452 .cond = .{},
1453 .queue = std.fifo.LinearFifo(CodegenJob, .Dynamic).init(gpa),
1454 .job_error = null,
1455 .done = false,
1456 },
1434 .c_object_work_queue = std.fifo.LinearFifo(*CObject, .Dynamic).init(gpa),1457 .c_object_work_queue = std.fifo.LinearFifo(*CObject, .Dynamic).init(gpa),
1435 .win32_resource_work_queue = if (build_options.only_core_functionality) {} else std.fifo.LinearFifo(*Win32Resource, .Dynamic).init(gpa),1458 .win32_resource_work_queue = if (build_options.only_core_functionality) {} else std.fifo.LinearFifo(*Win32Resource, .Dynamic).init(gpa),
1436 .astgen_work_queue = std.fifo.LinearFifo(Zcu.File.Index, .Dynamic).init(gpa),1459 .astgen_work_queue = std.fifo.LinearFifo(Zcu.File.Index, .Dynamic).init(gpa),
1437 .embed_file_work_queue = std.fifo.LinearFifo(*Module.EmbedFile, .Dynamic).init(gpa),1460 .embed_file_work_queue = std.fifo.LinearFifo(*Zcu.EmbedFile, .Dynamic).init(gpa),
1438 .c_source_files = options.c_source_files,1461 .c_source_files = options.c_source_files,
1439 .rc_source_files = options.rc_source_files,1462 .rc_source_files = options.rc_source_files,
1440 .cache_parent = cache,1463 .cache_parent = cache,
...@@ -2146,6 +2169,8 @@ pub fn update(comp: *Compilation, main_progress_node: std.Progress.Node) !void {...@@ -2146,6 +2169,8 @@ pub fn update(comp: *Compilation, main_progress_node: std.Progress.Node) !void {
2146 try comp.performAllTheWork(main_progress_node);2169 try comp.performAllTheWork(main_progress_node);
21472170
2148 if (comp.module) |zcu| {2171 if (comp.module) |zcu| {
2172 const pt: Zcu.PerThread = .{ .zcu = zcu, .tid = .main };
2173
2149 if (build_options.enable_debug_extensions and comp.verbose_intern_pool) {2174 if (build_options.enable_debug_extensions and comp.verbose_intern_pool) {
2150 std.debug.print("intern pool stats for '{s}':\n", .{2175 std.debug.print("intern pool stats for '{s}':\n", .{
2151 comp.root_name,2176 comp.root_name,
...@@ -2156,7 +2181,7 @@ pub fn update(comp: *Compilation, main_progress_node: std.Progress.Node) !void {...@@ -2156,7 +2181,7 @@ pub fn update(comp: *Compilation, main_progress_node: std.Progress.Node) !void {
2156 if (build_options.enable_debug_extensions and comp.verbose_generic_instances) {2181 if (build_options.enable_debug_extensions and comp.verbose_generic_instances) {
2157 std.debug.print("generic instances for '{s}:0x{x}':\n", .{2182 std.debug.print("generic instances for '{s}:0x{x}':\n", .{
2158 comp.root_name,2183 comp.root_name,
2159 @as(usize, @intFromPtr(zcu)),2184 @intFromPtr(zcu),
2160 });2185 });
2161 zcu.intern_pool.dumpGenericInstances(gpa);2186 zcu.intern_pool.dumpGenericInstances(gpa);
2162 }2187 }
...@@ -2165,10 +2190,10 @@ pub fn update(comp: *Compilation, main_progress_node: std.Progress.Node) !void {...@@ -2165,10 +2190,10 @@ pub fn update(comp: *Compilation, main_progress_node: std.Progress.Node) !void {
2165 // The `test_functions` decl has been intentionally postponed until now,2190 // The `test_functions` decl has been intentionally postponed until now,
2166 // at which point we must populate it with the list of test functions that2191 // at which point we must populate it with the list of test functions that
2167 // have been discovered and not filtered out.2192 // have been discovered and not filtered out.
2168 try zcu.populateTestFunctions(main_progress_node);2193 try pt.populateTestFunctions(main_progress_node);
2169 }2194 }
21702195
2171 try zcu.processExports();2196 try pt.processExports();
2172 }2197 }
21732198
2174 if (comp.totalErrorCount() != 0) {2199 if (comp.totalErrorCount() != 0) {
...@@ -2247,7 +2272,7 @@ pub fn update(comp: *Compilation, main_progress_node: std.Progress.Node) !void {...@@ -2247,7 +2272,7 @@ pub fn update(comp: *Compilation, main_progress_node: std.Progress.Node) !void {
2247 }2272 }
2248 }2273 }
22492274
2250 try flush(comp, arena, main_progress_node);2275 try flush(comp, arena, .main, main_progress_node);
2251 if (comp.totalErrorCount() != 0) return;2276 if (comp.totalErrorCount() != 0) return;
22522277
2253 // Failure here only means an unnecessary cache miss.2278 // Failure here only means an unnecessary cache miss.
...@@ -2264,16 +2289,16 @@ pub fn update(comp: *Compilation, main_progress_node: std.Progress.Node) !void {...@@ -2264,16 +2289,16 @@ pub fn update(comp: *Compilation, main_progress_node: std.Progress.Node) !void {
2264 whole.lock = man.toOwnedLock();2289 whole.lock = man.toOwnedLock();
2265 },2290 },
2266 .incremental => {2291 .incremental => {
2267 try flush(comp, arena, main_progress_node);2292 try flush(comp, arena, .main, main_progress_node);
2268 if (comp.totalErrorCount() != 0) return;2293 if (comp.totalErrorCount() != 0) return;
2269 },2294 },
2270 }2295 }
2271}2296}
22722297
2273fn flush(comp: *Compilation, arena: Allocator, prog_node: std.Progress.Node) !void {2298fn flush(comp: *Compilation, arena: Allocator, tid: Zcu.PerThread.Id, prog_node: std.Progress.Node) !void {
2274 if (comp.bin_file) |lf| {2299 if (comp.bin_file) |lf| {
2275 // This is needed before reading the error flags.2300 // This is needed before reading the error flags.
2276 lf.flush(arena, prog_node) catch |err| switch (err) {2301 lf.flush(arena, tid, prog_node) catch |err| switch (err) {
2277 error.FlushFailure => {}, // error reported through link_error_flags2302 error.FlushFailure => {}, // error reported through link_error_flags
2278 error.LLDReportedFailure => {}, // error reported via lockAndParseLldStderr2303 error.LLDReportedFailure => {}, // error reported via lockAndParseLldStderr
2279 else => |e| return e,2304 else => |e| return e,
...@@ -2624,7 +2649,7 @@ fn reportMultiModuleErrors(zcu: *Zcu) !void {...@@ -2624,7 +2649,7 @@ fn reportMultiModuleErrors(zcu: *Zcu) !void {
2624 var num_errors: u32 = 0;2649 var num_errors: u32 = 0;
2625 const max_errors = 5;2650 const max_errors = 5;
2626 // Attach the "some omitted" note to the final error message2651 // Attach the "some omitted" note to the final error message
2627 var last_err: ?*Module.ErrorMsg = null;2652 var last_err: ?*Zcu.ErrorMsg = null;
26282653
2629 for (zcu.import_table.values(), 0..) |file, file_index_usize| {2654 for (zcu.import_table.values(), 0..) |file, file_index_usize| {
2630 if (!file.multi_pkg) continue;2655 if (!file.multi_pkg) continue;
...@@ -2640,13 +2665,13 @@ fn reportMultiModuleErrors(zcu: *Zcu) !void {...@@ -2640,13 +2665,13 @@ fn reportMultiModuleErrors(zcu: *Zcu) !void {
2640 const omitted = file.references.items.len -| max_notes;2665 const omitted = file.references.items.len -| max_notes;
2641 const num_notes = file.references.items.len - omitted;2666 const num_notes = file.references.items.len - omitted;
26422667
2643 const notes = try gpa.alloc(Module.ErrorMsg, if (omitted > 0) num_notes + 1 else num_notes);2668 const notes = try gpa.alloc(Zcu.ErrorMsg, if (omitted > 0) num_notes + 1 else num_notes);
2644 errdefer gpa.free(notes);2669 errdefer gpa.free(notes);
26452670
2646 for (notes[0..num_notes], file.references.items[0..num_notes], 0..) |*note, ref, i| {2671 for (notes[0..num_notes], file.references.items[0..num_notes], 0..) |*note, ref, i| {
2647 errdefer for (notes[0..i]) |*n| n.deinit(gpa);2672 errdefer for (notes[0..i]) |*n| n.deinit(gpa);
2648 note.* = switch (ref) {2673 note.* = switch (ref) {
2649 .import => |import| try Module.ErrorMsg.init(2674 .import => |import| try Zcu.ErrorMsg.init(
2650 gpa,2675 gpa,
2651 .{2676 .{
2652 .base_node_inst = try ip.trackZir(gpa, import.file, .main_struct_inst),2677 .base_node_inst = try ip.trackZir(gpa, import.file, .main_struct_inst),
...@@ -2655,7 +2680,7 @@ fn reportMultiModuleErrors(zcu: *Zcu) !void {...@@ -2655,7 +2680,7 @@ fn reportMultiModuleErrors(zcu: *Zcu) !void {
2655 "imported from module {s}",2680 "imported from module {s}",
2656 .{zcu.fileByIndex(import.file).mod.fully_qualified_name},2681 .{zcu.fileByIndex(import.file).mod.fully_qualified_name},
2657 ),2682 ),
2658 .root => |pkg| try Module.ErrorMsg.init(2683 .root => |pkg| try Zcu.ErrorMsg.init(
2659 gpa,2684 gpa,
2660 .{2685 .{
2661 .base_node_inst = try ip.trackZir(gpa, file_index, .main_struct_inst),2686 .base_node_inst = try ip.trackZir(gpa, file_index, .main_struct_inst),
...@@ -2669,7 +2694,7 @@ fn reportMultiModuleErrors(zcu: *Zcu) !void {...@@ -2669,7 +2694,7 @@ fn reportMultiModuleErrors(zcu: *Zcu) !void {
2669 errdefer for (notes[0..num_notes]) |*n| n.deinit(gpa);2694 errdefer for (notes[0..num_notes]) |*n| n.deinit(gpa);
26702695
2671 if (omitted > 0) {2696 if (omitted > 0) {
2672 notes[num_notes] = try Module.ErrorMsg.init(2697 notes[num_notes] = try Zcu.ErrorMsg.init(
2673 gpa,2698 gpa,
2674 .{2699 .{
2675 .base_node_inst = try ip.trackZir(gpa, file_index, .main_struct_inst),2700 .base_node_inst = try ip.trackZir(gpa, file_index, .main_struct_inst),
...@@ -2681,7 +2706,7 @@ fn reportMultiModuleErrors(zcu: *Zcu) !void {...@@ -2681,7 +2706,7 @@ fn reportMultiModuleErrors(zcu: *Zcu) !void {
2681 }2706 }
2682 errdefer if (omitted > 0) notes[num_notes].deinit(gpa);2707 errdefer if (omitted > 0) notes[num_notes].deinit(gpa);
26832708
2684 const err = try Module.ErrorMsg.create(2709 const err = try Zcu.ErrorMsg.create(
2685 gpa,2710 gpa,
2686 .{2711 .{
2687 .base_node_inst = try ip.trackZir(gpa, file_index, .main_struct_inst),2712 .base_node_inst = try ip.trackZir(gpa, file_index, .main_struct_inst),
...@@ -2704,7 +2729,7 @@ fn reportMultiModuleErrors(zcu: *Zcu) !void {...@@ -2704,7 +2729,7 @@ fn reportMultiModuleErrors(zcu: *Zcu) !void {
27042729
2705 // There isn't really any meaningful place to put this note, so just attach it to the2730 // There isn't really any meaningful place to put this note, so just attach it to the
2706 // last failed file2731 // last failed file
2707 var note = try Module.ErrorMsg.init(2732 var note = try Zcu.ErrorMsg.init(
2708 gpa,2733 gpa,
2709 err.src_loc,2734 err.src_loc,
2710 "{} more errors omitted",2735 "{} more errors omitted",
...@@ -2745,10 +2770,10 @@ pub fn makeBinFileWritable(comp: *Compilation) !void {...@@ -2745,10 +2770,10 @@ pub fn makeBinFileWritable(comp: *Compilation) !void {
27452770
2746const Header = extern struct {2771const Header = extern struct {
2747 intern_pool: extern struct {2772 intern_pool: extern struct {
2748 items_len: u32,2773 //items_len: u32,
2749 extra_len: u32,2774 //extra_len: u32,
2750 limbs_len: u32,2775 //limbs_len: u32,
2751 string_bytes_len: u32,2776 //string_bytes_len: u32,
2752 tracked_insts_len: u32,2777 tracked_insts_len: u32,
2753 src_hash_deps_len: u32,2778 src_hash_deps_len: u32,
2754 decl_val_deps_len: u32,2779 decl_val_deps_len: u32,
...@@ -2774,10 +2799,10 @@ pub fn saveState(comp: *Compilation) !void {...@@ -2774,10 +2799,10 @@ pub fn saveState(comp: *Compilation) !void {
2774 const ip = &zcu.intern_pool;2799 const ip = &zcu.intern_pool;
2775 const header: Header = .{2800 const header: Header = .{
2776 .intern_pool = .{2801 .intern_pool = .{
2777 .items_len = @intCast(ip.items.len),2802 //.items_len = @intCast(ip.items.len),
2778 .extra_len = @intCast(ip.extra.items.len),2803 //.extra_len = @intCast(ip.extra.items.len),
2779 .limbs_len = @intCast(ip.limbs.items.len),2804 //.limbs_len = @intCast(ip.limbs.items.len),
2780 .string_bytes_len = @intCast(ip.string_bytes.items.len),2805 //.string_bytes_len = @intCast(ip.string_bytes.items.len),
2781 .tracked_insts_len = @intCast(ip.tracked_insts.count()),2806 .tracked_insts_len = @intCast(ip.tracked_insts.count()),
2782 .src_hash_deps_len = @intCast(ip.src_hash_deps.count()),2807 .src_hash_deps_len = @intCast(ip.src_hash_deps.count()),
2783 .decl_val_deps_len = @intCast(ip.decl_val_deps.count()),2808 .decl_val_deps_len = @intCast(ip.decl_val_deps.count()),
...@@ -2790,11 +2815,11 @@ pub fn saveState(comp: *Compilation) !void {...@@ -2790,11 +2815,11 @@ pub fn saveState(comp: *Compilation) !void {
2790 },2815 },
2791 };2816 };
2792 addBuf(&bufs_list, &bufs_len, mem.asBytes(&header));2817 addBuf(&bufs_list, &bufs_len, mem.asBytes(&header));
2793 addBuf(&bufs_list, &bufs_len, mem.sliceAsBytes(ip.limbs.items));2818 //addBuf(&bufs_list, &bufs_len, mem.sliceAsBytes(ip.limbs.items));
2794 addBuf(&bufs_list, &bufs_len, mem.sliceAsBytes(ip.extra.items));2819 //addBuf(&bufs_list, &bufs_len, mem.sliceAsBytes(ip.extra.items));
2795 addBuf(&bufs_list, &bufs_len, mem.sliceAsBytes(ip.items.items(.data)));2820 //addBuf(&bufs_list, &bufs_len, mem.sliceAsBytes(ip.items.items(.data)));
2796 addBuf(&bufs_list, &bufs_len, mem.sliceAsBytes(ip.items.items(.tag)));2821 //addBuf(&bufs_list, &bufs_len, mem.sliceAsBytes(ip.items.items(.tag)));
2797 addBuf(&bufs_list, &bufs_len, ip.string_bytes.items);2822 //addBuf(&bufs_list, &bufs_len, ip.string_bytes.items);
2798 addBuf(&bufs_list, &bufs_len, mem.sliceAsBytes(ip.tracked_insts.keys()));2823 addBuf(&bufs_list, &bufs_len, mem.sliceAsBytes(ip.tracked_insts.keys()));
27992824
2800 addBuf(&bufs_list, &bufs_len, mem.sliceAsBytes(ip.src_hash_deps.keys()));2825 addBuf(&bufs_list, &bufs_len, mem.sliceAsBytes(ip.src_hash_deps.keys()));
...@@ -3093,10 +3118,10 @@ pub fn getAllErrorsAlloc(comp: *Compilation) !ErrorBundle {...@@ -3093,10 +3118,10 @@ pub fn getAllErrorsAlloc(comp: *Compilation) !ErrorBundle {
3093 const values = zcu.compile_log_sources.values();3118 const values = zcu.compile_log_sources.values();
3094 // First one will be the error; subsequent ones will be notes.3119 // First one will be the error; subsequent ones will be notes.
3095 const src_loc = values[0].src();3120 const src_loc = values[0].src();
3096 const err_msg: Module.ErrorMsg = .{3121 const err_msg: Zcu.ErrorMsg = .{
3097 .src_loc = src_loc,3122 .src_loc = src_loc,
3098 .msg = "found compile log statement",3123 .msg = "found compile log statement",
3099 .notes = try gpa.alloc(Module.ErrorMsg, zcu.compile_log_sources.count() - 1),3124 .notes = try gpa.alloc(Zcu.ErrorMsg, zcu.compile_log_sources.count() - 1),
3100 };3125 };
3101 defer gpa.free(err_msg.notes);3126 defer gpa.free(err_msg.notes);
31023127
...@@ -3164,9 +3189,9 @@ pub const ErrorNoteHashContext = struct {...@@ -3164,9 +3189,9 @@ pub const ErrorNoteHashContext = struct {
3164};3189};
31653190
3166pub fn addModuleErrorMsg(3191pub fn addModuleErrorMsg(
3167 mod: *Module,3192 mod: *Zcu,
3168 eb: *ErrorBundle.Wip,3193 eb: *ErrorBundle.Wip,
3169 module_err_msg: Module.ErrorMsg,3194 module_err_msg: Zcu.ErrorMsg,
3170 all_references: *const std.AutoHashMapUnmanaged(InternPool.AnalUnit, Zcu.ResolvedReference),3195 all_references: *const std.AutoHashMapUnmanaged(InternPool.AnalUnit, Zcu.ResolvedReference),
3171) !void {3196) !void {
3172 const gpa = eb.gpa;3197 const gpa = eb.gpa;
...@@ -3297,7 +3322,7 @@ pub fn addModuleErrorMsg(...@@ -3297,7 +3322,7 @@ pub fn addModuleErrorMsg(
3297 }3322 }
3298}3323}
32993324
3300pub fn addZirErrorMessages(eb: *ErrorBundle.Wip, file: *Module.File) !void {3325pub fn addZirErrorMessages(eb: *ErrorBundle.Wip, file: *Zcu.File) !void {
3301 assert(file.zir_loaded);3326 assert(file.zir_loaded);
3302 assert(file.tree_loaded);3327 assert(file.tree_loaded);
3303 assert(file.source_loaded);3328 assert(file.source_loaded);
...@@ -3310,7 +3335,21 @@ pub fn addZirErrorMessages(eb: *ErrorBundle.Wip, file: *Module.File) !void {...@@ -3310,7 +3335,21 @@ pub fn addZirErrorMessages(eb: *ErrorBundle.Wip, file: *Module.File) !void {
3310pub fn performAllTheWork(3335pub fn performAllTheWork(
3311 comp: *Compilation,3336 comp: *Compilation,
3312 main_progress_node: std.Progress.Node,3337 main_progress_node: std.Progress.Node,
3313) error{ TimerUnsupported, OutOfMemory }!void {3338) JobError!void {
3339 defer if (comp.module) |mod| {
3340 mod.sema_prog_node.end();
3341 mod.sema_prog_node = std.Progress.Node.none;
3342 mod.codegen_prog_node.end();
3343 mod.codegen_prog_node = std.Progress.Node.none;
3344 };
3345 try comp.performAllTheWorkInner(main_progress_node);
3346 if (!InternPool.single_threaded) if (comp.codegen_work.job_error) |job_error| return job_error;
3347}
3348
3349fn performAllTheWorkInner(
3350 comp: *Compilation,
3351 main_progress_node: std.Progress.Node,
3352) JobError!void {
3314 // Here we queue up all the AstGen tasks first, followed by C object compilation.3353 // Here we queue up all the AstGen tasks first, followed by C object compilation.
3315 // We wait until the AstGen tasks are all completed before proceeding to the3354 // We wait until the AstGen tasks are all completed before proceeding to the
3316 // (at least for now) single-threaded main work queue. However, C object compilation3355 // (at least for now) single-threaded main work queue. However, C object compilation
...@@ -3376,7 +3415,7 @@ pub fn performAllTheWork(...@@ -3376,7 +3415,7 @@ pub fn performAllTheWork(
3376 const path_digest = zcu.filePathDigest(file_index);3415 const path_digest = zcu.filePathDigest(file_index);
3377 const root_decl = zcu.fileRootDecl(file_index);3416 const root_decl = zcu.fileRootDecl(file_index);
3378 const file = zcu.fileByIndex(file_index);3417 const file = zcu.fileByIndex(file_index);
3379 comp.thread_pool.spawnWg(&comp.astgen_wait_group, workerAstGenFile, .{3418 comp.thread_pool.spawnWgId(&comp.astgen_wait_group, workerAstGenFile, .{
3380 comp, file, file_index, path_digest, root_decl, zir_prog_node, &comp.astgen_wait_group, .root,3419 comp, file, file_index, path_digest, root_decl, zir_prog_node, &comp.astgen_wait_group, .root,
3381 });3420 });
3382 }3421 }
...@@ -3410,16 +3449,20 @@ pub fn performAllTheWork(...@@ -3410,16 +3449,20 @@ pub fn performAllTheWork(
3410 mod.sema_prog_node = main_progress_node.start("Semantic Analysis", 0);3449 mod.sema_prog_node = main_progress_node.start("Semantic Analysis", 0);
3411 mod.codegen_prog_node = main_progress_node.start("Code Generation", 0);3450 mod.codegen_prog_node = main_progress_node.start("Code Generation", 0);
3412 }3451 }
3413 defer if (comp.module) |mod| {3452
3414 mod.sema_prog_node.end();3453 if (!InternPool.single_threaded) comp.thread_pool.spawnWgId(&comp.work_queue_wait_group, codegenThread, .{comp});
3415 mod.sema_prog_node = undefined;3454 defer if (!InternPool.single_threaded) {
3416 mod.codegen_prog_node.end();3455 {
3417 mod.codegen_prog_node = undefined;3456 comp.codegen_work.mutex.lock();
3457 defer comp.codegen_work.mutex.unlock();
3458 comp.codegen_work.done = true;
3459 }
3460 comp.codegen_work.cond.signal();
3418 };3461 };
34193462
3420 while (true) {3463 while (true) {
3421 if (comp.work_queue.readItem()) |work_item| {3464 if (comp.work_queue.readItem()) |work_item| {
3422 try processOneJob(comp, work_item, main_progress_node);3465 try processOneJob(@intFromEnum(Zcu.PerThread.Id.main), comp, work_item, main_progress_node);
3423 continue;3466 continue;
3424 }3467 }
3425 if (comp.module) |zcu| {3468 if (comp.module) |zcu| {
...@@ -3447,11 +3490,12 @@ pub fn performAllTheWork(...@@ -3447,11 +3490,12 @@ pub fn performAllTheWork(
3447 }3490 }
3448}3491}
34493492
3450fn processOneJob(comp: *Compilation, job: Job, prog_node: std.Progress.Node) !void {3493const JobError = Allocator.Error;
3494
3495fn processOneJob(tid: usize, comp: *Compilation, job: Job, prog_node: std.Progress.Node) JobError!void {
3451 switch (job) {3496 switch (job) {
3452 .codegen_decl => |decl_index| {3497 .codegen_decl => |decl_index| {
3453 const zcu = comp.module.?;3498 const decl = comp.module.?.declPtr(decl_index);
3454 const decl = zcu.declPtr(decl_index);
34553499
3456 switch (decl.analysis) {3500 switch (decl.analysis) {
3457 .unreferenced => unreachable,3501 .unreferenced => unreachable,
...@@ -3461,33 +3505,27 @@ fn processOneJob(comp: *Compilation, job: Job, prog_node: std.Progress.Node) !vo...@@ -3461,33 +3505,27 @@ fn processOneJob(comp: *Compilation, job: Job, prog_node: std.Progress.Node) !vo
3461 .sema_failure,3505 .sema_failure,
3462 .codegen_failure,3506 .codegen_failure,
3463 .dependency_failure,3507 .dependency_failure,
3464 => return,3508 => {},
34653509
3466 .complete => {3510 .complete => {
3467 const named_frame = tracy.namedFrame("codegen_decl");
3468 defer named_frame.end();
3469
3470 assert(decl.has_tv);3511 assert(decl.has_tv);
34713512 try comp.queueCodegenJob(tid, .{ .decl = decl_index });
3472 try zcu.linkerUpdateDecl(decl_index);
3473 return;
3474 },3513 },
3475 }3514 }
3476 },3515 },
3477 .codegen_func => |func| {3516 .codegen_func => |func| {
3478 const named_frame = tracy.namedFrame("codegen_func");
3479 defer named_frame.end();
3480
3481 const zcu = comp.module.?;
3482 // This call takes ownership of `func.air`.3517 // This call takes ownership of `func.air`.
3483 try zcu.linkerUpdateFunc(func.func, func.air);3518 try comp.queueCodegenJob(tid, .{ .func = .{
3519 .func = func.func,
3520 .air = func.air,
3521 } });
3484 },3522 },
3485 .analyze_func => |func| {3523 .analyze_func => |func| {
3486 const named_frame = tracy.namedFrame("analyze_func");3524 const named_frame = tracy.namedFrame("analyze_func");
3487 defer named_frame.end();3525 defer named_frame.end();
34883526
3489 const zcu = comp.module.?;3527 const pt: Zcu.PerThread = .{ .zcu = comp.module.?, .tid = @enumFromInt(tid) };
3490 zcu.ensureFuncBodyAnalyzed(func) catch |err| switch (err) {3528 pt.ensureFuncBodyAnalyzed(func) catch |err| switch (err) {
3491 error.OutOfMemory => return error.OutOfMemory,3529 error.OutOfMemory => return error.OutOfMemory,
3492 error.AnalysisFail => return,3530 error.AnalysisFail => return,
3493 };3531 };
...@@ -3496,8 +3534,8 @@ fn processOneJob(comp: *Compilation, job: Job, prog_node: std.Progress.Node) !vo...@@ -3496,8 +3534,8 @@ fn processOneJob(comp: *Compilation, job: Job, prog_node: std.Progress.Node) !vo
3496 if (true) @panic("regressed compiler feature: emit-h should hook into updateExports, " ++3534 if (true) @panic("regressed compiler feature: emit-h should hook into updateExports, " ++
3497 "not decl analysis, which is too early to know about @export calls");3535 "not decl analysis, which is too early to know about @export calls");
34983536
3499 const zcu = comp.module.?;3537 const pt: Zcu.PerThread = .{ .zcu = comp.module.?, .tid = @enumFromInt(tid) };
3500 const decl = zcu.declPtr(decl_index);3538 const decl = pt.zcu.declPtr(decl_index);
35013539
3502 switch (decl.analysis) {3540 switch (decl.analysis) {
3503 .unreferenced => unreachable,3541 .unreferenced => unreachable,
...@@ -3515,7 +3553,7 @@ fn processOneJob(comp: *Compilation, job: Job, prog_node: std.Progress.Node) !vo...@@ -3515,7 +3553,7 @@ fn processOneJob(comp: *Compilation, job: Job, prog_node: std.Progress.Node) !vo
3515 defer named_frame.end();3553 defer named_frame.end();
35163554
3517 const gpa = comp.gpa;3555 const gpa = comp.gpa;
3518 const emit_h = zcu.emit_h.?;3556 const emit_h = pt.zcu.emit_h.?;
3519 _ = try emit_h.decl_table.getOrPut(gpa, decl_index);3557 _ = try emit_h.decl_table.getOrPut(gpa, decl_index);
3520 const decl_emit_h = emit_h.declPtr(decl_index);3558 const decl_emit_h = emit_h.declPtr(decl_index);
3521 const fwd_decl = &decl_emit_h.fwd_decl;3559 const fwd_decl = &decl_emit_h.fwd_decl;
...@@ -3523,11 +3561,11 @@ fn processOneJob(comp: *Compilation, job: Job, prog_node: std.Progress.Node) !vo...@@ -3523,11 +3561,11 @@ fn processOneJob(comp: *Compilation, job: Job, prog_node: std.Progress.Node) !vo
3523 var ctypes_arena = std.heap.ArenaAllocator.init(gpa);3561 var ctypes_arena = std.heap.ArenaAllocator.init(gpa);
3524 defer ctypes_arena.deinit();3562 defer ctypes_arena.deinit();
35253563
3526 const file_scope = zcu.namespacePtr(decl.src_namespace).fileScope(zcu);3564 const file_scope = pt.zcu.namespacePtr(decl.src_namespace).fileScope(pt.zcu);
35273565
3528 var dg: c_codegen.DeclGen = .{3566 var dg: c_codegen.DeclGen = .{
3529 .gpa = gpa,3567 .gpa = gpa,
3530 .zcu = zcu,3568 .pt = pt,
3531 .mod = file_scope.mod,3569 .mod = file_scope.mod,
3532 .error_msg = null,3570 .error_msg = null,
3533 .pass = .{ .decl = decl_index },3571 .pass = .{ .decl = decl_index },
...@@ -3557,25 +3595,25 @@ fn processOneJob(comp: *Compilation, job: Job, prog_node: std.Progress.Node) !vo...@@ -3557,25 +3595,25 @@ fn processOneJob(comp: *Compilation, job: Job, prog_node: std.Progress.Node) !vo
3557 }3595 }
3558 },3596 },
3559 .analyze_decl => |decl_index| {3597 .analyze_decl => |decl_index| {
3560 const zcu = comp.module.?;3598 const pt: Zcu.PerThread = .{ .zcu = comp.module.?, .tid = @enumFromInt(tid) };
3561 zcu.ensureDeclAnalyzed(decl_index) catch |err| switch (err) {3599 pt.ensureDeclAnalyzed(decl_index) catch |err| switch (err) {
3562 error.OutOfMemory => return error.OutOfMemory,3600 error.OutOfMemory => return error.OutOfMemory,
3563 error.AnalysisFail => return,3601 error.AnalysisFail => return,
3564 };3602 };
3565 const decl = zcu.declPtr(decl_index);3603 const decl = pt.zcu.declPtr(decl_index);
3566 if (decl.kind == .@"test" and comp.config.is_test) {3604 if (decl.kind == .@"test" and comp.config.is_test) {
3567 // Tests are always emitted in test binaries. The decl_refs are created by3605 // Tests are always emitted in test binaries. The decl_refs are created by
3568 // Zcu.populateTestFunctions, but this will not queue body analysis, so do3606 // Zcu.populateTestFunctions, but this will not queue body analysis, so do
3569 // that now.3607 // that now.
3570 try zcu.ensureFuncBodyAnalysisQueued(decl.val.toIntern());3608 try pt.zcu.ensureFuncBodyAnalysisQueued(decl.val.toIntern());
3571 }3609 }
3572 },3610 },
3573 .resolve_type_fully => |ty| {3611 .resolve_type_fully => |ty| {
3574 const named_frame = tracy.namedFrame("resolve_type_fully");3612 const named_frame = tracy.namedFrame("resolve_type_fully");
3575 defer named_frame.end();3613 defer named_frame.end();
35763614
3577 const zcu = comp.module.?;3615 const pt: Zcu.PerThread = .{ .zcu = comp.module.?, .tid = @enumFromInt(tid) };
3578 Type.fromInterned(ty).resolveFully(zcu) catch |err| switch (err) {3616 Type.fromInterned(ty).resolveFully(pt) catch |err| switch (err) {
3579 error.OutOfMemory => return error.OutOfMemory,3617 error.OutOfMemory => return error.OutOfMemory,
3580 error.AnalysisFail => return,3618 error.AnalysisFail => return,
3581 };3619 };
...@@ -3585,30 +3623,30 @@ fn processOneJob(comp: *Compilation, job: Job, prog_node: std.Progress.Node) !vo...@@ -3585,30 +3623,30 @@ fn processOneJob(comp: *Compilation, job: Job, prog_node: std.Progress.Node) !vo
3585 defer named_frame.end();3623 defer named_frame.end();
35863624
3587 const gpa = comp.gpa;3625 const gpa = comp.gpa;
3588 const zcu = comp.module.?;3626 const pt: Zcu.PerThread = .{ .zcu = comp.module.?, .tid = @enumFromInt(tid) };
3589 const decl = zcu.declPtr(decl_index);3627 const decl = pt.zcu.declPtr(decl_index);
3590 const lf = comp.bin_file.?;3628 const lf = comp.bin_file.?;
3591 lf.updateDeclLineNumber(zcu, decl_index) catch |err| {3629 lf.updateDeclLineNumber(pt, decl_index) catch |err| {
3592 try zcu.failed_analysis.ensureUnusedCapacity(gpa, 1);3630 try pt.zcu.failed_analysis.ensureUnusedCapacity(gpa, 1);
3593 zcu.failed_analysis.putAssumeCapacityNoClobber(3631 pt.zcu.failed_analysis.putAssumeCapacityNoClobber(
3594 InternPool.AnalUnit.wrap(.{ .decl = decl_index }),3632 InternPool.AnalUnit.wrap(.{ .decl = decl_index }),
3595 try Zcu.ErrorMsg.create(3633 try Zcu.ErrorMsg.create(
3596 gpa,3634 gpa,
3597 decl.navSrcLoc(zcu),3635 decl.navSrcLoc(pt.zcu),
3598 "unable to update line number: {s}",3636 "unable to update line number: {s}",
3599 .{@errorName(err)},3637 .{@errorName(err)},
3600 ),3638 ),
3601 );3639 );
3602 decl.analysis = .codegen_failure;3640 decl.analysis = .codegen_failure;
3603 try zcu.retryable_failures.append(gpa, InternPool.AnalUnit.wrap(.{ .decl = decl_index }));3641 try pt.zcu.retryable_failures.append(gpa, InternPool.AnalUnit.wrap(.{ .decl = decl_index }));
3604 };3642 };
3605 },3643 },
3606 .analyze_mod => |pkg| {3644 .analyze_mod => |mod| {
3607 const named_frame = tracy.namedFrame("analyze_mod");3645 const named_frame = tracy.namedFrame("analyze_mod");
3608 defer named_frame.end();3646 defer named_frame.end();
36093647
3610 const zcu = comp.module.?;3648 const pt: Zcu.PerThread = .{ .zcu = comp.module.?, .tid = @enumFromInt(tid) };
3611 zcu.semaPkg(pkg) catch |err| switch (err) {3649 pt.semaPkg(mod) catch |err| switch (err) {
3612 error.OutOfMemory => return error.OutOfMemory,3650 error.OutOfMemory => return error.OutOfMemory,
3613 error.AnalysisFail => return,3651 error.AnalysisFail => return,
3614 };3652 };
...@@ -3772,6 +3810,61 @@ fn processOneJob(comp: *Compilation, job: Job, prog_node: std.Progress.Node) !vo...@@ -3772,6 +3810,61 @@ fn processOneJob(comp: *Compilation, job: Job, prog_node: std.Progress.Node) !vo
3772 }3810 }
3773}3811}
37743812
3813fn queueCodegenJob(comp: *Compilation, tid: usize, codegen_job: CodegenJob) !void {
3814 if (InternPool.single_threaded or
3815 !comp.module.?.backendSupportsFeature(.separate_thread))
3816 return processOneCodegenJob(tid, comp, codegen_job);
3817
3818 {
3819 comp.codegen_work.mutex.lock();
3820 defer comp.codegen_work.mutex.unlock();
3821 try comp.codegen_work.queue.writeItem(codegen_job);
3822 }
3823 comp.codegen_work.cond.signal();
3824}
3825
3826fn codegenThread(tid: usize, comp: *Compilation) void {
3827 comp.codegen_work.mutex.lock();
3828 defer comp.codegen_work.mutex.unlock();
3829
3830 while (true) {
3831 if (comp.codegen_work.queue.readItem()) |codegen_job| {
3832 comp.codegen_work.mutex.unlock();
3833 defer comp.codegen_work.mutex.lock();
3834
3835 processOneCodegenJob(tid, comp, codegen_job) catch |job_error| {
3836 comp.codegen_work.job_error = job_error;
3837 break;
3838 };
3839 continue;
3840 }
3841
3842 if (comp.codegen_work.done) break;
3843
3844 comp.codegen_work.cond.wait(&comp.codegen_work.mutex);
3845 }
3846}
3847
3848fn processOneCodegenJob(tid: usize, comp: *Compilation, codegen_job: CodegenJob) JobError!void {
3849 switch (codegen_job) {
3850 .decl => |decl_index| {
3851 const named_frame = tracy.namedFrame("codegen_decl");
3852 defer named_frame.end();
3853
3854 const pt: Zcu.PerThread = .{ .zcu = comp.module.?, .tid = @enumFromInt(tid) };
3855 try pt.linkerUpdateDecl(decl_index);
3856 },
3857 .func => |func| {
3858 const named_frame = tracy.namedFrame("codegen_func");
3859 defer named_frame.end();
3860
3861 const pt: Zcu.PerThread = .{ .zcu = comp.module.?, .tid = @enumFromInt(tid) };
3862 // This call takes ownership of `func.air`.
3863 try pt.linkerUpdateFunc(func.func, func.air);
3864 },
3865 }
3866}
3867
3775fn workerDocsCopy(comp: *Compilation) void {3868fn workerDocsCopy(comp: *Compilation) void {
3776 docsCopyFallible(comp) catch |err| {3869 docsCopyFallible(comp) catch |err| {
3777 return comp.lockAndSetMiscFailure(3870 return comp.lockAndSetMiscFailure(
...@@ -4047,6 +4140,7 @@ const AstGenSrc = union(enum) {...@@ -4047,6 +4140,7 @@ const AstGenSrc = union(enum) {
4047};4140};
40484141
4049fn workerAstGenFile(4142fn workerAstGenFile(
4143 tid: usize,
4050 comp: *Compilation,4144 comp: *Compilation,
4051 file: *Zcu.File,4145 file: *Zcu.File,
4052 file_index: Zcu.File.Index,4146 file_index: Zcu.File.Index,
...@@ -4059,8 +4153,8 @@ fn workerAstGenFile(...@@ -4059,8 +4153,8 @@ fn workerAstGenFile(
4059 const child_prog_node = prog_node.start(file.sub_file_path, 0);4153 const child_prog_node = prog_node.start(file.sub_file_path, 0);
4060 defer child_prog_node.end();4154 defer child_prog_node.end();
40614155
4062 const zcu = comp.module.?;4156 const pt: Zcu.PerThread = .{ .zcu = comp.module.?, .tid = @enumFromInt(tid) };
4063 zcu.astGenFile(file, file_index, path_digest, root_decl) catch |err| switch (err) {4157 pt.astGenFile(file, file_index, path_digest, root_decl) catch |err| switch (err) {
4064 error.AnalysisFail => return,4158 error.AnalysisFail => return,
4065 else => {4159 else => {
4066 file.status = .retryable_failure;4160 file.status = .retryable_failure;
...@@ -4095,15 +4189,15 @@ fn workerAstGenFile(...@@ -4095,15 +4189,15 @@ fn workerAstGenFile(
4095 comp.mutex.lock();4189 comp.mutex.lock();
4096 defer comp.mutex.unlock();4190 defer comp.mutex.unlock();
40974191
4098 const res = zcu.importFile(file, import_path) catch continue;4192 const res = pt.zcu.importFile(file, import_path) catch continue;
4099 if (!res.is_pkg) {4193 if (!res.is_pkg) {
4100 res.file.addReference(zcu.*, .{ .import = .{4194 res.file.addReference(pt.zcu.*, .{ .import = .{
4101 .file = file_index,4195 .file = file_index,
4102 .token = item.data.token,4196 .token = item.data.token,
4103 } }) catch continue;4197 } }) catch continue;
4104 }4198 }
4105 const imported_path_digest = zcu.filePathDigest(res.file_index);4199 const imported_path_digest = pt.zcu.filePathDigest(res.file_index);
4106 const imported_root_decl = zcu.fileRootDecl(res.file_index);4200 const imported_root_decl = pt.zcu.fileRootDecl(res.file_index);
4107 break :blk .{ res, imported_path_digest, imported_root_decl };4201 break :blk .{ res, imported_path_digest, imported_root_decl };
4108 };4202 };
4109 if (import_result.is_new) {4203 if (import_result.is_new) {
...@@ -4114,7 +4208,7 @@ fn workerAstGenFile(...@@ -4114,7 +4208,7 @@ fn workerAstGenFile(
4114 .importing_file = file_index,4208 .importing_file = file_index,
4115 .import_tok = item.data.token,4209 .import_tok = item.data.token,
4116 } };4210 } };
4117 comp.thread_pool.spawnWg(wg, workerAstGenFile, .{4211 comp.thread_pool.spawnWgId(wg, workerAstGenFile, .{
4118 comp, import_result.file, import_result.file_index, imported_path_digest, imported_root_decl, prog_node, wg, sub_src,4212 comp, import_result.file, import_result.file_index, imported_path_digest, imported_root_decl, prog_node, wg, sub_src,
4119 });4213 });
4120 }4214 }
...@@ -4125,7 +4219,7 @@ fn workerAstGenFile(...@@ -4125,7 +4219,7 @@ fn workerAstGenFile(
4125fn workerUpdateBuiltinZigFile(4219fn workerUpdateBuiltinZigFile(
4126 comp: *Compilation,4220 comp: *Compilation,
4127 mod: *Package.Module,4221 mod: *Package.Module,
4128 file: *Module.File,4222 file: *Zcu.File,
4129) void {4223) void {
4130 Builtin.populateFile(comp, mod, file) catch |err| {4224 Builtin.populateFile(comp, mod, file) catch |err| {
4131 comp.mutex.lock();4225 comp.mutex.lock();
...@@ -4137,7 +4231,7 @@ fn workerUpdateBuiltinZigFile(...@@ -4137,7 +4231,7 @@ fn workerUpdateBuiltinZigFile(
4137 };4231 };
4138}4232}
41394233
4140fn workerCheckEmbedFile(comp: *Compilation, embed_file: *Module.EmbedFile) void {4234fn workerCheckEmbedFile(comp: *Compilation, embed_file: *Zcu.EmbedFile) void {
4141 comp.detectEmbedFileUpdate(embed_file) catch |err| {4235 comp.detectEmbedFileUpdate(embed_file) catch |err| {
4142 comp.reportRetryableEmbedFileError(embed_file, err) catch |oom| switch (oom) {4236 comp.reportRetryableEmbedFileError(embed_file, err) catch |oom| switch (oom) {
4143 // Swallowing this error is OK because it's implied to be OOM when4237 // Swallowing this error is OK because it's implied to be OOM when
...@@ -4148,7 +4242,7 @@ fn workerCheckEmbedFile(comp: *Compilation, embed_file: *Module.EmbedFile) void...@@ -4148,7 +4242,7 @@ fn workerCheckEmbedFile(comp: *Compilation, embed_file: *Module.EmbedFile) void
4148 };4242 };
4149}4243}
41504244
4151fn detectEmbedFileUpdate(comp: *Compilation, embed_file: *Module.EmbedFile) !void {4245fn detectEmbedFileUpdate(comp: *Compilation, embed_file: *Zcu.EmbedFile) !void {
4152 const mod = comp.module.?;4246 const mod = comp.module.?;
4153 const ip = &mod.intern_pool;4247 const ip = &mod.intern_pool;
4154 var file = try embed_file.owner.root.openFile(embed_file.sub_file_path.toSlice(ip), .{});4248 var file = try embed_file.owner.root.openFile(embed_file.sub_file_path.toSlice(ip), .{});
...@@ -4475,7 +4569,7 @@ fn reportRetryableAstGenError(...@@ -4475,7 +4569,7 @@ fn reportRetryableAstGenError(
4475 const file = zcu.fileByIndex(file_index);4569 const file = zcu.fileByIndex(file_index);
4476 file.status = .retryable_failure;4570 file.status = .retryable_failure;
44774571
4478 const src_loc: Module.LazySrcLoc = switch (src) {4572 const src_loc: Zcu.LazySrcLoc = switch (src) {
4479 .root => .{4573 .root => .{
4480 .base_node_inst = try zcu.intern_pool.trackZir(gpa, file_index, .main_struct_inst),4574 .base_node_inst = try zcu.intern_pool.trackZir(gpa, file_index, .main_struct_inst),
4481 .offset = .entire_file,4575 .offset = .entire_file,
...@@ -4486,7 +4580,7 @@ fn reportRetryableAstGenError(...@@ -4486,7 +4580,7 @@ fn reportRetryableAstGenError(
4486 },4580 },
4487 };4581 };
44884582
4489 const err_msg = try Module.ErrorMsg.create(gpa, src_loc, "unable to load '{}{s}': {s}", .{4583 const err_msg = try Zcu.ErrorMsg.create(gpa, src_loc, "unable to load '{}{s}': {s}", .{
4490 file.mod.root, file.sub_file_path, @errorName(err),4584 file.mod.root, file.sub_file_path, @errorName(err),
4491 });4585 });
4492 errdefer err_msg.destroy(gpa);4586 errdefer err_msg.destroy(gpa);
...@@ -4500,14 +4594,14 @@ fn reportRetryableAstGenError(...@@ -4500,14 +4594,14 @@ fn reportRetryableAstGenError(
45004594
4501fn reportRetryableEmbedFileError(4595fn reportRetryableEmbedFileError(
4502 comp: *Compilation,4596 comp: *Compilation,
4503 embed_file: *Module.EmbedFile,4597 embed_file: *Zcu.EmbedFile,
4504 err: anyerror,4598 err: anyerror,
4505) error{OutOfMemory}!void {4599) error{OutOfMemory}!void {
4506 const mod = comp.module.?;4600 const mod = comp.module.?;
4507 const gpa = mod.gpa;4601 const gpa = mod.gpa;
4508 const src_loc = embed_file.src_loc;4602 const src_loc = embed_file.src_loc;
4509 const ip = &mod.intern_pool;4603 const ip = &mod.intern_pool;
4510 const err_msg = try Module.ErrorMsg.create(gpa, src_loc, "unable to load '{}{s}': {s}", .{4604 const err_msg = try Zcu.ErrorMsg.create(gpa, src_loc, "unable to load '{}{s}': {s}", .{
4511 embed_file.owner.root,4605 embed_file.owner.root,
4512 embed_file.sub_file_path.toSlice(ip),4606 embed_file.sub_file_path.toSlice(ip),
4513 @errorName(err),4607 @errorName(err),
src/Compilation/Config.zig+2-6
...@@ -440,12 +440,8 @@ pub fn resolve(options: Options) ResolveError!Config {...@@ -440,12 +440,8 @@ pub fn resolve(options: Options) ResolveError!Config {
440 };440 };
441 };441 };
442442
443 const backend_supports_error_tracing = target_util.backendSupportsFeature(443 const backend = target_util.zigBackend(target, use_llvm);
444 target.cpu.arch,444 const backend_supports_error_tracing = target_util.backendSupportsFeature(backend, .error_return_trace);
445 target.ofmt,
446 use_llvm,
447 .error_return_trace,
448 );
449445
450 const root_error_tracing = b: {446 const root_error_tracing = b: {
451 if (options.root_error_tracing) |x| break :b x;447 if (options.root_error_tracing) |x| break :b x;
src/InternPool.zig+2634-1638
...@@ -2,22 +2,17 @@...@@ -2,22 +2,17 @@
2//! This data structure is self-contained, with the following exceptions:2//! This data structure is self-contained, with the following exceptions:
3//! * Module.Namespace has a pointer to Module.File3//! * Module.Namespace has a pointer to Module.File
44
5/// Maps `Key` to `Index`. `Key` objects are not stored anywhere; they are5/// One item per thread, indexed by `tid`, which is dense and unique per thread.
6/// constructed lazily.6locals: []Local = &.{},
7map: std.AutoArrayHashMapUnmanaged(void, void) = .{},7/// Length must be a power of two and represents the number of simultaneous
8items: std.MultiArrayList(Item) = .{},8/// writers that can mutate any single sharded data structure.
9extra: std.ArrayListUnmanaged(u32) = .{},9shards: []Shard = &.{},
10/// On 32-bit systems, this array is ignored and extra is used for everything.10/// Cached number of active bits in a `tid`.
11/// On 64-bit systems, this array is used for big integers and associated metadata.11tid_width: if (single_threaded) u0 else std.math.Log2Int(u32) = 0,
12/// Use the helper methods instead of accessing this directly in order to not12/// Cached shift amount to put a `tid` in the top bits of a 31-bit value.
13/// violate the above mechanism.13tid_shift_31: if (single_threaded) u0 else std.math.Log2Int(u32) = if (single_threaded) 0 else 31,
14limbs: std.ArrayListUnmanaged(u64) = .{},14/// Cached shift amount to put a `tid` in the top bits of a 32-bit value.
15/// In order to store references to strings in fewer bytes, we copy all15tid_shift_32: if (single_threaded) u0 else std.math.Log2Int(u32) = if (single_threaded) 0 else 31,
16/// string bytes into here. String bytes can be null. It is up to whomever
17/// is referencing the data here whether they want to store both index and length,
18/// thus allowing null bytes, or store only index, and use null-termination. The
19/// `string_bytes` array is agnostic to either usage.
20string_bytes: std.ArrayListUnmanaged(u8) = .{},
2116
22/// Rather than allocating Decl objects with an Allocator, we instead allocate17/// Rather than allocating Decl objects with an Allocator, we instead allocate
23/// them with this SegmentedList. This provides four advantages:18/// them with this SegmentedList. This provides four advantages:
...@@ -45,14 +40,6 @@ namespaces_free_list: std.ArrayListUnmanaged(NamespaceIndex) = .{},...@@ -45,14 +40,6 @@ namespaces_free_list: std.ArrayListUnmanaged(NamespaceIndex) = .{},
45/// These are not serialized; it is computed upon deserialization.40/// These are not serialized; it is computed upon deserialization.
46maps: std.ArrayListUnmanaged(FieldMap) = .{},41maps: std.ArrayListUnmanaged(FieldMap) = .{},
4742
48/// Used for finding the index inside `string_bytes`.
49string_table: std.HashMapUnmanaged(
50 u32,
51 void,
52 std.hash_map.StringIndexContext,
53 std.hash_map.default_max_load_percentage,
54) = .{},
55
56/// An index into `tracked_insts` gives a reference to a single ZIR instruction which43/// An index into `tracked_insts` gives a reference to a single ZIR instruction which
57/// persists across incremental updates.44/// persists across incremental updates.
58tracked_insts: std.AutoArrayHashMapUnmanaged(TrackedInst, void) = .{},45tracked_insts: std.AutoArrayHashMapUnmanaged(TrackedInst, void) = .{},
...@@ -103,6 +90,14 @@ free_dep_entries: std.ArrayListUnmanaged(DepEntry.Index) = .{},...@@ -103,6 +90,14 @@ free_dep_entries: std.ArrayListUnmanaged(DepEntry.Index) = .{},
103/// Value is the `Decl` of the struct that represents this `File`.90/// Value is the `Decl` of the struct that represents this `File`.
104files: std.AutoArrayHashMapUnmanaged(Cache.BinDigest, OptionalDeclIndex) = .{},91files: std.AutoArrayHashMapUnmanaged(Cache.BinDigest, OptionalDeclIndex) = .{},
10592
93/// Whether a multi-threaded intern pool is useful.
94/// Currently `false` until the intern pool is actually accessed
95/// from multiple threads to reduce the cost of this data structure.
96const want_multi_threaded = false;
97
98/// Whether a single-threaded intern pool impl is in use.
99pub const single_threaded = builtin.single_threaded or !want_multi_threaded;
100
106pub const FileIndex = enum(u32) {101pub const FileIndex = enum(u32) {
107 _,102 _,
108};103};
...@@ -351,6 +346,417 @@ pub const DepEntry = extern struct {...@@ -351,6 +346,417 @@ pub const DepEntry = extern struct {
351 };346 };
352};347};
353348
349const Local = struct {
350 /// These fields can be accessed from any thread by calling `acquire`.
351 /// They are only modified by the owning thread.
352 shared: Shared align(std.atomic.cache_line),
353 /// This state is fully local to the owning thread and does not require any
354 /// atomic access.
355 mutate: struct {
356 arena: std.heap.ArenaAllocator.State,
357 items: Mutate,
358 extra: Mutate,
359 limbs: Mutate,
360 strings: Mutate,
361 } align(std.atomic.cache_line),
362
363 const Shared = struct {
364 items: List(Item),
365 extra: Extra,
366 limbs: Limbs,
367 strings: Strings,
368
369 pub fn getLimbs(shared: *const Local.Shared) Limbs {
370 return switch (@sizeOf(Limb)) {
371 @sizeOf(u32) => shared.extra,
372 @sizeOf(u64) => shared.limbs,
373 else => @compileError("unsupported host"),
374 }.acquire();
375 }
376 };
377
378 const Extra = List(struct { u32 });
379 const Limbs = switch (@sizeOf(Limb)) {
380 @sizeOf(u32) => Extra,
381 @sizeOf(u64) => List(struct { u64 }),
382 else => @compileError("unsupported host"),
383 };
384 const Strings = List(struct { u8 });
385
386 const Mutate = struct {
387 len: u32,
388
389 const empty: Mutate = .{
390 .len = 0,
391 };
392 };
393
394 fn List(comptime Elem: type) type {
395 assert(@typeInfo(Elem) == .Struct);
396 return struct {
397 bytes: [*]align(@alignOf(Elem)) u8,
398
399 const ListSelf = @This();
400 const Mutable = struct {
401 gpa: std.mem.Allocator,
402 arena: *std.heap.ArenaAllocator.State,
403 mutate: *Mutate,
404 list: *ListSelf,
405
406 const fields = std.enums.values(std.meta.FieldEnum(Elem));
407
408 fn PtrArrayElem(comptime len: usize) type {
409 const elem_info = @typeInfo(Elem).Struct;
410 const elem_fields = elem_info.fields;
411 var new_fields: [elem_fields.len]std.builtin.Type.StructField = undefined;
412 for (&new_fields, elem_fields) |*new_field, elem_field| new_field.* = .{
413 .name = elem_field.name,
414 .type = *[len]elem_field.type,
415 .default_value = null,
416 .is_comptime = false,
417 .alignment = 0,
418 };
419 return @Type(.{ .Struct = .{
420 .layout = .auto,
421 .fields = &new_fields,
422 .decls = &.{},
423 .is_tuple = elem_info.is_tuple,
424 } });
425 }
426 fn SliceElem(comptime opts: struct { is_const: bool = false }) type {
427 const elem_info = @typeInfo(Elem).Struct;
428 const elem_fields = elem_info.fields;
429 var new_fields: [elem_fields.len]std.builtin.Type.StructField = undefined;
430 for (&new_fields, elem_fields) |*new_field, elem_field| new_field.* = .{
431 .name = elem_field.name,
432 .type = @Type(.{ .Pointer = .{
433 .size = .Slice,
434 .is_const = opts.is_const,
435 .is_volatile = false,
436 .alignment = 0,
437 .address_space = .generic,
438 .child = elem_field.type,
439 .is_allowzero = false,
440 .sentinel = null,
441 } }),
442 .default_value = null,
443 .is_comptime = false,
444 .alignment = 0,
445 };
446 return @Type(.{ .Struct = .{
447 .layout = .auto,
448 .fields = &new_fields,
449 .decls = &.{},
450 .is_tuple = elem_info.is_tuple,
451 } });
452 }
453
454 pub fn append(mutable: Mutable, elem: Elem) Allocator.Error!void {
455 try mutable.ensureUnusedCapacity(1);
456 mutable.appendAssumeCapacity(elem);
457 }
458
459 pub fn appendAssumeCapacity(mutable: Mutable, elem: Elem) void {
460 var mutable_view = mutable.view();
461 defer mutable.mutate.len = @intCast(mutable_view.len);
462 mutable_view.appendAssumeCapacity(elem);
463 }
464
465 pub fn appendSliceAssumeCapacity(
466 mutable: Mutable,
467 slice: SliceElem(.{ .is_const = true }),
468 ) void {
469 if (fields.len == 0) return;
470 const start = mutable.mutate.len;
471 const slice_len = @field(slice, @tagName(fields[0])).len;
472 assert(slice_len <= mutable.list.header().capacity - start);
473 mutable.mutate.len = @intCast(start + slice_len);
474 const mutable_view = mutable.view();
475 inline for (fields) |field| {
476 const field_slice = @field(slice, @tagName(field));
477 assert(field_slice.len == slice_len);
478 @memcpy(mutable_view.items(field)[start..][0..slice_len], field_slice);
479 }
480 }
481
482 pub fn appendNTimes(mutable: Mutable, elem: Elem, len: usize) Allocator.Error!void {
483 try mutable.ensureUnusedCapacity(len);
484 mutable.appendNTimesAssumeCapacity(elem, len);
485 }
486
487 pub fn appendNTimesAssumeCapacity(mutable: Mutable, elem: Elem, len: usize) void {
488 const start = mutable.mutate.len;
489 assert(len <= mutable.list.header().capacity - start);
490 mutable.mutate.len = @intCast(start + len);
491 const mutable_view = mutable.view();
492 inline for (fields) |field| {
493 @memset(mutable_view.items(field)[start..][0..len], @field(elem, @tagName(field)));
494 }
495 }
496
497 pub fn addManyAsArray(mutable: Mutable, comptime len: usize) Allocator.Error!PtrArrayElem(len) {
498 try mutable.ensureUnusedCapacity(len);
499 return mutable.addManyAsArrayAssumeCapacity(len);
500 }
501
502 pub fn addManyAsArrayAssumeCapacity(mutable: Mutable, comptime len: usize) PtrArrayElem(len) {
503 const start = mutable.mutate.len;
504 assert(len <= mutable.list.header().capacity - start);
505 mutable.mutate.len = @intCast(start + len);
506 const mutable_view = mutable.view();
507 var ptr_array: PtrArrayElem(len) = undefined;
508 inline for (fields) |field| {
509 @field(ptr_array, @tagName(field)) = mutable_view.items(field)[start..][0..len];
510 }
511 return ptr_array;
512 }
513
514 pub fn addManyAsSlice(mutable: Mutable, len: usize) Allocator.Error!SliceElem(.{}) {
515 try mutable.ensureUnusedCapacity(len);
516 return mutable.addManyAsSliceAssumeCapacity(len);
517 }
518
519 pub fn addManyAsSliceAssumeCapacity(mutable: Mutable, len: usize) SliceElem(.{}) {
520 const start = mutable.mutate.len;
521 assert(len <= mutable.list.header().capacity - start);
522 mutable.mutate.len = @intCast(start + len);
523 const mutable_view = mutable.view();
524 var slice: SliceElem(.{}) = undefined;
525 inline for (fields) |field| {
526 @field(slice, @tagName(field)) = mutable_view.items(field)[start..][0..len];
527 }
528 return slice;
529 }
530
531 pub fn shrinkRetainingCapacity(mutable: Mutable, len: usize) void {
532 assert(len <= mutable.mutate.len);
533 mutable.mutate.len = @intCast(len);
534 }
535
536 pub fn ensureUnusedCapacity(mutable: Mutable, unused_capacity: usize) Allocator.Error!void {
537 try mutable.ensureTotalCapacity(@intCast(mutable.mutate.len + unused_capacity));
538 }
539
540 pub fn ensureTotalCapacity(mutable: Mutable, total_capacity: usize) Allocator.Error!void {
541 const old_capacity = mutable.list.header().capacity;
542 if (old_capacity >= total_capacity) return;
543 var new_capacity = old_capacity;
544 while (new_capacity < total_capacity) new_capacity = (new_capacity + 10) * 2;
545 try mutable.setCapacity(new_capacity);
546 }
547
548 fn setCapacity(mutable: Mutable, capacity: u32) Allocator.Error!void {
549 var arena = mutable.arena.promote(mutable.gpa);
550 defer mutable.arena.* = arena.state;
551 const buf = try arena.allocator().alignedAlloc(
552 u8,
553 alignment,
554 bytes_offset + View.capacityInBytes(capacity),
555 );
556 var new_list: ListSelf = .{ .bytes = @ptrCast(buf[bytes_offset..].ptr) };
557 new_list.header().* = .{ .capacity = capacity };
558 const len = mutable.mutate.len;
559 // this cold, quickly predictable, condition enables
560 // the `MultiArrayList` optimization in `view`
561 if (len > 0) {
562 const old_slice = mutable.list.view().slice();
563 const new_slice = new_list.view().slice();
564 inline for (fields) |field| @memcpy(new_slice.items(field)[0..len], old_slice.items(field)[0..len]);
565 }
566 mutable.list.release(new_list);
567 }
568
569 fn view(mutable: Mutable) View {
570 const capacity = mutable.list.header().capacity;
571 assert(capacity > 0); // optimizes `MultiArrayList.Slice.items`
572 return .{
573 .bytes = mutable.list.bytes,
574 .len = mutable.mutate.len,
575 .capacity = capacity,
576 };
577 }
578 };
579
580 const empty: ListSelf = .{ .bytes = @constCast(&(extern struct {
581 header: Header,
582 bytes: [0]u8 align(@alignOf(Elem)),
583 }{
584 .header = .{ .capacity = 0 },
585 .bytes = .{},
586 }).bytes) };
587
588 const alignment = @max(@alignOf(Header), @alignOf(Elem));
589 const bytes_offset = std.mem.alignForward(usize, @sizeOf(Header), @alignOf(Elem));
590 const View = std.MultiArrayList(Elem);
591
592 /// Must be called when accessing from another thread.
593 fn acquire(list: *const ListSelf) ListSelf {
594 return .{ .bytes = @atomicLoad([*]align(@alignOf(Elem)) u8, &list.bytes, .acquire) };
595 }
596 fn release(list: *ListSelf, new_list: ListSelf) void {
597 @atomicStore([*]align(@alignOf(Elem)) u8, &list.bytes, new_list.bytes, .release);
598 }
599
600 const Header = extern struct {
601 capacity: u32,
602 };
603 fn header(list: ListSelf) *Header {
604 return @ptrFromInt(@intFromPtr(list.bytes) - bytes_offset);
605 }
606
607 fn view(list: ListSelf) View {
608 const capacity = list.header().capacity;
609 assert(capacity > 0); // optimizes `MultiArrayList.Slice.items`
610 return .{
611 .bytes = list.bytes,
612 .len = capacity,
613 .capacity = capacity,
614 };
615 }
616 };
617 }
618
619 pub fn getMutableItems(local: *Local, gpa: std.mem.Allocator) List(Item).Mutable {
620 return .{
621 .gpa = gpa,
622 .arena = &local.mutate.arena,
623 .mutate = &local.mutate.items,
624 .list = &local.shared.items,
625 };
626 }
627
628 pub fn getMutableExtra(local: *Local, gpa: std.mem.Allocator) Extra.Mutable {
629 return .{
630 .gpa = gpa,
631 .arena = &local.mutate.arena,
632 .mutate = &local.mutate.extra,
633 .list = &local.shared.extra,
634 };
635 }
636
637 /// On 32-bit systems, this array is ignored and extra is used for everything.
638 /// On 64-bit systems, this array is used for big integers and associated metadata.
639 /// Use the helper methods instead of accessing this directly in order to not
640 /// violate the above mechanism.
641 pub fn getMutableLimbs(local: *Local, gpa: std.mem.Allocator) Limbs.Mutable {
642 return switch (@sizeOf(Limb)) {
643 @sizeOf(u32) => local.getMutableExtra(gpa),
644 @sizeOf(u64) => .{
645 .gpa = gpa,
646 .arena = &local.mutate.arena,
647 .mutate = &local.mutate.limbs,
648 .list = &local.shared.limbs,
649 },
650 else => @compileError("unsupported host"),
651 };
652 }
653
654 /// In order to store references to strings in fewer bytes, we copy all
655 /// string bytes into here. String bytes can be null. It is up to whomever
656 /// is referencing the data here whether they want to store both index and length,
657 /// thus allowing null bytes, or store only index, and use null-termination. The
658 /// `strings` array is agnostic to either usage.
659 pub fn getMutableStrings(local: *Local, gpa: std.mem.Allocator) Strings.Mutable {
660 return .{
661 .gpa = gpa,
662 .arena = &local.mutate.arena,
663 .mutate = &local.mutate.strings,
664 .list = &local.shared.strings,
665 };
666 }
667};
668
669pub fn getLocal(ip: *InternPool, tid: Zcu.PerThread.Id) *Local {
670 return &ip.locals[@intFromEnum(tid)];
671}
672
673pub fn getLocalShared(ip: *const InternPool, tid: Zcu.PerThread.Id) *const Local.Shared {
674 return &ip.locals[@intFromEnum(tid)].shared;
675}
676
677const Shard = struct {
678 shared: struct {
679 map: Map(Index),
680 string_map: Map(OptionalNullTerminatedString),
681 } align(std.atomic.cache_line),
682 mutate: struct {
683 // TODO: measure cost of sharing unrelated mutate state
684 map: Mutate align(std.atomic.cache_line),
685 string_map: Mutate align(std.atomic.cache_line),
686 },
687
688 const Mutate = struct {
689 mutex: std.Thread.Mutex.Recursive,
690 len: u32,
691
692 const empty: Mutate = .{
693 .mutex = std.Thread.Mutex.Recursive.init,
694 .len = 0,
695 };
696 };
697
698 fn Map(comptime Value: type) type {
699 comptime assert(@typeInfo(Value).Enum.tag_type == u32);
700 _ = @as(Value, .none); // expected .none key
701 return struct {
702 /// header: Header,
703 /// entries: [header.capacity]Entry,
704 entries: [*]Entry,
705
706 const empty: @This() = .{ .entries = @constCast(&(extern struct {
707 header: Header,
708 entries: [1]Entry,
709 }{
710 .header = .{ .capacity = 1 },
711 .entries = .{.{ .value = .none, .hash = undefined }},
712 }).entries) };
713
714 const alignment = @max(@alignOf(Header), @alignOf(Entry));
715 const entries_offset = std.mem.alignForward(usize, @sizeOf(Header), @alignOf(Entry));
716
717 /// Must be called unless the mutate mutex is locked.
718 fn acquire(map: *const @This()) @This() {
719 return .{ .entries = @atomicLoad([*]Entry, &map.entries, .acquire) };
720 }
721 fn release(map: *@This(), new_map: @This()) void {
722 @atomicStore([*]Entry, &map.entries, new_map.entries, .release);
723 }
724
725 const Header = extern struct {
726 capacity: u32,
727
728 fn mask(head: *const Header) u32 {
729 assert(std.math.isPowerOfTwo(head.capacity));
730 return head.capacity - 1;
731 }
732 };
733 fn header(map: @This()) *Header {
734 return @ptrFromInt(@intFromPtr(map.entries) - entries_offset);
735 }
736
737 const Entry = extern struct {
738 value: Value,
739 hash: u32,
740
741 fn acquire(entry: *const Entry) Value {
742 return @atomicLoad(Value, &entry.value, .acquire);
743 }
744 fn release(entry: *Entry, value: Value) void {
745 @atomicStore(Value, &entry.value, value, .release);
746 }
747 };
748 };
749 }
750};
751
752fn getTidMask(ip: *const InternPool) u32 {
753 return (@as(u32, 1) << ip.tid_width) - 1;
754}
755
756fn getIndexMask(ip: *const InternPool, comptime BackingInt: type) u32 {
757 return @as(u32, std.math.maxInt(BackingInt)) >> ip.tid_width;
758}
759
354const FieldMap = std.ArrayHashMapUnmanaged(void, void, std.array_hash_map.AutoContext(void), false);760const FieldMap = std.ArrayHashMapUnmanaged(void, void, std.array_hash_map.AutoContext(void), false);
355761
356const builtin = @import("builtin");762const builtin = @import("builtin");
...@@ -369,20 +775,6 @@ const Zcu = @import("Zcu.zig");...@@ -369,20 +775,6 @@ const Zcu = @import("Zcu.zig");
369const Module = Zcu;775const Module = Zcu;
370const Zir = std.zig.Zir;776const Zir = std.zig.Zir;
371777
372const KeyAdapter = struct {
373 intern_pool: *const InternPool,
374
375 pub fn eql(ctx: @This(), a: Key, b_void: void, b_map_index: usize) bool {
376 _ = b_void;
377 if (ctx.intern_pool.items.items(.tag)[b_map_index] == .removed) return false;
378 return ctx.intern_pool.indexToKey(@enumFromInt(b_map_index)).eql(a, ctx.intern_pool);
379 }
380
381 pub fn hash(ctx: @This(), a: Key) u32 {
382 return a.hash32(ctx.intern_pool);
383 }
384};
385
386/// An index into `maps` which might be `none`.778/// An index into `maps` which might be `none`.
387pub const OptionalMapIndex = enum(u32) {779pub const OptionalMapIndex = enum(u32) {
388 none = std.math.maxInt(u32),780 none = std.math.maxInt(u32),
...@@ -459,18 +851,18 @@ pub const OptionalNamespaceIndex = enum(u32) {...@@ -459,18 +851,18 @@ pub const OptionalNamespaceIndex = enum(u32) {
459 }851 }
460};852};
461853
462/// An index into `string_bytes`.854/// An index into `strings`.
463pub const String = enum(u32) {855pub const String = enum(u32) {
464 /// An empty string.856 /// An empty string.
465 empty = 0,857 empty = 0,
466 _,858 _,
467859
468 pub fn toSlice(string: String, len: u64, ip: *const InternPool) []const u8 {860 pub fn toSlice(string: String, len: u64, ip: *const InternPool) []const u8 {
469 return ip.string_bytes.items[@intFromEnum(string)..][0..@intCast(len)];861 return string.toOverlongSlice(ip)[0..@intCast(len)];
470 }862 }
471863
472 pub fn at(string: String, index: u64, ip: *const InternPool) u8 {864 pub fn at(string: String, index: u64, ip: *const InternPool) u8 {
473 return ip.string_bytes.items[@intCast(@intFromEnum(string) + index)];865 return string.toOverlongSlice(ip)[@intCast(index)];
474 }866 }
475867
476 pub fn toNullTerminatedString(string: String, len: u64, ip: *const InternPool) NullTerminatedString {868 pub fn toNullTerminatedString(string: String, len: u64, ip: *const InternPool) NullTerminatedString {
...@@ -478,9 +870,32 @@ pub const String = enum(u32) {...@@ -478,9 +870,32 @@ pub const String = enum(u32) {
478 assert(string.at(len, ip) == 0);870 assert(string.at(len, ip) == 0);
479 return @enumFromInt(@intFromEnum(string));871 return @enumFromInt(@intFromEnum(string));
480 }872 }
873
874 const Unwrapped = struct {
875 tid: Zcu.PerThread.Id,
876 index: u32,
877
878 fn wrap(unwrapped: Unwrapped, ip: *const InternPool) String {
879 assert(@intFromEnum(unwrapped.tid) <= ip.getTidMask());
880 assert(unwrapped.index <= ip.getIndexMask(u32));
881 return @enumFromInt(@as(u32, @intFromEnum(unwrapped.tid)) << ip.tid_shift_32 | unwrapped.index);
882 }
883 };
884 fn unwrap(string: String, ip: *const InternPool) Unwrapped {
885 return .{
886 .tid = @enumFromInt(@intFromEnum(string) >> ip.tid_shift_32 & ip.getTidMask()),
887 .index = @intFromEnum(string) & ip.getIndexMask(u32),
888 };
889 }
890
891 fn toOverlongSlice(string: String, ip: *const InternPool) []const u8 {
892 const unwrapped_string = string.unwrap(ip);
893 const strings = ip.getLocalShared(unwrapped_string.tid).strings.acquire();
894 return strings.view().items(.@"0")[unwrapped_string.index..];
895 }
481};896};
482897
483/// An index into `string_bytes` which might be `none`.898/// An index into `strings` which might be `none`.
484pub const OptionalString = enum(u32) {899pub const OptionalString = enum(u32) {
485 /// This is distinct from `none` - it is a valid index that represents empty string.900 /// This is distinct from `none` - it is a valid index that represents empty string.
486 empty = 0,901 empty = 0,
...@@ -496,7 +911,7 @@ pub const OptionalString = enum(u32) {...@@ -496,7 +911,7 @@ pub const OptionalString = enum(u32) {
496 }911 }
497};912};
498913
499/// An index into `string_bytes`.914/// An index into `strings`.
500pub const NullTerminatedString = enum(u32) {915pub const NullTerminatedString = enum(u32) {
501 /// An empty string.916 /// An empty string.
502 empty = 0,917 empty = 0,
...@@ -506,11 +921,15 @@ pub const NullTerminatedString = enum(u32) {...@@ -506,11 +921,15 @@ pub const NullTerminatedString = enum(u32) {
506 /// This type exists to provide a struct with lifetime that is921 /// This type exists to provide a struct with lifetime that is
507 /// not invalidated when items are added to the `InternPool`.922 /// not invalidated when items are added to the `InternPool`.
508 pub const Slice = struct {923 pub const Slice = struct {
924 tid: Zcu.PerThread.Id,
509 start: u32,925 start: u32,
510 len: u32,926 len: u32,
511927
928 pub const empty: Slice = .{ .tid = .main, .start = 0, .len = 0 };
929
512 pub fn get(slice: Slice, ip: *const InternPool) []NullTerminatedString {930 pub fn get(slice: Slice, ip: *const InternPool) []NullTerminatedString {
513 return @ptrCast(ip.extra.items[slice.start..][0..slice.len]);931 const extra = ip.getLocalShared(slice.tid).extra.acquire();
932 return @ptrCast(extra.view().items(.@"0")[slice.start..][0..slice.len]);
514 }933 }
515 };934 };
516935
...@@ -523,8 +942,8 @@ pub const NullTerminatedString = enum(u32) {...@@ -523,8 +942,8 @@ pub const NullTerminatedString = enum(u32) {
523 }942 }
524943
525 pub fn toSlice(string: NullTerminatedString, ip: *const InternPool) [:0]const u8 {944 pub fn toSlice(string: NullTerminatedString, ip: *const InternPool) [:0]const u8 {
526 const slice = ip.string_bytes.items[@intFromEnum(string)..];945 const overlong_slice = string.toString().toOverlongSlice(ip);
527 return slice[0..std.mem.indexOfScalar(u8, slice, 0).? :0];946 return overlong_slice[0..std.mem.indexOfScalar(u8, overlong_slice, 0).? :0];
528 }947 }
529948
530 pub fn length(string: NullTerminatedString, ip: *const InternPool) u32 {949 pub fn length(string: NullTerminatedString, ip: *const InternPool) u32 {
...@@ -532,7 +951,10 @@ pub const NullTerminatedString = enum(u32) {...@@ -532,7 +951,10 @@ pub const NullTerminatedString = enum(u32) {
532 }951 }
533952
534 pub fn eqlSlice(string: NullTerminatedString, slice: []const u8, ip: *const InternPool) bool {953 pub fn eqlSlice(string: NullTerminatedString, slice: []const u8, ip: *const InternPool) bool {
535 return std.mem.eql(u8, string.toSlice(ip), slice);954 const overlong_slice = string.toString().toOverlongSlice(ip);
955 return overlong_slice.len > slice.len and
956 std.mem.eql(u8, overlong_slice[0..slice.len], slice) and
957 overlong_slice[slice.len] == 0;
536 }958 }
537959
538 const Adapter = struct {960 const Adapter = struct {
...@@ -580,12 +1002,12 @@ pub const NullTerminatedString = enum(u32) {...@@ -580,12 +1002,12 @@ pub const NullTerminatedString = enum(u32) {
580 } else @compileError("invalid format string '" ++ specifier ++ "' for '" ++ @typeName(NullTerminatedString) ++ "'");1002 } else @compileError("invalid format string '" ++ specifier ++ "' for '" ++ @typeName(NullTerminatedString) ++ "'");
581 }1003 }
5821004
583 pub fn fmt(self: NullTerminatedString, ip: *const InternPool) std.fmt.Formatter(format) {1005 pub fn fmt(string: NullTerminatedString, ip: *const InternPool) std.fmt.Formatter(format) {
584 return .{ .data = .{ .string = self, .ip = ip } };1006 return .{ .data = .{ .string = string, .ip = ip } };
585 }1007 }
586};1008};
5871009
588/// An index into `string_bytes` which might be `none`.1010/// An index into `strings` which might be `none`.
589pub const OptionalNullTerminatedString = enum(u32) {1011pub const OptionalNullTerminatedString = enum(u32) {
590 /// This is distinct from `none` - it is a valid index that represents empty string.1012 /// This is distinct from `none` - it is a valid index that represents empty string.
591 empty = 0,1013 empty = 0,
...@@ -638,10 +1060,15 @@ pub const CaptureValue = packed struct(u32) {...@@ -638,10 +1060,15 @@ pub const CaptureValue = packed struct(u32) {
638 };1060 };
6391061
640 pub const Slice = struct {1062 pub const Slice = struct {
1063 tid: Zcu.PerThread.Id,
641 start: u32,1064 start: u32,
642 len: u32,1065 len: u32,
1066
1067 pub const empty: Slice = .{ .tid = .main, .start = 0, .len = 0 };
1068
643 pub fn get(slice: Slice, ip: *const InternPool) []CaptureValue {1069 pub fn get(slice: Slice, ip: *const InternPool) []CaptureValue {
644 return @ptrCast(ip.extra.items[slice.start..][0..slice.len]);1070 const extra = ip.getLocalShared(slice.tid).extra.acquire();
1071 return @ptrCast(extra.view().items(.@"0")[slice.start..][0..slice.len]);
645 }1072 }
646 };1073 };
647};1074};
...@@ -927,6 +1354,7 @@ pub const Key = union(enum) {...@@ -927,6 +1354,7 @@ pub const Key = union(enum) {
927 };1354 };
9281355
929 pub const Func = struct {1356 pub const Func = struct {
1357 tid: Zcu.PerThread.Id,
930 /// In the case of a generic function, this type will potentially have fewer parameters1358 /// In the case of a generic function, this type will potentially have fewer parameters
931 /// than the generic owner's type, because the comptime parameters will be deleted.1359 /// than the generic owner's type, because the comptime parameters will be deleted.
932 ty: Index,1360 ty: Index,
...@@ -982,23 +1410,27 @@ pub const Key = union(enum) {...@@ -982,23 +1410,27 @@ pub const Key = union(enum) {
9821410
983 /// Returns a pointer that becomes invalid after any additions to the `InternPool`.1411 /// Returns a pointer that becomes invalid after any additions to the `InternPool`.
984 pub fn analysis(func: *const Func, ip: *const InternPool) *FuncAnalysis {1412 pub fn analysis(func: *const Func, ip: *const InternPool) *FuncAnalysis {
985 return @ptrCast(&ip.extra.items[func.analysis_extra_index]);1413 const extra = ip.getLocalShared(func.tid).extra.acquire();
1414 return @ptrCast(&extra.view().items(.@"0")[func.analysis_extra_index]);
986 }1415 }
9871416
988 /// Returns a pointer that becomes invalid after any additions to the `InternPool`.1417 /// Returns a pointer that becomes invalid after any additions to the `InternPool`.
989 pub fn zirBodyInst(func: *const Func, ip: *const InternPool) *TrackedInst.Index {1418 pub fn zirBodyInst(func: *const Func, ip: *const InternPool) *TrackedInst.Index {
990 return @ptrCast(&ip.extra.items[func.zir_body_inst_extra_index]);1419 const extra = ip.getLocalShared(func.tid).extra.acquire();
1420 return @ptrCast(&extra.view().items(.@"0")[func.zir_body_inst_extra_index]);
991 }1421 }
9921422
993 /// Returns a pointer that becomes invalid after any additions to the `InternPool`.1423 /// Returns a pointer that becomes invalid after any additions to the `InternPool`.
994 pub fn branchQuota(func: *const Func, ip: *const InternPool) *u32 {1424 pub fn branchQuota(func: *const Func, ip: *const InternPool) *u32 {
995 return &ip.extra.items[func.branch_quota_extra_index];1425 const extra = ip.getLocalShared(func.tid).extra.acquire();
1426 return &extra.view().items(.@"0")[func.branch_quota_extra_index];
996 }1427 }
9971428
998 /// Returns a pointer that becomes invalid after any additions to the `InternPool`.1429 /// Returns a pointer that becomes invalid after any additions to the `InternPool`.
999 pub fn resolvedErrorSet(func: *const Func, ip: *const InternPool) *Index {1430 pub fn resolvedErrorSet(func: *const Func, ip: *const InternPool) *Index {
1431 const extra = ip.getLocalShared(func.tid).extra.acquire();
1000 assert(func.analysis(ip).inferred_error_set);1432 assert(func.analysis(ip).inferred_error_set);
1001 return @ptrCast(&ip.extra.items[func.resolved_error_set_extra_index]);1433 return @ptrCast(&extra.view().items(.@"0")[func.resolved_error_set_extra_index]);
1002 }1434 }
1003 };1435 };
10041436
...@@ -1841,6 +2273,7 @@ pub const RequiresComptime = enum(u2) { no, yes, unknown, wip };...@@ -1841,6 +2273,7 @@ pub const RequiresComptime = enum(u2) { no, yes, unknown, wip };
1841// minimal hashmap key, this type is a convenience type that contains info2273// minimal hashmap key, this type is a convenience type that contains info
1842// needed by semantic analysis.2274// needed by semantic analysis.
1843pub const LoadedUnionType = struct {2275pub const LoadedUnionType = struct {
2276 tid: Zcu.PerThread.Id,
1844 /// The index of the `Tag.TypeUnion` payload.2277 /// The index of the `Tag.TypeUnion` payload.
1845 extra_index: u32,2278 extra_index: u32,
1846 /// The Decl that corresponds to the union itself.2279 /// The Decl that corresponds to the union itself.
...@@ -1913,7 +2346,7 @@ pub const LoadedUnionType = struct {...@@ -1913,7 +2346,7 @@ pub const LoadedUnionType = struct {
1913 }2346 }
1914 };2347 };
19152348
1916 pub fn loadTagType(self: LoadedUnionType, ip: *InternPool) LoadedEnumType {2349 pub fn loadTagType(self: LoadedUnionType, ip: *const InternPool) LoadedEnumType {
1917 return ip.loadEnumType(self.enum_tag_ty);2350 return ip.loadEnumType(self.enum_tag_ty);
1918 }2351 }
19192352
...@@ -1926,26 +2359,30 @@ pub const LoadedUnionType = struct {...@@ -1926,26 +2359,30 @@ pub const LoadedUnionType = struct {
1926 /// when it is mutated, the mutations are observed.2359 /// when it is mutated, the mutations are observed.
1927 /// The returned pointer expires with any addition to the `InternPool`.2360 /// The returned pointer expires with any addition to the `InternPool`.
1928 pub fn tagTypePtr(self: LoadedUnionType, ip: *const InternPool) *Index {2361 pub fn tagTypePtr(self: LoadedUnionType, ip: *const InternPool) *Index {
2362 const extra = ip.getLocalShared(self.tid).extra.acquire();
1929 const field_index = std.meta.fieldIndex(Tag.TypeUnion, "tag_ty").?;2363 const field_index = std.meta.fieldIndex(Tag.TypeUnion, "tag_ty").?;
1930 return @ptrCast(&ip.extra.items[self.extra_index + field_index]);2364 return @ptrCast(&extra.view().items(.@"0")[self.extra_index + field_index]);
1931 }2365 }
19322366
1933 /// The returned pointer expires with any addition to the `InternPool`.2367 /// The returned pointer expires with any addition to the `InternPool`.
1934 pub fn flagsPtr(self: LoadedUnionType, ip: *const InternPool) *Tag.TypeUnion.Flags {2368 pub fn flagsPtr(self: LoadedUnionType, ip: *const InternPool) *Tag.TypeUnion.Flags {
2369 const extra = ip.getLocalShared(self.tid).extra.acquire();
1935 const field_index = std.meta.fieldIndex(Tag.TypeUnion, "flags").?;2370 const field_index = std.meta.fieldIndex(Tag.TypeUnion, "flags").?;
1936 return @ptrCast(&ip.extra.items[self.extra_index + field_index]);2371 return @ptrCast(&extra.view().items(.@"0")[self.extra_index + field_index]);
1937 }2372 }
19382373
1939 /// The returned pointer expires with any addition to the `InternPool`.2374 /// The returned pointer expires with any addition to the `InternPool`.
1940 pub fn size(self: LoadedUnionType, ip: *const InternPool) *u32 {2375 pub fn size(self: LoadedUnionType, ip: *const InternPool) *u32 {
2376 const extra = ip.getLocalShared(self.tid).extra.acquire();
1941 const field_index = std.meta.fieldIndex(Tag.TypeUnion, "size").?;2377 const field_index = std.meta.fieldIndex(Tag.TypeUnion, "size").?;
1942 return &ip.extra.items[self.extra_index + field_index];2378 return &extra.view().items(.@"0")[self.extra_index + field_index];
1943 }2379 }
19442380
1945 /// The returned pointer expires with any addition to the `InternPool`.2381 /// The returned pointer expires with any addition to the `InternPool`.
1946 pub fn padding(self: LoadedUnionType, ip: *const InternPool) *u32 {2382 pub fn padding(self: LoadedUnionType, ip: *const InternPool) *u32 {
2383 const extra = ip.getLocalShared(self.tid).extra.acquire();
1947 const field_index = std.meta.fieldIndex(Tag.TypeUnion, "padding").?;2384 const field_index = std.meta.fieldIndex(Tag.TypeUnion, "padding").?;
1948 return &ip.extra.items[self.extra_index + field_index];2385 return &extra.view().items(.@"0")[self.extra_index + field_index];
1949 }2386 }
19502387
1951 pub fn hasTag(self: LoadedUnionType, ip: *const InternPool) bool {2388 pub fn hasTag(self: LoadedUnionType, ip: *const InternPool) bool {
...@@ -1974,7 +2411,7 @@ pub const LoadedUnionType = struct {...@@ -1974,7 +2411,7 @@ pub const LoadedUnionType = struct {
1974 const flags_field_index = std.meta.fieldIndex(Tag.TypeUnion, "flags").?;2411 const flags_field_index = std.meta.fieldIndex(Tag.TypeUnion, "flags").?;
1975 const zir_index_field_index = std.meta.fieldIndex(Tag.TypeUnion, "zir_index").?;2412 const zir_index_field_index = std.meta.fieldIndex(Tag.TypeUnion, "zir_index").?;
1976 const ptr: *TrackedInst.Index.Optional =2413 const ptr: *TrackedInst.Index.Optional =
1977 @ptrCast(&ip.extra.items[self.flags_index - flags_field_index + zir_index_field_index]);2414 @ptrCast(&ip.extra_.items[self.flags_index - flags_field_index + zir_index_field_index]);
1978 ptr.* = new_zir_index;2415 ptr.* = new_zir_index;
1979 }2416 }
19802417
...@@ -1990,18 +2427,21 @@ pub const LoadedUnionType = struct {...@@ -1990,18 +2427,21 @@ pub const LoadedUnionType = struct {
1990};2427};
19912428
1992pub fn loadUnionType(ip: *const InternPool, index: Index) LoadedUnionType {2429pub fn loadUnionType(ip: *const InternPool, index: Index) LoadedUnionType {
1993 const data = ip.items.items(.data)[@intFromEnum(index)];2430 const unwrapped_index = index.unwrap(ip);
1994 const type_union = ip.extraDataTrail(Tag.TypeUnion, data);2431 const extra_list = unwrapped_index.getExtra(ip);
2432 const data = unwrapped_index.getData(ip);
2433 const type_union = extraDataTrail(extra_list, Tag.TypeUnion, data);
1995 const fields_len = type_union.data.fields_len;2434 const fields_len = type_union.data.fields_len;
19962435
1997 var extra_index = type_union.end;2436 var extra_index = type_union.end;
1998 const captures_len = if (type_union.data.flags.any_captures) c: {2437 const captures_len = if (type_union.data.flags.any_captures) c: {
1999 const len = ip.extra.items[extra_index];2438 const len = extra_list.view().items(.@"0")[extra_index];
2000 extra_index += 1;2439 extra_index += 1;
2001 break :c len;2440 break :c len;
2002 } else 0;2441 } else 0;
20032442
2004 const captures: CaptureValue.Slice = .{2443 const captures: CaptureValue.Slice = .{
2444 .tid = unwrapped_index.tid,
2005 .start = extra_index,2445 .start = extra_index,
2006 .len = captures_len,2446 .len = captures_len,
2007 };2447 };
...@@ -2011,21 +2451,24 @@ pub fn loadUnionType(ip: *const InternPool, index: Index) LoadedUnionType {...@@ -2011,21 +2451,24 @@ pub fn loadUnionType(ip: *const InternPool, index: Index) LoadedUnionType {
2011 }2451 }
20122452
2013 const field_types: Index.Slice = .{2453 const field_types: Index.Slice = .{
2454 .tid = unwrapped_index.tid,
2014 .start = extra_index,2455 .start = extra_index,
2015 .len = fields_len,2456 .len = fields_len,
2016 };2457 };
2017 extra_index += fields_len;2458 extra_index += fields_len;
20182459
2019 const field_aligns: Alignment.Slice = if (type_union.data.flags.any_aligned_fields) a: {2460 const field_aligns = if (type_union.data.flags.any_aligned_fields) a: {
2020 const a: Alignment.Slice = .{2461 const a: Alignment.Slice = .{
2462 .tid = unwrapped_index.tid,
2021 .start = extra_index,2463 .start = extra_index,
2022 .len = fields_len,2464 .len = fields_len,
2023 };2465 };
2024 extra_index += std.math.divCeil(u32, fields_len, 4) catch unreachable;2466 extra_index += std.math.divCeil(u32, fields_len, 4) catch unreachable;
2025 break :a a;2467 break :a a;
2026 } else .{ .start = 0, .len = 0 };2468 } else Alignment.Slice.empty;
20272469
2028 return .{2470 return .{
2471 .tid = unwrapped_index.tid,
2029 .extra_index = data,2472 .extra_index = data,
2030 .decl = type_union.data.decl,2473 .decl = type_union.data.decl,
2031 .namespace = type_union.data.namespace,2474 .namespace = type_union.data.namespace,
...@@ -2038,6 +2481,7 @@ pub fn loadUnionType(ip: *const InternPool, index: Index) LoadedUnionType {...@@ -2038,6 +2481,7 @@ pub fn loadUnionType(ip: *const InternPool, index: Index) LoadedUnionType {
2038}2481}
20392482
2040pub const LoadedStructType = struct {2483pub const LoadedStructType = struct {
2484 tid: Zcu.PerThread.Id,
2041 /// The index of the `Tag.TypeStruct` or `Tag.TypeStructPacked` payload.2485 /// The index of the `Tag.TypeStruct` or `Tag.TypeStructPacked` payload.
2042 extra_index: u32,2486 extra_index: u32,
2043 /// The struct's owner Decl. `none` when the struct is `@TypeOf(.{})`.2487 /// The struct's owner Decl. `none` when the struct is `@TypeOf(.{})`.
...@@ -2059,12 +2503,16 @@ pub const LoadedStructType = struct {...@@ -2059,12 +2503,16 @@ pub const LoadedStructType = struct {
2059 captures: CaptureValue.Slice,2503 captures: CaptureValue.Slice,
20602504
2061 pub const ComptimeBits = struct {2505 pub const ComptimeBits = struct {
2506 tid: Zcu.PerThread.Id,
2062 start: u32,2507 start: u32,
2063 /// This is the number of u32 elements, not the number of struct fields.2508 /// This is the number of u32 elements, not the number of struct fields.
2064 len: u32,2509 len: u32,
20652510
2511 pub const empty: ComptimeBits = .{ .tid = .main, .start = 0, .len = 0 };
2512
2066 pub fn get(this: ComptimeBits, ip: *const InternPool) []u32 {2513 pub fn get(this: ComptimeBits, ip: *const InternPool) []u32 {
2067 return ip.extra.items[this.start..][0..this.len];2514 const extra = ip.getLocalShared(this.tid).extra.acquire();
2515 return extra.view().items(.@"0")[this.start..][0..this.len];
2068 }2516 }
20692517
2070 pub fn getBit(this: ComptimeBits, ip: *const InternPool, i: usize) bool {2518 pub fn getBit(this: ComptimeBits, ip: *const InternPool, i: usize) bool {
...@@ -2082,11 +2530,15 @@ pub const LoadedStructType = struct {...@@ -2082,11 +2530,15 @@ pub const LoadedStructType = struct {
2082 };2530 };
20832531
2084 pub const Offsets = struct {2532 pub const Offsets = struct {
2533 tid: Zcu.PerThread.Id,
2085 start: u32,2534 start: u32,
2086 len: u32,2535 len: u32,
20872536
2537 pub const empty: Offsets = .{ .tid = .main, .start = 0, .len = 0 };
2538
2088 pub fn get(this: Offsets, ip: *const InternPool) []u32 {2539 pub fn get(this: Offsets, ip: *const InternPool) []u32 {
2089 return @ptrCast(ip.extra.items[this.start..][0..this.len]);2540 const extra = ip.getLocalShared(this.tid).extra.acquire();
2541 return @ptrCast(extra.view().items(.@"0")[this.start..][0..this.len]);
2090 }2542 }
2091 };2543 };
20922544
...@@ -2098,11 +2550,15 @@ pub const LoadedStructType = struct {...@@ -2098,11 +2550,15 @@ pub const LoadedStructType = struct {
2098 _,2550 _,
20992551
2100 pub const Slice = struct {2552 pub const Slice = struct {
2553 tid: Zcu.PerThread.Id,
2101 start: u32,2554 start: u32,
2102 len: u32,2555 len: u32,
21032556
2557 pub const empty: Slice = .{ .tid = .main, .start = 0, .len = 0 };
2558
2104 pub fn get(slice: RuntimeOrder.Slice, ip: *const InternPool) []RuntimeOrder {2559 pub fn get(slice: RuntimeOrder.Slice, ip: *const InternPool) []RuntimeOrder {
2105 return @ptrCast(ip.extra.items[slice.start..][0..slice.len]);2560 const extra = ip.getLocalShared(slice.tid).extra.acquire();
2561 return @ptrCast(extra.view().items(.@"0")[slice.start..][0..slice.len]);
2106 }2562 }
2107 };2563 };
21082564
...@@ -2134,7 +2590,8 @@ pub const LoadedStructType = struct {...@@ -2134,7 +2590,8 @@ pub const LoadedStructType = struct {
2134 ip: *InternPool,2590 ip: *InternPool,
2135 name: NullTerminatedString,2591 name: NullTerminatedString,
2136 ) ?u32 {2592 ) ?u32 {
2137 return ip.addFieldName(self.names_map.unwrap().?, self.field_names.start, name);2593 const extra = ip.getLocalShared(self.tid).extra.acquire();
2594 return ip.addFieldName(extra, self.names_map.unwrap().?, self.field_names.start, name);
2138 }2595 }
21392596
2140 pub fn fieldAlign(s: LoadedStructType, ip: *const InternPool, i: usize) Alignment {2597 pub fn fieldAlign(s: LoadedStructType, ip: *const InternPool, i: usize) Alignment {
...@@ -2142,7 +2599,7 @@ pub const LoadedStructType = struct {...@@ -2142,7 +2599,7 @@ pub const LoadedStructType = struct {
2142 return s.field_aligns.get(ip)[i];2599 return s.field_aligns.get(ip)[i];
2143 }2600 }
21442601
2145 pub fn fieldInit(s: LoadedStructType, ip: *const InternPool, i: usize) Index {2602 pub fn fieldInit(s: LoadedStructType, ip: *InternPool, i: usize) Index {
2146 if (s.field_inits.len == 0) return .none;2603 if (s.field_inits.len == 0) return .none;
2147 assert(s.haveFieldInits(ip));2604 assert(s.haveFieldInits(ip));
2148 return s.field_inits.get(ip)[i];2605 return s.field_inits.get(ip)[i];
...@@ -2173,18 +2630,20 @@ pub const LoadedStructType = struct {...@@ -2173,18 +2630,20 @@ pub const LoadedStructType = struct {
21732630
2174 /// The returned pointer expires with any addition to the `InternPool`.2631 /// The returned pointer expires with any addition to the `InternPool`.
2175 /// Asserts the struct is not packed.2632 /// Asserts the struct is not packed.
2176 pub fn flagsPtr(self: LoadedStructType, ip: *const InternPool) *Tag.TypeStruct.Flags {2633 pub fn flagsPtr(self: LoadedStructType, ip: *InternPool) *Tag.TypeStruct.Flags {
2177 assert(self.layout != .@"packed");2634 assert(self.layout != .@"packed");
2635 const extra = ip.getLocalShared(self.tid).extra.acquire();
2178 const flags_field_index = std.meta.fieldIndex(Tag.TypeStruct, "flags").?;2636 const flags_field_index = std.meta.fieldIndex(Tag.TypeStruct, "flags").?;
2179 return @ptrCast(&ip.extra.items[self.extra_index + flags_field_index]);2637 return @ptrCast(&extra.view().items(.@"0")[self.extra_index + flags_field_index]);
2180 }2638 }
21812639
2182 /// The returned pointer expires with any addition to the `InternPool`.2640 /// The returned pointer expires with any addition to the `InternPool`.
2183 /// Asserts that the struct is packed.2641 /// Asserts that the struct is packed.
2184 pub fn packedFlagsPtr(self: LoadedStructType, ip: *const InternPool) *Tag.TypeStructPacked.Flags {2642 pub fn packedFlagsPtr(self: LoadedStructType, ip: *InternPool) *Tag.TypeStructPacked.Flags {
2185 assert(self.layout == .@"packed");2643 assert(self.layout == .@"packed");
2644 const extra = ip.getLocalShared(self.tid).extra.acquire();
2186 const flags_field_index = std.meta.fieldIndex(Tag.TypeStructPacked, "flags").?;2645 const flags_field_index = std.meta.fieldIndex(Tag.TypeStructPacked, "flags").?;
2187 return @ptrCast(&ip.extra.items[self.extra_index + flags_field_index]);2646 return @ptrCast(&extra.view().items(.@"0")[self.extra_index + flags_field_index]);
2188 }2647 }
21892648
2190 pub fn assumeRuntimeBitsIfFieldTypesWip(s: LoadedStructType, ip: *InternPool) bool {2649 pub fn assumeRuntimeBitsIfFieldTypesWip(s: LoadedStructType, ip: *InternPool) bool {
...@@ -2276,25 +2735,27 @@ pub const LoadedStructType = struct {...@@ -2276,25 +2735,27 @@ pub const LoadedStructType = struct {
2276 /// Asserts the struct is not packed.2735 /// Asserts the struct is not packed.
2277 pub fn size(self: LoadedStructType, ip: *InternPool) *u32 {2736 pub fn size(self: LoadedStructType, ip: *InternPool) *u32 {
2278 assert(self.layout != .@"packed");2737 assert(self.layout != .@"packed");
2738 const extra = ip.getLocalShared(self.tid).extra.acquire();
2279 const size_field_index = std.meta.fieldIndex(Tag.TypeStruct, "size").?;2739 const size_field_index = std.meta.fieldIndex(Tag.TypeStruct, "size").?;
2280 return @ptrCast(&ip.extra.items[self.extra_index + size_field_index]);2740 return @ptrCast(&extra.view().items(.@"0")[self.extra_index + size_field_index]);
2281 }2741 }
22822742
2283 /// The backing integer type of the packed struct. Whether zig chooses2743 /// The backing integer type of the packed struct. Whether zig chooses
2284 /// this type or the user specifies it, it is stored here. This will be2744 /// this type or the user specifies it, it is stored here. This will be
2285 /// set to `none` until the layout is resolved.2745 /// set to `none` until the layout is resolved.
2286 /// Asserts the struct is packed.2746 /// Asserts the struct is packed.
2287 pub fn backingIntType(s: LoadedStructType, ip: *const InternPool) *Index {2747 pub fn backingIntType(s: LoadedStructType, ip: *InternPool) *Index {
2288 assert(s.layout == .@"packed");2748 assert(s.layout == .@"packed");
2749 const extra = ip.getLocalShared(s.tid).extra.acquire();
2289 const field_index = std.meta.fieldIndex(Tag.TypeStructPacked, "backing_int_ty").?;2750 const field_index = std.meta.fieldIndex(Tag.TypeStructPacked, "backing_int_ty").?;
2290 return @ptrCast(&ip.extra.items[s.extra_index + field_index]);2751 return @ptrCast(&extra.view().items(.@"0")[s.extra_index + field_index]);
2291 }2752 }
22922753
2293 /// Asserts the struct is not packed.2754 /// Asserts the struct is not packed.
2294 pub fn setZirIndex(s: LoadedStructType, ip: *InternPool, new_zir_index: TrackedInst.Index.Optional) void {2755 pub fn setZirIndex(s: LoadedStructType, ip: *InternPool, new_zir_index: TrackedInst.Index.Optional) void {
2295 assert(s.layout != .@"packed");2756 assert(s.layout != .@"packed");
2296 const field_index = std.meta.fieldIndex(Tag.TypeStruct, "zir_index").?;2757 const field_index = std.meta.fieldIndex(Tag.TypeStruct, "zir_index").?;
2297 ip.extra.items[s.extra_index + field_index] = @intFromEnum(new_zir_index);2758 ip.extra_.items[s.extra_index + field_index] = @intFromEnum(new_zir_index);
2298 }2759 }
22992760
2300 pub fn haveFieldTypes(s: LoadedStructType, ip: *const InternPool) bool {2761 pub fn haveFieldTypes(s: LoadedStructType, ip: *const InternPool) bool {
...@@ -2302,7 +2763,7 @@ pub const LoadedStructType = struct {...@@ -2302,7 +2763,7 @@ pub const LoadedStructType = struct {
2302 return types.len == 0 or types[0] != .none;2763 return types.len == 0 or types[0] != .none;
2303 }2764 }
23042765
2305 pub fn haveFieldInits(s: LoadedStructType, ip: *const InternPool) bool {2766 pub fn haveFieldInits(s: LoadedStructType, ip: *InternPool) bool {
2306 return switch (s.layout) {2767 return switch (s.layout) {
2307 .@"packed" => s.packedFlagsPtr(ip).inits_resolved,2768 .@"packed" => s.packedFlagsPtr(ip).inits_resolved,
2308 .auto, .@"extern" => s.flagsPtr(ip).inits_resolved,2769 .auto, .@"extern" => s.flagsPtr(ip).inits_resolved,
...@@ -2412,34 +2873,38 @@ pub const LoadedStructType = struct {...@@ -2412,34 +2873,38 @@ pub const LoadedStructType = struct {
2412};2873};
24132874
2414pub fn loadStructType(ip: *const InternPool, index: Index) LoadedStructType {2875pub fn loadStructType(ip: *const InternPool, index: Index) LoadedStructType {
2415 const item = ip.items.get(@intFromEnum(index));2876 const unwrapped_index = index.unwrap(ip);
2877 const extra_list = unwrapped_index.getExtra(ip);
2878 const item = unwrapped_index.getItem(ip);
2416 switch (item.tag) {2879 switch (item.tag) {
2417 .type_struct => {2880 .type_struct => {
2418 if (item.data == 0) return .{2881 if (item.data == 0) return .{
2882 .tid = .main,
2419 .extra_index = 0,2883 .extra_index = 0,
2420 .decl = .none,2884 .decl = .none,
2421 .namespace = .none,2885 .namespace = .none,
2422 .zir_index = .none,2886 .zir_index = .none,
2423 .layout = .auto,2887 .layout = .auto,
2424 .field_names = .{ .start = 0, .len = 0 },2888 .field_names = NullTerminatedString.Slice.empty,
2425 .field_types = .{ .start = 0, .len = 0 },2889 .field_types = Index.Slice.empty,
2426 .field_inits = .{ .start = 0, .len = 0 },2890 .field_inits = Index.Slice.empty,
2427 .field_aligns = .{ .start = 0, .len = 0 },2891 .field_aligns = Alignment.Slice.empty,
2428 .runtime_order = .{ .start = 0, .len = 0 },2892 .runtime_order = LoadedStructType.RuntimeOrder.Slice.empty,
2429 .comptime_bits = .{ .start = 0, .len = 0 },2893 .comptime_bits = LoadedStructType.ComptimeBits.empty,
2430 .offsets = .{ .start = 0, .len = 0 },2894 .offsets = LoadedStructType.Offsets.empty,
2431 .names_map = .none,2895 .names_map = .none,
2432 .captures = .{ .start = 0, .len = 0 },2896 .captures = CaptureValue.Slice.empty,
2433 };2897 };
2434 const extra = ip.extraDataTrail(Tag.TypeStruct, item.data);2898 const extra = extraDataTrail(extra_list, Tag.TypeStruct, item.data);
2435 const fields_len = extra.data.fields_len;2899 const fields_len = extra.data.fields_len;
2436 var extra_index = extra.end;2900 var extra_index = extra.end;
2437 const captures_len = if (extra.data.flags.any_captures) c: {2901 const captures_len = if (extra.data.flags.any_captures) c: {
2438 const len = ip.extra.items[extra_index];2902 const len = extra_list.view().items(.@"0")[extra_index];
2439 extra_index += 1;2903 extra_index += 1;
2440 break :c len;2904 break :c len;
2441 } else 0;2905 } else 0;
2442 const captures: CaptureValue.Slice = .{2906 const captures: CaptureValue.Slice = .{
2907 .tid = unwrapped_index.tid,
2443 .start = extra_index,2908 .start = extra_index,
2444 .len = captures_len,2909 .len = captures_len,
2445 };2910 };
...@@ -2448,49 +2913,75 @@ pub fn loadStructType(ip: *const InternPool, index: Index) LoadedStructType {...@@ -2448,49 +2913,75 @@ pub fn loadStructType(ip: *const InternPool, index: Index) LoadedStructType {
2448 extra_index += 2; // PackedU642913 extra_index += 2; // PackedU64
2449 }2914 }
2450 const field_types: Index.Slice = .{2915 const field_types: Index.Slice = .{
2916 .tid = unwrapped_index.tid,
2451 .start = extra_index,2917 .start = extra_index,
2452 .len = fields_len,2918 .len = fields_len,
2453 };2919 };
2454 extra_index += fields_len;2920 extra_index += fields_len;
2455 const names_map: OptionalMapIndex, const names: NullTerminatedString.Slice = if (!extra.data.flags.is_tuple) n: {2921 const names_map: OptionalMapIndex, const names = if (!extra.data.flags.is_tuple) n: {
2456 const names_map: OptionalMapIndex = @enumFromInt(ip.extra.items[extra_index]);2922 const names_map: OptionalMapIndex = @enumFromInt(extra_list.view().items(.@"0")[extra_index]);
2457 extra_index += 1;2923 extra_index += 1;
2458 const names: NullTerminatedString.Slice = .{ .start = extra_index, .len = fields_len };2924 const names: NullTerminatedString.Slice = .{
2925 .tid = unwrapped_index.tid,
2926 .start = extra_index,
2927 .len = fields_len,
2928 };
2459 extra_index += fields_len;2929 extra_index += fields_len;
2460 break :n .{ names_map, names };2930 break :n .{ names_map, names };
2461 } else .{ .none, .{ .start = 0, .len = 0 } };2931 } else .{ .none, NullTerminatedString.Slice.empty };
2462 const inits: Index.Slice = if (extra.data.flags.any_default_inits) i: {2932 const inits: Index.Slice = if (extra.data.flags.any_default_inits) i: {
2463 const inits: Index.Slice = .{ .start = extra_index, .len = fields_len };2933 const inits: Index.Slice = .{
2934 .tid = unwrapped_index.tid,
2935 .start = extra_index,
2936 .len = fields_len,
2937 };
2464 extra_index += fields_len;2938 extra_index += fields_len;
2465 break :i inits;2939 break :i inits;
2466 } else .{ .start = 0, .len = 0 };2940 } else Index.Slice.empty;
2467 const namespace: OptionalNamespaceIndex = if (extra.data.flags.has_namespace) n: {2941 const namespace: OptionalNamespaceIndex = if (extra.data.flags.has_namespace) n: {
2468 const n: NamespaceIndex = @enumFromInt(ip.extra.items[extra_index]);2942 const n: NamespaceIndex = @enumFromInt(extra_list.view().items(.@"0")[extra_index]);
2469 extra_index += 1;2943 extra_index += 1;
2470 break :n n.toOptional();2944 break :n n.toOptional();
2471 } else .none;2945 } else .none;
2472 const aligns: Alignment.Slice = if (extra.data.flags.any_aligned_fields) a: {2946 const aligns: Alignment.Slice = if (extra.data.flags.any_aligned_fields) a: {
2473 const a: Alignment.Slice = .{ .start = extra_index, .len = fields_len };2947 const a: Alignment.Slice = .{
2948 .tid = unwrapped_index.tid,
2949 .start = extra_index,
2950 .len = fields_len,
2951 };
2474 extra_index += std.math.divCeil(u32, fields_len, 4) catch unreachable;2952 extra_index += std.math.divCeil(u32, fields_len, 4) catch unreachable;
2475 break :a a;2953 break :a a;
2476 } else .{ .start = 0, .len = 0 };2954 } else Alignment.Slice.empty;
2477 const comptime_bits: LoadedStructType.ComptimeBits = if (extra.data.flags.any_comptime_fields) c: {2955 const comptime_bits: LoadedStructType.ComptimeBits = if (extra.data.flags.any_comptime_fields) c: {
2478 const len = std.math.divCeil(u32, fields_len, 32) catch unreachable;2956 const len = std.math.divCeil(u32, fields_len, 32) catch unreachable;
2479 const c: LoadedStructType.ComptimeBits = .{ .start = extra_index, .len = len };2957 const c: LoadedStructType.ComptimeBits = .{
2958 .tid = unwrapped_index.tid,
2959 .start = extra_index,
2960 .len = len,
2961 };
2480 extra_index += len;2962 extra_index += len;
2481 break :c c;2963 break :c c;
2482 } else .{ .start = 0, .len = 0 };2964 } else LoadedStructType.ComptimeBits.empty;
2483 const runtime_order: LoadedStructType.RuntimeOrder.Slice = if (!extra.data.flags.is_extern) ro: {2965 const runtime_order: LoadedStructType.RuntimeOrder.Slice = if (!extra.data.flags.is_extern) ro: {
2484 const ro: LoadedStructType.RuntimeOrder.Slice = .{ .start = extra_index, .len = fields_len };2966 const ro: LoadedStructType.RuntimeOrder.Slice = .{
2967 .tid = unwrapped_index.tid,
2968 .start = extra_index,
2969 .len = fields_len,
2970 };
2485 extra_index += fields_len;2971 extra_index += fields_len;
2486 break :ro ro;2972 break :ro ro;
2487 } else .{ .start = 0, .len = 0 };2973 } else LoadedStructType.RuntimeOrder.Slice.empty;
2488 const offsets: LoadedStructType.Offsets = o: {2974 const offsets: LoadedStructType.Offsets = o: {
2489 const o: LoadedStructType.Offsets = .{ .start = extra_index, .len = fields_len };2975 const o: LoadedStructType.Offsets = .{
2976 .tid = unwrapped_index.tid,
2977 .start = extra_index,
2978 .len = fields_len,
2979 };
2490 extra_index += fields_len;2980 extra_index += fields_len;
2491 break :o o;2981 break :o o;
2492 };2982 };
2493 return .{2983 return .{
2984 .tid = unwrapped_index.tid,
2494 .extra_index = item.data,2985 .extra_index = item.data,
2495 .decl = extra.data.decl.toOptional(),2986 .decl = extra.data.decl.toOptional(),
2496 .namespace = namespace,2987 .namespace = namespace,
...@@ -2508,16 +2999,17 @@ pub fn loadStructType(ip: *const InternPool, index: Index) LoadedStructType {...@@ -2508,16 +2999,17 @@ pub fn loadStructType(ip: *const InternPool, index: Index) LoadedStructType {
2508 };2999 };
2509 },3000 },
2510 .type_struct_packed, .type_struct_packed_inits => {3001 .type_struct_packed, .type_struct_packed_inits => {
2511 const extra = ip.extraDataTrail(Tag.TypeStructPacked, item.data);3002 const extra = extraDataTrail(extra_list, Tag.TypeStructPacked, item.data);
2512 const has_inits = item.tag == .type_struct_packed_inits;3003 const has_inits = item.tag == .type_struct_packed_inits;
2513 const fields_len = extra.data.fields_len;3004 const fields_len = extra.data.fields_len;
2514 var extra_index = extra.end;3005 var extra_index = extra.end;
2515 const captures_len = if (extra.data.flags.any_captures) c: {3006 const captures_len = if (extra.data.flags.any_captures) c: {
2516 const len = ip.extra.items[extra_index];3007 const len = extra_list.view().items(.@"0")[extra_index];
2517 extra_index += 1;3008 extra_index += 1;
2518 break :c len;3009 break :c len;
2519 } else 0;3010 } else 0;
2520 const captures: CaptureValue.Slice = .{3011 const captures: CaptureValue.Slice = .{
3012 .tid = unwrapped_index.tid,
2521 .start = extra_index,3013 .start = extra_index,
2522 .len = captures_len,3014 .len = captures_len,
2523 };3015 };
...@@ -2526,24 +3018,28 @@ pub fn loadStructType(ip: *const InternPool, index: Index) LoadedStructType {...@@ -2526,24 +3018,28 @@ pub fn loadStructType(ip: *const InternPool, index: Index) LoadedStructType {
2526 extra_index += 2; // PackedU643018 extra_index += 2; // PackedU64
2527 }3019 }
2528 const field_types: Index.Slice = .{3020 const field_types: Index.Slice = .{
3021 .tid = unwrapped_index.tid,
2529 .start = extra_index,3022 .start = extra_index,
2530 .len = fields_len,3023 .len = fields_len,
2531 };3024 };
2532 extra_index += fields_len;3025 extra_index += fields_len;
2533 const field_names: NullTerminatedString.Slice = .{3026 const field_names: NullTerminatedString.Slice = .{
3027 .tid = unwrapped_index.tid,
2534 .start = extra_index,3028 .start = extra_index,
2535 .len = fields_len,3029 .len = fields_len,
2536 };3030 };
2537 extra_index += fields_len;3031 extra_index += fields_len;
2538 const field_inits: Index.Slice = if (has_inits) inits: {3032 const field_inits: Index.Slice = if (has_inits) inits: {
2539 const i: Index.Slice = .{3033 const i: Index.Slice = .{
3034 .tid = unwrapped_index.tid,
2540 .start = extra_index,3035 .start = extra_index,
2541 .len = fields_len,3036 .len = fields_len,
2542 };3037 };
2543 extra_index += fields_len;3038 extra_index += fields_len;
2544 break :inits i;3039 break :inits i;
2545 } else .{ .start = 0, .len = 0 };3040 } else Index.Slice.empty;
2546 return .{3041 return .{
3042 .tid = unwrapped_index.tid,
2547 .extra_index = item.data,3043 .extra_index = item.data,
2548 .decl = extra.data.decl.toOptional(),3044 .decl = extra.data.decl.toOptional(),
2549 .namespace = extra.data.namespace,3045 .namespace = extra.data.namespace,
...@@ -2552,10 +3048,10 @@ pub fn loadStructType(ip: *const InternPool, index: Index) LoadedStructType {...@@ -2552,10 +3048,10 @@ pub fn loadStructType(ip: *const InternPool, index: Index) LoadedStructType {
2552 .field_names = field_names,3048 .field_names = field_names,
2553 .field_types = field_types,3049 .field_types = field_types,
2554 .field_inits = field_inits,3050 .field_inits = field_inits,
2555 .field_aligns = .{ .start = 0, .len = 0 },3051 .field_aligns = Alignment.Slice.empty,
2556 .runtime_order = .{ .start = 0, .len = 0 },3052 .runtime_order = LoadedStructType.RuntimeOrder.Slice.empty,
2557 .comptime_bits = .{ .start = 0, .len = 0 },3053 .comptime_bits = LoadedStructType.ComptimeBits.empty,
2558 .offsets = .{ .start = 0, .len = 0 },3054 .offsets = LoadedStructType.Offsets.empty,
2559 .names_map = extra.data.names_map.toOptional(),3055 .names_map = extra.data.names_map.toOptional(),
2560 .captures = captures,3056 .captures = captures,
2561 };3057 };
...@@ -2636,10 +3132,12 @@ const LoadedEnumType = struct {...@@ -2636,10 +3132,12 @@ const LoadedEnumType = struct {
2636};3132};
26373133
2638pub fn loadEnumType(ip: *const InternPool, index: Index) LoadedEnumType {3134pub fn loadEnumType(ip: *const InternPool, index: Index) LoadedEnumType {
2639 const item = ip.items.get(@intFromEnum(index));3135 const unwrapped_index = index.unwrap(ip);
3136 const extra_list = unwrapped_index.getExtra(ip);
3137 const item = unwrapped_index.getItem(ip);
2640 const tag_mode: LoadedEnumType.TagMode = switch (item.tag) {3138 const tag_mode: LoadedEnumType.TagMode = switch (item.tag) {
2641 .type_enum_auto => {3139 .type_enum_auto => {
2642 const extra = ip.extraDataTrail(EnumAuto, item.data);3140 const extra = extraDataTrail(extra_list, EnumAuto, item.data);
2643 var extra_index: u32 = @intCast(extra.end);3141 var extra_index: u32 = @intCast(extra.end);
2644 if (extra.data.zir_index == .none) {3142 if (extra.data.zir_index == .none) {
2645 extra_index += 1; // owner_union3143 extra_index += 1; // owner_union
...@@ -2653,15 +3151,17 @@ pub fn loadEnumType(ip: *const InternPool, index: Index) LoadedEnumType {...@@ -2653,15 +3151,17 @@ pub fn loadEnumType(ip: *const InternPool, index: Index) LoadedEnumType {
2653 .namespace = extra.data.namespace,3151 .namespace = extra.data.namespace,
2654 .tag_ty = extra.data.int_tag_type,3152 .tag_ty = extra.data.int_tag_type,
2655 .names = .{3153 .names = .{
3154 .tid = unwrapped_index.tid,
2656 .start = extra_index + captures_len,3155 .start = extra_index + captures_len,
2657 .len = extra.data.fields_len,3156 .len = extra.data.fields_len,
2658 },3157 },
2659 .values = .{ .start = 0, .len = 0 },3158 .values = Index.Slice.empty,
2660 .tag_mode = .auto,3159 .tag_mode = .auto,
2661 .names_map = extra.data.names_map,3160 .names_map = extra.data.names_map,
2662 .values_map = .none,3161 .values_map = .none,
2663 .zir_index = extra.data.zir_index,3162 .zir_index = extra.data.zir_index,
2664 .captures = .{3163 .captures = .{
3164 .tid = unwrapped_index.tid,
2665 .start = extra_index,3165 .start = extra_index,
2666 .len = captures_len,3166 .len = captures_len,
2667 },3167 },
...@@ -2671,7 +3171,7 @@ pub fn loadEnumType(ip: *const InternPool, index: Index) LoadedEnumType {...@@ -2671,7 +3171,7 @@ pub fn loadEnumType(ip: *const InternPool, index: Index) LoadedEnumType {
2671 .type_enum_nonexhaustive => .nonexhaustive,3171 .type_enum_nonexhaustive => .nonexhaustive,
2672 else => unreachable,3172 else => unreachable,
2673 };3173 };
2674 const extra = ip.extraDataTrail(EnumExplicit, item.data);3174 const extra = extraDataTrail(extra_list, EnumExplicit, item.data);
2675 var extra_index: u32 = @intCast(extra.end);3175 var extra_index: u32 = @intCast(extra.end);
2676 if (extra.data.zir_index == .none) {3176 if (extra.data.zir_index == .none) {
2677 extra_index += 1; // owner_union3177 extra_index += 1; // owner_union
...@@ -2685,10 +3185,12 @@ pub fn loadEnumType(ip: *const InternPool, index: Index) LoadedEnumType {...@@ -2685,10 +3185,12 @@ pub fn loadEnumType(ip: *const InternPool, index: Index) LoadedEnumType {
2685 .namespace = extra.data.namespace,3185 .namespace = extra.data.namespace,
2686 .tag_ty = extra.data.int_tag_type,3186 .tag_ty = extra.data.int_tag_type,
2687 .names = .{3187 .names = .{
3188 .tid = unwrapped_index.tid,
2688 .start = extra_index + captures_len,3189 .start = extra_index + captures_len,
2689 .len = extra.data.fields_len,3190 .len = extra.data.fields_len,
2690 },3191 },
2691 .values = .{3192 .values = .{
3193 .tid = unwrapped_index.tid,
2692 .start = extra_index + captures_len + extra.data.fields_len,3194 .start = extra_index + captures_len + extra.data.fields_len,
2693 .len = if (extra.data.values_map != .none) extra.data.fields_len else 0,3195 .len = if (extra.data.values_map != .none) extra.data.fields_len else 0,
2694 },3196 },
...@@ -2697,6 +3199,7 @@ pub fn loadEnumType(ip: *const InternPool, index: Index) LoadedEnumType {...@@ -2697,6 +3199,7 @@ pub fn loadEnumType(ip: *const InternPool, index: Index) LoadedEnumType {
2697 .values_map = extra.data.values_map,3199 .values_map = extra.data.values_map,
2698 .zir_index = extra.data.zir_index,3200 .zir_index = extra.data.zir_index,
2699 .captures = .{3201 .captures = .{
3202 .tid = unwrapped_index.tid,
2700 .start = extra_index,3203 .start = extra_index,
2701 .len = captures_len,3204 .len = captures_len,
2702 },3205 },
...@@ -2715,9 +3218,10 @@ pub const LoadedOpaqueType = struct {...@@ -2715,9 +3218,10 @@ pub const LoadedOpaqueType = struct {
2715};3218};
27163219
2717pub fn loadOpaqueType(ip: *const InternPool, index: Index) LoadedOpaqueType {3220pub fn loadOpaqueType(ip: *const InternPool, index: Index) LoadedOpaqueType {
2718 assert(ip.items.items(.tag)[@intFromEnum(index)] == .type_opaque);3221 const unwrapped_index = index.unwrap(ip);
2719 const extra_index = ip.items.items(.data)[@intFromEnum(index)];3222 const item = unwrapped_index.getItem(ip);
2720 const extra = ip.extraDataTrail(Tag.TypeOpaque, extra_index);3223 assert(item.tag == .type_opaque);
3224 const extra = extraDataTrail(unwrapped_index.getExtra(ip), Tag.TypeOpaque, item.data);
2721 const captures_len = if (extra.data.captures_len == std.math.maxInt(u32))3225 const captures_len = if (extra.data.captures_len == std.math.maxInt(u32))
2722 03226 0
2723 else3227 else
...@@ -2727,6 +3231,7 @@ pub fn loadOpaqueType(ip: *const InternPool, index: Index) LoadedOpaqueType {...@@ -2727,6 +3231,7 @@ pub fn loadOpaqueType(ip: *const InternPool, index: Index) LoadedOpaqueType {
2727 .namespace = extra.data.namespace,3231 .namespace = extra.data.namespace,
2728 .zir_index = extra.data.zir_index,3232 .zir_index = extra.data.zir_index,
2729 .captures = .{3233 .captures = .{
3234 .tid = unwrapped_index.tid,
2730 .start = extra.end,3235 .start = extra.end,
2731 .len = captures_len,3236 .len = captures_len,
2732 },3237 },
...@@ -2869,11 +3374,15 @@ pub const Index = enum(u32) {...@@ -2869,11 +3374,15 @@ pub const Index = enum(u32) {
2869 /// This type exists to provide a struct with lifetime that is3374 /// This type exists to provide a struct with lifetime that is
2870 /// not invalidated when items are added to the `InternPool`.3375 /// not invalidated when items are added to the `InternPool`.
2871 pub const Slice = struct {3376 pub const Slice = struct {
3377 tid: Zcu.PerThread.Id,
2872 start: u32,3378 start: u32,
2873 len: u32,3379 len: u32,
28743380
3381 pub const empty: Slice = .{ .tid = .main, .start = 0, .len = 0 };
3382
2875 pub fn get(slice: Slice, ip: *const InternPool) []Index {3383 pub fn get(slice: Slice, ip: *const InternPool) []Index {
2876 return @ptrCast(ip.extra.items[slice.start..][0..slice.len]);3384 const extra = ip.getLocalShared(slice.tid).extra.acquire();
3385 return @ptrCast(extra.view().items(.@"0")[slice.start..][0..slice.len]);
2877 }3386 }
2878 };3387 };
28793388
...@@ -2892,6 +3401,57 @@ pub const Index = enum(u32) {...@@ -2892,6 +3401,57 @@ pub const Index = enum(u32) {
2892 }3401 }
2893 };3402 };
28943403
3404 const Unwrapped = struct {
3405 tid: Zcu.PerThread.Id,
3406 index: u32,
3407
3408 fn wrap(unwrapped: Unwrapped, ip: *const InternPool) Index {
3409 assert(@intFromEnum(unwrapped.tid) <= ip.getTidMask());
3410 assert(unwrapped.index <= ip.getIndexMask(u31));
3411 return @enumFromInt(@as(u32, @intFromEnum(unwrapped.tid)) << ip.tid_shift_31 | unwrapped.index);
3412 }
3413
3414 pub fn getExtra(unwrapped: Unwrapped, ip: *const InternPool) Local.Extra {
3415 return ip.getLocalShared(unwrapped.tid).extra.acquire();
3416 }
3417
3418 pub fn getItem(unwrapped: Unwrapped, ip: *const InternPool) Item {
3419 const item_ptr = unwrapped.itemPtr(ip);
3420 const tag = @atomicLoad(Tag, item_ptr.tag_ptr, .acquire);
3421 return .{ .tag = tag, .data = item_ptr.data_ptr.* };
3422 }
3423
3424 pub fn getTag(unwrapped: Unwrapped, ip: *const InternPool) Tag {
3425 const item_ptr = unwrapped.itemPtr(ip);
3426 return @atomicLoad(Tag, item_ptr.tag_ptr, .acquire);
3427 }
3428
3429 pub fn getData(unwrapped: Unwrapped, ip: *const InternPool) u32 {
3430 return unwrapped.getItem(ip).data;
3431 }
3432
3433 const ItemPtr = struct {
3434 tag_ptr: *Tag,
3435 data_ptr: *u32,
3436 };
3437 fn itemPtr(unwrapped: Unwrapped, ip: *const InternPool) ItemPtr {
3438 const slice = ip.getLocalShared(unwrapped.tid).items.acquire().view().slice();
3439 return .{
3440 .tag_ptr = &slice.items(.tag)[unwrapped.index],
3441 .data_ptr = &slice.items(.data)[unwrapped.index],
3442 };
3443 }
3444 };
3445 pub fn unwrap(index: Index, ip: *const InternPool) Unwrapped {
3446 return if (single_threaded) .{
3447 .tid = .main,
3448 .index = @intFromEnum(index),
3449 } else .{
3450 .tid = @enumFromInt(@intFromEnum(index) >> ip.tid_shift_31 & ip.getTidMask()),
3451 .index = @intFromEnum(index) & ip.getIndexMask(u31),
3452 };
3453 }
3454
2895 /// This function is used in the debugger pretty formatters in tools/ to fetch the3455 /// This function is used in the debugger pretty formatters in tools/ to fetch the
2896 /// Tag to encoding mapping to facilitate fancy debug printing for this type.3456 /// Tag to encoding mapping to facilitate fancy debug printing for this type.
2897 /// TODO merge this with `Tag.Payload`.3457 /// TODO merge this with `Tag.Payload`.
...@@ -2947,7 +3507,7 @@ pub const Index = enum(u32) {...@@ -2947,7 +3507,7 @@ pub const Index = enum(u32) {
2947 },3507 },
2948 type_enum_explicit: DataIsExtraIndexOfEnumExplicit,3508 type_enum_explicit: DataIsExtraIndexOfEnumExplicit,
2949 type_enum_nonexhaustive: DataIsExtraIndexOfEnumExplicit,3509 type_enum_nonexhaustive: DataIsExtraIndexOfEnumExplicit,
2950 simple_type: struct { data: SimpleType },3510 simple_type: void,
2951 type_opaque: struct { data: *Tag.TypeOpaque },3511 type_opaque: struct { data: *Tag.TypeOpaque },
2952 type_struct: struct { data: *Tag.TypeStruct },3512 type_struct: struct { data: *Tag.TypeStruct },
2953 type_struct_anon: DataIsExtraIndexOfTypeStructAnon,3513 type_struct_anon: DataIsExtraIndexOfTypeStructAnon,
...@@ -2967,7 +3527,7 @@ pub const Index = enum(u32) {...@@ -2967,7 +3527,7 @@ pub const Index = enum(u32) {
2967 },3527 },
29683528
2969 undef: DataIsIndex,3529 undef: DataIsIndex,
2970 simple_value: struct { data: SimpleValue },3530 simple_value: void,
2971 ptr_decl: struct { data: *PtrDecl },3531 ptr_decl: struct { data: *PtrDecl },
2972 ptr_comptime_alloc: struct { data: *PtrComptimeAlloc },3532 ptr_comptime_alloc: struct { data: *PtrComptimeAlloc },
2973 ptr_anon_decl: struct { data: *PtrAnonDecl },3533 ptr_anon_decl: struct { data: *PtrAnonDecl },
...@@ -3250,9 +3810,9 @@ pub const static_keys = [_]Key{...@@ -3250,9 +3810,9 @@ pub const static_keys = [_]Key{
32503810
3251 // empty_struct_type3811 // empty_struct_type
3252 .{ .anon_struct_type = .{3812 .{ .anon_struct_type = .{
3253 .types = .{ .start = 0, .len = 0 },3813 .types = Index.Slice.empty,
3254 .names = .{ .start = 0, .len = 0 },3814 .names = NullTerminatedString.Slice.empty,
3255 .values = .{ .start = 0, .len = 0 },3815 .values = Index.Slice.empty,
3256 } },3816 } },
32573817
3258 .{ .simple_value = .undefined },3818 .{ .simple_value = .undefined },
...@@ -3969,7 +4529,7 @@ pub const FuncAnalysis = packed struct(u32) {...@@ -3969,7 +4529,7 @@ pub const FuncAnalysis = packed struct(u32) {
3969pub const Bytes = struct {4529pub const Bytes = struct {
3970 /// The type of the aggregate4530 /// The type of the aggregate
3971 ty: Index,4531 ty: Index,
3972 /// Index into string_bytes, of len ip.aggregateTypeLen(ty)4532 /// Index into strings, of len ip.aggregateTypeLen(ty)
3973 bytes: String,4533 bytes: String,
3974};4534};
39754535
...@@ -3993,64 +4553,64 @@ pub const TypeStructAnon = struct {...@@ -3993,64 +4553,64 @@ pub const TypeStructAnon = struct {
3993/// implement logic that only wants to deal with types because the logic can4553/// implement logic that only wants to deal with types because the logic can
3994/// ignore all simple values. Note that technically, types are values.4554/// ignore all simple values. Note that technically, types are values.
3995pub const SimpleType = enum(u32) {4555pub const SimpleType = enum(u32) {
3996 f16,4556 f16 = @intFromEnum(Index.f16_type),
3997 f32,4557 f32 = @intFromEnum(Index.f32_type),
3998 f64,4558 f64 = @intFromEnum(Index.f64_type),
3999 f80,4559 f80 = @intFromEnum(Index.f80_type),
4000 f128,4560 f128 = @intFromEnum(Index.f128_type),
4001 usize,4561 usize = @intFromEnum(Index.usize_type),
4002 isize,4562 isize = @intFromEnum(Index.isize_type),
4003 c_char,4563 c_char = @intFromEnum(Index.c_char_type),
4004 c_short,4564 c_short = @intFromEnum(Index.c_short_type),
4005 c_ushort,4565 c_ushort = @intFromEnum(Index.c_ushort_type),
4006 c_int,4566 c_int = @intFromEnum(Index.c_int_type),
4007 c_uint,4567 c_uint = @intFromEnum(Index.c_uint_type),
4008 c_long,4568 c_long = @intFromEnum(Index.c_long_type),
4009 c_ulong,4569 c_ulong = @intFromEnum(Index.c_ulong_type),
4010 c_longlong,4570 c_longlong = @intFromEnum(Index.c_longlong_type),
4011 c_ulonglong,4571 c_ulonglong = @intFromEnum(Index.c_ulonglong_type),
4012 c_longdouble,4572 c_longdouble = @intFromEnum(Index.c_longdouble_type),
4013 anyopaque,4573 anyopaque = @intFromEnum(Index.anyopaque_type),
4014 bool,4574 bool = @intFromEnum(Index.bool_type),
4015 void,4575 void = @intFromEnum(Index.void_type),
4016 type,4576 type = @intFromEnum(Index.type_type),
4017 anyerror,4577 anyerror = @intFromEnum(Index.anyerror_type),
4018 comptime_int,4578 comptime_int = @intFromEnum(Index.comptime_int_type),
4019 comptime_float,4579 comptime_float = @intFromEnum(Index.comptime_float_type),
4020 noreturn,4580 noreturn = @intFromEnum(Index.noreturn_type),
4021 null,4581 null = @intFromEnum(Index.null_type),
4022 undefined,4582 undefined = @intFromEnum(Index.undefined_type),
4023 enum_literal,4583 enum_literal = @intFromEnum(Index.enum_literal_type),
40244584
4025 atomic_order,4585 atomic_order = @intFromEnum(Index.atomic_order_type),
4026 atomic_rmw_op,4586 atomic_rmw_op = @intFromEnum(Index.atomic_rmw_op_type),
4027 calling_convention,4587 calling_convention = @intFromEnum(Index.calling_convention_type),
4028 address_space,4588 address_space = @intFromEnum(Index.address_space_type),
4029 float_mode,4589 float_mode = @intFromEnum(Index.float_mode_type),
4030 reduce_op,4590 reduce_op = @intFromEnum(Index.reduce_op_type),
4031 call_modifier,4591 call_modifier = @intFromEnum(Index.call_modifier_type),
4032 prefetch_options,4592 prefetch_options = @intFromEnum(Index.prefetch_options_type),
4033 export_options,4593 export_options = @intFromEnum(Index.export_options_type),
4034 extern_options,4594 extern_options = @intFromEnum(Index.extern_options_type),
4035 type_info,4595 type_info = @intFromEnum(Index.type_info_type),
40364596
4037 adhoc_inferred_error_set,4597 adhoc_inferred_error_set = @intFromEnum(Index.adhoc_inferred_error_set_type),
4038 generic_poison,4598 generic_poison = @intFromEnum(Index.generic_poison_type),
4039};4599};
40404600
4041pub const SimpleValue = enum(u32) {4601pub const SimpleValue = enum(u32) {
4042 /// This is untyped `undefined`.4602 /// This is untyped `undefined`.
4043 undefined,4603 undefined = @intFromEnum(Index.undef),
4044 void,4604 void = @intFromEnum(Index.void_value),
4045 /// This is untyped `null`.4605 /// This is untyped `null`.
4046 null,4606 null = @intFromEnum(Index.null_value),
4047 /// This is the untyped empty struct literal: `.{}`4607 /// This is the untyped empty struct literal: `.{}`
4048 empty_struct,4608 empty_struct = @intFromEnum(Index.empty_struct),
4049 true,4609 true = @intFromEnum(Index.bool_true),
4050 false,4610 false = @intFromEnum(Index.bool_false),
4051 @"unreachable",4611 @"unreachable" = @intFromEnum(Index.unreachable_value),
40524612
4053 generic_poison,4613 generic_poison = @intFromEnum(Index.generic_poison),
4054};4614};
40554615
4056/// Stored as a power-of-two, with one special value to indicate none.4616/// Stored as a power-of-two, with one special value to indicate none.
...@@ -4170,14 +4730,18 @@ pub const Alignment = enum(u6) {...@@ -4170,14 +4730,18 @@ pub const Alignment = enum(u6) {
4170 /// This type exists to provide a struct with lifetime that is4730 /// This type exists to provide a struct with lifetime that is
4171 /// not invalidated when items are added to the `InternPool`.4731 /// not invalidated when items are added to the `InternPool`.
4172 pub const Slice = struct {4732 pub const Slice = struct {
4733 tid: Zcu.PerThread.Id,
4173 start: u32,4734 start: u32,
4174 /// This is the number of alignment values, not the number of u32 elements.4735 /// This is the number of alignment values, not the number of u32 elements.
4175 len: u32,4736 len: u32,
41764737
4738 pub const empty: Slice = .{ .tid = .main, .start = 0, .len = 0 };
4739
4177 pub fn get(slice: Slice, ip: *const InternPool) []Alignment {4740 pub fn get(slice: Slice, ip: *const InternPool) []Alignment {
4178 // TODO: implement @ptrCast between slices changing the length4741 // TODO: implement @ptrCast between slices changing the length
4179 //const bytes: []u8 = @ptrCast(ip.extra.items[slice.start..]);4742 const extra = ip.getLocalShared(slice.tid).extra.acquire();
4180 const bytes: []u8 = std.mem.sliceAsBytes(ip.extra.items[slice.start..]);4743 //const bytes: []u8 = @ptrCast(extra.view().items(.@"0")[slice.start..]);
4744 const bytes: []u8 = std.mem.sliceAsBytes(extra.view().items(.@"0")[slice.start..]);
4181 return @ptrCast(bytes[0..slice.len]);4745 return @ptrCast(bytes[0..slice.len]);
4182 }4746 }
4183 };4747 };
...@@ -4444,9 +5008,11 @@ pub const PtrSlice = struct {...@@ -4444,9 +5008,11 @@ pub const PtrSlice = struct {
4444};5008};
44455009
4446/// Trailing: Limb for every limbs_len5010/// Trailing: Limb for every limbs_len
4447pub const Int = struct {5011pub const Int = packed struct {
4448 ty: Index,5012 ty: Index,
4449 limbs_len: u32,5013 limbs_len: u32,
5014
5015 const limbs_items_len = @divExact(@sizeOf(Int), @sizeOf(Limb));
4450};5016};
44515017
4452pub const IntSmall = struct {5018pub const IntSmall = struct {
...@@ -4535,30 +5101,57 @@ pub const MemoizedCall = struct {...@@ -4535,30 +5101,57 @@ pub const MemoizedCall = struct {
4535 result: Index,5101 result: Index,
4536};5102};
45375103
4538pub fn init(ip: *InternPool, gpa: Allocator) !void {5104pub fn init(ip: *InternPool, gpa: Allocator, available_threads: usize) !void {
4539 assert(ip.items.len == 0);5105 errdefer ip.deinit(gpa);
5106 assert(ip.locals.len == 0 and ip.shards.len == 0);
5107 assert(available_threads > 0 and available_threads <= std.math.maxInt(u8));
5108
5109 const used_threads = if (single_threaded) 1 else available_threads;
5110 ip.locals = try gpa.alloc(Local, used_threads);
5111 @memset(ip.locals, .{
5112 .shared = .{
5113 .items = Local.List(Item).empty,
5114 .extra = Local.Extra.empty,
5115 .limbs = Local.Limbs.empty,
5116 .strings = Local.Strings.empty,
5117 },
5118 .mutate = .{
5119 .arena = .{},
5120 .items = Local.Mutate.empty,
5121 .extra = Local.Mutate.empty,
5122 .limbs = Local.Mutate.empty,
5123 .strings = Local.Mutate.empty,
5124 },
5125 });
45405126
4541 // Reserve string index 0 for an empty string.5127 ip.tid_width = @intCast(std.math.log2_int_ceil(usize, used_threads));
4542 assert((try ip.getOrPutString(gpa, "", .no_embedded_nulls)) == .empty);5128 ip.tid_shift_31 = if (single_threaded) 0 else 31 - ip.tid_width;
5129 ip.tid_shift_32 = if (single_threaded) 0 else ip.tid_shift_31 +| 1;
5130 ip.shards = try gpa.alloc(Shard, @as(usize, 1) << ip.tid_width);
5131 @memset(ip.shards, .{
5132 .shared = .{
5133 .map = Shard.Map(Index).empty,
5134 .string_map = Shard.Map(OptionalNullTerminatedString).empty,
5135 },
5136 .mutate = .{
5137 .map = Shard.Mutate.empty,
5138 .string_map = Shard.Mutate.empty,
5139 },
5140 });
45435141
4544 // So that we can use `catch unreachable` below.5142 // Reserve string index 0 for an empty string.
4545 try ip.items.ensureUnusedCapacity(gpa, static_keys.len);5143 assert((try ip.getOrPutString(gpa, .main, "", .no_embedded_nulls)) == .empty);
4546 try ip.map.ensureUnusedCapacity(gpa, static_keys.len);
4547 try ip.extra.ensureUnusedCapacity(gpa, static_keys.len);
45485144
4549 // This inserts all the statically-known values into the intern pool in the5145 // This inserts all the statically-known values into the intern pool in the
4550 // order expected.5146 // order expected.
4551 for (static_keys[0..@intFromEnum(Index.empty_struct_type)]) |key| {5147 for (&static_keys, 0..) |key, key_index| switch (@as(Index, @enumFromInt(key_index))) {
4552 _ = ip.get(gpa, key) catch unreachable;5148 .empty_struct_type => assert(try ip.getAnonStructType(gpa, .main, .{
4553 }5149 .types = &.{},
4554 _ = ip.getAnonStructType(gpa, .{5150 .names = &.{},
4555 .types = &.{},5151 .values = &.{},
4556 .names = &.{},5152 }) == .empty_struct_type),
4557 .values = &.{},5153 else => |expected_index| assert(try ip.get(gpa, .main, key) == expected_index),
4558 }) catch unreachable;5154 };
4559 for (static_keys[@intFromEnum(Index.empty_struct_type) + 1 ..]) |key| {
4560 _ = ip.get(gpa, key) catch unreachable;
4561 }
45625155
4563 if (std.debug.runtime_safety) {5156 if (std.debug.runtime_safety) {
4564 // Sanity check.5157 // Sanity check.
...@@ -4577,17 +5170,9 @@ pub fn init(ip: *InternPool, gpa: Allocator) !void {...@@ -4577,17 +5170,9 @@ pub fn init(ip: *InternPool, gpa: Allocator) !void {
4577 assert(ip.indexToKey(ip.typeOf(cc_inline)).int_type.bits ==5170 assert(ip.indexToKey(ip.typeOf(cc_inline)).int_type.bits ==
4578 @typeInfo(@typeInfo(std.builtin.CallingConvention).Enum.tag_type).Int.bits);5171 @typeInfo(@typeInfo(std.builtin.CallingConvention).Enum.tag_type).Int.bits);
4579 }5172 }
4580
4581 assert(ip.items.len == static_keys.len);
4582}5173}
45835174
4584pub fn deinit(ip: *InternPool, gpa: Allocator) void {5175pub fn deinit(ip: *InternPool, gpa: Allocator) void {
4585 ip.map.deinit(gpa);
4586 ip.items.deinit(gpa);
4587 ip.extra.deinit(gpa);
4588 ip.limbs.deinit(gpa);
4589 ip.string_bytes.deinit(gpa);
4590
4591 ip.decls_free_list.deinit(gpa);5176 ip.decls_free_list.deinit(gpa);
4592 ip.allocated_decls.deinit(gpa);5177 ip.allocated_decls.deinit(gpa);
45935178
...@@ -4597,8 +5182,6 @@ pub fn deinit(ip: *InternPool, gpa: Allocator) void {...@@ -4597,8 +5182,6 @@ pub fn deinit(ip: *InternPool, gpa: Allocator) void {
4597 for (ip.maps.items) |*map| map.deinit(gpa);5182 for (ip.maps.items) |*map| map.deinit(gpa);
4598 ip.maps.deinit(gpa);5183 ip.maps.deinit(gpa);
45995184
4600 ip.string_table.deinit(gpa);
4601
4602 ip.tracked_insts.deinit(gpa);5185 ip.tracked_insts.deinit(gpa);
46035186
4604 ip.src_hash_deps.deinit(gpa);5187 ip.src_hash_deps.deinit(gpa);
...@@ -4614,12 +5197,17 @@ pub fn deinit(ip: *InternPool, gpa: Allocator) void {...@@ -4614,12 +5197,17 @@ pub fn deinit(ip: *InternPool, gpa: Allocator) void {
46145197
4615 ip.files.deinit(gpa);5198 ip.files.deinit(gpa);
46165199
5200 gpa.free(ip.shards);
5201 for (ip.locals) |*local| local.mutate.arena.promote(gpa).deinit();
5202 gpa.free(ip.locals);
5203
4617 ip.* = undefined;5204 ip.* = undefined;
4618}5205}
46195206
4620pub fn indexToKey(ip: *const InternPool, index: Index) Key {5207pub fn indexToKey(ip: *const InternPool, index: Index) Key {
4621 assert(index != .none);5208 assert(index != .none);
4622 const item = ip.items.get(@intFromEnum(index));5209 const unwrapped_index = index.unwrap(ip);
5210 const item = unwrapped_index.getItem(ip);
4623 const data = item.data;5211 const data = item.data;
4624 return switch (item.tag) {5212 return switch (item.tag) {
4625 .removed => unreachable,5213 .removed => unreachable,
...@@ -4636,7 +5224,7 @@ pub fn indexToKey(ip: *const InternPool, index: Index) Key {...@@ -4636,7 +5224,7 @@ pub fn indexToKey(ip: *const InternPool, index: Index) Key {
4636 },5224 },
4637 },5225 },
4638 .type_array_big => {5226 .type_array_big => {
4639 const array_info = ip.extraData(Array, data);5227 const array_info = extraData(unwrapped_index.getExtra(ip), Array, data);
4640 return .{ .array_type = .{5228 return .{ .array_type = .{
4641 .len = array_info.getLength(),5229 .len = array_info.getLength(),
4642 .child = array_info.child,5230 .child = array_info.child,
...@@ -4644,29 +5232,32 @@ pub fn indexToKey(ip: *const InternPool, index: Index) Key {...@@ -4644,29 +5232,32 @@ pub fn indexToKey(ip: *const InternPool, index: Index) Key {
4644 } };5232 } };
4645 },5233 },
4646 .type_array_small => {5234 .type_array_small => {
4647 const array_info = ip.extraData(Vector, data);5235 const array_info = extraData(unwrapped_index.getExtra(ip), Vector, data);
4648 return .{ .array_type = .{5236 return .{ .array_type = .{
4649 .len = array_info.len,5237 .len = array_info.len,
4650 .child = array_info.child,5238 .child = array_info.child,
4651 .sentinel = .none,5239 .sentinel = .none,
4652 } };5240 } };
4653 },5241 },
4654 .simple_type => .{ .simple_type = @enumFromInt(data) },5242 .simple_type => .{ .simple_type = @enumFromInt(@intFromEnum(index)) },
4655 .simple_value => .{ .simple_value = @enumFromInt(data) },5243 .simple_value => .{ .simple_value = @enumFromInt(@intFromEnum(index)) },
46565244
4657 .type_vector => {5245 .type_vector => {
4658 const vector_info = ip.extraData(Vector, data);5246 const vector_info = extraData(unwrapped_index.getExtra(ip), Vector, data);
4659 return .{ .vector_type = .{5247 return .{ .vector_type = .{
4660 .len = vector_info.len,5248 .len = vector_info.len,
4661 .child = vector_info.child,5249 .child = vector_info.child,
4662 } };5250 } };
4663 },5251 },
46645252
4665 .type_pointer => .{ .ptr_type = ip.extraData(Tag.TypePointer, data) },5253 .type_pointer => .{ .ptr_type = extraData(unwrapped_index.getExtra(ip), Tag.TypePointer, data) },
46665254
4667 .type_slice => {5255 .type_slice => {
4668 assert(ip.items.items(.tag)[data] == .type_pointer);5256 const many_ptr_index: Index = @enumFromInt(data);
4669 var ptr_info = ip.extraData(Tag.TypePointer, ip.items.items(.data)[data]);5257 const many_ptr_unwrapped = many_ptr_index.unwrap(ip);
5258 const many_ptr_item = many_ptr_unwrapped.getItem(ip);
5259 assert(many_ptr_item.tag == .type_pointer);
5260 var ptr_info = extraData(many_ptr_unwrapped.getExtra(ip), Tag.TypePointer, many_ptr_item.data);
4670 ptr_info.flags.size = .Slice;5261 ptr_info.flags.size = .Slice;
4671 return .{ .ptr_type = ptr_info };5262 return .{ .ptr_type = ptr_info };
4672 },5263 },
...@@ -4674,18 +5265,18 @@ pub fn indexToKey(ip: *const InternPool, index: Index) Key {...@@ -4674,18 +5265,18 @@ pub fn indexToKey(ip: *const InternPool, index: Index) Key {
4674 .type_optional => .{ .opt_type = @enumFromInt(data) },5265 .type_optional => .{ .opt_type = @enumFromInt(data) },
4675 .type_anyframe => .{ .anyframe_type = @enumFromInt(data) },5266 .type_anyframe => .{ .anyframe_type = @enumFromInt(data) },
46765267
4677 .type_error_union => .{ .error_union_type = ip.extraData(Key.ErrorUnionType, data) },5268 .type_error_union => .{ .error_union_type = extraData(unwrapped_index.getExtra(ip), Key.ErrorUnionType, data) },
4678 .type_anyerror_union => .{ .error_union_type = .{5269 .type_anyerror_union => .{ .error_union_type = .{
4679 .error_set_type = .anyerror_type,5270 .error_set_type = .anyerror_type,
4680 .payload_type = @enumFromInt(data),5271 .payload_type = @enumFromInt(data),
4681 } },5272 } },
4682 .type_error_set => .{ .error_set_type = ip.extraErrorSet(data) },5273 .type_error_set => .{ .error_set_type = extraErrorSet(unwrapped_index.tid, unwrapped_index.getExtra(ip), data) },
4683 .type_inferred_error_set => .{5274 .type_inferred_error_set => .{
4684 .inferred_error_set_type = @enumFromInt(data),5275 .inferred_error_set_type = @enumFromInt(data),
4685 },5276 },
46865277
4687 .type_opaque => .{ .opaque_type = ns: {5278 .type_opaque => .{ .opaque_type = ns: {
4688 const extra = ip.extraDataTrail(Tag.TypeOpaque, data);5279 const extra = extraDataTrail(unwrapped_index.getExtra(ip), Tag.TypeOpaque, data);
4689 if (extra.data.captures_len == std.math.maxInt(u32)) {5280 if (extra.data.captures_len == std.math.maxInt(u32)) {
4690 break :ns .{ .reified = .{5281 break :ns .{ .reified = .{
4691 .zir_index = extra.data.zir_index,5282 .zir_index = extra.data.zir_index,
...@@ -4695,6 +5286,7 @@ pub fn indexToKey(ip: *const InternPool, index: Index) Key {...@@ -4695,6 +5286,7 @@ pub fn indexToKey(ip: *const InternPool, index: Index) Key {
4695 break :ns .{ .declared = .{5286 break :ns .{ .declared = .{
4696 .zir_index = extra.data.zir_index,5287 .zir_index = extra.data.zir_index,
4697 .captures = .{ .owned = .{5288 .captures = .{ .owned = .{
5289 .tid = unwrapped_index.tid,
4698 .start = extra.end,5290 .start = extra.end,
4699 .len = extra.data.captures_len,5291 .len = extra.data.captures_len,
4700 } },5292 } },
...@@ -4703,105 +5295,115 @@ pub fn indexToKey(ip: *const InternPool, index: Index) Key {...@@ -4703,105 +5295,115 @@ pub fn indexToKey(ip: *const InternPool, index: Index) Key {
47035295
4704 .type_struct => .{ .struct_type = ns: {5296 .type_struct => .{ .struct_type = ns: {
4705 if (data == 0) break :ns .empty_struct;5297 if (data == 0) break :ns .empty_struct;
4706 const extra = ip.extraDataTrail(Tag.TypeStruct, data);5298 const extra_list = unwrapped_index.getExtra(ip);
5299 const extra = extraDataTrail(extra_list, Tag.TypeStruct, data);
4707 if (extra.data.flags.is_reified) {5300 if (extra.data.flags.is_reified) {
4708 assert(!extra.data.flags.any_captures);5301 assert(!extra.data.flags.any_captures);
4709 break :ns .{ .reified = .{5302 break :ns .{ .reified = .{
4710 .zir_index = extra.data.zir_index,5303 .zir_index = extra.data.zir_index,
4711 .type_hash = ip.extraData(PackedU64, extra.end).get(),5304 .type_hash = extraData(extra_list, PackedU64, extra.end).get(),
4712 } };5305 } };
4713 }5306 }
4714 break :ns .{ .declared = .{5307 break :ns .{ .declared = .{
4715 .zir_index = extra.data.zir_index,5308 .zir_index = extra.data.zir_index,
4716 .captures = .{ .owned = if (extra.data.flags.any_captures) .{5309 .captures = .{ .owned = if (extra.data.flags.any_captures) .{
5310 .tid = unwrapped_index.tid,
4717 .start = extra.end + 1,5311 .start = extra.end + 1,
4718 .len = ip.extra.items[extra.end],5312 .len = extra_list.view().items(.@"0")[extra.end],
4719 } else .{ .start = 0, .len = 0 } },5313 } else CaptureValue.Slice.empty },
4720 } };5314 } };
4721 } },5315 } },
47225316
4723 .type_struct_packed, .type_struct_packed_inits => .{ .struct_type = ns: {5317 .type_struct_packed, .type_struct_packed_inits => .{ .struct_type = ns: {
4724 const extra = ip.extraDataTrail(Tag.TypeStructPacked, data);5318 const extra_list = unwrapped_index.getExtra(ip);
5319 const extra = extraDataTrail(extra_list, Tag.TypeStructPacked, data);
4725 if (extra.data.flags.is_reified) {5320 if (extra.data.flags.is_reified) {
4726 assert(!extra.data.flags.any_captures);5321 assert(!extra.data.flags.any_captures);
4727 break :ns .{ .reified = .{5322 break :ns .{ .reified = .{
4728 .zir_index = extra.data.zir_index,5323 .zir_index = extra.data.zir_index,
4729 .type_hash = ip.extraData(PackedU64, extra.end).get(),5324 .type_hash = extraData(extra_list, PackedU64, extra.end).get(),
4730 } };5325 } };
4731 }5326 }
4732 break :ns .{ .declared = .{5327 break :ns .{ .declared = .{
4733 .zir_index = extra.data.zir_index,5328 .zir_index = extra.data.zir_index,
4734 .captures = .{ .owned = if (extra.data.flags.any_captures) .{5329 .captures = .{ .owned = if (extra.data.flags.any_captures) .{
5330 .tid = unwrapped_index.tid,
4735 .start = extra.end + 1,5331 .start = extra.end + 1,
4736 .len = ip.extra.items[extra.end],5332 .len = extra_list.view().items(.@"0")[extra.end],
4737 } else .{ .start = 0, .len = 0 } },5333 } else CaptureValue.Slice.empty },
4738 } };5334 } };
4739 } },5335 } },
4740 .type_struct_anon => .{ .anon_struct_type = extraTypeStructAnon(ip, data) },5336 .type_struct_anon => .{ .anon_struct_type = extraTypeStructAnon(unwrapped_index.tid, unwrapped_index.getExtra(ip), data) },
4741 .type_tuple_anon => .{ .anon_struct_type = extraTypeTupleAnon(ip, data) },5337 .type_tuple_anon => .{ .anon_struct_type = extraTypeTupleAnon(unwrapped_index.tid, unwrapped_index.getExtra(ip), data) },
4742 .type_union => .{ .union_type = ns: {5338 .type_union => .{ .union_type = ns: {
4743 const extra = ip.extraDataTrail(Tag.TypeUnion, data);5339 const extra_list = unwrapped_index.getExtra(ip);
5340 const extra = extraDataTrail(extra_list, Tag.TypeUnion, data);
4744 if (extra.data.flags.is_reified) {5341 if (extra.data.flags.is_reified) {
4745 assert(!extra.data.flags.any_captures);5342 assert(!extra.data.flags.any_captures);
4746 break :ns .{ .reified = .{5343 break :ns .{ .reified = .{
4747 .zir_index = extra.data.zir_index,5344 .zir_index = extra.data.zir_index,
4748 .type_hash = ip.extraData(PackedU64, extra.end).get(),5345 .type_hash = extraData(extra_list, PackedU64, extra.end).get(),
4749 } };5346 } };
4750 }5347 }
4751 break :ns .{ .declared = .{5348 break :ns .{ .declared = .{
4752 .zir_index = extra.data.zir_index,5349 .zir_index = extra.data.zir_index,
4753 .captures = .{ .owned = if (extra.data.flags.any_captures) .{5350 .captures = .{ .owned = if (extra.data.flags.any_captures) .{
5351 .tid = unwrapped_index.tid,
4754 .start = extra.end + 1,5352 .start = extra.end + 1,
4755 .len = ip.extra.items[extra.end],5353 .len = extra_list.view().items(.@"0")[extra.end],
4756 } else .{ .start = 0, .len = 0 } },5354 } else CaptureValue.Slice.empty },
4757 } };5355 } };
4758 } },5356 } },
47595357
4760 .type_enum_auto => .{ .enum_type = ns: {5358 .type_enum_auto => .{ .enum_type = ns: {
4761 const extra = ip.extraDataTrail(EnumAuto, data);5359 const extra_list = unwrapped_index.getExtra(ip);
5360 const extra = extraDataTrail(extra_list, EnumAuto, data);
4762 const zir_index = extra.data.zir_index.unwrap() orelse {5361 const zir_index = extra.data.zir_index.unwrap() orelse {
4763 assert(extra.data.captures_len == 0);5362 assert(extra.data.captures_len == 0);
4764 break :ns .{ .generated_tag = .{5363 break :ns .{ .generated_tag = .{
4765 .union_type = @enumFromInt(ip.extra.items[extra.end]),5364 .union_type = @enumFromInt(extra_list.view().items(.@"0")[extra.end]),
4766 } };5365 } };
4767 };5366 };
4768 if (extra.data.captures_len == std.math.maxInt(u32)) {5367 if (extra.data.captures_len == std.math.maxInt(u32)) {
4769 break :ns .{ .reified = .{5368 break :ns .{ .reified = .{
4770 .zir_index = zir_index,5369 .zir_index = zir_index,
4771 .type_hash = ip.extraData(PackedU64, extra.end).get(),5370 .type_hash = extraData(extra_list, PackedU64, extra.end).get(),
4772 } };5371 } };
4773 }5372 }
4774 break :ns .{ .declared = .{5373 break :ns .{ .declared = .{
4775 .zir_index = zir_index,5374 .zir_index = zir_index,
4776 .captures = .{ .owned = .{5375 .captures = .{ .owned = .{
5376 .tid = unwrapped_index.tid,
4777 .start = extra.end,5377 .start = extra.end,
4778 .len = extra.data.captures_len,5378 .len = extra.data.captures_len,
4779 } },5379 } },
4780 } };5380 } };
4781 } },5381 } },
4782 .type_enum_explicit, .type_enum_nonexhaustive => .{ .enum_type = ns: {5382 .type_enum_explicit, .type_enum_nonexhaustive => .{ .enum_type = ns: {
4783 const extra = ip.extraDataTrail(EnumExplicit, data);5383 const extra_list = unwrapped_index.getExtra(ip);
5384 const extra = extraDataTrail(extra_list, EnumExplicit, data);
4784 const zir_index = extra.data.zir_index.unwrap() orelse {5385 const zir_index = extra.data.zir_index.unwrap() orelse {
4785 assert(extra.data.captures_len == 0);5386 assert(extra.data.captures_len == 0);
4786 break :ns .{ .generated_tag = .{5387 break :ns .{ .generated_tag = .{
4787 .union_type = @enumFromInt(ip.extra.items[extra.end]),5388 .union_type = @enumFromInt(extra_list.view().items(.@"0")[extra.end]),
4788 } };5389 } };
4789 };5390 };
4790 if (extra.data.captures_len == std.math.maxInt(u32)) {5391 if (extra.data.captures_len == std.math.maxInt(u32)) {
4791 break :ns .{ .reified = .{5392 break :ns .{ .reified = .{
4792 .zir_index = zir_index,5393 .zir_index = zir_index,
4793 .type_hash = ip.extraData(PackedU64, extra.end).get(),5394 .type_hash = extraData(extra_list, PackedU64, extra.end).get(),
4794 } };5395 } };
4795 }5396 }
4796 break :ns .{ .declared = .{5397 break :ns .{ .declared = .{
4797 .zir_index = zir_index,5398 .zir_index = zir_index,
4798 .captures = .{ .owned = .{5399 .captures = .{ .owned = .{
5400 .tid = unwrapped_index.tid,
4799 .start = extra.end,5401 .start = extra.end,
4800 .len = extra.data.captures_len,5402 .len = extra.data.captures_len,
4801 } },5403 } },
4802 } };5404 } };
4803 } },5405 } },
4804 .type_function => .{ .func_type = ip.extraFuncType(data) },5406 .type_function => .{ .func_type = extraFuncType(unwrapped_index.tid, unwrapped_index.getExtra(ip), data) },
48055407
4806 .undef => .{ .undef = @enumFromInt(data) },5408 .undef => .{ .undef = @enumFromInt(data) },
4807 .opt_null => .{ .opt = .{5409 .opt_null => .{ .opt = .{
...@@ -4809,40 +5411,40 @@ pub fn indexToKey(ip: *const InternPool, index: Index) Key {...@@ -4809,40 +5411,40 @@ pub fn indexToKey(ip: *const InternPool, index: Index) Key {
4809 .val = .none,5411 .val = .none,
4810 } },5412 } },
4811 .opt_payload => {5413 .opt_payload => {
4812 const extra = ip.extraData(Tag.TypeValue, data);5414 const extra = extraData(unwrapped_index.getExtra(ip), Tag.TypeValue, data);
4813 return .{ .opt = .{5415 return .{ .opt = .{
4814 .ty = extra.ty,5416 .ty = extra.ty,
4815 .val = extra.val,5417 .val = extra.val,
4816 } };5418 } };
4817 },5419 },
4818 .ptr_decl => {5420 .ptr_decl => {
4819 const info = ip.extraData(PtrDecl, data);5421 const info = extraData(unwrapped_index.getExtra(ip), PtrDecl, data);
4820 return .{ .ptr = .{ .ty = info.ty, .base_addr = .{ .decl = info.decl }, .byte_offset = info.byteOffset() } };5422 return .{ .ptr = .{ .ty = info.ty, .base_addr = .{ .decl = info.decl }, .byte_offset = info.byteOffset() } };
4821 },5423 },
4822 .ptr_comptime_alloc => {5424 .ptr_comptime_alloc => {
4823 const info = ip.extraData(PtrComptimeAlloc, data);5425 const info = extraData(unwrapped_index.getExtra(ip), PtrComptimeAlloc, data);
4824 return .{ .ptr = .{ .ty = info.ty, .base_addr = .{ .comptime_alloc = info.index }, .byte_offset = info.byteOffset() } };5426 return .{ .ptr = .{ .ty = info.ty, .base_addr = .{ .comptime_alloc = info.index }, .byte_offset = info.byteOffset() } };
4825 },5427 },
4826 .ptr_anon_decl => {5428 .ptr_anon_decl => {
4827 const info = ip.extraData(PtrAnonDecl, data);5429 const info = extraData(unwrapped_index.getExtra(ip), PtrAnonDecl, data);
4828 return .{ .ptr = .{ .ty = info.ty, .base_addr = .{ .anon_decl = .{5430 return .{ .ptr = .{ .ty = info.ty, .base_addr = .{ .anon_decl = .{
4829 .val = info.val,5431 .val = info.val,
4830 .orig_ty = info.ty,5432 .orig_ty = info.ty,
4831 } }, .byte_offset = info.byteOffset() } };5433 } }, .byte_offset = info.byteOffset() } };
4832 },5434 },
4833 .ptr_anon_decl_aligned => {5435 .ptr_anon_decl_aligned => {
4834 const info = ip.extraData(PtrAnonDeclAligned, data);5436 const info = extraData(unwrapped_index.getExtra(ip), PtrAnonDeclAligned, data);
4835 return .{ .ptr = .{ .ty = info.ty, .base_addr = .{ .anon_decl = .{5437 return .{ .ptr = .{ .ty = info.ty, .base_addr = .{ .anon_decl = .{
4836 .val = info.val,5438 .val = info.val,
4837 .orig_ty = info.orig_ty,5439 .orig_ty = info.orig_ty,
4838 } }, .byte_offset = info.byteOffset() } };5440 } }, .byte_offset = info.byteOffset() } };
4839 },5441 },
4840 .ptr_comptime_field => {5442 .ptr_comptime_field => {
4841 const info = ip.extraData(PtrComptimeField, data);5443 const info = extraData(unwrapped_index.getExtra(ip), PtrComptimeField, data);
4842 return .{ .ptr = .{ .ty = info.ty, .base_addr = .{ .comptime_field = info.field_val }, .byte_offset = info.byteOffset() } };5444 return .{ .ptr = .{ .ty = info.ty, .base_addr = .{ .comptime_field = info.field_val }, .byte_offset = info.byteOffset() } };
4843 },5445 },
4844 .ptr_int => {5446 .ptr_int => {
4845 const info = ip.extraData(PtrInt, data);5447 const info = extraData(unwrapped_index.getExtra(ip), PtrInt, data);
4846 return .{ .ptr = .{5448 return .{ .ptr = .{
4847 .ty = info.ty,5449 .ty = info.ty,
4848 .base_addr = .int,5450 .base_addr = .int,
...@@ -4850,17 +5452,17 @@ pub fn indexToKey(ip: *const InternPool, index: Index) Key {...@@ -4850,17 +5452,17 @@ pub fn indexToKey(ip: *const InternPool, index: Index) Key {
4850 } };5452 } };
4851 },5453 },
4852 .ptr_eu_payload => {5454 .ptr_eu_payload => {
4853 const info = ip.extraData(PtrBase, data);5455 const info = extraData(unwrapped_index.getExtra(ip), PtrBase, data);
4854 return .{ .ptr = .{ .ty = info.ty, .base_addr = .{ .eu_payload = info.base }, .byte_offset = info.byteOffset() } };5456 return .{ .ptr = .{ .ty = info.ty, .base_addr = .{ .eu_payload = info.base }, .byte_offset = info.byteOffset() } };
4855 },5457 },
4856 .ptr_opt_payload => {5458 .ptr_opt_payload => {
4857 const info = ip.extraData(PtrBase, data);5459 const info = extraData(unwrapped_index.getExtra(ip), PtrBase, data);
4858 return .{ .ptr = .{ .ty = info.ty, .base_addr = .{ .opt_payload = info.base }, .byte_offset = info.byteOffset() } };5460 return .{ .ptr = .{ .ty = info.ty, .base_addr = .{ .opt_payload = info.base }, .byte_offset = info.byteOffset() } };
4859 },5461 },
4860 .ptr_elem => {5462 .ptr_elem => {
4861 // Avoid `indexToKey` recursion by asserting the tag encoding.5463 // Avoid `indexToKey` recursion by asserting the tag encoding.
4862 const info = ip.extraData(PtrBaseIndex, data);5464 const info = extraData(unwrapped_index.getExtra(ip), PtrBaseIndex, data);
4863 const index_item = ip.items.get(@intFromEnum(info.index));5465 const index_item = info.index.unwrap(ip).getItem(ip);
4864 return switch (index_item.tag) {5466 return switch (index_item.tag) {
4865 .int_usize => .{ .ptr = .{ .ty = info.ty, .base_addr = .{ .arr_elem = .{5467 .int_usize => .{ .ptr = .{ .ty = info.ty, .base_addr = .{ .arr_elem = .{
4866 .base = info.base,5468 .base = info.base,
...@@ -4872,8 +5474,8 @@ pub fn indexToKey(ip: *const InternPool, index: Index) Key {...@@ -4872,8 +5474,8 @@ pub fn indexToKey(ip: *const InternPool, index: Index) Key {
4872 },5474 },
4873 .ptr_field => {5475 .ptr_field => {
4874 // Avoid `indexToKey` recursion by asserting the tag encoding.5476 // Avoid `indexToKey` recursion by asserting the tag encoding.
4875 const info = ip.extraData(PtrBaseIndex, data);5477 const info = extraData(unwrapped_index.getExtra(ip), PtrBaseIndex, data);
4876 const index_item = ip.items.get(@intFromEnum(info.index));5478 const index_item = info.index.unwrap(ip).getItem(ip);
4877 return switch (index_item.tag) {5479 return switch (index_item.tag) {
4878 .int_usize => .{ .ptr = .{ .ty = info.ty, .base_addr = .{ .field = .{5480 .int_usize => .{ .ptr = .{ .ty = info.ty, .base_addr = .{ .field = .{
4879 .base = info.base,5481 .base = info.base,
...@@ -4884,7 +5486,7 @@ pub fn indexToKey(ip: *const InternPool, index: Index) Key {...@@ -4884,7 +5486,7 @@ pub fn indexToKey(ip: *const InternPool, index: Index) Key {
4884 };5486 };
4885 },5487 },
4886 .ptr_slice => {5488 .ptr_slice => {
4887 const info = ip.extraData(PtrSlice, data);5489 const info = extraData(unwrapped_index.getExtra(ip), PtrSlice, data);
4888 return .{ .slice = .{5490 return .{ .slice = .{
4889 .ty = info.ty,5491 .ty = info.ty,
4890 .ptr = info.ptr,5492 .ptr = info.ptr,
...@@ -4919,17 +5521,17 @@ pub fn indexToKey(ip: *const InternPool, index: Index) Key {...@@ -4919,17 +5521,17 @@ pub fn indexToKey(ip: *const InternPool, index: Index) Key {
4919 .ty = .comptime_int_type,5521 .ty = .comptime_int_type,
4920 .storage = .{ .i64 = @as(i32, @bitCast(data)) },5522 .storage = .{ .i64 = @as(i32, @bitCast(data)) },
4921 } },5523 } },
4922 .int_positive => ip.indexToKeyBigInt(data, true),5524 .int_positive => ip.indexToKeyBigInt(unwrapped_index.tid, data, true),
4923 .int_negative => ip.indexToKeyBigInt(data, false),5525 .int_negative => ip.indexToKeyBigInt(unwrapped_index.tid, data, false),
4924 .int_small => {5526 .int_small => {
4925 const info = ip.extraData(IntSmall, data);5527 const info = extraData(unwrapped_index.getExtra(ip), IntSmall, data);
4926 return .{ .int = .{5528 return .{ .int = .{
4927 .ty = info.ty,5529 .ty = info.ty,
4928 .storage = .{ .u64 = info.value },5530 .storage = .{ .u64 = info.value },
4929 } };5531 } };
4930 },5532 },
4931 .int_lazy_align, .int_lazy_size => |tag| {5533 .int_lazy_align, .int_lazy_size => |tag| {
4932 const info = ip.extraData(IntLazy, data);5534 const info = extraData(unwrapped_index.getExtra(ip), IntLazy, data);
4933 return .{ .int = .{5535 return .{ .int = .{
4934 .ty = info.ty,5536 .ty = info.ty,
4935 .storage = switch (tag) {5537 .storage = switch (tag) {
...@@ -4949,30 +5551,30 @@ pub fn indexToKey(ip: *const InternPool, index: Index) Key {...@@ -4949,30 +5551,30 @@ pub fn indexToKey(ip: *const InternPool, index: Index) Key {
4949 } },5551 } },
4950 .float_f64 => .{ .float = .{5552 .float_f64 => .{ .float = .{
4951 .ty = .f64_type,5553 .ty = .f64_type,
4952 .storage = .{ .f64 = ip.extraData(Float64, data).get() },5554 .storage = .{ .f64 = extraData(unwrapped_index.getExtra(ip), Float64, data).get() },
4953 } },5555 } },
4954 .float_f80 => .{ .float = .{5556 .float_f80 => .{ .float = .{
4955 .ty = .f80_type,5557 .ty = .f80_type,
4956 .storage = .{ .f80 = ip.extraData(Float80, data).get() },5558 .storage = .{ .f80 = extraData(unwrapped_index.getExtra(ip), Float80, data).get() },
4957 } },5559 } },
4958 .float_f128 => .{ .float = .{5560 .float_f128 => .{ .float = .{
4959 .ty = .f128_type,5561 .ty = .f128_type,
4960 .storage = .{ .f128 = ip.extraData(Float128, data).get() },5562 .storage = .{ .f128 = extraData(unwrapped_index.getExtra(ip), Float128, data).get() },
4961 } },5563 } },
4962 .float_c_longdouble_f80 => .{ .float = .{5564 .float_c_longdouble_f80 => .{ .float = .{
4963 .ty = .c_longdouble_type,5565 .ty = .c_longdouble_type,
4964 .storage = .{ .f80 = ip.extraData(Float80, data).get() },5566 .storage = .{ .f80 = extraData(unwrapped_index.getExtra(ip), Float80, data).get() },
4965 } },5567 } },
4966 .float_c_longdouble_f128 => .{ .float = .{5568 .float_c_longdouble_f128 => .{ .float = .{
4967 .ty = .c_longdouble_type,5569 .ty = .c_longdouble_type,
4968 .storage = .{ .f128 = ip.extraData(Float128, data).get() },5570 .storage = .{ .f128 = extraData(unwrapped_index.getExtra(ip), Float128, data).get() },
4969 } },5571 } },
4970 .float_comptime_float => .{ .float = .{5572 .float_comptime_float => .{ .float = .{
4971 .ty = .comptime_float_type,5573 .ty = .comptime_float_type,
4972 .storage = .{ .f128 = ip.extraData(Float128, data).get() },5574 .storage = .{ .f128 = extraData(unwrapped_index.getExtra(ip), Float128, data).get() },
4973 } },5575 } },
4974 .variable => {5576 .variable => {
4975 const extra = ip.extraData(Tag.Variable, data);5577 const extra = extraData(unwrapped_index.getExtra(ip), Tag.Variable, data);
4976 return .{ .variable = .{5578 return .{ .variable = .{
4977 .ty = extra.ty,5579 .ty = extra.ty,
4978 .init = extra.init,5580 .init = extra.init,
...@@ -4984,18 +5586,20 @@ pub fn indexToKey(ip: *const InternPool, index: Index) Key {...@@ -4984,18 +5586,20 @@ pub fn indexToKey(ip: *const InternPool, index: Index) Key {
4984 .is_weak_linkage = extra.flags.is_weak_linkage,5586 .is_weak_linkage = extra.flags.is_weak_linkage,
4985 } };5587 } };
4986 },5588 },
4987 .extern_func => .{ .extern_func = ip.extraData(Tag.ExternFunc, data) },5589 .extern_func => .{ .extern_func = extraData(unwrapped_index.getExtra(ip), Tag.ExternFunc, data) },
4988 .func_instance => .{ .func = ip.extraFuncInstance(data) },5590 .func_instance => .{ .func = ip.extraFuncInstance(unwrapped_index.tid, unwrapped_index.getExtra(ip), data) },
4989 .func_decl => .{ .func = ip.extraFuncDecl(data) },5591 .func_decl => .{ .func = extraFuncDecl(unwrapped_index.tid, unwrapped_index.getExtra(ip), data) },
4990 .func_coerced => .{ .func = ip.extraFuncCoerced(data) },5592 .func_coerced => .{ .func = ip.extraFuncCoerced(unwrapped_index.getExtra(ip), data) },
4991 .only_possible_value => {5593 .only_possible_value => {
4992 const ty: Index = @enumFromInt(data);5594 const ty: Index = @enumFromInt(data);
4993 const ty_item = ip.items.get(@intFromEnum(ty));5595 const ty_unwrapped = ty.unwrap(ip);
5596 const ty_extra = ty_unwrapped.getExtra(ip);
5597 const ty_item = ty_unwrapped.getItem(ip);
4994 return switch (ty_item.tag) {5598 return switch (ty_item.tag) {
4995 .type_array_big => {5599 .type_array_big => {
4996 const sentinel = @as(5600 const sentinel = @as(
4997 *const [1]Index,5601 *const [1]Index,
4998 @ptrCast(&ip.extra.items[ty_item.data + std.meta.fieldIndex(Array, "sentinel").?]),5602 @ptrCast(&ty_extra.view().items(.@"0")[ty_item.data + std.meta.fieldIndex(Array, "sentinel").?]),
4999 );5603 );
5000 return .{ .aggregate = .{5604 return .{ .aggregate = .{
5001 .ty = ty,5605 .ty = ty,
...@@ -5023,9 +5627,9 @@ pub fn indexToKey(ip: *const InternPool, index: Index) Key {...@@ -5023,9 +5627,9 @@ pub fn indexToKey(ip: *const InternPool, index: Index) Key {
5023 // There is only one possible value precisely due to the5627 // There is only one possible value precisely due to the
5024 // fact that this values slice is fully populated!5628 // fact that this values slice is fully populated!
5025 .type_struct_anon, .type_tuple_anon => {5629 .type_struct_anon, .type_tuple_anon => {
5026 const type_struct_anon = ip.extraDataTrail(TypeStructAnon, ty_item.data);5630 const type_struct_anon = extraDataTrail(ty_extra, TypeStructAnon, ty_item.data);
5027 const fields_len = type_struct_anon.data.fields_len;5631 const fields_len = type_struct_anon.data.fields_len;
5028 const values = ip.extra.items[type_struct_anon.end + fields_len ..][0..fields_len];5632 const values = ty_extra.view().items(.@"0")[type_struct_anon.end + fields_len ..][0..fields_len];
5029 return .{ .aggregate = .{5633 return .{ .aggregate = .{
5030 .ty = ty,5634 .ty = ty,
5031 .storage = .{ .elems = @ptrCast(values) },5635 .storage = .{ .elems = @ptrCast(values) },
...@@ -5041,62 +5645,65 @@ pub fn indexToKey(ip: *const InternPool, index: Index) Key {...@@ -5041,62 +5645,65 @@ pub fn indexToKey(ip: *const InternPool, index: Index) Key {
5041 };5645 };
5042 },5646 },
5043 .bytes => {5647 .bytes => {
5044 const extra = ip.extraData(Bytes, data);5648 const extra = extraData(unwrapped_index.getExtra(ip), Bytes, data);
5045 return .{ .aggregate = .{5649 return .{ .aggregate = .{
5046 .ty = extra.ty,5650 .ty = extra.ty,
5047 .storage = .{ .bytes = extra.bytes },5651 .storage = .{ .bytes = extra.bytes },
5048 } };5652 } };
5049 },5653 },
5050 .aggregate => {5654 .aggregate => {
5051 const extra = ip.extraDataTrail(Tag.Aggregate, data);5655 const extra_list = unwrapped_index.getExtra(ip);
5656 const extra = extraDataTrail(extra_list, Tag.Aggregate, data);
5052 const len: u32 = @intCast(ip.aggregateTypeLenIncludingSentinel(extra.data.ty));5657 const len: u32 = @intCast(ip.aggregateTypeLenIncludingSentinel(extra.data.ty));
5053 const fields: []const Index = @ptrCast(ip.extra.items[extra.end..][0..len]);5658 const fields: []const Index = @ptrCast(extra_list.view().items(.@"0")[extra.end..][0..len]);
5054 return .{ .aggregate = .{5659 return .{ .aggregate = .{
5055 .ty = extra.data.ty,5660 .ty = extra.data.ty,
5056 .storage = .{ .elems = fields },5661 .storage = .{ .elems = fields },
5057 } };5662 } };
5058 },5663 },
5059 .repeated => {5664 .repeated => {
5060 const extra = ip.extraData(Repeated, data);5665 const extra = extraData(unwrapped_index.getExtra(ip), Repeated, data);
5061 return .{ .aggregate = .{5666 return .{ .aggregate = .{
5062 .ty = extra.ty,5667 .ty = extra.ty,
5063 .storage = .{ .repeated_elem = extra.elem_val },5668 .storage = .{ .repeated_elem = extra.elem_val },
5064 } };5669 } };
5065 },5670 },
5066 .union_value => .{ .un = ip.extraData(Key.Union, data) },5671 .union_value => .{ .un = extraData(unwrapped_index.getExtra(ip), Key.Union, data) },
5067 .error_set_error => .{ .err = ip.extraData(Key.Error, data) },5672 .error_set_error => .{ .err = extraData(unwrapped_index.getExtra(ip), Key.Error, data) },
5068 .error_union_error => {5673 .error_union_error => {
5069 const extra = ip.extraData(Key.Error, data);5674 const extra = extraData(unwrapped_index.getExtra(ip), Key.Error, data);
5070 return .{ .error_union = .{5675 return .{ .error_union = .{
5071 .ty = extra.ty,5676 .ty = extra.ty,
5072 .val = .{ .err_name = extra.name },5677 .val = .{ .err_name = extra.name },
5073 } };5678 } };
5074 },5679 },
5075 .error_union_payload => {5680 .error_union_payload => {
5076 const extra = ip.extraData(Tag.TypeValue, data);5681 const extra = extraData(unwrapped_index.getExtra(ip), Tag.TypeValue, data);
5077 return .{ .error_union = .{5682 return .{ .error_union = .{
5078 .ty = extra.ty,5683 .ty = extra.ty,
5079 .val = .{ .payload = extra.val },5684 .val = .{ .payload = extra.val },
5080 } };5685 } };
5081 },5686 },
5082 .enum_literal => .{ .enum_literal = @enumFromInt(data) },5687 .enum_literal => .{ .enum_literal = @enumFromInt(data) },
5083 .enum_tag => .{ .enum_tag = ip.extraData(Tag.EnumTag, data) },5688 .enum_tag => .{ .enum_tag = extraData(unwrapped_index.getExtra(ip), Tag.EnumTag, data) },
50845689
5085 .memoized_call => {5690 .memoized_call => {
5086 const extra = ip.extraDataTrail(MemoizedCall, data);5691 const extra_list = unwrapped_index.getExtra(ip);
5692 const extra = extraDataTrail(extra_list, MemoizedCall, data);
5087 return .{ .memoized_call = .{5693 return .{ .memoized_call = .{
5088 .func = extra.data.func,5694 .func = extra.data.func,
5089 .arg_values = @ptrCast(ip.extra.items[extra.end..][0..extra.data.args_len]),5695 .arg_values = @ptrCast(extra_list.view().items(.@"0")[extra.end..][0..extra.data.args_len]),
5090 .result = extra.data.result,5696 .result = extra.data.result,
5091 } };5697 } };
5092 },5698 },
5093 };5699 };
5094}5700}
50955701
5096fn extraErrorSet(ip: *const InternPool, extra_index: u32) Key.ErrorSetType {5702fn extraErrorSet(tid: Zcu.PerThread.Id, extra: Local.Extra, extra_index: u32) Key.ErrorSetType {
5097 const error_set = ip.extraDataTrail(Tag.ErrorSet, extra_index);5703 const error_set = extraDataTrail(extra, Tag.ErrorSet, extra_index);
5098 return .{5704 return .{
5099 .names = .{5705 .names = .{
5706 .tid = tid,
5100 .start = @intCast(error_set.end),5707 .start = @intCast(error_set.end),
5101 .len = error_set.data.names_len,5708 .len = error_set.data.names_len,
5102 },5709 },
...@@ -5104,60 +5711,67 @@ fn extraErrorSet(ip: *const InternPool, extra_index: u32) Key.ErrorSetType {...@@ -5104,60 +5711,67 @@ fn extraErrorSet(ip: *const InternPool, extra_index: u32) Key.ErrorSetType {
5104 };5711 };
5105}5712}
51065713
5107fn extraTypeStructAnon(ip: *const InternPool, extra_index: u32) Key.AnonStructType {5714fn extraTypeStructAnon(tid: Zcu.PerThread.Id, extra: Local.Extra, extra_index: u32) Key.AnonStructType {
5108 const type_struct_anon = ip.extraDataTrail(TypeStructAnon, extra_index);5715 const type_struct_anon = extraDataTrail(extra, TypeStructAnon, extra_index);
5109 const fields_len = type_struct_anon.data.fields_len;5716 const fields_len = type_struct_anon.data.fields_len;
5110 return .{5717 return .{
5111 .types = .{5718 .types = .{
5719 .tid = tid,
5112 .start = type_struct_anon.end,5720 .start = type_struct_anon.end,
5113 .len = fields_len,5721 .len = fields_len,
5114 },5722 },
5115 .values = .{5723 .values = .{
5724 .tid = tid,
5116 .start = type_struct_anon.end + fields_len,5725 .start = type_struct_anon.end + fields_len,
5117 .len = fields_len,5726 .len = fields_len,
5118 },5727 },
5119 .names = .{5728 .names = .{
5729 .tid = tid,
5120 .start = type_struct_anon.end + fields_len + fields_len,5730 .start = type_struct_anon.end + fields_len + fields_len,
5121 .len = fields_len,5731 .len = fields_len,
5122 },5732 },
5123 };5733 };
5124}5734}
51255735
5126fn extraTypeTupleAnon(ip: *const InternPool, extra_index: u32) Key.AnonStructType {5736fn extraTypeTupleAnon(tid: Zcu.PerThread.Id, extra: Local.Extra, extra_index: u32) Key.AnonStructType {
5127 const type_struct_anon = ip.extraDataTrail(TypeStructAnon, extra_index);5737 const type_struct_anon = extraDataTrail(extra, TypeStructAnon, extra_index);
5128 const fields_len = type_struct_anon.data.fields_len;5738 const fields_len = type_struct_anon.data.fields_len;
5129 return .{5739 return .{
5130 .types = .{5740 .types = .{
5741 .tid = tid,
5131 .start = type_struct_anon.end,5742 .start = type_struct_anon.end,
5132 .len = fields_len,5743 .len = fields_len,
5133 },5744 },
5134 .values = .{5745 .values = .{
5746 .tid = tid,
5135 .start = type_struct_anon.end + fields_len,5747 .start = type_struct_anon.end + fields_len,
5136 .len = fields_len,5748 .len = fields_len,
5137 },5749 },
5138 .names = .{5750 .names = .{
5751 .tid = tid,
5139 .start = 0,5752 .start = 0,
5140 .len = 0,5753 .len = 0,
5141 },5754 },
5142 };5755 };
5143}5756}
51445757
5145fn extraFuncType(ip: *const InternPool, extra_index: u32) Key.FuncType {5758fn extraFuncType(tid: Zcu.PerThread.Id, extra: Local.Extra, extra_index: u32) Key.FuncType {
5146 const type_function = ip.extraDataTrail(Tag.TypeFunction, extra_index);5759 const type_function = extraDataTrail(extra, Tag.TypeFunction, extra_index);
5147 var index: usize = type_function.end;5760 var trail_index: usize = type_function.end;
5148 const comptime_bits: u32 = if (!type_function.data.flags.has_comptime_bits) 0 else b: {5761 const comptime_bits: u32 = if (!type_function.data.flags.has_comptime_bits) 0 else b: {
5149 const x = ip.extra.items[index];5762 const x = extra.view().items(.@"0")[trail_index];
5150 index += 1;5763 trail_index += 1;
5151 break :b x;5764 break :b x;
5152 };5765 };
5153 const noalias_bits: u32 = if (!type_function.data.flags.has_noalias_bits) 0 else b: {5766 const noalias_bits: u32 = if (!type_function.data.flags.has_noalias_bits) 0 else b: {
5154 const x = ip.extra.items[index];5767 const x = extra.view().items(.@"0")[trail_index];
5155 index += 1;5768 trail_index += 1;
5156 break :b x;5769 break :b x;
5157 };5770 };
5158 return .{5771 return .{
5159 .param_types = .{5772 .param_types = .{
5160 .start = @intCast(index),5773 .tid = tid,
5774 .start = @intCast(trail_index),
5161 .len = type_function.data.params_len,5775 .len = type_function.data.params_len,
5162 },5776 },
5163 .return_type = type_function.data.return_type,5777 .return_type = type_function.data.return_type,
...@@ -5173,10 +5787,11 @@ fn extraFuncType(ip: *const InternPool, extra_index: u32) Key.FuncType {...@@ -5173,10 +5787,11 @@ fn extraFuncType(ip: *const InternPool, extra_index: u32) Key.FuncType {
5173 };5787 };
5174}5788}
51755789
5176fn extraFuncDecl(ip: *const InternPool, extra_index: u32) Key.Func {5790fn extraFuncDecl(tid: Zcu.PerThread.Id, extra: Local.Extra, extra_index: u32) Key.Func {
5177 const P = Tag.FuncDecl;5791 const P = Tag.FuncDecl;
5178 const func_decl = ip.extraDataTrail(P, extra_index);5792 const func_decl = extraDataTrail(extra, P, extra_index);
5179 return .{5793 return .{
5794 .tid = tid,
5180 .ty = func_decl.data.ty,5795 .ty = func_decl.data.ty,
5181 .uncoerced_ty = func_decl.data.ty,5796 .uncoerced_ty = func_decl.data.ty,
5182 .analysis_extra_index = extra_index + std.meta.fieldIndex(P, "analysis").?,5797 .analysis_extra_index = extra_index + std.meta.fieldIndex(P, "analysis").?,
...@@ -5190,15 +5805,16 @@ fn extraFuncDecl(ip: *const InternPool, extra_index: u32) Key.Func {...@@ -5190,15 +5805,16 @@ fn extraFuncDecl(ip: *const InternPool, extra_index: u32) Key.Func {
5190 .lbrace_column = func_decl.data.lbrace_column,5805 .lbrace_column = func_decl.data.lbrace_column,
5191 .rbrace_column = func_decl.data.rbrace_column,5806 .rbrace_column = func_decl.data.rbrace_column,
5192 .generic_owner = .none,5807 .generic_owner = .none,
5193 .comptime_args = .{ .start = 0, .len = 0 },5808 .comptime_args = Index.Slice.empty,
5194 };5809 };
5195}5810}
51965811
5197fn extraFuncInstance(ip: *const InternPool, extra_index: u32) Key.Func {5812fn extraFuncInstance(ip: *const InternPool, tid: Zcu.PerThread.Id, extra: Local.Extra, extra_index: u32) Key.Func {
5198 const P = Tag.FuncInstance;5813 const P = Tag.FuncInstance;
5199 const fi = ip.extraDataTrail(P, extra_index);5814 const fi = extraDataTrail(extra, P, extra_index);
5200 const func_decl = ip.funcDeclInfo(fi.data.generic_owner);5815 const func_decl = ip.funcDeclInfo(fi.data.generic_owner);
5201 return .{5816 return .{
5817 .tid = tid,
5202 .ty = fi.data.ty,5818 .ty = fi.data.ty,
5203 .uncoerced_ty = fi.data.ty,5819 .uncoerced_ty = fi.data.ty,
5204 .analysis_extra_index = extra_index + std.meta.fieldIndex(P, "analysis").?,5820 .analysis_extra_index = extra_index + std.meta.fieldIndex(P, "analysis").?,
...@@ -5213,47 +5829,185 @@ fn extraFuncInstance(ip: *const InternPool, extra_index: u32) Key.Func {...@@ -5213,47 +5829,185 @@ fn extraFuncInstance(ip: *const InternPool, extra_index: u32) Key.Func {
5213 .rbrace_column = func_decl.rbrace_column,5829 .rbrace_column = func_decl.rbrace_column,
5214 .generic_owner = fi.data.generic_owner,5830 .generic_owner = fi.data.generic_owner,
5215 .comptime_args = .{5831 .comptime_args = .{
5832 .tid = tid,
5216 .start = fi.end + @intFromBool(fi.data.analysis.inferred_error_set),5833 .start = fi.end + @intFromBool(fi.data.analysis.inferred_error_set),
5217 .len = ip.funcTypeParamsLen(func_decl.ty),5834 .len = ip.funcTypeParamsLen(func_decl.ty),
5218 },5835 },
5219 };5836 };
5220}5837}
52215838
5222fn extraFuncCoerced(ip: *const InternPool, extra_index: u32) Key.Func {5839fn extraFuncCoerced(ip: *const InternPool, extra: Local.Extra, extra_index: u32) Key.Func {
5223 const func_coerced = ip.extraData(Tag.FuncCoerced, extra_index);5840 const func_coerced = extraData(extra, Tag.FuncCoerced, extra_index);
5224 const sub_item = ip.items.get(@intFromEnum(func_coerced.func));5841 const func_unwrapped = func_coerced.func.unwrap(ip);
5842 const sub_item = func_unwrapped.getItem(ip);
5843 const func_extra = func_unwrapped.getExtra(ip);
5225 var func: Key.Func = switch (sub_item.tag) {5844 var func: Key.Func = switch (sub_item.tag) {
5226 .func_instance => ip.extraFuncInstance(sub_item.data),5845 .func_instance => ip.extraFuncInstance(func_unwrapped.tid, func_extra, sub_item.data),
5227 .func_decl => ip.extraFuncDecl(sub_item.data),5846 .func_decl => extraFuncDecl(func_unwrapped.tid, func_extra, sub_item.data),
5228 else => unreachable,5847 else => unreachable,
5229 };5848 };
5230 func.ty = func_coerced.ty;5849 func.ty = func_coerced.ty;
5231 return func;5850 return func;
5232}5851}
52335852
5234fn indexToKeyBigInt(ip: *const InternPool, limb_index: u32, positive: bool) Key {5853fn indexToKeyBigInt(ip: *const InternPool, tid: Zcu.PerThread.Id, limb_index: u32, positive: bool) Key {
5235 const int_info = ip.limbData(Int, limb_index);5854 const limbs_items = ip.getLocalShared(tid).getLimbs().view().items(.@"0");
5855 const int: Int = @bitCast(limbs_items[limb_index..][0..Int.limbs_items_len].*);
5236 return .{ .int = .{5856 return .{ .int = .{
5237 .ty = int_info.ty,5857 .ty = int.ty,
5238 .storage = .{ .big_int = .{5858 .storage = .{ .big_int = .{
5239 .limbs = ip.limbSlice(Int, limb_index, int_info.limbs_len),5859 .limbs = limbs_items[limb_index + Int.limbs_items_len ..][0..int.limbs_len],
5240 .positive = positive,5860 .positive = positive,
5241 } },5861 } },
5242 } };5862 } };
5243}5863}
52445864
5245pub fn get(ip: *InternPool, gpa: Allocator, key: Key) Allocator.Error!Index {5865const GetOrPutKey = union(enum) {
5246 const adapter: KeyAdapter = .{ .intern_pool = ip };5866 existing: Index,
5247 const gop = try ip.map.getOrPutAdapted(gpa, key, adapter);5867 new: struct {
5248 if (gop.found_existing) return @enumFromInt(gop.index);5868 ip: *InternPool,
5249 try ip.items.ensureUnusedCapacity(gpa, 1);5869 tid: Zcu.PerThread.Id,
5870 shard: *Shard,
5871 map_index: u32,
5872 },
5873
5874 fn put(gop: *GetOrPutKey) Index {
5875 return gop.putAt(0);
5876 }
5877 fn putAt(gop: *GetOrPutKey, offset: u32) Index {
5878 switch (gop.*) {
5879 .existing => unreachable,
5880 .new => |info| {
5881 const index = Index.Unwrapped.wrap(.{
5882 .tid = info.tid,
5883 .index = info.ip.getLocal(info.tid).mutate.items.len - 1 - offset,
5884 }, info.ip);
5885 info.shard.shared.map.entries[info.map_index].release(index);
5886 info.shard.mutate.map.len += 1;
5887 info.shard.mutate.map.mutex.unlock();
5888 gop.* = .{ .existing = index };
5889 return index;
5890 },
5891 }
5892 }
5893
5894 fn assign(gop: *GetOrPutKey, new_gop: GetOrPutKey) void {
5895 gop.deinit();
5896 gop.* = new_gop;
5897 }
5898
5899 fn deinit(gop: *GetOrPutKey) void {
5900 switch (gop.*) {
5901 .existing => {},
5902 .new => |info| info.shard.mutate.map.mutex.unlock(),
5903 }
5904 gop.* = undefined;
5905 }
5906};
5907fn getOrPutKey(
5908 ip: *InternPool,
5909 gpa: Allocator,
5910 tid: Zcu.PerThread.Id,
5911 key: Key,
5912) Allocator.Error!GetOrPutKey {
5913 const full_hash = key.hash64(ip);
5914 const hash: u32 = @truncate(full_hash >> 32);
5915 const shard = &ip.shards[@intCast(full_hash & (ip.shards.len - 1))];
5916 var map = shard.shared.map.acquire();
5917 const Map = @TypeOf(map);
5918 var map_mask = map.header().mask();
5919 var map_index = hash;
5920 while (true) : (map_index += 1) {
5921 map_index &= map_mask;
5922 const entry = &map.entries[map_index];
5923 const index = entry.acquire();
5924 if (index == .none) break;
5925 if (entry.hash != hash) continue;
5926 if (ip.indexToKey(index).eql(key, ip)) return .{ .existing = index };
5927 }
5928 shard.mutate.map.mutex.lock();
5929 errdefer shard.mutate.map.mutex.unlock();
5930 if (map.entries != shard.shared.map.entries) {
5931 map = shard.shared.map;
5932 map_mask = map.header().mask();
5933 map_index = hash;
5934 }
5935 while (true) : (map_index += 1) {
5936 map_index &= map_mask;
5937 const entry = &map.entries[map_index];
5938 const index = entry.value;
5939 if (index == .none) break;
5940 if (entry.hash != hash) continue;
5941 if (ip.indexToKey(index).eql(key, ip)) {
5942 defer shard.mutate.map.mutex.unlock();
5943 return .{ .existing = index };
5944 }
5945 }
5946 const map_header = map.header().*;
5947 if (shard.mutate.map.len >= map_header.capacity * 3 / 5) {
5948 const arena_state = &ip.getLocal(tid).mutate.arena;
5949 var arena = arena_state.promote(gpa);
5950 defer arena_state.* = arena.state;
5951 const new_map_capacity = map_header.capacity * 2;
5952 const new_map_buf = try arena.allocator().alignedAlloc(
5953 u8,
5954 Map.alignment,
5955 Map.entries_offset + new_map_capacity * @sizeOf(Map.Entry),
5956 );
5957 const new_map: Map = .{ .entries = @ptrCast(new_map_buf[Map.entries_offset..].ptr) };
5958 new_map.header().* = .{ .capacity = new_map_capacity };
5959 @memset(new_map.entries[0..new_map_capacity], .{ .value = .none, .hash = undefined });
5960 const new_map_mask = new_map.header().mask();
5961 map_index = 0;
5962 while (map_index < map_header.capacity) : (map_index += 1) {
5963 const entry = &map.entries[map_index];
5964 const index = entry.value;
5965 if (index == .none) continue;
5966 const item_hash = entry.hash;
5967 var new_map_index = item_hash;
5968 while (true) : (new_map_index += 1) {
5969 new_map_index &= new_map_mask;
5970 const new_entry = &new_map.entries[new_map_index];
5971 if (new_entry.value != .none) continue;
5972 new_entry.* = .{
5973 .value = index,
5974 .hash = item_hash,
5975 };
5976 break;
5977 }
5978 }
5979 map = new_map;
5980 map_index = hash;
5981 while (true) : (map_index += 1) {
5982 map_index &= new_map_mask;
5983 if (map.entries[map_index].value == .none) break;
5984 }
5985 shard.shared.map.release(new_map);
5986 }
5987 map.entries[map_index].hash = hash;
5988 return .{ .new = .{
5989 .ip = ip,
5990 .tid = tid,
5991 .shard = shard,
5992 .map_index = map_index,
5993 } };
5994}
5995
5996pub fn get(ip: *InternPool, gpa: Allocator, tid: Zcu.PerThread.Id, key: Key) Allocator.Error!Index {
5997 var gop = try ip.getOrPutKey(gpa, tid, key);
5998 defer gop.deinit();
5999 if (gop == .existing) return gop.existing;
6000 const local = ip.getLocal(tid);
6001 const items = local.getMutableItems(gpa);
6002 const extra = local.getMutableExtra(gpa);
6003 try items.ensureUnusedCapacity(1);
5250 switch (key) {6004 switch (key) {
5251 .int_type => |int_type| {6005 .int_type => |int_type| {
5252 const t: Tag = switch (int_type.signedness) {6006 const t: Tag = switch (int_type.signedness) {
5253 .signed => .type_int_signed,6007 .signed => .type_int_signed,
5254 .unsigned => .type_int_unsigned,6008 .unsigned => .type_int_unsigned,
5255 };6009 };
5256 ip.items.appendAssumeCapacity(.{6010 items.appendAssumeCapacity(.{
5257 .tag = t,6011 .tag = t,
5258 .data = int_type.bits,6012 .data = int_type.bits,
5259 });6013 });
...@@ -5263,25 +6017,25 @@ pub fn get(ip: *InternPool, gpa: Allocator, key: Key) Allocator.Error!Index {...@@ -5263,25 +6017,25 @@ pub fn get(ip: *InternPool, gpa: Allocator, key: Key) Allocator.Error!Index {
5263 assert(ptr_type.sentinel == .none or ip.typeOf(ptr_type.sentinel) == ptr_type.child);6017 assert(ptr_type.sentinel == .none or ip.typeOf(ptr_type.sentinel) == ptr_type.child);
52646018
5265 if (ptr_type.flags.size == .Slice) {6019 if (ptr_type.flags.size == .Slice) {
5266 _ = ip.map.pop();
5267 var new_key = key;6020 var new_key = key;
5268 new_key.ptr_type.flags.size = .Many;6021 new_key.ptr_type.flags.size = .Many;
5269 const ptr_type_index = try ip.get(gpa, new_key);6022 const ptr_type_index = try ip.get(gpa, tid, new_key);
5270 assert(!(try ip.map.getOrPutAdapted(gpa, key, adapter)).found_existing);6023 gop.assign(try ip.getOrPutKey(gpa, tid, key));
5271 try ip.items.ensureUnusedCapacity(gpa, 1);6024
5272 ip.items.appendAssumeCapacity(.{6025 try items.ensureUnusedCapacity(1);
6026 items.appendAssumeCapacity(.{
5273 .tag = .type_slice,6027 .tag = .type_slice,
5274 .data = @intFromEnum(ptr_type_index),6028 .data = @intFromEnum(ptr_type_index),
5275 });6029 });
5276 return @enumFromInt(ip.items.len - 1);6030 return gop.put();
5277 }6031 }
52786032
5279 var ptr_type_adjusted = ptr_type;6033 var ptr_type_adjusted = ptr_type;
5280 if (ptr_type.flags.size == .C) ptr_type_adjusted.flags.is_allowzero = true;6034 if (ptr_type.flags.size == .C) ptr_type_adjusted.flags.is_allowzero = true;
52816035
5282 ip.items.appendAssumeCapacity(.{6036 items.appendAssumeCapacity(.{
5283 .tag = .type_pointer,6037 .tag = .type_pointer,
5284 .data = try ip.addExtra(gpa, ptr_type_adjusted),6038 .data = try addExtra(extra, ptr_type_adjusted),
5285 });6039 });
5286 },6040 },
5287 .array_type => |array_type| {6041 .array_type => |array_type| {
...@@ -5290,21 +6044,21 @@ pub fn get(ip: *InternPool, gpa: Allocator, key: Key) Allocator.Error!Index {...@@ -5290,21 +6044,21 @@ pub fn get(ip: *InternPool, gpa: Allocator, key: Key) Allocator.Error!Index {
52906044
5291 if (std.math.cast(u32, array_type.len)) |len| {6045 if (std.math.cast(u32, array_type.len)) |len| {
5292 if (array_type.sentinel == .none) {6046 if (array_type.sentinel == .none) {
5293 ip.items.appendAssumeCapacity(.{6047 items.appendAssumeCapacity(.{
5294 .tag = .type_array_small,6048 .tag = .type_array_small,
5295 .data = try ip.addExtra(gpa, Vector{6049 .data = try addExtra(extra, Vector{
5296 .len = len,6050 .len = len,
5297 .child = array_type.child,6051 .child = array_type.child,
5298 }),6052 }),
5299 });6053 });
5300 return @enumFromInt(ip.items.len - 1);6054 return gop.put();
5301 }6055 }
5302 }6056 }
53036057
5304 const length = Array.Length.init(array_type.len);6058 const length = Array.Length.init(array_type.len);
5305 ip.items.appendAssumeCapacity(.{6059 items.appendAssumeCapacity(.{
5306 .tag = .type_array_big,6060 .tag = .type_array_big,
5307 .data = try ip.addExtra(gpa, Array{6061 .data = try addExtra(extra, Array{
5308 .len0 = length.a,6062 .len0 = length.a,
5309 .len1 = length.b,6063 .len1 = length.b,
5310 .child = array_type.child,6064 .child = array_type.child,
...@@ -5313,9 +6067,9 @@ pub fn get(ip: *InternPool, gpa: Allocator, key: Key) Allocator.Error!Index {...@@ -5313,9 +6067,9 @@ pub fn get(ip: *InternPool, gpa: Allocator, key: Key) Allocator.Error!Index {
5313 });6067 });
5314 },6068 },
5315 .vector_type => |vector_type| {6069 .vector_type => |vector_type| {
5316 ip.items.appendAssumeCapacity(.{6070 items.appendAssumeCapacity(.{
5317 .tag = .type_vector,6071 .tag = .type_vector,
5318 .data = try ip.addExtra(gpa, Vector{6072 .data = try addExtra(extra, Vector{
5319 .len = vector_type.len,6073 .len = vector_type.len,
5320 .child = vector_type.child,6074 .child = vector_type.child,
5321 }),6075 }),
...@@ -5323,25 +6077,25 @@ pub fn get(ip: *InternPool, gpa: Allocator, key: Key) Allocator.Error!Index {...@@ -5323,25 +6077,25 @@ pub fn get(ip: *InternPool, gpa: Allocator, key: Key) Allocator.Error!Index {
5323 },6077 },
5324 .opt_type => |payload_type| {6078 .opt_type => |payload_type| {
5325 assert(payload_type != .none);6079 assert(payload_type != .none);
5326 ip.items.appendAssumeCapacity(.{6080 items.appendAssumeCapacity(.{
5327 .tag = .type_optional,6081 .tag = .type_optional,
5328 .data = @intFromEnum(payload_type),6082 .data = @intFromEnum(payload_type),
5329 });6083 });
5330 },6084 },
5331 .anyframe_type => |payload_type| {6085 .anyframe_type => |payload_type| {
5332 // payload_type might be none, indicating the type is `anyframe`.6086 // payload_type might be none, indicating the type is `anyframe`.
5333 ip.items.appendAssumeCapacity(.{6087 items.appendAssumeCapacity(.{
5334 .tag = .type_anyframe,6088 .tag = .type_anyframe,
5335 .data = @intFromEnum(payload_type),6089 .data = @intFromEnum(payload_type),
5336 });6090 });
5337 },6091 },
5338 .error_union_type => |error_union_type| {6092 .error_union_type => |error_union_type| {
5339 ip.items.appendAssumeCapacity(if (error_union_type.error_set_type == .anyerror_type) .{6093 items.appendAssumeCapacity(if (error_union_type.error_set_type == .anyerror_type) .{
5340 .tag = .type_anyerror_union,6094 .tag = .type_anyerror_union,
5341 .data = @intFromEnum(error_union_type.payload_type),6095 .data = @intFromEnum(error_union_type.payload_type),
5342 } else .{6096 } else .{
5343 .tag = .type_error_union,6097 .tag = .type_error_union,
5344 .data = try ip.addExtra(gpa, error_union_type),6098 .data = try addExtra(extra, error_union_type),
5345 });6099 });
5346 },6100 },
5347 .error_set_type => |error_set_type| {6101 .error_set_type => |error_set_type| {
...@@ -5351,37 +6105,39 @@ pub fn get(ip: *InternPool, gpa: Allocator, key: Key) Allocator.Error!Index {...@@ -5351,37 +6105,39 @@ pub fn get(ip: *InternPool, gpa: Allocator, key: Key) Allocator.Error!Index {
5351 const names_map = try ip.addMap(gpa, names.len);6105 const names_map = try ip.addMap(gpa, names.len);
5352 addStringsToMap(ip, names_map, names);6106 addStringsToMap(ip, names_map, names);
5353 const names_len = error_set_type.names.len;6107 const names_len = error_set_type.names.len;
5354 try ip.extra.ensureUnusedCapacity(gpa, @typeInfo(Tag.ErrorSet).Struct.fields.len + names_len);6108 try extra.ensureUnusedCapacity(@typeInfo(Tag.ErrorSet).Struct.fields.len + names_len);
5355 ip.items.appendAssumeCapacity(.{6109 items.appendAssumeCapacity(.{
5356 .tag = .type_error_set,6110 .tag = .type_error_set,
5357 .data = ip.addExtraAssumeCapacity(Tag.ErrorSet{6111 .data = addExtraAssumeCapacity(extra, Tag.ErrorSet{
5358 .names_len = names_len,6112 .names_len = names_len,
5359 .names_map = names_map,6113 .names_map = names_map,
5360 }),6114 }),
5361 });6115 });
5362 ip.extra.appendSliceAssumeCapacity(@ptrCast(error_set_type.names.get(ip)));6116 extra.appendSliceAssumeCapacity(.{@ptrCast(error_set_type.names.get(ip))});
5363 },6117 },
5364 .inferred_error_set_type => |ies_index| {6118 .inferred_error_set_type => |ies_index| {
5365 ip.items.appendAssumeCapacity(.{6119 items.appendAssumeCapacity(.{
5366 .tag = .type_inferred_error_set,6120 .tag = .type_inferred_error_set,
5367 .data = @intFromEnum(ies_index),6121 .data = @intFromEnum(ies_index),
5368 });6122 });
5369 },6123 },
5370 .simple_type => |simple_type| {6124 .simple_type => |simple_type| {
5371 ip.items.appendAssumeCapacity(.{6125 assert(@intFromEnum(simple_type) == items.mutate.len);
6126 items.appendAssumeCapacity(.{
5372 .tag = .simple_type,6127 .tag = .simple_type,
5373 .data = @intFromEnum(simple_type),6128 .data = 0, // avoid writing `undefined` bits to a file
5374 });6129 });
5375 },6130 },
5376 .simple_value => |simple_value| {6131 .simple_value => |simple_value| {
5377 ip.items.appendAssumeCapacity(.{6132 assert(@intFromEnum(simple_value) == items.mutate.len);
6133 items.appendAssumeCapacity(.{
5378 .tag = .simple_value,6134 .tag = .simple_value,
5379 .data = @intFromEnum(simple_value),6135 .data = 0, // avoid writing `undefined` bits to a file
5380 });6136 });
5381 },6137 },
5382 .undef => |ty| {6138 .undef => |ty| {
5383 assert(ty != .none);6139 assert(ty != .none);
5384 ip.items.appendAssumeCapacity(.{6140 items.appendAssumeCapacity(.{
5385 .tag = .undef,6141 .tag = .undef,
5386 .data = @intFromEnum(ty),6142 .data = @intFromEnum(ty),
5387 });6143 });
...@@ -5400,9 +6156,9 @@ pub fn get(ip: *InternPool, gpa: Allocator, key: Key) Allocator.Error!Index {...@@ -5400,9 +6156,9 @@ pub fn get(ip: *InternPool, gpa: Allocator, key: Key) Allocator.Error!Index {
5400 .variable => |variable| {6156 .variable => |variable| {
5401 const has_init = variable.init != .none;6157 const has_init = variable.init != .none;
5402 if (has_init) assert(variable.ty == ip.typeOf(variable.init));6158 if (has_init) assert(variable.ty == ip.typeOf(variable.init));
5403 ip.items.appendAssumeCapacity(.{6159 items.appendAssumeCapacity(.{
5404 .tag = .variable,6160 .tag = .variable,
5405 .data = try ip.addExtra(gpa, Tag.Variable{6161 .data = try addExtra(extra, Tag.Variable{
5406 .ty = variable.ty,6162 .ty = variable.ty,
5407 .init = variable.init,6163 .init = variable.init,
5408 .decl = variable.decl,6164 .decl = variable.decl,
...@@ -5420,9 +6176,9 @@ pub fn get(ip: *InternPool, gpa: Allocator, key: Key) Allocator.Error!Index {...@@ -5420,9 +6176,9 @@ pub fn get(ip: *InternPool, gpa: Allocator, key: Key) Allocator.Error!Index {
5420 .slice => |slice| {6176 .slice => |slice| {
5421 assert(ip.indexToKey(slice.ty).ptr_type.flags.size == .Slice);6177 assert(ip.indexToKey(slice.ty).ptr_type.flags.size == .Slice);
5422 assert(ip.indexToKey(ip.typeOf(slice.ptr)).ptr_type.flags.size == .Many);6178 assert(ip.indexToKey(ip.typeOf(slice.ptr)).ptr_type.flags.size == .Many);
5423 ip.items.appendAssumeCapacity(.{6179 items.appendAssumeCapacity(.{
5424 .tag = .ptr_slice,6180 .tag = .ptr_slice,
5425 .data = try ip.addExtra(gpa, PtrSlice{6181 .data = try addExtra(extra, PtrSlice{
5426 .ty = slice.ty,6182 .ty = slice.ty,
5427 .ptr = slice.ptr,6183 .ptr = slice.ptr,
5428 .len = slice.len,6184 .len = slice.len,
...@@ -5433,36 +6189,35 @@ pub fn get(ip: *InternPool, gpa: Allocator, key: Key) Allocator.Error!Index {...@@ -5433,36 +6189,35 @@ pub fn get(ip: *InternPool, gpa: Allocator, key: Key) Allocator.Error!Index {
5433 .ptr => |ptr| {6189 .ptr => |ptr| {
5434 const ptr_type = ip.indexToKey(ptr.ty).ptr_type;6190 const ptr_type = ip.indexToKey(ptr.ty).ptr_type;
5435 assert(ptr_type.flags.size != .Slice);6191 assert(ptr_type.flags.size != .Slice);
5436 ip.items.appendAssumeCapacity(switch (ptr.base_addr) {6192 items.appendAssumeCapacity(switch (ptr.base_addr) {
5437 .decl => |decl| .{6193 .decl => |decl| .{
5438 .tag = .ptr_decl,6194 .tag = .ptr_decl,
5439 .data = try ip.addExtra(gpa, PtrDecl.init(ptr.ty, decl, ptr.byte_offset)),6195 .data = try addExtra(extra, PtrDecl.init(ptr.ty, decl, ptr.byte_offset)),
5440 },6196 },
5441 .comptime_alloc => |alloc_index| .{6197 .comptime_alloc => |alloc_index| .{
5442 .tag = .ptr_comptime_alloc,6198 .tag = .ptr_comptime_alloc,
5443 .data = try ip.addExtra(gpa, PtrComptimeAlloc.init(ptr.ty, alloc_index, ptr.byte_offset)),6199 .data = try addExtra(extra, PtrComptimeAlloc.init(ptr.ty, alloc_index, ptr.byte_offset)),
5444 },6200 },
5445 .anon_decl => |anon_decl| if (ptrsHaveSameAlignment(ip, ptr.ty, ptr_type, anon_decl.orig_ty)) item: {6201 .anon_decl => |anon_decl| if (ptrsHaveSameAlignment(ip, ptr.ty, ptr_type, anon_decl.orig_ty)) item: {
5446 if (ptr.ty != anon_decl.orig_ty) {6202 if (ptr.ty != anon_decl.orig_ty) {
5447 _ = ip.map.pop();
5448 var new_key = key;6203 var new_key = key;
5449 new_key.ptr.base_addr.anon_decl.orig_ty = ptr.ty;6204 new_key.ptr.base_addr.anon_decl.orig_ty = ptr.ty;
5450 const new_gop = try ip.map.getOrPutAdapted(gpa, new_key, adapter);6205 gop.assign(try ip.getOrPutKey(gpa, tid, new_key));
5451 if (new_gop.found_existing) return @enumFromInt(new_gop.index);6206 if (gop == .existing) return gop.existing;
5452 }6207 }
5453 break :item .{6208 break :item .{
5454 .tag = .ptr_anon_decl,6209 .tag = .ptr_anon_decl,
5455 .data = try ip.addExtra(gpa, PtrAnonDecl.init(ptr.ty, anon_decl.val, ptr.byte_offset)),6210 .data = try addExtra(extra, PtrAnonDecl.init(ptr.ty, anon_decl.val, ptr.byte_offset)),
5456 };6211 };
5457 } else .{6212 } else .{
5458 .tag = .ptr_anon_decl_aligned,6213 .tag = .ptr_anon_decl_aligned,
5459 .data = try ip.addExtra(gpa, PtrAnonDeclAligned.init(ptr.ty, anon_decl.val, anon_decl.orig_ty, ptr.byte_offset)),6214 .data = try addExtra(extra, PtrAnonDeclAligned.init(ptr.ty, anon_decl.val, anon_decl.orig_ty, ptr.byte_offset)),
5460 },6215 },
5461 .comptime_field => |field_val| item: {6216 .comptime_field => |field_val| item: {
5462 assert(field_val != .none);6217 assert(field_val != .none);
5463 break :item .{6218 break :item .{
5464 .tag = .ptr_comptime_field,6219 .tag = .ptr_comptime_field,
5465 .data = try ip.addExtra(gpa, PtrComptimeField.init(ptr.ty, field_val, ptr.byte_offset)),6220 .data = try addExtra(extra, PtrComptimeField.init(ptr.ty, field_val, ptr.byte_offset)),
5466 };6221 };
5467 },6222 },
5468 .eu_payload, .opt_payload => |base| item: {6223 .eu_payload, .opt_payload => |base| item: {
...@@ -5481,14 +6236,14 @@ pub fn get(ip: *InternPool, gpa: Allocator, key: Key) Allocator.Error!Index {...@@ -5481,14 +6236,14 @@ pub fn get(ip: *InternPool, gpa: Allocator, key: Key) Allocator.Error!Index {
5481 .opt_payload => .ptr_opt_payload,6236 .opt_payload => .ptr_opt_payload,
5482 else => unreachable,6237 else => unreachable,
5483 },6238 },
5484 .data = try ip.addExtra(gpa, PtrBase.init(ptr.ty, base, ptr.byte_offset)),6239 .data = try addExtra(extra, PtrBase.init(ptr.ty, base, ptr.byte_offset)),
5485 };6240 };
5486 },6241 },
5487 .int => .{6242 .int => .{
5488 .tag = .ptr_int,6243 .tag = .ptr_int,
5489 .data = try ip.addExtra(gpa, PtrInt.init(ptr.ty, ptr.byte_offset)),6244 .data = try addExtra(extra, PtrInt.init(ptr.ty, ptr.byte_offset)),
5490 },6245 },
5491 .arr_elem, .field => |base_index| item: {6246 .arr_elem, .field => |base_index| {
5492 const base_ptr_type = ip.indexToKey(ip.typeOf(base_index.base)).ptr_type;6247 const base_ptr_type = ip.indexToKey(ip.typeOf(base_index.base)).ptr_type;
5493 switch (ptr.base_addr) {6248 switch (ptr.base_addr) {
5494 .arr_elem => assert(base_ptr_type.flags.size == .Many),6249 .arr_elem => assert(base_ptr_type.flags.size == .Many),
...@@ -5518,21 +6273,21 @@ pub fn get(ip: *InternPool, gpa: Allocator, key: Key) Allocator.Error!Index {...@@ -5518,21 +6273,21 @@ pub fn get(ip: *InternPool, gpa: Allocator, key: Key) Allocator.Error!Index {
5518 },6273 },
5519 else => unreachable,6274 else => unreachable,
5520 }6275 }
5521 _ = ip.map.pop();6276 const index_index = try ip.get(gpa, tid, .{ .int = .{
5522 const index_index = try ip.get(gpa, .{ .int = .{
5523 .ty = .usize_type,6277 .ty = .usize_type,
5524 .storage = .{ .u64 = base_index.index },6278 .storage = .{ .u64 = base_index.index },
5525 } });6279 } });
5526 assert(!(try ip.map.getOrPutAdapted(gpa, key, adapter)).found_existing);6280 gop.assign(try ip.getOrPutKey(gpa, tid, key));
5527 try ip.items.ensureUnusedCapacity(gpa, 1);6281 try items.ensureUnusedCapacity(1);
5528 break :item .{6282 items.appendAssumeCapacity(.{
5529 .tag = switch (ptr.base_addr) {6283 .tag = switch (ptr.base_addr) {
5530 .arr_elem => .ptr_elem,6284 .arr_elem => .ptr_elem,
5531 .field => .ptr_field,6285 .field => .ptr_field,
5532 else => unreachable,6286 else => unreachable,
5533 },6287 },
5534 .data = try ip.addExtra(gpa, PtrBaseIndex.init(ptr.ty, base_index.base, index_index, ptr.byte_offset)),6288 .data = try addExtra(extra, PtrBaseIndex.init(ptr.ty, base_index.base, index_index, ptr.byte_offset)),
5535 };6289 });
6290 return gop.put();
5536 },6291 },
5537 });6292 });
5538 },6293 },
...@@ -5540,12 +6295,12 @@ pub fn get(ip: *InternPool, gpa: Allocator, key: Key) Allocator.Error!Index {...@@ -5540,12 +6295,12 @@ pub fn get(ip: *InternPool, gpa: Allocator, key: Key) Allocator.Error!Index {
5540 .opt => |opt| {6295 .opt => |opt| {
5541 assert(ip.isOptionalType(opt.ty));6296 assert(ip.isOptionalType(opt.ty));
5542 assert(opt.val == .none or ip.indexToKey(opt.ty).opt_type == ip.typeOf(opt.val));6297 assert(opt.val == .none or ip.indexToKey(opt.ty).opt_type == ip.typeOf(opt.val));
5543 ip.items.appendAssumeCapacity(if (opt.val == .none) .{6298 items.appendAssumeCapacity(if (opt.val == .none) .{
5544 .tag = .opt_null,6299 .tag = .opt_null,
5545 .data = @intFromEnum(opt.ty),6300 .data = @intFromEnum(opt.ty),
5546 } else .{6301 } else .{
5547 .tag = .opt_payload,6302 .tag = .opt_payload,
5548 .data = try ip.addExtra(gpa, Tag.TypeValue{6303 .data = try addExtra(extra, Tag.TypeValue{
5549 .ty = opt.ty,6304 .ty = opt.ty,
5550 .val = opt.val,6305 .val = opt.val,
5551 }),6306 }),
...@@ -5557,31 +6312,31 @@ pub fn get(ip: *InternPool, gpa: Allocator, key: Key) Allocator.Error!Index {...@@ -5557,31 +6312,31 @@ pub fn get(ip: *InternPool, gpa: Allocator, key: Key) Allocator.Error!Index {
5557 switch (int.storage) {6312 switch (int.storage) {
5558 .u64, .i64, .big_int => {},6313 .u64, .i64, .big_int => {},
5559 .lazy_align, .lazy_size => |lazy_ty| {6314 .lazy_align, .lazy_size => |lazy_ty| {
5560 ip.items.appendAssumeCapacity(.{6315 items.appendAssumeCapacity(.{
5561 .tag = switch (int.storage) {6316 .tag = switch (int.storage) {
5562 else => unreachable,6317 else => unreachable,
5563 .lazy_align => .int_lazy_align,6318 .lazy_align => .int_lazy_align,
5564 .lazy_size => .int_lazy_size,6319 .lazy_size => .int_lazy_size,
5565 },6320 },
5566 .data = try ip.addExtra(gpa, IntLazy{6321 .data = try addExtra(extra, IntLazy{
5567 .ty = int.ty,6322 .ty = int.ty,
5568 .lazy_ty = lazy_ty,6323 .lazy_ty = lazy_ty,
5569 }),6324 }),
5570 });6325 });
5571 return @enumFromInt(ip.items.len - 1);6326 return gop.put();
5572 },6327 },
5573 }6328 }
5574 switch (int.ty) {6329 switch (int.ty) {
5575 .u8_type => switch (int.storage) {6330 .u8_type => switch (int.storage) {
5576 .big_int => |big_int| {6331 .big_int => |big_int| {
5577 ip.items.appendAssumeCapacity(.{6332 items.appendAssumeCapacity(.{
5578 .tag = .int_u8,6333 .tag = .int_u8,
5579 .data = big_int.to(u8) catch unreachable,6334 .data = big_int.to(u8) catch unreachable,
5580 });6335 });
5581 break :b;6336 break :b;
5582 },6337 },
5583 inline .u64, .i64 => |x| {6338 inline .u64, .i64 => |x| {
5584 ip.items.appendAssumeCapacity(.{6339 items.appendAssumeCapacity(.{
5585 .tag = .int_u8,6340 .tag = .int_u8,
5586 .data = @as(u8, @intCast(x)),6341 .data = @as(u8, @intCast(x)),
5587 });6342 });
...@@ -5591,14 +6346,14 @@ pub fn get(ip: *InternPool, gpa: Allocator, key: Key) Allocator.Error!Index {...@@ -5591,14 +6346,14 @@ pub fn get(ip: *InternPool, gpa: Allocator, key: Key) Allocator.Error!Index {
5591 },6346 },
5592 .u16_type => switch (int.storage) {6347 .u16_type => switch (int.storage) {
5593 .big_int => |big_int| {6348 .big_int => |big_int| {
5594 ip.items.appendAssumeCapacity(.{6349 items.appendAssumeCapacity(.{
5595 .tag = .int_u16,6350 .tag = .int_u16,
5596 .data = big_int.to(u16) catch unreachable,6351 .data = big_int.to(u16) catch unreachable,
5597 });6352 });
5598 break :b;6353 break :b;
5599 },6354 },
5600 inline .u64, .i64 => |x| {6355 inline .u64, .i64 => |x| {
5601 ip.items.appendAssumeCapacity(.{6356 items.appendAssumeCapacity(.{
5602 .tag = .int_u16,6357 .tag = .int_u16,
5603 .data = @as(u16, @intCast(x)),6358 .data = @as(u16, @intCast(x)),
5604 });6359 });
...@@ -5608,14 +6363,14 @@ pub fn get(ip: *InternPool, gpa: Allocator, key: Key) Allocator.Error!Index {...@@ -5608,14 +6363,14 @@ pub fn get(ip: *InternPool, gpa: Allocator, key: Key) Allocator.Error!Index {
5608 },6363 },
5609 .u32_type => switch (int.storage) {6364 .u32_type => switch (int.storage) {
5610 .big_int => |big_int| {6365 .big_int => |big_int| {
5611 ip.items.appendAssumeCapacity(.{6366 items.appendAssumeCapacity(.{
5612 .tag = .int_u32,6367 .tag = .int_u32,
5613 .data = big_int.to(u32) catch unreachable,6368 .data = big_int.to(u32) catch unreachable,
5614 });6369 });
5615 break :b;6370 break :b;
5616 },6371 },
5617 inline .u64, .i64 => |x| {6372 inline .u64, .i64 => |x| {
5618 ip.items.appendAssumeCapacity(.{6373 items.appendAssumeCapacity(.{
5619 .tag = .int_u32,6374 .tag = .int_u32,
5620 .data = @as(u32, @intCast(x)),6375 .data = @as(u32, @intCast(x)),
5621 });6376 });
...@@ -5626,14 +6381,14 @@ pub fn get(ip: *InternPool, gpa: Allocator, key: Key) Allocator.Error!Index {...@@ -5626,14 +6381,14 @@ pub fn get(ip: *InternPool, gpa: Allocator, key: Key) Allocator.Error!Index {
5626 .i32_type => switch (int.storage) {6381 .i32_type => switch (int.storage) {
5627 .big_int => |big_int| {6382 .big_int => |big_int| {
5628 const casted = big_int.to(i32) catch unreachable;6383 const casted = big_int.to(i32) catch unreachable;
5629 ip.items.appendAssumeCapacity(.{6384 items.appendAssumeCapacity(.{
5630 .tag = .int_i32,6385 .tag = .int_i32,
5631 .data = @as(u32, @bitCast(casted)),6386 .data = @as(u32, @bitCast(casted)),
5632 });6387 });
5633 break :b;6388 break :b;
5634 },6389 },
5635 inline .u64, .i64 => |x| {6390 inline .u64, .i64 => |x| {
5636 ip.items.appendAssumeCapacity(.{6391 items.appendAssumeCapacity(.{
5637 .tag = .int_i32,6392 .tag = .int_i32,
5638 .data = @as(u32, @bitCast(@as(i32, @intCast(x)))),6393 .data = @as(u32, @bitCast(@as(i32, @intCast(x)))),
5639 });6394 });
...@@ -5644,7 +6399,7 @@ pub fn get(ip: *InternPool, gpa: Allocator, key: Key) Allocator.Error!Index {...@@ -5644,7 +6399,7 @@ pub fn get(ip: *InternPool, gpa: Allocator, key: Key) Allocator.Error!Index {
5644 .usize_type => switch (int.storage) {6399 .usize_type => switch (int.storage) {
5645 .big_int => |big_int| {6400 .big_int => |big_int| {
5646 if (big_int.to(u32)) |casted| {6401 if (big_int.to(u32)) |casted| {
5647 ip.items.appendAssumeCapacity(.{6402 items.appendAssumeCapacity(.{
5648 .tag = .int_usize,6403 .tag = .int_usize,
5649 .data = casted,6404 .data = casted,
5650 });6405 });
...@@ -5653,7 +6408,7 @@ pub fn get(ip: *InternPool, gpa: Allocator, key: Key) Allocator.Error!Index {...@@ -5653,7 +6408,7 @@ pub fn get(ip: *InternPool, gpa: Allocator, key: Key) Allocator.Error!Index {
5653 },6408 },
5654 inline .u64, .i64 => |x| {6409 inline .u64, .i64 => |x| {
5655 if (std.math.cast(u32, x)) |casted| {6410 if (std.math.cast(u32, x)) |casted| {
5656 ip.items.appendAssumeCapacity(.{6411 items.appendAssumeCapacity(.{
5657 .tag = .int_usize,6412 .tag = .int_usize,
5658 .data = casted,6413 .data = casted,
5659 });6414 });
...@@ -5665,14 +6420,14 @@ pub fn get(ip: *InternPool, gpa: Allocator, key: Key) Allocator.Error!Index {...@@ -5665,14 +6420,14 @@ pub fn get(ip: *InternPool, gpa: Allocator, key: Key) Allocator.Error!Index {
5665 .comptime_int_type => switch (int.storage) {6420 .comptime_int_type => switch (int.storage) {
5666 .big_int => |big_int| {6421 .big_int => |big_int| {
5667 if (big_int.to(u32)) |casted| {6422 if (big_int.to(u32)) |casted| {
5668 ip.items.appendAssumeCapacity(.{6423 items.appendAssumeCapacity(.{
5669 .tag = .int_comptime_int_u32,6424 .tag = .int_comptime_int_u32,
5670 .data = casted,6425 .data = casted,
5671 });6426 });
5672 break :b;6427 break :b;
5673 } else |_| {}6428 } else |_| {}
5674 if (big_int.to(i32)) |casted| {6429 if (big_int.to(i32)) |casted| {
5675 ip.items.appendAssumeCapacity(.{6430 items.appendAssumeCapacity(.{
5676 .tag = .int_comptime_int_i32,6431 .tag = .int_comptime_int_i32,
5677 .data = @as(u32, @bitCast(casted)),6432 .data = @as(u32, @bitCast(casted)),
5678 });6433 });
...@@ -5681,14 +6436,14 @@ pub fn get(ip: *InternPool, gpa: Allocator, key: Key) Allocator.Error!Index {...@@ -5681,14 +6436,14 @@ pub fn get(ip: *InternPool, gpa: Allocator, key: Key) Allocator.Error!Index {
5681 },6436 },
5682 inline .u64, .i64 => |x| {6437 inline .u64, .i64 => |x| {
5683 if (std.math.cast(u32, x)) |casted| {6438 if (std.math.cast(u32, x)) |casted| {
5684 ip.items.appendAssumeCapacity(.{6439 items.appendAssumeCapacity(.{
5685 .tag = .int_comptime_int_u32,6440 .tag = .int_comptime_int_u32,
5686 .data = casted,6441 .data = casted,
5687 });6442 });
5688 break :b;6443 break :b;
5689 }6444 }
5690 if (std.math.cast(i32, x)) |casted| {6445 if (std.math.cast(i32, x)) |casted| {
5691 ip.items.appendAssumeCapacity(.{6446 items.appendAssumeCapacity(.{
5692 .tag = .int_comptime_int_i32,6447 .tag = .int_comptime_int_i32,
5693 .data = @as(u32, @bitCast(casted)),6448 .data = @as(u32, @bitCast(casted)),
5694 });6449 });
...@@ -5702,35 +6457,35 @@ pub fn get(ip: *InternPool, gpa: Allocator, key: Key) Allocator.Error!Index {...@@ -5702,35 +6457,35 @@ pub fn get(ip: *InternPool, gpa: Allocator, key: Key) Allocator.Error!Index {
5702 switch (int.storage) {6457 switch (int.storage) {
5703 .big_int => |big_int| {6458 .big_int => |big_int| {
5704 if (big_int.to(u32)) |casted| {6459 if (big_int.to(u32)) |casted| {
5705 ip.items.appendAssumeCapacity(.{6460 items.appendAssumeCapacity(.{
5706 .tag = .int_small,6461 .tag = .int_small,
5707 .data = try ip.addExtra(gpa, IntSmall{6462 .data = try addExtra(extra, IntSmall{
5708 .ty = int.ty,6463 .ty = int.ty,
5709 .value = casted,6464 .value = casted,
5710 }),6465 }),
5711 });6466 });
5712 return @enumFromInt(ip.items.len - 1);6467 return gop.put();
5713 } else |_| {}6468 } else |_| {}
57146469
5715 const tag: Tag = if (big_int.positive) .int_positive else .int_negative;6470 const tag: Tag = if (big_int.positive) .int_positive else .int_negative;
5716 try addInt(ip, gpa, int.ty, tag, big_int.limbs);6471 try addInt(ip, gpa, tid, int.ty, tag, big_int.limbs);
5717 },6472 },
5718 inline .u64, .i64 => |x| {6473 inline .u64, .i64 => |x| {
5719 if (std.math.cast(u32, x)) |casted| {6474 if (std.math.cast(u32, x)) |casted| {
5720 ip.items.appendAssumeCapacity(.{6475 items.appendAssumeCapacity(.{
5721 .tag = .int_small,6476 .tag = .int_small,
5722 .data = try ip.addExtra(gpa, IntSmall{6477 .data = try addExtra(extra, IntSmall{
5723 .ty = int.ty,6478 .ty = int.ty,
5724 .value = casted,6479 .value = casted,
5725 }),6480 }),
5726 });6481 });
5727 return @enumFromInt(ip.items.len - 1);6482 return gop.put();
5728 }6483 }
57296484
5730 var buf: [2]Limb = undefined;6485 var buf: [2]Limb = undefined;
5731 const big_int = BigIntMutable.init(&buf, x).toConst();6486 const big_int = BigIntMutable.init(&buf, x).toConst();
5732 const tag: Tag = if (big_int.positive) .int_positive else .int_negative;6487 const tag: Tag = if (big_int.positive) .int_positive else .int_negative;
5733 try addInt(ip, gpa, int.ty, tag, big_int.limbs);6488 try addInt(ip, gpa, tid, int.ty, tag, big_int.limbs);
5734 },6489 },
5735 .lazy_align, .lazy_size => unreachable,6490 .lazy_align, .lazy_size => unreachable,
5736 }6491 }
...@@ -5738,25 +6493,25 @@ pub fn get(ip: *InternPool, gpa: Allocator, key: Key) Allocator.Error!Index {...@@ -5738,25 +6493,25 @@ pub fn get(ip: *InternPool, gpa: Allocator, key: Key) Allocator.Error!Index {
57386493
5739 .err => |err| {6494 .err => |err| {
5740 assert(ip.isErrorSetType(err.ty));6495 assert(ip.isErrorSetType(err.ty));
5741 ip.items.appendAssumeCapacity(.{6496 items.appendAssumeCapacity(.{
5742 .tag = .error_set_error,6497 .tag = .error_set_error,
5743 .data = try ip.addExtra(gpa, err),6498 .data = try addExtra(extra, err),
5744 });6499 });
5745 },6500 },
57466501
5747 .error_union => |error_union| {6502 .error_union => |error_union| {
5748 assert(ip.isErrorUnionType(error_union.ty));6503 assert(ip.isErrorUnionType(error_union.ty));
5749 ip.items.appendAssumeCapacity(switch (error_union.val) {6504 items.appendAssumeCapacity(switch (error_union.val) {
5750 .err_name => |err_name| .{6505 .err_name => |err_name| .{
5751 .tag = .error_union_error,6506 .tag = .error_union_error,
5752 .data = try ip.addExtra(gpa, Key.Error{6507 .data = try addExtra(extra, Key.Error{
5753 .ty = error_union.ty,6508 .ty = error_union.ty,
5754 .name = err_name,6509 .name = err_name,
5755 }),6510 }),
5756 },6511 },
5757 .payload => |payload| .{6512 .payload => |payload| .{
5758 .tag = .error_union_payload,6513 .tag = .error_union_payload,
5759 .data = try ip.addExtra(gpa, Tag.TypeValue{6514 .data = try addExtra(extra, Tag.TypeValue{
5760 .ty = error_union.ty,6515 .ty = error_union.ty,
5761 .val = payload,6516 .val = payload,
5762 }),6517 }),
...@@ -5764,7 +6519,7 @@ pub fn get(ip: *InternPool, gpa: Allocator, key: Key) Allocator.Error!Index {...@@ -5764,7 +6519,7 @@ pub fn get(ip: *InternPool, gpa: Allocator, key: Key) Allocator.Error!Index {
5764 });6519 });
5765 },6520 },
57666521
5767 .enum_literal => |enum_literal| ip.items.appendAssumeCapacity(.{6522 .enum_literal => |enum_literal| items.appendAssumeCapacity(.{
5768 .tag = .enum_literal,6523 .tag = .enum_literal,
5769 .data = @intFromEnum(enum_literal),6524 .data = @intFromEnum(enum_literal),
5770 }),6525 }),
...@@ -5776,52 +6531,52 @@ pub fn get(ip: *InternPool, gpa: Allocator, key: Key) Allocator.Error!Index {...@@ -5776,52 +6531,52 @@ pub fn get(ip: *InternPool, gpa: Allocator, key: Key) Allocator.Error!Index {
5776 .enum_type => assert(ip.typeOf(enum_tag.int) == ip.loadEnumType(enum_tag.ty).tag_ty),6531 .enum_type => assert(ip.typeOf(enum_tag.int) == ip.loadEnumType(enum_tag.ty).tag_ty),
5777 else => unreachable,6532 else => unreachable,
5778 }6533 }
5779 ip.items.appendAssumeCapacity(.{6534 items.appendAssumeCapacity(.{
5780 .tag = .enum_tag,6535 .tag = .enum_tag,
5781 .data = try ip.addExtra(gpa, enum_tag),6536 .data = try addExtra(extra, enum_tag),
5782 });6537 });
5783 },6538 },
57846539
5785 .empty_enum_value => |enum_or_union_ty| ip.items.appendAssumeCapacity(.{6540 .empty_enum_value => |enum_or_union_ty| items.appendAssumeCapacity(.{
5786 .tag = .only_possible_value,6541 .tag = .only_possible_value,
5787 .data = @intFromEnum(enum_or_union_ty),6542 .data = @intFromEnum(enum_or_union_ty),
5788 }),6543 }),
57896544
5790 .float => |float| {6545 .float => |float| {
5791 switch (float.ty) {6546 switch (float.ty) {
5792 .f16_type => ip.items.appendAssumeCapacity(.{6547 .f16_type => items.appendAssumeCapacity(.{
5793 .tag = .float_f16,6548 .tag = .float_f16,
5794 .data = @as(u16, @bitCast(float.storage.f16)),6549 .data = @as(u16, @bitCast(float.storage.f16)),
5795 }),6550 }),
5796 .f32_type => ip.items.appendAssumeCapacity(.{6551 .f32_type => items.appendAssumeCapacity(.{
5797 .tag = .float_f32,6552 .tag = .float_f32,
5798 .data = @as(u32, @bitCast(float.storage.f32)),6553 .data = @as(u32, @bitCast(float.storage.f32)),
5799 }),6554 }),
5800 .f64_type => ip.items.appendAssumeCapacity(.{6555 .f64_type => items.appendAssumeCapacity(.{
5801 .tag = .float_f64,6556 .tag = .float_f64,
5802 .data = try ip.addExtra(gpa, Float64.pack(float.storage.f64)),6557 .data = try addExtra(extra, Float64.pack(float.storage.f64)),
5803 }),6558 }),
5804 .f80_type => ip.items.appendAssumeCapacity(.{6559 .f80_type => items.appendAssumeCapacity(.{
5805 .tag = .float_f80,6560 .tag = .float_f80,
5806 .data = try ip.addExtra(gpa, Float80.pack(float.storage.f80)),6561 .data = try addExtra(extra, Float80.pack(float.storage.f80)),
5807 }),6562 }),
5808 .f128_type => ip.items.appendAssumeCapacity(.{6563 .f128_type => items.appendAssumeCapacity(.{
5809 .tag = .float_f128,6564 .tag = .float_f128,
5810 .data = try ip.addExtra(gpa, Float128.pack(float.storage.f128)),6565 .data = try addExtra(extra, Float128.pack(float.storage.f128)),
5811 }),6566 }),
5812 .c_longdouble_type => switch (float.storage) {6567 .c_longdouble_type => switch (float.storage) {
5813 .f80 => |x| ip.items.appendAssumeCapacity(.{6568 .f80 => |x| items.appendAssumeCapacity(.{
5814 .tag = .float_c_longdouble_f80,6569 .tag = .float_c_longdouble_f80,
5815 .data = try ip.addExtra(gpa, Float80.pack(x)),6570 .data = try addExtra(extra, Float80.pack(x)),
5816 }),6571 }),
5817 inline .f16, .f32, .f64, .f128 => |x| ip.items.appendAssumeCapacity(.{6572 inline .f16, .f32, .f64, .f128 => |x| items.appendAssumeCapacity(.{
5818 .tag = .float_c_longdouble_f128,6573 .tag = .float_c_longdouble_f128,
5819 .data = try ip.addExtra(gpa, Float128.pack(x)),6574 .data = try addExtra(extra, Float128.pack(x)),
5820 }),6575 }),
5821 },6576 },
5822 .comptime_float_type => ip.items.appendAssumeCapacity(.{6577 .comptime_float_type => items.appendAssumeCapacity(.{
5823 .tag = .float_comptime_float,6578 .tag = .float_comptime_float,
5824 .data = try ip.addExtra(gpa, Float128.pack(float.storage.f128)),6579 .data = try addExtra(extra, Float128.pack(float.storage.f128)),
5825 }),6580 }),
5826 else => unreachable,6581 else => unreachable,
5827 }6582 }
...@@ -5879,11 +6634,11 @@ pub fn get(ip: *InternPool, gpa: Allocator, key: Key) Allocator.Error!Index {...@@ -5879,11 +6634,11 @@ pub fn get(ip: *InternPool, gpa: Allocator, key: Key) Allocator.Error!Index {
5879 }6634 }
58806635
5881 if (len == 0) {6636 if (len == 0) {
5882 ip.items.appendAssumeCapacity(.{6637 items.appendAssumeCapacity(.{
5883 .tag = .only_possible_value,6638 .tag = .only_possible_value,
5884 .data = @intFromEnum(aggregate.ty),6639 .data = @intFromEnum(aggregate.ty),
5885 });6640 });
5886 return @enumFromInt(ip.items.len - 1);6641 return gop.put();
5887 }6642 }
58886643
5889 switch (ty_key) {6644 switch (ty_key) {
...@@ -5912,11 +6667,11 @@ pub fn get(ip: *InternPool, gpa: Allocator, key: Key) Allocator.Error!Index {...@@ -5912,11 +6667,11 @@ pub fn get(ip: *InternPool, gpa: Allocator, key: Key) Allocator.Error!Index {
5912 // This encoding works thanks to the fact that, as we just verified,6667 // This encoding works thanks to the fact that, as we just verified,
5913 // the type itself contains a slice of values that can be provided6668 // the type itself contains a slice of values that can be provided
5914 // in the aggregate fields.6669 // in the aggregate fields.
5915 ip.items.appendAssumeCapacity(.{6670 items.appendAssumeCapacity(.{
5916 .tag = .only_possible_value,6671 .tag = .only_possible_value,
5917 .data = @intFromEnum(aggregate.ty),6672 .data = @intFromEnum(aggregate.ty),
5918 });6673 });
5919 return @enumFromInt(ip.items.len - 1);6674 return gop.put();
5920 },6675 },
5921 else => {},6676 else => {},
5922 }6677 }
...@@ -5931,115 +6686,110 @@ pub fn get(ip: *InternPool, gpa: Allocator, key: Key) Allocator.Error!Index {...@@ -5931,115 +6686,110 @@ pub fn get(ip: *InternPool, gpa: Allocator, key: Key) Allocator.Error!Index {
5931 }6686 }
5932 const elem = switch (aggregate.storage) {6687 const elem = switch (aggregate.storage) {
5933 .bytes => |bytes| elem: {6688 .bytes => |bytes| elem: {
5934 _ = ip.map.pop();6689 const elem = try ip.get(gpa, tid, .{ .int = .{
5935 const elem = try ip.get(gpa, .{ .int = .{
5936 .ty = .u8_type,6690 .ty = .u8_type,
5937 .storage = .{ .u64 = bytes.at(0, ip) },6691 .storage = .{ .u64 = bytes.at(0, ip) },
5938 } });6692 } });
5939 assert(!(try ip.map.getOrPutAdapted(gpa, key, adapter)).found_existing);6693 gop.assign(try ip.getOrPutKey(gpa, tid, key));
5940 try ip.items.ensureUnusedCapacity(gpa, 1);6694 try items.ensureUnusedCapacity(1);
5941 break :elem elem;6695 break :elem elem;
5942 },6696 },
5943 .elems => |elems| elems[0],6697 .elems => |elems| elems[0],
5944 .repeated_elem => |elem| elem,6698 .repeated_elem => |elem| elem,
5945 };6699 };
59466700
5947 try ip.extra.ensureUnusedCapacity(6701 try extra.ensureUnusedCapacity(@typeInfo(Repeated).Struct.fields.len);
5948 gpa,6702 items.appendAssumeCapacity(.{
5949 @typeInfo(Repeated).Struct.fields.len,
5950 );
5951 ip.items.appendAssumeCapacity(.{
5952 .tag = .repeated,6703 .tag = .repeated,
5953 .data = ip.addExtraAssumeCapacity(Repeated{6704 .data = addExtraAssumeCapacity(extra, Repeated{
5954 .ty = aggregate.ty,6705 .ty = aggregate.ty,
5955 .elem_val = elem,6706 .elem_val = elem,
5956 }),6707 }),
5957 });6708 });
5958 return @enumFromInt(ip.items.len - 1);6709 return gop.put();
5959 }6710 }
59606711
5961 if (child == .u8_type) bytes: {6712 if (child == .u8_type) bytes: {
5962 const string_bytes_index = ip.string_bytes.items.len;6713 const strings = ip.getLocal(tid).getMutableStrings(gpa);
5963 try ip.string_bytes.ensureUnusedCapacity(gpa, @intCast(len_including_sentinel + 1));6714 const start = strings.mutate.len;
5964 try ip.extra.ensureUnusedCapacity(gpa, @typeInfo(Bytes).Struct.fields.len);6715 try strings.ensureUnusedCapacity(@intCast(len_including_sentinel + 1));
6716 try extra.ensureUnusedCapacity(@typeInfo(Bytes).Struct.fields.len);
5965 switch (aggregate.storage) {6717 switch (aggregate.storage) {
5966 .bytes => |bytes| ip.string_bytes.appendSliceAssumeCapacity(bytes.toSlice(len, ip)),6718 .bytes => |bytes| strings.appendSliceAssumeCapacity(.{bytes.toSlice(len, ip)}),
5967 .elems => |elems| for (elems[0..@intCast(len)]) |elem| switch (ip.indexToKey(elem)) {6719 .elems => |elems| for (elems[0..@intCast(len)]) |elem| switch (ip.indexToKey(elem)) {
5968 .undef => {6720 .undef => {
5969 ip.string_bytes.shrinkRetainingCapacity(string_bytes_index);6721 strings.shrinkRetainingCapacity(start);
5970 break :bytes;6722 break :bytes;
5971 },6723 },
5972 .int => |int| ip.string_bytes.appendAssumeCapacity(6724 .int => |int| strings.appendAssumeCapacity(.{@intCast(int.storage.u64)}),
5973 @intCast(int.storage.u64),
5974 ),
5975 else => unreachable,6725 else => unreachable,
5976 },6726 },
5977 .repeated_elem => |elem| switch (ip.indexToKey(elem)) {6727 .repeated_elem => |elem| switch (ip.indexToKey(elem)) {
5978 .undef => break :bytes,6728 .undef => break :bytes,
5979 .int => |int| @memset(6729 .int => |int| @memset(
5980 ip.string_bytes.addManyAsSliceAssumeCapacity(@intCast(len)),6730 strings.addManyAsSliceAssumeCapacity(@intCast(len))[0],
5981 @intCast(int.storage.u64),6731 @intCast(int.storage.u64),
5982 ),6732 ),
5983 else => unreachable,6733 else => unreachable,
5984 },6734 },
5985 }6735 }
5986 if (sentinel != .none) ip.string_bytes.appendAssumeCapacity(6736 if (sentinel != .none) strings.appendAssumeCapacity(.{
5987 @intCast(ip.indexToKey(sentinel).int.storage.u64),6737 @intCast(ip.indexToKey(sentinel).int.storage.u64),
5988 );6738 });
5989 const string = try ip.getOrPutTrailingString(6739 const string = try ip.getOrPutTrailingString(
5990 gpa,6740 gpa,
6741 tid,
5991 @intCast(len_including_sentinel),6742 @intCast(len_including_sentinel),
5992 .maybe_embedded_nulls,6743 .maybe_embedded_nulls,
5993 );6744 );
5994 ip.items.appendAssumeCapacity(.{6745 items.appendAssumeCapacity(.{
5995 .tag = .bytes,6746 .tag = .bytes,
5996 .data = ip.addExtraAssumeCapacity(Bytes{6747 .data = addExtraAssumeCapacity(extra, Bytes{
5997 .ty = aggregate.ty,6748 .ty = aggregate.ty,
5998 .bytes = string,6749 .bytes = string,
5999 }),6750 }),
6000 });6751 });
6001 return @enumFromInt(ip.items.len - 1);6752 return gop.put();
6002 }6753 }
60036754
6004 try ip.extra.ensureUnusedCapacity(6755 try extra.ensureUnusedCapacity(
6005 gpa,
6006 @typeInfo(Tag.Aggregate).Struct.fields.len + @as(usize, @intCast(len_including_sentinel + 1)),6756 @typeInfo(Tag.Aggregate).Struct.fields.len + @as(usize, @intCast(len_including_sentinel + 1)),
6007 );6757 );
6008 ip.items.appendAssumeCapacity(.{6758 items.appendAssumeCapacity(.{
6009 .tag = .aggregate,6759 .tag = .aggregate,
6010 .data = ip.addExtraAssumeCapacity(Tag.Aggregate{6760 .data = addExtraAssumeCapacity(extra, Tag.Aggregate{
6011 .ty = aggregate.ty,6761 .ty = aggregate.ty,
6012 }),6762 }),
6013 });6763 });
6014 ip.extra.appendSliceAssumeCapacity(@ptrCast(aggregate.storage.elems));6764 extra.appendSliceAssumeCapacity(.{@ptrCast(aggregate.storage.elems)});
6015 if (sentinel != .none) ip.extra.appendAssumeCapacity(@intFromEnum(sentinel));6765 if (sentinel != .none) extra.appendAssumeCapacity(.{@intFromEnum(sentinel)});
6016 },6766 },
60176767
6018 .un => |un| {6768 .un => |un| {
6019 assert(un.ty != .none);6769 assert(un.ty != .none);
6020 assert(un.val != .none);6770 assert(un.val != .none);
6021 ip.items.appendAssumeCapacity(.{6771 items.appendAssumeCapacity(.{
6022 .tag = .union_value,6772 .tag = .union_value,
6023 .data = try ip.addExtra(gpa, un),6773 .data = try addExtra(extra, un),
6024 });6774 });
6025 },6775 },
60266776
6027 .memoized_call => |memoized_call| {6777 .memoized_call => |memoized_call| {
6028 for (memoized_call.arg_values) |arg| assert(arg != .none);6778 for (memoized_call.arg_values) |arg| assert(arg != .none);
6029 try ip.extra.ensureUnusedCapacity(gpa, @typeInfo(MemoizedCall).Struct.fields.len +6779 try extra.ensureUnusedCapacity(@typeInfo(MemoizedCall).Struct.fields.len +
6030 memoized_call.arg_values.len);6780 memoized_call.arg_values.len);
6031 ip.items.appendAssumeCapacity(.{6781 items.appendAssumeCapacity(.{
6032 .tag = .memoized_call,6782 .tag = .memoized_call,
6033 .data = ip.addExtraAssumeCapacity(MemoizedCall{6783 .data = addExtraAssumeCapacity(extra, MemoizedCall{
6034 .func = memoized_call.func,6784 .func = memoized_call.func,
6035 .args_len = @intCast(memoized_call.arg_values.len),6785 .args_len = @intCast(memoized_call.arg_values.len),
6036 .result = memoized_call.result,6786 .result = memoized_call.result,
6037 }),6787 }),
6038 });6788 });
6039 ip.extra.appendSliceAssumeCapacity(@ptrCast(memoized_call.arg_values));6789 extra.appendSliceAssumeCapacity(.{@ptrCast(memoized_call.arg_values)});
6040 },6790 },
6041 }6791 }
6042 return @enumFromInt(ip.items.len - 1);6792 return gop.put();
6043}6793}
60446794
6045pub const UnionTypeInit = struct {6795pub const UnionTypeInit = struct {
...@@ -6074,9 +6824,13 @@ pub const UnionTypeInit = struct {...@@ -6074,9 +6824,13 @@ pub const UnionTypeInit = struct {
6074 },6824 },
6075};6825};
60766826
6077pub fn getUnionType(ip: *InternPool, gpa: Allocator, ini: UnionTypeInit) Allocator.Error!WipNamespaceType.Result {6827pub fn getUnionType(
6078 const adapter: KeyAdapter = .{ .intern_pool = ip };6828 ip: *InternPool,
6079 const gop = try ip.map.getOrPutAdapted(gpa, Key{ .union_type = switch (ini.key) {6829 gpa: Allocator,
6830 tid: Zcu.PerThread.Id,
6831 ini: UnionTypeInit,
6832) Allocator.Error!WipNamespaceType.Result {
6833 var gop = try ip.getOrPutKey(gpa, tid, .{ .union_type = switch (ini.key) {
6080 .declared => |d| .{ .declared = .{6834 .declared => |d| .{ .declared = .{
6081 .zir_index = d.zir_index,6835 .zir_index = d.zir_index,
6082 .captures = .{ .external = d.captures },6836 .captures = .{ .external = d.captures },
...@@ -6085,13 +6839,18 @@ pub fn getUnionType(ip: *InternPool, gpa: Allocator, ini: UnionTypeInit) Allocat...@@ -6085,13 +6839,18 @@ pub fn getUnionType(ip: *InternPool, gpa: Allocator, ini: UnionTypeInit) Allocat
6085 .zir_index = r.zir_index,6839 .zir_index = r.zir_index,
6086 .type_hash = r.type_hash,6840 .type_hash = r.type_hash,
6087 } },6841 } },
6088 } }, adapter);6842 } });
6089 if (gop.found_existing) return .{ .existing = @enumFromInt(gop.index) };6843 defer gop.deinit();
6090 errdefer _ = ip.map.pop();6844 if (gop == .existing) return .{ .existing = gop.existing };
6845
6846 const local = ip.getLocal(tid);
6847 const items = local.getMutableItems(gpa);
6848 try items.ensureUnusedCapacity(1);
6849 const extra = local.getMutableExtra(gpa);
60916850
6092 const align_elements_len = if (ini.flags.any_aligned_fields) (ini.fields_len + 3) / 4 else 0;6851 const align_elements_len = if (ini.flags.any_aligned_fields) (ini.fields_len + 3) / 4 else 0;
6093 const align_element: u32 = @bitCast([1]u8{@intFromEnum(Alignment.none)} ** 4);6852 const align_element: u32 = @bitCast([1]u8{@intFromEnum(Alignment.none)} ** 4);
6094 try ip.extra.ensureUnusedCapacity(gpa, @typeInfo(Tag.TypeUnion).Struct.fields.len +6853 try extra.ensureUnusedCapacity(@typeInfo(Tag.TypeUnion).Struct.fields.len +
6095 // TODO: fmt bug6854 // TODO: fmt bug
6096 // zig fmt: off6855 // zig fmt: off
6097 switch (ini.key) {6856 switch (ini.key) {
...@@ -6101,9 +6860,8 @@ pub fn getUnionType(ip: *InternPool, gpa: Allocator, ini: UnionTypeInit) Allocat...@@ -6101,9 +6860,8 @@ pub fn getUnionType(ip: *InternPool, gpa: Allocator, ini: UnionTypeInit) Allocat
6101 // zig fmt: on6860 // zig fmt: on
6102 ini.fields_len + // field types6861 ini.fields_len + // field types
6103 align_elements_len);6862 align_elements_len);
6104 try ip.items.ensureUnusedCapacity(gpa, 1);
61056863
6106 const extra_index = ip.addExtraAssumeCapacity(Tag.TypeUnion{6864 const extra_index = addExtraAssumeCapacity(extra, Tag.TypeUnion{
6107 .flags = .{6865 .flags = .{
6108 .any_captures = ini.key == .declared and ini.key.declared.captures.len != 0,6866 .any_captures = ini.key == .declared and ini.key.declared.captures.len != 0,
6109 .runtime_tag = ini.flags.runtime_tag,6867 .runtime_tag = ini.flags.runtime_tag,
...@@ -6127,34 +6885,35 @@ pub fn getUnionType(ip: *InternPool, gpa: Allocator, ini: UnionTypeInit) Allocat...@@ -6127,34 +6885,35 @@ pub fn getUnionType(ip: *InternPool, gpa: Allocator, ini: UnionTypeInit) Allocat
6127 },6885 },
6128 });6886 });
61296887
6130 ip.items.appendAssumeCapacity(.{6888 items.appendAssumeCapacity(.{
6131 .tag = .type_union,6889 .tag = .type_union,
6132 .data = extra_index,6890 .data = extra_index,
6133 });6891 });
61346892
6135 switch (ini.key) {6893 switch (ini.key) {
6136 .declared => |d| if (d.captures.len != 0) {6894 .declared => |d| if (d.captures.len != 0) {
6137 ip.extra.appendAssumeCapacity(@intCast(d.captures.len));6895 extra.appendAssumeCapacity(.{@intCast(d.captures.len)});
6138 ip.extra.appendSliceAssumeCapacity(@ptrCast(d.captures));6896 extra.appendSliceAssumeCapacity(.{@ptrCast(d.captures)});
6139 },6897 },
6140 .reified => |r| _ = ip.addExtraAssumeCapacity(PackedU64.init(r.type_hash)),6898 .reified => |r| _ = addExtraAssumeCapacity(extra, PackedU64.init(r.type_hash)),
6141 }6899 }
61426900
6143 // field types6901 // field types
6144 if (ini.field_types.len > 0) {6902 if (ini.field_types.len > 0) {
6145 assert(ini.field_types.len == ini.fields_len);6903 assert(ini.field_types.len == ini.fields_len);
6146 ip.extra.appendSliceAssumeCapacity(@ptrCast(ini.field_types));6904 extra.appendSliceAssumeCapacity(.{@ptrCast(ini.field_types)});
6147 } else {6905 } else {
6148 ip.extra.appendNTimesAssumeCapacity(@intFromEnum(Index.none), ini.fields_len);6906 extra.appendNTimesAssumeCapacity(.{@intFromEnum(Index.none)}, ini.fields_len);
6149 }6907 }
61506908
6151 // field alignments6909 // field alignments
6152 if (ini.flags.any_aligned_fields) {6910 if (ini.flags.any_aligned_fields) {
6153 ip.extra.appendNTimesAssumeCapacity(align_element, align_elements_len);6911 extra.appendNTimesAssumeCapacity(.{align_element}, align_elements_len);
6154 if (ini.field_aligns.len > 0) {6912 if (ini.field_aligns.len > 0) {
6155 assert(ini.field_aligns.len == ini.fields_len);6913 assert(ini.field_aligns.len == ini.fields_len);
6156 @memcpy((Alignment.Slice{6914 @memcpy((Alignment.Slice{
6157 .start = @intCast(ip.extra.items.len - align_elements_len),6915 .tid = tid,
6916 .start = @intCast(extra.mutate.len - align_elements_len),
6158 .len = @intCast(ini.field_aligns.len),6917 .len = @intCast(ini.field_aligns.len),
6159 }).get(ip), ini.field_aligns);6918 }).get(ip), ini.field_aligns);
6160 }6919 }
...@@ -6163,7 +6922,8 @@ pub fn getUnionType(ip: *InternPool, gpa: Allocator, ini: UnionTypeInit) Allocat...@@ -6163,7 +6922,8 @@ pub fn getUnionType(ip: *InternPool, gpa: Allocator, ini: UnionTypeInit) Allocat
6163 }6922 }
61646923
6165 return .{ .wip = .{6924 return .{ .wip = .{
6166 .index = @enumFromInt(ip.items.len - 1),6925 .tid = tid,
6926 .index = gop.put(),
6167 .decl_extra_index = extra_index + std.meta.fieldIndex(Tag.TypeUnion, "decl").?,6927 .decl_extra_index = extra_index + std.meta.fieldIndex(Tag.TypeUnion, "decl").?,
6168 .namespace_extra_index = if (ini.has_namespace)6928 .namespace_extra_index = if (ini.has_namespace)
6169 extra_index + std.meta.fieldIndex(Tag.TypeUnion, "namespace").?6929 extra_index + std.meta.fieldIndex(Tag.TypeUnion, "namespace").?
...@@ -6173,20 +6933,22 @@ pub fn getUnionType(ip: *InternPool, gpa: Allocator, ini: UnionTypeInit) Allocat...@@ -6173,20 +6933,22 @@ pub fn getUnionType(ip: *InternPool, gpa: Allocator, ini: UnionTypeInit) Allocat
6173}6933}
61746934
6175pub const WipNamespaceType = struct {6935pub const WipNamespaceType = struct {
6936 tid: Zcu.PerThread.Id,
6176 index: Index,6937 index: Index,
6177 decl_extra_index: u32,6938 decl_extra_index: u32,
6178 namespace_extra_index: ?u32,6939 namespace_extra_index: ?u32,
6179 pub fn finish(wip: WipNamespaceType, ip: *InternPool, decl: DeclIndex, namespace: OptionalNamespaceIndex) Index {6940 pub fn finish(wip: WipNamespaceType, ip: *InternPool, decl: DeclIndex, namespace: OptionalNamespaceIndex) Index {
6180 ip.extra.items[wip.decl_extra_index] = @intFromEnum(decl);6941 const extra_items = ip.getLocalShared(wip.tid).extra.acquire().view().items(.@"0");
6942 extra_items[wip.decl_extra_index] = @intFromEnum(decl);
6181 if (wip.namespace_extra_index) |i| {6943 if (wip.namespace_extra_index) |i| {
6182 ip.extra.items[i] = @intFromEnum(namespace.unwrap().?);6944 extra_items[i] = @intFromEnum(namespace.unwrap().?);
6183 } else {6945 } else {
6184 assert(namespace == .none);6946 assert(namespace == .none);
6185 }6947 }
6186 return wip.index;6948 return wip.index;
6187 }6949 }
6188 pub fn cancel(wip: WipNamespaceType, ip: *InternPool) void {6950 pub fn cancel(wip: WipNamespaceType, ip: *InternPool, tid: Zcu.PerThread.Id) void {
6189 ip.remove(wip.index);6951 ip.remove(tid, wip.index);
6190 }6952 }
61916953
6192 pub const Result = union(enum) {6954 pub const Result = union(enum) {
...@@ -6221,10 +6983,10 @@ pub const StructTypeInit = struct {...@@ -6221,10 +6983,10 @@ pub const StructTypeInit = struct {
6221pub fn getStructType(6983pub fn getStructType(
6222 ip: *InternPool,6984 ip: *InternPool,
6223 gpa: Allocator,6985 gpa: Allocator,
6986 tid: Zcu.PerThread.Id,
6224 ini: StructTypeInit,6987 ini: StructTypeInit,
6225) Allocator.Error!WipNamespaceType.Result {6988) Allocator.Error!WipNamespaceType.Result {
6226 const adapter: KeyAdapter = .{ .intern_pool = ip };6989 var gop = try ip.getOrPutKey(gpa, tid, .{ .struct_type = switch (ini.key) {
6227 const key: Key = .{ .struct_type = switch (ini.key) {
6228 .declared => |d| .{ .declared = .{6990 .declared => |d| .{ .declared = .{
6229 .zir_index = d.zir_index,6991 .zir_index = d.zir_index,
6230 .captures = .{ .external = d.captures },6992 .captures = .{ .external = d.captures },
...@@ -6233,10 +6995,13 @@ pub fn getStructType(...@@ -6233,10 +6995,13 @@ pub fn getStructType(
6233 .zir_index = r.zir_index,6995 .zir_index = r.zir_index,
6234 .type_hash = r.type_hash,6996 .type_hash = r.type_hash,
6235 } },6997 } },
6236 } };6998 } });
6237 const gop = try ip.map.getOrPutAdapted(gpa, key, adapter);6999 defer gop.deinit();
6238 if (gop.found_existing) return .{ .existing = @enumFromInt(gop.index) };7000 if (gop == .existing) return .{ .existing = gop.existing };
6239 errdefer _ = ip.map.pop();7001
7002 const local = ip.getLocal(tid);
7003 const items = local.getMutableItems(gpa);
7004 const extra = local.getMutableExtra(gpa);
62407005
6241 const names_map = try ip.addMap(gpa, ini.fields_len);7006 const names_map = try ip.addMap(gpa, ini.fields_len);
6242 errdefer _ = ip.maps.pop();7007 errdefer _ = ip.maps.pop();
...@@ -6249,7 +7014,7 @@ pub fn getStructType(...@@ -6249,7 +7014,7 @@ pub fn getStructType(
6249 .auto => false,7014 .auto => false,
6250 .@"extern" => true,7015 .@"extern" => true,
6251 .@"packed" => {7016 .@"packed" => {
6252 try ip.extra.ensureUnusedCapacity(gpa, @typeInfo(Tag.TypeStructPacked).Struct.fields.len +7017 try extra.ensureUnusedCapacity(@typeInfo(Tag.TypeStructPacked).Struct.fields.len +
6253 // TODO: fmt bug7018 // TODO: fmt bug
6254 // zig fmt: off7019 // zig fmt: off
6255 switch (ini.key) {7020 switch (ini.key) {
...@@ -6260,7 +7025,7 @@ pub fn getStructType(...@@ -6260,7 +7025,7 @@ pub fn getStructType(
6260 ini.fields_len + // types7025 ini.fields_len + // types
6261 ini.fields_len + // names7026 ini.fields_len + // names
6262 ini.fields_len); // inits7027 ini.fields_len); // inits
6263 const extra_index = ip.addExtraAssumeCapacity(Tag.TypeStructPacked{7028 const extra_index = addExtraAssumeCapacity(extra, Tag.TypeStructPacked{
6264 .decl = undefined, // set by `finish`7029 .decl = undefined, // set by `finish`
6265 .zir_index = zir_index,7030 .zir_index = zir_index,
6266 .fields_len = ini.fields_len,7031 .fields_len = ini.fields_len,
...@@ -6274,26 +7039,27 @@ pub fn getStructType(...@@ -6274,26 +7039,27 @@ pub fn getStructType(
6274 .is_reified = ini.key == .reified,7039 .is_reified = ini.key == .reified,
6275 },7040 },
6276 });7041 });
6277 try ip.items.append(gpa, .{7042 try items.append(.{
6278 .tag = if (ini.any_default_inits) .type_struct_packed_inits else .type_struct_packed,7043 .tag = if (ini.any_default_inits) .type_struct_packed_inits else .type_struct_packed,
6279 .data = extra_index,7044 .data = extra_index,
6280 });7045 });
6281 switch (ini.key) {7046 switch (ini.key) {
6282 .declared => |d| if (d.captures.len != 0) {7047 .declared => |d| if (d.captures.len != 0) {
6283 ip.extra.appendAssumeCapacity(@intCast(d.captures.len));7048 extra.appendAssumeCapacity(.{@intCast(d.captures.len)});
6284 ip.extra.appendSliceAssumeCapacity(@ptrCast(d.captures));7049 extra.appendSliceAssumeCapacity(.{@ptrCast(d.captures)});
6285 },7050 },
6286 .reified => |r| {7051 .reified => |r| {
6287 _ = ip.addExtraAssumeCapacity(PackedU64.init(r.type_hash));7052 _ = addExtraAssumeCapacity(extra, PackedU64.init(r.type_hash));
6288 },7053 },
6289 }7054 }
6290 ip.extra.appendNTimesAssumeCapacity(@intFromEnum(Index.none), ini.fields_len);7055 extra.appendNTimesAssumeCapacity(.{@intFromEnum(Index.none)}, ini.fields_len);
6291 ip.extra.appendNTimesAssumeCapacity(@intFromEnum(OptionalNullTerminatedString.none), ini.fields_len);7056 extra.appendNTimesAssumeCapacity(.{@intFromEnum(OptionalNullTerminatedString.none)}, ini.fields_len);
6292 if (ini.any_default_inits) {7057 if (ini.any_default_inits) {
6293 ip.extra.appendNTimesAssumeCapacity(@intFromEnum(Index.none), ini.fields_len);7058 extra.appendNTimesAssumeCapacity(.{@intFromEnum(Index.none)}, ini.fields_len);
6294 }7059 }
6295 return .{ .wip = .{7060 return .{ .wip = .{
6296 .index = @enumFromInt(ip.items.len - 1),7061 .tid = tid,
7062 .index = gop.put(),
6297 .decl_extra_index = extra_index + std.meta.fieldIndex(Tag.TypeStructPacked, "decl").?,7063 .decl_extra_index = extra_index + std.meta.fieldIndex(Tag.TypeStructPacked, "decl").?,
6298 .namespace_extra_index = if (ini.has_namespace)7064 .namespace_extra_index = if (ini.has_namespace)
6299 extra_index + std.meta.fieldIndex(Tag.TypeStructPacked, "namespace").?7065 extra_index + std.meta.fieldIndex(Tag.TypeStructPacked, "namespace").?
...@@ -6307,7 +7073,7 @@ pub fn getStructType(...@@ -6307,7 +7073,7 @@ pub fn getStructType(
6307 const align_element: u32 = @bitCast([1]u8{@intFromEnum(Alignment.none)} ** 4);7073 const align_element: u32 = @bitCast([1]u8{@intFromEnum(Alignment.none)} ** 4);
6308 const comptime_elements_len = if (ini.any_comptime_fields) (ini.fields_len + 31) / 32 else 0;7074 const comptime_elements_len = if (ini.any_comptime_fields) (ini.fields_len + 31) / 32 else 0;
63097075
6310 try ip.extra.ensureUnusedCapacity(gpa, @typeInfo(Tag.TypeStruct).Struct.fields.len +7076 try extra.ensureUnusedCapacity(@typeInfo(Tag.TypeStruct).Struct.fields.len +
6311 // TODO: fmt bug7077 // TODO: fmt bug
6312 // zig fmt: off7078 // zig fmt: off
6313 switch (ini.key) {7079 switch (ini.key) {
...@@ -6318,7 +7084,7 @@ pub fn getStructType(...@@ -6318,7 +7084,7 @@ pub fn getStructType(
6318 (ini.fields_len * 5) + // types, names, inits, runtime order, offsets7084 (ini.fields_len * 5) + // types, names, inits, runtime order, offsets
6319 align_elements_len + comptime_elements_len +7085 align_elements_len + comptime_elements_len +
6320 2); // names_map + namespace7086 2); // names_map + namespace
6321 const extra_index = ip.addExtraAssumeCapacity(Tag.TypeStruct{7087 const extra_index = addExtraAssumeCapacity(extra, Tag.TypeStruct{
6322 .decl = undefined, // set by `finish`7088 .decl = undefined, // set by `finish`
6323 .zir_index = zir_index,7089 .zir_index = zir_index,
6324 .fields_len = ini.fields_len,7090 .fields_len = ini.fields_len,
...@@ -6346,43 +7112,44 @@ pub fn getStructType(...@@ -6346,43 +7112,44 @@ pub fn getStructType(
6346 .is_reified = ini.key == .reified,7112 .is_reified = ini.key == .reified,
6347 },7113 },
6348 });7114 });
6349 try ip.items.append(gpa, .{7115 try items.append(.{
6350 .tag = .type_struct,7116 .tag = .type_struct,
6351 .data = extra_index,7117 .data = extra_index,
6352 });7118 });
6353 switch (ini.key) {7119 switch (ini.key) {
6354 .declared => |d| if (d.captures.len != 0) {7120 .declared => |d| if (d.captures.len != 0) {
6355 ip.extra.appendAssumeCapacity(@intCast(d.captures.len));7121 extra.appendAssumeCapacity(.{@intCast(d.captures.len)});
6356 ip.extra.appendSliceAssumeCapacity(@ptrCast(d.captures));7122 extra.appendSliceAssumeCapacity(.{@ptrCast(d.captures)});
6357 },7123 },
6358 .reified => |r| {7124 .reified => |r| {
6359 _ = ip.addExtraAssumeCapacity(PackedU64.init(r.type_hash));7125 _ = addExtraAssumeCapacity(extra, PackedU64.init(r.type_hash));
6360 },7126 },
6361 }7127 }
6362 ip.extra.appendNTimesAssumeCapacity(@intFromEnum(Index.none), ini.fields_len);7128 extra.appendNTimesAssumeCapacity(.{@intFromEnum(Index.none)}, ini.fields_len);
6363 if (!ini.is_tuple) {7129 if (!ini.is_tuple) {
6364 ip.extra.appendAssumeCapacity(@intFromEnum(names_map));7130 extra.appendAssumeCapacity(.{@intFromEnum(names_map)});
6365 ip.extra.appendNTimesAssumeCapacity(@intFromEnum(OptionalNullTerminatedString.none), ini.fields_len);7131 extra.appendNTimesAssumeCapacity(.{@intFromEnum(OptionalNullTerminatedString.none)}, ini.fields_len);
6366 }7132 }
6367 if (ini.any_default_inits) {7133 if (ini.any_default_inits) {
6368 ip.extra.appendNTimesAssumeCapacity(@intFromEnum(Index.none), ini.fields_len);7134 extra.appendNTimesAssumeCapacity(.{@intFromEnum(Index.none)}, ini.fields_len);
6369 }7135 }
6370 const namespace_extra_index: ?u32 = if (ini.has_namespace) i: {7136 const namespace_extra_index: ?u32 = if (ini.has_namespace) i: {
6371 ip.extra.appendAssumeCapacity(undefined); // set by `finish`7137 extra.appendAssumeCapacity(undefined); // set by `finish`
6372 break :i @intCast(ip.extra.items.len - 1);7138 break :i @intCast(extra.mutate.len - 1);
6373 } else null;7139 } else null;
6374 if (ini.any_aligned_fields) {7140 if (ini.any_aligned_fields) {
6375 ip.extra.appendNTimesAssumeCapacity(align_element, align_elements_len);7141 extra.appendNTimesAssumeCapacity(.{align_element}, align_elements_len);
6376 }7142 }
6377 if (ini.any_comptime_fields) {7143 if (ini.any_comptime_fields) {
6378 ip.extra.appendNTimesAssumeCapacity(0, comptime_elements_len);7144 extra.appendNTimesAssumeCapacity(.{0}, comptime_elements_len);
6379 }7145 }
6380 if (ini.layout == .auto) {7146 if (ini.layout == .auto) {
6381 ip.extra.appendNTimesAssumeCapacity(@intFromEnum(LoadedStructType.RuntimeOrder.unresolved), ini.fields_len);7147 extra.appendNTimesAssumeCapacity(.{@intFromEnum(LoadedStructType.RuntimeOrder.unresolved)}, ini.fields_len);
6382 }7148 }
6383 ip.extra.appendNTimesAssumeCapacity(std.math.maxInt(u32), ini.fields_len);7149 extra.appendNTimesAssumeCapacity(.{std.math.maxInt(u32)}, ini.fields_len);
6384 return .{ .wip = .{7150 return .{ .wip = .{
6385 .index = @enumFromInt(ip.items.len - 1),7151 .tid = tid,
7152 .index = gop.put(),
6386 .decl_extra_index = extra_index + std.meta.fieldIndex(Tag.TypeStruct, "decl").?,7153 .decl_extra_index = extra_index + std.meta.fieldIndex(Tag.TypeStruct, "decl").?,
6387 .namespace_extra_index = namespace_extra_index,7154 .namespace_extra_index = namespace_extra_index,
6388 } };7155 } };
...@@ -6396,43 +7163,52 @@ pub const AnonStructTypeInit = struct {...@@ -6396,43 +7163,52 @@ pub const AnonStructTypeInit = struct {
6396 values: []const Index,7163 values: []const Index,
6397};7164};
63987165
6399pub fn getAnonStructType(ip: *InternPool, gpa: Allocator, ini: AnonStructTypeInit) Allocator.Error!Index {7166pub fn getAnonStructType(
7167 ip: *InternPool,
7168 gpa: Allocator,
7169 tid: Zcu.PerThread.Id,
7170 ini: AnonStructTypeInit,
7171) Allocator.Error!Index {
6400 assert(ini.types.len == ini.values.len);7172 assert(ini.types.len == ini.values.len);
6401 for (ini.types) |elem| assert(elem != .none);7173 for (ini.types) |elem| assert(elem != .none);
64027174
6403 const prev_extra_len = ip.extra.items.len;7175 const local = ip.getLocal(tid);
7176 const items = local.getMutableItems(gpa);
7177 const extra = local.getMutableExtra(gpa);
7178
7179 const prev_extra_len = extra.mutate.len;
6404 const fields_len: u32 = @intCast(ini.types.len);7180 const fields_len: u32 = @intCast(ini.types.len);
64057181
6406 try ip.extra.ensureUnusedCapacity(7182 try items.ensureUnusedCapacity(1);
6407 gpa,7183 try extra.ensureUnusedCapacity(
6408 @typeInfo(TypeStructAnon).Struct.fields.len + (fields_len * 3),7184 @typeInfo(TypeStructAnon).Struct.fields.len + (fields_len * 3),
6409 );7185 );
6410 try ip.items.ensureUnusedCapacity(gpa, 1);
64117186
6412 const extra_index = ip.addExtraAssumeCapacity(TypeStructAnon{7187 const extra_index = addExtraAssumeCapacity(extra, TypeStructAnon{
6413 .fields_len = fields_len,7188 .fields_len = fields_len,
6414 });7189 });
6415 ip.extra.appendSliceAssumeCapacity(@ptrCast(ini.types));7190 extra.appendSliceAssumeCapacity(.{@ptrCast(ini.types)});
6416 ip.extra.appendSliceAssumeCapacity(@ptrCast(ini.values));7191 extra.appendSliceAssumeCapacity(.{@ptrCast(ini.values)});
7192 errdefer extra.mutate.len = prev_extra_len;
64177193
6418 const adapter: KeyAdapter = .{ .intern_pool = ip };7194 var gop = try ip.getOrPutKey(gpa, tid, .{
6419 const key: Key = .{7195 .anon_struct_type = if (ini.names.len == 0) extraTypeTupleAnon(tid, extra.list.*, extra_index) else k: {
6420 .anon_struct_type = if (ini.names.len == 0) extraTypeTupleAnon(ip, extra_index) else k: {
6421 assert(ini.names.len == ini.types.len);7196 assert(ini.names.len == ini.types.len);
6422 ip.extra.appendSliceAssumeCapacity(@ptrCast(ini.names));7197 extra.appendSliceAssumeCapacity(.{@ptrCast(ini.names)});
6423 break :k extraTypeStructAnon(ip, extra_index);7198 break :k extraTypeStructAnon(tid, extra.list.*, extra_index);
6424 },7199 },
6425 };7200 });
6426 const gop = try ip.map.getOrPutAdapted(gpa, key, adapter);7201 defer gop.deinit();
6427 if (gop.found_existing) {7202 if (gop == .existing) {
6428 ip.extra.items.len = prev_extra_len;7203 extra.mutate.len = prev_extra_len;
6429 return @enumFromInt(gop.index);7204 return gop.existing;
6430 }7205 }
6431 ip.items.appendAssumeCapacity(.{7206
7207 items.appendAssumeCapacity(.{
6432 .tag = if (ini.names.len == 0) .type_tuple_anon else .type_struct_anon,7208 .tag = if (ini.names.len == 0) .type_tuple_anon else .type_struct_anon,
6433 .data = extra_index,7209 .data = extra_index,
6434 });7210 });
6435 return @enumFromInt(ip.items.len - 1);7211 return gop.put();
6436}7212}
64377213
6438/// This is equivalent to `Key.FuncType` but adjusted to have a slice for `param_types`.7214/// This is equivalent to `Key.FuncType` but adjusted to have a slice for `param_types`.
...@@ -6450,24 +7226,33 @@ pub const GetFuncTypeKey = struct {...@@ -6450,24 +7226,33 @@ pub const GetFuncTypeKey = struct {
6450 addrspace_is_generic: bool = false,7226 addrspace_is_generic: bool = false,
6451};7227};
64527228
6453pub fn getFuncType(ip: *InternPool, gpa: Allocator, key: GetFuncTypeKey) Allocator.Error!Index {7229pub fn getFuncType(
7230 ip: *InternPool,
7231 gpa: Allocator,
7232 tid: Zcu.PerThread.Id,
7233 key: GetFuncTypeKey,
7234) Allocator.Error!Index {
6454 // Validate input parameters.7235 // Validate input parameters.
6455 assert(key.return_type != .none);7236 assert(key.return_type != .none);
6456 for (key.param_types) |param_type| assert(param_type != .none);7237 for (key.param_types) |param_type| assert(param_type != .none);
64577238
7239 const local = ip.getLocal(tid);
7240 const items = local.getMutableItems(gpa);
7241 try items.ensureUnusedCapacity(1);
7242 const extra = local.getMutableExtra(gpa);
7243
6458 // The strategy here is to add the function type unconditionally, then to7244 // The strategy here is to add the function type unconditionally, then to
6459 // ask if it already exists, and if so, revert the lengths of the mutated7245 // ask if it already exists, and if so, revert the lengths of the mutated
6460 // arrays. This is similar to what `getOrPutTrailingString` does.7246 // arrays. This is similar to what `getOrPutTrailingString` does.
6461 const prev_extra_len = ip.extra.items.len;7247 const prev_extra_len = extra.mutate.len;
6462 const params_len: u32 = @intCast(key.param_types.len);7248 const params_len: u32 = @intCast(key.param_types.len);
64637249
6464 try ip.extra.ensureUnusedCapacity(gpa, @typeInfo(Tag.TypeFunction).Struct.fields.len +7250 try extra.ensureUnusedCapacity(@typeInfo(Tag.TypeFunction).Struct.fields.len +
6465 @intFromBool(key.comptime_bits != 0) +7251 @intFromBool(key.comptime_bits != 0) +
6466 @intFromBool(key.noalias_bits != 0) +7252 @intFromBool(key.noalias_bits != 0) +
6467 params_len);7253 params_len);
6468 try ip.items.ensureUnusedCapacity(gpa, 1);
64697254
6470 const func_type_extra_index = ip.addExtraAssumeCapacity(Tag.TypeFunction{7255 const func_type_extra_index = addExtraAssumeCapacity(extra, Tag.TypeFunction{
6471 .params_len = params_len,7256 .params_len = params_len,
6472 .return_type = key.return_type,7257 .return_type = key.return_type,
6473 .flags = .{7258 .flags = .{
...@@ -6483,40 +7268,51 @@ pub fn getFuncType(ip: *InternPool, gpa: Allocator, key: GetFuncTypeKey) Allocat...@@ -6483,40 +7268,51 @@ pub fn getFuncType(ip: *InternPool, gpa: Allocator, key: GetFuncTypeKey) Allocat
6483 },7268 },
6484 });7269 });
64857270
6486 if (key.comptime_bits != 0) ip.extra.appendAssumeCapacity(key.comptime_bits);7271 if (key.comptime_bits != 0) extra.appendAssumeCapacity(.{key.comptime_bits});
6487 if (key.noalias_bits != 0) ip.extra.appendAssumeCapacity(key.noalias_bits);7272 if (key.noalias_bits != 0) extra.appendAssumeCapacity(.{key.noalias_bits});
6488 ip.extra.appendSliceAssumeCapacity(@ptrCast(key.param_types));7273 extra.appendSliceAssumeCapacity(.{@ptrCast(key.param_types)});
7274 errdefer extra.mutate.len = prev_extra_len;
64897275
6490 const adapter: KeyAdapter = .{ .intern_pool = ip };7276 var gop = try ip.getOrPutKey(gpa, tid, .{
6491 const gop = try ip.map.getOrPutAdapted(gpa, Key{7277 .func_type = extraFuncType(tid, extra.list.*, func_type_extra_index),
6492 .func_type = extraFuncType(ip, func_type_extra_index),7278 });
6493 }, adapter);7279 defer gop.deinit();
6494 if (gop.found_existing) {7280 if (gop == .existing) {
6495 ip.extra.items.len = prev_extra_len;7281 extra.mutate.len = prev_extra_len;
6496 return @enumFromInt(gop.index);7282 return gop.existing;
6497 }7283 }
64987284
6499 ip.items.appendAssumeCapacity(.{7285 items.appendAssumeCapacity(.{
6500 .tag = .type_function,7286 .tag = .type_function,
6501 .data = func_type_extra_index,7287 .data = func_type_extra_index,
6502 });7288 });
6503 return @enumFromInt(ip.items.len - 1);7289 return gop.put();
6504}7290}
65057291
6506pub fn getExternFunc(ip: *InternPool, gpa: Allocator, key: Key.ExternFunc) Allocator.Error!Index {7292pub fn getExternFunc(
6507 const adapter: KeyAdapter = .{ .intern_pool = ip };7293 ip: *InternPool,
6508 const gop = try ip.map.getOrPutAdapted(gpa, Key{ .extern_func = key }, adapter);7294 gpa: Allocator,
6509 if (gop.found_existing) return @enumFromInt(gop.index);7295 tid: Zcu.PerThread.Id,
6510 errdefer _ = ip.map.pop();7296 key: Key.ExternFunc,
6511 const prev_extra_len = ip.extra.items.len;7297) Allocator.Error!Index {
6512 const extra_index = try ip.addExtra(gpa, @as(Tag.ExternFunc, key));7298 var gop = try ip.getOrPutKey(gpa, tid, .{ .extern_func = key });
6513 errdefer ip.extra.items.len = prev_extra_len;7299 defer gop.deinit();
6514 try ip.items.append(gpa, .{7300 if (gop == .existing) return gop.existing;
6515 .tag = .extern_func,7301
6516 .data = extra_index,7302 const local = ip.getLocal(tid);
7303 const items = local.getMutableItems(gpa);
7304 try items.ensureUnusedCapacity(1);
7305 const extra = local.getMutableExtra(gpa);
7306
7307 const prev_extra_len = extra.mutate.len;
7308 const extra_index = try addExtra(extra, @as(Tag.ExternFunc, key));
7309 errdefer extra.mutate.len = prev_extra_len;
7310 items.appendAssumeCapacity(.{
7311 .tag = .extern_func,
7312 .data = extra_index,
6517 });7313 });
6518 errdefer ip.items.len -= 1;7314 errdefer items.mutate.len -= 1;
6519 return @enumFromInt(ip.items.len - 1);7315 return gop.put();
6520}7316}
65217317
6522pub const GetFuncDeclKey = struct {7318pub const GetFuncDeclKey = struct {
...@@ -6531,17 +7327,25 @@ pub const GetFuncDeclKey = struct {...@@ -6531,17 +7327,25 @@ pub const GetFuncDeclKey = struct {
6531 is_noinline: bool,7327 is_noinline: bool,
6532};7328};
65337329
6534pub fn getFuncDecl(ip: *InternPool, gpa: Allocator, key: GetFuncDeclKey) Allocator.Error!Index {7330pub fn getFuncDecl(
7331 ip: *InternPool,
7332 gpa: Allocator,
7333 tid: Zcu.PerThread.Id,
7334 key: GetFuncDeclKey,
7335) Allocator.Error!Index {
7336 const local = ip.getLocal(tid);
7337 const items = local.getMutableItems(gpa);
7338 try items.ensureUnusedCapacity(1);
7339 const extra = local.getMutableExtra(gpa);
7340
6535 // The strategy here is to add the function type unconditionally, then to7341 // The strategy here is to add the function type unconditionally, then to
6536 // ask if it already exists, and if so, revert the lengths of the mutated7342 // ask if it already exists, and if so, revert the lengths of the mutated
6537 // arrays. This is similar to what `getOrPutTrailingString` does.7343 // arrays. This is similar to what `getOrPutTrailingString` does.
6538 const prev_extra_len = ip.extra.items.len;7344 const prev_extra_len = extra.mutate.len;
65397345
6540 try ip.extra.ensureUnusedCapacity(gpa, @typeInfo(Tag.FuncDecl).Struct.fields.len);7346 try extra.ensureUnusedCapacity(@typeInfo(Tag.FuncDecl).Struct.fields.len);
6541 try ip.items.ensureUnusedCapacity(gpa, 1);
6542 try ip.map.ensureUnusedCapacity(gpa, 1);
65437347
6544 const func_decl_extra_index = ip.addExtraAssumeCapacity(Tag.FuncDecl{7348 const func_decl_extra_index = addExtraAssumeCapacity(extra, Tag.FuncDecl{
6545 .analysis = .{7349 .analysis = .{
6546 .state = if (key.cc == .Inline) .inline_only else .none,7350 .state = if (key.cc == .Inline) .inline_only else .none,
6547 .is_cold = false,7351 .is_cold = false,
...@@ -6558,22 +7362,22 @@ pub fn getFuncDecl(ip: *InternPool, gpa: Allocator, key: GetFuncDeclKey) Allocat...@@ -6558,22 +7362,22 @@ pub fn getFuncDecl(ip: *InternPool, gpa: Allocator, key: GetFuncDeclKey) Allocat
6558 .lbrace_column = key.lbrace_column,7362 .lbrace_column = key.lbrace_column,
6559 .rbrace_column = key.rbrace_column,7363 .rbrace_column = key.rbrace_column,
6560 });7364 });
7365 errdefer extra.mutate.len = prev_extra_len;
65617366
6562 const adapter: KeyAdapter = .{ .intern_pool = ip };7367 var gop = try ip.getOrPutKey(gpa, tid, .{
6563 const gop = ip.map.getOrPutAssumeCapacityAdapted(Key{7368 .func = extraFuncDecl(tid, extra.list.*, func_decl_extra_index),
6564 .func = extraFuncDecl(ip, func_decl_extra_index),7369 });
6565 }, adapter);7370 defer gop.deinit();
65667371 if (gop == .existing) {
6567 if (gop.found_existing) {7372 extra.mutate.len = prev_extra_len;
6568 ip.extra.items.len = prev_extra_len;7373 return gop.existing;
6569 return @enumFromInt(gop.index);
6570 }7374 }
65717375
6572 ip.items.appendAssumeCapacity(.{7376 items.appendAssumeCapacity(.{
6573 .tag = .func_decl,7377 .tag = .func_decl,
6574 .data = func_decl_extra_index,7378 .data = func_decl_extra_index,
6575 });7379 });
6576 return @enumFromInt(ip.items.len - 1);7380 return gop.put();
6577}7381}
65787382
6579pub const GetFuncDeclIesKey = struct {7383pub const GetFuncDeclIesKey = struct {
...@@ -6598,28 +7402,53 @@ pub const GetFuncDeclIesKey = struct {...@@ -6598,28 +7402,53 @@ pub const GetFuncDeclIesKey = struct {
6598 rbrace_column: u32,7402 rbrace_column: u32,
6599};7403};
66007404
6601pub fn getFuncDeclIes(ip: *InternPool, gpa: Allocator, key: GetFuncDeclIesKey) Allocator.Error!Index {7405pub fn getFuncDeclIes(
7406 ip: *InternPool,
7407 gpa: Allocator,
7408 tid: Zcu.PerThread.Id,
7409 key: GetFuncDeclIesKey,
7410) Allocator.Error!Index {
6602 // Validate input parameters.7411 // Validate input parameters.
6603 assert(key.bare_return_type != .none);7412 assert(key.bare_return_type != .none);
6604 for (key.param_types) |param_type| assert(param_type != .none);7413 for (key.param_types) |param_type| assert(param_type != .none);
66057414
7415 const local = ip.getLocal(tid);
7416 const items = local.getMutableItems(gpa);
7417 try items.ensureUnusedCapacity(4);
7418 const extra = local.getMutableExtra(gpa);
7419
6606 // The strategy here is to add the function decl unconditionally, then to7420 // The strategy here is to add the function decl unconditionally, then to
6607 // ask if it already exists, and if so, revert the lengths of the mutated7421 // ask if it already exists, and if so, revert the lengths of the mutated
6608 // arrays. This is similar to what `getOrPutTrailingString` does.7422 // arrays. This is similar to what `getOrPutTrailingString` does.
6609 const prev_extra_len = ip.extra.items.len;7423 const prev_extra_len = extra.mutate.len;
6610 const params_len: u32 = @intCast(key.param_types.len);7424 const params_len: u32 = @intCast(key.param_types.len);
66117425
6612 try ip.map.ensureUnusedCapacity(gpa, 4);7426 try extra.ensureUnusedCapacity(@typeInfo(Tag.FuncDecl).Struct.fields.len +
6613 try ip.extra.ensureUnusedCapacity(gpa, @typeInfo(Tag.FuncDecl).Struct.fields.len +
6614 1 + // inferred_error_set7427 1 + // inferred_error_set
6615 @typeInfo(Tag.ErrorUnionType).Struct.fields.len +7428 @typeInfo(Tag.ErrorUnionType).Struct.fields.len +
6616 @typeInfo(Tag.TypeFunction).Struct.fields.len +7429 @typeInfo(Tag.TypeFunction).Struct.fields.len +
6617 @intFromBool(key.comptime_bits != 0) +7430 @intFromBool(key.comptime_bits != 0) +
6618 @intFromBool(key.noalias_bits != 0) +7431 @intFromBool(key.noalias_bits != 0) +
6619 params_len);7432 params_len);
6620 try ip.items.ensureUnusedCapacity(gpa, 4);
66217433
6622 const func_decl_extra_index = ip.addExtraAssumeCapacity(Tag.FuncDecl{7434 const func_index = Index.Unwrapped.wrap(.{
7435 .tid = tid,
7436 .index = items.mutate.len + 0,
7437 }, ip);
7438 const error_union_type = Index.Unwrapped.wrap(.{
7439 .tid = tid,
7440 .index = items.mutate.len + 1,
7441 }, ip);
7442 const error_set_type = Index.Unwrapped.wrap(.{
7443 .tid = tid,
7444 .index = items.mutate.len + 2,
7445 }, ip);
7446 const func_ty = Index.Unwrapped.wrap(.{
7447 .tid = tid,
7448 .index = items.mutate.len + 3,
7449 }, ip);
7450
7451 const func_decl_extra_index = addExtraAssumeCapacity(extra, Tag.FuncDecl{
6623 .analysis = .{7452 .analysis = .{
6624 .state = if (key.cc == .Inline) .inline_only else .none,7453 .state = if (key.cc == .Inline) .inline_only else .none,
6625 .is_cold = false,7454 .is_cold = false,
...@@ -6629,36 +7458,18 @@ pub fn getFuncDeclIes(ip: *InternPool, gpa: Allocator, key: GetFuncDeclIesKey) A...@@ -6629,36 +7458,18 @@ pub fn getFuncDeclIes(ip: *InternPool, gpa: Allocator, key: GetFuncDeclIesKey) A
6629 .inferred_error_set = true,7458 .inferred_error_set = true,
6630 },7459 },
6631 .owner_decl = key.owner_decl,7460 .owner_decl = key.owner_decl,
6632 .ty = @enumFromInt(ip.items.len + 3),7461 .ty = func_ty,
6633 .zir_body_inst = key.zir_body_inst,7462 .zir_body_inst = key.zir_body_inst,
6634 .lbrace_line = key.lbrace_line,7463 .lbrace_line = key.lbrace_line,
6635 .rbrace_line = key.rbrace_line,7464 .rbrace_line = key.rbrace_line,
6636 .lbrace_column = key.lbrace_column,7465 .lbrace_column = key.lbrace_column,
6637 .rbrace_column = key.rbrace_column,7466 .rbrace_column = key.rbrace_column,
6638 });7467 });
7468 extra.appendAssumeCapacity(.{@intFromEnum(Index.none)});
66397469
6640 ip.items.appendAssumeCapacity(.{7470 const func_type_extra_index = addExtraAssumeCapacity(extra, Tag.TypeFunction{
6641 .tag = .func_decl,
6642 .data = func_decl_extra_index,
6643 });
6644 ip.extra.appendAssumeCapacity(@intFromEnum(Index.none));
6645
6646 ip.items.appendAssumeCapacity(.{
6647 .tag = .type_error_union,
6648 .data = ip.addExtraAssumeCapacity(Tag.ErrorUnionType{
6649 .error_set_type = @enumFromInt(ip.items.len + 1),
6650 .payload_type = key.bare_return_type,
6651 }),
6652 });
6653
6654 ip.items.appendAssumeCapacity(.{
6655 .tag = .type_inferred_error_set,
6656 .data = @intCast(ip.items.len - 2),
6657 });
6658
6659 const func_type_extra_index = ip.addExtraAssumeCapacity(Tag.TypeFunction{
6660 .params_len = params_len,7471 .params_len = params_len,
6661 .return_type = @enumFromInt(ip.items.len - 2),7472 .return_type = error_union_type,
6662 .flags = .{7473 .flags = .{
6663 .cc = key.cc orelse .Unspecified,7474 .cc = key.cc orelse .Unspecified,
6664 .is_var_args = key.is_var_args,7475 .is_var_args = key.is_var_args,
...@@ -6671,78 +7482,104 @@ pub fn getFuncDeclIes(ip: *InternPool, gpa: Allocator, key: GetFuncDeclIesKey) A...@@ -6671,78 +7482,104 @@ pub fn getFuncDeclIes(ip: *InternPool, gpa: Allocator, key: GetFuncDeclIesKey) A
6671 .addrspace_is_generic = key.addrspace_is_generic,7482 .addrspace_is_generic = key.addrspace_is_generic,
6672 },7483 },
6673 });7484 });
6674 if (key.comptime_bits != 0) ip.extra.appendAssumeCapacity(key.comptime_bits);7485 if (key.comptime_bits != 0) extra.appendAssumeCapacity(.{key.comptime_bits});
6675 if (key.noalias_bits != 0) ip.extra.appendAssumeCapacity(key.noalias_bits);7486 if (key.noalias_bits != 0) extra.appendAssumeCapacity(.{key.noalias_bits});
6676 ip.extra.appendSliceAssumeCapacity(@ptrCast(key.param_types));7487 extra.appendSliceAssumeCapacity(.{@ptrCast(key.param_types)});
66777488
6678 ip.items.appendAssumeCapacity(.{7489 items.appendSliceAssumeCapacity(.{
6679 .tag = .type_function,7490 .tag = &.{
6680 .data = func_type_extra_index,7491 .func_decl,
7492 .type_error_union,
7493 .type_inferred_error_set,
7494 .type_function,
7495 },
7496 .data = &.{
7497 func_decl_extra_index,
7498 addExtraAssumeCapacity(extra, Tag.ErrorUnionType{
7499 .error_set_type = error_set_type,
7500 .payload_type = key.bare_return_type,
7501 }),
7502 @intFromEnum(func_index),
7503 func_type_extra_index,
7504 },
6681 });7505 });
7506 errdefer {
7507 items.mutate.len -= 4;
7508 extra.mutate.len = prev_extra_len;
7509 }
66827510
6683 const adapter: KeyAdapter = .{ .intern_pool = ip };7511 var func_gop = try ip.getOrPutKey(gpa, tid, .{
6684 const gop = ip.map.getOrPutAssumeCapacityAdapted(Key{7512 .func = extraFuncDecl(tid, extra.list.*, func_decl_extra_index),
6685 .func = extraFuncDecl(ip, func_decl_extra_index),7513 });
6686 }, adapter);7514 defer func_gop.deinit();
6687 if (!gop.found_existing) {7515 if (func_gop == .existing) {
6688 assert(!ip.map.getOrPutAssumeCapacityAdapted(Key{ .error_union_type = .{7516 // An existing function type was found; undo the additions to our two arrays.
6689 .error_set_type = @enumFromInt(ip.items.len - 2),7517 items.mutate.len -= 4;
6690 .payload_type = key.bare_return_type,7518 extra.mutate.len = prev_extra_len;
6691 } }, adapter).found_existing);7519 return func_gop.existing;
6692 assert(!ip.map.getOrPutAssumeCapacityAdapted(Key{7520 }
6693 .inferred_error_set_type = @enumFromInt(ip.items.len - 4),7521 var error_union_type_gop = try ip.getOrPutKey(gpa, tid, .{ .error_union_type = .{
6694 }, adapter).found_existing);7522 .error_set_type = error_set_type,
6695 assert(!ip.map.getOrPutAssumeCapacityAdapted(Key{7523 .payload_type = key.bare_return_type,
6696 .func_type = extraFuncType(ip, func_type_extra_index),7524 } });
6697 }, adapter).found_existing);7525 defer error_union_type_gop.deinit();
6698 return @enumFromInt(ip.items.len - 4);7526 var error_set_type_gop = try ip.getOrPutKey(gpa, tid, .{
6699 }7527 .inferred_error_set_type = func_index,
67007528 });
6701 // An existing function type was found; undo the additions to our two arrays.7529 defer error_set_type_gop.deinit();
6702 ip.items.len -= 4;7530 var func_ty_gop = try ip.getOrPutKey(gpa, tid, .{
6703 ip.extra.items.len = prev_extra_len;7531 .func_type = extraFuncType(tid, extra.list.*, func_type_extra_index),
6704 return @enumFromInt(gop.index);7532 });
7533 defer func_ty_gop.deinit();
7534 assert(func_gop.putAt(3) == func_index);
7535 assert(error_union_type_gop.putAt(2) == error_union_type);
7536 assert(error_set_type_gop.putAt(1) == error_set_type);
7537 assert(func_ty_gop.putAt(0) == func_ty);
7538 return func_index;
6705}7539}
67067540
6707pub fn getErrorSetType(7541pub fn getErrorSetType(
6708 ip: *InternPool,7542 ip: *InternPool,
6709 gpa: Allocator,7543 gpa: Allocator,
7544 tid: Zcu.PerThread.Id,
6710 names: []const NullTerminatedString,7545 names: []const NullTerminatedString,
6711) Allocator.Error!Index {7546) Allocator.Error!Index {
6712 assert(std.sort.isSorted(NullTerminatedString, names, {}, NullTerminatedString.indexLessThan));7547 assert(std.sort.isSorted(NullTerminatedString, names, {}, NullTerminatedString.indexLessThan));
67137548
7549 const local = ip.getLocal(tid);
7550 const items = local.getMutableItems(gpa);
7551 const extra = local.getMutableExtra(gpa);
7552 try extra.ensureUnusedCapacity(@typeInfo(Tag.ErrorSet).Struct.fields.len + names.len);
7553
6714 // The strategy here is to add the type unconditionally, then to ask if it7554 // The strategy here is to add the type unconditionally, then to ask if it
6715 // already exists, and if so, revert the lengths of the mutated arrays.7555 // already exists, and if so, revert the lengths of the mutated arrays.
6716 // This is similar to what `getOrPutTrailingString` does.7556 // This is similar to what `getOrPutTrailingString` does.
6717 try ip.extra.ensureUnusedCapacity(gpa, @typeInfo(Tag.ErrorSet).Struct.fields.len + names.len);7557 const prev_extra_len = extra.mutate.len;
67187558 errdefer extra.mutate.len = prev_extra_len;
6719 const prev_extra_len = ip.extra.items.len;
6720 errdefer ip.extra.items.len = prev_extra_len;
67217559
6722 const predicted_names_map: MapIndex = @enumFromInt(ip.maps.items.len);7560 const predicted_names_map: MapIndex = @enumFromInt(ip.maps.items.len);
67237561
6724 const error_set_extra_index = ip.addExtraAssumeCapacity(Tag.ErrorSet{7562 const error_set_extra_index = addExtraAssumeCapacity(extra, Tag.ErrorSet{
6725 .names_len = @intCast(names.len),7563 .names_len = @intCast(names.len),
6726 .names_map = predicted_names_map,7564 .names_map = predicted_names_map,
6727 });7565 });
6728 ip.extra.appendSliceAssumeCapacity(@ptrCast(names));7566 extra.appendSliceAssumeCapacity(.{@ptrCast(names)});
67297567 errdefer extra.mutate.len = prev_extra_len;
6730 const adapter: KeyAdapter = .{ .intern_pool = ip };
6731 const gop = try ip.map.getOrPutAdapted(gpa, Key{
6732 .error_set_type = extraErrorSet(ip, error_set_extra_index),
6733 }, adapter);
6734 errdefer _ = ip.map.pop();
67357568
6736 if (gop.found_existing) {7569 var gop = try ip.getOrPutKey(gpa, tid, .{
6737 ip.extra.items.len = prev_extra_len;7570 .error_set_type = extraErrorSet(tid, extra.list.*, error_set_extra_index),
6738 return @enumFromInt(gop.index);7571 });
7572 defer gop.deinit();
7573 if (gop == .existing) {
7574 extra.mutate.len = prev_extra_len;
7575 return gop.existing;
6739 }7576 }
67407577
6741 try ip.items.append(gpa, .{7578 try items.append(.{
6742 .tag = .type_error_set,7579 .tag = .type_error_set,
6743 .data = error_set_extra_index,7580 .data = error_set_extra_index,
6744 });7581 });
6745 errdefer ip.items.len -= 1;7582 errdefer items.mutate.len -= 1;
67467583
6747 const names_map = try ip.addMap(gpa, names.len);7584 const names_map = try ip.addMap(gpa, names.len);
6748 assert(names_map == predicted_names_map);7585 assert(names_map == predicted_names_map);
...@@ -6750,7 +7587,7 @@ pub fn getErrorSetType(...@@ -6750,7 +7587,7 @@ pub fn getErrorSetType(
67507587
6751 addStringsToMap(ip, names_map, names);7588 addStringsToMap(ip, names_map, names);
67527589
6753 return @enumFromInt(ip.items.len - 1);7590 return gop.put();
6754}7591}
67557592
6756pub const GetFuncInstanceKey = struct {7593pub const GetFuncInstanceKey = struct {
...@@ -6770,11 +7607,16 @@ pub const GetFuncInstanceKey = struct {...@@ -6770,11 +7607,16 @@ pub const GetFuncInstanceKey = struct {
6770 inferred_error_set: bool,7607 inferred_error_set: bool,
6771};7608};
67727609
6773pub fn getFuncInstance(ip: *InternPool, gpa: Allocator, arg: GetFuncInstanceKey) Allocator.Error!Index {7610pub fn getFuncInstance(
7611 ip: *InternPool,
7612 gpa: Allocator,
7613 tid: Zcu.PerThread.Id,
7614 arg: GetFuncInstanceKey,
7615) Allocator.Error!Index {
6774 if (arg.inferred_error_set)7616 if (arg.inferred_error_set)
6775 return getFuncInstanceIes(ip, gpa, arg);7617 return getFuncInstanceIes(ip, gpa, tid, arg);
67767618
6777 const func_ty = try ip.getFuncType(gpa, .{7619 const func_ty = try ip.getFuncType(gpa, tid, .{
6778 .param_types = arg.param_types,7620 .param_types = arg.param_types,
6779 .return_type = arg.bare_return_type,7621 .return_type = arg.bare_return_type,
6780 .noalias_bits = arg.noalias_bits,7622 .noalias_bits = arg.noalias_bits,
...@@ -6782,16 +7624,20 @@ pub fn getFuncInstance(ip: *InternPool, gpa: Allocator, arg: GetFuncInstanceKey)...@@ -6782,16 +7624,20 @@ pub fn getFuncInstance(ip: *InternPool, gpa: Allocator, arg: GetFuncInstanceKey)
6782 .is_noinline = arg.is_noinline,7624 .is_noinline = arg.is_noinline,
6783 });7625 });
67847626
7627 const local = ip.getLocal(tid);
7628 const items = local.getMutableItems(gpa);
7629 const extra = local.getMutableExtra(gpa);
7630 try extra.ensureUnusedCapacity(@typeInfo(Tag.FuncInstance).Struct.fields.len +
7631 arg.comptime_args.len);
7632
6785 const generic_owner = unwrapCoercedFunc(ip, arg.generic_owner);7633 const generic_owner = unwrapCoercedFunc(ip, arg.generic_owner);
67867634
6787 assert(arg.comptime_args.len == ip.funcTypeParamsLen(ip.typeOf(generic_owner)));7635 assert(arg.comptime_args.len == ip.funcTypeParamsLen(ip.typeOf(generic_owner)));
67887636
6789 try ip.extra.ensureUnusedCapacity(gpa, @typeInfo(Tag.FuncInstance).Struct.fields.len +7637 const prev_extra_len = extra.mutate.len;
6790 arg.comptime_args.len);7638 errdefer extra.mutate.len = prev_extra_len;
6791 const prev_extra_len = ip.extra.items.len;
6792 errdefer ip.extra.items.len = prev_extra_len;
67937639
6794 const func_extra_index = ip.addExtraAssumeCapacity(Tag.FuncInstance{7640 const func_extra_index = addExtraAssumeCapacity(extra, Tag.FuncInstance{
6795 .analysis = .{7641 .analysis = .{
6796 .state = if (arg.cc == .Inline) .inline_only else .none,7642 .state = if (arg.cc == .Inline) .inline_only else .none,
6797 .is_cold = false,7643 .is_cold = false,
...@@ -6807,35 +7653,35 @@ pub fn getFuncInstance(ip: *InternPool, gpa: Allocator, arg: GetFuncInstanceKey)...@@ -6807,35 +7653,35 @@ pub fn getFuncInstance(ip: *InternPool, gpa: Allocator, arg: GetFuncInstanceKey)
6807 .branch_quota = 0,7653 .branch_quota = 0,
6808 .generic_owner = generic_owner,7654 .generic_owner = generic_owner,
6809 });7655 });
6810 ip.extra.appendSliceAssumeCapacity(@ptrCast(arg.comptime_args));7656 extra.appendSliceAssumeCapacity(.{@ptrCast(arg.comptime_args)});
6811
6812 const gop = try ip.map.getOrPutAdapted(gpa, Key{
6813 .func = extraFuncInstance(ip, func_extra_index),
6814 }, KeyAdapter{ .intern_pool = ip });
6815 errdefer _ = ip.map.pop();
68167657
6817 if (gop.found_existing) {7658 var gop = try ip.getOrPutKey(gpa, tid, .{
6818 ip.extra.items.len = prev_extra_len;7659 .func = ip.extraFuncInstance(tid, extra.list.*, func_extra_index),
6819 return @enumFromInt(gop.index);7660 });
7661 defer gop.deinit();
7662 if (gop == .existing) {
7663 extra.mutate.len = prev_extra_len;
7664 return gop.existing;
6820 }7665 }
68217666
6822 const func_index: Index = @enumFromInt(ip.items.len);7667 const func_index = Index.Unwrapped.wrap(.{ .tid = tid, .index = items.mutate.len }, ip);
68237668 try items.append(.{
6824 try ip.items.append(gpa, .{
6825 .tag = .func_instance,7669 .tag = .func_instance,
6826 .data = func_extra_index,7670 .data = func_extra_index,
6827 });7671 });
6828 errdefer ip.items.len -= 1;7672 errdefer items.mutate.len -= 1;
68297673 try finishFuncInstance(
6830 return finishFuncInstance(
6831 ip,7674 ip,
6832 gpa,7675 gpa,
7676 tid,
7677 extra,
6833 generic_owner,7678 generic_owner,
6834 func_index,7679 func_index,
6835 func_extra_index,7680 func_extra_index,
6836 arg.alignment,7681 arg.alignment,
6837 arg.section,7682 arg.section,
6838 );7683 );
7684 return gop.put();
6839}7685}
68407686
6841/// This function exists separately than `getFuncInstance` because it needs to7687/// This function exists separately than `getFuncInstance` because it needs to
...@@ -6844,6 +7690,7 @@ pub fn getFuncInstance(ip: *InternPool, gpa: Allocator, arg: GetFuncInstanceKey)...@@ -6844,6 +7690,7 @@ pub fn getFuncInstance(ip: *InternPool, gpa: Allocator, arg: GetFuncInstanceKey)
6844pub fn getFuncInstanceIes(7690pub fn getFuncInstanceIes(
6845 ip: *InternPool,7691 ip: *InternPool,
6846 gpa: Allocator,7692 gpa: Allocator,
7693 tid: Zcu.PerThread.Id,
6847 arg: GetFuncInstanceKey,7694 arg: GetFuncInstanceKey,
6848) Allocator.Error!Index {7695) Allocator.Error!Index {
6849 // Validate input parameters.7696 // Validate input parameters.
...@@ -6851,30 +7698,45 @@ pub fn getFuncInstanceIes(...@@ -6851,30 +7698,45 @@ pub fn getFuncInstanceIes(
6851 assert(arg.bare_return_type != .none);7698 assert(arg.bare_return_type != .none);
6852 for (arg.param_types) |param_type| assert(param_type != .none);7699 for (arg.param_types) |param_type| assert(param_type != .none);
68537700
7701 const local = ip.getLocal(tid);
7702 const items = local.getMutableItems(gpa);
7703 const extra = local.getMutableExtra(gpa);
7704 try items.ensureUnusedCapacity(4);
7705
6854 const generic_owner = unwrapCoercedFunc(ip, arg.generic_owner);7706 const generic_owner = unwrapCoercedFunc(ip, arg.generic_owner);
68557707
6856 // The strategy here is to add the function decl unconditionally, then to7708 // The strategy here is to add the function decl unconditionally, then to
6857 // ask if it already exists, and if so, revert the lengths of the mutated7709 // ask if it already exists, and if so, revert the lengths of the mutated
6858 // arrays. This is similar to what `getOrPutTrailingString` does.7710 // arrays. This is similar to what `getOrPutTrailingString` does.
6859 const prev_extra_len = ip.extra.items.len;7711 const prev_extra_len = extra.mutate.len;
6860 const params_len: u32 = @intCast(arg.param_types.len);7712 const params_len: u32 = @intCast(arg.param_types.len);
68617713
6862 try ip.map.ensureUnusedCapacity(gpa, 4);7714 try extra.ensureUnusedCapacity(@typeInfo(Tag.FuncInstance).Struct.fields.len +
6863 try ip.extra.ensureUnusedCapacity(gpa, @typeInfo(Tag.FuncInstance).Struct.fields.len +
6864 1 + // inferred_error_set7715 1 + // inferred_error_set
6865 arg.comptime_args.len +7716 arg.comptime_args.len +
6866 @typeInfo(Tag.ErrorUnionType).Struct.fields.len +7717 @typeInfo(Tag.ErrorUnionType).Struct.fields.len +
6867 @typeInfo(Tag.TypeFunction).Struct.fields.len +7718 @typeInfo(Tag.TypeFunction).Struct.fields.len +
6868 @intFromBool(arg.noalias_bits != 0) +7719 @intFromBool(arg.noalias_bits != 0) +
6869 params_len);7720 params_len);
6870 try ip.items.ensureUnusedCapacity(gpa, 4);
6871
6872 const func_index: Index = @enumFromInt(ip.items.len);
6873 const error_union_type: Index = @enumFromInt(ip.items.len + 1);
6874 const error_set_type: Index = @enumFromInt(ip.items.len + 2);
6875 const func_ty: Index = @enumFromInt(ip.items.len + 3);
68767721
6877 const func_extra_index = ip.addExtraAssumeCapacity(Tag.FuncInstance{7722 const func_index = Index.Unwrapped.wrap(.{
7723 .tid = tid,
7724 .index = items.mutate.len + 0,
7725 }, ip);
7726 const error_union_type = Index.Unwrapped.wrap(.{
7727 .tid = tid,
7728 .index = items.mutate.len + 1,
7729 }, ip);
7730 const error_set_type = Index.Unwrapped.wrap(.{
7731 .tid = tid,
7732 .index = items.mutate.len + 2,
7733 }, ip);
7734 const func_ty = Index.Unwrapped.wrap(.{
7735 .tid = tid,
7736 .index = items.mutate.len + 3,
7737 }, ip);
7738
7739 const func_extra_index = addExtraAssumeCapacity(extra, Tag.FuncInstance{
6878 .analysis = .{7740 .analysis = .{
6879 .state = if (arg.cc == .Inline) .inline_only else .none,7741 .state = if (arg.cc == .Inline) .inline_only else .none,
6880 .is_cold = false,7742 .is_cold = false,
...@@ -6890,10 +7752,10 @@ pub fn getFuncInstanceIes(...@@ -6890,10 +7752,10 @@ pub fn getFuncInstanceIes(
6890 .branch_quota = 0,7752 .branch_quota = 0,
6891 .generic_owner = generic_owner,7753 .generic_owner = generic_owner,
6892 });7754 });
6893 ip.extra.appendAssumeCapacity(@intFromEnum(Index.none)); // resolved error set7755 extra.appendAssumeCapacity(.{@intFromEnum(Index.none)}); // resolved error set
6894 ip.extra.appendSliceAssumeCapacity(@ptrCast(arg.comptime_args));7756 extra.appendSliceAssumeCapacity(.{@ptrCast(arg.comptime_args)});
68957757
6896 const func_type_extra_index = ip.addExtraAssumeCapacity(Tag.TypeFunction{7758 const func_type_extra_index = addExtraAssumeCapacity(extra, Tag.TypeFunction{
6897 .params_len = params_len,7759 .params_len = params_len,
6898 .return_type = error_union_type,7760 .return_type = error_union_type,
6899 .flags = .{7761 .flags = .{
...@@ -6909,73 +7771,83 @@ pub fn getFuncInstanceIes(...@@ -6909,73 +7771,83 @@ pub fn getFuncInstanceIes(
6909 },7771 },
6910 });7772 });
6911 // no comptime_bits because has_comptime_bits is false7773 // no comptime_bits because has_comptime_bits is false
6912 if (arg.noalias_bits != 0) ip.extra.appendAssumeCapacity(arg.noalias_bits);7774 if (arg.noalias_bits != 0) extra.appendAssumeCapacity(.{arg.noalias_bits});
6913 ip.extra.appendSliceAssumeCapacity(@ptrCast(arg.param_types));7775 extra.appendSliceAssumeCapacity(.{@ptrCast(arg.param_types)});
69147776
6915 // TODO: add appendSliceAssumeCapacity to MultiArrayList.7777 items.appendSliceAssumeCapacity(.{
6916 ip.items.appendAssumeCapacity(.{7778 .tag = &.{
6917 .tag = .func_instance,7779 .func_instance,
6918 .data = func_extra_index,7780 .type_error_union,
6919 });7781 .type_inferred_error_set,
6920 ip.items.appendAssumeCapacity(.{7782 .type_function,
6921 .tag = .type_error_union,7783 },
6922 .data = ip.addExtraAssumeCapacity(Tag.ErrorUnionType{7784 .data = &.{
6923 .error_set_type = error_set_type,7785 func_extra_index,
6924 .payload_type = arg.bare_return_type,7786 addExtraAssumeCapacity(extra, Tag.ErrorUnionType{
6925 }),7787 .error_set_type = error_set_type,
6926 });7788 .payload_type = arg.bare_return_type,
6927 ip.items.appendAssumeCapacity(.{7789 }),
6928 .tag = .type_inferred_error_set,7790 @intFromEnum(func_index),
6929 .data = @intFromEnum(func_index),7791 func_type_extra_index,
6930 });7792 },
6931 ip.items.appendAssumeCapacity(.{
6932 .tag = .type_function,
6933 .data = func_type_extra_index,
6934 });7793 });
7794 errdefer {
7795 items.mutate.len -= 4;
7796 extra.mutate.len = prev_extra_len;
7797 }
69357798
6936 const adapter: KeyAdapter = .{ .intern_pool = ip };7799 var func_gop = try ip.getOrPutKey(gpa, tid, .{
6937 const gop = ip.map.getOrPutAssumeCapacityAdapted(Key{7800 .func = ip.extraFuncInstance(tid, extra.list.*, func_extra_index),
6938 .func = extraFuncInstance(ip, func_extra_index),7801 });
6939 }, adapter);7802 defer func_gop.deinit();
6940 if (gop.found_existing) {7803 if (func_gop == .existing) {
6941 // Hot path: undo the additions to our two arrays.7804 // Hot path: undo the additions to our two arrays.
6942 ip.items.len -= 4;7805 items.mutate.len -= 4;
6943 ip.extra.items.len = prev_extra_len;7806 extra.mutate.len = prev_extra_len;
6944 return @enumFromInt(gop.index);7807 return func_gop.existing;
6945 }7808 }
69467809 var error_union_type_gop = try ip.getOrPutKey(gpa, tid, .{ .error_union_type = .{
6947 // Synchronize the map with items.
6948 assert(!ip.map.getOrPutAssumeCapacityAdapted(Key{ .error_union_type = .{
6949 .error_set_type = error_set_type,7810 .error_set_type = error_set_type,
6950 .payload_type = arg.bare_return_type,7811 .payload_type = arg.bare_return_type,
6951 } }, adapter).found_existing);7812 } });
6952 assert(!ip.map.getOrPutAssumeCapacityAdapted(Key{7813 defer error_union_type_gop.deinit();
7814 var error_set_type_gop = try ip.getOrPutKey(gpa, tid, .{
6953 .inferred_error_set_type = func_index,7815 .inferred_error_set_type = func_index,
6954 }, adapter).found_existing);7816 });
6955 assert(!ip.map.getOrPutAssumeCapacityAdapted(Key{7817 defer error_set_type_gop.deinit();
6956 .func_type = extraFuncType(ip, func_type_extra_index),7818 var func_ty_gop = try ip.getOrPutKey(gpa, tid, .{
6957 }, adapter).found_existing);7819 .func_type = extraFuncType(tid, extra.list.*, func_type_extra_index),
69587820 });
6959 return finishFuncInstance(7821 defer func_ty_gop.deinit();
7822 try finishFuncInstance(
6960 ip,7823 ip,
6961 gpa,7824 gpa,
7825 tid,
7826 extra,
6962 generic_owner,7827 generic_owner,
6963 func_index,7828 func_index,
6964 func_extra_index,7829 func_extra_index,
6965 arg.alignment,7830 arg.alignment,
6966 arg.section,7831 arg.section,
6967 );7832 );
7833 assert(func_gop.putAt(3) == func_index);
7834 assert(error_union_type_gop.putAt(2) == error_union_type);
7835 assert(error_set_type_gop.putAt(1) == error_set_type);
7836 assert(func_ty_gop.putAt(0) == func_ty);
7837 return func_index;
6968}7838}
69697839
6970fn finishFuncInstance(7840fn finishFuncInstance(
6971 ip: *InternPool,7841 ip: *InternPool,
6972 gpa: Allocator,7842 gpa: Allocator,
7843 tid: Zcu.PerThread.Id,
7844 extra: Local.Extra.Mutable,
6973 generic_owner: Index,7845 generic_owner: Index,
6974 func_index: Index,7846 func_index: Index,
6975 func_extra_index: u32,7847 func_extra_index: u32,
6976 alignment: Alignment,7848 alignment: Alignment,
6977 section: OptionalNullTerminatedString,7849 section: OptionalNullTerminatedString,
6978) Allocator.Error!Index {7850) Allocator.Error!void {
6979 const fn_owner_decl = ip.declPtr(ip.funcDeclOwner(generic_owner));7851 const fn_owner_decl = ip.declPtr(ip.funcDeclOwner(generic_owner));
6980 const decl_index = try ip.createDecl(gpa, .{7852 const decl_index = try ip.createDecl(gpa, .{
6981 .name = undefined,7853 .name = undefined,
...@@ -6995,17 +7867,15 @@ fn finishFuncInstance(...@@ -6995,17 +7867,15 @@ fn finishFuncInstance(
6995 errdefer ip.destroyDecl(gpa, decl_index);7867 errdefer ip.destroyDecl(gpa, decl_index);
69967868
6997 // Populate the owner_decl field which was left undefined until now.7869 // Populate the owner_decl field which was left undefined until now.
6998 ip.extra.items[7870 extra.view().items(.@"0")[
6999 func_extra_index + std.meta.fieldIndex(Tag.FuncInstance, "owner_decl").?7871 func_extra_index + std.meta.fieldIndex(Tag.FuncInstance, "owner_decl").?
7000 ] = @intFromEnum(decl_index);7872 ] = @intFromEnum(decl_index);
70017873
7002 // TODO: improve this name7874 // TODO: improve this name
7003 const decl = ip.declPtr(decl_index);7875 const decl = ip.declPtr(decl_index);
7004 decl.name = try ip.getOrPutStringFmt(gpa, "{}__anon_{d}", .{7876 decl.name = try ip.getOrPutStringFmt(gpa, tid, "{}__anon_{d}", .{
7005 fn_owner_decl.name.fmt(ip), @intFromEnum(decl_index),7877 fn_owner_decl.name.fmt(ip), @intFromEnum(decl_index),
7006 }, .no_embedded_nulls);7878 }, .no_embedded_nulls);
7007
7008 return func_index;
7009}7879}
70107880
7011pub const EnumTypeInit = struct {7881pub const EnumTypeInit = struct {
...@@ -7026,6 +7896,7 @@ pub const EnumTypeInit = struct {...@@ -7026,6 +7896,7 @@ pub const EnumTypeInit = struct {
7026};7896};
70277897
7028pub const WipEnumType = struct {7898pub const WipEnumType = struct {
7899 tid: Zcu.PerThread.Id,
7029 index: Index,7900 index: Index,
7030 tag_ty_index: u32,7901 tag_ty_index: u32,
7031 decl_index: u32,7902 decl_index: u32,
...@@ -7041,9 +7912,11 @@ pub const WipEnumType = struct {...@@ -7041,9 +7912,11 @@ pub const WipEnumType = struct {
7041 decl: DeclIndex,7912 decl: DeclIndex,
7042 namespace: OptionalNamespaceIndex,7913 namespace: OptionalNamespaceIndex,
7043 ) void {7914 ) void {
7044 ip.extra.items[wip.decl_index] = @intFromEnum(decl);7915 const extra = ip.getLocalShared(wip.tid).extra.acquire();
7916 const extra_items = extra.view().items(.@"0");
7917 extra_items[wip.decl_index] = @intFromEnum(decl);
7045 if (wip.namespace_index) |i| {7918 if (wip.namespace_index) |i| {
7046 ip.extra.items[i] = @intFromEnum(namespace.unwrap().?);7919 extra_items[i] = @intFromEnum(namespace.unwrap().?);
7047 } else {7920 } else {
7048 assert(namespace == .none);7921 assert(namespace == .none);
7049 }7922 }
...@@ -7051,7 +7924,8 @@ pub const WipEnumType = struct {...@@ -7051,7 +7924,8 @@ pub const WipEnumType = struct {
70517924
7052 pub fn setTagTy(wip: WipEnumType, ip: *InternPool, tag_ty: Index) void {7925 pub fn setTagTy(wip: WipEnumType, ip: *InternPool, tag_ty: Index) void {
7053 assert(ip.isIntegerType(tag_ty));7926 assert(ip.isIntegerType(tag_ty));
7054 ip.extra.items[wip.tag_ty_index] = @intFromEnum(tag_ty);7927 const extra = ip.getLocalShared(wip.tid).extra.acquire();
7928 extra.view().items(.@"0")[wip.tag_ty_index] = @intFromEnum(tag_ty);
7055 }7929 }
70567930
7057 pub const FieldConflict = struct {7931 pub const FieldConflict = struct {
...@@ -7063,28 +7937,31 @@ pub const WipEnumType = struct {...@@ -7063,28 +7937,31 @@ pub const WipEnumType = struct {
7063 /// If the enum is automatially numbered, `value` must be `.none`.7937 /// If the enum is automatially numbered, `value` must be `.none`.
7064 /// Otherwise, the type of `value` must be the integer tag type of the enum.7938 /// Otherwise, the type of `value` must be the integer tag type of the enum.
7065 pub fn nextField(wip: WipEnumType, ip: *InternPool, name: NullTerminatedString, value: Index) ?FieldConflict {7939 pub fn nextField(wip: WipEnumType, ip: *InternPool, name: NullTerminatedString, value: Index) ?FieldConflict {
7066 if (ip.addFieldName(wip.names_map, wip.names_start, name)) |conflict| {7940 const unwrapped_index = wip.index.unwrap(ip);
7941 const extra_list = ip.getLocalShared(unwrapped_index.tid).extra.acquire();
7942 const extra_items = extra_list.view().items(.@"0");
7943 if (ip.addFieldName(extra_list, wip.names_map, wip.names_start, name)) |conflict| {
7067 return .{ .kind = .name, .prev_field_idx = conflict };7944 return .{ .kind = .name, .prev_field_idx = conflict };
7068 }7945 }
7069 if (value == .none) {7946 if (value == .none) {
7070 assert(wip.values_map == .none);7947 assert(wip.values_map == .none);
7071 return null;7948 return null;
7072 }7949 }
7073 assert(ip.typeOf(value) == @as(Index, @enumFromInt(ip.extra.items[wip.tag_ty_index])));7950 assert(ip.typeOf(value) == @as(Index, @enumFromInt(extra_items[wip.tag_ty_index])));
7074 const map = &ip.maps.items[@intFromEnum(wip.values_map.unwrap().?)];7951 const map = &ip.maps.items[@intFromEnum(wip.values_map.unwrap().?)];
7075 const field_index = map.count();7952 const field_index = map.count();
7076 const indexes = ip.extra.items[wip.values_start..][0..field_index];7953 const indexes = extra_items[wip.values_start..][0..field_index];
7077 const adapter: Index.Adapter = .{ .indexes = @ptrCast(indexes) };7954 const adapter: Index.Adapter = .{ .indexes = @ptrCast(indexes) };
7078 const gop = map.getOrPutAssumeCapacityAdapted(value, adapter);7955 const gop = map.getOrPutAssumeCapacityAdapted(value, adapter);
7079 if (gop.found_existing) {7956 if (gop.found_existing) {
7080 return .{ .kind = .value, .prev_field_idx = @intCast(gop.index) };7957 return .{ .kind = .value, .prev_field_idx = @intCast(gop.index) };
7081 }7958 }
7082 ip.extra.items[wip.values_start + field_index] = @intFromEnum(value);7959 extra_items[wip.values_start + field_index] = @intFromEnum(value);
7083 return null;7960 return null;
7084 }7961 }
70857962
7086 pub fn cancel(wip: WipEnumType, ip: *InternPool) void {7963 pub fn cancel(wip: WipEnumType, ip: *InternPool, tid: Zcu.PerThread.Id) void {
7087 ip.remove(wip.index);7964 ip.remove(tid, wip.index);
7088 }7965 }
70897966
7090 pub const Result = union(enum) {7967 pub const Result = union(enum) {
...@@ -7096,10 +7973,10 @@ pub const WipEnumType = struct {...@@ -7096,10 +7973,10 @@ pub const WipEnumType = struct {
7096pub fn getEnumType(7973pub fn getEnumType(
7097 ip: *InternPool,7974 ip: *InternPool,
7098 gpa: Allocator,7975 gpa: Allocator,
7976 tid: Zcu.PerThread.Id,
7099 ini: EnumTypeInit,7977 ini: EnumTypeInit,
7100) Allocator.Error!WipEnumType.Result {7978) Allocator.Error!WipEnumType.Result {
7101 const adapter: KeyAdapter = .{ .intern_pool = ip };7979 var gop = try ip.getOrPutKey(gpa, tid, .{ .enum_type = switch (ini.key) {
7102 const gop = try ip.map.getOrPutAdapted(gpa, Key{ .enum_type = switch (ini.key) {
7103 .declared => |d| .{ .declared = .{7980 .declared => |d| .{ .declared = .{
7104 .zir_index = d.zir_index,7981 .zir_index = d.zir_index,
7105 .captures = .{ .external = d.captures },7982 .captures = .{ .external = d.captures },
...@@ -7108,12 +7985,14 @@ pub fn getEnumType(...@@ -7108,12 +7985,14 @@ pub fn getEnumType(
7108 .zir_index = r.zir_index,7985 .zir_index = r.zir_index,
7109 .type_hash = r.type_hash,7986 .type_hash = r.type_hash,
7110 } },7987 } },
7111 } }, adapter);7988 } });
7112 if (gop.found_existing) return .{ .existing = @enumFromInt(gop.index) };7989 defer gop.deinit();
7113 assert(gop.index == ip.items.len);7990 if (gop == .existing) return .{ .existing = gop.existing };
7114 errdefer _ = ip.map.pop();
71157991
7116 try ip.items.ensureUnusedCapacity(gpa, 1);7992 const local = ip.getLocal(tid);
7993 const items = local.getMutableItems(gpa);
7994 try items.ensureUnusedCapacity(1);
7995 const extra = local.getMutableExtra(gpa);
71177996
7118 const names_map = try ip.addMap(gpa, ini.fields_len);7997 const names_map = try ip.addMap(gpa, ini.fields_len);
7119 errdefer _ = ip.maps.pop();7998 errdefer _ = ip.maps.pop();
...@@ -7121,7 +8000,7 @@ pub fn getEnumType(...@@ -7121,7 +8000,7 @@ pub fn getEnumType(
7121 switch (ini.tag_mode) {8000 switch (ini.tag_mode) {
7122 .auto => {8001 .auto => {
7123 assert(!ini.has_values);8002 assert(!ini.has_values);
7124 try ip.extra.ensureUnusedCapacity(gpa, @typeInfo(EnumAuto).Struct.fields.len +8003 try extra.ensureUnusedCapacity(@typeInfo(EnumAuto).Struct.fields.len +
7125 // TODO: fmt bug8004 // TODO: fmt bug
7126 // zig fmt: off8005 // zig fmt: off
7127 switch (ini.key) {8006 switch (ini.key) {
...@@ -7131,7 +8010,7 @@ pub fn getEnumType(...@@ -7131,7 +8010,7 @@ pub fn getEnumType(
7131 // zig fmt: on8010 // zig fmt: on
7132 ini.fields_len); // field types8011 ini.fields_len); // field types
71338012
7134 const extra_index = ip.addExtraAssumeCapacity(EnumAuto{8013 const extra_index = addExtraAssumeCapacity(extra, EnumAuto{
7135 .decl = undefined, // set by `prepare`8014 .decl = undefined, // set by `prepare`
7136 .captures_len = switch (ini.key) {8015 .captures_len = switch (ini.key) {
7137 .declared => |d| @intCast(d.captures.len),8016 .declared => |d| @intCast(d.captures.len),
...@@ -7145,18 +8024,19 @@ pub fn getEnumType(...@@ -7145,18 +8024,19 @@ pub fn getEnumType(
7145 inline else => |x| x.zir_index,8024 inline else => |x| x.zir_index,
7146 }.toOptional(),8025 }.toOptional(),
7147 });8026 });
7148 ip.items.appendAssumeCapacity(.{8027 items.appendAssumeCapacity(.{
7149 .tag = .type_enum_auto,8028 .tag = .type_enum_auto,
7150 .data = extra_index,8029 .data = extra_index,
7151 });8030 });
7152 switch (ini.key) {8031 switch (ini.key) {
7153 .declared => |d| ip.extra.appendSliceAssumeCapacity(@ptrCast(d.captures)),8032 .declared => |d| extra.appendSliceAssumeCapacity(.{@ptrCast(d.captures)}),
7154 .reified => |r| _ = ip.addExtraAssumeCapacity(PackedU64.init(r.type_hash)),8033 .reified => |r| _ = addExtraAssumeCapacity(extra, PackedU64.init(r.type_hash)),
7155 }8034 }
7156 const names_start = ip.extra.items.len;8035 const names_start = extra.mutate.len;
7157 ip.extra.appendNTimesAssumeCapacity(undefined, ini.fields_len);8036 _ = extra.addManyAsSliceAssumeCapacity(ini.fields_len);
7158 return .{ .wip = .{8037 return .{ .wip = .{
7159 .index = @enumFromInt(gop.index),8038 .tid = tid,
8039 .index = gop.put(),
7160 .tag_ty_index = extra_index + std.meta.fieldIndex(EnumAuto, "int_tag_type").?,8040 .tag_ty_index = extra_index + std.meta.fieldIndex(EnumAuto, "int_tag_type").?,
7161 .decl_index = extra_index + std.meta.fieldIndex(EnumAuto, "decl").?,8041 .decl_index = extra_index + std.meta.fieldIndex(EnumAuto, "decl").?,
7162 .namespace_index = if (ini.has_namespace) extra_index + std.meta.fieldIndex(EnumAuto, "namespace").? else null,8042 .namespace_index = if (ini.has_namespace) extra_index + std.meta.fieldIndex(EnumAuto, "namespace").? else null,
...@@ -7172,10 +8052,10 @@ pub fn getEnumType(...@@ -7172,10 +8052,10 @@ pub fn getEnumType(
7172 break :m values_map.toOptional();8052 break :m values_map.toOptional();
7173 };8053 };
7174 errdefer if (ini.has_values) {8054 errdefer if (ini.has_values) {
7175 _ = ip.map.pop();8055 _ = ip.maps.pop();
7176 };8056 };
71778057
7178 try ip.extra.ensureUnusedCapacity(gpa, @typeInfo(EnumExplicit).Struct.fields.len +8058 try extra.ensureUnusedCapacity(@typeInfo(EnumExplicit).Struct.fields.len +
7179 // TODO: fmt bug8059 // TODO: fmt bug
7180 // zig fmt: off8060 // zig fmt: off
7181 switch (ini.key) {8061 switch (ini.key) {
...@@ -7186,7 +8066,7 @@ pub fn getEnumType(...@@ -7186,7 +8066,7 @@ pub fn getEnumType(
7186 ini.fields_len + // field types8066 ini.fields_len + // field types
7187 ini.fields_len * @intFromBool(ini.has_values)); // field values8067 ini.fields_len * @intFromBool(ini.has_values)); // field values
71888068
7189 const extra_index = ip.addExtraAssumeCapacity(EnumExplicit{8069 const extra_index = addExtraAssumeCapacity(extra, EnumExplicit{
7190 .decl = undefined, // set by `prepare`8070 .decl = undefined, // set by `prepare`
7191 .captures_len = switch (ini.key) {8071 .captures_len = switch (ini.key) {
7192 .declared => |d| @intCast(d.captures.len),8072 .declared => |d| @intCast(d.captures.len),
...@@ -7201,7 +8081,7 @@ pub fn getEnumType(...@@ -7201,7 +8081,7 @@ pub fn getEnumType(
7201 inline else => |x| x.zir_index,8081 inline else => |x| x.zir_index,
7202 }.toOptional(),8082 }.toOptional(),
7203 });8083 });
7204 ip.items.appendAssumeCapacity(.{8084 items.appendAssumeCapacity(.{
7205 .tag = switch (ini.tag_mode) {8085 .tag = switch (ini.tag_mode) {
7206 .auto => unreachable,8086 .auto => unreachable,
7207 .explicit => .type_enum_explicit,8087 .explicit => .type_enum_explicit,
...@@ -7210,17 +8090,18 @@ pub fn getEnumType(...@@ -7210,17 +8090,18 @@ pub fn getEnumType(
7210 .data = extra_index,8090 .data = extra_index,
7211 });8091 });
7212 switch (ini.key) {8092 switch (ini.key) {
7213 .declared => |d| ip.extra.appendSliceAssumeCapacity(@ptrCast(d.captures)),8093 .declared => |d| extra.appendSliceAssumeCapacity(.{@ptrCast(d.captures)}),
7214 .reified => |r| _ = ip.addExtraAssumeCapacity(PackedU64.init(r.type_hash)),8094 .reified => |r| _ = addExtraAssumeCapacity(extra, PackedU64.init(r.type_hash)),
7215 }8095 }
7216 const names_start = ip.extra.items.len;8096 const names_start = extra.mutate.len;
7217 ip.extra.appendNTimesAssumeCapacity(undefined, ini.fields_len);8097 _ = extra.addManyAsSliceAssumeCapacity(ini.fields_len);
7218 const values_start = ip.extra.items.len;8098 const values_start = extra.mutate.len;
7219 if (ini.has_values) {8099 if (ini.has_values) {
7220 ip.extra.appendNTimesAssumeCapacity(undefined, ini.fields_len);8100 _ = extra.addManyAsSliceAssumeCapacity(ini.fields_len);
7221 }8101 }
7222 return .{ .wip = .{8102 return .{ .wip = .{
7223 .index = @enumFromInt(gop.index),8103 .tid = tid,
8104 .index = gop.put(),
7224 .tag_ty_index = extra_index + std.meta.fieldIndex(EnumAuto, "int_tag_type").?,8105 .tag_ty_index = extra_index + std.meta.fieldIndex(EnumAuto, "int_tag_type").?,
7225 .decl_index = extra_index + std.meta.fieldIndex(EnumAuto, "decl").?,8106 .decl_index = extra_index + std.meta.fieldIndex(EnumAuto, "decl").?,
7226 .namespace_index = if (ini.has_namespace) extra_index + std.meta.fieldIndex(EnumAuto, "namespace").? else null,8107 .namespace_index = if (ini.has_namespace) extra_index + std.meta.fieldIndex(EnumAuto, "namespace").? else null,
...@@ -7245,13 +8126,20 @@ const GeneratedTagEnumTypeInit = struct {...@@ -7245,13 +8126,20 @@ const GeneratedTagEnumTypeInit = struct {
7245/// Creates an enum type which was automatically-generated as the tag type of a8126/// Creates an enum type which was automatically-generated as the tag type of a
7246/// `union` with no explicit tag type. Since this is only called once per union8127/// `union` with no explicit tag type. Since this is only called once per union
7247/// type, it asserts that no matching type yet exists.8128/// type, it asserts that no matching type yet exists.
7248pub fn getGeneratedTagEnumType(ip: *InternPool, gpa: Allocator, ini: GeneratedTagEnumTypeInit) Allocator.Error!Index {8129pub fn getGeneratedTagEnumType(
8130 ip: *InternPool,
8131 gpa: Allocator,
8132 tid: Zcu.PerThread.Id,
8133 ini: GeneratedTagEnumTypeInit,
8134) Allocator.Error!Index {
7249 assert(ip.isUnion(ini.owner_union_ty));8135 assert(ip.isUnion(ini.owner_union_ty));
7250 assert(ip.isIntegerType(ini.tag_ty));8136 assert(ip.isIntegerType(ini.tag_ty));
7251 for (ini.values) |val| assert(ip.typeOf(val) == ini.tag_ty);8137 for (ini.values) |val| assert(ip.typeOf(val) == ini.tag_ty);
72528138
7253 try ip.map.ensureUnusedCapacity(gpa, 1);8139 const local = ip.getLocal(tid);
7254 try ip.items.ensureUnusedCapacity(gpa, 1);8140 const items = local.getMutableItems(gpa);
8141 try items.ensureUnusedCapacity(1);
8142 const extra = local.getMutableExtra(gpa);
72558143
7256 const names_map = try ip.addMap(gpa, ini.names.len);8144 const names_map = try ip.addMap(gpa, ini.names.len);
7257 errdefer _ = ip.maps.pop();8145 errdefer _ = ip.maps.pop();
...@@ -7259,14 +8147,15 @@ pub fn getGeneratedTagEnumType(ip: *InternPool, gpa: Allocator, ini: GeneratedTa...@@ -7259,14 +8147,15 @@ pub fn getGeneratedTagEnumType(ip: *InternPool, gpa: Allocator, ini: GeneratedTa
72598147
7260 const fields_len: u32 = @intCast(ini.names.len);8148 const fields_len: u32 = @intCast(ini.names.len);
72618149
8150 const prev_extra_len = extra.mutate.len;
7262 switch (ini.tag_mode) {8151 switch (ini.tag_mode) {
7263 .auto => {8152 .auto => {
7264 try ip.extra.ensureUnusedCapacity(gpa, @typeInfo(EnumAuto).Struct.fields.len +8153 try extra.ensureUnusedCapacity(@typeInfo(EnumAuto).Struct.fields.len +
7265 1 + // owner_union8154 1 + // owner_union
7266 fields_len); // field names8155 fields_len); // field names
7267 ip.items.appendAssumeCapacity(.{8156 items.appendAssumeCapacity(.{
7268 .tag = .type_enum_auto,8157 .tag = .type_enum_auto,
7269 .data = ip.addExtraAssumeCapacity(EnumAuto{8158 .data = addExtraAssumeCapacity(extra, EnumAuto{
7270 .decl = ini.decl,8159 .decl = ini.decl,
7271 .captures_len = 0,8160 .captures_len = 0,
7272 .namespace = .none,8161 .namespace = .none,
...@@ -7276,11 +8165,11 @@ pub fn getGeneratedTagEnumType(ip: *InternPool, gpa: Allocator, ini: GeneratedTa...@@ -7276,11 +8165,11 @@ pub fn getGeneratedTagEnumType(ip: *InternPool, gpa: Allocator, ini: GeneratedTa
7276 .zir_index = .none,8165 .zir_index = .none,
7277 }),8166 }),
7278 });8167 });
7279 ip.extra.appendAssumeCapacity(@intFromEnum(ini.owner_union_ty));8168 extra.appendAssumeCapacity(.{@intFromEnum(ini.owner_union_ty)});
7280 ip.extra.appendSliceAssumeCapacity(@ptrCast(ini.names));8169 extra.appendSliceAssumeCapacity(.{@ptrCast(ini.names)});
7281 },8170 },
7282 .explicit, .nonexhaustive => {8171 .explicit, .nonexhaustive => {
7283 try ip.extra.ensureUnusedCapacity(gpa, @typeInfo(EnumExplicit).Struct.fields.len +8172 try extra.ensureUnusedCapacity(@typeInfo(EnumExplicit).Struct.fields.len +
7284 1 + // owner_union8173 1 + // owner_union
7285 fields_len + // field names8174 fields_len + // field names
7286 ini.values.len); // field values8175 ini.values.len); // field values
...@@ -7293,13 +8182,13 @@ pub fn getGeneratedTagEnumType(ip: *InternPool, gpa: Allocator, ini: GeneratedTa...@@ -7293,13 +8182,13 @@ pub fn getGeneratedTagEnumType(ip: *InternPool, gpa: Allocator, ini: GeneratedTa
7293 // We don't clean up the values map on error!8182 // We don't clean up the values map on error!
7294 errdefer @compileError("error path leaks values_map");8183 errdefer @compileError("error path leaks values_map");
72958184
7296 ip.items.appendAssumeCapacity(.{8185 items.appendAssumeCapacity(.{
7297 .tag = switch (ini.tag_mode) {8186 .tag = switch (ini.tag_mode) {
7298 .explicit => .type_enum_explicit,8187 .explicit => .type_enum_explicit,
7299 .nonexhaustive => .type_enum_nonexhaustive,8188 .nonexhaustive => .type_enum_nonexhaustive,
7300 .auto => unreachable,8189 .auto => unreachable,
7301 },8190 },
7302 .data = ip.addExtraAssumeCapacity(EnumExplicit{8191 .data = addExtraAssumeCapacity(extra, EnumExplicit{
7303 .decl = ini.decl,8192 .decl = ini.decl,
7304 .captures_len = 0,8193 .captures_len = 0,
7305 .namespace = .none,8194 .namespace = .none,
...@@ -7310,22 +8199,22 @@ pub fn getGeneratedTagEnumType(ip: *InternPool, gpa: Allocator, ini: GeneratedTa...@@ -7310,22 +8199,22 @@ pub fn getGeneratedTagEnumType(ip: *InternPool, gpa: Allocator, ini: GeneratedTa
7310 .zir_index = .none,8199 .zir_index = .none,
7311 }),8200 }),
7312 });8201 });
7313 ip.extra.appendAssumeCapacity(@intFromEnum(ini.owner_union_ty));8202 extra.appendAssumeCapacity(.{@intFromEnum(ini.owner_union_ty)});
7314 ip.extra.appendSliceAssumeCapacity(@ptrCast(ini.names));8203 extra.appendSliceAssumeCapacity(.{@ptrCast(ini.names)});
7315 ip.extra.appendSliceAssumeCapacity(@ptrCast(ini.values));8204 extra.appendSliceAssumeCapacity(.{@ptrCast(ini.values)});
7316 },8205 },
7317 }8206 }
7318 // Same as above8207 errdefer extra.mutate.len = prev_extra_len;
7319 errdefer @compileError("error path leaks values_map and extra data");8208 errdefer switch (ini.tag_mode) {
8209 .auto => {},
8210 .explicit, .nonexhaustive => _ = if (ini.values.len != 0) ip.maps.pop(),
8211 };
73208212
7321 // Capacity for this was ensured earlier8213 var gop = try ip.getOrPutKey(gpa, tid, .{ .enum_type = .{
7322 const adapter: KeyAdapter = .{ .intern_pool = ip };
7323 const gop = ip.map.getOrPutAssumeCapacityAdapted(Key{ .enum_type = .{
7324 .generated_tag = .{ .union_type = ini.owner_union_ty },8214 .generated_tag = .{ .union_type = ini.owner_union_ty },
7325 } }, adapter);8215 } });
7326 assert(!gop.found_existing);8216 defer gop.deinit();
7327 assert(gop.index == ip.items.len - 1);8217 return gop.put();
7328 return @enumFromInt(gop.index);
7329}8218}
73308219
7331pub const OpaqueTypeInit = struct {8220pub const OpaqueTypeInit = struct {
...@@ -7342,9 +8231,13 @@ pub const OpaqueTypeInit = struct {...@@ -7342,9 +8231,13 @@ pub const OpaqueTypeInit = struct {
7342 },8231 },
7343};8232};
73448233
7345pub fn getOpaqueType(ip: *InternPool, gpa: Allocator, ini: OpaqueTypeInit) Allocator.Error!WipNamespaceType.Result {8234pub fn getOpaqueType(
7346 const adapter: KeyAdapter = .{ .intern_pool = ip };8235 ip: *InternPool,
7347 const gop = try ip.map.getOrPutAdapted(gpa, Key{ .opaque_type = switch (ini.key) {8236 gpa: Allocator,
8237 tid: Zcu.PerThread.Id,
8238 ini: OpaqueTypeInit,
8239) Allocator.Error!WipNamespaceType.Result {
8240 var gop = try ip.getOrPutKey(gpa, tid, .{ .opaque_type = switch (ini.key) {
7348 .declared => |d| .{ .declared = .{8241 .declared => |d| .{ .declared = .{
7349 .zir_index = d.zir_index,8242 .zir_index = d.zir_index,
7350 .captures = .{ .external = d.captures },8243 .captures = .{ .external = d.captures },
...@@ -7353,15 +8246,20 @@ pub fn getOpaqueType(ip: *InternPool, gpa: Allocator, ini: OpaqueTypeInit) Alloc...@@ -7353,15 +8246,20 @@ pub fn getOpaqueType(ip: *InternPool, gpa: Allocator, ini: OpaqueTypeInit) Alloc
7353 .zir_index = r.zir_index,8246 .zir_index = r.zir_index,
7354 .type_hash = 0,8247 .type_hash = 0,
7355 } },8248 } },
7356 } }, adapter);8249 } });
7357 if (gop.found_existing) return .{ .existing = @enumFromInt(gop.index) };8250 defer gop.deinit();
7358 errdefer _ = ip.map.pop();8251 if (gop == .existing) return .{ .existing = gop.existing };
7359 try ip.items.ensureUnusedCapacity(gpa, 1);8252
7360 try ip.extra.ensureUnusedCapacity(gpa, @typeInfo(Tag.TypeOpaque).Struct.fields.len + switch (ini.key) {8253 const local = ip.getLocal(tid);
8254 const items = local.getMutableItems(gpa);
8255 const extra = local.getMutableExtra(gpa);
8256 try items.ensureUnusedCapacity(1);
8257
8258 try extra.ensureUnusedCapacity(@typeInfo(Tag.TypeOpaque).Struct.fields.len + switch (ini.key) {
7361 .declared => |d| d.captures.len,8259 .declared => |d| d.captures.len,
7362 .reified => 0,8260 .reified => 0,
7363 });8261 });
7364 const extra_index = ip.addExtraAssumeCapacity(Tag.TypeOpaque{8262 const extra_index = addExtraAssumeCapacity(extra, Tag.TypeOpaque{
7365 .decl = undefined, // set by `finish`8263 .decl = undefined, // set by `finish`
7366 .namespace = .none,8264 .namespace = .none,
7367 .zir_index = switch (ini.key) {8265 .zir_index = switch (ini.key) {
...@@ -7372,16 +8270,17 @@ pub fn getOpaqueType(ip: *InternPool, gpa: Allocator, ini: OpaqueTypeInit) Alloc...@@ -7372,16 +8270,17 @@ pub fn getOpaqueType(ip: *InternPool, gpa: Allocator, ini: OpaqueTypeInit) Alloc
7372 .reified => std.math.maxInt(u32),8270 .reified => std.math.maxInt(u32),
7373 },8271 },
7374 });8272 });
7375 ip.items.appendAssumeCapacity(.{8273 items.appendAssumeCapacity(.{
7376 .tag = .type_opaque,8274 .tag = .type_opaque,
7377 .data = extra_index,8275 .data = extra_index,
7378 });8276 });
7379 switch (ini.key) {8277 switch (ini.key) {
7380 .declared => |d| ip.extra.appendSliceAssumeCapacity(@ptrCast(d.captures)),8278 .declared => |d| extra.appendSliceAssumeCapacity(.{@ptrCast(d.captures)}),
7381 .reified => {},8279 .reified => {},
7382 }8280 }
7383 return .{ .wip = .{8281 return .{ .wip = .{
7384 .index = @enumFromInt(gop.index),8282 .tid = tid,
8283 .index = gop.put(),
7385 .decl_extra_index = extra_index + std.meta.fieldIndex(Tag.TypeOpaque, "decl").?,8284 .decl_extra_index = extra_index + std.meta.fieldIndex(Tag.TypeOpaque, "decl").?,
7386 .namespace_extra_index = if (ini.has_namespace)8285 .namespace_extra_index = if (ini.has_namespace)
7387 extra_index + std.meta.fieldIndex(Tag.TypeOpaque, "namespace").?8286 extra_index + std.meta.fieldIndex(Tag.TypeOpaque, "namespace").?
...@@ -7391,13 +8290,20 @@ pub fn getOpaqueType(ip: *InternPool, gpa: Allocator, ini: OpaqueTypeInit) Alloc...@@ -7391,13 +8290,20 @@ pub fn getOpaqueType(ip: *InternPool, gpa: Allocator, ini: OpaqueTypeInit) Alloc
7391}8290}
73928291
7393pub fn getIfExists(ip: *const InternPool, key: Key) ?Index {8292pub fn getIfExists(ip: *const InternPool, key: Key) ?Index {
7394 const adapter: KeyAdapter = .{ .intern_pool = ip };8293 const full_hash = key.hash64(ip);
7395 const index = ip.map.getIndexAdapted(key, adapter) orelse return null;8294 const hash: u32 = @truncate(full_hash >> 32);
7396 return @enumFromInt(index);8295 const shard = &ip.shards[@intCast(full_hash & (ip.shards.len - 1))];
7397}8296 const map = shard.shared.map.acquire();
73988297 const map_mask = map.header().mask();
7399pub fn getAssumeExists(ip: *const InternPool, key: Key) Index {8298 var map_index = hash;
7400 return ip.getIfExists(key).?;8299 while (true) : (map_index += 1) {
8300 map_index &= map_mask;
8301 const entry = &map.entries[map_index];
8302 const index = entry.acquire();
8303 if (index == .none) return null;
8304 if (entry.hash != hash) continue;
8305 if (ip.indexToKey(index).eql(key, ip)) return index;
8306 }
7401}8307}
74028308
7403fn addStringsToMap(8309fn addStringsToMap(
...@@ -7437,57 +8343,67 @@ fn addMap(ip: *InternPool, gpa: Allocator, cap: usize) Allocator.Error!MapIndex...@@ -7437,57 +8343,67 @@ fn addMap(ip: *InternPool, gpa: Allocator, cap: usize) Allocator.Error!MapIndex
7437/// This operation only happens under compile error conditions.8343/// This operation only happens under compile error conditions.
7438/// Leak the index until the next garbage collection.8344/// Leak the index until the next garbage collection.
7439/// Invalidates all references to this index.8345/// Invalidates all references to this index.
7440pub fn remove(ip: *InternPool, index: Index) void {8346pub fn remove(ip: *InternPool, tid: Zcu.PerThread.Id, index: Index) void {
8347 const unwrapped_index = index.unwrap(ip);
7441 if (@intFromEnum(index) < static_keys.len) {8348 if (@intFromEnum(index) < static_keys.len) {
7442 // The item being removed replaced a special index via `InternPool.resolveBuiltinType`.8349 // The item being removed replaced a special index via `InternPool.resolveBuiltinType`.
7443 // Restore the original item at this index.8350 // Restore the original item at this index.
7444 switch (static_keys[@intFromEnum(index)]) {8351 assert(static_keys[@intFromEnum(index)] == .simple_type);
7445 .simple_type => |s| {8352 const items = ip.getLocalShared(unwrapped_index.tid).items.acquire().view();
7446 ip.items.set(@intFromEnum(index), .{8353 @atomicStore(Tag, &items.items(.tag)[unwrapped_index.index], .simple_type, .monotonic);
7447 .tag = .simple_type,
7448 .data = @intFromEnum(s),
7449 });
7450 },
7451 else => unreachable,
7452 }
7453 return;8354 return;
7454 }8355 }
74558356
7456 if (@intFromEnum(index) == ip.items.len - 1) {8357 if (unwrapped_index.tid == tid) {
7457 // Happy case - we can just drop the item without affecting any other indices.8358 const items_len = &ip.getLocal(unwrapped_index.tid).mutate.items.len;
7458 ip.items.len -= 1;8359 if (unwrapped_index.index == items_len.* - 1) {
7459 _ = ip.map.pop();8360 // Happy case - we can just drop the item without affecting any other indices.
7460 } else {8361 items_len.* -= 1;
7461 // We must preserve the item so that indices following it remain valid.8362 return;
7462 // Thus, we will rewrite the tag to `removed`, leaking the item until8363 }
7463 // next GC but causing `KeyAdapter` to ignore it.
7464 ip.items.set(@intFromEnum(index), .{ .tag = .removed, .data = undefined });
7465 }8364 }
8365
8366 // We must preserve the item so that indices following it remain valid.
8367 // Thus, we will rewrite the tag to `removed`, leaking the item until
8368 // next GC but causing `KeyAdapter` to ignore it.
8369 const items = ip.getLocalShared(unwrapped_index.tid).items.acquire().view();
8370 @atomicStore(Tag, &items.items(.tag)[unwrapped_index.index], .removed, .monotonic);
7466}8371}
74678372
7468fn addInt(ip: *InternPool, gpa: Allocator, ty: Index, tag: Tag, limbs: []const Limb) !void {8373fn addInt(
8374 ip: *InternPool,
8375 gpa: Allocator,
8376 tid: Zcu.PerThread.Id,
8377 ty: Index,
8378 tag: Tag,
8379 limbs: []const Limb,
8380) !void {
8381 const local = ip.getLocal(tid);
8382 const items_list = local.getMutableItems(gpa);
8383 const limbs_list = local.getMutableLimbs(gpa);
7469 const limbs_len: u32 = @intCast(limbs.len);8384 const limbs_len: u32 = @intCast(limbs.len);
7470 try ip.reserveLimbs(gpa, @typeInfo(Int).Struct.fields.len + limbs_len);8385 try limbs_list.ensureUnusedCapacity(Int.limbs_items_len + limbs_len);
7471 ip.items.appendAssumeCapacity(.{8386 items_list.appendAssumeCapacity(.{
7472 .tag = tag,8387 .tag = tag,
7473 .data = ip.addLimbsExtraAssumeCapacity(Int{8388 .data = limbs_list.mutate.len,
7474 .ty = ty,8389 });
7475 .limbs_len = limbs_len,8390 limbs_list.addManyAsArrayAssumeCapacity(Int.limbs_items_len)[0].* = @bitCast(Int{
7476 }),8391 .ty = ty,
8392 .limbs_len = limbs_len,
7477 });8393 });
7478 ip.addLimbsAssumeCapacity(limbs);8394 limbs_list.appendSliceAssumeCapacity(.{limbs});
7479}8395}
74808396
7481fn addExtra(ip: *InternPool, gpa: Allocator, extra: anytype) Allocator.Error!u32 {8397fn addExtra(extra: Local.Extra.Mutable, item: anytype) Allocator.Error!u32 {
7482 const fields = @typeInfo(@TypeOf(extra)).Struct.fields;8398 const fields = @typeInfo(@TypeOf(item)).Struct.fields;
7483 try ip.extra.ensureUnusedCapacity(gpa, fields.len);8399 try extra.ensureUnusedCapacity(fields.len);
7484 return ip.addExtraAssumeCapacity(extra);8400 return addExtraAssumeCapacity(extra, item);
7485}8401}
74868402
7487fn addExtraAssumeCapacity(ip: *InternPool, extra: anytype) u32 {8403fn addExtraAssumeCapacity(extra: Local.Extra.Mutable, item: anytype) u32 {
7488 const result: u32 = @intCast(ip.extra.items.len);8404 const result: u32 = extra.mutate.len;
7489 inline for (@typeInfo(@TypeOf(extra)).Struct.fields) |field| {8405 inline for (@typeInfo(@TypeOf(item)).Struct.fields) |field| {
7490 ip.extra.appendAssumeCapacity(switch (field.type) {8406 extra.appendAssumeCapacity(.{switch (field.type) {
7491 Index,8407 Index,
7492 DeclIndex,8408 DeclIndex,
7493 NamespaceIndex,8409 NamespaceIndex,
...@@ -7502,7 +8418,7 @@ fn addExtraAssumeCapacity(ip: *InternPool, extra: anytype) u32 {...@@ -7502,7 +8418,7 @@ fn addExtraAssumeCapacity(ip: *InternPool, extra: anytype) u32 {
7502 TrackedInst.Index,8418 TrackedInst.Index,
7503 TrackedInst.Index.Optional,8419 TrackedInst.Index.Optional,
7504 ComptimeAllocIndex,8420 ComptimeAllocIndex,
7505 => @intFromEnum(@field(extra, field.name)),8421 => @intFromEnum(@field(item, field.name)),
75068422
7507 u32,8423 u32,
7508 i32,8424 i32,
...@@ -7514,22 +8430,14 @@ fn addExtraAssumeCapacity(ip: *InternPool, extra: anytype) u32 {...@@ -7514,22 +8430,14 @@ fn addExtraAssumeCapacity(ip: *InternPool, extra: anytype) u32 {
7514 Tag.TypeStruct.Flags,8430 Tag.TypeStruct.Flags,
7515 Tag.TypeStructPacked.Flags,8431 Tag.TypeStructPacked.Flags,
7516 Tag.Variable.Flags,8432 Tag.Variable.Flags,
7517 => @bitCast(@field(extra, field.name)),8433 => @bitCast(@field(item, field.name)),
75188434
7519 else => @compileError("bad field type: " ++ @typeName(field.type)),8435 else => @compileError("bad field type: " ++ @typeName(field.type)),
7520 });8436 }});
7521 }8437 }
7522 return result;8438 return result;
7523}8439}
75248440
7525fn reserveLimbs(ip: *InternPool, gpa: Allocator, n: usize) !void {
7526 switch (@sizeOf(Limb)) {
7527 @sizeOf(u32) => try ip.extra.ensureUnusedCapacity(gpa, n),
7528 @sizeOf(u64) => try ip.limbs.ensureUnusedCapacity(gpa, n),
7529 else => @compileError("unsupported host"),
7530 }
7531}
7532
7533fn addLimbsExtraAssumeCapacity(ip: *InternPool, extra: anytype) u32 {8441fn addLimbsExtraAssumeCapacity(ip: *InternPool, extra: anytype) u32 {
7534 switch (@sizeOf(Limb)) {8442 switch (@sizeOf(Limb)) {
7535 @sizeOf(u32) => return addExtraAssumeCapacity(ip, extra),8443 @sizeOf(u32) => return addExtraAssumeCapacity(ip, extra),
...@@ -7552,19 +8460,12 @@ fn addLimbsExtraAssumeCapacity(ip: *InternPool, extra: anytype) u32 {...@@ -7552,19 +8460,12 @@ fn addLimbsExtraAssumeCapacity(ip: *InternPool, extra: anytype) u32 {
7552 return result;8460 return result;
7553}8461}
75548462
7555fn addLimbsAssumeCapacity(ip: *InternPool, limbs: []const Limb) void {8463fn extraDataTrail(extra: Local.Extra, comptime T: type, index: u32) struct { data: T, end: u32 } {
7556 switch (@sizeOf(Limb)) {8464 const extra_items = extra.view().items(.@"0");
7557 @sizeOf(u32) => ip.extra.appendSliceAssumeCapacity(limbs),
7558 @sizeOf(u64) => ip.limbs.appendSliceAssumeCapacity(limbs),
7559 else => @compileError("unsupported host"),
7560 }
7561}
7562
7563fn extraDataTrail(ip: *const InternPool, comptime T: type, index: usize) struct { data: T, end: u32 } {
7564 var result: T = undefined;8465 var result: T = undefined;
7565 const fields = @typeInfo(T).Struct.fields;8466 const fields = @typeInfo(T).Struct.fields;
7566 inline for (fields, 0..) |field, i| {8467 inline for (fields, index..) |field, extra_index| {
7567 const int32 = ip.extra.items[i + index];8468 const extra_item = extra_items[extra_index];
7568 @field(result, field.name) = switch (field.type) {8469 @field(result, field.name) = switch (field.type) {
7569 Index,8470 Index,
7570 DeclIndex,8471 DeclIndex,
...@@ -7580,7 +8481,7 @@ fn extraDataTrail(ip: *const InternPool, comptime T: type, index: usize) struct...@@ -7580,7 +8481,7 @@ fn extraDataTrail(ip: *const InternPool, comptime T: type, index: usize) struct
7580 TrackedInst.Index,8481 TrackedInst.Index,
7581 TrackedInst.Index.Optional,8482 TrackedInst.Index.Optional,
7582 ComptimeAllocIndex,8483 ComptimeAllocIndex,
7583 => @enumFromInt(int32),8484 => @enumFromInt(extra_item),
75848485
7585 u32,8486 u32,
7586 i32,8487 i32,
...@@ -7592,7 +8493,7 @@ fn extraDataTrail(ip: *const InternPool, comptime T: type, index: usize) struct...@@ -7592,7 +8493,7 @@ fn extraDataTrail(ip: *const InternPool, comptime T: type, index: usize) struct
7592 Tag.TypeStructPacked.Flags,8493 Tag.TypeStructPacked.Flags,
7593 Tag.Variable.Flags,8494 Tag.Variable.Flags,
7594 FuncAnalysis,8495 FuncAnalysis,
7595 => @bitCast(int32),8496 => @bitCast(extra_item),
75968497
7597 else => @compileError("bad field type: " ++ @typeName(field.type)),8498 else => @compileError("bad field type: " ++ @typeName(field.type)),
7598 };8499 };
...@@ -7603,75 +8504,8 @@ fn extraDataTrail(ip: *const InternPool, comptime T: type, index: usize) struct...@@ -7603,75 +8504,8 @@ fn extraDataTrail(ip: *const InternPool, comptime T: type, index: usize) struct
7603 };8504 };
7604}8505}
76058506
7606fn extraData(ip: *const InternPool, comptime T: type, index: usize) T {8507fn extraData(extra: Local.Extra, comptime T: type, index: u32) T {
7607 return extraDataTrail(ip, T, index).data;8508 return extraDataTrail(extra, T, index).data;
7608}
7609
7610/// Asserts the struct has 32-bit fields and the number of fields is evenly divisible by 2.
7611fn limbData(ip: *const InternPool, comptime T: type, index: usize) T {
7612 switch (@sizeOf(Limb)) {
7613 @sizeOf(u32) => return extraData(ip, T, index),
7614 @sizeOf(u64) => {},
7615 else => @compileError("unsupported host"),
7616 }
7617 var result: T = undefined;
7618 inline for (@typeInfo(T).Struct.fields, 0..) |field, i| {
7619 const host_int = ip.limbs.items[index + i / 2];
7620 const int32 = if (i % 2 == 0)
7621 @as(u32, @truncate(host_int))
7622 else
7623 @as(u32, @truncate(host_int >> 32));
7624
7625 @field(result, field.name) = switch (field.type) {
7626 u32 => int32,
7627 Index => @enumFromInt(int32),
7628 else => @compileError("bad field type: " ++ @typeName(field.type)),
7629 };
7630 }
7631 return result;
7632}
7633
7634/// This function returns the Limb slice that is trailing data after a payload.
7635fn limbSlice(ip: *const InternPool, comptime S: type, limb_index: u32, len: u32) []const Limb {
7636 const field_count = @typeInfo(S).Struct.fields.len;
7637 switch (@sizeOf(Limb)) {
7638 @sizeOf(u32) => {
7639 const start = limb_index + field_count;
7640 return ip.extra.items[start..][0..len];
7641 },
7642 @sizeOf(u64) => {
7643 const start = limb_index + @divExact(field_count, 2);
7644 return ip.limbs.items[start..][0..len];
7645 },
7646 else => @compileError("unsupported host"),
7647 }
7648}
7649
7650const LimbsAsIndexes = struct {
7651 start: u32,
7652 len: u32,
7653};
7654
7655fn limbsSliceToIndex(ip: *const InternPool, limbs: []const Limb) LimbsAsIndexes {
7656 const host_slice = switch (@sizeOf(Limb)) {
7657 @sizeOf(u32) => ip.extra.items,
7658 @sizeOf(u64) => ip.limbs.items,
7659 else => @compileError("unsupported host"),
7660 };
7661 // TODO: https://github.com/ziglang/zig/issues/1738
7662 return .{
7663 .start = @intCast(@divExact(@intFromPtr(limbs.ptr) - @intFromPtr(host_slice.ptr), @sizeOf(Limb))),
7664 .len = @intCast(limbs.len),
7665 };
7666}
7667
7668/// This function converts Limb array indexes to a primitive slice type.
7669fn limbsIndexToSlice(ip: *const InternPool, limbs: LimbsAsIndexes) []const Limb {
7670 return switch (@sizeOf(Limb)) {
7671 @sizeOf(u32) => ip.extra.items[limbs.start..][0..limbs.len],
7672 @sizeOf(u64) => ip.limbs.items[limbs.start..][0..limbs.len],
7673 else => @compileError("unsupported host"),
7674 };
7675}8509}
76768510
7677test "basic usage" {8511test "basic usage" {
...@@ -7680,23 +8514,23 @@ test "basic usage" {...@@ -7680,23 +8514,23 @@ test "basic usage" {
7680 var ip: InternPool = .{};8514 var ip: InternPool = .{};
7681 defer ip.deinit(gpa);8515 defer ip.deinit(gpa);
76828516
7683 const i32_type = try ip.get(gpa, .{ .int_type = .{8517 const i32_type = try ip.get(gpa, .main, .{ .int_type = .{
7684 .signedness = .signed,8518 .signedness = .signed,
7685 .bits = 32,8519 .bits = 32,
7686 } });8520 } });
7687 const array_i32 = try ip.get(gpa, .{ .array_type = .{8521 const array_i32 = try ip.get(gpa, .main, .{ .array_type = .{
7688 .len = 10,8522 .len = 10,
7689 .child = i32_type,8523 .child = i32_type,
7690 .sentinel = .none,8524 .sentinel = .none,
7691 } });8525 } });
76928526
7693 const another_i32_type = try ip.get(gpa, .{ .int_type = .{8527 const another_i32_type = try ip.get(gpa, .main, .{ .int_type = .{
7694 .signedness = .signed,8528 .signedness = .signed,
7695 .bits = 32,8529 .bits = 32,
7696 } });8530 } });
7697 try std.testing.expect(another_i32_type == i32_type);8531 try std.testing.expect(another_i32_type == i32_type);
76988532
7699 const another_array_i32 = try ip.get(gpa, .{ .array_type = .{8533 const another_array_i32 = try ip.get(gpa, .main, .{ .array_type = .{
7700 .len = 10,8534 .len = 10,
7701 .child = i32_type,8535 .child = i32_type,
7702 .sentinel = .none,8536 .sentinel = .none,
...@@ -7715,13 +8549,13 @@ pub fn childType(ip: *const InternPool, i: Index) Index {...@@ -7715,13 +8549,13 @@ pub fn childType(ip: *const InternPool, i: Index) Index {
7715}8549}
77168550
7717/// Given a slice type, returns the type of the ptr field.8551/// Given a slice type, returns the type of the ptr field.
7718pub fn slicePtrType(ip: *const InternPool, i: Index) Index {8552pub fn slicePtrType(ip: *const InternPool, index: Index) Index {
7719 switch (i) {8553 switch (index) {
7720 .slice_const_u8_type => return .manyptr_const_u8_type,8554 .slice_const_u8_type => return .manyptr_const_u8_type,
7721 .slice_const_u8_sentinel_0_type => return .manyptr_const_u8_sentinel_0_type,8555 .slice_const_u8_sentinel_0_type => return .manyptr_const_u8_sentinel_0_type,
7722 else => {},8556 else => {},
7723 }8557 }
7724 const item = ip.items.get(@intFromEnum(i));8558 const item = index.unwrap(ip).getItem(ip);
7725 switch (item.tag) {8559 switch (item.tag) {
7726 .type_slice => return @enumFromInt(item.data),8560 .type_slice => return @enumFromInt(item.data),
7727 else => unreachable, // not a slice type8561 else => unreachable, // not a slice type
...@@ -7729,19 +8563,21 @@ pub fn slicePtrType(ip: *const InternPool, i: Index) Index {...@@ -7729,19 +8563,21 @@ pub fn slicePtrType(ip: *const InternPool, i: Index) Index {
7729}8563}
77308564
7731/// Given a slice value, returns the value of the ptr field.8565/// Given a slice value, returns the value of the ptr field.
7732pub fn slicePtr(ip: *const InternPool, i: Index) Index {8566pub fn slicePtr(ip: *const InternPool, index: Index) Index {
7733 const item = ip.items.get(@intFromEnum(i));8567 const unwrapped_index = index.unwrap(ip);
8568 const item = unwrapped_index.getItem(ip);
7734 switch (item.tag) {8569 switch (item.tag) {
7735 .ptr_slice => return ip.extraData(PtrSlice, item.data).ptr,8570 .ptr_slice => return extraData(unwrapped_index.getExtra(ip), PtrSlice, item.data).ptr,
7736 else => unreachable, // not a slice value8571 else => unreachable, // not a slice value
7737 }8572 }
7738}8573}
77398574
7740/// Given a slice value, returns the value of the len field.8575/// Given a slice value, returns the value of the len field.
7741pub fn sliceLen(ip: *const InternPool, i: Index) Index {8576pub fn sliceLen(ip: *const InternPool, index: Index) Index {
7742 const item = ip.items.get(@intFromEnum(i));8577 const unwrapped_index = index.unwrap(ip);
8578 const item = unwrapped_index.getItem(ip);
7743 switch (item.tag) {8579 switch (item.tag) {
7744 .ptr_slice => return ip.extraData(PtrSlice, item.data).len,8580 .ptr_slice => return extraData(unwrapped_index.getExtra(ip), PtrSlice, item.data).len,
7745 else => unreachable, // not a slice value8581 else => unreachable, // not a slice value
7746 }8582 }
7747}8583}
...@@ -7766,59 +8602,66 @@ pub fn sliceLen(ip: *const InternPool, i: Index) Index {...@@ -7766,59 +8602,66 @@ pub fn sliceLen(ip: *const InternPool, i: Index) Index {
7766/// * payload => error union8602/// * payload => error union
7767/// * fn <=> fn8603/// * fn <=> fn
7768/// * aggregate <=> aggregate (where children can also be coerced)8604/// * aggregate <=> aggregate (where children can also be coerced)
7769pub fn getCoerced(ip: *InternPool, gpa: Allocator, val: Index, new_ty: Index) Allocator.Error!Index {8605pub fn getCoerced(
8606 ip: *InternPool,
8607 gpa: Allocator,
8608 tid: Zcu.PerThread.Id,
8609 val: Index,
8610 new_ty: Index,
8611) Allocator.Error!Index {
7770 const old_ty = ip.typeOf(val);8612 const old_ty = ip.typeOf(val);
7771 if (old_ty == new_ty) return val;8613 if (old_ty == new_ty) return val;
77728614
7773 const tags = ip.items.items(.tag);
7774
7775 switch (val) {8615 switch (val) {
7776 .undef => return ip.get(gpa, .{ .undef = new_ty }),8616 .undef => return ip.get(gpa, tid, .{ .undef = new_ty }),
7777 .null_value => {8617 .null_value => {
7778 if (ip.isOptionalType(new_ty)) return ip.get(gpa, .{ .opt = .{8618 if (ip.isOptionalType(new_ty)) return ip.get(gpa, tid, .{ .opt = .{
7779 .ty = new_ty,8619 .ty = new_ty,
7780 .val = .none,8620 .val = .none,
7781 } });8621 } });
77828622
7783 if (ip.isPointerType(new_ty)) switch (ip.indexToKey(new_ty).ptr_type.flags.size) {8623 if (ip.isPointerType(new_ty)) switch (ip.indexToKey(new_ty).ptr_type.flags.size) {
7784 .One, .Many, .C => return ip.get(gpa, .{ .ptr = .{8624 .One, .Many, .C => return ip.get(gpa, tid, .{ .ptr = .{
7785 .ty = new_ty,8625 .ty = new_ty,
7786 .base_addr = .int,8626 .base_addr = .int,
7787 .byte_offset = 0,8627 .byte_offset = 0,
7788 } }),8628 } }),
7789 .Slice => return ip.get(gpa, .{ .slice = .{8629 .Slice => return ip.get(gpa, tid, .{ .slice = .{
7790 .ty = new_ty,8630 .ty = new_ty,
7791 .ptr = try ip.get(gpa, .{ .ptr = .{8631 .ptr = try ip.get(gpa, tid, .{ .ptr = .{
7792 .ty = ip.slicePtrType(new_ty),8632 .ty = ip.slicePtrType(new_ty),
7793 .base_addr = .int,8633 .base_addr = .int,
7794 .byte_offset = 0,8634 .byte_offset = 0,
7795 } }),8635 } }),
7796 .len = try ip.get(gpa, .{ .undef = .usize_type }),8636 .len = try ip.get(gpa, tid, .{ .undef = .usize_type }),
7797 } }),8637 } }),
7798 };8638 };
7799 },8639 },
7800 else => switch (tags[@intFromEnum(val)]) {8640 else => {
7801 .func_decl => return getCoercedFuncDecl(ip, gpa, val, new_ty),8641 const unwrapped_val = val.unwrap(ip);
7802 .func_instance => return getCoercedFuncInstance(ip, gpa, val, new_ty),8642 const val_item = unwrapped_val.getItem(ip);
7803 .func_coerced => {8643 switch (val_item.tag) {
7804 const extra_index = ip.items.items(.data)[@intFromEnum(val)];8644 .func_decl => return getCoercedFuncDecl(ip, gpa, tid, val, new_ty),
7805 const func: Index = @enumFromInt(8645 .func_instance => return getCoercedFuncInstance(ip, gpa, tid, val, new_ty),
7806 ip.extra.items[extra_index + std.meta.fieldIndex(Tag.FuncCoerced, "func").?],8646 .func_coerced => {
7807 );8647 const func: Index = @enumFromInt(unwrapped_val.getExtra(ip).view().items(.@"0")[
7808 switch (tags[@intFromEnum(func)]) {8648 val_item.data + std.meta.fieldIndex(Tag.FuncCoerced, "func").?
7809 .func_decl => return getCoercedFuncDecl(ip, gpa, val, new_ty),8649 ]);
7810 .func_instance => return getCoercedFuncInstance(ip, gpa, val, new_ty),8650 switch (func.unwrap(ip).getTag(ip)) {
7811 else => unreachable,8651 .func_decl => return getCoercedFuncDecl(ip, gpa, tid, val, new_ty),
7812 }8652 .func_instance => return getCoercedFuncInstance(ip, gpa, tid, val, new_ty),
7813 },8653 else => unreachable,
7814 else => {},8654 }
8655 },
8656 else => {},
8657 }
7815 },8658 },
7816 }8659 }
78178660
7818 switch (ip.indexToKey(val)) {8661 switch (ip.indexToKey(val)) {
7819 .undef => return ip.get(gpa, .{ .undef = new_ty }),8662 .undef => return ip.get(gpa, tid, .{ .undef = new_ty }),
7820 .extern_func => |extern_func| if (ip.isFunctionType(new_ty))8663 .extern_func => |extern_func| if (ip.isFunctionType(new_ty))
7821 return ip.get(gpa, .{ .extern_func = .{8664 return ip.get(gpa, tid, .{ .extern_func = .{
7822 .ty = new_ty,8665 .ty = new_ty,
7823 .decl = extern_func.decl,8666 .decl = extern_func.decl,
7824 .lib_name = extern_func.lib_name,8667 .lib_name = extern_func.lib_name,
...@@ -7827,12 +8670,12 @@ pub fn getCoerced(ip: *InternPool, gpa: Allocator, val: Index, new_ty: Index) Al...@@ -7827,12 +8670,12 @@ pub fn getCoerced(ip: *InternPool, gpa: Allocator, val: Index, new_ty: Index) Al
7827 .func => unreachable,8670 .func => unreachable,
78288671
7829 .int => |int| switch (ip.indexToKey(new_ty)) {8672 .int => |int| switch (ip.indexToKey(new_ty)) {
7830 .enum_type => return ip.get(gpa, .{ .enum_tag = .{8673 .enum_type => return ip.get(gpa, tid, .{ .enum_tag = .{
7831 .ty = new_ty,8674 .ty = new_ty,
7832 .int = try ip.getCoerced(gpa, val, ip.loadEnumType(new_ty).tag_ty),8675 .int = try ip.getCoerced(gpa, tid, val, ip.loadEnumType(new_ty).tag_ty),
7833 } }),8676 } }),
7834 .ptr_type => switch (int.storage) {8677 .ptr_type => switch (int.storage) {
7835 inline .u64, .i64 => |int_val| return ip.get(gpa, .{ .ptr = .{8678 inline .u64, .i64 => |int_val| return ip.get(gpa, tid, .{ .ptr = .{
7836 .ty = new_ty,8679 .ty = new_ty,
7837 .base_addr = .int,8680 .base_addr = .int,
7838 .byte_offset = @intCast(int_val),8681 .byte_offset = @intCast(int_val),
...@@ -7841,7 +8684,7 @@ pub fn getCoerced(ip: *InternPool, gpa: Allocator, val: Index, new_ty: Index) Al...@@ -7841,7 +8684,7 @@ pub fn getCoerced(ip: *InternPool, gpa: Allocator, val: Index, new_ty: Index) Al
7841 .lazy_align, .lazy_size => {},8684 .lazy_align, .lazy_size => {},
7842 },8685 },
7843 else => if (ip.isIntegerType(new_ty))8686 else => if (ip.isIntegerType(new_ty))
7844 return getCoercedInts(ip, gpa, int, new_ty),8687 return ip.getCoercedInts(gpa, tid, int, new_ty),
7845 },8688 },
7846 .float => |float| switch (ip.indexToKey(new_ty)) {8689 .float => |float| switch (ip.indexToKey(new_ty)) {
7847 .simple_type => |simple| switch (simple) {8690 .simple_type => |simple| switch (simple) {
...@@ -7852,7 +8695,7 @@ pub fn getCoerced(ip: *InternPool, gpa: Allocator, val: Index, new_ty: Index) Al...@@ -7852,7 +8695,7 @@ pub fn getCoerced(ip: *InternPool, gpa: Allocator, val: Index, new_ty: Index) Al
7852 .f128,8695 .f128,
7853 .c_longdouble,8696 .c_longdouble,
7854 .comptime_float,8697 .comptime_float,
7855 => return ip.get(gpa, .{ .float = .{8698 => return ip.get(gpa, tid, .{ .float = .{
7856 .ty = new_ty,8699 .ty = new_ty,
7857 .storage = float.storage,8700 .storage = float.storage,
7858 } }),8701 } }),
...@@ -7861,17 +8704,17 @@ pub fn getCoerced(ip: *InternPool, gpa: Allocator, val: Index, new_ty: Index) Al...@@ -7861,17 +8704,17 @@ pub fn getCoerced(ip: *InternPool, gpa: Allocator, val: Index, new_ty: Index) Al
7861 else => {},8704 else => {},
7862 },8705 },
7863 .enum_tag => |enum_tag| if (ip.isIntegerType(new_ty))8706 .enum_tag => |enum_tag| if (ip.isIntegerType(new_ty))
7864 return getCoercedInts(ip, gpa, ip.indexToKey(enum_tag.int).int, new_ty),8707 return ip.getCoercedInts(gpa, tid, ip.indexToKey(enum_tag.int).int, new_ty),
7865 .enum_literal => |enum_literal| switch (ip.indexToKey(new_ty)) {8708 .enum_literal => |enum_literal| switch (ip.indexToKey(new_ty)) {
7866 .enum_type => {8709 .enum_type => {
7867 const enum_type = ip.loadEnumType(new_ty);8710 const enum_type = ip.loadEnumType(new_ty);
7868 const index = enum_type.nameIndex(ip, enum_literal).?;8711 const index = enum_type.nameIndex(ip, enum_literal).?;
7869 return ip.get(gpa, .{ .enum_tag = .{8712 return ip.get(gpa, tid, .{ .enum_tag = .{
7870 .ty = new_ty,8713 .ty = new_ty,
7871 .int = if (enum_type.values.len != 0)8714 .int = if (enum_type.values.len != 0)
7872 enum_type.values.get(ip)[index]8715 enum_type.values.get(ip)[index]
7873 else8716 else
7874 try ip.get(gpa, .{ .int = .{8717 try ip.get(gpa, tid, .{ .int = .{
7875 .ty = enum_type.tag_ty,8718 .ty = enum_type.tag_ty,
7876 .storage = .{ .u64 = index },8719 .storage = .{ .u64 = index },
7877 } }),8720 } }),
...@@ -7880,22 +8723,22 @@ pub fn getCoerced(ip: *InternPool, gpa: Allocator, val: Index, new_ty: Index) Al...@@ -7880,22 +8723,22 @@ pub fn getCoerced(ip: *InternPool, gpa: Allocator, val: Index, new_ty: Index) Al
7880 else => {},8723 else => {},
7881 },8724 },
7882 .slice => |slice| if (ip.isPointerType(new_ty) and ip.indexToKey(new_ty).ptr_type.flags.size == .Slice)8725 .slice => |slice| if (ip.isPointerType(new_ty) and ip.indexToKey(new_ty).ptr_type.flags.size == .Slice)
7883 return ip.get(gpa, .{ .slice = .{8726 return ip.get(gpa, tid, .{ .slice = .{
7884 .ty = new_ty,8727 .ty = new_ty,
7885 .ptr = try ip.getCoerced(gpa, slice.ptr, ip.slicePtrType(new_ty)),8728 .ptr = try ip.getCoerced(gpa, tid, slice.ptr, ip.slicePtrType(new_ty)),
7886 .len = slice.len,8729 .len = slice.len,
7887 } })8730 } })
7888 else if (ip.isIntegerType(new_ty))8731 else if (ip.isIntegerType(new_ty))
7889 return ip.getCoerced(gpa, slice.ptr, new_ty),8732 return ip.getCoerced(gpa, tid, slice.ptr, new_ty),
7890 .ptr => |ptr| if (ip.isPointerType(new_ty) and ip.indexToKey(new_ty).ptr_type.flags.size != .Slice)8733 .ptr => |ptr| if (ip.isPointerType(new_ty) and ip.indexToKey(new_ty).ptr_type.flags.size != .Slice)
7891 return ip.get(gpa, .{ .ptr = .{8734 return ip.get(gpa, tid, .{ .ptr = .{
7892 .ty = new_ty,8735 .ty = new_ty,
7893 .base_addr = ptr.base_addr,8736 .base_addr = ptr.base_addr,
7894 .byte_offset = ptr.byte_offset,8737 .byte_offset = ptr.byte_offset,
7895 } })8738 } })
7896 else if (ip.isIntegerType(new_ty))8739 else if (ip.isIntegerType(new_ty))
7897 switch (ptr.base_addr) {8740 switch (ptr.base_addr) {
7898 .int => return ip.get(gpa, .{ .int = .{8741 .int => return ip.get(gpa, tid, .{ .int = .{
7899 .ty = .usize_type,8742 .ty = .usize_type,
7900 .storage = .{ .u64 = @intCast(ptr.byte_offset) },8743 .storage = .{ .u64 = @intCast(ptr.byte_offset) },
7901 } }),8744 } }),
...@@ -7904,44 +8747,44 @@ pub fn getCoerced(ip: *InternPool, gpa: Allocator, val: Index, new_ty: Index) Al...@@ -7904,44 +8747,44 @@ pub fn getCoerced(ip: *InternPool, gpa: Allocator, val: Index, new_ty: Index) Al
7904 .opt => |opt| switch (ip.indexToKey(new_ty)) {8747 .opt => |opt| switch (ip.indexToKey(new_ty)) {
7905 .ptr_type => |ptr_type| return switch (opt.val) {8748 .ptr_type => |ptr_type| return switch (opt.val) {
7906 .none => switch (ptr_type.flags.size) {8749 .none => switch (ptr_type.flags.size) {
7907 .One, .Many, .C => try ip.get(gpa, .{ .ptr = .{8750 .One, .Many, .C => try ip.get(gpa, tid, .{ .ptr = .{
7908 .ty = new_ty,8751 .ty = new_ty,
7909 .base_addr = .int,8752 .base_addr = .int,
7910 .byte_offset = 0,8753 .byte_offset = 0,
7911 } }),8754 } }),
7912 .Slice => try ip.get(gpa, .{ .slice = .{8755 .Slice => try ip.get(gpa, tid, .{ .slice = .{
7913 .ty = new_ty,8756 .ty = new_ty,
7914 .ptr = try ip.get(gpa, .{ .ptr = .{8757 .ptr = try ip.get(gpa, tid, .{ .ptr = .{
7915 .ty = ip.slicePtrType(new_ty),8758 .ty = ip.slicePtrType(new_ty),
7916 .base_addr = .int,8759 .base_addr = .int,
7917 .byte_offset = 0,8760 .byte_offset = 0,
7918 } }),8761 } }),
7919 .len = try ip.get(gpa, .{ .undef = .usize_type }),8762 .len = try ip.get(gpa, tid, .{ .undef = .usize_type }),
7920 } }),8763 } }),
7921 },8764 },
7922 else => |payload| try ip.getCoerced(gpa, payload, new_ty),8765 else => |payload| try ip.getCoerced(gpa, tid, payload, new_ty),
7923 },8766 },
7924 .opt_type => |child_type| return try ip.get(gpa, .{ .opt = .{8767 .opt_type => |child_type| return try ip.get(gpa, tid, .{ .opt = .{
7925 .ty = new_ty,8768 .ty = new_ty,
7926 .val = switch (opt.val) {8769 .val = switch (opt.val) {
7927 .none => .none,8770 .none => .none,
7928 else => try ip.getCoerced(gpa, opt.val, child_type),8771 else => try ip.getCoerced(gpa, tid, opt.val, child_type),
7929 },8772 },
7930 } }),8773 } }),
7931 else => {},8774 else => {},
7932 },8775 },
7933 .err => |err| if (ip.isErrorSetType(new_ty))8776 .err => |err| if (ip.isErrorSetType(new_ty))
7934 return ip.get(gpa, .{ .err = .{8777 return ip.get(gpa, tid, .{ .err = .{
7935 .ty = new_ty,8778 .ty = new_ty,
7936 .name = err.name,8779 .name = err.name,
7937 } })8780 } })
7938 else if (ip.isErrorUnionType(new_ty))8781 else if (ip.isErrorUnionType(new_ty))
7939 return ip.get(gpa, .{ .error_union = .{8782 return ip.get(gpa, tid, .{ .error_union = .{
7940 .ty = new_ty,8783 .ty = new_ty,
7941 .val = .{ .err_name = err.name },8784 .val = .{ .err_name = err.name },
7942 } }),8785 } }),
7943 .error_union => |error_union| if (ip.isErrorUnionType(new_ty))8786 .error_union => |error_union| if (ip.isErrorUnionType(new_ty))
7944 return ip.get(gpa, .{ .error_union = .{8787 return ip.get(gpa, tid, .{ .error_union = .{
7945 .ty = new_ty,8788 .ty = new_ty,
7946 .val = error_union.val,8789 .val = error_union.val,
7947 } }),8790 } }),
...@@ -7960,20 +8803,20 @@ pub fn getCoerced(ip: *InternPool, gpa: Allocator, val: Index, new_ty: Index) Al...@@ -7960,20 +8803,20 @@ pub fn getCoerced(ip: *InternPool, gpa: Allocator, val: Index, new_ty: Index) Al
7960 };8803 };
7961 if (old_ty_child != new_ty_child) break :direct;8804 if (old_ty_child != new_ty_child) break :direct;
7962 switch (aggregate.storage) {8805 switch (aggregate.storage) {
7963 .bytes => |bytes| return ip.get(gpa, .{ .aggregate = .{8806 .bytes => |bytes| return ip.get(gpa, tid, .{ .aggregate = .{
7964 .ty = new_ty,8807 .ty = new_ty,
7965 .storage = .{ .bytes = bytes },8808 .storage = .{ .bytes = bytes },
7966 } }),8809 } }),
7967 .elems => |elems| {8810 .elems => |elems| {
7968 const elems_copy = try gpa.dupe(Index, elems[0..new_len]);8811 const elems_copy = try gpa.dupe(Index, elems[0..new_len]);
7969 defer gpa.free(elems_copy);8812 defer gpa.free(elems_copy);
7970 return ip.get(gpa, .{ .aggregate = .{8813 return ip.get(gpa, tid, .{ .aggregate = .{
7971 .ty = new_ty,8814 .ty = new_ty,
7972 .storage = .{ .elems = elems_copy },8815 .storage = .{ .elems = elems_copy },
7973 } });8816 } });
7974 },8817 },
7975 .repeated_elem => |elem| {8818 .repeated_elem => |elem| {
7976 return ip.get(gpa, .{ .aggregate = .{8819 return ip.get(gpa, tid, .{ .aggregate = .{
7977 .ty = new_ty,8820 .ty = new_ty,
7978 .storage = .{ .repeated_elem = elem },8821 .storage = .{ .repeated_elem = elem },
7979 } });8822 } });
...@@ -7991,7 +8834,7 @@ pub fn getCoerced(ip: *InternPool, gpa: Allocator, val: Index, new_ty: Index) Al...@@ -7991,7 +8834,7 @@ pub fn getCoerced(ip: *InternPool, gpa: Allocator, val: Index, new_ty: Index) Al
7991 // We have to intern each value here, so unfortunately we can't easily avoid8834 // We have to intern each value here, so unfortunately we can't easily avoid
7992 // the repeated indexToKey calls.8835 // the repeated indexToKey calls.
7993 for (agg_elems, 0..) |*elem, index| {8836 for (agg_elems, 0..) |*elem, index| {
7994 elem.* = try ip.get(gpa, .{ .int = .{8837 elem.* = try ip.get(gpa, tid, .{ .int = .{
7995 .ty = .u8_type,8838 .ty = .u8_type,
7996 .storage = .{ .u64 = bytes.at(index, ip) },8839 .storage = .{ .u64 = bytes.at(index, ip) },
7997 } });8840 } });
...@@ -8008,27 +8851,27 @@ pub fn getCoerced(ip: *InternPool, gpa: Allocator, val: Index, new_ty: Index) Al...@@ -8008,27 +8851,27 @@ pub fn getCoerced(ip: *InternPool, gpa: Allocator, val: Index, new_ty: Index) Al
8008 .struct_type => ip.loadStructType(new_ty).field_types.get(ip)[i],8851 .struct_type => ip.loadStructType(new_ty).field_types.get(ip)[i],
8009 else => unreachable,8852 else => unreachable,
8010 };8853 };
8011 elem.* = try ip.getCoerced(gpa, elem.*, new_elem_ty);8854 elem.* = try ip.getCoerced(gpa, tid, elem.*, new_elem_ty);
8012 }8855 }
8013 return ip.get(gpa, .{ .aggregate = .{ .ty = new_ty, .storage = .{ .elems = agg_elems } } });8856 return ip.get(gpa, tid, .{ .aggregate = .{ .ty = new_ty, .storage = .{ .elems = agg_elems } } });
8014 },8857 },
8015 else => {},8858 else => {},
8016 }8859 }
80178860
8018 switch (ip.indexToKey(new_ty)) {8861 switch (ip.indexToKey(new_ty)) {
8019 .opt_type => |child_type| switch (val) {8862 .opt_type => |child_type| switch (val) {
8020 .null_value => return ip.get(gpa, .{ .opt = .{8863 .null_value => return ip.get(gpa, tid, .{ .opt = .{
8021 .ty = new_ty,8864 .ty = new_ty,
8022 .val = .none,8865 .val = .none,
8023 } }),8866 } }),
8024 else => return ip.get(gpa, .{ .opt = .{8867 else => return ip.get(gpa, tid, .{ .opt = .{
8025 .ty = new_ty,8868 .ty = new_ty,
8026 .val = try ip.getCoerced(gpa, val, child_type),8869 .val = try ip.getCoerced(gpa, tid, val, child_type),
8027 } }),8870 } }),
8028 },8871 },
8029 .error_union_type => |error_union_type| return ip.get(gpa, .{ .error_union = .{8872 .error_union_type => |error_union_type| return ip.get(gpa, tid, .{ .error_union = .{
8030 .ty = new_ty,8873 .ty = new_ty,
8031 .val = .{ .payload = try ip.getCoerced(gpa, val, error_union_type.payload_type) },8874 .val = .{ .payload = try ip.getCoerced(gpa, tid, val, error_union_type.payload_type) },
8032 } }),8875 } }),
8033 else => {},8876 else => {},
8034 }8877 }
...@@ -8042,87 +8885,87 @@ pub fn getCoerced(ip: *InternPool, gpa: Allocator, val: Index, new_ty: Index) Al...@@ -8042,87 +8885,87 @@ pub fn getCoerced(ip: *InternPool, gpa: Allocator, val: Index, new_ty: Index) Al
8042 unreachable;8885 unreachable;
8043}8886}
80448887
8045fn getCoercedFuncDecl(ip: *InternPool, gpa: Allocator, val: Index, new_ty: Index) Allocator.Error!Index {8888fn getCoercedFuncDecl(
8046 const datas = ip.items.items(.data);8889 ip: *InternPool,
8047 const extra_index = datas[@intFromEnum(val)];8890 gpa: Allocator,
8048 const prev_ty: Index = @enumFromInt(8891 tid: Zcu.PerThread.Id,
8049 ip.extra.items[extra_index + std.meta.fieldIndex(Tag.FuncDecl, "ty").?],8892 val: Index,
8050 );8893 new_ty: Index,
8894) Allocator.Error!Index {
8895 const unwrapped_val = val.unwrap(ip);
8896 const prev_ty: Index = @enumFromInt(unwrapped_val.getExtra(ip).view().items(.@"0")[
8897 unwrapped_val.getData(ip) + std.meta.fieldIndex(Tag.FuncDecl, "ty").?
8898 ]);
8051 if (new_ty == prev_ty) return val;8899 if (new_ty == prev_ty) return val;
8052 return getCoercedFunc(ip, gpa, val, new_ty);8900 return getCoercedFunc(ip, gpa, tid, val, new_ty);
8053}8901}
80548902
8055fn getCoercedFuncInstance(ip: *InternPool, gpa: Allocator, val: Index, new_ty: Index) Allocator.Error!Index {8903fn getCoercedFuncInstance(
8056 const datas = ip.items.items(.data);8904 ip: *InternPool,
8057 const extra_index = datas[@intFromEnum(val)];8905 gpa: Allocator,
8058 const prev_ty: Index = @enumFromInt(8906 tid: Zcu.PerThread.Id,
8059 ip.extra.items[extra_index + std.meta.fieldIndex(Tag.FuncInstance, "ty").?],8907 val: Index,
8060 );8908 new_ty: Index,
8909) Allocator.Error!Index {
8910 const unwrapped_val = val.unwrap(ip);
8911 const prev_ty: Index = @enumFromInt(unwrapped_val.getExtra(ip).view().items(.@"0")[
8912 unwrapped_val.getData(ip) + std.meta.fieldIndex(Tag.FuncInstance, "ty").?
8913 ]);
8061 if (new_ty == prev_ty) return val;8914 if (new_ty == prev_ty) return val;
8062 return getCoercedFunc(ip, gpa, val, new_ty);8915 return getCoercedFunc(ip, gpa, tid, val, new_ty);
8063}8916}
80648917
8065fn getCoercedFunc(ip: *InternPool, gpa: Allocator, func: Index, ty: Index) Allocator.Error!Index {8918fn getCoercedFunc(
8066 const prev_extra_len = ip.extra.items.len;8919 ip: *InternPool,
8067 try ip.extra.ensureUnusedCapacity(gpa, @typeInfo(Tag.FuncCoerced).Struct.fields.len);8920 gpa: Allocator,
8068 try ip.items.ensureUnusedCapacity(gpa, 1);8921 tid: Zcu.PerThread.Id,
8069 try ip.map.ensureUnusedCapacity(gpa, 1);8922 func: Index,
8923 ty: Index,
8924) Allocator.Error!Index {
8925 const local = ip.getLocal(tid);
8926 const items = local.getMutableItems(gpa);
8927 try items.ensureUnusedCapacity(1);
8928 const extra = local.getMutableExtra(gpa);
80708929
8071 const extra_index = ip.addExtraAssumeCapacity(Tag.FuncCoerced{8930 const prev_extra_len = extra.mutate.len;
8931 try extra.ensureUnusedCapacity(@typeInfo(Tag.FuncCoerced).Struct.fields.len);
8932
8933 const extra_index = addExtraAssumeCapacity(extra, Tag.FuncCoerced{
8072 .ty = ty,8934 .ty = ty,
8073 .func = func,8935 .func = func,
8074 });8936 });
8937 errdefer extra.mutate.len = prev_extra_len;
80758938
8076 const adapter: KeyAdapter = .{ .intern_pool = ip };8939 var gop = try ip.getOrPutKey(gpa, tid, .{
8077 const gop = ip.map.getOrPutAssumeCapacityAdapted(Key{8940 .func = ip.extraFuncCoerced(extra.list.*, extra_index),
8078 .func = extraFuncCoerced(ip, extra_index),8941 });
8079 }, adapter);8942 defer gop.deinit();
80808943 if (gop == .existing) {
8081 if (gop.found_existing) {8944 extra.mutate.len = prev_extra_len;
8082 ip.extra.items.len = prev_extra_len;8945 return gop.existing;
8083 return @enumFromInt(gop.index);
8084 }8946 }
80858947
8086 ip.items.appendAssumeCapacity(.{8948 items.appendAssumeCapacity(.{
8087 .tag = .func_coerced,8949 .tag = .func_coerced,
8088 .data = extra_index,8950 .data = extra_index,
8089 });8951 });
8090 return @enumFromInt(ip.items.len - 1);8952 return gop.put();
8091}8953}
80928954
8093/// Asserts `val` has an integer type.8955/// Asserts `val` has an integer type.
8094/// Assumes `new_ty` is an integer type.8956/// Assumes `new_ty` is an integer type.
8095pub fn getCoercedInts(ip: *InternPool, gpa: Allocator, int: Key.Int, new_ty: Index) Allocator.Error!Index {8957pub fn getCoercedInts(ip: *InternPool, gpa: Allocator, tid: Zcu.PerThread.Id, int: Key.Int, new_ty: Index) Allocator.Error!Index {
8096 // The key cannot be passed directly to `get`, otherwise in the case of8958 return ip.get(gpa, tid, .{ .int = .{
8097 // big_int storage, the limbs would be invalidated before they are read.
8098 // Here we pre-reserve the limbs to ensure that the logic in `addInt` will
8099 // not use an invalidated limbs pointer.
8100 const new_storage: Key.Int.Storage = switch (int.storage) {
8101 .u64, .i64, .lazy_align, .lazy_size => int.storage,
8102 .big_int => |big_int| storage: {
8103 const positive = big_int.positive;
8104 const limbs = ip.limbsSliceToIndex(big_int.limbs);
8105 // This line invalidates the limbs slice, but the indexes computed in the
8106 // previous line are still correct.
8107 try reserveLimbs(ip, gpa, @typeInfo(Int).Struct.fields.len + big_int.limbs.len);
8108 break :storage .{ .big_int = .{
8109 .limbs = ip.limbsIndexToSlice(limbs),
8110 .positive = positive,
8111 } };
8112 },
8113 };
8114 return ip.get(gpa, .{ .int = .{
8115 .ty = new_ty,8959 .ty = new_ty,
8116 .storage = new_storage,8960 .storage = int.storage,
8117 } });8961 } });
8118}8962}
81198963
8120pub fn indexToFuncType(ip: *const InternPool, val: Index) ?Key.FuncType {8964pub fn indexToFuncType(ip: *const InternPool, val: Index) ?Key.FuncType {
8121 assert(val != .none);8965 const unwrapped_val = val.unwrap(ip);
8122 const tags = ip.items.items(.tag);8966 const item = unwrapped_val.getItem(ip);
8123 const datas = ip.items.items(.data);8967 switch (item.tag) {
8124 switch (tags[@intFromEnum(val)]) {8968 .type_function => return extraFuncType(unwrapped_val.tid, unwrapped_val.getExtra(ip), item.data),
8125 .type_function => return extraFuncType(ip, datas[@intFromEnum(val)]),
8126 else => return null,8969 else => return null,
8127 }8970 }
8128}8971}
...@@ -8143,7 +8986,7 @@ pub fn isIntegerType(ip: *const InternPool, ty: Index) bool {...@@ -8143,7 +8986,7 @@ pub fn isIntegerType(ip: *const InternPool, ty: Index) bool {
8143 .c_ulonglong_type,8986 .c_ulonglong_type,
8144 .comptime_int_type,8987 .comptime_int_type,
8145 => true,8988 => true,
8146 else => switch (ip.items.items(.tag)[@intFromEnum(ty)]) {8989 else => switch (ty.unwrap(ip).getTag(ip)) {
8147 .type_int_signed,8990 .type_int_signed,
8148 .type_int_unsigned,8991 .type_int_unsigned,
8149 => true,8992 => true,
...@@ -8219,9 +9062,11 @@ pub fn errorUnionPayload(ip: *const InternPool, ty: Index) Index {...@@ -8219,9 +9062,11 @@ pub fn errorUnionPayload(ip: *const InternPool, ty: Index) Index {
82199062
8220/// The is only legal because the initializer is not part of the hash.9063/// The is only legal because the initializer is not part of the hash.
8221pub fn mutateVarInit(ip: *InternPool, index: Index, init_index: Index) void {9064pub fn mutateVarInit(ip: *InternPool, index: Index, init_index: Index) void {
8222 const item = ip.items.get(@intFromEnum(index));9065 const unwrapped_index = index.unwrap(ip);
9066 const extra_list = unwrapped_index.getExtra(ip);
9067 const item = unwrapped_index.getItem(ip);
8223 assert(item.tag == .variable);9068 assert(item.tag == .variable);
8224 ip.extra.items[item.data + std.meta.fieldIndex(Tag.Variable, "init").?] = @intFromEnum(init_index);9069 @atomicStore(u32, &extra_list.view().items(.@"0")[item.data + std.meta.fieldIndex(Tag.Variable, "init").?], @intFromEnum(init_index), .release);
8225}9070}
82269071
8227pub fn dump(ip: *const InternPool) void {9072pub fn dump(ip: *const InternPool) void {
...@@ -8230,9 +9075,17 @@ pub fn dump(ip: *const InternPool) void {...@@ -8230,9 +9075,17 @@ pub fn dump(ip: *const InternPool) void {
8230}9075}
82319076
8232fn dumpStatsFallible(ip: *const InternPool, arena: Allocator) anyerror!void {9077fn dumpStatsFallible(ip: *const InternPool, arena: Allocator) anyerror!void {
8233 const items_size = (1 + 4) * ip.items.len;9078 var items_len: usize = 0;
8234 const extra_size = 4 * ip.extra.items.len;9079 var extra_len: usize = 0;
8235 const limbs_size = 8 * ip.limbs.items.len;9080 var limbs_len: usize = 0;
9081 for (ip.locals) |*local| {
9082 items_len += local.mutate.items.len;
9083 extra_len += local.mutate.extra.len;
9084 limbs_len += local.mutate.limbs.len;
9085 }
9086 const items_size = (1 + 4) * items_len;
9087 const extra_size = 4 * extra_len;
9088 const limbs_size = 8 * limbs_len;
8236 const decls_size = ip.allocated_decls.len * @sizeOf(Module.Decl);9089 const decls_size = ip.allocated_decls.len * @sizeOf(Module.Decl);
82379090
8238 // TODO: map overhead size is not taken into account9091 // TODO: map overhead size is not taken into account
...@@ -8247,221 +9100,234 @@ fn dumpStatsFallible(ip: *const InternPool, arena: Allocator) anyerror!void {...@@ -8247,221 +9100,234 @@ fn dumpStatsFallible(ip: *const InternPool, arena: Allocator) anyerror!void {
8247 \\9100 \\
8248 , .{9101 , .{
8249 total_size,9102 total_size,
8250 ip.items.len,9103 items_len,
8251 items_size,9104 items_size,
8252 ip.extra.items.len,9105 extra_len,
8253 extra_size,9106 extra_size,
8254 ip.limbs.items.len,9107 limbs_len,
8255 limbs_size,9108 limbs_size,
8256 ip.allocated_decls.len,9109 ip.allocated_decls.len,
8257 decls_size,9110 decls_size,
8258 });9111 });
82599112
8260 const tags = ip.items.items(.tag);
8261 const datas = ip.items.items(.data);
8262 const TagStats = struct {9113 const TagStats = struct {
8263 count: usize = 0,9114 count: usize = 0,
8264 bytes: usize = 0,9115 bytes: usize = 0,
8265 };9116 };
8266 var counts = std.AutoArrayHashMap(Tag, TagStats).init(arena);9117 var counts = std.AutoArrayHashMap(Tag, TagStats).init(arena);
8267 for (tags, datas) |tag, data| {9118 for (ip.locals) |*local| {
8268 const gop = try counts.getOrPut(tag);9119 const items = local.shared.items.view().slice();
8269 if (!gop.found_existing) gop.value_ptr.* = .{};9120 const extra_list = local.shared.extra;
8270 gop.value_ptr.count += 1;9121 const extra_items = extra_list.view().items(.@"0");
8271 gop.value_ptr.bytes += 1 + 4 + @as(usize, switch (tag) {9122 for (
8272 // Note that in this case, we have technically leaked some extra data9123 items.items(.tag)[0..local.mutate.items.len],
8273 // bytes which we do not account for here.9124 items.items(.data)[0..local.mutate.items.len],
8274 .removed => 0,9125 ) |tag, data| {
82759126 const gop = try counts.getOrPut(tag);
8276 .type_int_signed => 0,9127 if (!gop.found_existing) gop.value_ptr.* = .{};
8277 .type_int_unsigned => 0,9128 gop.value_ptr.count += 1;
8278 .type_array_small => @sizeOf(Vector),9129 gop.value_ptr.bytes += 1 + 4 + @as(usize, switch (tag) {
8279 .type_array_big => @sizeOf(Array),9130 // Note that in this case, we have technically leaked some extra data
8280 .type_vector => @sizeOf(Vector),9131 // bytes which we do not account for here.
8281 .type_pointer => @sizeOf(Tag.TypePointer),9132 .removed => 0,
8282 .type_slice => 0,9133
8283 .type_optional => 0,9134 .type_int_signed => 0,
8284 .type_anyframe => 0,9135 .type_int_unsigned => 0,
8285 .type_error_union => @sizeOf(Key.ErrorUnionType),9136 .type_array_small => @sizeOf(Vector),
8286 .type_anyerror_union => 0,9137 .type_array_big => @sizeOf(Array),
8287 .type_error_set => b: {9138 .type_vector => @sizeOf(Vector),
8288 const info = ip.extraData(Tag.ErrorSet, data);9139 .type_pointer => @sizeOf(Tag.TypePointer),
8289 break :b @sizeOf(Tag.ErrorSet) + (@sizeOf(u32) * info.names_len);9140 .type_slice => 0,
8290 },9141 .type_optional => 0,
8291 .type_inferred_error_set => 0,9142 .type_anyframe => 0,
8292 .type_enum_explicit, .type_enum_nonexhaustive => b: {9143 .type_error_union => @sizeOf(Key.ErrorUnionType),
8293 const info = ip.extraData(EnumExplicit, data);9144 .type_anyerror_union => 0,
8294 var ints = @typeInfo(EnumExplicit).Struct.fields.len + info.captures_len + info.fields_len;9145 .type_error_set => b: {
8295 if (info.values_map != .none) ints += info.fields_len;9146 const info = extraData(extra_list, Tag.ErrorSet, data);
8296 break :b @sizeOf(u32) * ints;9147 break :b @sizeOf(Tag.ErrorSet) + (@sizeOf(u32) * info.names_len);
8297 },9148 },
8298 .type_enum_auto => b: {9149 .type_inferred_error_set => 0,
8299 const info = ip.extraData(EnumAuto, data);9150 .type_enum_explicit, .type_enum_nonexhaustive => b: {
8300 const ints = @typeInfo(EnumAuto).Struct.fields.len + info.captures_len + info.fields_len;9151 const info = extraData(extra_list, EnumExplicit, data);
8301 break :b @sizeOf(u32) * ints;9152 var ints = @typeInfo(EnumExplicit).Struct.fields.len;
8302 },9153 if (info.zir_index == .none) ints += 1;
8303 .type_opaque => b: {9154 ints += if (info.captures_len != std.math.maxInt(u32))
8304 const info = ip.extraData(Tag.TypeOpaque, data);9155 info.captures_len
8305 const ints = @typeInfo(Tag.TypeOpaque).Struct.fields.len + info.captures_len;9156 else
8306 break :b @sizeOf(u32) * ints;9157 @typeInfo(PackedU64).Struct.fields.len;
8307 },9158 ints += info.fields_len;
8308 .type_struct => b: {9159 if (info.values_map != .none) ints += info.fields_len;
8309 if (data == 0) break :b 0;9160 break :b @sizeOf(u32) * ints;
8310 const extra = ip.extraDataTrail(Tag.TypeStruct, data);9161 },
8311 const info = extra.data;9162 .type_enum_auto => b: {
8312 var ints: usize = @typeInfo(Tag.TypeStruct).Struct.fields.len;9163 const info = extraData(extra_list, EnumAuto, data);
8313 if (info.flags.any_captures) {9164 const ints = @typeInfo(EnumAuto).Struct.fields.len + info.captures_len + info.fields_len;
8314 const captures_len = ip.extra.items[extra.end];9165 break :b @sizeOf(u32) * ints;
8315 ints += 1 + captures_len;9166 },
8316 }9167 .type_opaque => b: {
8317 ints += info.fields_len; // types9168 const info = extraData(extra_list, Tag.TypeOpaque, data);
8318 if (!info.flags.is_tuple) {9169 const ints = @typeInfo(Tag.TypeOpaque).Struct.fields.len + info.captures_len;
8319 ints += 1; // names_map9170 break :b @sizeOf(u32) * ints;
8320 ints += info.fields_len; // names9171 },
8321 }9172 .type_struct => b: {
8322 if (info.flags.any_default_inits)9173 if (data == 0) break :b 0;
8323 ints += info.fields_len; // inits9174 const extra = extraDataTrail(extra_list, Tag.TypeStruct, data);
8324 ints += @intFromBool(info.flags.has_namespace); // namespace9175 const info = extra.data;
8325 if (info.flags.any_aligned_fields)9176 var ints: usize = @typeInfo(Tag.TypeStruct).Struct.fields.len;
8326 ints += (info.fields_len + 3) / 4; // aligns9177 if (info.flags.any_captures) {
8327 if (info.flags.any_comptime_fields)9178 const captures_len = extra_items[extra.end];
8328 ints += (info.fields_len + 31) / 32; // comptime bits9179 ints += 1 + captures_len;
8329 if (!info.flags.is_extern)9180 }
8330 ints += info.fields_len; // runtime order9181 ints += info.fields_len; // types
8331 ints += info.fields_len; // offsets9182 if (!info.flags.is_tuple) {
8332 break :b @sizeOf(u32) * ints;9183 ints += 1; // names_map
8333 },9184 ints += info.fields_len; // names
8334 .type_struct_anon => b: {9185 }
8335 const info = ip.extraData(TypeStructAnon, data);9186 if (info.flags.any_default_inits)
8336 break :b @sizeOf(TypeStructAnon) + (@sizeOf(u32) * 3 * info.fields_len);9187 ints += info.fields_len; // inits
8337 },9188 ints += @intFromBool(info.flags.has_namespace); // namespace
8338 .type_struct_packed => b: {9189 if (info.flags.any_aligned_fields)
8339 const extra = ip.extraDataTrail(Tag.TypeStructPacked, data);9190 ints += (info.fields_len + 3) / 4; // aligns
8340 const captures_len = if (extra.data.flags.any_captures)9191 if (info.flags.any_comptime_fields)
8341 ip.extra.items[extra.end]9192 ints += (info.fields_len + 31) / 32; // comptime bits
8342 else9193 if (!info.flags.is_extern)
8343 0;9194 ints += info.fields_len; // runtime order
8344 break :b @sizeOf(u32) * (@typeInfo(Tag.TypeStructPacked).Struct.fields.len +9195 ints += info.fields_len; // offsets
8345 @intFromBool(extra.data.flags.any_captures) + captures_len +9196 break :b @sizeOf(u32) * ints;
8346 extra.data.fields_len * 2);9197 },
8347 },9198 .type_struct_anon => b: {
8348 .type_struct_packed_inits => b: {9199 const info = extraData(extra_list, TypeStructAnon, data);
8349 const extra = ip.extraDataTrail(Tag.TypeStructPacked, data);9200 break :b @sizeOf(TypeStructAnon) + (@sizeOf(u32) * 3 * info.fields_len);
8350 const captures_len = if (extra.data.flags.any_captures)9201 },
8351 ip.extra.items[extra.end]9202 .type_struct_packed => b: {
8352 else9203 const extra = extraDataTrail(extra_list, Tag.TypeStructPacked, data);
8353 0;9204 const captures_len = if (extra.data.flags.any_captures)
8354 break :b @sizeOf(u32) * (@typeInfo(Tag.TypeStructPacked).Struct.fields.len +9205 extra_items[extra.end]
8355 @intFromBool(extra.data.flags.any_captures) + captures_len +9206 else
8356 extra.data.fields_len * 3);9207 0;
8357 },9208 break :b @sizeOf(u32) * (@typeInfo(Tag.TypeStructPacked).Struct.fields.len +
8358 .type_tuple_anon => b: {9209 @intFromBool(extra.data.flags.any_captures) + captures_len +
8359 const info = ip.extraData(TypeStructAnon, data);9210 extra.data.fields_len * 2);
8360 break :b @sizeOf(TypeStructAnon) + (@sizeOf(u32) * 2 * info.fields_len);9211 },
8361 },9212 .type_struct_packed_inits => b: {
83629213 const extra = extraDataTrail(extra_list, Tag.TypeStructPacked, data);
8363 .type_union => b: {9214 const captures_len = if (extra.data.flags.any_captures)
8364 const extra = ip.extraDataTrail(Tag.TypeUnion, data);9215 extra_items[extra.end]
8365 const captures_len = if (extra.data.flags.any_captures)9216 else
8366 ip.extra.items[extra.end]9217 0;
8367 else9218 break :b @sizeOf(u32) * (@typeInfo(Tag.TypeStructPacked).Struct.fields.len +
8368 0;9219 @intFromBool(extra.data.flags.any_captures) + captures_len +
8369 const per_field = @sizeOf(u32); // field type9220 extra.data.fields_len * 3);
8370 // 1 byte per field for alignment, rounded up to the nearest 4 bytes9221 },
8371 const alignments = if (extra.data.flags.any_aligned_fields)9222 .type_tuple_anon => b: {
8372 ((extra.data.fields_len + 3) / 4) * 49223 const info = extraData(extra_list, TypeStructAnon, data);
8373 else9224 break :b @sizeOf(TypeStructAnon) + (@sizeOf(u32) * 2 * info.fields_len);
8374 0;9225 },
8375 break :b @sizeOf(Tag.TypeUnion) +
8376 4 * (@intFromBool(extra.data.flags.any_captures) + captures_len) +
8377 (extra.data.fields_len * per_field) + alignments;
8378 },
83799226
8380 .type_function => b: {9227 .type_union => b: {
8381 const info = ip.extraData(Tag.TypeFunction, data);9228 const extra = extraDataTrail(extra_list, Tag.TypeUnion, data);
8382 break :b @sizeOf(Tag.TypeFunction) +9229 const captures_len = if (extra.data.flags.any_captures)
8383 (@sizeOf(Index) * info.params_len) +9230 extra_items[extra.end]
8384 (@as(u32, 4) * @intFromBool(info.flags.has_comptime_bits)) +9231 else
8385 (@as(u32, 4) * @intFromBool(info.flags.has_noalias_bits));9232 0;
8386 },9233 const per_field = @sizeOf(u32); // field type
9234 // 1 byte per field for alignment, rounded up to the nearest 4 bytes
9235 const alignments = if (extra.data.flags.any_aligned_fields)
9236 ((extra.data.fields_len + 3) / 4) * 4
9237 else
9238 0;
9239 break :b @sizeOf(Tag.TypeUnion) +
9240 4 * (@intFromBool(extra.data.flags.any_captures) + captures_len) +
9241 (extra.data.fields_len * per_field) + alignments;
9242 },
83879243
8388 .undef => 0,9244 .type_function => b: {
8389 .simple_type => 0,9245 const info = extraData(extra_list, Tag.TypeFunction, data);
8390 .simple_value => 0,9246 break :b @sizeOf(Tag.TypeFunction) +
8391 .ptr_decl => @sizeOf(PtrDecl),9247 (@sizeOf(Index) * info.params_len) +
8392 .ptr_comptime_alloc => @sizeOf(PtrComptimeAlloc),9248 (@as(u32, 4) * @intFromBool(info.flags.has_comptime_bits)) +
8393 .ptr_anon_decl => @sizeOf(PtrAnonDecl),9249 (@as(u32, 4) * @intFromBool(info.flags.has_noalias_bits));
8394 .ptr_anon_decl_aligned => @sizeOf(PtrAnonDeclAligned),9250 },
8395 .ptr_comptime_field => @sizeOf(PtrComptimeField),
8396 .ptr_int => @sizeOf(PtrInt),
8397 .ptr_eu_payload => @sizeOf(PtrBase),
8398 .ptr_opt_payload => @sizeOf(PtrBase),
8399 .ptr_elem => @sizeOf(PtrBaseIndex),
8400 .ptr_field => @sizeOf(PtrBaseIndex),
8401 .ptr_slice => @sizeOf(PtrSlice),
8402 .opt_null => 0,
8403 .opt_payload => @sizeOf(Tag.TypeValue),
8404 .int_u8 => 0,
8405 .int_u16 => 0,
8406 .int_u32 => 0,
8407 .int_i32 => 0,
8408 .int_usize => 0,
8409 .int_comptime_int_u32 => 0,
8410 .int_comptime_int_i32 => 0,
8411 .int_small => @sizeOf(IntSmall),
84129251
8413 .int_positive,9252 .undef => 0,
8414 .int_negative,9253 .simple_type => 0,
8415 => b: {9254 .simple_value => 0,
8416 const int = ip.limbData(Int, data);9255 .ptr_decl => @sizeOf(PtrDecl),
8417 break :b @sizeOf(Int) + int.limbs_len * 8;9256 .ptr_comptime_alloc => @sizeOf(PtrComptimeAlloc),
8418 },9257 .ptr_anon_decl => @sizeOf(PtrAnonDecl),
9258 .ptr_anon_decl_aligned => @sizeOf(PtrAnonDeclAligned),
9259 .ptr_comptime_field => @sizeOf(PtrComptimeField),
9260 .ptr_int => @sizeOf(PtrInt),
9261 .ptr_eu_payload => @sizeOf(PtrBase),
9262 .ptr_opt_payload => @sizeOf(PtrBase),
9263 .ptr_elem => @sizeOf(PtrBaseIndex),
9264 .ptr_field => @sizeOf(PtrBaseIndex),
9265 .ptr_slice => @sizeOf(PtrSlice),
9266 .opt_null => 0,
9267 .opt_payload => @sizeOf(Tag.TypeValue),
9268 .int_u8 => 0,
9269 .int_u16 => 0,
9270 .int_u32 => 0,
9271 .int_i32 => 0,
9272 .int_usize => 0,
9273 .int_comptime_int_u32 => 0,
9274 .int_comptime_int_i32 => 0,
9275 .int_small => @sizeOf(IntSmall),
9276
9277 .int_positive,
9278 .int_negative,
9279 => b: {
9280 const limbs_list = local.shared.getLimbs();
9281 const int: Int = @bitCast(limbs_list.view().items(.@"0")[data..][0..Int.limbs_items_len].*);
9282 break :b @sizeOf(Int) + int.limbs_len * @sizeOf(Limb);
9283 },
84199284
8420 .int_lazy_align, .int_lazy_size => @sizeOf(IntLazy),9285 .int_lazy_align, .int_lazy_size => @sizeOf(IntLazy),
84219286
8422 .error_set_error, .error_union_error => @sizeOf(Key.Error),9287 .error_set_error, .error_union_error => @sizeOf(Key.Error),
8423 .error_union_payload => @sizeOf(Tag.TypeValue),9288 .error_union_payload => @sizeOf(Tag.TypeValue),
8424 .enum_literal => 0,9289 .enum_literal => 0,
8425 .enum_tag => @sizeOf(Tag.EnumTag),9290 .enum_tag => @sizeOf(Tag.EnumTag),
84269291
8427 .bytes => b: {9292 .bytes => b: {
8428 const info = ip.extraData(Bytes, data);9293 const info = extraData(extra_list, Bytes, data);
8429 const len: usize = @intCast(ip.aggregateTypeLenIncludingSentinel(info.ty));9294 const len: usize = @intCast(ip.aggregateTypeLenIncludingSentinel(info.ty));
8430 break :b @sizeOf(Bytes) + len + @intFromBool(info.bytes.at(len - 1, ip) != 0);9295 break :b @sizeOf(Bytes) + len + @intFromBool(info.bytes.at(len - 1, ip) != 0);
8431 },9296 },
8432 .aggregate => b: {9297 .aggregate => b: {
8433 const info = ip.extraData(Tag.Aggregate, data);9298 const info = extraData(extra_list, Tag.Aggregate, data);
8434 const fields_len: u32 = @intCast(ip.aggregateTypeLenIncludingSentinel(info.ty));9299 const fields_len: u32 = @intCast(ip.aggregateTypeLenIncludingSentinel(info.ty));
8435 break :b @sizeOf(Tag.Aggregate) + (@sizeOf(Index) * fields_len);9300 break :b @sizeOf(Tag.Aggregate) + (@sizeOf(Index) * fields_len);
8436 },9301 },
8437 .repeated => @sizeOf(Repeated),9302 .repeated => @sizeOf(Repeated),
84389303
8439 .float_f16 => 0,9304 .float_f16 => 0,
8440 .float_f32 => 0,9305 .float_f32 => 0,
8441 .float_f64 => @sizeOf(Float64),9306 .float_f64 => @sizeOf(Float64),
8442 .float_f80 => @sizeOf(Float80),9307 .float_f80 => @sizeOf(Float80),
8443 .float_f128 => @sizeOf(Float128),9308 .float_f128 => @sizeOf(Float128),
8444 .float_c_longdouble_f80 => @sizeOf(Float80),9309 .float_c_longdouble_f80 => @sizeOf(Float80),
8445 .float_c_longdouble_f128 => @sizeOf(Float128),9310 .float_c_longdouble_f128 => @sizeOf(Float128),
8446 .float_comptime_float => @sizeOf(Float128),9311 .float_comptime_float => @sizeOf(Float128),
8447 .variable => @sizeOf(Tag.Variable),9312 .variable => @sizeOf(Tag.Variable),
8448 .extern_func => @sizeOf(Tag.ExternFunc),9313 .extern_func => @sizeOf(Tag.ExternFunc),
8449 .func_decl => @sizeOf(Tag.FuncDecl),9314 .func_decl => @sizeOf(Tag.FuncDecl),
8450 .func_instance => b: {9315 .func_instance => b: {
8451 const info = ip.extraData(Tag.FuncInstance, data);9316 const info = extraData(extra_list, Tag.FuncInstance, data);
8452 const ty = ip.typeOf(info.generic_owner);9317 const ty = ip.typeOf(info.generic_owner);
8453 const params_len = ip.indexToKey(ty).func_type.param_types.len;9318 const params_len = ip.indexToKey(ty).func_type.param_types.len;
8454 break :b @sizeOf(Tag.FuncInstance) + @sizeOf(Index) * params_len;9319 break :b @sizeOf(Tag.FuncInstance) + @sizeOf(Index) * params_len;
8455 },9320 },
8456 .func_coerced => @sizeOf(Tag.FuncCoerced),9321 .func_coerced => @sizeOf(Tag.FuncCoerced),
8457 .only_possible_value => 0,9322 .only_possible_value => 0,
8458 .union_value => @sizeOf(Key.Union),9323 .union_value => @sizeOf(Key.Union),
84599324
8460 .memoized_call => b: {9325 .memoized_call => b: {
8461 const info = ip.extraData(MemoizedCall, data);9326 const info = extraData(extra_list, MemoizedCall, data);
8462 break :b @sizeOf(MemoizedCall) + (@sizeOf(Index) * info.args_len);9327 break :b @sizeOf(MemoizedCall) + (@sizeOf(Index) * info.args_len);
8463 },9328 },
8464 });9329 });
9330 }
8465 }9331 }
8466 const SortContext = struct {9332 const SortContext = struct {
8467 map: *std.AutoArrayHashMap(Tag, TagStats),9333 map: *std.AutoArrayHashMap(Tag, TagStats),
...@@ -8482,97 +9348,103 @@ fn dumpStatsFallible(ip: *const InternPool, arena: Allocator) anyerror!void {...@@ -8482,97 +9348,103 @@ fn dumpStatsFallible(ip: *const InternPool, arena: Allocator) anyerror!void {
8482}9348}
84839349
8484fn dumpAllFallible(ip: *const InternPool) anyerror!void {9350fn dumpAllFallible(ip: *const InternPool) anyerror!void {
8485 const tags = ip.items.items(.tag);
8486 const datas = ip.items.items(.data);
8487 var bw = std.io.bufferedWriter(std.io.getStdErr().writer());9351 var bw = std.io.bufferedWriter(std.io.getStdErr().writer());
8488 const w = bw.writer();9352 const w = bw.writer();
8489 for (tags, datas, 0..) |tag, data, i| {9353 for (ip.locals, 0..) |*local, tid| {
8490 try w.print("${d} = {s}(", .{ i, @tagName(tag) });9354 const items = local.shared.items.view();
8491 switch (tag) {9355 for (
8492 .removed => {},9356 items.items(.tag)[0..local.mutate.items.len],
84939357 items.items(.data)[0..local.mutate.items.len],
8494 .simple_type => try w.print("{s}", .{@tagName(@as(SimpleType, @enumFromInt(data)))}),9358 0..,
8495 .simple_value => try w.print("{s}", .{@tagName(@as(SimpleValue, @enumFromInt(data)))}),9359 ) |tag, data, index| {
84969360 const i = Index.Unwrapped.wrap(.{ .tid = @enumFromInt(tid), .index = @intCast(index) }, ip);
8497 .type_int_signed,9361 try w.print("${d} = {s}(", .{ i, @tagName(tag) });
8498 .type_int_unsigned,9362 switch (tag) {
8499 .type_array_small,9363 .removed => {},
8500 .type_array_big,9364
8501 .type_vector,9365 .simple_type => try w.print("{s}", .{@tagName(@as(SimpleType, @enumFromInt(@intFromEnum(i))))}),
8502 .type_pointer,9366 .simple_value => try w.print("{s}", .{@tagName(@as(SimpleValue, @enumFromInt(@intFromEnum(i))))}),
8503 .type_optional,9367
8504 .type_anyframe,9368 .type_int_signed,
8505 .type_error_union,9369 .type_int_unsigned,
8506 .type_anyerror_union,9370 .type_array_small,
8507 .type_error_set,9371 .type_array_big,
8508 .type_inferred_error_set,9372 .type_vector,
8509 .type_enum_explicit,9373 .type_pointer,
8510 .type_enum_nonexhaustive,9374 .type_optional,
8511 .type_enum_auto,9375 .type_anyframe,
8512 .type_opaque,9376 .type_error_union,
8513 .type_struct,9377 .type_anyerror_union,
8514 .type_struct_anon,9378 .type_error_set,
8515 .type_struct_packed,9379 .type_inferred_error_set,
8516 .type_struct_packed_inits,9380 .type_enum_explicit,
8517 .type_tuple_anon,9381 .type_enum_nonexhaustive,
8518 .type_union,9382 .type_enum_auto,
8519 .type_function,9383 .type_opaque,
8520 .undef,9384 .type_struct,
8521 .ptr_decl,9385 .type_struct_anon,
8522 .ptr_comptime_alloc,9386 .type_struct_packed,
8523 .ptr_anon_decl,9387 .type_struct_packed_inits,
8524 .ptr_anon_decl_aligned,9388 .type_tuple_anon,
8525 .ptr_comptime_field,9389 .type_union,
8526 .ptr_int,9390 .type_function,
8527 .ptr_eu_payload,9391 .undef,
8528 .ptr_opt_payload,9392 .ptr_decl,
8529 .ptr_elem,9393 .ptr_comptime_alloc,
8530 .ptr_field,9394 .ptr_anon_decl,
8531 .ptr_slice,9395 .ptr_anon_decl_aligned,
8532 .opt_payload,9396 .ptr_comptime_field,
8533 .int_u8,9397 .ptr_int,
8534 .int_u16,9398 .ptr_eu_payload,
8535 .int_u32,9399 .ptr_opt_payload,
8536 .int_i32,9400 .ptr_elem,
8537 .int_usize,9401 .ptr_field,
8538 .int_comptime_int_u32,9402 .ptr_slice,
8539 .int_comptime_int_i32,9403 .opt_payload,
8540 .int_small,9404 .int_u8,
8541 .int_positive,9405 .int_u16,
8542 .int_negative,9406 .int_u32,
8543 .int_lazy_align,9407 .int_i32,
8544 .int_lazy_size,9408 .int_usize,
8545 .error_set_error,9409 .int_comptime_int_u32,
8546 .error_union_error,9410 .int_comptime_int_i32,
8547 .error_union_payload,9411 .int_small,
8548 .enum_literal,9412 .int_positive,
8549 .enum_tag,9413 .int_negative,
8550 .bytes,9414 .int_lazy_align,
8551 .aggregate,9415 .int_lazy_size,
8552 .repeated,9416 .error_set_error,
8553 .float_f16,9417 .error_union_error,
8554 .float_f32,9418 .error_union_payload,
8555 .float_f64,9419 .enum_literal,
8556 .float_f80,9420 .enum_tag,
8557 .float_f128,9421 .bytes,
8558 .float_c_longdouble_f80,9422 .aggregate,
8559 .float_c_longdouble_f128,9423 .repeated,
8560 .float_comptime_float,9424 .float_f16,
8561 .variable,9425 .float_f32,
8562 .extern_func,9426 .float_f64,
8563 .func_decl,9427 .float_f80,
8564 .func_instance,9428 .float_f128,
8565 .func_coerced,9429 .float_c_longdouble_f80,
8566 .union_value,9430 .float_c_longdouble_f128,
8567 .memoized_call,9431 .float_comptime_float,
8568 => try w.print("{d}", .{data}),9432 .variable,
85699433 .extern_func,
8570 .opt_null,9434 .func_decl,
8571 .type_slice,9435 .func_instance,
8572 .only_possible_value,9436 .func_coerced,
8573 => try w.print("${d}", .{data}),9437 .union_value,
9438 .memoized_call,
9439 => try w.print("{d}", .{data}),
9440
9441 .opt_null,
9442 .type_slice,
9443 .only_possible_value,
9444 => try w.print("${d}", .{data}),
9445 }
9446 try w.writeAll(")\n");
8574 }9447 }
8575 try w.writeAll(")\n");
8576 }9448 }
8577 try bw.flush();9449 try bw.flush();
8578}9450}
...@@ -8590,15 +9462,25 @@ pub fn dumpGenericInstancesFallible(ip: *const InternPool, allocator: Allocator)...@@ -8590,15 +9462,25 @@ pub fn dumpGenericInstancesFallible(ip: *const InternPool, allocator: Allocator)
8590 const w = bw.writer();9462 const w = bw.writer();
85919463
8592 var instances: std.AutoArrayHashMapUnmanaged(Index, std.ArrayListUnmanaged(Index)) = .{};9464 var instances: std.AutoArrayHashMapUnmanaged(Index, std.ArrayListUnmanaged(Index)) = .{};
8593 const datas = ip.items.items(.data);9465 for (ip.locals, 0..) |*local, tid| {
8594 for (ip.items.items(.tag), 0..) |tag, i| {9466 const items = local.shared.items.view().slice();
8595 if (tag != .func_instance) continue;9467 const extra_list = local.shared.extra;
8596 const info = ip.extraData(Tag.FuncInstance, datas[i]);9468 for (
85979469 items.items(.tag)[0..local.mutate.items.len],
8598 const gop = try instances.getOrPut(arena, info.generic_owner);9470 items.items(.data)[0..local.mutate.items.len],
8599 if (!gop.found_existing) gop.value_ptr.* = .{};9471 0..,
86009472 ) |tag, data, index| {
8601 try gop.value_ptr.append(arena, @enumFromInt(i));9473 if (tag != .func_instance) continue;
9474 const info = extraData(extra_list, Tag.FuncInstance, data);
9475
9476 const gop = try instances.getOrPut(arena, info.generic_owner);
9477 if (!gop.found_existing) gop.value_ptr.* = .{};
9478
9479 try gop.value_ptr.append(
9480 arena,
9481 Index.Unwrapped.wrap(.{ .tid = @enumFromInt(tid), .index = @intCast(index) }, ip),
9482 );
9483 }
8602 }9484 }
86039485
8604 const SortContext = struct {9486 const SortContext = struct {
...@@ -8614,7 +9496,8 @@ pub fn dumpGenericInstancesFallible(ip: *const InternPool, allocator: Allocator)...@@ -8614,7 +9496,8 @@ pub fn dumpGenericInstancesFallible(ip: *const InternPool, allocator: Allocator)
8614 const generic_fn_owner_decl = ip.declPtrConst(ip.funcDeclOwner(entry.key_ptr.*));9496 const generic_fn_owner_decl = ip.declPtrConst(ip.funcDeclOwner(entry.key_ptr.*));
8615 try w.print("{} ({}): \n", .{ generic_fn_owner_decl.name.fmt(ip), entry.value_ptr.items.len });9497 try w.print("{} ({}): \n", .{ generic_fn_owner_decl.name.fmt(ip), entry.value_ptr.items.len });
8616 for (entry.value_ptr.items) |index| {9498 for (entry.value_ptr.items) |index| {
8617 const func = ip.extraFuncInstance(datas[@intFromEnum(index)]);9499 const unwrapped_index = index.unwrap(ip);
9500 const func = ip.extraFuncInstance(unwrapped_index.tid, unwrapped_index.getExtra(ip), unwrapped_index.getData(ip));
8618 const owner_decl = ip.declPtrConst(func.owner_decl);9501 const owner_decl = ip.declPtrConst(func.owner_decl);
8619 try w.print(" {}: (", .{owner_decl.name.fmt(ip)});9502 try w.print(" {}: (", .{owner_decl.name.fmt(ip)});
8620 for (func.comptime_args.get(ip)) |arg| {9503 for (func.comptime_args.get(ip)) |arg| {
...@@ -8712,82 +9595,173 @@ const EmbeddedNulls = enum {...@@ -8712,82 +9595,173 @@ const EmbeddedNulls = enum {
8712pub fn getOrPutString(9595pub fn getOrPutString(
8713 ip: *InternPool,9596 ip: *InternPool,
8714 gpa: Allocator,9597 gpa: Allocator,
9598 tid: Zcu.PerThread.Id,
8715 slice: []const u8,9599 slice: []const u8,
8716 comptime embedded_nulls: EmbeddedNulls,9600 comptime embedded_nulls: EmbeddedNulls,
8717) Allocator.Error!embedded_nulls.StringType() {9601) Allocator.Error!embedded_nulls.StringType() {
8718 try ip.string_bytes.ensureUnusedCapacity(gpa, slice.len + 1);9602 const strings = ip.getLocal(tid).getMutableStrings(gpa);
8719 ip.string_bytes.appendSliceAssumeCapacity(slice);9603 try strings.ensureUnusedCapacity(slice.len + 1);
8720 ip.string_bytes.appendAssumeCapacity(0);9604 strings.appendSliceAssumeCapacity(.{slice});
8721 return ip.getOrPutTrailingString(gpa, slice.len + 1, embedded_nulls);9605 strings.appendAssumeCapacity(.{0});
9606 return ip.getOrPutTrailingString(gpa, tid, @intCast(slice.len + 1), embedded_nulls);
8722}9607}
87239608
8724pub fn getOrPutStringFmt(9609pub fn getOrPutStringFmt(
8725 ip: *InternPool,9610 ip: *InternPool,
8726 gpa: Allocator,9611 gpa: Allocator,
9612 tid: Zcu.PerThread.Id,
8727 comptime format: []const u8,9613 comptime format: []const u8,
8728 args: anytype,9614 args: anytype,
8729 comptime embedded_nulls: EmbeddedNulls,9615 comptime embedded_nulls: EmbeddedNulls,
8730) Allocator.Error!embedded_nulls.StringType() {9616) Allocator.Error!embedded_nulls.StringType() {
8731 // ensure that references to string_bytes in args do not get invalidated9617 // ensure that references to strings in args do not get invalidated
8732 const len: usize = @intCast(std.fmt.count(format, args) + 1);9618 const format_z = format ++ .{0};
8733 try ip.string_bytes.ensureUnusedCapacity(gpa, len);9619 const len: u32 = @intCast(std.fmt.count(format_z, args));
8734 ip.string_bytes.writer(undefined).print(format, args) catch unreachable;9620 const strings = ip.getLocal(tid).getMutableStrings(gpa);
8735 ip.string_bytes.appendAssumeCapacity(0);9621 const slice = try strings.addManyAsSlice(len);
8736 return ip.getOrPutTrailingString(gpa, len, embedded_nulls);9622 assert((std.fmt.bufPrint(slice[0], format_z, args) catch unreachable).len == len);
9623 return ip.getOrPutTrailingString(gpa, tid, len, embedded_nulls);
8737}9624}
87389625
8739pub fn getOrPutStringOpt(9626pub fn getOrPutStringOpt(
8740 ip: *InternPool,9627 ip: *InternPool,
8741 gpa: Allocator,9628 gpa: Allocator,
9629 tid: Zcu.PerThread.Id,
8742 slice: ?[]const u8,9630 slice: ?[]const u8,
8743 comptime embedded_nulls: EmbeddedNulls,9631 comptime embedded_nulls: EmbeddedNulls,
8744) Allocator.Error!embedded_nulls.OptionalStringType() {9632) Allocator.Error!embedded_nulls.OptionalStringType() {
8745 const string = try getOrPutString(ip, gpa, slice orelse return .none, embedded_nulls);9633 const string = try getOrPutString(ip, gpa, tid, slice orelse return .none, embedded_nulls);
8746 return string.toOptional();9634 return string.toOptional();
8747}9635}
87489636
8749/// Uses the last len bytes of ip.string_bytes as the key.9637/// Uses the last len bytes of strings as the key.
8750pub fn getOrPutTrailingString(9638pub fn getOrPutTrailingString(
8751 ip: *InternPool,9639 ip: *InternPool,
8752 gpa: Allocator,9640 gpa: Allocator,
8753 len: usize,9641 tid: Zcu.PerThread.Id,
9642 len: u32,
8754 comptime embedded_nulls: EmbeddedNulls,9643 comptime embedded_nulls: EmbeddedNulls,
8755) Allocator.Error!embedded_nulls.StringType() {9644) Allocator.Error!embedded_nulls.StringType() {
8756 const string_bytes = &ip.string_bytes;9645 const strings = ip.getLocal(tid).getMutableStrings(gpa);
8757 const str_index: u32 = @intCast(string_bytes.items.len - len);9646 const start: u32 = @intCast(strings.mutate.len - len);
8758 if (len > 0 and string_bytes.getLast() == 0) {9647 if (len > 0 and strings.view().items(.@"0")[strings.mutate.len - 1] == 0) {
8759 _ = string_bytes.pop();9648 strings.mutate.len -= 1;
8760 } else {9649 } else {
8761 try string_bytes.ensureUnusedCapacity(gpa, 1);9650 try strings.ensureUnusedCapacity(1);
8762 }9651 }
8763 const key: []const u8 = string_bytes.items[str_index..];9652 const key: []const u8 = strings.view().items(.@"0")[start..];
9653 const value: embedded_nulls.StringType() =
9654 @enumFromInt(@as(u32, @intFromEnum(tid)) << ip.tid_shift_32 | start);
8764 const has_embedded_null = std.mem.indexOfScalar(u8, key, 0) != null;9655 const has_embedded_null = std.mem.indexOfScalar(u8, key, 0) != null;
8765 switch (embedded_nulls) {9656 switch (embedded_nulls) {
8766 .no_embedded_nulls => assert(!has_embedded_null),9657 .no_embedded_nulls => assert(!has_embedded_null),
8767 .maybe_embedded_nulls => if (has_embedded_null) {9658 .maybe_embedded_nulls => if (has_embedded_null) {
8768 string_bytes.appendAssumeCapacity(0);9659 strings.appendAssumeCapacity(.{0});
8769 return @enumFromInt(str_index);9660 return value;
8770 },9661 },
9662 }
9663
9664 const full_hash = Hash.hash(0, key);
9665 const hash: u32 = @truncate(full_hash >> 32);
9666 const shard = &ip.shards[@intCast(full_hash & (ip.shards.len - 1))];
9667 var map = shard.shared.string_map.acquire();
9668 const Map = @TypeOf(map);
9669 var map_mask = map.header().mask();
9670 var map_index = hash;
9671 while (true) : (map_index += 1) {
9672 map_index &= map_mask;
9673 const entry = &map.entries[map_index];
9674 const index = entry.acquire().unwrap() orelse break;
9675 if (entry.hash != hash) continue;
9676 if (!index.eqlSlice(key, ip)) continue;
9677 strings.shrinkRetainingCapacity(start);
9678 return @enumFromInt(@intFromEnum(index));
9679 }
9680 shard.mutate.string_map.mutex.lock();
9681 defer shard.mutate.string_map.mutex.unlock();
9682 if (map.entries != shard.shared.string_map.entries) {
9683 shard.mutate.string_map.len += 1;
9684 map = shard.shared.string_map;
9685 map_mask = map.header().mask();
9686 map_index = hash;
9687 }
9688 while (true) : (map_index += 1) {
9689 map_index &= map_mask;
9690 const entry = &map.entries[map_index];
9691 const index = entry.acquire().unwrap() orelse break;
9692 if (entry.hash != hash) continue;
9693 if (!index.eqlSlice(key, ip)) continue;
9694 strings.shrinkRetainingCapacity(start);
9695 return @enumFromInt(@intFromEnum(index));
9696 }
9697 defer shard.mutate.string_map.len += 1;
9698 const map_header = map.header().*;
9699 if (shard.mutate.string_map.len < map_header.capacity * 3 / 5) {
9700 const entry = &map.entries[map_index];
9701 entry.hash = hash;
9702 entry.release(@enumFromInt(@intFromEnum(value)));
9703 strings.appendAssumeCapacity(.{0});
9704 return value;
9705 }
9706 const arena_state = &ip.getLocal(tid).mutate.arena;
9707 var arena = arena_state.promote(gpa);
9708 defer arena_state.* = arena.state;
9709 const new_map_capacity = map_header.capacity * 2;
9710 const new_map_buf = try arena.allocator().alignedAlloc(
9711 u8,
9712 Map.alignment,
9713 Map.entries_offset + new_map_capacity * @sizeOf(Map.Entry),
9714 );
9715 const new_map: Map = .{ .entries = @ptrCast(new_map_buf[Map.entries_offset..].ptr) };
9716 new_map.header().* = .{ .capacity = new_map_capacity };
9717 @memset(new_map.entries[0..new_map_capacity], .{ .value = .none, .hash = undefined });
9718 const new_map_mask = new_map.header().mask();
9719 map_index = 0;
9720 while (map_index < map_header.capacity) : (map_index += 1) {
9721 const entry = &map.entries[map_index];
9722 const index = entry.value.unwrap() orelse continue;
9723 const item_hash = entry.hash;
9724 var new_map_index = item_hash;
9725 while (true) : (new_map_index += 1) {
9726 new_map_index &= new_map_mask;
9727 const new_entry = &new_map.entries[new_map_index];
9728 if (new_entry.value != .none) continue;
9729 new_entry.* = .{
9730 .value = index.toOptional(),
9731 .hash = item_hash,
9732 };
9733 break;
9734 }
8771 }9735 }
8772 const gop = try ip.string_table.getOrPutContextAdapted(gpa, key, std.hash_map.StringIndexAdapter{9736 map = new_map;
8773 .bytes = string_bytes,9737 map_index = hash;
8774 }, std.hash_map.StringIndexContext{9738 while (true) : (map_index += 1) {
8775 .bytes = string_bytes,9739 map_index &= new_map_mask;
8776 });9740 if (map.entries[map_index].value == .none) break;
8777 if (gop.found_existing) {
8778 string_bytes.shrinkRetainingCapacity(str_index);
8779 return @enumFromInt(gop.key_ptr.*);
8780 } else {
8781 gop.key_ptr.* = str_index;
8782 string_bytes.appendAssumeCapacity(0);
8783 return @enumFromInt(str_index);
8784 }9741 }
9742 map.entries[map_index] = .{
9743 .value = @enumFromInt(@intFromEnum(value)),
9744 .hash = hash,
9745 };
9746 shard.shared.string_map.release(new_map);
9747 strings.appendAssumeCapacity(.{0});
9748 return value;
8785}9749}
87869750
8787pub fn getString(ip: *InternPool, s: []const u8) OptionalNullTerminatedString {9751pub fn getString(ip: *InternPool, key: []const u8) OptionalNullTerminatedString {
8788 return if (ip.string_table.getKeyAdapted(s, std.hash_map.StringIndexAdapter{9752 const full_hash = Hash.hash(0, key);
8789 .bytes = &ip.string_bytes,9753 const hash: u32 = @truncate(full_hash >> 32);
8790 })) |index| @enumFromInt(index) else .none;9754 const shard = &ip.shards[@intCast(full_hash & (ip.shards.len - 1))];
9755 const map = shard.shared.string_map.acquire();
9756 const map_mask = map.header().mask();
9757 var map_index = hash;
9758 while (true) : (map_index += 1) {
9759 map_index &= map_mask;
9760 const entry = map.at(map_index);
9761 const index = entry.acquire().unwrap() orelse return null;
9762 if (entry.hash != hash) continue;
9763 if (index.eqlSlice(key, ip)) return index;
9764 }
8791}9765}
87929766
8793pub fn typeOf(ip: *const InternPool, index: Index) Index {9767pub fn typeOf(ip: *const InternPool, index: Index) Index {
...@@ -8878,106 +9852,112 @@ pub fn typeOf(ip: *const InternPool, index: Index) Index {...@@ -8878,106 +9852,112 @@ pub fn typeOf(ip: *const InternPool, index: Index) Index {
88789852
8879 // This optimization on tags is needed so that indexToKey can call9853 // This optimization on tags is needed so that indexToKey can call
8880 // typeOf without being recursive.9854 // typeOf without being recursive.
8881 _ => switch (ip.items.items(.tag)[@intFromEnum(index)]) {9855 _ => {
8882 .removed => unreachable,9856 const unwrapped_index = index.unwrap(ip);
88839857 const item = unwrapped_index.getItem(ip);
8884 .type_int_signed,9858 return switch (item.tag) {
8885 .type_int_unsigned,9859 .removed => unreachable,
8886 .type_array_big,9860
8887 .type_array_small,9861 .type_int_signed,
8888 .type_vector,9862 .type_int_unsigned,
8889 .type_pointer,9863 .type_array_big,
8890 .type_slice,9864 .type_array_small,
8891 .type_optional,9865 .type_vector,
8892 .type_anyframe,9866 .type_pointer,
8893 .type_error_union,9867 .type_slice,
8894 .type_anyerror_union,9868 .type_optional,
8895 .type_error_set,9869 .type_anyframe,
8896 .type_inferred_error_set,9870 .type_error_union,
8897 .type_enum_auto,9871 .type_anyerror_union,
8898 .type_enum_explicit,9872 .type_error_set,
8899 .type_enum_nonexhaustive,9873 .type_inferred_error_set,
8900 .simple_type,9874 .type_enum_auto,
8901 .type_opaque,9875 .type_enum_explicit,
8902 .type_struct,9876 .type_enum_nonexhaustive,
8903 .type_struct_anon,9877 .type_opaque,
8904 .type_struct_packed,9878 .type_struct,
8905 .type_struct_packed_inits,9879 .type_struct_anon,
8906 .type_tuple_anon,9880 .type_struct_packed,
8907 .type_union,9881 .type_struct_packed_inits,
8908 .type_function,9882 .type_tuple_anon,
8909 => .type_type,9883 .type_union,
89109884 .type_function,
8911 .undef,9885 => .type_type,
8912 .opt_null,9886
8913 .only_possible_value,9887 .undef,
8914 => @enumFromInt(ip.items.items(.data)[@intFromEnum(index)]),9888 .opt_null,
89159889 .only_possible_value,
8916 .simple_value => unreachable, // handled via Index above9890 => @enumFromInt(item.data),
89179891
8918 inline .ptr_decl,9892 .simple_type, .simple_value => unreachable, // handled via Index above
8919 .ptr_comptime_alloc,9893
8920 .ptr_anon_decl,9894 inline .ptr_decl,
8921 .ptr_anon_decl_aligned,9895 .ptr_comptime_alloc,
8922 .ptr_comptime_field,9896 .ptr_anon_decl,
8923 .ptr_int,9897 .ptr_anon_decl_aligned,
8924 .ptr_eu_payload,9898 .ptr_comptime_field,
8925 .ptr_opt_payload,9899 .ptr_int,
8926 .ptr_elem,9900 .ptr_eu_payload,
8927 .ptr_field,9901 .ptr_opt_payload,
8928 .ptr_slice,9902 .ptr_elem,
8929 .opt_payload,9903 .ptr_field,
8930 .error_union_payload,9904 .ptr_slice,
8931 .int_small,9905 .opt_payload,
8932 .int_lazy_align,9906 .error_union_payload,
8933 .int_lazy_size,9907 .int_small,
8934 .error_set_error,9908 .int_lazy_align,
8935 .error_union_error,9909 .int_lazy_size,
8936 .enum_tag,9910 .error_set_error,
8937 .variable,9911 .error_union_error,
8938 .extern_func,9912 .enum_tag,
8939 .func_decl,9913 .variable,
8940 .func_instance,9914 .extern_func,
8941 .func_coerced,9915 .func_decl,
8942 .union_value,9916 .func_instance,
8943 .bytes,9917 .func_coerced,
8944 .aggregate,9918 .union_value,
8945 .repeated,9919 .bytes,
8946 => |t| {9920 .aggregate,
8947 const extra_index = ip.items.items(.data)[@intFromEnum(index)];9921 .repeated,
8948 const field_index = std.meta.fieldIndex(t.Payload(), "ty").?;9922 => |t| {
8949 return @enumFromInt(ip.extra.items[extra_index + field_index]);9923 const extra_list = unwrapped_index.getExtra(ip);
8950 },9924 return @enumFromInt(extra_list.view().items(.@"0")[item.data + std.meta.fieldIndex(t.Payload(), "ty").?]);
89519925 },
8952 .int_u8 => .u8_type,
8953 .int_u16 => .u16_type,
8954 .int_u32 => .u32_type,
8955 .int_i32 => .i32_type,
8956 .int_usize => .usize_type,
8957
8958 .int_comptime_int_u32,
8959 .int_comptime_int_i32,
8960 => .comptime_int_type,
89619926
8962 // Note these are stored in limbs data, not extra data.9927 .int_u8 => .u8_type,
8963 .int_positive,9928 .int_u16 => .u16_type,
8964 .int_negative,9929 .int_u32 => .u32_type,
8965 => ip.limbData(Int, ip.items.items(.data)[@intFromEnum(index)]).ty,9930 .int_i32 => .i32_type,
9931 .int_usize => .usize_type,
9932
9933 .int_comptime_int_u32,
9934 .int_comptime_int_i32,
9935 => .comptime_int_type,
9936
9937 // Note these are stored in limbs data, not extra data.
9938 .int_positive,
9939 .int_negative,
9940 => {
9941 const limbs_list = ip.getLocalShared(unwrapped_index.tid).getLimbs();
9942 const int: Int = @bitCast(limbs_list.view().items(.@"0")[item.data..][0..Int.limbs_items_len].*);
9943 return int.ty;
9944 },
89669945
8967 .enum_literal => .enum_literal_type,9946 .enum_literal => .enum_literal_type,
8968 .float_f16 => .f16_type,9947 .float_f16 => .f16_type,
8969 .float_f32 => .f32_type,9948 .float_f32 => .f32_type,
8970 .float_f64 => .f64_type,9949 .float_f64 => .f64_type,
8971 .float_f80 => .f80_type,9950 .float_f80 => .f80_type,
8972 .float_f128 => .f128_type,9951 .float_f128 => .f128_type,
89739952
8974 .float_c_longdouble_f80,9953 .float_c_longdouble_f80,
8975 .float_c_longdouble_f128,9954 .float_c_longdouble_f128,
8976 => .c_longdouble_type,9955 => .c_longdouble_type,
89779956
8978 .float_comptime_float => .comptime_float_type,9957 .float_comptime_float => .comptime_float_type,
89799958
8980 .memoized_call => unreachable,9959 .memoized_call => unreachable,
9960 };
8981 },9961 },
89829962
8983 .none => unreachable,9963 .none => unreachable,
...@@ -9011,64 +9991,79 @@ pub fn aggregateTypeLenIncludingSentinel(ip: *const InternPool, ty: Index) u64 {...@@ -9011,64 +9991,79 @@ pub fn aggregateTypeLenIncludingSentinel(ip: *const InternPool, ty: Index) u64 {
9011}9991}
90129992
9013pub fn funcTypeReturnType(ip: *const InternPool, ty: Index) Index {9993pub fn funcTypeReturnType(ip: *const InternPool, ty: Index) Index {
9014 const item = ip.items.get(@intFromEnum(ty));9994 const unwrapped_ty = ty.unwrap(ip);
9015 const child_item = switch (item.tag) {9995 const ty_extra = unwrapped_ty.getExtra(ip);
9016 .type_pointer => ip.items.get(ip.extra.items[9996 const ty_item = unwrapped_ty.getItem(ip);
9017 item.data + std.meta.fieldIndex(Tag.TypePointer, "child").?9997 const child_extra, const child_item = switch (ty_item.tag) {
9018 ]),9998 .type_pointer => child: {
9019 .type_function => item,9999 const child_index: Index = @enumFromInt(ty_extra.view().items(.@"0")[
10000 ty_item.data + std.meta.fieldIndex(Tag.TypePointer, "child").?
10001 ]);
10002 const unwrapped_child = child_index.unwrap(ip);
10003 break :child .{ unwrapped_child.getExtra(ip), unwrapped_child.getItem(ip) };
10004 },
10005 .type_function => .{ ty_extra, ty_item },
9020 else => unreachable,10006 else => unreachable,
9021 };10007 };
9022 assert(child_item.tag == .type_function);10008 assert(child_item.tag == .type_function);
9023 return @enumFromInt(ip.extra.items[10009 return @enumFromInt(child_extra.view().items(.@"0")[
9024 child_item.data + std.meta.fieldIndex(Tag.TypeFunction, "return_type").?10010 child_item.data + std.meta.fieldIndex(Tag.TypeFunction, "return_type").?
9025 ]);10011 ]);
9026}10012}
902710013
9028pub fn isNoReturn(ip: *const InternPool, ty: Index) bool {10014pub fn isNoReturn(ip: *const InternPool, ty: Index) bool {
9029 return switch (ty) {10015 switch (ty) {
9030 .noreturn_type => true,10016 .noreturn_type => return true,
9031 else => switch (ip.items.items(.tag)[@intFromEnum(ty)]) {10017 else => {
9032 .type_error_set => ip.extra.items[ip.items.items(.data)[@intFromEnum(ty)] + std.meta.fieldIndex(Tag.ErrorSet, "names_len").?] == 0,10018 const unwrapped_ty = ty.unwrap(ip);
9033 else => false,10019 const ty_item = unwrapped_ty.getItem(ip);
10020 return switch (ty_item.tag) {
10021 .type_error_set => unwrapped_ty.getExtra(ip).view().items(.@"0")[ty_item.data + std.meta.fieldIndex(Tag.ErrorSet, "names_len").?] == 0,
10022 else => false,
10023 };
9034 },10024 },
9035 };10025 }
9036}10026}
903710027
9038pub fn isUndef(ip: *const InternPool, val: Index) bool {10028pub fn isUndef(ip: *const InternPool, val: Index) bool {
9039 return val == .undef or ip.items.items(.tag)[@intFromEnum(val)] == .undef;10029 return val == .undef or val.unwrap(ip).getTag(ip) == .undef;
9040}10030}
904110031
9042pub fn isVariable(ip: *const InternPool, val: Index) bool {10032pub fn isVariable(ip: *const InternPool, val: Index) bool {
9043 return ip.items.items(.tag)[@intFromEnum(val)] == .variable;10033 return val.unwrap(ip).getTag(ip) == .variable;
9044}10034}
904510035
9046pub fn getBackingDecl(ip: *const InternPool, val: Index) OptionalDeclIndex {10036pub fn getBackingDecl(ip: *const InternPool, val: Index) OptionalDeclIndex {
9047 var base = @intFromEnum(val);10037 var base = val;
9048 while (true) {10038 while (true) {
9049 switch (ip.items.items(.tag)[base]) {10039 const unwrapped_base = base.unwrap(ip);
9050 .ptr_decl => return @enumFromInt(ip.extra.items[10040 const base_item = unwrapped_base.getItem(ip);
9051 ip.items.items(.data)[base] + std.meta.fieldIndex(PtrDecl, "decl").?10041 const base_extra_items = unwrapped_base.getExtra(ip).view().items(.@"0");
10042 switch (base_item.tag) {
10043 .ptr_decl => return @enumFromInt(base_extra_items[
10044 base_item.data + std.meta.fieldIndex(PtrDecl, "decl").?
9052 ]),10045 ]),
9053 inline .ptr_eu_payload,10046 inline .ptr_eu_payload,
9054 .ptr_opt_payload,10047 .ptr_opt_payload,
9055 .ptr_elem,10048 .ptr_elem,
9056 .ptr_field,10049 .ptr_field,
9057 => |tag| base = ip.extra.items[10050 => |tag| base = @enumFromInt(base_extra_items[
9058 ip.items.items(.data)[base] + std.meta.fieldIndex(tag.Payload(), "base").?10051 base_item.data + std.meta.fieldIndex(tag.Payload(), "base").?
9059 ],10052 ]),
9060 .ptr_slice => base = ip.extra.items[10053 .ptr_slice => base = @enumFromInt(base_extra_items[
9061 ip.items.items(.data)[base] + std.meta.fieldIndex(PtrSlice, "ptr").?10054 base_item.data + std.meta.fieldIndex(PtrSlice, "ptr").?
9062 ],10055 ]),
9063 else => return .none,10056 else => return .none,
9064 }10057 }
9065 }10058 }
9066}10059}
906710060
9068pub fn getBackingAddrTag(ip: *const InternPool, val: Index) ?Key.Ptr.BaseAddr.Tag {10061pub fn getBackingAddrTag(ip: *const InternPool, val: Index) ?Key.Ptr.BaseAddr.Tag {
9069 var base = @intFromEnum(val);10062 var base = val;
9070 while (true) {10063 while (true) {
9071 switch (ip.items.items(.tag)[base]) {10064 const unwrapped_base = base.unwrap(ip);
10065 const base_item = unwrapped_base.getItem(ip);
10066 switch (base_item.tag) {
9072 .ptr_decl => return .decl,10067 .ptr_decl => return .decl,
9073 .ptr_comptime_alloc => return .comptime_alloc,10068 .ptr_comptime_alloc => return .comptime_alloc,
9074 .ptr_anon_decl,10069 .ptr_anon_decl,
...@@ -9080,12 +10075,12 @@ pub fn getBackingAddrTag(ip: *const InternPool, val: Index) ?Key.Ptr.BaseAddr.Ta...@@ -9080,12 +10075,12 @@ pub fn getBackingAddrTag(ip: *const InternPool, val: Index) ?Key.Ptr.BaseAddr.Ta
9080 .ptr_opt_payload,10075 .ptr_opt_payload,
9081 .ptr_elem,10076 .ptr_elem,
9082 .ptr_field,10077 .ptr_field,
9083 => |tag| base = ip.extra.items[10078 => |tag| base = @enumFromInt(unwrapped_base.getExtra(ip).view().items(.@"0")[
9084 ip.items.items(.data)[base] + std.meta.fieldIndex(tag.Payload(), "base").?10079 base_item.data + std.meta.fieldIndex(tag.Payload(), "base").?
9085 ],10080 ]),
9086 inline .ptr_slice => |tag| base = ip.extra.items[10081 inline .ptr_slice => |tag| base = @enumFromInt(unwrapped_base.getExtra(ip).view().items(.@"0")[
9087 ip.items.items(.data)[base] + std.meta.fieldIndex(tag.Payload(), "ptr").?10082 base_item.data + std.meta.fieldIndex(tag.Payload(), "ptr").?
9088 ],10083 ]),
9089 else => return null,10084 else => return null,
9090 }10085 }
9091 }10086 }
...@@ -9194,7 +10189,7 @@ pub fn zigTypeTagOrPoison(ip: *const InternPool, index: Index) error{GenericPois...@@ -9194,7 +10189,7 @@ pub fn zigTypeTagOrPoison(ip: *const InternPool, index: Index) error{GenericPois
9194 .empty_struct => unreachable,10189 .empty_struct => unreachable,
9195 .generic_poison => unreachable,10190 .generic_poison => unreachable,
919610191
9197 _ => switch (ip.items.items(.tag)[@intFromEnum(index)]) {10192 _ => switch (index.unwrap(ip).getTag(ip)) {
9198 .removed => unreachable,10193 .removed => unreachable,
919910194
9200 .type_int_signed,10195 .type_int_signed,
...@@ -9301,143 +10296,145 @@ pub fn zigTypeTagOrPoison(ip: *const InternPool, index: Index) error{GenericPois...@@ -9301,143 +10296,145 @@ pub fn zigTypeTagOrPoison(ip: *const InternPool, index: Index) error{GenericPois
9301 };10296 };
9302}10297}
930310298
9304pub fn isFuncBody(ip: *const InternPool, i: Index) bool {10299pub fn isFuncBody(ip: *const InternPool, index: Index) bool {
9305 assert(i != .none);10300 return switch (index.unwrap(ip).getTag(ip)) {
9306 return switch (ip.items.items(.tag)[@intFromEnum(i)]) {
9307 .func_decl, .func_instance, .func_coerced => true,10301 .func_decl, .func_instance, .func_coerced => true,
9308 else => false,10302 else => false,
9309 };10303 };
9310}10304}
931110305
9312pub fn funcAnalysis(ip: *const InternPool, i: Index) *FuncAnalysis {10306pub fn funcAnalysis(ip: *const InternPool, index: Index) *FuncAnalysis {
9313 assert(i != .none);10307 const unwrapped_index = index.unwrap(ip);
9314 const item = ip.items.get(@intFromEnum(i));10308 const extra = unwrapped_index.getExtra(ip);
10309 const item = unwrapped_index.getItem(ip);
9315 const extra_index = switch (item.tag) {10310 const extra_index = switch (item.tag) {
9316 .func_decl => item.data + std.meta.fieldIndex(Tag.FuncDecl, "analysis").?,10311 .func_decl => item.data + std.meta.fieldIndex(Tag.FuncDecl, "analysis").?,
9317 .func_instance => item.data + std.meta.fieldIndex(Tag.FuncInstance, "analysis").?,10312 .func_instance => item.data + std.meta.fieldIndex(Tag.FuncInstance, "analysis").?,
9318 .func_coerced => i: {10313 .func_coerced => {
9319 const extra_index = item.data + std.meta.fieldIndex(Tag.FuncCoerced, "func").?;10314 const extra_index = item.data + std.meta.fieldIndex(Tag.FuncCoerced, "func").?;
9320 const func_index: Index = @enumFromInt(ip.extra.items[extra_index]);10315 const func_index: Index = @enumFromInt(extra.view().items(.@"0")[extra_index]);
9321 const sub_item = ip.items.get(@intFromEnum(func_index));10316 const unwrapped_func = func_index.unwrap(ip);
9322 break :i switch (sub_item.tag) {10317 const func_item = unwrapped_func.getItem(ip);
9323 .func_decl => sub_item.data + std.meta.fieldIndex(Tag.FuncDecl, "analysis").?,10318 return @ptrCast(&unwrapped_func.getExtra(ip).view().items(.@"0")[
9324 .func_instance => sub_item.data + std.meta.fieldIndex(Tag.FuncInstance, "analysis").?,10319 switch (func_item.tag) {
9325 else => unreachable,10320 .func_decl => func_item.data + std.meta.fieldIndex(Tag.FuncDecl, "analysis").?,
9326 };10321 .func_instance => func_item.data + std.meta.fieldIndex(Tag.FuncInstance, "analysis").?,
10322 else => unreachable,
10323 }
10324 ]);
9327 },10325 },
9328 else => unreachable,10326 else => unreachable,
9329 };10327 };
9330 return @ptrCast(&ip.extra.items[extra_index]);10328 return @ptrCast(&extra.view().items(.@"0")[extra_index]);
9331}10329}
933210330
9333pub fn funcHasInferredErrorSet(ip: *const InternPool, i: Index) bool {10331pub fn funcHasInferredErrorSet(ip: *const InternPool, i: Index) bool {
9334 return funcAnalysis(ip, i).inferred_error_set;10332 return funcAnalysis(ip, i).inferred_error_set;
9335}10333}
933610334
9337pub fn funcZirBodyInst(ip: *const InternPool, i: Index) TrackedInst.Index {10335pub fn funcZirBodyInst(ip: *const InternPool, index: Index) TrackedInst.Index {
9338 assert(i != .none);10336 const unwrapped_index = index.unwrap(ip);
9339 const item = ip.items.get(@intFromEnum(i));10337 const item = unwrapped_index.getItem(ip);
10338 const item_extra = unwrapped_index.getExtra(ip);
9340 const zir_body_inst_field_index = std.meta.fieldIndex(Tag.FuncDecl, "zir_body_inst").?;10339 const zir_body_inst_field_index = std.meta.fieldIndex(Tag.FuncDecl, "zir_body_inst").?;
9341 const extra_index = switch (item.tag) {10340 switch (item.tag) {
9342 .func_decl => item.data + zir_body_inst_field_index,10341 .func_decl => return @enumFromInt(item_extra.view().items(.@"0")[item.data + zir_body_inst_field_index]),
9343 .func_instance => b: {10342 .func_instance => {
9344 const generic_owner_field_index = std.meta.fieldIndex(Tag.FuncInstance, "generic_owner").?;10343 const generic_owner_field_index = std.meta.fieldIndex(Tag.FuncInstance, "generic_owner").?;
9345 const func_decl_index = ip.extra.items[item.data + generic_owner_field_index];10344 const func_decl_index: Index = @enumFromInt(item_extra.view().items(.@"0")[item.data + generic_owner_field_index]);
9346 assert(ip.items.items(.tag)[func_decl_index] == .func_decl);10345 const unwrapped_func_decl = func_decl_index.unwrap(ip);
9347 break :b ip.items.items(.data)[func_decl_index] + zir_body_inst_field_index;10346 const func_decl_item = unwrapped_func_decl.getItem(ip);
10347 const func_decl_extra = unwrapped_func_decl.getExtra(ip);
10348 assert(func_decl_item.tag == .func_decl);
10349 return @enumFromInt(func_decl_extra.view().items(.@"0")[func_decl_item.data + zir_body_inst_field_index]);
9348 },10350 },
9349 .func_coerced => {10351 .func_coerced => {
9350 const datas = ip.items.items(.data);10352 const uncoerced_func_index: Index = @enumFromInt(item_extra.view().items(.@"0")[
9351 const uncoerced_func_index: Index = @enumFromInt(ip.extra.items[10353 item.data + std.meta.fieldIndex(Tag.FuncCoerced, "func").?
9352 datas[@intFromEnum(i)] + std.meta.fieldIndex(Tag.FuncCoerced, "func").?
9353 ]);10354 ]);
9354 return ip.funcZirBodyInst(uncoerced_func_index);10355 return ip.funcZirBodyInst(uncoerced_func_index);
9355 },10356 },
9356 else => unreachable,10357 else => unreachable,
9357 };10358 }
9358 return @enumFromInt(ip.extra.items[extra_index]);
9359}10359}
936010360
9361pub fn iesFuncIndex(ip: *const InternPool, ies_index: Index) Index {10361pub fn iesFuncIndex(ip: *const InternPool, ies_index: Index) Index {
9362 assert(ies_index != .none);10362 const item = ies_index.unwrap(ip).getItem(ip);
9363 const tags = ip.items.items(.tag);10363 assert(item.tag == .type_inferred_error_set);
9364 assert(tags[@intFromEnum(ies_index)] == .type_inferred_error_set);10364 const func_index: Index = @enumFromInt(item.data);
9365 const func_index = ip.items.items(.data)[@intFromEnum(ies_index)];10365 switch (func_index.unwrap(ip).getTag(ip)) {
9366 switch (tags[func_index]) {
9367 .func_decl, .func_instance => {},10366 .func_decl, .func_instance => {},
9368 else => unreachable, // assertion failed10367 else => unreachable, // assertion failed
9369 }10368 }
9370 return @enumFromInt(func_index);10369 return func_index;
9371}10370}
937210371
9373/// Returns a mutable pointer to the resolved error set type of an inferred10372/// Returns a mutable pointer to the resolved error set type of an inferred
9374/// error set function. The returned pointer is invalidated when anything is10373/// error set function. The returned pointer is invalidated when anything is
9375/// added to `ip`.10374/// added to `ip`.
9376pub fn iesResolved(ip: *const InternPool, ies_index: Index) *Index {10375pub fn iesResolved(ip: *const InternPool, ies_index: Index) *Index {
9377 assert(ies_index != .none);10376 const ies_item = ies_index.getItem(ip);
9378 const tags = ip.items.items(.tag);10377 assert(ies_item.tag == .type_inferred_error_set);
9379 const datas = ip.items.items(.data);10378 return funcIesResolved(ip, ies_item.data);
9380 assert(tags[@intFromEnum(ies_index)] == .type_inferred_error_set);
9381 const func_index = datas[@intFromEnum(ies_index)];
9382 return funcIesResolved(ip, func_index);
9383}10379}
938410380
9385/// Returns a mutable pointer to the resolved error set type of an inferred10381/// Returns a mutable pointer to the resolved error set type of an inferred
9386/// error set function. The returned pointer is invalidated when anything is10382/// error set function. The returned pointer is invalidated when anything is
9387/// added to `ip`.10383/// added to `ip`.
9388pub fn funcIesResolved(ip: *const InternPool, func_index: Index) *Index {10384pub fn funcIesResolved(ip: *const InternPool, func_index: Index) *Index {
9389 const tags = ip.items.items(.tag);
9390 const datas = ip.items.items(.data);
9391 assert(funcHasInferredErrorSet(ip, func_index));10385 assert(funcHasInferredErrorSet(ip, func_index));
9392 const func_start = datas[@intFromEnum(func_index)];10386 const unwrapped_func = func_index.unwrap(ip);
9393 const extra_index = switch (tags[@intFromEnum(func_index)]) {10387 const func_extra = unwrapped_func.getExtra(ip);
9394 .func_decl => func_start + @typeInfo(Tag.FuncDecl).Struct.fields.len,10388 const func_item = unwrapped_func.getItem(ip);
9395 .func_instance => func_start + @typeInfo(Tag.FuncInstance).Struct.fields.len,10389 const extra_index = switch (func_item.tag) {
9396 .func_coerced => i: {10390 .func_decl => func_item.data + @typeInfo(Tag.FuncDecl).Struct.fields.len,
9397 const uncoerced_func_index: Index = @enumFromInt(ip.extra.items[10391 .func_instance => func_item.data + @typeInfo(Tag.FuncInstance).Struct.fields.len,
9398 func_start + std.meta.fieldIndex(Tag.FuncCoerced, "func").?10392 .func_coerced => {
10393 const uncoerced_func_index: Index = @enumFromInt(func_extra.view().items(.@"0")[
10394 func_item.data + std.meta.fieldIndex(Tag.FuncCoerced, "func").?
10395 ]);
10396 const unwrapped_uncoerced_func = uncoerced_func_index.unwrap(ip);
10397 const uncoerced_func_item = unwrapped_uncoerced_func.getItem(ip);
10398 return @ptrCast(&unwrapped_uncoerced_func.getExtra(ip).view().items(.@"0")[
10399 switch (uncoerced_func_item.tag) {
10400 .func_decl => uncoerced_func_item.data + @typeInfo(Tag.FuncDecl).Struct.fields.len,
10401 .func_instance => uncoerced_func_item.data + @typeInfo(Tag.FuncInstance).Struct.fields.len,
10402 else => unreachable,
10403 }
9399 ]);10404 ]);
9400 const uncoerced_func_start = datas[@intFromEnum(uncoerced_func_index)];
9401 break :i switch (tags[@intFromEnum(uncoerced_func_index)]) {
9402 .func_decl => uncoerced_func_start + @typeInfo(Tag.FuncDecl).Struct.fields.len,
9403 .func_instance => uncoerced_func_start + @typeInfo(Tag.FuncInstance).Struct.fields.len,
9404 else => unreachable,
9405 };
9406 },10405 },
9407 else => unreachable,10406 else => unreachable,
9408 };10407 };
9409 return @ptrCast(&ip.extra.items[extra_index]);10408 return @ptrCast(&func_extra.view().items(.@"0")[extra_index]);
9410}10409}
941110410
9412pub fn funcDeclInfo(ip: *const InternPool, i: Index) Key.Func {10411pub fn funcDeclInfo(ip: *const InternPool, index: Index) Key.Func {
9413 const tags = ip.items.items(.tag);10412 const unwrapped_index = index.unwrap(ip);
9414 const datas = ip.items.items(.data);10413 const item = unwrapped_index.getItem(ip);
9415 assert(tags[@intFromEnum(i)] == .func_decl);10414 assert(item.tag == .func_decl);
9416 return extraFuncDecl(ip, datas[@intFromEnum(i)]);10415 return extraFuncDecl(unwrapped_index.tid, unwrapped_index.getExtra(ip), item.data);
9417}10416}
941810417
9419pub fn funcDeclOwner(ip: *const InternPool, i: Index) DeclIndex {10418pub fn funcDeclOwner(ip: *const InternPool, index: Index) DeclIndex {
9420 return funcDeclInfo(ip, i).owner_decl;10419 return funcDeclInfo(ip, index).owner_decl;
9421}10420}
942210421
9423pub fn funcTypeParamsLen(ip: *const InternPool, i: Index) u32 {10422pub fn funcTypeParamsLen(ip: *const InternPool, index: Index) u32 {
9424 const tags = ip.items.items(.tag);10423 const unwrapped_index = index.unwrap(ip);
9425 const datas = ip.items.items(.data);10424 const extra_list = unwrapped_index.getExtra(ip);
9426 assert(tags[@intFromEnum(i)] == .type_function);10425 const item = unwrapped_index.getItem(ip);
9427 const start = datas[@intFromEnum(i)];10426 assert(item.tag == .type_function);
9428 return ip.extra.items[start + std.meta.fieldIndex(Tag.TypeFunction, "params_len").?];10427 return extra_list.view().items(.@"0")[item.data + std.meta.fieldIndex(Tag.TypeFunction, "params_len").?];
9429}10428}
943010429
9431pub fn unwrapCoercedFunc(ip: *const InternPool, i: Index) Index {10430pub fn unwrapCoercedFunc(ip: *const InternPool, index: Index) Index {
9432 const tags = ip.items.items(.tag);10431 const unwrapped_index = index.unwrap(ip);
9433 return switch (tags[@intFromEnum(i)]) {10432 const item = unwrapped_index.getItem(ip);
9434 .func_coerced => {10433 return switch (item.tag) {
9435 const datas = ip.items.items(.data);10434 .func_coerced => @enumFromInt(unwrapped_index.getExtra(ip).view().items(.@"0")[
9436 return @enumFromInt(ip.extra.items[10435 item.data + std.meta.fieldIndex(Tag.FuncCoerced, "func").?
9437 datas[@intFromEnum(i)] + std.meta.fieldIndex(Tag.FuncCoerced, "func").?10436 ]),
9438 ]);10437 .func_instance, .func_decl => index,
9439 },
9440 .func_instance, .func_decl => i,
9441 else => unreachable,10438 else => unreachable,
9442 };10439 };
9443}10440}
...@@ -9445,7 +10442,12 @@ pub fn unwrapCoercedFunc(ip: *const InternPool, i: Index) Index {...@@ -9445,7 +10442,12 @@ pub fn unwrapCoercedFunc(ip: *const InternPool, i: Index) Index {
9445/// Having resolved a builtin type to a real struct/union/enum (which is now at `resolverd_index`),10442/// Having resolved a builtin type to a real struct/union/enum (which is now at `resolverd_index`),
9446/// make `want_index` refer to this type instead. This invalidates `resolved_index`, so must be10443/// make `want_index` refer to this type instead. This invalidates `resolved_index`, so must be
9447/// called only when it is guaranteed that no reference to `resolved_index` exists.10444/// called only when it is guaranteed that no reference to `resolved_index` exists.
9448pub fn resolveBuiltinType(ip: *InternPool, want_index: Index, resolved_index: Index) void {10445pub fn resolveBuiltinType(
10446 ip: *InternPool,
10447 tid: Zcu.PerThread.Id,
10448 want_index: Index,
10449 resolved_index: Index,
10450) void {
9449 assert(@intFromEnum(want_index) >= @intFromEnum(Index.first_type));10451 assert(@intFromEnum(want_index) >= @intFromEnum(Index.first_type));
9450 assert(@intFromEnum(want_index) <= @intFromEnum(Index.last_type));10452 assert(@intFromEnum(want_index) <= @intFromEnum(Index.last_type));
945110453
...@@ -9457,20 +10459,12 @@ pub fn resolveBuiltinType(ip: *InternPool, want_index: Index, resolved_index: In...@@ -9457,20 +10459,12 @@ pub fn resolveBuiltinType(ip: *InternPool, want_index: Index, resolved_index: In
9457 (ip.zigTypeTagOrPoison(resolved_index) catch unreachable));10459 (ip.zigTypeTagOrPoison(resolved_index) catch unreachable));
945810460
9459 // Copy the data10461 // Copy the data
9460 const item = ip.items.get(@intFromEnum(resolved_index));10462 const item = resolved_index.unwrap(ip).getItem(ip);
9461 ip.items.set(@intFromEnum(want_index), item);10463 const unwrapped_index = want_index.unwrap(ip);
946210464 var items = ip.getLocalShared(unwrapped_index.tid).items.acquire().view().slice();
9463 if (std.debug.runtime_safety) {10465 items.items(.data)[unwrapped_index.index] = item.data;
9464 // Make the value unreachable - this is a weird value which will make (incorrect) existing10466 @atomicStore(Tag, &items.items(.tag)[unwrapped_index.index], item.tag, .release);
9465 // references easier to spot10467 ip.remove(tid, resolved_index);
9466 ip.items.set(@intFromEnum(resolved_index), .{
9467 .tag = .simple_value,
9468 .data = @intFromEnum(SimpleValue.@"unreachable"),
9469 });
9470 } else {
9471 // Here we could add the index to a free-list for reuse, but since
9472 // there is so little garbage created this way it's not worth it.
9473 }
9474}10468}
947510469
9476pub fn anonStructFieldTypes(ip: *const InternPool, i: Index) []const Index {10470pub fn anonStructFieldTypes(ip: *const InternPool, i: Index) []const Index {
...@@ -9492,17 +10486,19 @@ pub fn structDecl(ip: *const InternPool, i: Index) OptionalDeclIndex {...@@ -9492,17 +10486,19 @@ pub fn structDecl(ip: *const InternPool, i: Index) OptionalDeclIndex {
9492/// Returns the already-existing field with the same name, if any.10486/// Returns the already-existing field with the same name, if any.
9493pub fn addFieldName(10487pub fn addFieldName(
9494 ip: *InternPool,10488 ip: *InternPool,
10489 extra: Local.Extra,
9495 names_map: MapIndex,10490 names_map: MapIndex,
9496 names_start: u32,10491 names_start: u32,
9497 name: NullTerminatedString,10492 name: NullTerminatedString,
9498) ?u32 {10493) ?u32 {
10494 const extra_items = extra.view().items(.@"0");
9499 const map = &ip.maps.items[@intFromEnum(names_map)];10495 const map = &ip.maps.items[@intFromEnum(names_map)];
9500 const field_index = map.count();10496 const field_index = map.count();
9501 const strings = ip.extra.items[names_start..][0..field_index];10497 const strings = extra_items[names_start..][0..field_index];
9502 const adapter: NullTerminatedString.Adapter = .{ .strings = @ptrCast(strings) };10498 const adapter: NullTerminatedString.Adapter = .{ .strings = @ptrCast(strings) };
9503 const gop = map.getOrPutAssumeCapacityAdapted(name, adapter);10499 const gop = map.getOrPutAssumeCapacityAdapted(name, adapter);
9504 if (gop.found_existing) return @intCast(gop.index);10500 if (gop.found_existing) return @intCast(gop.index);
9505 ip.extra.items[names_start + field_index] = @intFromEnum(name);10501 extra_items[names_start + field_index] = @intFromEnum(name);
9506 return null;10502 return null;
9507}10503}
950810504
src/RangeSet.zig+15-17
...@@ -6,13 +6,11 @@ const InternPool = @import("InternPool.zig");...@@ -6,13 +6,11 @@ const InternPool = @import("InternPool.zig");
6const Type = @import("Type.zig");6const Type = @import("Type.zig");
7const Value = @import("Value.zig");7const Value = @import("Value.zig");
8const Zcu = @import("Zcu.zig");8const Zcu = @import("Zcu.zig");
9/// Deprecated.
10const Module = Zcu;
11const RangeSet = @This();9const RangeSet = @This();
12const LazySrcLoc = Zcu.LazySrcLoc;10const LazySrcLoc = Zcu.LazySrcLoc;
1311
12pt: Zcu.PerThread,
14ranges: std.ArrayList(Range),13ranges: std.ArrayList(Range),
15module: *Module,
1614
17pub const Range = struct {15pub const Range = struct {
18 first: InternPool.Index,16 first: InternPool.Index,
...@@ -20,10 +18,10 @@ pub const Range = struct {...@@ -20,10 +18,10 @@ pub const Range = struct {
20 src: LazySrcLoc,18 src: LazySrcLoc,
21};19};
2220
23pub fn init(allocator: std.mem.Allocator, module: *Module) RangeSet {21pub fn init(allocator: std.mem.Allocator, pt: Zcu.PerThread) RangeSet {
24 return .{22 return .{
23 .pt = pt,
25 .ranges = std.ArrayList(Range).init(allocator),24 .ranges = std.ArrayList(Range).init(allocator),
26 .module = module,
27 };25 };
28}26}
2927
...@@ -37,8 +35,8 @@ pub fn add(...@@ -37,8 +35,8 @@ pub fn add(
37 last: InternPool.Index,35 last: InternPool.Index,
38 src: LazySrcLoc,36 src: LazySrcLoc,
39) !?LazySrcLoc {37) !?LazySrcLoc {
40 const mod = self.module;38 const pt = self.pt;
41 const ip = &mod.intern_pool;39 const ip = &pt.zcu.intern_pool;
4240
43 const ty = ip.typeOf(first);41 const ty = ip.typeOf(first);
44 assert(ty == ip.typeOf(last));42 assert(ty == ip.typeOf(last));
...@@ -47,8 +45,8 @@ pub fn add(...@@ -47,8 +45,8 @@ pub fn add(
47 assert(ty == ip.typeOf(range.first));45 assert(ty == ip.typeOf(range.first));
48 assert(ty == ip.typeOf(range.last));46 assert(ty == ip.typeOf(range.last));
4947
50 if (Value.fromInterned(last).compareScalar(.gte, Value.fromInterned(range.first), Type.fromInterned(ty), mod) and48 if (Value.fromInterned(last).compareScalar(.gte, Value.fromInterned(range.first), Type.fromInterned(ty), pt) and
51 Value.fromInterned(first).compareScalar(.lte, Value.fromInterned(range.last), Type.fromInterned(ty), mod))49 Value.fromInterned(first).compareScalar(.lte, Value.fromInterned(range.last), Type.fromInterned(ty), pt))
52 {50 {
53 return range.src; // They overlap.51 return range.src; // They overlap.
54 }52 }
...@@ -63,20 +61,20 @@ pub fn add(...@@ -63,20 +61,20 @@ pub fn add(
63}61}
6462
65/// Assumes a and b do not overlap63/// Assumes a and b do not overlap
66fn lessThan(mod: *Module, a: Range, b: Range) bool {64fn lessThan(pt: Zcu.PerThread, a: Range, b: Range) bool {
67 const ty = Type.fromInterned(mod.intern_pool.typeOf(a.first));65 const ty = Type.fromInterned(pt.zcu.intern_pool.typeOf(a.first));
68 return Value.fromInterned(a.first).compareScalar(.lt, Value.fromInterned(b.first), ty, mod);66 return Value.fromInterned(a.first).compareScalar(.lt, Value.fromInterned(b.first), ty, pt);
69}67}
7068
71pub fn spans(self: *RangeSet, first: InternPool.Index, last: InternPool.Index) !bool {69pub fn spans(self: *RangeSet, first: InternPool.Index, last: InternPool.Index) !bool {
72 const mod = self.module;70 const pt = self.pt;
73 const ip = &mod.intern_pool;71 const ip = &pt.zcu.intern_pool;
74 assert(ip.typeOf(first) == ip.typeOf(last));72 assert(ip.typeOf(first) == ip.typeOf(last));
7573
76 if (self.ranges.items.len == 0)74 if (self.ranges.items.len == 0)
77 return false;75 return false;
7876
79 std.mem.sort(Range, self.ranges.items, mod, lessThan);77 std.mem.sort(Range, self.ranges.items, pt, lessThan);
8078
81 if (self.ranges.items[0].first != first or79 if (self.ranges.items[0].first != first or
82 self.ranges.items[self.ranges.items.len - 1].last != last)80 self.ranges.items[self.ranges.items.len - 1].last != last)
...@@ -95,10 +93,10 @@ pub fn spans(self: *RangeSet, first: InternPool.Index, last: InternPool.Index) !...@@ -95,10 +93,10 @@ pub fn spans(self: *RangeSet, first: InternPool.Index, last: InternPool.Index) !
95 const prev = self.ranges.items[i];93 const prev = self.ranges.items[i];
9694
97 // prev.last + 1 == cur.first95 // prev.last + 1 == cur.first
98 try counter.copy(Value.fromInterned(prev.last).toBigInt(&space, mod));96 try counter.copy(Value.fromInterned(prev.last).toBigInt(&space, pt));
99 try counter.addScalar(&counter, 1);97 try counter.addScalar(&counter, 1);
10098
101 const cur_start_int = Value.fromInterned(cur.first).toBigInt(&space, mod);99 const cur_start_int = Value.fromInterned(cur.first).toBigInt(&space, pt);
102 if (!cur_start_int.eql(counter.toConst())) {100 if (!cur_start_int.eql(counter.toConst())) {
103 return false;101 return false;
104 }102 }
src/Sema.zig+2820-2425
...@@ -5,7 +5,7 @@...@@ -5,7 +5,7 @@
5//! Does type checking, comptime control flow, and safety-check generation.5//! Does type checking, comptime control flow, and safety-check generation.
6//! This is the the heart of the Zig compiler.6//! This is the the heart of the Zig compiler.
77
8mod: *Module,8pt: Zcu.PerThread,
9/// Alias to `mod.gpa`.9/// Alias to `mod.gpa`.
10gpa: Allocator,10gpa: Allocator,
11/// Points to the temporary arena allocator of the Sema.11/// Points to the temporary arena allocator of the Sema.
...@@ -146,7 +146,7 @@ const ComptimeAlloc = struct {...@@ -146,7 +146,7 @@ const ComptimeAlloc = struct {
146fn newComptimeAlloc(sema: *Sema, block: *Block, ty: Type, alignment: Alignment) !ComptimeAllocIndex {146fn newComptimeAlloc(sema: *Sema, block: *Block, ty: Type, alignment: Alignment) !ComptimeAllocIndex {
147 const idx = sema.comptime_allocs.items.len;147 const idx = sema.comptime_allocs.items.len;
148 try sema.comptime_allocs.append(sema.gpa, .{148 try sema.comptime_allocs.append(sema.gpa, .{
149 .val = .{ .interned = try sema.mod.intern(.{ .undef = ty.toIntern() }) },149 .val = .{ .interned = try sema.pt.intern(.{ .undef = ty.toIntern() }) },
150 .is_const = false,150 .is_const = false,
151 .alignment = alignment,151 .alignment = alignment,
152 .runtime_index = block.runtime_index,152 .runtime_index = block.runtime_index,
...@@ -433,7 +433,7 @@ pub const Block = struct {...@@ -433,7 +433,7 @@ pub const Block = struct {
433433
434 fn explain(cr: ComptimeReason, sema: *Sema, msg: ?*Module.ErrorMsg) !void {434 fn explain(cr: ComptimeReason, sema: *Sema, msg: ?*Module.ErrorMsg) !void {
435 const parent = msg orelse return;435 const parent = msg orelse return;
436 const mod = sema.mod;436 const pt = sema.pt;
437 const prefix = "expression is evaluated at comptime because ";437 const prefix = "expression is evaluated at comptime because ";
438 switch (cr) {438 switch (cr) {
439 .c_import => |ci| {439 .c_import => |ci| {
...@@ -451,7 +451,7 @@ pub const Block = struct {...@@ -451,7 +451,7 @@ pub const Block = struct {
451 ret_ty_src,451 ret_ty_src,
452 parent,452 parent,
453 prefix ++ "the function returns a comptime-only type '{}'",453 prefix ++ "the function returns a comptime-only type '{}'",
454 .{rt.return_ty.fmt(mod)},454 .{rt.return_ty.fmt(pt)},
455 );455 );
456 try sema.explainWhyTypeIsComptime(parent, ret_ty_src, rt.return_ty);456 try sema.explainWhyTypeIsComptime(parent, ret_ty_src, rt.return_ty);
457 },457 },
...@@ -538,7 +538,7 @@ pub const Block = struct {...@@ -538,7 +538,7 @@ pub const Block = struct {
538 }538 }
539539
540 pub fn wantSafety(block: *const Block) bool {540 pub fn wantSafety(block: *const Block) bool {
541 return block.want_safety orelse switch (block.sema.mod.optimizeMode()) {541 return block.want_safety orelse switch (block.sema.pt.zcu.optimizeMode()) {
542 .Debug => true,542 .Debug => true,
543 .ReleaseSafe => true,543 .ReleaseSafe => true,
544 .ReleaseFast => false,544 .ReleaseFast => false,
...@@ -737,11 +737,12 @@ pub const Block = struct {...@@ -737,11 +737,12 @@ pub const Block = struct {
737737
738 fn addCmpVector(block: *Block, lhs: Air.Inst.Ref, rhs: Air.Inst.Ref, cmp_op: std.math.CompareOperator) !Air.Inst.Ref {738 fn addCmpVector(block: *Block, lhs: Air.Inst.Ref, rhs: Air.Inst.Ref, cmp_op: std.math.CompareOperator) !Air.Inst.Ref {
739 const sema = block.sema;739 const sema = block.sema;
740 const mod = sema.mod;740 const pt = sema.pt;
741 const mod = pt.zcu;
741 return block.addInst(.{742 return block.addInst(.{
742 .tag = if (block.float_mode == .optimized) .cmp_vector_optimized else .cmp_vector,743 .tag = if (block.float_mode == .optimized) .cmp_vector_optimized else .cmp_vector,
743 .data = .{ .ty_pl = .{744 .data = .{ .ty_pl = .{
744 .ty = Air.internedToRef((try mod.vectorType(.{745 .ty = Air.internedToRef((try pt.vectorType(.{
745 .len = sema.typeOf(lhs).vectorLen(mod),746 .len = sema.typeOf(lhs).vectorLen(mod),
746 .child = .bool_type,747 .child = .bool_type,
747 })).toIntern()),748 })).toIntern()),
...@@ -829,14 +830,14 @@ pub const Block = struct {...@@ -829,14 +830,14 @@ pub const Block = struct {
829 }830 }
830831
831 pub fn ownerModule(block: Block) *Package.Module {832 pub fn ownerModule(block: Block) *Package.Module {
832 const zcu = block.sema.mod;833 const zcu = block.sema.pt.zcu;
833 return zcu.namespacePtr(block.namespace).fileScope(zcu).mod;834 return zcu.namespacePtr(block.namespace).fileScope(zcu).mod;
834 }835 }
835836
836 fn trackZir(block: *Block, inst: Zir.Inst.Index) Allocator.Error!InternPool.TrackedInst.Index {837 fn trackZir(block: *Block, inst: Zir.Inst.Index) Allocator.Error!InternPool.TrackedInst.Index {
837 const sema = block.sema;838 const sema = block.sema;
838 const gpa = sema.gpa;839 const gpa = sema.gpa;
839 const zcu = sema.mod;840 const zcu = sema.pt.zcu;
840 const ip = &zcu.intern_pool;841 const ip = &zcu.intern_pool;
841 const file_index = block.getFileScopeIndex(zcu);842 const file_index = block.getFileScopeIndex(zcu);
842 return ip.trackZir(gpa, file_index, inst);843 return ip.trackZir(gpa, file_index, inst);
...@@ -992,7 +993,8 @@ fn analyzeBodyInner(...@@ -992,7 +993,8 @@ fn analyzeBodyInner(
992993
993 try sema.inst_map.ensureSpaceForInstructions(sema.gpa, body);994 try sema.inst_map.ensureSpaceForInstructions(sema.gpa, body);
994995
995 const zcu = sema.mod;996 const pt = sema.pt;
997 const zcu = pt.zcu;
996 const map = &sema.inst_map;998 const map = &sema.inst_map;
997 const tags = sema.code.instructions.items(.tag);999 const tags = sema.code.instructions.items(.tag);
998 const datas = sema.code.instructions.items(.data);1000 const datas = sema.code.instructions.items(.data);
...@@ -1777,7 +1779,7 @@ fn analyzeBodyInner(...@@ -1777,7 +1779,7 @@ fn analyzeBodyInner(
1777 const err_union_ty = sema.typeOf(err_union);1779 const err_union_ty = sema.typeOf(err_union);
1778 if (err_union_ty.zigTypeTag(zcu) != .ErrorUnion) {1780 if (err_union_ty.zigTypeTag(zcu) != .ErrorUnion) {
1779 return sema.fail(block, operand_src, "expected error union type, found '{}'", .{1781 return sema.fail(block, operand_src, "expected error union type, found '{}'", .{
1780 err_union_ty.fmt(zcu),1782 err_union_ty.fmt(pt),
1781 });1783 });
1782 }1784 }
1783 const is_non_err = try sema.analyzeIsNonErrComptimeOnly(block, operand_src, err_union);1785 const is_non_err = try sema.analyzeIsNonErrComptimeOnly(block, operand_src, err_union);
...@@ -1910,10 +1912,11 @@ pub fn toConstString(...@@ -1910,10 +1912,11 @@ pub fn toConstString(
1910 air_inst: Air.Inst.Ref,1912 air_inst: Air.Inst.Ref,
1911 reason: NeededComptimeReason,1913 reason: NeededComptimeReason,
1912) ![]u8 {1914) ![]u8 {
1915 const pt = sema.pt;
1913 const coerced_inst = try sema.coerce(block, Type.slice_const_u8, air_inst, src);1916 const coerced_inst = try sema.coerce(block, Type.slice_const_u8, air_inst, src);
1914 const slice_val = try sema.resolveConstDefinedValue(block, src, coerced_inst, reason);1917 const slice_val = try sema.resolveConstDefinedValue(block, src, coerced_inst, reason);
1915 const arr_val = try sema.derefSliceAsArray(block, src, slice_val, reason);1918 const arr_val = try sema.derefSliceAsArray(block, src, slice_val, reason);
1916 return arr_val.toAllocatedBytes(arr_val.typeOf(sema.mod), sema.arena, sema.mod);1919 return arr_val.toAllocatedBytes(arr_val.typeOf(pt.zcu), sema.arena, pt);
1917}1920}
19181921
1919pub fn resolveConstStringIntern(1922pub fn resolveConstStringIntern(
...@@ -1945,7 +1948,8 @@ fn resolveDestType(...@@ -1945,7 +1948,8 @@ fn resolveDestType(
1945 strat: enum { remove_eu_opt, remove_eu, remove_opt },1948 strat: enum { remove_eu_opt, remove_eu, remove_opt },
1946 builtin_name: []const u8,1949 builtin_name: []const u8,
1947) !Type {1950) !Type {
1948 const mod = sema.mod;1951 const pt = sema.pt;
1952 const mod = pt.zcu;
1949 const remove_eu = switch (strat) {1953 const remove_eu = switch (strat) {
1950 .remove_eu_opt, .remove_eu => true,1954 .remove_eu_opt, .remove_eu => true,
1951 .remove_opt => false,1955 .remove_opt => false,
...@@ -2062,7 +2066,8 @@ fn analyzeAsType(...@@ -2062,7 +2066,8 @@ fn analyzeAsType(
2062}2066}
20632067
2064pub fn setupErrorReturnTrace(sema: *Sema, block: *Block, last_arg_index: usize) !void {2068pub fn setupErrorReturnTrace(sema: *Sema, block: *Block, last_arg_index: usize) !void {
2065 const mod = sema.mod;2069 const pt = sema.pt;
2070 const mod = pt.zcu;
2066 const comp = mod.comp;2071 const comp = mod.comp;
2067 const gpa = sema.gpa;2072 const gpa = sema.gpa;
2068 const ip = &mod.intern_pool;2073 const ip = &mod.intern_pool;
...@@ -2076,24 +2081,24 @@ pub fn setupErrorReturnTrace(sema: *Sema, block: *Block, last_arg_index: usize)...@@ -2076,24 +2081,24 @@ pub fn setupErrorReturnTrace(sema: *Sema, block: *Block, last_arg_index: usize)
20762081
2077 // var addrs: [err_return_trace_addr_count]usize = undefined;2082 // var addrs: [err_return_trace_addr_count]usize = undefined;
2078 const err_return_trace_addr_count = 32;2083 const err_return_trace_addr_count = 32;
2079 const addr_arr_ty = try mod.arrayType(.{2084 const addr_arr_ty = try pt.arrayType(.{
2080 .len = err_return_trace_addr_count,2085 .len = err_return_trace_addr_count,
2081 .child = .usize_type,2086 .child = .usize_type,
2082 });2087 });
2083 const addrs_ptr = try err_trace_block.addTy(.alloc, try mod.singleMutPtrType(addr_arr_ty));2088 const addrs_ptr = try err_trace_block.addTy(.alloc, try pt.singleMutPtrType(addr_arr_ty));
20842089
2085 // var st: StackTrace = undefined;2090 // var st: StackTrace = undefined;
2086 const stack_trace_ty = try mod.getBuiltinType("StackTrace");2091 const stack_trace_ty = try pt.getBuiltinType("StackTrace");
2087 try stack_trace_ty.resolveFields(mod);2092 try stack_trace_ty.resolveFields(pt);
2088 const st_ptr = try err_trace_block.addTy(.alloc, try mod.singleMutPtrType(stack_trace_ty));2093 const st_ptr = try err_trace_block.addTy(.alloc, try pt.singleMutPtrType(stack_trace_ty));
20892094
2090 // st.instruction_addresses = &addrs;2095 // st.instruction_addresses = &addrs;
2091 const instruction_addresses_field_name = try ip.getOrPutString(gpa, "instruction_addresses", .no_embedded_nulls);2096 const instruction_addresses_field_name = try ip.getOrPutString(gpa, pt.tid, "instruction_addresses", .no_embedded_nulls);
2092 const addr_field_ptr = try sema.fieldPtr(&err_trace_block, src, st_ptr, instruction_addresses_field_name, src, true);2097 const addr_field_ptr = try sema.fieldPtr(&err_trace_block, src, st_ptr, instruction_addresses_field_name, src, true);
2093 try sema.storePtr2(&err_trace_block, src, addr_field_ptr, src, addrs_ptr, src, .store);2098 try sema.storePtr2(&err_trace_block, src, addr_field_ptr, src, addrs_ptr, src, .store);
20942099
2095 // st.index = 0;2100 // st.index = 0;
2096 const index_field_name = try ip.getOrPutString(gpa, "index", .no_embedded_nulls);2101 const index_field_name = try ip.getOrPutString(gpa, pt.tid, "index", .no_embedded_nulls);
2097 const index_field_ptr = try sema.fieldPtr(&err_trace_block, src, st_ptr, index_field_name, src, true);2102 const index_field_ptr = try sema.fieldPtr(&err_trace_block, src, st_ptr, index_field_name, src, true);
2098 try sema.storePtr2(&err_trace_block, src, index_field_ptr, src, .zero_usize, src, .store);2103 try sema.storePtr2(&err_trace_block, src, index_field_ptr, src, .zero_usize, src, .store);
20992104
...@@ -2109,7 +2114,7 @@ pub fn setupErrorReturnTrace(sema: *Sema, block: *Block, last_arg_index: usize)...@@ -2109,7 +2114,7 @@ pub fn setupErrorReturnTrace(sema: *Sema, block: *Block, last_arg_index: usize)
2109fn resolveValue(sema: *Sema, inst: Air.Inst.Ref) CompileError!?Value {2114fn resolveValue(sema: *Sema, inst: Air.Inst.Ref) CompileError!?Value {
2110 const val = (try sema.resolveValueAllowVariables(inst)) orelse return null;2115 const val = (try sema.resolveValueAllowVariables(inst)) orelse return null;
2111 if (val.isGenericPoison()) return error.GenericPoison;2116 if (val.isGenericPoison()) return error.GenericPoison;
2112 if (sema.mod.intern_pool.isVariable(val.toIntern())) return null;2117 if (sema.pt.zcu.intern_pool.isVariable(val.toIntern())) return null;
2113 return val;2118 return val;
2114}2119}
21152120
...@@ -2133,7 +2138,8 @@ fn resolveDefinedValue(...@@ -2133,7 +2138,8 @@ fn resolveDefinedValue(
2133 src: LazySrcLoc,2138 src: LazySrcLoc,
2134 air_ref: Air.Inst.Ref,2139 air_ref: Air.Inst.Ref,
2135) CompileError!?Value {2140) CompileError!?Value {
2136 const mod = sema.mod;2141 const pt = sema.pt;
2142 const mod = pt.zcu;
2137 const val = try sema.resolveValue(air_ref) orelse return null;2143 const val = try sema.resolveValue(air_ref) orelse return null;
2138 if (val.isUndef(mod)) {2144 if (val.isUndef(mod)) {
2139 return sema.failWithUseOfUndef(block, src);2145 return sema.failWithUseOfUndef(block, src);
...@@ -2150,7 +2156,7 @@ fn resolveConstDefinedValue(...@@ -2150,7 +2156,7 @@ fn resolveConstDefinedValue(
2150 reason: NeededComptimeReason,2156 reason: NeededComptimeReason,
2151) CompileError!Value {2157) CompileError!Value {
2152 const val = try sema.resolveConstValue(block, src, air_ref, reason);2158 const val = try sema.resolveConstValue(block, src, air_ref, reason);
2153 if (val.isUndef(sema.mod)) return sema.failWithUseOfUndef(block, src);2159 if (val.isUndef(sema.pt.zcu)) return sema.failWithUseOfUndef(block, src);
2154 return val;2160 return val;
2155}2161}
21562162
...@@ -2164,7 +2170,7 @@ fn resolveValueResolveLazy(sema: *Sema, inst: Air.Inst.Ref) CompileError!?Value...@@ -2164,7 +2170,7 @@ fn resolveValueResolveLazy(sema: *Sema, inst: Air.Inst.Ref) CompileError!?Value
2164/// Lazy values are recursively resolved.2170/// Lazy values are recursively resolved.
2165fn resolveValueIntable(sema: *Sema, inst: Air.Inst.Ref) CompileError!?Value {2171fn resolveValueIntable(sema: *Sema, inst: Air.Inst.Ref) CompileError!?Value {
2166 const val = (try sema.resolveValue(inst)) orelse return null;2172 const val = (try sema.resolveValue(inst)) orelse return null;
2167 if (sema.mod.intern_pool.getBackingAddrTag(val.toIntern())) |addr| switch (addr) {2173 if (sema.pt.zcu.intern_pool.getBackingAddrTag(val.toIntern())) |addr| switch (addr) {
2168 .decl, .anon_decl, .comptime_alloc, .comptime_field => return null,2174 .decl, .anon_decl, .comptime_alloc, .comptime_field => return null,
2169 .int => {},2175 .int => {},
2170 .eu_payload, .opt_payload, .arr_elem, .field => unreachable,2176 .eu_payload, .opt_payload, .arr_elem, .field => unreachable,
...@@ -2174,6 +2180,7 @@ fn resolveValueIntable(sema: *Sema, inst: Air.Inst.Ref) CompileError!?Value {...@@ -2174,6 +2180,7 @@ fn resolveValueIntable(sema: *Sema, inst: Air.Inst.Ref) CompileError!?Value {
21742180
2175/// Returns all InternPool keys representing values, including `variable`, `undef`, and `generic_poison`.2181/// Returns all InternPool keys representing values, including `variable`, `undef`, and `generic_poison`.
2176fn resolveValueAllowVariables(sema: *Sema, inst: Air.Inst.Ref) CompileError!?Value {2182fn resolveValueAllowVariables(sema: *Sema, inst: Air.Inst.Ref) CompileError!?Value {
2183 const pt = sema.pt;
2177 assert(inst != .none);2184 assert(inst != .none);
2178 // First section of indexes correspond to a set number of constant values.2185 // First section of indexes correspond to a set number of constant values.
2179 if (@intFromEnum(inst) < InternPool.static_len) {2186 if (@intFromEnum(inst) < InternPool.static_len) {
...@@ -2184,7 +2191,7 @@ fn resolveValueAllowVariables(sema: *Sema, inst: Air.Inst.Ref) CompileError!?Val...@@ -2184,7 +2191,7 @@ fn resolveValueAllowVariables(sema: *Sema, inst: Air.Inst.Ref) CompileError!?Val
2184 if (try sema.typeHasOnePossibleValue(sema.typeOf(inst))) |opv| {2191 if (try sema.typeHasOnePossibleValue(sema.typeOf(inst))) |opv| {
2185 if (inst.toInterned()) |ip_index| {2192 if (inst.toInterned()) |ip_index| {
2186 const val = Value.fromInterned(ip_index);2193 const val = Value.fromInterned(ip_index);
2187 if (val.getVariable(sema.mod) != null) return val;2194 if (val.getVariable(pt.zcu) != null) return val;
2188 }2195 }
2189 return opv;2196 return opv;
2190 }2197 }
...@@ -2196,7 +2203,7 @@ fn resolveValueAllowVariables(sema: *Sema, inst: Air.Inst.Ref) CompileError!?Val...@@ -2196,7 +2203,7 @@ fn resolveValueAllowVariables(sema: *Sema, inst: Air.Inst.Ref) CompileError!?Val
2196 }2203 }
2197 };2204 };
2198 const val = Value.fromInterned(ip_index);2205 const val = Value.fromInterned(ip_index);
2199 if (val.isPtrToThreadLocal(sema.mod)) return null;2206 if (val.isPtrToThreadLocal(pt.zcu)) return null;
2200 return val;2207 return val;
2201}2208}
22022209
...@@ -2225,7 +2232,7 @@ pub fn resolveFinalDeclValue(...@@ -2225,7 +2232,7 @@ pub fn resolveFinalDeclValue(
2225 });2232 });
2226 };2233 };
2227 if (val.isGenericPoison()) return error.GenericPoison;2234 if (val.isGenericPoison()) return error.GenericPoison;
2228 if (val.canMutateComptimeVarState(sema.mod)) {2235 if (val.canMutateComptimeVarState(sema.pt.zcu)) {
2229 return sema.fail(block, src, "global variable contains reference to comptime var", .{});2236 return sema.fail(block, src, "global variable contains reference to comptime var", .{});
2230 }2237 }
2231 return val;2238 return val;
...@@ -2254,19 +2261,20 @@ fn failWithDivideByZero(sema: *Sema, block: *Block, src: LazySrcLoc) CompileErro...@@ -2254,19 +2261,20 @@ fn failWithDivideByZero(sema: *Sema, block: *Block, src: LazySrcLoc) CompileErro
2254}2261}
22552262
2256fn failWithModRemNegative(sema: *Sema, block: *Block, src: LazySrcLoc, lhs_ty: Type, rhs_ty: Type) CompileError {2263fn failWithModRemNegative(sema: *Sema, block: *Block, src: LazySrcLoc, lhs_ty: Type, rhs_ty: Type) CompileError {
2264 const pt = sema.pt;
2257 return sema.fail(block, src, "remainder division with '{}' and '{}': signed integers and floats must use @rem or @mod", .{2265 return sema.fail(block, src, "remainder division with '{}' and '{}': signed integers and floats must use @rem or @mod", .{
2258 lhs_ty.fmt(sema.mod), rhs_ty.fmt(sema.mod),2266 lhs_ty.fmt(pt), rhs_ty.fmt(pt),
2259 });2267 });
2260}2268}
22612269
2262fn failWithExpectedOptionalType(sema: *Sema, block: *Block, src: LazySrcLoc, non_optional_ty: Type) CompileError {2270fn failWithExpectedOptionalType(sema: *Sema, block: *Block, src: LazySrcLoc, non_optional_ty: Type) CompileError {
2263 const mod = sema.mod;2271 const pt = sema.pt;
2264 const msg = msg: {2272 const msg = msg: {
2265 const msg = try sema.errMsg(src, "expected optional type, found '{}'", .{2273 const msg = try sema.errMsg(src, "expected optional type, found '{}'", .{
2266 non_optional_ty.fmt(mod),2274 non_optional_ty.fmt(pt),
2267 });2275 });
2268 errdefer msg.destroy(sema.gpa);2276 errdefer msg.destroy(sema.gpa);
2269 if (non_optional_ty.zigTypeTag(mod) == .ErrorUnion) {2277 if (non_optional_ty.zigTypeTag(pt.zcu) == .ErrorUnion) {
2270 try sema.errNote(src, msg, "consider using 'try', 'catch', or 'if'", .{});2278 try sema.errNote(src, msg, "consider using 'try', 'catch', or 'if'", .{});
2271 }2279 }
2272 try addDeclaredHereNote(sema, msg, non_optional_ty);2280 try addDeclaredHereNote(sema, msg, non_optional_ty);
...@@ -2276,14 +2284,14 @@ fn failWithExpectedOptionalType(sema: *Sema, block: *Block, src: LazySrcLoc, non...@@ -2276,14 +2284,14 @@ fn failWithExpectedOptionalType(sema: *Sema, block: *Block, src: LazySrcLoc, non
2276}2284}
22772285
2278fn failWithArrayInitNotSupported(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type) CompileError {2286fn failWithArrayInitNotSupported(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type) CompileError {
2279 const mod = sema.mod;2287 const pt = sema.pt;
2280 const msg = msg: {2288 const msg = msg: {
2281 const msg = try sema.errMsg(src, "type '{}' does not support array initialization syntax", .{2289 const msg = try sema.errMsg(src, "type '{}' does not support array initialization syntax", .{
2282 ty.fmt(mod),2290 ty.fmt(pt),
2283 });2291 });
2284 errdefer msg.destroy(sema.gpa);2292 errdefer msg.destroy(sema.gpa);
2285 if (ty.isSlice(mod)) {2293 if (ty.isSlice(pt.zcu)) {
2286 try sema.errNote(src, msg, "inferred array length is specified with an underscore: '[_]{}'", .{ty.elemType2(mod).fmt(mod)});2294 try sema.errNote(src, msg, "inferred array length is specified with an underscore: '[_]{}'", .{ty.elemType2(pt.zcu).fmt(pt)});
2287 }2295 }
2288 break :msg msg;2296 break :msg msg;
2289 };2297 };
...@@ -2291,8 +2299,9 @@ fn failWithArrayInitNotSupported(sema: *Sema, block: *Block, src: LazySrcLoc, ty...@@ -2291,8 +2299,9 @@ fn failWithArrayInitNotSupported(sema: *Sema, block: *Block, src: LazySrcLoc, ty
2291}2299}
22922300
2293fn failWithStructInitNotSupported(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type) CompileError {2301fn failWithStructInitNotSupported(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type) CompileError {
2302 const pt = sema.pt;
2294 return sema.fail(block, src, "type '{}' does not support struct initialization syntax", .{2303 return sema.fail(block, src, "type '{}' does not support struct initialization syntax", .{
2295 ty.fmt(sema.mod),2304 ty.fmt(pt),
2296 });2305 });
2297}2306}
22982307
...@@ -2303,17 +2312,19 @@ fn failWithErrorSetCodeMissing(...@@ -2303,17 +2312,19 @@ fn failWithErrorSetCodeMissing(
2303 dest_err_set_ty: Type,2312 dest_err_set_ty: Type,
2304 src_err_set_ty: Type,2313 src_err_set_ty: Type,
2305) CompileError {2314) CompileError {
2315 const pt = sema.pt;
2306 return sema.fail(block, src, "expected type '{}', found type '{}'", .{2316 return sema.fail(block, src, "expected type '{}', found type '{}'", .{
2307 dest_err_set_ty.fmt(sema.mod), src_err_set_ty.fmt(sema.mod),2317 dest_err_set_ty.fmt(pt), src_err_set_ty.fmt(pt),
2308 });2318 });
2309}2319}
23102320
2311fn failWithIntegerOverflow(sema: *Sema, block: *Block, src: LazySrcLoc, int_ty: Type, val: Value, vector_index: usize) CompileError {2321fn failWithIntegerOverflow(sema: *Sema, block: *Block, src: LazySrcLoc, int_ty: Type, val: Value, vector_index: usize) CompileError {
2312 const zcu = sema.mod;2322 const pt = sema.pt;
2323 const zcu = pt.zcu;
2313 if (int_ty.zigTypeTag(zcu) == .Vector) {2324 if (int_ty.zigTypeTag(zcu) == .Vector) {
2314 const msg = msg: {2325 const msg = msg: {
2315 const msg = try sema.errMsg(src, "overflow of vector type '{}' with value '{}'", .{2326 const msg = try sema.errMsg(src, "overflow of vector type '{}' with value '{}'", .{
2316 int_ty.fmt(zcu), val.fmtValue(zcu, sema),2327 int_ty.fmt(pt), val.fmtValue(pt, sema),
2317 });2328 });
2318 errdefer msg.destroy(sema.gpa);2329 errdefer msg.destroy(sema.gpa);
2319 try sema.errNote(src, msg, "when computing vector element at index '{d}'", .{vector_index});2330 try sema.errNote(src, msg, "when computing vector element at index '{d}'", .{vector_index});
...@@ -2322,12 +2333,13 @@ fn failWithIntegerOverflow(sema: *Sema, block: *Block, src: LazySrcLoc, int_ty:...@@ -2322,12 +2333,13 @@ fn failWithIntegerOverflow(sema: *Sema, block: *Block, src: LazySrcLoc, int_ty:
2322 return sema.failWithOwnedErrorMsg(block, msg);2333 return sema.failWithOwnedErrorMsg(block, msg);
2323 }2334 }
2324 return sema.fail(block, src, "overflow of integer type '{}' with value '{}'", .{2335 return sema.fail(block, src, "overflow of integer type '{}' with value '{}'", .{
2325 int_ty.fmt(zcu), val.fmtValue(zcu, sema),2336 int_ty.fmt(pt), val.fmtValue(pt, sema),
2326 });2337 });
2327}2338}
23282339
2329fn failWithInvalidComptimeFieldStore(sema: *Sema, block: *Block, init_src: LazySrcLoc, container_ty: Type, field_index: usize) CompileError {2340fn failWithInvalidComptimeFieldStore(sema: *Sema, block: *Block, init_src: LazySrcLoc, container_ty: Type, field_index: usize) CompileError {
2330 const mod = sema.mod;2341 const pt = sema.pt;
2342 const mod = pt.zcu;
2331 const msg = msg: {2343 const msg = msg: {
2332 const msg = try sema.errMsg(init_src, "value stored in comptime field does not match the default value of the field", .{});2344 const msg = try sema.errMsg(init_src, "value stored in comptime field does not match the default value of the field", .{});
2333 errdefer msg.destroy(sema.gpa);2345 errdefer msg.destroy(sema.gpa);
...@@ -2358,14 +2370,15 @@ fn failWithInvalidFieldAccess(...@@ -2358,14 +2370,15 @@ fn failWithInvalidFieldAccess(
2358 object_ty: Type,2370 object_ty: Type,
2359 field_name: InternPool.NullTerminatedString,2371 field_name: InternPool.NullTerminatedString,
2360) CompileError {2372) CompileError {
2361 const mod = sema.mod;2373 const pt = sema.pt;
2374 const mod = pt.zcu;
2362 const inner_ty = if (object_ty.isSinglePointer(mod)) object_ty.childType(mod) else object_ty;2375 const inner_ty = if (object_ty.isSinglePointer(mod)) object_ty.childType(mod) else object_ty;
23632376
2364 if (inner_ty.zigTypeTag(mod) == .Optional) opt: {2377 if (inner_ty.zigTypeTag(mod) == .Optional) opt: {
2365 const child_ty = inner_ty.optionalChild(mod);2378 const child_ty = inner_ty.optionalChild(mod);
2366 if (!typeSupportsFieldAccess(mod, child_ty, field_name)) break :opt;2379 if (!typeSupportsFieldAccess(mod, child_ty, field_name)) break :opt;
2367 const msg = msg: {2380 const msg = msg: {
2368 const msg = try sema.errMsg(src, "optional type '{}' does not support field access", .{object_ty.fmt(sema.mod)});2381 const msg = try sema.errMsg(src, "optional type '{}' does not support field access", .{object_ty.fmt(pt)});
2369 errdefer msg.destroy(sema.gpa);2382 errdefer msg.destroy(sema.gpa);
2370 try sema.errNote(src, msg, "consider using '.?', 'orelse', or 'if'", .{});2383 try sema.errNote(src, msg, "consider using '.?', 'orelse', or 'if'", .{});
2371 break :msg msg;2384 break :msg msg;
...@@ -2375,14 +2388,14 @@ fn failWithInvalidFieldAccess(...@@ -2375,14 +2388,14 @@ fn failWithInvalidFieldAccess(
2375 const child_ty = inner_ty.errorUnionPayload(mod);2388 const child_ty = inner_ty.errorUnionPayload(mod);
2376 if (!typeSupportsFieldAccess(mod, child_ty, field_name)) break :err;2389 if (!typeSupportsFieldAccess(mod, child_ty, field_name)) break :err;
2377 const msg = msg: {2390 const msg = msg: {
2378 const msg = try sema.errMsg(src, "error union type '{}' does not support field access", .{object_ty.fmt(sema.mod)});2391 const msg = try sema.errMsg(src, "error union type '{}' does not support field access", .{object_ty.fmt(pt)});
2379 errdefer msg.destroy(sema.gpa);2392 errdefer msg.destroy(sema.gpa);
2380 try sema.errNote(src, msg, "consider using 'try', 'catch', or 'if'", .{});2393 try sema.errNote(src, msg, "consider using 'try', 'catch', or 'if'", .{});
2381 break :msg msg;2394 break :msg msg;
2382 };2395 };
2383 return sema.failWithOwnedErrorMsg(block, msg);2396 return sema.failWithOwnedErrorMsg(block, msg);
2384 }2397 }
2385 return sema.fail(block, src, "type '{}' does not support field access", .{object_ty.fmt(sema.mod)});2398 return sema.fail(block, src, "type '{}' does not support field access", .{object_ty.fmt(pt)});
2386}2399}
23872400
2388fn typeSupportsFieldAccess(mod: *const Module, ty: Type, field_name: InternPool.NullTerminatedString) bool {2401fn typeSupportsFieldAccess(mod: *const Module, ty: Type, field_name: InternPool.NullTerminatedString) bool {
...@@ -2408,7 +2421,8 @@ fn failWithComptimeErrorRetTrace(...@@ -2408,7 +2421,8 @@ fn failWithComptimeErrorRetTrace(
2408 src: LazySrcLoc,2421 src: LazySrcLoc,
2409 name: InternPool.NullTerminatedString,2422 name: InternPool.NullTerminatedString,
2410) CompileError {2423) CompileError {
2411 const mod = sema.mod;2424 const pt = sema.pt;
2425 const mod = pt.zcu;
2412 const msg = msg: {2426 const msg = msg: {
2413 const msg = try sema.errMsg(src, "caught unexpected error '{}'", .{name.fmt(&mod.intern_pool)});2427 const msg = try sema.errMsg(src, "caught unexpected error '{}'", .{name.fmt(&mod.intern_pool)});
2414 errdefer msg.destroy(sema.gpa);2428 errdefer msg.destroy(sema.gpa);
...@@ -2430,7 +2444,7 @@ pub fn errNote(...@@ -2430,7 +2444,7 @@ pub fn errNote(
2430 comptime format: []const u8,2444 comptime format: []const u8,
2431 args: anytype,2445 args: anytype,
2432) error{OutOfMemory}!void {2446) error{OutOfMemory}!void {
2433 return sema.mod.errNote(src, parent, format, args);2447 return sema.pt.zcu.errNote(src, parent, format, args);
2434}2448}
24352449
2436fn addFieldErrNote(2450fn addFieldErrNote(
...@@ -2442,8 +2456,7 @@ fn addFieldErrNote(...@@ -2442,8 +2456,7 @@ fn addFieldErrNote(
2442 args: anytype,2456 args: anytype,
2443) !void {2457) !void {
2444 @setCold(true);2458 @setCold(true);
2445 const zcu = sema.mod;2459 const type_src = container_ty.srcLocOrNull(sema.pt.zcu) orelse return;
2446 const type_src = container_ty.srcLocOrNull(zcu) orelse return;
2447 const field_src: LazySrcLoc = .{2460 const field_src: LazySrcLoc = .{
2448 .base_node_inst = type_src.base_node_inst,2461 .base_node_inst = type_src.base_node_inst,
2449 .offset = .{ .container_field_name = @intCast(field_index) },2462 .offset = .{ .container_field_name = @intCast(field_index) },
...@@ -2480,7 +2493,7 @@ pub fn fail(...@@ -2480,7 +2493,7 @@ pub fn fail(
2480pub fn failWithOwnedErrorMsg(sema: *Sema, block: ?*Block, err_msg: *Module.ErrorMsg) error{ AnalysisFail, OutOfMemory } {2493pub fn failWithOwnedErrorMsg(sema: *Sema, block: ?*Block, err_msg: *Module.ErrorMsg) error{ AnalysisFail, OutOfMemory } {
2481 @setCold(true);2494 @setCold(true);
2482 const gpa = sema.gpa;2495 const gpa = sema.gpa;
2483 const mod = sema.mod;2496 const mod = sema.pt.zcu;
2484 const ip = &mod.intern_pool;2497 const ip = &mod.intern_pool;
24852498
2486 if (build_options.enable_debug_extensions and mod.comp.debug_compile_errors) {2499 if (build_options.enable_debug_extensions and mod.comp.debug_compile_errors) {
...@@ -2545,8 +2558,7 @@ fn reparentOwnedErrorMsg(...@@ -2545,8 +2558,7 @@ fn reparentOwnedErrorMsg(
2545 comptime format: []const u8,2558 comptime format: []const u8,
2546 args: anytype,2559 args: anytype,
2547) !void {2560) !void {
2548 const mod = sema.mod;2561 const msg_str = try std.fmt.allocPrint(sema.gpa, format, args);
2549 const msg_str = try std.fmt.allocPrint(mod.gpa, format, args);
25502562
2551 const orig_notes = msg.notes.len;2563 const orig_notes = msg.notes.len;
2552 msg.notes = try sema.gpa.realloc(msg.notes, orig_notes + 1);2564 msg.notes = try sema.gpa.realloc(msg.notes, orig_notes + 1);
...@@ -2630,16 +2642,16 @@ fn analyzeAsInt(...@@ -2630,16 +2642,16 @@ fn analyzeAsInt(
2630 dest_ty: Type,2642 dest_ty: Type,
2631 reason: NeededComptimeReason,2643 reason: NeededComptimeReason,
2632) !u64 {2644) !u64 {
2633 const mod = sema.mod;
2634 const coerced = try sema.coerce(block, dest_ty, air_ref, src);2645 const coerced = try sema.coerce(block, dest_ty, air_ref, src);
2635 const val = try sema.resolveConstDefinedValue(block, src, coerced, reason);2646 const val = try sema.resolveConstDefinedValue(block, src, coerced, reason);
2636 return (try val.getUnsignedIntAdvanced(mod, .sema)).?;2647 return (try val.getUnsignedIntAdvanced(sema.pt, .sema)).?;
2637}2648}
26382649
2639/// Given a ZIR extra index which points to a list of `Zir.Inst.Capture`,2650/// Given a ZIR extra index which points to a list of `Zir.Inst.Capture`,
2640/// resolves this into a list of `InternPool.CaptureValue` allocated by `arena`.2651/// resolves this into a list of `InternPool.CaptureValue` allocated by `arena`.
2641fn getCaptures(sema: *Sema, block: *Block, type_src: LazySrcLoc, extra_index: usize, captures_len: u32) ![]InternPool.CaptureValue {2652fn getCaptures(sema: *Sema, block: *Block, type_src: LazySrcLoc, extra_index: usize, captures_len: u32) ![]InternPool.CaptureValue {
2642 const zcu = sema.mod;2653 const pt = sema.pt;
2654 const zcu = pt.zcu;
2643 const ip = &zcu.intern_pool;2655 const ip = &zcu.intern_pool;
2644 const parent_captures: InternPool.CaptureValue.Slice = zcu.namespacePtr(block.namespace).getType(zcu).getCaptures(zcu);2656 const parent_captures: InternPool.CaptureValue.Slice = zcu.namespacePtr(block.namespace).getType(zcu).getCaptures(zcu);
26452657
...@@ -2679,6 +2691,7 @@ fn getCaptures(sema: *Sema, block: *Block, type_src: LazySrcLoc, extra_index: us...@@ -2679,6 +2691,7 @@ fn getCaptures(sema: *Sema, block: *Block, type_src: LazySrcLoc, extra_index: us
2679 .decl_val => |str| capture: {2691 .decl_val => |str| capture: {
2680 const decl_name = try ip.getOrPutString(2692 const decl_name = try ip.getOrPutString(
2681 sema.gpa,2693 sema.gpa,
2694 pt.tid,
2682 sema.code.nullTerminatedString(str),2695 sema.code.nullTerminatedString(str),
2683 .no_embedded_nulls,2696 .no_embedded_nulls,
2684 );2697 );
...@@ -2688,6 +2701,7 @@ fn getCaptures(sema: *Sema, block: *Block, type_src: LazySrcLoc, extra_index: us...@@ -2688,6 +2701,7 @@ fn getCaptures(sema: *Sema, block: *Block, type_src: LazySrcLoc, extra_index: us
2688 .decl_ref => |str| capture: {2701 .decl_ref => |str| capture: {
2689 const decl_name = try ip.getOrPutString(2702 const decl_name = try ip.getOrPutString(
2690 sema.gpa,2703 sema.gpa,
2704 pt.tid,
2691 sema.code.nullTerminatedString(str),2705 sema.code.nullTerminatedString(str),
2692 .no_embedded_nulls,2706 .no_embedded_nulls,
2693 );2707 );
...@@ -2703,10 +2717,11 @@ fn getCaptures(sema: *Sema, block: *Block, type_src: LazySrcLoc, extra_index: us...@@ -2703,10 +2717,11 @@ fn getCaptures(sema: *Sema, block: *Block, type_src: LazySrcLoc, extra_index: us
2703/// Given an `InternPool.WipNamespaceType` or `InternPool.WipEnumType`, apply2717/// Given an `InternPool.WipNamespaceType` or `InternPool.WipEnumType`, apply
2704/// `sema.builtin_type_target_index` to it if necessary.2718/// `sema.builtin_type_target_index` to it if necessary.
2705fn wrapWipTy(sema: *Sema, wip_ty: anytype) @TypeOf(wip_ty) {2719fn wrapWipTy(sema: *Sema, wip_ty: anytype) @TypeOf(wip_ty) {
2720 const pt = sema.pt;
2706 if (sema.builtin_type_target_index == .none) return wip_ty;2721 if (sema.builtin_type_target_index == .none) return wip_ty;
2707 var new = wip_ty;2722 var new = wip_ty;
2708 new.index = sema.builtin_type_target_index;2723 new.index = sema.builtin_type_target_index;
2709 sema.mod.intern_pool.resolveBuiltinType(new.index, wip_ty.index);2724 pt.zcu.intern_pool.resolveBuiltinType(pt.tid, new.index, wip_ty.index);
2710 return new;2725 return new;
2711}2726}
27122727
...@@ -2714,7 +2729,8 @@ fn wrapWipTy(sema: *Sema, wip_ty: anytype) @TypeOf(wip_ty) {...@@ -2714,7 +2729,8 @@ fn wrapWipTy(sema: *Sema, wip_ty: anytype) @TypeOf(wip_ty) {
2714/// considered outdated on this update. If so, remove it from the pool2729/// considered outdated on this update. If so, remove it from the pool
2715/// and return `true`.2730/// and return `true`.
2716fn maybeRemoveOutdatedType(sema: *Sema, ty: InternPool.Index) !bool {2731fn maybeRemoveOutdatedType(sema: *Sema, ty: InternPool.Index) !bool {
2717 const zcu = sema.mod;2732 const pt = sema.pt;
2733 const zcu = pt.zcu;
27182734
2719 if (!zcu.comp.debug_incremental) return false;2735 if (!zcu.comp.debug_incremental) return false;
27202736
...@@ -2725,7 +2741,7 @@ fn maybeRemoveOutdatedType(sema: *Sema, ty: InternPool.Index) !bool {...@@ -2725,7 +2741,7 @@ fn maybeRemoveOutdatedType(sema: *Sema, ty: InternPool.Index) !bool {
2725 if (!was_outdated) return false;2741 if (!was_outdated) return false;
2726 _ = zcu.outdated_ready.swapRemove(decl_as_depender);2742 _ = zcu.outdated_ready.swapRemove(decl_as_depender);
2727 zcu.intern_pool.removeDependenciesForDepender(zcu.gpa, AnalUnit.wrap(.{ .decl = decl_index }));2743 zcu.intern_pool.removeDependenciesForDepender(zcu.gpa, AnalUnit.wrap(.{ .decl = decl_index }));
2728 zcu.intern_pool.remove(ty);2744 zcu.intern_pool.remove(pt.tid, ty);
2729 zcu.declPtr(decl_index).analysis = .dependency_failure;2745 zcu.declPtr(decl_index).analysis = .dependency_failure;
2730 try zcu.markDependeeOutdated(.{ .decl_val = decl_index });2746 try zcu.markDependeeOutdated(.{ .decl_val = decl_index });
2731 return true;2747 return true;
...@@ -2737,7 +2753,8 @@ fn zirStructDecl(...@@ -2737,7 +2753,8 @@ fn zirStructDecl(
2737 extended: Zir.Inst.Extended.InstData,2753 extended: Zir.Inst.Extended.InstData,
2738 inst: Zir.Inst.Index,2754 inst: Zir.Inst.Index,
2739) CompileError!Air.Inst.Ref {2755) CompileError!Air.Inst.Ref {
2740 const mod = sema.mod;2756 const pt = sema.pt;
2757 const mod = pt.zcu;
2741 const gpa = sema.gpa;2758 const gpa = sema.gpa;
2742 const ip = &mod.intern_pool;2759 const ip = &mod.intern_pool;
2743 const small: Zir.Inst.StructDecl.Small = @bitCast(extended.small);2760 const small: Zir.Inst.StructDecl.Small = @bitCast(extended.small);
...@@ -2796,14 +2813,14 @@ fn zirStructDecl(...@@ -2796,14 +2813,14 @@ fn zirStructDecl(
2796 .captures = captures,2813 .captures = captures,
2797 } },2814 } },
2798 };2815 };
2799 const wip_ty = sema.wrapWipTy(switch (try ip.getStructType(gpa, struct_init)) {2816 const wip_ty = sema.wrapWipTy(switch (try ip.getStructType(gpa, pt.tid, struct_init)) {
2800 .existing => |ty| wip: {2817 .existing => |ty| wip: {
2801 if (!try sema.maybeRemoveOutdatedType(ty)) return Air.internedToRef(ty);2818 if (!try sema.maybeRemoveOutdatedType(ty)) return Air.internedToRef(ty);
2802 break :wip (try ip.getStructType(gpa, struct_init)).wip;2819 break :wip (try ip.getStructType(gpa, pt.tid, struct_init)).wip;
2803 },2820 },
2804 .wip => |wip| wip,2821 .wip => |wip| wip,
2805 });2822 });
2806 errdefer wip_ty.cancel(ip);2823 errdefer wip_ty.cancel(ip, pt.tid);
28072824
2808 const new_decl_index = try sema.createAnonymousDeclTypeNamed(2825 const new_decl_index = try sema.createAnonymousDeclTypeNamed(
2809 block,2826 block,
...@@ -2815,7 +2832,7 @@ fn zirStructDecl(...@@ -2815,7 +2832,7 @@ fn zirStructDecl(
2815 mod.declPtr(new_decl_index).owns_tv = true;2832 mod.declPtr(new_decl_index).owns_tv = true;
2816 errdefer mod.abortAnonDecl(new_decl_index);2833 errdefer mod.abortAnonDecl(new_decl_index);
28172834
2818 if (sema.mod.comp.debug_incremental) {2835 if (pt.zcu.comp.debug_incremental) {
2819 try ip.addDependency(2836 try ip.addDependency(
2820 sema.gpa,2837 sema.gpa,
2821 AnalUnit.wrap(.{ .decl = new_decl_index }),2838 AnalUnit.wrap(.{ .decl = new_decl_index }),
...@@ -2833,10 +2850,10 @@ fn zirStructDecl(...@@ -2833,10 +2850,10 @@ fn zirStructDecl(
28332850
2834 if (new_namespace_index.unwrap()) |ns| {2851 if (new_namespace_index.unwrap()) |ns| {
2835 const decls = sema.code.bodySlice(extra_index, decls_len);2852 const decls = sema.code.bodySlice(extra_index, decls_len);
2836 try mod.scanNamespace(ns, decls, mod.declPtr(new_decl_index));2853 try pt.scanNamespace(ns, decls, mod.declPtr(new_decl_index));
2837 }2854 }
28382855
2839 try mod.finalizeAnonDecl(new_decl_index);2856 try pt.finalizeAnonDecl(new_decl_index);
2840 try mod.comp.work_queue.writeItem(.{ .resolve_type_fully = wip_ty.index });2857 try mod.comp.work_queue.writeItem(.{ .resolve_type_fully = wip_ty.index });
2841 try sema.addReferenceEntry(src, AnalUnit.wrap(.{ .decl = new_decl_index }));2858 try sema.addReferenceEntry(src, AnalUnit.wrap(.{ .decl = new_decl_index }));
2842 return Air.internedToRef(wip_ty.finish(ip, new_decl_index, new_namespace_index));2859 return Air.internedToRef(wip_ty.finish(ip, new_decl_index, new_namespace_index));
...@@ -2850,7 +2867,8 @@ fn createAnonymousDeclTypeNamed(...@@ -2850,7 +2867,8 @@ fn createAnonymousDeclTypeNamed(
2850 anon_prefix: []const u8,2867 anon_prefix: []const u8,
2851 inst: ?Zir.Inst.Index,2868 inst: ?Zir.Inst.Index,
2852) !InternPool.DeclIndex {2869) !InternPool.DeclIndex {
2853 const zcu = sema.mod;2870 const pt = sema.pt;
2871 const zcu = pt.zcu;
2854 const ip = &zcu.intern_pool;2872 const ip = &zcu.intern_pool;
2855 const gpa = sema.gpa;2873 const gpa = sema.gpa;
2856 const namespace = block.namespace;2874 const namespace = block.namespace;
...@@ -2892,7 +2910,7 @@ fn createAnonymousDeclTypeNamed(...@@ -2892,7 +2910,7 @@ fn createAnonymousDeclTypeNamed(
2892 // some tooling may not support very long symbol names.2910 // some tooling may not support very long symbol names.
2893 try writer.print("{}", .{Value.fmtValueFull(.{2911 try writer.print("{}", .{Value.fmtValueFull(.{
2894 .val = arg_val,2912 .val = arg_val,
2895 .mod = zcu,2913 .pt = pt,
2896 .opt_sema = sema,2914 .opt_sema = sema,
2897 .depth = 1,2915 .depth = 1,
2898 })});2916 })});
...@@ -2904,7 +2922,7 @@ fn createAnonymousDeclTypeNamed(...@@ -2904,7 +2922,7 @@ fn createAnonymousDeclTypeNamed(
2904 };2922 };
29052923
2906 try writer.writeByte(')');2924 try writer.writeByte(')');
2907 const name = try ip.getOrPutString(gpa, buf.items, .no_embedded_nulls);2925 const name = try ip.getOrPutString(gpa, pt.tid, buf.items, .no_embedded_nulls);
2908 try zcu.initNewAnonDecl(new_decl_index, val, name);2926 try zcu.initNewAnonDecl(new_decl_index, val, name);
2909 return new_decl_index;2927 return new_decl_index;
2910 },2928 },
...@@ -2916,7 +2934,7 @@ fn createAnonymousDeclTypeNamed(...@@ -2916,7 +2934,7 @@ fn createAnonymousDeclTypeNamed(
2916 .dbg_var_ptr, .dbg_var_val => {2934 .dbg_var_ptr, .dbg_var_val => {
2917 if (zir_data[i].str_op.operand != ref) continue;2935 if (zir_data[i].str_op.operand != ref) continue;
29182936
2919 const name = try ip.getOrPutStringFmt(gpa, "{}.{s}", .{2937 const name = try ip.getOrPutStringFmt(gpa, pt.tid, "{}.{s}", .{
2920 block.type_name_ctx.fmt(ip), zir_data[i].str_op.getStr(sema.code),2938 block.type_name_ctx.fmt(ip), zir_data[i].str_op.getStr(sema.code),
2921 }, .no_embedded_nulls);2939 }, .no_embedded_nulls);
2922 try zcu.initNewAnonDecl(new_decl_index, val, name);2940 try zcu.initNewAnonDecl(new_decl_index, val, name);
...@@ -2937,7 +2955,7 @@ fn createAnonymousDeclTypeNamed(...@@ -2937,7 +2955,7 @@ fn createAnonymousDeclTypeNamed(
2937 // This name is also used as the key in the parent namespace so it cannot be2955 // This name is also used as the key in the parent namespace so it cannot be
2938 // renamed.2956 // renamed.
29392957
2940 const name = ip.getOrPutStringFmt(gpa, "{}__{s}_{d}", .{2958 const name = ip.getOrPutStringFmt(gpa, pt.tid, "{}__{s}_{d}", .{
2941 block.type_name_ctx.fmt(ip), anon_prefix, @intFromEnum(new_decl_index),2959 block.type_name_ctx.fmt(ip), anon_prefix, @intFromEnum(new_decl_index),
2942 }, .no_embedded_nulls) catch unreachable;2960 }, .no_embedded_nulls) catch unreachable;
2943 try zcu.initNewAnonDecl(new_decl_index, val, name);2961 try zcu.initNewAnonDecl(new_decl_index, val, name);
...@@ -2953,7 +2971,8 @@ fn zirEnumDecl(...@@ -2953,7 +2971,8 @@ fn zirEnumDecl(
2953 const tracy = trace(@src());2971 const tracy = trace(@src());
2954 defer tracy.end();2972 defer tracy.end();
29552973
2956 const mod = sema.mod;2974 const pt = sema.pt;
2975 const mod = pt.zcu;
2957 const gpa = sema.gpa;2976 const gpa = sema.gpa;
2958 const ip = &mod.intern_pool;2977 const ip = &mod.intern_pool;
2959 const small: Zir.Inst.EnumDecl.Small = @bitCast(extended.small);2978 const small: Zir.Inst.EnumDecl.Small = @bitCast(extended.small);
...@@ -3026,10 +3045,10 @@ fn zirEnumDecl(...@@ -3026,10 +3045,10 @@ fn zirEnumDecl(
3026 .captures = captures,3045 .captures = captures,
3027 } },3046 } },
3028 };3047 };
3029 const wip_ty = sema.wrapWipTy(switch (try ip.getEnumType(gpa, enum_init)) {3048 const wip_ty = sema.wrapWipTy(switch (try ip.getEnumType(gpa, pt.tid, enum_init)) {
3030 .existing => |ty| wip: {3049 .existing => |ty| wip: {
3031 if (!try sema.maybeRemoveOutdatedType(ty)) return Air.internedToRef(ty);3050 if (!try sema.maybeRemoveOutdatedType(ty)) return Air.internedToRef(ty);
3032 break :wip (try ip.getEnumType(gpa, enum_init)).wip;3051 break :wip (try ip.getEnumType(gpa, pt.tid, enum_init)).wip;
3033 },3052 },
3034 .wip => |wip| wip,3053 .wip => |wip| wip,
3035 });3054 });
...@@ -3038,7 +3057,7 @@ fn zirEnumDecl(...@@ -3038,7 +3057,7 @@ fn zirEnumDecl(
3038 // have finished constructing the type and are in the process of analyzing it.3057 // have finished constructing the type and are in the process of analyzing it.
3039 var done = false;3058 var done = false;
30403059
3041 errdefer if (!done) wip_ty.cancel(ip);3060 errdefer if (!done) wip_ty.cancel(ip, pt.tid);
30423061
3043 const new_decl_index = try sema.createAnonymousDeclTypeNamed(3062 const new_decl_index = try sema.createAnonymousDeclTypeNamed(
3044 block,3063 block,
...@@ -3051,7 +3070,7 @@ fn zirEnumDecl(...@@ -3051,7 +3070,7 @@ fn zirEnumDecl(
3051 new_decl.owns_tv = true;3070 new_decl.owns_tv = true;
3052 errdefer if (!done) mod.abortAnonDecl(new_decl_index);3071 errdefer if (!done) mod.abortAnonDecl(new_decl_index);
30533072
3054 if (sema.mod.comp.debug_incremental) {3073 if (pt.zcu.comp.debug_incremental) {
3055 try mod.intern_pool.addDependency(3074 try mod.intern_pool.addDependency(
3056 gpa,3075 gpa,
3057 AnalUnit.wrap(.{ .decl = new_decl_index }),3076 AnalUnit.wrap(.{ .decl = new_decl_index }),
...@@ -3068,7 +3087,7 @@ fn zirEnumDecl(...@@ -3068,7 +3087,7 @@ fn zirEnumDecl(
3068 errdefer if (!done) if (new_namespace_index.unwrap()) |ns| mod.destroyNamespace(ns);3087 errdefer if (!done) if (new_namespace_index.unwrap()) |ns| mod.destroyNamespace(ns);
30693088
3070 if (new_namespace_index.unwrap()) |ns| {3089 if (new_namespace_index.unwrap()) |ns| {
3071 try mod.scanNamespace(ns, decls, new_decl);3090 try pt.scanNamespace(ns, decls, new_decl);
3072 }3091 }
30733092
3074 // We've finished the initial construction of this type, and are about to perform analysis.3093 // We've finished the initial construction of this type, and are about to perform analysis.
...@@ -3118,21 +3137,21 @@ fn zirEnumDecl(...@@ -3118,21 +3137,21 @@ fn zirEnumDecl(
3118 if (tag_type_ref != .none) {3137 if (tag_type_ref != .none) {
3119 const ty = try sema.resolveType(&enum_block, tag_ty_src, tag_type_ref);3138 const ty = try sema.resolveType(&enum_block, tag_ty_src, tag_type_ref);
3120 if (ty.zigTypeTag(mod) != .Int and ty.zigTypeTag(mod) != .ComptimeInt) {3139 if (ty.zigTypeTag(mod) != .Int and ty.zigTypeTag(mod) != .ComptimeInt) {
3121 return sema.fail(&enum_block, tag_ty_src, "expected integer tag type, found '{}'", .{ty.fmt(sema.mod)});3140 return sema.fail(&enum_block, tag_ty_src, "expected integer tag type, found '{}'", .{ty.fmt(pt)});
3122 }3141 }
3123 break :ty ty;3142 break :ty ty;
3124 } else if (fields_len == 0) {3143 } else if (fields_len == 0) {
3125 break :ty try mod.intType(.unsigned, 0);3144 break :ty try pt.intType(.unsigned, 0);
3126 } else {3145 } else {
3127 const bits = std.math.log2_int_ceil(usize, fields_len);3146 const bits = std.math.log2_int_ceil(usize, fields_len);
3128 break :ty try mod.intType(.unsigned, bits);3147 break :ty try pt.intType(.unsigned, bits);
3129 }3148 }
3130 };3149 };
31313150
3132 wip_ty.setTagTy(ip, int_tag_ty.toIntern());3151 wip_ty.setTagTy(ip, int_tag_ty.toIntern());
31333152
3134 if (small.nonexhaustive and int_tag_ty.toIntern() != .comptime_int_type) {3153 if (small.nonexhaustive and int_tag_ty.toIntern() != .comptime_int_type) {
3135 if (fields_len > 1 and std.math.log2_int(u64, fields_len) == int_tag_ty.bitSize(mod)) {3154 if (fields_len > 1 and std.math.log2_int(u64, fields_len) == int_tag_ty.bitSize(pt)) {
3136 return sema.fail(block, src, "non-exhaustive enum specifies every value", .{});3155 return sema.fail(block, src, "non-exhaustive enum specifies every value", .{});
3137 }3156 }
3138 }3157 }
...@@ -3153,7 +3172,7 @@ fn zirEnumDecl(...@@ -3153,7 +3172,7 @@ fn zirEnumDecl(
3153 const field_name_zir = sema.code.nullTerminatedString(field_name_index);3172 const field_name_zir = sema.code.nullTerminatedString(field_name_index);
3154 extra_index += 2; // field name, doc comment3173 extra_index += 2; // field name, doc comment
31553174
3156 const field_name = try mod.intern_pool.getOrPutString(gpa, field_name_zir, .no_embedded_nulls);3175 const field_name = try mod.intern_pool.getOrPutString(gpa, pt.tid, field_name_zir, .no_embedded_nulls);
31573176
3158 const value_src: LazySrcLoc = .{3177 const value_src: LazySrcLoc = .{
3159 .base_node_inst = tracked_inst,3178 .base_node_inst = tracked_inst,
...@@ -3171,7 +3190,7 @@ fn zirEnumDecl(...@@ -3171,7 +3190,7 @@ fn zirEnumDecl(
3171 .needed_comptime_reason = "enum tag value must be comptime-known",3190 .needed_comptime_reason = "enum tag value must be comptime-known",
3172 });3191 });
3173 if (!(try sema.intFitsInType(last_tag_val.?, int_tag_ty, null))) break :overflow true;3192 if (!(try sema.intFitsInType(last_tag_val.?, int_tag_ty, null))) break :overflow true;
3174 last_tag_val = try mod.getCoerced(last_tag_val.?, int_tag_ty);3193 last_tag_val = try pt.getCoerced(last_tag_val.?, int_tag_ty);
3175 if (wip_ty.nextField(&mod.intern_pool, field_name, last_tag_val.?.toIntern())) |conflict| {3194 if (wip_ty.nextField(&mod.intern_pool, field_name, last_tag_val.?.toIntern())) |conflict| {
3176 assert(conflict.kind == .value); // AstGen validated names are unique3195 assert(conflict.kind == .value); // AstGen validated names are unique
3177 const other_field_src: LazySrcLoc = .{3196 const other_field_src: LazySrcLoc = .{
...@@ -3179,7 +3198,7 @@ fn zirEnumDecl(...@@ -3179,7 +3198,7 @@ fn zirEnumDecl(
3179 .offset = .{ .container_field_value = conflict.prev_field_idx },3198 .offset = .{ .container_field_value = conflict.prev_field_idx },
3180 };3199 };
3181 const msg = msg: {3200 const msg = msg: {
3182 const msg = try sema.errMsg(value_src, "enum tag value {} already taken", .{last_tag_val.?.fmtValue(sema.mod, sema)});3201 const msg = try sema.errMsg(value_src, "enum tag value {} already taken", .{last_tag_val.?.fmtValue(pt, sema)});
3183 errdefer msg.destroy(gpa);3202 errdefer msg.destroy(gpa);
3184 try sema.errNote(other_field_src, msg, "other occurrence here", .{});3203 try sema.errNote(other_field_src, msg, "other occurrence here", .{});
3185 break :msg msg;3204 break :msg msg;
...@@ -3190,9 +3209,9 @@ fn zirEnumDecl(...@@ -3190,9 +3209,9 @@ fn zirEnumDecl(
3190 } else if (any_values) overflow: {3209 } else if (any_values) overflow: {
3191 var overflow: ?usize = null;3210 var overflow: ?usize = null;
3192 last_tag_val = if (last_tag_val) |val|3211 last_tag_val = if (last_tag_val) |val|
3193 try sema.intAdd(val, try mod.intValue(int_tag_ty, 1), int_tag_ty, &overflow)3212 try sema.intAdd(val, try pt.intValue(int_tag_ty, 1), int_tag_ty, &overflow)
3194 else3213 else
3195 try mod.intValue(int_tag_ty, 0);3214 try pt.intValue(int_tag_ty, 0);
3196 if (overflow != null) break :overflow true;3215 if (overflow != null) break :overflow true;
3197 if (wip_ty.nextField(&mod.intern_pool, field_name, last_tag_val.?.toIntern())) |conflict| {3216 if (wip_ty.nextField(&mod.intern_pool, field_name, last_tag_val.?.toIntern())) |conflict| {
3198 assert(conflict.kind == .value); // AstGen validated names are unique3217 assert(conflict.kind == .value); // AstGen validated names are unique
...@@ -3201,7 +3220,7 @@ fn zirEnumDecl(...@@ -3201,7 +3220,7 @@ fn zirEnumDecl(
3201 .offset = .{ .container_field_value = conflict.prev_field_idx },3220 .offset = .{ .container_field_value = conflict.prev_field_idx },
3202 };3221 };
3203 const msg = msg: {3222 const msg = msg: {
3204 const msg = try sema.errMsg(value_src, "enum tag value {} already taken", .{last_tag_val.?.fmtValue(sema.mod, sema)});3223 const msg = try sema.errMsg(value_src, "enum tag value {} already taken", .{last_tag_val.?.fmtValue(pt, sema)});
3205 errdefer msg.destroy(gpa);3224 errdefer msg.destroy(gpa);
3206 try sema.errNote(other_field_src, msg, "other occurrence here", .{});3225 try sema.errNote(other_field_src, msg, "other occurrence here", .{});
3207 break :msg msg;3226 break :msg msg;
...@@ -3211,21 +3230,21 @@ fn zirEnumDecl(...@@ -3211,21 +3230,21 @@ fn zirEnumDecl(
3211 break :overflow false;3230 break :overflow false;
3212 } else overflow: {3231 } else overflow: {
3213 assert(wip_ty.nextField(&mod.intern_pool, field_name, .none) == null);3232 assert(wip_ty.nextField(&mod.intern_pool, field_name, .none) == null);
3214 last_tag_val = try mod.intValue(Type.comptime_int, field_i);3233 last_tag_val = try pt.intValue(Type.comptime_int, field_i);
3215 if (!try sema.intFitsInType(last_tag_val.?, int_tag_ty, null)) break :overflow true;3234 if (!try sema.intFitsInType(last_tag_val.?, int_tag_ty, null)) break :overflow true;
3216 last_tag_val = try mod.getCoerced(last_tag_val.?, int_tag_ty);3235 last_tag_val = try pt.getCoerced(last_tag_val.?, int_tag_ty);
3217 break :overflow false;3236 break :overflow false;
3218 };3237 };
32193238
3220 if (tag_overflow) {3239 if (tag_overflow) {
3221 const msg = try sema.errMsg(value_src, "enumeration value '{}' too large for type '{}'", .{3240 const msg = try sema.errMsg(value_src, "enumeration value '{}' too large for type '{}'", .{
3222 last_tag_val.?.fmtValue(mod, sema), int_tag_ty.fmt(mod),3241 last_tag_val.?.fmtValue(pt, sema), int_tag_ty.fmt(pt),
3223 });3242 });
3224 return sema.failWithOwnedErrorMsg(block, msg);3243 return sema.failWithOwnedErrorMsg(block, msg);
3225 }3244 }
3226 }3245 }
32273246
3228 try mod.finalizeAnonDecl(new_decl_index);3247 try pt.finalizeAnonDecl(new_decl_index);
3229 return Air.internedToRef(wip_ty.index);3248 return Air.internedToRef(wip_ty.index);
3230}3249}
32313250
...@@ -3238,7 +3257,8 @@ fn zirUnionDecl(...@@ -3238,7 +3257,8 @@ fn zirUnionDecl(
3238 const tracy = trace(@src());3257 const tracy = trace(@src());
3239 defer tracy.end();3258 defer tracy.end();
32403259
3241 const mod = sema.mod;3260 const pt = sema.pt;
3261 const mod = pt.zcu;
3242 const gpa = sema.gpa;3262 const gpa = sema.gpa;
3243 const ip = &mod.intern_pool;3263 const ip = &mod.intern_pool;
3244 const small: Zir.Inst.UnionDecl.Small = @bitCast(extended.small);3264 const small: Zir.Inst.UnionDecl.Small = @bitCast(extended.small);
...@@ -3298,14 +3318,14 @@ fn zirUnionDecl(...@@ -3298,14 +3318,14 @@ fn zirUnionDecl(
3298 .captures = captures,3318 .captures = captures,
3299 } },3319 } },
3300 };3320 };
3301 const wip_ty = sema.wrapWipTy(switch (try ip.getUnionType(gpa, union_init)) {3321 const wip_ty = sema.wrapWipTy(switch (try ip.getUnionType(gpa, pt.tid, union_init)) {
3302 .existing => |ty| wip: {3322 .existing => |ty| wip: {
3303 if (!try sema.maybeRemoveOutdatedType(ty)) return Air.internedToRef(ty);3323 if (!try sema.maybeRemoveOutdatedType(ty)) return Air.internedToRef(ty);
3304 break :wip (try ip.getUnionType(gpa, union_init)).wip;3324 break :wip (try ip.getUnionType(gpa, pt.tid, union_init)).wip;
3305 },3325 },
3306 .wip => |wip| wip,3326 .wip => |wip| wip,
3307 });3327 });
3308 errdefer wip_ty.cancel(ip);3328 errdefer wip_ty.cancel(ip, pt.tid);
33093329
3310 const new_decl_index = try sema.createAnonymousDeclTypeNamed(3330 const new_decl_index = try sema.createAnonymousDeclTypeNamed(
3311 block,3331 block,
...@@ -3317,7 +3337,7 @@ fn zirUnionDecl(...@@ -3317,7 +3337,7 @@ fn zirUnionDecl(
3317 mod.declPtr(new_decl_index).owns_tv = true;3337 mod.declPtr(new_decl_index).owns_tv = true;
3318 errdefer mod.abortAnonDecl(new_decl_index);3338 errdefer mod.abortAnonDecl(new_decl_index);
33193339
3320 if (sema.mod.comp.debug_incremental) {3340 if (pt.zcu.comp.debug_incremental) {
3321 try mod.intern_pool.addDependency(3341 try mod.intern_pool.addDependency(
3322 gpa,3342 gpa,
3323 AnalUnit.wrap(.{ .decl = new_decl_index }),3343 AnalUnit.wrap(.{ .decl = new_decl_index }),
...@@ -3335,10 +3355,10 @@ fn zirUnionDecl(...@@ -3335,10 +3355,10 @@ fn zirUnionDecl(
33353355
3336 if (new_namespace_index.unwrap()) |ns| {3356 if (new_namespace_index.unwrap()) |ns| {
3337 const decls = sema.code.bodySlice(extra_index, decls_len);3357 const decls = sema.code.bodySlice(extra_index, decls_len);
3338 try mod.scanNamespace(ns, decls, mod.declPtr(new_decl_index));3358 try pt.scanNamespace(ns, decls, mod.declPtr(new_decl_index));
3339 }3359 }
33403360
3341 try mod.finalizeAnonDecl(new_decl_index);3361 try pt.finalizeAnonDecl(new_decl_index);
3342 try mod.comp.work_queue.writeItem(.{ .resolve_type_fully = wip_ty.index });3362 try mod.comp.work_queue.writeItem(.{ .resolve_type_fully = wip_ty.index });
3343 try sema.addReferenceEntry(src, AnalUnit.wrap(.{ .decl = new_decl_index }));3363 try sema.addReferenceEntry(src, AnalUnit.wrap(.{ .decl = new_decl_index }));
3344 return Air.internedToRef(wip_ty.finish(ip, new_decl_index, new_namespace_index));3364 return Air.internedToRef(wip_ty.finish(ip, new_decl_index, new_namespace_index));
...@@ -3353,7 +3373,8 @@ fn zirOpaqueDecl(...@@ -3353,7 +3373,8 @@ fn zirOpaqueDecl(
3353 const tracy = trace(@src());3373 const tracy = trace(@src());
3354 defer tracy.end();3374 defer tracy.end();
33553375
3356 const mod = sema.mod;3376 const pt = sema.pt;
3377 const mod = pt.zcu;
3357 const gpa = sema.gpa;3378 const gpa = sema.gpa;
3358 const ip = &mod.intern_pool;3379 const ip = &mod.intern_pool;
33593380
...@@ -3387,14 +3408,14 @@ fn zirOpaqueDecl(...@@ -3387,14 +3408,14 @@ fn zirOpaqueDecl(
3387 } },3408 } },
3388 };3409 };
3389 // No `wrapWipTy` needed as no std.builtin types are opaque.3410 // No `wrapWipTy` needed as no std.builtin types are opaque.
3390 const wip_ty = switch (try ip.getOpaqueType(gpa, opaque_init)) {3411 const wip_ty = switch (try ip.getOpaqueType(gpa, pt.tid, opaque_init)) {
3391 .existing => |ty| wip: {3412 .existing => |ty| wip: {
3392 if (!try sema.maybeRemoveOutdatedType(ty)) return Air.internedToRef(ty);3413 if (!try sema.maybeRemoveOutdatedType(ty)) return Air.internedToRef(ty);
3393 break :wip (try ip.getOpaqueType(gpa, opaque_init)).wip;3414 break :wip (try ip.getOpaqueType(gpa, pt.tid, opaque_init)).wip;
3394 },3415 },
3395 .wip => |wip| wip,3416 .wip => |wip| wip,
3396 };3417 };
3397 errdefer wip_ty.cancel(ip);3418 errdefer wip_ty.cancel(ip, pt.tid);
33983419
3399 const new_decl_index = try sema.createAnonymousDeclTypeNamed(3420 const new_decl_index = try sema.createAnonymousDeclTypeNamed(
3400 block,3421 block,
...@@ -3406,7 +3427,7 @@ fn zirOpaqueDecl(...@@ -3406,7 +3427,7 @@ fn zirOpaqueDecl(
3406 mod.declPtr(new_decl_index).owns_tv = true;3427 mod.declPtr(new_decl_index).owns_tv = true;
3407 errdefer mod.abortAnonDecl(new_decl_index);3428 errdefer mod.abortAnonDecl(new_decl_index);
34083429
3409 if (sema.mod.comp.debug_incremental) {3430 if (pt.zcu.comp.debug_incremental) {
3410 try ip.addDependency(3431 try ip.addDependency(
3411 gpa,3432 gpa,
3412 AnalUnit.wrap(.{ .decl = new_decl_index }),3433 AnalUnit.wrap(.{ .decl = new_decl_index }),
...@@ -3423,10 +3444,10 @@ fn zirOpaqueDecl(...@@ -3423,10 +3444,10 @@ fn zirOpaqueDecl(
34233444
3424 if (new_namespace_index.unwrap()) |ns| {3445 if (new_namespace_index.unwrap()) |ns| {
3425 const decls = sema.code.bodySlice(extra_index, decls_len);3446 const decls = sema.code.bodySlice(extra_index, decls_len);
3426 try mod.scanNamespace(ns, decls, mod.declPtr(new_decl_index));3447 try pt.scanNamespace(ns, decls, mod.declPtr(new_decl_index));
3427 }3448 }
34283449
3429 try mod.finalizeAnonDecl(new_decl_index);3450 try pt.finalizeAnonDecl(new_decl_index);
34303451
3431 return Air.internedToRef(wip_ty.finish(ip, new_decl_index, new_namespace_index));3452 return Air.internedToRef(wip_ty.finish(ip, new_decl_index, new_namespace_index));
3432}3453}
...@@ -3438,7 +3459,8 @@ fn zirErrorSetDecl(...@@ -3438,7 +3459,8 @@ fn zirErrorSetDecl(
3438 const tracy = trace(@src());3459 const tracy = trace(@src());
3439 defer tracy.end();3460 defer tracy.end();
34403461
3441 const mod = sema.mod;3462 const pt = sema.pt;
3463 const mod = pt.zcu;
3442 const gpa = sema.gpa;3464 const gpa = sema.gpa;
3443 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;3465 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
3444 const extra = sema.code.extraData(Zir.Inst.ErrorSetDecl, inst_data.payload_index);3466 const extra = sema.code.extraData(Zir.Inst.ErrorSetDecl, inst_data.payload_index);
...@@ -3451,26 +3473,28 @@ fn zirErrorSetDecl(...@@ -3451,26 +3473,28 @@ fn zirErrorSetDecl(
3451 while (extra_index < extra_index_end) : (extra_index += 2) { // +2 to skip over doc_string3473 while (extra_index < extra_index_end) : (extra_index += 2) { // +2 to skip over doc_string
3452 const name_index: Zir.NullTerminatedString = @enumFromInt(sema.code.extra[extra_index]);3474 const name_index: Zir.NullTerminatedString = @enumFromInt(sema.code.extra[extra_index]);
3453 const name = sema.code.nullTerminatedString(name_index);3475 const name = sema.code.nullTerminatedString(name_index);
3454 const name_ip = try mod.intern_pool.getOrPutString(gpa, name, .no_embedded_nulls);3476 const name_ip = try mod.intern_pool.getOrPutString(gpa, pt.tid, name, .no_embedded_nulls);
3455 _ = try mod.getErrorValue(name_ip);3477 _ = try mod.getErrorValue(name_ip);
3456 const result = names.getOrPutAssumeCapacity(name_ip);3478 const result = names.getOrPutAssumeCapacity(name_ip);
3457 assert(!result.found_existing); // verified in AstGen3479 assert(!result.found_existing); // verified in AstGen
3458 }3480 }
34593481
3460 return Air.internedToRef((try mod.errorSetFromUnsortedNames(names.keys())).toIntern());3482 return Air.internedToRef((try pt.errorSetFromUnsortedNames(names.keys())).toIntern());
3461}3483}
34623484
3463fn zirRetPtr(sema: *Sema, block: *Block) CompileError!Air.Inst.Ref {3485fn zirRetPtr(sema: *Sema, block: *Block) CompileError!Air.Inst.Ref {
3464 const tracy = trace(@src());3486 const tracy = trace(@src());
3465 defer tracy.end();3487 defer tracy.end();
34663488
3489 const pt = sema.pt;
3490
3467 if (block.is_comptime or try sema.typeRequiresComptime(sema.fn_ret_ty)) {3491 if (block.is_comptime or try sema.typeRequiresComptime(sema.fn_ret_ty)) {
3468 try sema.fn_ret_ty.resolveFields(sema.mod);3492 try sema.fn_ret_ty.resolveFields(pt);
3469 return sema.analyzeComptimeAlloc(block, sema.fn_ret_ty, .none);3493 return sema.analyzeComptimeAlloc(block, sema.fn_ret_ty, .none);
3470 }3494 }
34713495
3472 const target = sema.mod.getTarget();3496 const target = pt.zcu.getTarget();
3473 const ptr_type = try sema.mod.ptrTypeSema(.{3497 const ptr_type = try pt.ptrTypeSema(.{
3474 .child = sema.fn_ret_ty.toIntern(),3498 .child = sema.fn_ret_ty.toIntern(),
3475 .flags = .{ .address_space = target_util.defaultAddressSpace(target, .local) },3499 .flags = .{ .address_space = target_util.defaultAddressSpace(target, .local) },
3476 });3500 });
...@@ -3511,7 +3535,8 @@ fn ensureResultUsed(...@@ -3511,7 +3535,8 @@ fn ensureResultUsed(
3511 ty: Type,3535 ty: Type,
3512 src: LazySrcLoc,3536 src: LazySrcLoc,
3513) CompileError!void {3537) CompileError!void {
3514 const mod = sema.mod;3538 const pt = sema.pt;
3539 const mod = pt.zcu;
3515 switch (ty.zigTypeTag(mod)) {3540 switch (ty.zigTypeTag(mod)) {
3516 .Void, .NoReturn => return,3541 .Void, .NoReturn => return,
3517 .ErrorSet => return sema.fail(block, src, "error set is ignored", .{}),3542 .ErrorSet => return sema.fail(block, src, "error set is ignored", .{}),
...@@ -3526,7 +3551,7 @@ fn ensureResultUsed(...@@ -3526,7 +3551,7 @@ fn ensureResultUsed(
3526 },3551 },
3527 else => {3552 else => {
3528 const msg = msg: {3553 const msg = msg: {
3529 const msg = try sema.errMsg(src, "value of type '{}' ignored", .{ty.fmt(sema.mod)});3554 const msg = try sema.errMsg(src, "value of type '{}' ignored", .{ty.fmt(pt)});
3530 errdefer msg.destroy(sema.gpa);3555 errdefer msg.destroy(sema.gpa);
3531 try sema.errNote(src, msg, "all non-void values must be used", .{});3556 try sema.errNote(src, msg, "all non-void values must be used", .{});
3532 try sema.errNote(src, msg, "to discard the value, assign it to '_'", .{});3557 try sema.errNote(src, msg, "to discard the value, assign it to '_'", .{});
...@@ -3541,7 +3566,8 @@ fn zirEnsureResultNonError(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Com...@@ -3541,7 +3566,8 @@ fn zirEnsureResultNonError(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Com
3541 const tracy = trace(@src());3566 const tracy = trace(@src());
3542 defer tracy.end();3567 defer tracy.end();
35433568
3544 const mod = sema.mod;3569 const pt = sema.pt;
3570 const mod = pt.zcu;
3545 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;3571 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;
3546 const operand = try sema.resolveInst(inst_data.operand);3572 const operand = try sema.resolveInst(inst_data.operand);
3547 const src = block.nodeOffset(inst_data.src_node);3573 const src = block.nodeOffset(inst_data.src_node);
...@@ -3565,7 +3591,8 @@ fn zirEnsureErrUnionPayloadVoid(sema: *Sema, block: *Block, inst: Zir.Inst.Index...@@ -3565,7 +3591,8 @@ fn zirEnsureErrUnionPayloadVoid(sema: *Sema, block: *Block, inst: Zir.Inst.Index
3565 const tracy = trace(@src());3591 const tracy = trace(@src());
3566 defer tracy.end();3592 defer tracy.end();
35673593
3568 const mod = sema.mod;3594 const pt = sema.pt;
3595 const mod = pt.zcu;
3569 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;3596 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;
3570 const src = block.nodeOffset(inst_data.src_node);3597 const src = block.nodeOffset(inst_data.src_node);
3571 const operand = try sema.resolveInst(inst_data.operand);3598 const operand = try sema.resolveInst(inst_data.operand);
...@@ -3604,12 +3631,13 @@ fn indexablePtrLen(...@@ -3604,12 +3631,13 @@ fn indexablePtrLen(
3604 src: LazySrcLoc,3631 src: LazySrcLoc,
3605 object: Air.Inst.Ref,3632 object: Air.Inst.Ref,
3606) CompileError!Air.Inst.Ref {3633) CompileError!Air.Inst.Ref {
3607 const mod = sema.mod;3634 const pt = sema.pt;
3635 const mod = pt.zcu;
3608 const object_ty = sema.typeOf(object);3636 const object_ty = sema.typeOf(object);
3609 const is_pointer_to = object_ty.isSinglePointer(mod);3637 const is_pointer_to = object_ty.isSinglePointer(mod);
3610 const indexable_ty = if (is_pointer_to) object_ty.childType(mod) else object_ty;3638 const indexable_ty = if (is_pointer_to) object_ty.childType(mod) else object_ty;
3611 try checkIndexable(sema, block, src, indexable_ty);3639 try checkIndexable(sema, block, src, indexable_ty);
3612 const field_name = try mod.intern_pool.getOrPutString(sema.gpa, "len", .no_embedded_nulls);3640 const field_name = try mod.intern_pool.getOrPutString(sema.gpa, pt.tid, "len", .no_embedded_nulls);
3613 return sema.fieldVal(block, src, object, field_name, src);3641 return sema.fieldVal(block, src, object, field_name, src);
3614}3642}
36153643
...@@ -3619,11 +3647,12 @@ fn indexablePtrLenOrNone(...@@ -3619,11 +3647,12 @@ fn indexablePtrLenOrNone(
3619 src: LazySrcLoc,3647 src: LazySrcLoc,
3620 operand: Air.Inst.Ref,3648 operand: Air.Inst.Ref,
3621) CompileError!Air.Inst.Ref {3649) CompileError!Air.Inst.Ref {
3622 const mod = sema.mod;3650 const pt = sema.pt;
3651 const mod = pt.zcu;
3623 const operand_ty = sema.typeOf(operand);3652 const operand_ty = sema.typeOf(operand);
3624 try checkMemOperand(sema, block, src, operand_ty);3653 try checkMemOperand(sema, block, src, operand_ty);
3625 if (operand_ty.ptrSize(mod) == .Many) return .none;3654 if (operand_ty.ptrSize(mod) == .Many) return .none;
3626 const field_name = try mod.intern_pool.getOrPutString(sema.gpa, "len", .no_embedded_nulls);3655 const field_name = try mod.intern_pool.getOrPutString(sema.gpa, pt.tid, "len", .no_embedded_nulls);
3627 return sema.fieldVal(block, src, operand, field_name, src);3656 return sema.fieldVal(block, src, operand, field_name, src);
3628}3657}
36293658
...@@ -3632,6 +3661,7 @@ fn zirAllocExtended(...@@ -3632,6 +3661,7 @@ fn zirAllocExtended(
3632 block: *Block,3661 block: *Block,
3633 extended: Zir.Inst.Extended.InstData,3662 extended: Zir.Inst.Extended.InstData,
3634) CompileError!Air.Inst.Ref {3663) CompileError!Air.Inst.Ref {
3664 const pt = sema.pt;
3635 const gpa = sema.gpa;3665 const gpa = sema.gpa;
3636 const extra = sema.code.extraData(Zir.Inst.AllocExtended, extended.operand);3666 const extra = sema.code.extraData(Zir.Inst.AllocExtended, extended.operand);
3637 const ty_src = block.src(.{ .node_offset_var_decl_ty = extra.data.src_node });3667 const ty_src = block.src(.{ .node_offset_var_decl_ty = extra.data.src_node });
...@@ -3673,9 +3703,9 @@ fn zirAllocExtended(...@@ -3673,9 +3703,9 @@ fn zirAllocExtended(
3673 if (!small.is_const) {3703 if (!small.is_const) {
3674 try sema.validateVarType(block, ty_src, var_ty, false);3704 try sema.validateVarType(block, ty_src, var_ty, false);
3675 }3705 }
3676 const target = sema.mod.getTarget();3706 const target = pt.zcu.getTarget();
3677 try var_ty.resolveLayout(sema.mod);3707 try var_ty.resolveLayout(pt);
3678 const ptr_type = try sema.mod.ptrTypeSema(.{3708 const ptr_type = try sema.pt.ptrTypeSema(.{
3679 .child = var_ty.toIntern(),3709 .child = var_ty.toIntern(),
3680 .flags = .{3710 .flags = .{
3681 .alignment = alignment,3711 .alignment = alignment,
...@@ -3717,7 +3747,8 @@ fn zirAllocComptime(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErr...@@ -3717,7 +3747,8 @@ fn zirAllocComptime(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErr
3717}3747}
37183748
3719fn zirMakePtrConst(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {3749fn zirMakePtrConst(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
3720 const mod = sema.mod;3750 const pt = sema.pt;
3751 const mod = pt.zcu;
3721 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;3752 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;
3722 const alloc = try sema.resolveInst(inst_data.operand);3753 const alloc = try sema.resolveInst(inst_data.operand);
3723 const alloc_ty = sema.typeOf(alloc);3754 const alloc_ty = sema.typeOf(alloc);
...@@ -3749,7 +3780,7 @@ fn zirMakePtrConst(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErro...@@ -3749,7 +3780,7 @@ fn zirMakePtrConst(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErro
3749 assert(ptr.byte_offset == 0);3780 assert(ptr.byte_offset == 0);
3750 const alloc_index = ptr.base_addr.comptime_alloc;3781 const alloc_index = ptr.base_addr.comptime_alloc;
3751 const ct_alloc = sema.getComptimeAlloc(alloc_index);3782 const ct_alloc = sema.getComptimeAlloc(alloc_index);
3752 const interned = try ct_alloc.val.intern(mod, sema.arena);3783 const interned = try ct_alloc.val.intern(pt, sema.arena);
3753 if (interned.canMutateComptimeVarState(mod)) {3784 if (interned.canMutateComptimeVarState(mod)) {
3754 // Preserve the comptime alloc, just make the pointer const.3785 // Preserve the comptime alloc, just make the pointer const.
3755 ct_alloc.val = .{ .interned = interned.toIntern() };3786 ct_alloc.val = .{ .interned = interned.toIntern() };
...@@ -3757,7 +3788,7 @@ fn zirMakePtrConst(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErro...@@ -3757,7 +3788,7 @@ fn zirMakePtrConst(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErro
3757 return sema.makePtrConst(block, alloc);3788 return sema.makePtrConst(block, alloc);
3758 } else {3789 } else {
3759 // Promote the constant to an anon decl.3790 // Promote the constant to an anon decl.
3760 const new_mut_ptr = Air.internedToRef(try mod.intern(.{ .ptr = .{3791 const new_mut_ptr = Air.internedToRef(try pt.intern(.{ .ptr = .{
3761 .ty = alloc_ty.toIntern(),3792 .ty = alloc_ty.toIntern(),
3762 .base_addr = .{ .anon_decl = .{3793 .base_addr = .{ .anon_decl = .{
3763 .val = interned.toIntern(),3794 .val = interned.toIntern(),
...@@ -3778,7 +3809,7 @@ fn zirMakePtrConst(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErro...@@ -3778,7 +3809,7 @@ fn zirMakePtrConst(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErro
3778 // The value was initialized through RLS, so we didn't detect the runtime condition earlier.3809 // The value was initialized through RLS, so we didn't detect the runtime condition earlier.
3779 // TODO: source location of runtime control flow3810 // TODO: source location of runtime control flow
3780 const init_src = block.src(.{ .node_offset_bin_rhs = inst_data.src_node });3811 const init_src = block.src(.{ .node_offset_bin_rhs = inst_data.src_node });
3781 return sema.fail(block, init_src, "value with comptime-only type '{}' depends on runtime control flow", .{elem_ty.fmt(mod)});3812 return sema.fail(block, init_src, "value with comptime-only type '{}' depends on runtime control flow", .{elem_ty.fmt(pt)});
3782 }3813 }
37833814
3784 // This is a runtime value.3815 // This is a runtime value.
...@@ -3788,7 +3819,8 @@ fn zirMakePtrConst(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErro...@@ -3788,7 +3819,8 @@ fn zirMakePtrConst(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErro
3788/// If `alloc` is an inferred allocation, `resolved_inferred_ty` is taken to be its resolved3819/// If `alloc` is an inferred allocation, `resolved_inferred_ty` is taken to be its resolved
3789/// type. Otherwise, it may be `null`, and the type will be inferred from `alloc`.3820/// type. Otherwise, it may be `null`, and the type will be inferred from `alloc`.
3790fn resolveComptimeKnownAllocPtr(sema: *Sema, block: *Block, alloc: Air.Inst.Ref, resolved_alloc_ty: ?Type) CompileError!?InternPool.Index {3821fn resolveComptimeKnownAllocPtr(sema: *Sema, block: *Block, alloc: Air.Inst.Ref, resolved_alloc_ty: ?Type) CompileError!?InternPool.Index {
3791 const zcu = sema.mod;3822 const pt = sema.pt;
3823 const zcu = pt.zcu;
37923824
3793 const alloc_ty = resolved_alloc_ty orelse sema.typeOf(alloc);3825 const alloc_ty = resolved_alloc_ty orelse sema.typeOf(alloc);
3794 const ptr_info = alloc_ty.ptrInfo(zcu);3826 const ptr_info = alloc_ty.ptrInfo(zcu);
...@@ -3831,7 +3863,7 @@ fn resolveComptimeKnownAllocPtr(sema: *Sema, block: *Block, alloc: Air.Inst.Ref,...@@ -3831,7 +3863,7 @@ fn resolveComptimeKnownAllocPtr(sema: *Sema, block: *Block, alloc: Air.Inst.Ref,
38313863
3832 const ct_alloc = try sema.newComptimeAlloc(block, elem_ty, ptr_info.flags.alignment);3864 const ct_alloc = try sema.newComptimeAlloc(block, elem_ty, ptr_info.flags.alignment);
38333865
3834 const alloc_ptr = try zcu.intern(.{ .ptr = .{3866 const alloc_ptr = try pt.intern(.{ .ptr = .{
3835 .ty = alloc_ty.toIntern(),3867 .ty = alloc_ty.toIntern(),
3836 .base_addr = .{ .comptime_alloc = ct_alloc },3868 .base_addr = .{ .comptime_alloc = ct_alloc },
3837 .byte_offset = 0,3869 .byte_offset = 0,
...@@ -3909,7 +3941,7 @@ fn resolveComptimeKnownAllocPtr(sema: *Sema, block: *Block, alloc: Air.Inst.Ref,...@@ -3909,7 +3941,7 @@ fn resolveComptimeKnownAllocPtr(sema: *Sema, block: *Block, alloc: Air.Inst.Ref,
3909 const idx_val = (try sema.resolveValue(data.rhs)).?;3941 const idx_val = (try sema.resolveValue(data.rhs)).?;
3910 break :blk .{3942 break :blk .{
3911 data.lhs,3943 data.lhs,
3912 .{ .elem = try idx_val.toUnsignedIntSema(zcu) },3944 .{ .elem = try idx_val.toUnsignedIntSema(pt) },
3913 };3945 };
3914 },3946 },
3915 .bitcast => .{3947 .bitcast => .{
...@@ -3935,32 +3967,32 @@ fn resolveComptimeKnownAllocPtr(sema: *Sema, block: *Block, alloc: Air.Inst.Ref,...@@ -3935,32 +3967,32 @@ fn resolveComptimeKnownAllocPtr(sema: *Sema, block: *Block, alloc: Air.Inst.Ref,
3935 };3967 };
3936 const new_ptr_ty = tmp_air.typeOfIndex(air_ptr, &zcu.intern_pool).toIntern();3968 const new_ptr_ty = tmp_air.typeOfIndex(air_ptr, &zcu.intern_pool).toIntern();
3937 const new_ptr = switch (method) {3969 const new_ptr = switch (method) {
3938 .same_addr => try zcu.intern_pool.getCoerced(sema.gpa, decl_parent_ptr, new_ptr_ty),3970 .same_addr => try zcu.intern_pool.getCoerced(sema.gpa, pt.tid, decl_parent_ptr, new_ptr_ty),
3939 .opt_payload => ptr: {3971 .opt_payload => ptr: {
3940 // Set the optional to non-null at comptime.3972 // Set the optional to non-null at comptime.
3941 // If the payload is OPV, we must use that value instead of undef.3973 // If the payload is OPV, we must use that value instead of undef.
3942 const opt_ty = Value.fromInterned(decl_parent_ptr).typeOf(zcu).childType(zcu);3974 const opt_ty = Value.fromInterned(decl_parent_ptr).typeOf(zcu).childType(zcu);
3943 const payload_ty = opt_ty.optionalChild(zcu);3975 const payload_ty = opt_ty.optionalChild(zcu);
3944 const payload_val = try sema.typeHasOnePossibleValue(payload_ty) orelse try zcu.undefValue(payload_ty);3976 const payload_val = try sema.typeHasOnePossibleValue(payload_ty) orelse try pt.undefValue(payload_ty);
3945 const opt_val = try zcu.intern(.{ .opt = .{3977 const opt_val = try pt.intern(.{ .opt = .{
3946 .ty = opt_ty.toIntern(),3978 .ty = opt_ty.toIntern(),
3947 .val = payload_val.toIntern(),3979 .val = payload_val.toIntern(),
3948 } });3980 } });
3949 try sema.storePtrVal(block, LazySrcLoc.unneeded, Value.fromInterned(decl_parent_ptr), Value.fromInterned(opt_val), opt_ty);3981 try sema.storePtrVal(block, LazySrcLoc.unneeded, Value.fromInterned(decl_parent_ptr), Value.fromInterned(opt_val), opt_ty);
3950 break :ptr (try Value.fromInterned(decl_parent_ptr).ptrOptPayload(zcu)).toIntern();3982 break :ptr (try Value.fromInterned(decl_parent_ptr).ptrOptPayload(pt)).toIntern();
3951 },3983 },
3952 .eu_payload => ptr: {3984 .eu_payload => ptr: {
3953 // Set the error union to non-error at comptime.3985 // Set the error union to non-error at comptime.
3954 // If the payload is OPV, we must use that value instead of undef.3986 // If the payload is OPV, we must use that value instead of undef.
3955 const eu_ty = Value.fromInterned(decl_parent_ptr).typeOf(zcu).childType(zcu);3987 const eu_ty = Value.fromInterned(decl_parent_ptr).typeOf(zcu).childType(zcu);
3956 const payload_ty = eu_ty.errorUnionPayload(zcu);3988 const payload_ty = eu_ty.errorUnionPayload(zcu);
3957 const payload_val = try sema.typeHasOnePossibleValue(payload_ty) orelse try zcu.undefValue(payload_ty);3989 const payload_val = try sema.typeHasOnePossibleValue(payload_ty) orelse try pt.undefValue(payload_ty);
3958 const eu_val = try zcu.intern(.{ .error_union = .{3990 const eu_val = try pt.intern(.{ .error_union = .{
3959 .ty = eu_ty.toIntern(),3991 .ty = eu_ty.toIntern(),
3960 .val = .{ .payload = payload_val.toIntern() },3992 .val = .{ .payload = payload_val.toIntern() },
3961 } });3993 } });
3962 try sema.storePtrVal(block, LazySrcLoc.unneeded, Value.fromInterned(decl_parent_ptr), Value.fromInterned(eu_val), eu_ty);3994 try sema.storePtrVal(block, LazySrcLoc.unneeded, Value.fromInterned(decl_parent_ptr), Value.fromInterned(eu_val), eu_ty);
3963 break :ptr (try Value.fromInterned(decl_parent_ptr).ptrEuPayload(zcu)).toIntern();3995 break :ptr (try Value.fromInterned(decl_parent_ptr).ptrEuPayload(pt)).toIntern();
3964 },3996 },
3965 .field => |idx| ptr: {3997 .field => |idx| ptr: {
3966 const maybe_union_ty = Value.fromInterned(decl_parent_ptr).typeOf(zcu).childType(zcu);3998 const maybe_union_ty = Value.fromInterned(decl_parent_ptr).typeOf(zcu).childType(zcu);
...@@ -3969,14 +4001,14 @@ fn resolveComptimeKnownAllocPtr(sema: *Sema, block: *Block, alloc: Air.Inst.Ref,...@@ -3969,14 +4001,14 @@ fn resolveComptimeKnownAllocPtr(sema: *Sema, block: *Block, alloc: Air.Inst.Ref,
3969 // If the payload is OPV, there will not be a payload store, so we store that value.4001 // If the payload is OPV, there will not be a payload store, so we store that value.
3970 // Otherwise, there will be a payload store to process later, so undef will suffice.4002 // Otherwise, there will be a payload store to process later, so undef will suffice.
3971 const payload_ty = Type.fromInterned(union_obj.field_types.get(&zcu.intern_pool)[idx]);4003 const payload_ty = Type.fromInterned(union_obj.field_types.get(&zcu.intern_pool)[idx]);
3972 const payload_val = try sema.typeHasOnePossibleValue(payload_ty) orelse try zcu.undefValue(payload_ty);4004 const payload_val = try sema.typeHasOnePossibleValue(payload_ty) orelse try pt.undefValue(payload_ty);
3973 const tag_val = try zcu.enumValueFieldIndex(Type.fromInterned(union_obj.enum_tag_ty), idx);4005 const tag_val = try pt.enumValueFieldIndex(Type.fromInterned(union_obj.enum_tag_ty), idx);
3974 const store_val = try zcu.unionValue(maybe_union_ty, tag_val, payload_val);4006 const store_val = try pt.unionValue(maybe_union_ty, tag_val, payload_val);
3975 try sema.storePtrVal(block, LazySrcLoc.unneeded, Value.fromInterned(decl_parent_ptr), store_val, maybe_union_ty);4007 try sema.storePtrVal(block, LazySrcLoc.unneeded, Value.fromInterned(decl_parent_ptr), store_val, maybe_union_ty);
3976 }4008 }
3977 break :ptr (try Value.fromInterned(decl_parent_ptr).ptrField(idx, zcu)).toIntern();4009 break :ptr (try Value.fromInterned(decl_parent_ptr).ptrField(idx, pt)).toIntern();
3978 },4010 },
3979 .elem => |idx| (try Value.fromInterned(decl_parent_ptr).ptrElem(idx, zcu)).toIntern(),4011 .elem => |idx| (try Value.fromInterned(decl_parent_ptr).ptrElem(idx, pt)).toIntern(),
3980 };4012 };
3981 try ptr_mapping.put(air_ptr, new_ptr);4013 try ptr_mapping.put(air_ptr, new_ptr);
3982 }4014 }
...@@ -4020,7 +4052,8 @@ fn finishResolveComptimeKnownAllocPtr(...@@ -4020,7 +4052,8 @@ fn finishResolveComptimeKnownAllocPtr(
4020 alloc_inst: Air.Inst.Index,4052 alloc_inst: Air.Inst.Index,
4021 comptime_info: MaybeComptimeAlloc,4053 comptime_info: MaybeComptimeAlloc,
4022) CompileError!?InternPool.Index {4054) CompileError!?InternPool.Index {
4023 const zcu = sema.mod;4055 const pt = sema.pt;
4056 const zcu = pt.zcu;
40244057
4025 // We're almost done - we have the resolved comptime value. We just need to4058 // We're almost done - we have the resolved comptime value. We just need to
4026 // eliminate the now-dead runtime instructions.4059 // eliminate the now-dead runtime instructions.
...@@ -4041,19 +4074,19 @@ fn finishResolveComptimeKnownAllocPtr(...@@ -4041,19 +4074,19 @@ fn finishResolveComptimeKnownAllocPtr(
40414074
4042 if (Value.fromInterned(result_val).canMutateComptimeVarState(zcu)) {4075 if (Value.fromInterned(result_val).canMutateComptimeVarState(zcu)) {
4043 const alloc_index = existing_comptime_alloc orelse a: {4076 const alloc_index = existing_comptime_alloc orelse a: {
4044 const idx = try sema.newComptimeAlloc(block, alloc_ty.childType(zcu), alloc_ty.ptrAlignment(zcu));4077 const idx = try sema.newComptimeAlloc(block, alloc_ty.childType(zcu), alloc_ty.ptrAlignment(pt));
4045 const alloc = sema.getComptimeAlloc(idx);4078 const alloc = sema.getComptimeAlloc(idx);
4046 alloc.val = .{ .interned = result_val };4079 alloc.val = .{ .interned = result_val };
4047 break :a idx;4080 break :a idx;
4048 };4081 };
4049 sema.getComptimeAlloc(alloc_index).is_const = true;4082 sema.getComptimeAlloc(alloc_index).is_const = true;
4050 return try zcu.intern(.{ .ptr = .{4083 return try pt.intern(.{ .ptr = .{
4051 .ty = alloc_ty.toIntern(),4084 .ty = alloc_ty.toIntern(),
4052 .base_addr = .{ .comptime_alloc = alloc_index },4085 .base_addr = .{ .comptime_alloc = alloc_index },
4053 .byte_offset = 0,4086 .byte_offset = 0,
4054 } });4087 } });
4055 } else {4088 } else {
4056 return try zcu.intern(.{ .ptr = .{4089 return try pt.intern(.{ .ptr = .{
4057 .ty = alloc_ty.toIntern(),4090 .ty = alloc_ty.toIntern(),
4058 .base_addr = .{ .anon_decl = .{4091 .base_addr = .{ .anon_decl = .{
4059 .orig_ty = alloc_ty.toIntern(),4092 .orig_ty = alloc_ty.toIntern(),
...@@ -4065,9 +4098,9 @@ fn finishResolveComptimeKnownAllocPtr(...@@ -4065,9 +4098,9 @@ fn finishResolveComptimeKnownAllocPtr(
4065}4098}
40664099
4067fn makePtrTyConst(sema: *Sema, ptr_ty: Type) CompileError!Type {4100fn makePtrTyConst(sema: *Sema, ptr_ty: Type) CompileError!Type {
4068 var ptr_info = ptr_ty.ptrInfo(sema.mod);4101 var ptr_info = ptr_ty.ptrInfo(sema.pt.zcu);
4069 ptr_info.flags.is_const = true;4102 ptr_info.flags.is_const = true;
4070 return sema.mod.ptrTypeSema(ptr_info);4103 return sema.pt.ptrTypeSema(ptr_info);
4071}4104}
40724105
4073fn makePtrConst(sema: *Sema, block: *Block, alloc: Air.Inst.Ref) CompileError!Air.Inst.Ref {4106fn makePtrConst(sema: *Sema, block: *Block, alloc: Air.Inst.Ref) CompileError!Air.Inst.Ref {
...@@ -4076,7 +4109,7 @@ fn makePtrConst(sema: *Sema, block: *Block, alloc: Air.Inst.Ref) CompileError!Ai...@@ -4076,7 +4109,7 @@ fn makePtrConst(sema: *Sema, block: *Block, alloc: Air.Inst.Ref) CompileError!Ai
40764109
4077 // Detect if a comptime value simply needs to have its type changed.4110 // Detect if a comptime value simply needs to have its type changed.
4078 if (try sema.resolveValue(alloc)) |val| {4111 if (try sema.resolveValue(alloc)) |val| {
4079 return Air.internedToRef((try sema.mod.getCoerced(val, const_ptr_ty)).toIntern());4112 return Air.internedToRef((try sema.pt.getCoerced(val, const_ptr_ty)).toIntern());
4080 }4113 }
40814114
4082 return block.addBitCast(const_ptr_ty, alloc);4115 return block.addBitCast(const_ptr_ty, alloc);
...@@ -4103,14 +4136,16 @@ fn zirAlloc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I...@@ -4103,14 +4136,16 @@ fn zirAlloc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I
4103 const tracy = trace(@src());4136 const tracy = trace(@src());
4104 defer tracy.end();4137 defer tracy.end();
41054138
4139 const pt = sema.pt;
4140
4106 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;4141 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;
4107 const ty_src = block.src(.{ .node_offset_var_decl_ty = inst_data.src_node });4142 const ty_src = block.src(.{ .node_offset_var_decl_ty = inst_data.src_node });
4108 const var_ty = try sema.resolveType(block, ty_src, inst_data.operand);4143 const var_ty = try sema.resolveType(block, ty_src, inst_data.operand);
4109 if (block.is_comptime) {4144 if (block.is_comptime) {
4110 return sema.analyzeComptimeAlloc(block, var_ty, .none);4145 return sema.analyzeComptimeAlloc(block, var_ty, .none);
4111 }4146 }
4112 const target = sema.mod.getTarget();4147 const target = pt.zcu.getTarget();
4113 const ptr_type = try sema.mod.ptrTypeSema(.{4148 const ptr_type = try pt.ptrTypeSema(.{
4114 .child = var_ty.toIntern(),4149 .child = var_ty.toIntern(),
4115 .flags = .{ .address_space = target_util.defaultAddressSpace(target, .local) },4150 .flags = .{ .address_space = target_util.defaultAddressSpace(target, .local) },
4116 });4151 });
...@@ -4125,6 +4160,8 @@ fn zirAllocMut(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -4125,6 +4160,8 @@ fn zirAllocMut(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
4125 const tracy = trace(@src());4160 const tracy = trace(@src());
4126 defer tracy.end();4161 defer tracy.end();
41274162
4163 const pt = sema.pt;
4164
4128 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;4165 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;
4129 const ty_src = block.src(.{ .node_offset_var_decl_ty = inst_data.src_node });4166 const ty_src = block.src(.{ .node_offset_var_decl_ty = inst_data.src_node });
4130 const var_ty = try sema.resolveType(block, ty_src, inst_data.operand);4167 const var_ty = try sema.resolveType(block, ty_src, inst_data.operand);
...@@ -4132,8 +4169,8 @@ fn zirAllocMut(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -4132,8 +4169,8 @@ fn zirAllocMut(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
4132 return sema.analyzeComptimeAlloc(block, var_ty, .none);4169 return sema.analyzeComptimeAlloc(block, var_ty, .none);
4133 }4170 }
4134 try sema.validateVarType(block, ty_src, var_ty, false);4171 try sema.validateVarType(block, ty_src, var_ty, false);
4135 const target = sema.mod.getTarget();4172 const target = pt.zcu.getTarget();
4136 const ptr_type = try sema.mod.ptrTypeSema(.{4173 const ptr_type = try pt.ptrTypeSema(.{
4137 .child = var_ty.toIntern(),4174 .child = var_ty.toIntern(),
4138 .flags = .{ .address_space = target_util.defaultAddressSpace(target, .local) },4175 .flags = .{ .address_space = target_util.defaultAddressSpace(target, .local) },
4139 });4176 });
...@@ -4181,7 +4218,8 @@ fn zirResolveInferredAlloc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Com...@@ -4181,7 +4218,8 @@ fn zirResolveInferredAlloc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Com
4181 const tracy = trace(@src());4218 const tracy = trace(@src());
4182 defer tracy.end();4219 defer tracy.end();
41834220
4184 const mod = sema.mod;4221 const pt = sema.pt;
4222 const mod = pt.zcu;
4185 const gpa = sema.gpa;4223 const gpa = sema.gpa;
4186 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;4224 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;
4187 const src = block.nodeOffset(inst_data.src_node);4225 const src = block.nodeOffset(inst_data.src_node);
...@@ -4206,7 +4244,7 @@ fn zirResolveInferredAlloc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Com...@@ -4206,7 +4244,7 @@ fn zirResolveInferredAlloc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Com
4206 .anon_decl => |a| a.val,4244 .anon_decl => |a| a.val,
4207 .comptime_alloc => |i| val: {4245 .comptime_alloc => |i| val: {
4208 const alloc = sema.getComptimeAlloc(i);4246 const alloc = sema.getComptimeAlloc(i);
4209 break :val (try alloc.val.intern(mod, sema.arena)).toIntern();4247 break :val (try alloc.val.intern(pt, sema.arena)).toIntern();
4210 },4248 },
4211 else => unreachable,4249 else => unreachable,
4212 };4250 };
...@@ -4232,7 +4270,7 @@ fn zirResolveInferredAlloc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Com...@@ -4232,7 +4270,7 @@ fn zirResolveInferredAlloc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Com
4232 }4270 }
4233 const final_elem_ty = try sema.resolvePeerTypes(block, ty_src, peer_vals, .none);4271 const final_elem_ty = try sema.resolvePeerTypes(block, ty_src, peer_vals, .none);
42344272
4235 const final_ptr_ty = try mod.ptrTypeSema(.{4273 const final_ptr_ty = try pt.ptrTypeSema(.{
4236 .child = final_elem_ty.toIntern(),4274 .child = final_elem_ty.toIntern(),
4237 .flags = .{4275 .flags = .{
4238 .alignment = ia1.alignment,4276 .alignment = ia1.alignment,
...@@ -4244,7 +4282,7 @@ fn zirResolveInferredAlloc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Com...@@ -4244,7 +4282,7 @@ fn zirResolveInferredAlloc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Com
4244 try sema.validateVarType(block, ty_src, final_elem_ty, false);4282 try sema.validateVarType(block, ty_src, final_elem_ty, false);
4245 } else if (try sema.resolveComptimeKnownAllocPtr(block, ptr, final_ptr_ty)) |ptr_val| {4283 } else if (try sema.resolveComptimeKnownAllocPtr(block, ptr, final_ptr_ty)) |ptr_val| {
4246 const const_ptr_ty = try sema.makePtrTyConst(final_ptr_ty);4284 const const_ptr_ty = try sema.makePtrTyConst(final_ptr_ty);
4247 const new_const_ptr = try mod.getCoerced(Value.fromInterned(ptr_val), const_ptr_ty);4285 const new_const_ptr = try pt.getCoerced(Value.fromInterned(ptr_val), const_ptr_ty);
42484286
4249 // Remap the ZIR operand to the resolved pointer value4287 // Remap the ZIR operand to the resolved pointer value
4250 sema.inst_map.putAssumeCapacity(inst_data.operand.toIndex().?, Air.internedToRef(new_const_ptr.toIntern()));4288 sema.inst_map.putAssumeCapacity(inst_data.operand.toIndex().?, Air.internedToRef(new_const_ptr.toIntern()));
...@@ -4252,7 +4290,7 @@ fn zirResolveInferredAlloc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Com...@@ -4252,7 +4290,7 @@ fn zirResolveInferredAlloc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Com
4252 // Unless the block is comptime, `alloc_inferred` always produces4290 // Unless the block is comptime, `alloc_inferred` always produces
4253 // a runtime constant. The final inferred type needs to be4291 // a runtime constant. The final inferred type needs to be
4254 // fully resolved so it can be lowered in codegen.4292 // fully resolved so it can be lowered in codegen.
4255 try final_elem_ty.resolveFully(mod);4293 try final_elem_ty.resolveFully(pt);
42564294
4257 return;4295 return;
4258 }4296 }
...@@ -4261,7 +4299,7 @@ fn zirResolveInferredAlloc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Com...@@ -4261,7 +4299,7 @@ fn zirResolveInferredAlloc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Com
4261 // The alloc wasn't comptime-known per the above logic, so the4299 // The alloc wasn't comptime-known per the above logic, so the
4262 // type cannot be comptime-only.4300 // type cannot be comptime-only.
4263 // TODO: source location of runtime control flow4301 // TODO: source location of runtime control flow
4264 return sema.fail(block, src, "value with comptime-only type '{}' depends on runtime control flow", .{final_elem_ty.fmt(mod)});4302 return sema.fail(block, src, "value with comptime-only type '{}' depends on runtime control flow", .{final_elem_ty.fmt(pt)});
4265 }4303 }
42664304
4267 // Change it to a normal alloc.4305 // Change it to a normal alloc.
...@@ -4318,7 +4356,8 @@ fn zirResolveInferredAlloc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Com...@@ -4318,7 +4356,8 @@ fn zirResolveInferredAlloc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Com
4318}4356}
43194357
4320fn zirForLen(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {4358fn zirForLen(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
4321 const mod = sema.mod;4359 const pt = sema.pt;
4360 const mod = pt.zcu;
4322 const gpa = sema.gpa;4361 const gpa = sema.gpa;
4323 const ip = &mod.intern_pool;4362 const ip = &mod.intern_pool;
4324 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;4363 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
...@@ -4355,7 +4394,7 @@ fn zirForLen(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air....@@ -4355,7 +4394,7 @@ fn zirForLen(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.
4355 if (!object_ty.isIndexable(mod)) {4394 if (!object_ty.isIndexable(mod)) {
4356 // Instead of using checkIndexable we customize this error.4395 // Instead of using checkIndexable we customize this error.
4357 const msg = msg: {4396 const msg = msg: {
4358 const msg = try sema.errMsg(arg_src, "type '{}' is not indexable and not a range", .{object_ty.fmt(sema.mod)});4397 const msg = try sema.errMsg(arg_src, "type '{}' is not indexable and not a range", .{object_ty.fmt(pt)});
4359 errdefer msg.destroy(sema.gpa);4398 errdefer msg.destroy(sema.gpa);
4360 try sema.errNote(arg_src, msg, "for loop operand must be a range, array, slice, tuple, or vector", .{});4399 try sema.errNote(arg_src, msg, "for loop operand must be a range, array, slice, tuple, or vector", .{});
43614400
...@@ -4369,7 +4408,7 @@ fn zirForLen(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air....@@ -4369,7 +4408,7 @@ fn zirForLen(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.
4369 }4408 }
4370 if (!object_ty.indexableHasLen(mod)) continue;4409 if (!object_ty.indexableHasLen(mod)) continue;
43714410
4372 break :l try sema.fieldVal(block, arg_src, object, try ip.getOrPutString(gpa, "len", .no_embedded_nulls), arg_src);4411 break :l try sema.fieldVal(block, arg_src, object, try ip.getOrPutString(gpa, pt.tid, "len", .no_embedded_nulls), arg_src);
4373 };4412 };
4374 const arg_len = try sema.coerce(block, Type.usize, arg_len_uncoerced, arg_src);4413 const arg_len = try sema.coerce(block, Type.usize, arg_len_uncoerced, arg_src);
4375 if (len == .none) {4414 if (len == .none) {
...@@ -4387,10 +4426,10 @@ fn zirForLen(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air....@@ -4387,10 +4426,10 @@ fn zirForLen(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.
4387 .input_index = len_idx,4426 .input_index = len_idx,
4388 } });4427 } });
4389 try sema.errNote(a_src, msg, "length {} here", .{4428 try sema.errNote(a_src, msg, "length {} here", .{
4390 v.fmtValue(sema.mod, sema),4429 v.fmtValue(pt, sema),
4391 });4430 });
4392 try sema.errNote(arg_src, msg, "length {} here", .{4431 try sema.errNote(arg_src, msg, "length {} here", .{
4393 arg_val.fmtValue(sema.mod, sema),4432 arg_val.fmtValue(pt, sema),
4394 });4433 });
4395 break :msg msg;4434 break :msg msg;
4396 };4435 };
...@@ -4427,7 +4466,7 @@ fn zirForLen(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air....@@ -4427,7 +4466,7 @@ fn zirForLen(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.
4427 .input_index = i,4466 .input_index = i,
4428 } });4467 } });
4429 try sema.errNote(arg_src, msg, "type '{}' has no upper bound", .{4468 try sema.errNote(arg_src, msg, "type '{}' has no upper bound", .{
4430 object_ty.fmt(sema.mod),4469 object_ty.fmt(pt),
4431 });4470 });
4432 }4471 }
4433 break :msg msg;4472 break :msg msg;
...@@ -4453,7 +4492,8 @@ fn zirForLen(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air....@@ -4453,7 +4492,8 @@ fn zirForLen(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.
4453/// Given a `*E!?T`, returns a (valid) `*T`.4492/// Given a `*E!?T`, returns a (valid) `*T`.
4454/// May invalidate already-stored payload data.4493/// May invalidate already-stored payload data.
4455fn optEuBasePtrInit(sema: *Sema, block: *Block, ptr: Air.Inst.Ref, src: LazySrcLoc) CompileError!Air.Inst.Ref {4494fn optEuBasePtrInit(sema: *Sema, block: *Block, ptr: Air.Inst.Ref, src: LazySrcLoc) CompileError!Air.Inst.Ref {
4456 const mod = sema.mod;4495 const pt = sema.pt;
4496 const mod = pt.zcu;
4457 var base_ptr = ptr;4497 var base_ptr = ptr;
4458 while (true) switch (sema.typeOf(base_ptr).childType(mod).zigTypeTag(mod)) {4498 while (true) switch (sema.typeOf(base_ptr).childType(mod).zigTypeTag(mod)) {
4459 .ErrorUnion => base_ptr = try sema.analyzeErrUnionPayloadPtr(block, src, base_ptr, false, true),4499 .ErrorUnion => base_ptr = try sema.analyzeErrUnionPayloadPtr(block, src, base_ptr, false, true),
...@@ -4471,7 +4511,8 @@ fn zirOptEuBasePtrInit(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Compile...@@ -4471,7 +4511,8 @@ fn zirOptEuBasePtrInit(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Compile
4471}4511}
44724512
4473fn zirCoercePtrElemTy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {4513fn zirCoercePtrElemTy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
4474 const mod = sema.mod;4514 const pt = sema.pt;
4515 const mod = pt.zcu;
4475 const pl_node = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;4516 const pl_node = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
4476 const src = block.nodeOffset(pl_node.src_node);4517 const src = block.nodeOffset(pl_node.src_node);
4477 const extra = sema.code.extraData(Zir.Inst.Bin, pl_node.payload_index).data;4518 const extra = sema.code.extraData(Zir.Inst.Bin, pl_node.payload_index).data;
...@@ -4503,10 +4544,10 @@ fn zirCoercePtrElemTy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileE...@@ -4503,10 +4544,10 @@ fn zirCoercePtrElemTy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileE
4503 switch (val_ty.zigTypeTag(mod)) {4544 switch (val_ty.zigTypeTag(mod)) {
4504 .Array, .Vector => {},4545 .Array, .Vector => {},
4505 else => if (!val_ty.isTuple(mod)) {4546 else => if (!val_ty.isTuple(mod)) {
4506 return sema.fail(block, src, "expected array of '{}', found '{}'", .{ elem_ty.fmt(mod), val_ty.fmt(mod) });4547 return sema.fail(block, src, "expected array of '{}', found '{}'", .{ elem_ty.fmt(pt), val_ty.fmt(pt) });
4507 },4548 },
4508 }4549 }
4509 const want_ty = try mod.arrayType(.{4550 const want_ty = try pt.arrayType(.{
4510 .len = val_ty.arrayLen(mod),4551 .len = val_ty.arrayLen(mod),
4511 .child = elem_ty.toIntern(),4552 .child = elem_ty.toIntern(),
4512 .sentinel = if (ptr_ty.sentinel(mod)) |s| s.toIntern() else .none,4553 .sentinel = if (ptr_ty.sentinel(mod)) |s| s.toIntern() else .none,
...@@ -4522,7 +4563,8 @@ fn zirCoercePtrElemTy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileE...@@ -4522,7 +4563,8 @@ fn zirCoercePtrElemTy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileE
4522}4563}
45234564
4524fn zirValidateRefTy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void {4565fn zirValidateRefTy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void {
4525 const mod = sema.mod;4566 const pt = sema.pt;
4567 const mod = pt.zcu;
4526 const un_tok = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_tok;4568 const un_tok = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_tok;
4527 const src = block.tokenOffset(un_tok.src_tok);4569 const src = block.tokenOffset(un_tok.src_tok);
4528 // In case of GenericPoison, we don't actually have a type, so this will be4570 // In case of GenericPoison, we don't actually have a type, so this will be
...@@ -4538,7 +4580,7 @@ fn zirValidateRefTy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErr...@@ -4538,7 +4580,7 @@ fn zirValidateRefTy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErr
4538 if (ty_operand.isGenericPoison()) return;4580 if (ty_operand.isGenericPoison()) return;
4539 if (ty_operand.optEuBaseType(mod).zigTypeTag(mod) != .Pointer) {4581 if (ty_operand.optEuBaseType(mod).zigTypeTag(mod) != .Pointer) {
4540 return sema.failWithOwnedErrorMsg(block, msg: {4582 return sema.failWithOwnedErrorMsg(block, msg: {
4541 const msg = try sema.errMsg(src, "expected type '{}', found pointer", .{ty_operand.fmt(mod)});4583 const msg = try sema.errMsg(src, "expected type '{}', found pointer", .{ty_operand.fmt(pt)});
4542 errdefer msg.destroy(sema.gpa);4584 errdefer msg.destroy(sema.gpa);
4543 try sema.errNote(src, msg, "address-of operator always returns a pointer", .{});4585 try sema.errNote(src, msg, "address-of operator always returns a pointer", .{});
4544 break :msg msg;4586 break :msg msg;
...@@ -4551,7 +4593,8 @@ fn zirValidateArrayInitRefTy(...@@ -4551,7 +4593,8 @@ fn zirValidateArrayInitRefTy(
4551 block: *Block,4593 block: *Block,
4552 inst: Zir.Inst.Index,4594 inst: Zir.Inst.Index,
4553) CompileError!Air.Inst.Ref {4595) CompileError!Air.Inst.Ref {
4554 const mod = sema.mod;4596 const pt = sema.pt;
4597 const mod = pt.zcu;
4555 const pl_node = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;4598 const pl_node = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
4556 const src = block.nodeOffset(pl_node.src_node);4599 const src = block.nodeOffset(pl_node.src_node);
4557 const extra = sema.code.extraData(Zir.Inst.ArrayInitRefTy, pl_node.payload_index).data;4600 const extra = sema.code.extraData(Zir.Inst.ArrayInitRefTy, pl_node.payload_index).data;
...@@ -4565,7 +4608,7 @@ fn zirValidateArrayInitRefTy(...@@ -4565,7 +4608,7 @@ fn zirValidateArrayInitRefTy(
4565 .ptr_type => |ptr_type| switch (ptr_type.flags.size) {4608 .ptr_type => |ptr_type| switch (ptr_type.flags.size) {
4566 .Slice, .Many => {4609 .Slice, .Many => {
4567 // Use array of correct length4610 // Use array of correct length
4568 const arr_ty = try mod.arrayType(.{4611 const arr_ty = try pt.arrayType(.{
4569 .len = extra.elem_count,4612 .len = extra.elem_count,
4570 .child = ptr_ty.childType(mod).toIntern(),4613 .child = ptr_ty.childType(mod).toIntern(),
4571 .sentinel = if (ptr_ty.sentinel(mod)) |s| s.toIntern() else .none,4614 .sentinel = if (ptr_ty.sentinel(mod)) |s| s.toIntern() else .none,
...@@ -4593,7 +4636,8 @@ fn zirValidateArrayInitTy(...@@ -4593,7 +4636,8 @@ fn zirValidateArrayInitTy(
4593 inst: Zir.Inst.Index,4636 inst: Zir.Inst.Index,
4594 is_result_ty: bool,4637 is_result_ty: bool,
4595) CompileError!void {4638) CompileError!void {
4596 const mod = sema.mod;4639 const pt = sema.pt;
4640 const mod = pt.zcu;
4597 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;4641 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
4598 const src = block.nodeOffset(inst_data.src_node);4642 const src = block.nodeOffset(inst_data.src_node);
4599 const ty_src: LazySrcLoc = if (is_result_ty) src else block.src(.{ .node_offset_init_ty = inst_data.src_node });4643 const ty_src: LazySrcLoc = if (is_result_ty) src else block.src(.{ .node_offset_init_ty = inst_data.src_node });
...@@ -4615,7 +4659,8 @@ fn validateArrayInitTy(...@@ -4615,7 +4659,8 @@ fn validateArrayInitTy(
4615 init_count: u32,4659 init_count: u32,
4616 ty: Type,4660 ty: Type,
4617) CompileError!void {4661) CompileError!void {
4618 const mod = sema.mod;4662 const pt = sema.pt;
4663 const mod = pt.zcu;
4619 switch (ty.zigTypeTag(mod)) {4664 switch (ty.zigTypeTag(mod)) {
4620 .Array => {4665 .Array => {
4621 const array_len = ty.arrayLen(mod);4666 const array_len = ty.arrayLen(mod);
...@@ -4636,7 +4681,7 @@ fn validateArrayInitTy(...@@ -4636,7 +4681,7 @@ fn validateArrayInitTy(
4636 return;4681 return;
4637 },4682 },
4638 .Struct => if (ty.isTuple(mod)) {4683 .Struct => if (ty.isTuple(mod)) {
4639 try ty.resolveFields(mod);4684 try ty.resolveFields(pt);
4640 const array_len = ty.arrayLen(mod);4685 const array_len = ty.arrayLen(mod);
4641 if (init_count > array_len) {4686 if (init_count > array_len) {
4642 return sema.fail(block, src, "expected at most {d} tuple fields; found {d}", .{4687 return sema.fail(block, src, "expected at most {d} tuple fields; found {d}", .{
...@@ -4656,7 +4701,8 @@ fn zirValidateStructInitTy(...@@ -4656,7 +4701,8 @@ fn zirValidateStructInitTy(
4656 inst: Zir.Inst.Index,4701 inst: Zir.Inst.Index,
4657 is_result_ty: bool,4702 is_result_ty: bool,
4658) CompileError!void {4703) CompileError!void {
4659 const mod = sema.mod;4704 const pt = sema.pt;
4705 const mod = pt.zcu;
4660 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;4706 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;
4661 const src = block.nodeOffset(inst_data.src_node);4707 const src = block.nodeOffset(inst_data.src_node);
4662 const ty = sema.resolveType(block, src, inst_data.operand) catch |err| switch (err) {4708 const ty = sema.resolveType(block, src, inst_data.operand) catch |err| switch (err) {
...@@ -4681,7 +4727,8 @@ fn zirValidatePtrStructInit(...@@ -4681,7 +4727,8 @@ fn zirValidatePtrStructInit(
4681 const tracy = trace(@src());4727 const tracy = trace(@src());
4682 defer tracy.end();4728 defer tracy.end();
46834729
4684 const mod = sema.mod;4730 const pt = sema.pt;
4731 const mod = pt.zcu;
4685 const validate_inst = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;4732 const validate_inst = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
4686 const init_src = block.nodeOffset(validate_inst.src_node);4733 const init_src = block.nodeOffset(validate_inst.src_node);
4687 const validate_extra = sema.code.extraData(Zir.Inst.Block, validate_inst.payload_index);4734 const validate_extra = sema.code.extraData(Zir.Inst.Block, validate_inst.payload_index);
...@@ -4716,7 +4763,8 @@ fn validateUnionInit(...@@ -4716,7 +4763,8 @@ fn validateUnionInit(
4716 instrs: []const Zir.Inst.Index,4763 instrs: []const Zir.Inst.Index,
4717 union_ptr: Air.Inst.Ref,4764 union_ptr: Air.Inst.Ref,
4718) CompileError!void {4765) CompileError!void {
4719 const mod = sema.mod;4766 const pt = sema.pt;
4767 const mod = pt.zcu;
4720 const gpa = sema.gpa;4768 const gpa = sema.gpa;
47214769
4722 if (instrs.len != 1) {4770 if (instrs.len != 1) {
...@@ -4752,6 +4800,7 @@ fn validateUnionInit(...@@ -4752,6 +4800,7 @@ fn validateUnionInit(
4752 const field_ptr_extra = sema.code.extraData(Zir.Inst.Field, field_ptr_data.payload_index).data;4800 const field_ptr_extra = sema.code.extraData(Zir.Inst.Field, field_ptr_data.payload_index).data;
4753 const field_name = try mod.intern_pool.getOrPutString(4801 const field_name = try mod.intern_pool.getOrPutString(
4754 gpa,4802 gpa,
4803 pt.tid,
4755 sema.code.nullTerminatedString(field_ptr_extra.field_name_start),4804 sema.code.nullTerminatedString(field_ptr_extra.field_name_start),
4756 .no_embedded_nulls,4805 .no_embedded_nulls,
4757 );4806 );
...@@ -4814,7 +4863,7 @@ fn validateUnionInit(...@@ -4814,7 +4863,7 @@ fn validateUnionInit(
4814 }4863 }
48154864
4816 const tag_ty = union_ty.unionTagTypeHypothetical(mod);4865 const tag_ty = union_ty.unionTagTypeHypothetical(mod);
4817 const tag_val = try mod.enumValueFieldIndex(tag_ty, field_index);4866 const tag_val = try pt.enumValueFieldIndex(tag_ty, field_index);
4818 const field_type = union_ty.unionFieldType(tag_val, mod).?;4867 const field_type = union_ty.unionFieldType(tag_val, mod).?;
48194868
4820 if (try sema.typeHasOnePossibleValue(field_type)) |field_only_value| {4869 if (try sema.typeHasOnePossibleValue(field_type)) |field_only_value| {
...@@ -4848,7 +4897,7 @@ fn validateUnionInit(...@@ -4848,7 +4897,7 @@ fn validateUnionInit(
4848 }4897 }
4849 block.instructions.shrinkRetainingCapacity(block_index);4898 block.instructions.shrinkRetainingCapacity(block_index);
48504899
4851 const union_val = try mod.intern(.{ .un = .{4900 const union_val = try pt.intern(.{ .un = .{
4852 .ty = union_ty.toIntern(),4901 .ty = union_ty.toIntern(),
4853 .tag = tag_val.toIntern(),4902 .tag = tag_val.toIntern(),
4854 .val = val.toIntern(),4903 .val = val.toIntern(),
...@@ -4875,7 +4924,8 @@ fn validateStructInit(...@@ -4875,7 +4924,8 @@ fn validateStructInit(
4875 init_src: LazySrcLoc,4924 init_src: LazySrcLoc,
4876 instrs: []const Zir.Inst.Index,4925 instrs: []const Zir.Inst.Index,
4877) CompileError!void {4926) CompileError!void {
4878 const mod = sema.mod;4927 const pt = sema.pt;
4928 const mod = pt.zcu;
4879 const gpa = sema.gpa;4929 const gpa = sema.gpa;
4880 const ip = &mod.intern_pool;4930 const ip = &mod.intern_pool;
48814931
...@@ -4896,6 +4946,7 @@ fn validateStructInit(...@@ -4896,6 +4946,7 @@ fn validateStructInit(
4896 struct_ptr_zir_ref = field_ptr_extra.lhs;4946 struct_ptr_zir_ref = field_ptr_extra.lhs;
4897 const field_name = try ip.getOrPutString(4947 const field_name = try ip.getOrPutString(
4898 gpa,4948 gpa,
4949 pt.tid,
4899 sema.code.nullTerminatedString(field_ptr_extra.field_name_start),4950 sema.code.nullTerminatedString(field_ptr_extra.field_name_start),
4900 .no_embedded_nulls,4951 .no_embedded_nulls,
4901 );4952 );
...@@ -4914,7 +4965,7 @@ fn validateStructInit(...@@ -4914,7 +4965,7 @@ fn validateStructInit(
4914 if (block.is_comptime and4965 if (block.is_comptime and
4915 (try sema.resolveDefinedValue(block, init_src, struct_ptr)) != null)4966 (try sema.resolveDefinedValue(block, init_src, struct_ptr)) != null)
4916 {4967 {
4917 try struct_ty.resolveLayout(mod);4968 try struct_ty.resolveLayout(pt);
4918 // In this case the only thing we need to do is evaluate the implicit4969 // In this case the only thing we need to do is evaluate the implicit
4919 // store instructions for default field values, and report any missing fields.4970 // store instructions for default field values, and report any missing fields.
4920 // Avoid the cost of the extra machinery for detecting a comptime struct init value.4971 // Avoid the cost of the extra machinery for detecting a comptime struct init value.
...@@ -4922,7 +4973,7 @@ fn validateStructInit(...@@ -4922,7 +4973,7 @@ fn validateStructInit(
4922 const i: u32 = @intCast(i_usize);4973 const i: u32 = @intCast(i_usize);
4923 if (field_ptr != .none) continue;4974 if (field_ptr != .none) continue;
49244975
4925 try struct_ty.resolveStructFieldInits(mod);4976 try struct_ty.resolveStructFieldInits(pt);
4926 const default_val = struct_ty.structFieldDefaultValue(i, mod);4977 const default_val = struct_ty.structFieldDefaultValue(i, mod);
4927 if (default_val.toIntern() == .unreachable_value) {4978 if (default_val.toIntern() == .unreachable_value) {
4928 const field_name = struct_ty.structFieldName(i, mod).unwrap() orelse {4979 const field_name = struct_ty.structFieldName(i, mod).unwrap() orelse {
...@@ -4971,7 +5022,7 @@ fn validateStructInit(...@@ -4971,7 +5022,7 @@ fn validateStructInit(
4971 const air_tags = sema.air_instructions.items(.tag);5022 const air_tags = sema.air_instructions.items(.tag);
4972 const air_datas = sema.air_instructions.items(.data);5023 const air_datas = sema.air_instructions.items(.data);
49735024
4974 try struct_ty.resolveStructFieldInits(mod);5025 try struct_ty.resolveStructFieldInits(pt);
49755026
4976 // We collect the comptime field values in case the struct initialization5027 // We collect the comptime field values in case the struct initialization
4977 // ends up being comptime-known.5028 // ends up being comptime-known.
...@@ -5094,7 +5145,7 @@ fn validateStructInit(...@@ -5094,7 +5145,7 @@ fn validateStructInit(
5094 for (block.instructions.items[first_block_index..]) |cur_inst| {5145 for (block.instructions.items[first_block_index..]) |cur_inst| {
5095 while (field_ptr_ref == .none and init_index < instrs.len) : (init_index += 1) {5146 while (field_ptr_ref == .none and init_index < instrs.len) : (init_index += 1) {
5096 const field_ty = struct_ty.structFieldType(field_indices[init_index], mod);5147 const field_ty = struct_ty.structFieldType(field_indices[init_index], mod);
5097 if (try field_ty.onePossibleValue(mod)) |_| continue;5148 if (try field_ty.onePossibleValue(pt)) |_| continue;
5098 field_ptr_ref = sema.inst_map.get(instrs[init_index]).?;5149 field_ptr_ref = sema.inst_map.get(instrs[init_index]).?;
5099 }5150 }
5100 switch (air_tags[@intFromEnum(cur_inst)]) {5151 switch (air_tags[@intFromEnum(cur_inst)]) {
...@@ -5122,7 +5173,7 @@ fn validateStructInit(...@@ -5122,7 +5173,7 @@ fn validateStructInit(
5122 }5173 }
5123 block.instructions.shrinkRetainingCapacity(block_index);5174 block.instructions.shrinkRetainingCapacity(block_index);
51245175
5125 const struct_val = try mod.intern(.{ .aggregate = .{5176 const struct_val = try pt.intern(.{ .aggregate = .{
5126 .ty = struct_ty.toIntern(),5177 .ty = struct_ty.toIntern(),
5127 .storage = .{ .elems = field_values },5178 .storage = .{ .elems = field_values },
5128 } });5179 } });
...@@ -5130,7 +5181,7 @@ fn validateStructInit(...@@ -5130,7 +5181,7 @@ fn validateStructInit(
5130 try sema.storePtr2(block, init_src, struct_ptr, init_src, struct_init, init_src, .store);5181 try sema.storePtr2(block, init_src, struct_ptr, init_src, struct_init, init_src, .store);
5131 return;5182 return;
5132 }5183 }
5133 try struct_ty.resolveLayout(mod);5184 try struct_ty.resolveLayout(pt);
51345185
5135 // Our task is to insert `store` instructions for all the default field values.5186 // Our task is to insert `store` instructions for all the default field values.
5136 for (found_fields, 0..) |field_ptr, i| {5187 for (found_fields, 0..) |field_ptr, i| {
...@@ -5152,7 +5203,8 @@ fn zirValidatePtrArrayInit(...@@ -5152,7 +5203,8 @@ fn zirValidatePtrArrayInit(
5152 block: *Block,5203 block: *Block,
5153 inst: Zir.Inst.Index,5204 inst: Zir.Inst.Index,
5154) CompileError!void {5205) CompileError!void {
5155 const mod = sema.mod;5206 const pt = sema.pt;
5207 const mod = pt.zcu;
5156 const validate_inst = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;5208 const validate_inst = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
5157 const init_src = block.nodeOffset(validate_inst.src_node);5209 const init_src = block.nodeOffset(validate_inst.src_node);
5158 const validate_extra = sema.code.extraData(Zir.Inst.Block, validate_inst.payload_index);5210 const validate_extra = sema.code.extraData(Zir.Inst.Block, validate_inst.payload_index);
...@@ -5175,7 +5227,7 @@ fn zirValidatePtrArrayInit(...@@ -5175,7 +5227,7 @@ fn zirValidatePtrArrayInit(
5175 var root_msg: ?*Module.ErrorMsg = null;5227 var root_msg: ?*Module.ErrorMsg = null;
5176 errdefer if (root_msg) |msg| msg.destroy(sema.gpa);5228 errdefer if (root_msg) |msg| msg.destroy(sema.gpa);
51775229
5178 try array_ty.resolveStructFieldInits(mod);5230 try array_ty.resolveStructFieldInits(pt);
5179 var i = instrs.len;5231 var i = instrs.len;
5180 while (i < array_len) : (i += 1) {5232 while (i < array_len) : (i += 1) {
5181 const default_val = array_ty.structFieldDefaultValue(i, mod).toIntern();5233 const default_val = array_ty.structFieldDefaultValue(i, mod).toIntern();
...@@ -5218,7 +5270,7 @@ fn zirValidatePtrArrayInit(...@@ -5218,7 +5270,7 @@ fn zirValidatePtrArrayInit(
5218 // sentinel-terminated array, the sentinel will not have been populated by5270 // sentinel-terminated array, the sentinel will not have been populated by
5219 // any ZIR instructions at comptime; we need to do that here.5271 // any ZIR instructions at comptime; we need to do that here.
5220 if (array_ty.sentinel(mod)) |sentinel_val| {5272 if (array_ty.sentinel(mod)) |sentinel_val| {
5221 const array_len_ref = try mod.intRef(Type.usize, array_len);5273 const array_len_ref = try pt.intRef(Type.usize, array_len);
5222 const sentinel_ptr = try sema.elemPtrArray(block, init_src, init_src, array_ptr, init_src, array_len_ref, true, true);5274 const sentinel_ptr = try sema.elemPtrArray(block, init_src, init_src, array_ptr, init_src, array_len_ref, true, true);
5223 const sentinel = Air.internedToRef(sentinel_val.toIntern());5275 const sentinel = Air.internedToRef(sentinel_val.toIntern());
5224 try sema.storePtr2(block, init_src, sentinel_ptr, init_src, sentinel, init_src, .store);5276 try sema.storePtr2(block, init_src, sentinel_ptr, init_src, sentinel, init_src, .store);
...@@ -5244,8 +5296,8 @@ fn zirValidatePtrArrayInit(...@@ -5244,8 +5296,8 @@ fn zirValidatePtrArrayInit(
52445296
5245 if (array_ty.isTuple(mod)) {5297 if (array_ty.isTuple(mod)) {
5246 if (array_ty.structFieldIsComptime(i, mod))5298 if (array_ty.structFieldIsComptime(i, mod))
5247 try array_ty.resolveStructFieldInits(mod);5299 try array_ty.resolveStructFieldInits(pt);
5248 if (try array_ty.structFieldValueComptime(mod, i)) |opv| {5300 if (try array_ty.structFieldValueComptime(pt, i)) |opv| {
5249 element_vals[i] = opv.toIntern();5301 element_vals[i] = opv.toIntern();
5250 continue;5302 continue;
5251 }5303 }
...@@ -5347,7 +5399,7 @@ fn zirValidatePtrArrayInit(...@@ -5347,7 +5399,7 @@ fn zirValidatePtrArrayInit(
5347 }5399 }
5348 block.instructions.shrinkRetainingCapacity(block_index);5400 block.instructions.shrinkRetainingCapacity(block_index);
53495401
5350 const array_val = try mod.intern(.{ .aggregate = .{5402 const array_val = try pt.intern(.{ .aggregate = .{
5351 .ty = array_ty.toIntern(),5403 .ty = array_ty.toIntern(),
5352 .storage = .{ .elems = element_vals },5404 .storage = .{ .elems = element_vals },
5353 } });5405 } });
...@@ -5357,18 +5409,19 @@ fn zirValidatePtrArrayInit(...@@ -5357,18 +5409,19 @@ fn zirValidatePtrArrayInit(
5357}5409}
53585410
5359fn zirValidateDeref(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void {5411fn zirValidateDeref(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void {
5360 const mod = sema.mod;5412 const pt = sema.pt;
5413 const mod = pt.zcu;
5361 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;5414 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;
5362 const src = block.nodeOffset(inst_data.src_node);5415 const src = block.nodeOffset(inst_data.src_node);
5363 const operand = try sema.resolveInst(inst_data.operand);5416 const operand = try sema.resolveInst(inst_data.operand);
5364 const operand_ty = sema.typeOf(operand);5417 const operand_ty = sema.typeOf(operand);
53655418
5366 if (operand_ty.zigTypeTag(mod) != .Pointer) {5419 if (operand_ty.zigTypeTag(mod) != .Pointer) {
5367 return sema.fail(block, src, "cannot dereference non-pointer type '{}'", .{operand_ty.fmt(mod)});5420 return sema.fail(block, src, "cannot dereference non-pointer type '{}'", .{operand_ty.fmt(pt)});
5368 } else switch (operand_ty.ptrSize(mod)) {5421 } else switch (operand_ty.ptrSize(mod)) {
5369 .One, .C => {},5422 .One, .C => {},
5370 .Many => return sema.fail(block, src, "index syntax required for unknown-length pointer type '{}'", .{operand_ty.fmt(mod)}),5423 .Many => return sema.fail(block, src, "index syntax required for unknown-length pointer type '{}'", .{operand_ty.fmt(pt)}),
5371 .Slice => return sema.fail(block, src, "index syntax required for slice type '{}'", .{operand_ty.fmt(mod)}),5424 .Slice => return sema.fail(block, src, "index syntax required for slice type '{}'", .{operand_ty.fmt(pt)}),
5372 }5425 }
53735426
5374 if ((try sema.typeHasOnePossibleValue(operand_ty.childType(mod))) != null) {5427 if ((try sema.typeHasOnePossibleValue(operand_ty.childType(mod))) != null) {
...@@ -5386,7 +5439,7 @@ fn zirValidateDeref(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErr...@@ -5386,7 +5439,7 @@ fn zirValidateDeref(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErr
5386 const msg = try sema.errMsg(5439 const msg = try sema.errMsg(
5387 src,5440 src,
5388 "values of type '{}' must be comptime-known, but operand value is runtime-known",5441 "values of type '{}' must be comptime-known, but operand value is runtime-known",
5389 .{elem_ty.fmt(mod)},5442 .{elem_ty.fmt(pt)},
5390 );5443 );
5391 errdefer msg.destroy(sema.gpa);5444 errdefer msg.destroy(sema.gpa);
53925445
...@@ -5398,7 +5451,8 @@ fn zirValidateDeref(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErr...@@ -5398,7 +5451,8 @@ fn zirValidateDeref(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErr
5398}5451}
53995452
5400fn zirValidateDestructure(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void {5453fn zirValidateDestructure(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void {
5401 const mod = sema.mod;5454 const pt = sema.pt;
5455 const mod = pt.zcu;
5402 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;5456 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
5403 const extra = sema.code.extraData(Zir.Inst.ValidateDestructure, inst_data.payload_index).data;5457 const extra = sema.code.extraData(Zir.Inst.ValidateDestructure, inst_data.payload_index).data;
5404 const src = block.nodeOffset(inst_data.src_node);5458 const src = block.nodeOffset(inst_data.src_node);
...@@ -5414,7 +5468,7 @@ fn zirValidateDestructure(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Comp...@@ -5414,7 +5468,7 @@ fn zirValidateDestructure(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Comp
54145468
5415 if (!can_destructure) {5469 if (!can_destructure) {
5416 return sema.failWithOwnedErrorMsg(block, msg: {5470 return sema.failWithOwnedErrorMsg(block, msg: {
5417 const msg = try sema.errMsg(src, "type '{}' cannot be destructured", .{operand_ty.fmt(mod)});5471 const msg = try sema.errMsg(src, "type '{}' cannot be destructured", .{operand_ty.fmt(pt)});
5418 errdefer msg.destroy(sema.gpa);5472 errdefer msg.destroy(sema.gpa);
5419 try sema.errNote(destructure_src, msg, "result destructured here", .{});5473 try sema.errNote(destructure_src, msg, "result destructured here", .{});
5420 break :msg msg;5474 break :msg msg;
...@@ -5441,7 +5495,8 @@ fn failWithBadMemberAccess(...@@ -5441,7 +5495,8 @@ fn failWithBadMemberAccess(
5441 field_src: LazySrcLoc,5495 field_src: LazySrcLoc,
5442 field_name: InternPool.NullTerminatedString,5496 field_name: InternPool.NullTerminatedString,
5443) CompileError {5497) CompileError {
5444 const mod = sema.mod;5498 const pt = sema.pt;
5499 const mod = pt.zcu;
5445 const kw_name = switch (agg_ty.zigTypeTag(mod)) {5500 const kw_name = switch (agg_ty.zigTypeTag(mod)) {
5446 .Union => "union",5501 .Union => "union",
5447 .Struct => "struct",5502 .Struct => "struct",
...@@ -5451,12 +5506,12 @@ fn failWithBadMemberAccess(...@@ -5451,12 +5506,12 @@ fn failWithBadMemberAccess(
5451 };5506 };
5452 if (agg_ty.getOwnerDeclOrNull(mod)) |some| if (mod.declIsRoot(some)) {5507 if (agg_ty.getOwnerDeclOrNull(mod)) |some| if (mod.declIsRoot(some)) {
5453 return sema.fail(block, field_src, "root struct of file '{}' has no member named '{}'", .{5508 return sema.fail(block, field_src, "root struct of file '{}' has no member named '{}'", .{
5454 agg_ty.fmt(mod), field_name.fmt(&mod.intern_pool),5509 agg_ty.fmt(pt), field_name.fmt(&mod.intern_pool),
5455 });5510 });
5456 };5511 };
54575512
5458 return sema.fail(block, field_src, "{s} '{}' has no member named '{}'", .{5513 return sema.fail(block, field_src, "{s} '{}' has no member named '{}'", .{
5459 kw_name, agg_ty.fmt(mod), field_name.fmt(&mod.intern_pool),5514 kw_name, agg_ty.fmt(pt), field_name.fmt(&mod.intern_pool),
5460 });5515 });
5461}5516}
54625517
...@@ -5468,18 +5523,19 @@ fn failWithBadStructFieldAccess(...@@ -5468,18 +5523,19 @@ fn failWithBadStructFieldAccess(
5468 field_src: LazySrcLoc,5523 field_src: LazySrcLoc,
5469 field_name: InternPool.NullTerminatedString,5524 field_name: InternPool.NullTerminatedString,
5470) CompileError {5525) CompileError {
5471 const zcu = sema.mod;5526 const pt = sema.pt;
5472 const gpa = sema.gpa;5527 const zcu = pt.zcu;
5528 const ip = &zcu.intern_pool;
5473 const decl = zcu.declPtr(struct_type.decl.unwrap().?);5529 const decl = zcu.declPtr(struct_type.decl.unwrap().?);
5474 const fqn = try decl.fullyQualifiedName(zcu);5530 const fqn = try decl.fullyQualifiedName(pt);
54755531
5476 const msg = msg: {5532 const msg = msg: {
5477 const msg = try sema.errMsg(5533 const msg = try sema.errMsg(
5478 field_src,5534 field_src,
5479 "no field named '{}' in struct '{}'",5535 "no field named '{}' in struct '{}'",
5480 .{ field_name.fmt(&zcu.intern_pool), fqn.fmt(&zcu.intern_pool) },5536 .{ field_name.fmt(ip), fqn.fmt(ip) },
5481 );5537 );
5482 errdefer msg.destroy(gpa);5538 errdefer msg.destroy(sema.gpa);
5483 try sema.errNote(struct_ty.srcLoc(zcu), msg, "struct declared here", .{});5539 try sema.errNote(struct_ty.srcLoc(zcu), msg, "struct declared here", .{});
5484 break :msg msg;5540 break :msg msg;
5485 };5541 };
...@@ -5494,17 +5550,19 @@ fn failWithBadUnionFieldAccess(...@@ -5494,17 +5550,19 @@ fn failWithBadUnionFieldAccess(
5494 field_src: LazySrcLoc,5550 field_src: LazySrcLoc,
5495 field_name: InternPool.NullTerminatedString,5551 field_name: InternPool.NullTerminatedString,
5496) CompileError {5552) CompileError {
5497 const zcu = sema.mod;5553 const pt = sema.pt;
5554 const zcu = pt.zcu;
5555 const ip = &zcu.intern_pool;
5498 const gpa = sema.gpa;5556 const gpa = sema.gpa;
54995557
5500 const decl = zcu.declPtr(union_obj.decl);5558 const decl = zcu.declPtr(union_obj.decl);
5501 const fqn = try decl.fullyQualifiedName(zcu);5559 const fqn = try decl.fullyQualifiedName(pt);
55025560
5503 const msg = msg: {5561 const msg = msg: {
5504 const msg = try sema.errMsg(5562 const msg = try sema.errMsg(
5505 field_src,5563 field_src,
5506 "no field named '{}' in union '{}'",5564 "no field named '{}' in union '{}'",
5507 .{ field_name.fmt(&zcu.intern_pool), fqn.fmt(&zcu.intern_pool) },5565 .{ field_name.fmt(ip), fqn.fmt(ip) },
5508 );5566 );
5509 errdefer msg.destroy(gpa);5567 errdefer msg.destroy(gpa);
5510 try sema.errNote(union_ty.srcLoc(zcu), msg, "union declared here", .{});5568 try sema.errNote(union_ty.srcLoc(zcu), msg, "union declared here", .{});
...@@ -5514,9 +5572,9 @@ fn failWithBadUnionFieldAccess(...@@ -5514,9 +5572,9 @@ fn failWithBadUnionFieldAccess(
5514}5572}
55155573
5516fn addDeclaredHereNote(sema: *Sema, parent: *Module.ErrorMsg, decl_ty: Type) !void {5574fn addDeclaredHereNote(sema: *Sema, parent: *Module.ErrorMsg, decl_ty: Type) !void {
5517 const mod = sema.mod;5575 const zcu = sema.pt.zcu;
5518 const src_loc = decl_ty.srcLocOrNull(mod) orelse return;5576 const src_loc = decl_ty.srcLocOrNull(zcu) orelse return;
5519 const category = switch (decl_ty.zigTypeTag(mod)) {5577 const category = switch (decl_ty.zigTypeTag(zcu)) {
5520 .Union => "union",5578 .Union => "union",
5521 .Struct => "struct",5579 .Struct => "struct",
5522 .Enum => "enum",5580 .Enum => "enum",
...@@ -5575,7 +5633,8 @@ fn storeToInferredAllocComptime(...@@ -5575,7 +5633,8 @@ fn storeToInferredAllocComptime(
5575 operand: Air.Inst.Ref,5633 operand: Air.Inst.Ref,
5576 iac: *Air.Inst.Data.InferredAllocComptime,5634 iac: *Air.Inst.Data.InferredAllocComptime,
5577) CompileError!void {5635) CompileError!void {
5578 const zcu = sema.mod;5636 const pt = sema.pt;
5637 const zcu = pt.zcu;
5579 const operand_ty = sema.typeOf(operand);5638 const operand_ty = sema.typeOf(operand);
5580 // There will be only one store_to_inferred_ptr because we are running at comptime.5639 // There will be only one store_to_inferred_ptr because we are running at comptime.
5581 // The alloc will turn into a Decl or a ComptimeAlloc.5640 // The alloc will turn into a Decl or a ComptimeAlloc.
...@@ -5584,7 +5643,7 @@ fn storeToInferredAllocComptime(...@@ -5584,7 +5643,7 @@ fn storeToInferredAllocComptime(
5584 .needed_comptime_reason = "value being stored to a comptime variable must be comptime-known",5643 .needed_comptime_reason = "value being stored to a comptime variable must be comptime-known",
5585 });5644 });
5586 };5645 };
5587 const alloc_ty = try zcu.ptrTypeSema(.{5646 const alloc_ty = try pt.ptrTypeSema(.{
5588 .child = operand_ty.toIntern(),5647 .child = operand_ty.toIntern(),
5589 .flags = .{5648 .flags = .{
5590 .alignment = iac.alignment,5649 .alignment = iac.alignment,
...@@ -5592,7 +5651,7 @@ fn storeToInferredAllocComptime(...@@ -5592,7 +5651,7 @@ fn storeToInferredAllocComptime(
5592 },5651 },
5593 });5652 });
5594 if (iac.is_const and !operand_val.canMutateComptimeVarState(zcu)) {5653 if (iac.is_const and !operand_val.canMutateComptimeVarState(zcu)) {
5595 iac.ptr = try zcu.intern(.{ .ptr = .{5654 iac.ptr = try pt.intern(.{ .ptr = .{
5596 .ty = alloc_ty.toIntern(),5655 .ty = alloc_ty.toIntern(),
5597 .base_addr = .{ .anon_decl = .{5656 .base_addr = .{ .anon_decl = .{
5598 .val = operand_val.toIntern(),5657 .val = operand_val.toIntern(),
...@@ -5603,7 +5662,7 @@ fn storeToInferredAllocComptime(...@@ -5603,7 +5662,7 @@ fn storeToInferredAllocComptime(
5603 } else {5662 } else {
5604 const alloc_index = try sema.newComptimeAlloc(block, operand_ty, iac.alignment);5663 const alloc_index = try sema.newComptimeAlloc(block, operand_ty, iac.alignment);
5605 sema.getComptimeAlloc(alloc_index).val = .{ .interned = operand_val.toIntern() };5664 sema.getComptimeAlloc(alloc_index).val = .{ .interned = operand_val.toIntern() };
5606 iac.ptr = try zcu.intern(.{ .ptr = .{5665 iac.ptr = try pt.intern(.{ .ptr = .{
5607 .ty = alloc_ty.toIntern(),5666 .ty = alloc_ty.toIntern(),
5608 .base_addr = .{ .comptime_alloc = alloc_index },5667 .base_addr = .{ .comptime_alloc = alloc_index },
5609 .byte_offset = 0,5668 .byte_offset = 0,
...@@ -5624,7 +5683,8 @@ fn zirStoreNode(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!v...@@ -5624,7 +5683,8 @@ fn zirStoreNode(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!v
5624 const tracy = trace(@src());5683 const tracy = trace(@src());
5625 defer tracy.end();5684 defer tracy.end();
56265685
5627 const mod = sema.mod;5686 const pt = sema.pt;
5687 const mod = pt.zcu;
5628 const zir_tags = sema.code.instructions.items(.tag);5688 const zir_tags = sema.code.instructions.items(.tag);
5629 const zir_datas = sema.code.instructions.items(.data);5689 const zir_datas = sema.code.instructions.items(.data);
5630 const inst_data = zir_datas[@intFromEnum(inst)].pl_node;5690 const inst_data = zir_datas[@intFromEnum(inst)].pl_node;
...@@ -5662,23 +5722,23 @@ fn zirStoreNode(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!v...@@ -5662,23 +5722,23 @@ fn zirStoreNode(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!v
5662fn zirStr(sema: *Sema, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {5722fn zirStr(sema: *Sema, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
5663 const bytes = sema.code.instructions.items(.data)[@intFromEnum(inst)].str.get(sema.code);5723 const bytes = sema.code.instructions.items(.data)[@intFromEnum(inst)].str.get(sema.code);
5664 return sema.addStrLit(5724 return sema.addStrLit(
5665 try sema.mod.intern_pool.getOrPutString(sema.gpa, bytes, .maybe_embedded_nulls),5725 try sema.pt.zcu.intern_pool.getOrPutString(sema.gpa, sema.pt.tid, bytes, .maybe_embedded_nulls),
5666 bytes.len,5726 bytes.len,
5667 );5727 );
5668}5728}
56695729
5670fn addNullTerminatedStrLit(sema: *Sema, string: InternPool.NullTerminatedString) CompileError!Air.Inst.Ref {5730fn addNullTerminatedStrLit(sema: *Sema, string: InternPool.NullTerminatedString) CompileError!Air.Inst.Ref {
5671 return sema.addStrLit(string.toString(), string.length(&sema.mod.intern_pool));5731 return sema.addStrLit(string.toString(), string.length(&sema.pt.zcu.intern_pool));
5672}5732}
56735733
5674fn addStrLit(sema: *Sema, string: InternPool.String, len: u64) CompileError!Air.Inst.Ref {5734fn addStrLit(sema: *Sema, string: InternPool.String, len: u64) CompileError!Air.Inst.Ref {
5675 const mod = sema.mod;5735 const pt = sema.pt;
5676 const array_ty = try mod.arrayType(.{5736 const array_ty = try pt.arrayType(.{
5677 .len = len,5737 .len = len,
5678 .sentinel = .zero_u8,5738 .sentinel = .zero_u8,
5679 .child = .u8_type,5739 .child = .u8_type,
5680 });5740 });
5681 const val = try mod.intern(.{ .aggregate = .{5741 const val = try pt.intern(.{ .aggregate = .{
5682 .ty = array_ty.toIntern(),5742 .ty = array_ty.toIntern(),
5683 .storage = .{ .bytes = string },5743 .storage = .{ .bytes = string },
5684 } });5744 } });
...@@ -5690,16 +5750,16 @@ fn anonDeclRef(sema: *Sema, val: InternPool.Index) CompileError!Air.Inst.Ref {...@@ -5690,16 +5750,16 @@ fn anonDeclRef(sema: *Sema, val: InternPool.Index) CompileError!Air.Inst.Ref {
5690}5750}
56915751
5692fn refValue(sema: *Sema, val: InternPool.Index) CompileError!InternPool.Index {5752fn refValue(sema: *Sema, val: InternPool.Index) CompileError!InternPool.Index {
5693 const mod = sema.mod;5753 const pt = sema.pt;
5694 const ptr_ty = (try mod.ptrTypeSema(.{5754 const ptr_ty = (try pt.ptrTypeSema(.{
5695 .child = mod.intern_pool.typeOf(val),5755 .child = pt.zcu.intern_pool.typeOf(val),
5696 .flags = .{5756 .flags = .{
5697 .alignment = .none,5757 .alignment = .none,
5698 .is_const = true,5758 .is_const = true,
5699 .address_space = .generic,5759 .address_space = .generic,
5700 },5760 },
5701 })).toIntern();5761 })).toIntern();
5702 return mod.intern(.{ .ptr = .{5762 return pt.intern(.{ .ptr = .{
5703 .ty = ptr_ty,5763 .ty = ptr_ty,
5704 .base_addr = .{ .anon_decl = .{5764 .base_addr = .{ .anon_decl = .{
5705 .val = val,5765 .val = val,
...@@ -5715,7 +5775,7 @@ fn zirInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Ins...@@ -5715,7 +5775,7 @@ fn zirInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Ins
5715 defer tracy.end();5775 defer tracy.end();
57165776
5717 const int = sema.code.instructions.items(.data)[@intFromEnum(inst)].int;5777 const int = sema.code.instructions.items(.data)[@intFromEnum(inst)].int;
5718 return sema.mod.intRef(Type.comptime_int, int);5778 return sema.pt.intRef(Type.comptime_int, int);
5719}5779}
57205780
5721fn zirIntBig(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {5781fn zirIntBig(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
...@@ -5723,7 +5783,6 @@ fn zirIntBig(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air....@@ -5723,7 +5783,6 @@ fn zirIntBig(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.
5723 const tracy = trace(@src());5783 const tracy = trace(@src());
5724 defer tracy.end();5784 defer tracy.end();
57255785
5726 const mod = sema.mod;
5727 const int = sema.code.instructions.items(.data)[@intFromEnum(inst)].str;5786 const int = sema.code.instructions.items(.data)[@intFromEnum(inst)].str;
5728 const byte_count = int.len * @sizeOf(std.math.big.Limb);5787 const byte_count = int.len * @sizeOf(std.math.big.Limb);
5729 const limb_bytes = sema.code.string_bytes[@intFromEnum(int.start)..][0..byte_count];5788 const limb_bytes = sema.code.string_bytes[@intFromEnum(int.start)..][0..byte_count];
...@@ -5734,7 +5793,7 @@ fn zirIntBig(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air....@@ -5734,7 +5793,7 @@ fn zirIntBig(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.
5734 const limbs = try sema.arena.alloc(std.math.big.Limb, int.len);5793 const limbs = try sema.arena.alloc(std.math.big.Limb, int.len);
5735 @memcpy(mem.sliceAsBytes(limbs), limb_bytes);5794 @memcpy(mem.sliceAsBytes(limbs), limb_bytes);
57365795
5737 return Air.internedToRef((try mod.intValue_big(Type.comptime_int, .{5796 return Air.internedToRef((try sema.pt.intValue_big(Type.comptime_int, .{
5738 .limbs = limbs,5797 .limbs = limbs,
5739 .positive = true,5798 .positive = true,
5740 })).toIntern());5799 })).toIntern());
...@@ -5743,7 +5802,7 @@ fn zirIntBig(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air....@@ -5743,7 +5802,7 @@ fn zirIntBig(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.
5743fn zirFloat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {5802fn zirFloat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
5744 _ = block;5803 _ = block;
5745 const number = sema.code.instructions.items(.data)[@intFromEnum(inst)].float;5804 const number = sema.code.instructions.items(.data)[@intFromEnum(inst)].float;
5746 return Air.internedToRef((try sema.mod.floatValue(5805 return Air.internedToRef((try sema.pt.floatValue(
5747 Type.comptime_float,5806 Type.comptime_float,
5748 number,5807 number,
5749 )).toIntern());5808 )).toIntern());
...@@ -5754,7 +5813,7 @@ fn zirFloat128(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -5754,7 +5813,7 @@ fn zirFloat128(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
5754 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;5813 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
5755 const extra = sema.code.extraData(Zir.Inst.Float128, inst_data.payload_index).data;5814 const extra = sema.code.extraData(Zir.Inst.Float128, inst_data.payload_index).data;
5756 const number = extra.get();5815 const number = extra.get();
5757 return Air.internedToRef((try sema.mod.floatValue(Type.comptime_float, number)).toIntern());5816 return Air.internedToRef((try sema.pt.floatValue(Type.comptime_float, number)).toIntern());
5758}5817}
57595818
5760fn zirCompileError(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void {5819fn zirCompileError(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void {
...@@ -5775,10 +5834,11 @@ fn zirCompileLog(...@@ -5775,10 +5834,11 @@ fn zirCompileLog(
5775 block: *Block,5834 block: *Block,
5776 extended: Zir.Inst.Extended.InstData,5835 extended: Zir.Inst.Extended.InstData,
5777) CompileError!Air.Inst.Ref {5836) CompileError!Air.Inst.Ref {
5778 const mod = sema.mod;5837 const pt = sema.pt;
5838 const mod = pt.zcu;
57795839
5780 var managed = mod.compile_log_text.toManaged(sema.gpa);5840 var managed = mod.compile_log_text.toManaged(sema.gpa);
5781 defer sema.mod.compile_log_text = managed.moveToUnmanaged();5841 defer pt.zcu.compile_log_text = managed.moveToUnmanaged();
5782 const writer = managed.writer();5842 const writer = managed.writer();
57835843
5784 const extra = sema.code.extraData(Zir.Inst.NodeMultiOp, extended.operand);5844 const extra = sema.code.extraData(Zir.Inst.NodeMultiOp, extended.operand);
...@@ -5792,10 +5852,10 @@ fn zirCompileLog(...@@ -5792,10 +5852,10 @@ fn zirCompileLog(
5792 const arg_ty = sema.typeOf(arg);5852 const arg_ty = sema.typeOf(arg);
5793 if (try sema.resolveValueResolveLazy(arg)) |val| {5853 if (try sema.resolveValueResolveLazy(arg)) |val| {
5794 try writer.print("@as({}, {})", .{5854 try writer.print("@as({}, {})", .{
5795 arg_ty.fmt(mod), val.fmtValue(mod, sema),5855 arg_ty.fmt(pt), val.fmtValue(pt, sema),
5796 });5856 });
5797 } else {5857 } else {
5798 try writer.print("@as({}, [runtime value])", .{arg_ty.fmt(mod)});5858 try writer.print("@as({}, [runtime value])", .{arg_ty.fmt(pt)});
5799 }5859 }
5800 }5860 }
5801 try writer.print("\n", .{});5861 try writer.print("\n", .{});
...@@ -5835,7 +5895,8 @@ fn zirLoop(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileError...@@ -5835,7 +5895,8 @@ fn zirLoop(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileError
5835 const tracy = trace(@src());5895 const tracy = trace(@src());
5836 defer tracy.end();5896 defer tracy.end();
58375897
5838 const mod = sema.mod;5898 const pt = sema.pt;
5899 const mod = pt.zcu;
5839 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;5900 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
5840 const src = parent_block.nodeOffset(inst_data.src_node);5901 const src = parent_block.nodeOffset(inst_data.src_node);
5841 const extra = sema.code.extraData(Zir.Inst.Block, inst_data.payload_index);5902 const extra = sema.code.extraData(Zir.Inst.Block, inst_data.payload_index);
...@@ -5906,7 +5967,8 @@ fn zirCImport(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileEr...@@ -5906,7 +5967,8 @@ fn zirCImport(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileEr
5906 const tracy = trace(@src());5967 const tracy = trace(@src());
5907 defer tracy.end();5968 defer tracy.end();
59085969
5909 const zcu = sema.mod;5970 const pt = sema.pt;
5971 const zcu = pt.zcu;
5910 const comp = zcu.comp;5972 const comp = zcu.comp;
5911 const gpa = sema.gpa;5973 const gpa = sema.gpa;
5912 const pl_node = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;5974 const pl_node = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
...@@ -6002,10 +6064,10 @@ fn zirCImport(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileEr...@@ -6002,10 +6064,10 @@ fn zirCImport(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileEr
60026064
6003 const path_digest = zcu.filePathDigest(result.file_index);6065 const path_digest = zcu.filePathDigest(result.file_index);
6004 const root_decl = zcu.fileRootDecl(result.file_index);6066 const root_decl = zcu.fileRootDecl(result.file_index);
6005 zcu.astGenFile(result.file, result.file_index, path_digest, root_decl) catch |err|6067 pt.astGenFile(result.file, result.file_index, path_digest, root_decl) catch |err|
6006 return sema.fail(&child_block, src, "C import failed: {s}", .{@errorName(err)});6068 return sema.fail(&child_block, src, "C import failed: {s}", .{@errorName(err)});
60076069
6008 try zcu.ensureFileAnalyzed(result.file_index);6070 try pt.ensureFileAnalyzed(result.file_index);
6009 const file_root_decl_index = zcu.fileRootDecl(result.file_index).unwrap().?;6071 const file_root_decl_index = zcu.fileRootDecl(result.file_index).unwrap().?;
6010 return sema.analyzeDeclVal(parent_block, src, file_root_decl_index);6072 return sema.analyzeDeclVal(parent_block, src, file_root_decl_index);
6011}6073}
...@@ -6147,7 +6209,8 @@ fn resolveAnalyzedBlock(...@@ -6147,7 +6209,8 @@ fn resolveAnalyzedBlock(
6147 defer tracy.end();6209 defer tracy.end();
61486210
6149 const gpa = sema.gpa;6211 const gpa = sema.gpa;
6150 const mod = sema.mod;6212 const pt = sema.pt;
6213 const mod = pt.zcu;
61516214
6152 // Blocks must terminate with noreturn instruction.6215 // Blocks must terminate with noreturn instruction.
6153 assert(child_block.instructions.items.len != 0);6216 assert(child_block.instructions.items.len != 0);
...@@ -6258,7 +6321,7 @@ fn resolveAnalyzedBlock(...@@ -6258,7 +6321,7 @@ fn resolveAnalyzedBlock(
6258 const type_src = src; // TODO: better source location6321 const type_src = src; // TODO: better source location
6259 if (try sema.typeRequiresComptime(resolved_ty)) {6322 if (try sema.typeRequiresComptime(resolved_ty)) {
6260 const msg = msg: {6323 const msg = msg: {
6261 const msg = try sema.errMsg(type_src, "value with comptime-only type '{}' depends on runtime control flow", .{resolved_ty.fmt(mod)});6324 const msg = try sema.errMsg(type_src, "value with comptime-only type '{}' depends on runtime control flow", .{resolved_ty.fmt(pt)});
6262 errdefer msg.destroy(sema.gpa);6325 errdefer msg.destroy(sema.gpa);
62636326
6264 const runtime_src = child_block.runtime_cond orelse child_block.runtime_loop.?;6327 const runtime_src = child_block.runtime_cond orelse child_block.runtime_loop.?;
...@@ -6353,7 +6416,8 @@ fn zirExport(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void...@@ -6353,7 +6416,8 @@ fn zirExport(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void
6353 const tracy = trace(@src());6416 const tracy = trace(@src());
6354 defer tracy.end();6417 defer tracy.end();
63556418
6356 const mod = sema.mod;6419 const pt = sema.pt;
6420 const mod = pt.zcu;
6357 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;6421 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
6358 const extra = sema.code.extraData(Zir.Inst.Export, inst_data.payload_index).data;6422 const extra = sema.code.extraData(Zir.Inst.Export, inst_data.payload_index).data;
6359 const src = block.nodeOffset(inst_data.src_node);6423 const src = block.nodeOffset(inst_data.src_node);
...@@ -6361,6 +6425,7 @@ fn zirExport(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void...@@ -6361,6 +6425,7 @@ fn zirExport(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void
6361 const options_src = block.builtinCallArgSrc(inst_data.src_node, 1);6425 const options_src = block.builtinCallArgSrc(inst_data.src_node, 1);
6362 const decl_name = try mod.intern_pool.getOrPutString(6426 const decl_name = try mod.intern_pool.getOrPutString(
6363 mod.gpa,6427 mod.gpa,
6428 pt.tid,
6364 sema.code.nullTerminatedString(extra.decl_name),6429 sema.code.nullTerminatedString(extra.decl_name),
6365 .no_embedded_nulls,6430 .no_embedded_nulls,
6366 );6431 );
...@@ -6388,7 +6453,8 @@ fn zirExportValue(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError...@@ -6388,7 +6453,8 @@ fn zirExportValue(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
6388 const tracy = trace(@src());6453 const tracy = trace(@src());
6389 defer tracy.end();6454 defer tracy.end();
63906455
6391 const mod = sema.mod;6456 const pt = sema.pt;
6457 const mod = pt.zcu;
6392 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;6458 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
6393 const extra = sema.code.extraData(Zir.Inst.ExportValue, inst_data.payload_index).data;6459 const extra = sema.code.extraData(Zir.Inst.ExportValue, inst_data.payload_index).data;
6394 const src = block.nodeOffset(inst_data.src_node);6460 const src = block.nodeOffset(inst_data.src_node);
...@@ -6421,7 +6487,8 @@ pub fn analyzeExport(...@@ -6421,7 +6487,8 @@ pub fn analyzeExport(
6421 exported_decl_index: InternPool.DeclIndex,6487 exported_decl_index: InternPool.DeclIndex,
6422) !void {6488) !void {
6423 const gpa = sema.gpa;6489 const gpa = sema.gpa;
6424 const mod = sema.mod;6490 const pt = sema.pt;
6491 const mod = pt.zcu;
64256492
6426 if (options.linkage == .internal)6493 if (options.linkage == .internal)
6427 return;6494 return;
...@@ -6433,7 +6500,7 @@ pub fn analyzeExport(...@@ -6433,7 +6500,7 @@ pub fn analyzeExport(
64336500
6434 if (!try sema.validateExternType(export_ty, .other)) {6501 if (!try sema.validateExternType(export_ty, .other)) {
6435 const msg = msg: {6502 const msg = msg: {
6436 const msg = try sema.errMsg(src, "unable to export type '{}'", .{export_ty.fmt(mod)});6503 const msg = try sema.errMsg(src, "unable to export type '{}'", .{export_ty.fmt(pt)});
6437 errdefer msg.destroy(gpa);6504 errdefer msg.destroy(gpa);
64386505
6439 try sema.explainWhyTypeIsNotExtern(msg, src, export_ty, .other);6506 try sema.explainWhyTypeIsNotExtern(msg, src, export_ty, .other);
...@@ -6460,7 +6527,8 @@ pub fn analyzeExport(...@@ -6460,7 +6527,8 @@ pub fn analyzeExport(
6460}6527}
64616528
6462fn zirSetAlignStack(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) CompileError!void {6529fn zirSetAlignStack(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) CompileError!void {
6463 const mod = sema.mod;6530 const pt = sema.pt;
6531 const mod = pt.zcu;
6464 const extra = sema.code.extraData(Zir.Inst.UnNode, extended.operand).data;6532 const extra = sema.code.extraData(Zir.Inst.UnNode, extended.operand).data;
6465 const operand_src = block.builtinCallArgSrc(extra.node, 0);6533 const operand_src = block.builtinCallArgSrc(extra.node, 0);
6466 const src = block.nodeOffset(extra.node);6534 const src = block.nodeOffset(extra.node);
...@@ -6502,7 +6570,8 @@ fn zirSetAlignStack(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.Inst...@@ -6502,7 +6570,8 @@ fn zirSetAlignStack(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.Inst
6502}6570}
65036571
6504fn zirSetCold(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) CompileError!void {6572fn zirSetCold(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) CompileError!void {
6505 const mod = sema.mod;6573 const pt = sema.pt;
6574 const mod = pt.zcu;
6506 const ip = &mod.intern_pool;6575 const ip = &mod.intern_pool;
6507 const extra = sema.code.extraData(Zir.Inst.UnNode, extended.operand).data;6576 const extra = sema.code.extraData(Zir.Inst.UnNode, extended.operand).data;
6508 const operand_src = block.builtinCallArgSrc(extra.node, 0);6577 const operand_src = block.builtinCallArgSrc(extra.node, 0);
...@@ -6628,7 +6697,8 @@ fn addDbgVar(...@@ -6628,7 +6697,8 @@ fn addDbgVar(
6628) CompileError!void {6697) CompileError!void {
6629 if (block.is_comptime or block.ownerModule().strip) return;6698 if (block.is_comptime or block.ownerModule().strip) return;
66306699
6631 const mod = sema.mod;6700 const pt = sema.pt;
6701 const mod = pt.zcu;
6632 const operand_ty = sema.typeOf(operand);6702 const operand_ty = sema.typeOf(operand);
6633 const val_ty = switch (air_tag) {6703 const val_ty = switch (air_tag) {
6634 .dbg_var_ptr => operand_ty.childType(mod),6704 .dbg_var_ptr => operand_ty.childType(mod),
...@@ -6669,11 +6739,13 @@ fn addDbgVar(...@@ -6669,11 +6739,13 @@ fn addDbgVar(
6669}6739}
66706740
6671fn zirDeclRef(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {6741fn zirDeclRef(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
6672 const mod = sema.mod;6742 const pt = sema.pt;
6743 const mod = pt.zcu;
6673 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].str_tok;6744 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].str_tok;
6674 const src = block.tokenOffset(inst_data.src_tok);6745 const src = block.tokenOffset(inst_data.src_tok);
6675 const decl_name = try mod.intern_pool.getOrPutString(6746 const decl_name = try mod.intern_pool.getOrPutString(
6676 sema.gpa,6747 sema.gpa,
6748 pt.tid,
6677 inst_data.get(sema.code),6749 inst_data.get(sema.code),
6678 .no_embedded_nulls,6750 .no_embedded_nulls,
6679 );6751 );
...@@ -6682,11 +6754,13 @@ fn zirDeclRef(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air...@@ -6682,11 +6754,13 @@ fn zirDeclRef(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
6682}6754}
66836755
6684fn zirDeclVal(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {6756fn zirDeclVal(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
6685 const mod = sema.mod;6757 const pt = sema.pt;
6758 const mod = pt.zcu;
6686 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].str_tok;6759 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].str_tok;
6687 const src = block.tokenOffset(inst_data.src_tok);6760 const src = block.tokenOffset(inst_data.src_tok);
6688 const decl_name = try mod.intern_pool.getOrPutString(6761 const decl_name = try mod.intern_pool.getOrPutString(
6689 sema.gpa,6762 sema.gpa,
6763 pt.tid,
6690 inst_data.get(sema.code),6764 inst_data.get(sema.code),
6691 .no_embedded_nulls,6765 .no_embedded_nulls,
6692 );6766 );
...@@ -6695,7 +6769,8 @@ fn zirDeclVal(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air...@@ -6695,7 +6769,8 @@ fn zirDeclVal(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
6695}6769}
66966770
6697fn lookupIdentifier(sema: *Sema, block: *Block, src: LazySrcLoc, name: InternPool.NullTerminatedString) !InternPool.DeclIndex {6771fn lookupIdentifier(sema: *Sema, block: *Block, src: LazySrcLoc, name: InternPool.NullTerminatedString) !InternPool.DeclIndex {
6698 const mod = sema.mod;6772 const pt = sema.pt;
6773 const mod = pt.zcu;
6699 var namespace = block.namespace;6774 var namespace = block.namespace;
6700 while (true) {6775 while (true) {
6701 if (try sema.lookupInNamespace(block, src, namespace.toOptional(), name, false)) |decl_index| {6776 if (try sema.lookupInNamespace(block, src, namespace.toOptional(), name, false)) |decl_index| {
...@@ -6716,7 +6791,8 @@ fn lookupInNamespace(...@@ -6716,7 +6791,8 @@ fn lookupInNamespace(
6716 ident_name: InternPool.NullTerminatedString,6791 ident_name: InternPool.NullTerminatedString,
6717 observe_usingnamespace: bool,6792 observe_usingnamespace: bool,
6718) CompileError!?InternPool.DeclIndex {6793) CompileError!?InternPool.DeclIndex {
6719 const mod = sema.mod;6794 const pt = sema.pt;
6795 const mod = pt.zcu;
67206796
6721 const namespace_index = opt_namespace_index.unwrap() orelse return null;6797 const namespace_index = opt_namespace_index.unwrap() orelse return null;
6722 const namespace = mod.namespacePtr(namespace_index);6798 const namespace = mod.namespacePtr(namespace_index);
...@@ -6811,7 +6887,8 @@ fn lookupInNamespace(...@@ -6811,7 +6887,8 @@ fn lookupInNamespace(
6811}6887}
68126888
6813fn funcDeclSrc(sema: *Sema, func_inst: Air.Inst.Ref) !?*Decl {6889fn funcDeclSrc(sema: *Sema, func_inst: Air.Inst.Ref) !?*Decl {
6814 const mod = sema.mod;6890 const pt = sema.pt;
6891 const mod = pt.zcu;
6815 const func_val = (try sema.resolveValue(func_inst)) orelse return null;6892 const func_val = (try sema.resolveValue(func_inst)) orelse return null;
6816 if (func_val.isUndef(mod)) return null;6893 if (func_val.isUndef(mod)) return null;
6817 const owner_decl_index = switch (mod.intern_pool.indexToKey(func_val.toIntern())) {6894 const owner_decl_index = switch (mod.intern_pool.indexToKey(func_val.toIntern())) {
...@@ -6827,19 +6904,20 @@ fn funcDeclSrc(sema: *Sema, func_inst: Air.Inst.Ref) !?*Decl {...@@ -6827,19 +6904,20 @@ fn funcDeclSrc(sema: *Sema, func_inst: Air.Inst.Ref) !?*Decl {
6827}6904}
68286905
6829pub fn analyzeSaveErrRetIndex(sema: *Sema, block: *Block) SemaError!Air.Inst.Ref {6906pub fn analyzeSaveErrRetIndex(sema: *Sema, block: *Block) SemaError!Air.Inst.Ref {
6830 const mod = sema.mod;6907 const pt = sema.pt;
6908 const mod = pt.zcu;
6831 const gpa = sema.gpa;6909 const gpa = sema.gpa;
68326910
6833 if (block.is_comptime or block.is_typeof) {6911 if (block.is_comptime or block.is_typeof) {
6834 const index_val = try mod.intValue_u64(Type.usize, sema.comptime_err_ret_trace.items.len);6912 const index_val = try pt.intValue_u64(Type.usize, sema.comptime_err_ret_trace.items.len);
6835 return Air.internedToRef(index_val.toIntern());6913 return Air.internedToRef(index_val.toIntern());
6836 }6914 }
68376915
6838 if (!block.ownerModule().error_tracing) return .none;6916 if (!block.ownerModule().error_tracing) return .none;
68396917
6840 const stack_trace_ty = try mod.getBuiltinType("StackTrace");6918 const stack_trace_ty = try pt.getBuiltinType("StackTrace");
6841 try stack_trace_ty.resolveFields(mod);6919 try stack_trace_ty.resolveFields(pt);
6842 const field_name = try mod.intern_pool.getOrPutString(gpa, "index", .no_embedded_nulls);6920 const field_name = try mod.intern_pool.getOrPutString(gpa, pt.tid, "index", .no_embedded_nulls);
6843 const field_index = sema.structFieldIndex(block, stack_trace_ty, field_name, LazySrcLoc.unneeded) catch |err| switch (err) {6921 const field_index = sema.structFieldIndex(block, stack_trace_ty, field_name, LazySrcLoc.unneeded) catch |err| switch (err) {
6844 error.AnalysisFail => @panic("std.builtin.StackTrace is corrupt"),6922 error.AnalysisFail => @panic("std.builtin.StackTrace is corrupt"),
6845 error.GenericPoison, error.ComptimeReturn, error.ComptimeBreak => unreachable,6923 error.GenericPoison, error.ComptimeReturn, error.ComptimeBreak => unreachable,
...@@ -6864,7 +6942,8 @@ fn popErrorReturnTrace(...@@ -6864,7 +6942,8 @@ fn popErrorReturnTrace(
6864 operand: Air.Inst.Ref,6942 operand: Air.Inst.Ref,
6865 saved_error_trace_index: Air.Inst.Ref,6943 saved_error_trace_index: Air.Inst.Ref,
6866) CompileError!void {6944) CompileError!void {
6867 const mod = sema.mod;6945 const pt = sema.pt;
6946 const mod = pt.zcu;
6868 const gpa = sema.gpa;6947 const gpa = sema.gpa;
6869 var is_non_error: ?bool = null;6948 var is_non_error: ?bool = null;
6870 var is_non_error_inst: Air.Inst.Ref = undefined;6949 var is_non_error_inst: Air.Inst.Ref = undefined;
...@@ -6878,11 +6957,11 @@ fn popErrorReturnTrace(...@@ -6878,11 +6957,11 @@ fn popErrorReturnTrace(
6878 // AstGen determined this result does not go to an error-handling expr (try/catch/return etc.), or6957 // AstGen determined this result does not go to an error-handling expr (try/catch/return etc.), or
6879 // the result is comptime-known to be a non-error. Either way, pop unconditionally.6958 // the result is comptime-known to be a non-error. Either way, pop unconditionally.
68806959
6881 const stack_trace_ty = try mod.getBuiltinType("StackTrace");6960 const stack_trace_ty = try pt.getBuiltinType("StackTrace");
6882 try stack_trace_ty.resolveFields(mod);6961 try stack_trace_ty.resolveFields(pt);
6883 const ptr_stack_trace_ty = try mod.singleMutPtrType(stack_trace_ty);6962 const ptr_stack_trace_ty = try pt.singleMutPtrType(stack_trace_ty);
6884 const err_return_trace = try block.addTy(.err_return_trace, ptr_stack_trace_ty);6963 const err_return_trace = try block.addTy(.err_return_trace, ptr_stack_trace_ty);
6885 const field_name = try mod.intern_pool.getOrPutString(gpa, "index", .no_embedded_nulls);6964 const field_name = try mod.intern_pool.getOrPutString(gpa, pt.tid, "index", .no_embedded_nulls);
6886 const field_ptr = try sema.structFieldPtr(block, src, err_return_trace, field_name, src, stack_trace_ty, true);6965 const field_ptr = try sema.structFieldPtr(block, src, err_return_trace, field_name, src, stack_trace_ty, true);
6887 try sema.storePtr2(block, src, field_ptr, src, saved_error_trace_index, src, .store);6966 try sema.storePtr2(block, src, field_ptr, src, saved_error_trace_index, src, .store);
6888 } else if (is_non_error == null) {6967 } else if (is_non_error == null) {
...@@ -6904,11 +6983,11 @@ fn popErrorReturnTrace(...@@ -6904,11 +6983,11 @@ fn popErrorReturnTrace(
6904 defer then_block.instructions.deinit(gpa);6983 defer then_block.instructions.deinit(gpa);
69056984
6906 // If non-error, then pop the error return trace by restoring the index.6985 // If non-error, then pop the error return trace by restoring the index.
6907 const stack_trace_ty = try mod.getBuiltinType("StackTrace");6986 const stack_trace_ty = try pt.getBuiltinType("StackTrace");
6908 try stack_trace_ty.resolveFields(mod);6987 try stack_trace_ty.resolveFields(pt);
6909 const ptr_stack_trace_ty = try mod.singleMutPtrType(stack_trace_ty);6988 const ptr_stack_trace_ty = try pt.singleMutPtrType(stack_trace_ty);
6910 const err_return_trace = try then_block.addTy(.err_return_trace, ptr_stack_trace_ty);6989 const err_return_trace = try then_block.addTy(.err_return_trace, ptr_stack_trace_ty);
6911 const field_name = try mod.intern_pool.getOrPutString(gpa, "index", .no_embedded_nulls);6990 const field_name = try mod.intern_pool.getOrPutString(gpa, pt.tid, "index", .no_embedded_nulls);
6912 const field_ptr = try sema.structFieldPtr(&then_block, src, err_return_trace, field_name, src, stack_trace_ty, true);6991 const field_ptr = try sema.structFieldPtr(&then_block, src, err_return_trace, field_name, src, stack_trace_ty, true);
6913 try sema.storePtr2(&then_block, src, field_ptr, src, saved_error_trace_index, src, .store);6992 try sema.storePtr2(&then_block, src, field_ptr, src, saved_error_trace_index, src, .store);
6914 _ = try then_block.addBr(cond_block_inst, .void_value);6993 _ = try then_block.addBr(cond_block_inst, .void_value);
...@@ -6947,7 +7026,8 @@ fn zirCall(...@@ -6947,7 +7026,8 @@ fn zirCall(
6947 const tracy = trace(@src());7026 const tracy = trace(@src());
6948 defer tracy.end();7027 defer tracy.end();
69497028
6950 const mod = sema.mod;7029 const pt = sema.pt;
7030 const mod = pt.zcu;
6951 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;7031 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
6952 const callee_src = block.src(.{ .node_offset_call_func = inst_data.src_node });7032 const callee_src = block.src(.{ .node_offset_call_func = inst_data.src_node });
6953 const call_src = block.nodeOffset(inst_data.src_node);7033 const call_src = block.nodeOffset(inst_data.src_node);
...@@ -6968,6 +7048,7 @@ fn zirCall(...@@ -6968,6 +7048,7 @@ fn zirCall(
6968 const object_ptr = try sema.resolveInst(extra.data.obj_ptr);7048 const object_ptr = try sema.resolveInst(extra.data.obj_ptr);
6969 const field_name = try mod.intern_pool.getOrPutString(7049 const field_name = try mod.intern_pool.getOrPutString(
6970 sema.gpa,7050 sema.gpa,
7051 pt.tid,
6971 sema.code.nullTerminatedString(extra.data.field_name_start),7052 sema.code.nullTerminatedString(extra.data.field_name_start),
6972 .no_embedded_nulls,7053 .no_embedded_nulls,
6973 );7054 );
...@@ -7031,9 +7112,9 @@ fn zirCall(...@@ -7031,9 +7112,9 @@ fn zirCall(
7031 // If any input is an error-type, we might need to pop any trace it generated. Otherwise, we only7112 // If any input is an error-type, we might need to pop any trace it generated. Otherwise, we only
7032 // need to clean-up our own trace if we were passed to a non-error-handling expression.7113 // need to clean-up our own trace if we were passed to a non-error-handling expression.
7033 if (input_is_error or (pop_error_return_trace and return_ty.isError(mod))) {7114 if (input_is_error or (pop_error_return_trace and return_ty.isError(mod))) {
7034 const stack_trace_ty = try mod.getBuiltinType("StackTrace");7115 const stack_trace_ty = try pt.getBuiltinType("StackTrace");
7035 try stack_trace_ty.resolveFields(mod);7116 try stack_trace_ty.resolveFields(pt);
7036 const field_name = try mod.intern_pool.getOrPutString(sema.gpa, "index", .no_embedded_nulls);7117 const field_name = try mod.intern_pool.getOrPutString(sema.gpa, pt.tid, "index", .no_embedded_nulls);
7037 const field_index = try sema.structFieldIndex(block, stack_trace_ty, field_name, call_src);7118 const field_index = try sema.structFieldIndex(block, stack_trace_ty, field_name, call_src);
70387119
7039 // Insert a save instruction before the arg resolution + call instructions we just generated7120 // Insert a save instruction before the arg resolution + call instructions we just generated
...@@ -7065,7 +7146,8 @@ fn checkCallArgumentCount(...@@ -7065,7 +7146,8 @@ fn checkCallArgumentCount(
7065 total_args: usize,7146 total_args: usize,
7066 member_fn: bool,7147 member_fn: bool,
7067) !Type {7148) !Type {
7068 const mod = sema.mod;7149 const pt = sema.pt;
7150 const mod = pt.zcu;
7069 const func_ty = func_ty: {7151 const func_ty = func_ty: {
7070 switch (callee_ty.zigTypeTag(mod)) {7152 switch (callee_ty.zigTypeTag(mod)) {
7071 .Fn => break :func_ty callee_ty,7153 .Fn => break :func_ty callee_ty,
...@@ -7082,7 +7164,7 @@ fn checkCallArgumentCount(...@@ -7082,7 +7164,7 @@ fn checkCallArgumentCount(
7082 {7164 {
7083 const msg = msg: {7165 const msg = msg: {
7084 const msg = try sema.errMsg(func_src, "cannot call optional type '{}'", .{7166 const msg = try sema.errMsg(func_src, "cannot call optional type '{}'", .{
7085 callee_ty.fmt(mod),7167 callee_ty.fmt(pt),
7086 });7168 });
7087 errdefer msg.destroy(sema.gpa);7169 errdefer msg.destroy(sema.gpa);
7088 try sema.errNote(func_src, msg, "consider using '.?', 'orelse' or 'if'", .{});7170 try sema.errNote(func_src, msg, "consider using '.?', 'orelse' or 'if'", .{});
...@@ -7093,7 +7175,7 @@ fn checkCallArgumentCount(...@@ -7093,7 +7175,7 @@ fn checkCallArgumentCount(
7093 },7175 },
7094 else => {},7176 else => {},
7095 }7177 }
7096 return sema.fail(block, func_src, "type '{}' not a function", .{callee_ty.fmt(mod)});7178 return sema.fail(block, func_src, "type '{}' not a function", .{callee_ty.fmt(pt)});
7097 };7179 };
70987180
7099 const func_ty_info = mod.typeToFunc(func_ty).?;7181 const func_ty_info = mod.typeToFunc(func_ty).?;
...@@ -7142,7 +7224,8 @@ fn callBuiltin(...@@ -7142,7 +7224,8 @@ fn callBuiltin(
7142 args: []const Air.Inst.Ref,7224 args: []const Air.Inst.Ref,
7143 operation: CallOperation,7225 operation: CallOperation,
7144) !void {7226) !void {
7145 const mod = sema.mod;7227 const pt = sema.pt;
7228 const mod = pt.zcu;
7146 const callee_ty = sema.typeOf(builtin_fn);7229 const callee_ty = sema.typeOf(builtin_fn);
7147 const func_ty = func_ty: {7230 const func_ty = func_ty: {
7148 switch (callee_ty.zigTypeTag(mod)) {7231 switch (callee_ty.zigTypeTag(mod)) {
...@@ -7155,7 +7238,7 @@ fn callBuiltin(...@@ -7155,7 +7238,7 @@ fn callBuiltin(
7155 },7238 },
7156 else => {},7239 else => {},
7157 }7240 }
7158 std.debug.panic("type '{}' is not a function calling builtin fn", .{callee_ty.fmt(mod)});7241 std.debug.panic("type '{}' is not a function calling builtin fn", .{callee_ty.fmt(pt)});
7159 };7242 };
71607243
7161 const func_ty_info = mod.typeToFunc(func_ty).?;7244 const func_ty_info = mod.typeToFunc(func_ty).?;
...@@ -7261,7 +7344,8 @@ const CallArgsInfo = union(enum) {...@@ -7261,7 +7344,8 @@ const CallArgsInfo = union(enum) {
7261 func_ty_info: InternPool.Key.FuncType,7344 func_ty_info: InternPool.Key.FuncType,
7262 func_inst: Air.Inst.Ref,7345 func_inst: Air.Inst.Ref,
7263 ) CompileError!Air.Inst.Ref {7346 ) CompileError!Air.Inst.Ref {
7264 const mod = sema.mod;7347 const pt = sema.pt;
7348 const mod = pt.zcu;
7265 const param_count = func_ty_info.param_types.len;7349 const param_count = func_ty_info.param_types.len;
7266 const uncoerced_arg: Air.Inst.Ref = switch (cai) {7350 const uncoerced_arg: Air.Inst.Ref = switch (cai) {
7267 inline .resolved, .call_builtin => |resolved| resolved.args[arg_index],7351 inline .resolved, .call_builtin => |resolved| resolved.args[arg_index],
...@@ -7438,7 +7522,8 @@ fn analyzeCall(...@@ -7438,7 +7522,8 @@ fn analyzeCall(
7438 call_dbg_node: ?Zir.Inst.Index,7522 call_dbg_node: ?Zir.Inst.Index,
7439 operation: CallOperation,7523 operation: CallOperation,
7440) CompileError!Air.Inst.Ref {7524) CompileError!Air.Inst.Ref {
7441 const mod = sema.mod;7525 const pt = sema.pt;
7526 const mod = pt.zcu;
7442 const ip = &mod.intern_pool;7527 const ip = &mod.intern_pool;
74437528
7444 const callee_ty = sema.typeOf(func);7529 const callee_ty = sema.typeOf(func);
...@@ -7741,10 +7826,10 @@ fn analyzeCall(...@@ -7741,10 +7826,10 @@ fn analyzeCall(
7741 const ies = try sema.arena.create(InferredErrorSet);7826 const ies = try sema.arena.create(InferredErrorSet);
7742 ies.* = .{ .func = .none };7827 ies.* = .{ .func = .none };
7743 sema.fn_ret_ty_ies = ies;7828 sema.fn_ret_ty_ies = ies;
7744 sema.fn_ret_ty = Type.fromInterned((try ip.get(gpa, .{ .error_union_type = .{7829 sema.fn_ret_ty = Type.fromInterned(try pt.intern(.{ .error_union_type = .{
7745 .error_set_type = .adhoc_inferred_error_set_type,7830 .error_set_type = .adhoc_inferred_error_set_type,
7746 .payload_type = sema.fn_ret_ty.toIntern(),7831 .payload_type = sema.fn_ret_ty.toIntern(),
7747 } })));7832 } }));
7748 }7833 }
77497834
7750 // This `res2` is here instead of directly breaking from `res` due to a stage17835 // This `res2` is here instead of directly breaking from `res` due to a stage1
...@@ -7816,7 +7901,7 @@ fn analyzeCall(...@@ -7816,7 +7901,7 @@ fn analyzeCall(
7816 // TODO: check whether any external comptime memory was mutated by the7901 // TODO: check whether any external comptime memory was mutated by the
7817 // comptime function call. If so, then do not memoize the call here.7902 // comptime function call. If so, then do not memoize the call here.
7818 if (should_memoize and !Value.fromInterned(result_interned).canMutateComptimeVarState(mod)) {7903 if (should_memoize and !Value.fromInterned(result_interned).canMutateComptimeVarState(mod)) {
7819 _ = try mod.intern(.{ .memoized_call = .{7904 _ = try pt.intern(.{ .memoized_call = .{
7820 .func = module_fn_index,7905 .func = module_fn_index,
7821 .arg_values = memoized_arg_values,7906 .arg_values = memoized_arg_values,
7822 .result = result_transformed,7907 .result = result_transformed,
...@@ -7921,7 +8006,8 @@ fn analyzeCall(...@@ -7921,7 +8006,8 @@ fn analyzeCall(
7921}8006}
79228007
7923fn handleTailCall(sema: *Sema, block: *Block, call_src: LazySrcLoc, func_ty: Type, result: Air.Inst.Ref) !Air.Inst.Ref {8008fn handleTailCall(sema: *Sema, block: *Block, call_src: LazySrcLoc, func_ty: Type, result: Air.Inst.Ref) !Air.Inst.Ref {
7924 const mod = sema.mod;8009 const pt = sema.pt;
8010 const mod = pt.zcu;
7925 const target = mod.getTarget();8011 const target = mod.getTarget();
7926 const backend = mod.comp.getZigBackend();8012 const backend = mod.comp.getZigBackend();
7927 if (!target_util.supportsTailCall(target, backend)) {8013 if (!target_util.supportsTailCall(target, backend)) {
...@@ -7932,7 +8018,7 @@ fn handleTailCall(sema: *Sema, block: *Block, call_src: LazySrcLoc, func_ty: Typ...@@ -7932,7 +8018,7 @@ fn handleTailCall(sema: *Sema, block: *Block, call_src: LazySrcLoc, func_ty: Typ
7932 const func_decl = mod.funcOwnerDeclPtr(sema.owner_func_index);8018 const func_decl = mod.funcOwnerDeclPtr(sema.owner_func_index);
7933 if (!func_ty.eql(func_decl.typeOf(mod), mod)) {8019 if (!func_ty.eql(func_decl.typeOf(mod), mod)) {
7934 return sema.fail(block, call_src, "unable to perform tail call: type of function being called '{}' does not match type of calling function '{}'", .{8020 return sema.fail(block, call_src, "unable to perform tail call: type of function being called '{}' does not match type of calling function '{}'", .{
7935 func_ty.fmt(mod), func_decl.typeOf(mod).fmt(mod),8021 func_ty.fmt(pt), func_decl.typeOf(mod).fmt(pt),
7936 });8022 });
7937 }8023 }
7938 _ = try block.addUnOp(.ret, result);8024 _ = try block.addUnOp(.ret, result);
...@@ -7954,7 +8040,7 @@ fn analyzeInlineCallArg(...@@ -7954,7 +8040,7 @@ fn analyzeInlineCallArg(
7954 func_ty_info: InternPool.Key.FuncType,8040 func_ty_info: InternPool.Key.FuncType,
7955 func_inst: Air.Inst.Ref,8041 func_inst: Air.Inst.Ref,
7956) !?Air.Inst.Ref {8042) !?Air.Inst.Ref {
7957 const mod = ics.sema.mod;8043 const mod = ics.sema.pt.zcu;
7958 const ip = &mod.intern_pool;8044 const ip = &mod.intern_pool;
7959 const zir_tags = ics.callee().code.instructions.items(.tag);8045 const zir_tags = ics.callee().code.instructions.items(.tag);
7960 switch (zir_tags[@intFromEnum(inst)]) {8046 switch (zir_tags[@intFromEnum(inst)]) {
...@@ -8084,7 +8170,8 @@ fn instantiateGenericCall(...@@ -8084,7 +8170,8 @@ fn instantiateGenericCall(
8084 call_tag: Air.Inst.Tag,8170 call_tag: Air.Inst.Tag,
8085 call_dbg_node: ?Zir.Inst.Index,8171 call_dbg_node: ?Zir.Inst.Index,
8086) CompileError!Air.Inst.Ref {8172) CompileError!Air.Inst.Ref {
8087 const zcu = sema.mod;8173 const pt = sema.pt;
8174 const zcu = pt.zcu;
8088 const gpa = sema.gpa;8175 const gpa = sema.gpa;
8089 const ip = &zcu.intern_pool;8176 const ip = &zcu.intern_pool;
80908177
...@@ -8127,7 +8214,7 @@ fn instantiateGenericCall(...@@ -8127,7 +8214,7 @@ fn instantiateGenericCall(
8127 // `param_anytype_comptime` ZIR instructions to be ignored, resulting in a8214 // `param_anytype_comptime` ZIR instructions to be ignored, resulting in a
8128 // new, monomorphized function, with the comptime parameters elided.8215 // new, monomorphized function, with the comptime parameters elided.
8129 var child_sema: Sema = .{8216 var child_sema: Sema = .{
8130 .mod = zcu,8217 .pt = pt,
8131 .gpa = gpa,8218 .gpa = gpa,
8132 .arena = sema.arena,8219 .arena = sema.arena,
8133 .code = fn_zir,8220 .code = fn_zir,
...@@ -8358,7 +8445,8 @@ fn instantiateGenericCall(...@@ -8358,7 +8445,8 @@ fn instantiateGenericCall(
8358}8445}
83598446
8360fn resolveTupleLazyValues(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type) CompileError!void {8447fn resolveTupleLazyValues(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type) CompileError!void {
8361 const mod = sema.mod;8448 const pt = sema.pt;
8449 const mod = pt.zcu;
8362 const ip = &mod.intern_pool;8450 const ip = &mod.intern_pool;
8363 const tuple = switch (ip.indexToKey(ty.toIntern())) {8451 const tuple = switch (ip.indexToKey(ty.toIntern())) {
8364 .anon_struct_type => |tuple| tuple,8452 .anon_struct_type => |tuple| tuple,
...@@ -8373,9 +8461,8 @@ fn resolveTupleLazyValues(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type)...@@ -8373,9 +8461,8 @@ fn resolveTupleLazyValues(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type)
8373}8461}
83748462
8375fn zirIntType(sema: *Sema, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {8463fn zirIntType(sema: *Sema, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
8376 const mod = sema.mod;
8377 const int_type = sema.code.instructions.items(.data)[@intFromEnum(inst)].int_type;8464 const int_type = sema.code.instructions.items(.data)[@intFromEnum(inst)].int_type;
8378 const ty = try mod.intType(int_type.signedness, int_type.bit_count);8465 const ty = try sema.pt.intType(int_type.signedness, int_type.bit_count);
8379 return Air.internedToRef(ty.toIntern());8466 return Air.internedToRef(ty.toIntern());
8380}8467}
83818468
...@@ -8383,22 +8470,24 @@ fn zirOptionalType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErro...@@ -8383,22 +8470,24 @@ fn zirOptionalType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErro
8383 const tracy = trace(@src());8470 const tracy = trace(@src());
8384 defer tracy.end();8471 defer tracy.end();
83858472
8386 const mod = sema.mod;8473 const pt = sema.pt;
8474 const mod = pt.zcu;
8387 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;8475 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;
8388 const operand_src = block.src(.{ .node_offset_un_op = inst_data.src_node });8476 const operand_src = block.src(.{ .node_offset_un_op = inst_data.src_node });
8389 const child_type = try sema.resolveType(block, operand_src, inst_data.operand);8477 const child_type = try sema.resolveType(block, operand_src, inst_data.operand);
8390 if (child_type.zigTypeTag(mod) == .Opaque) {8478 if (child_type.zigTypeTag(mod) == .Opaque) {
8391 return sema.fail(block, operand_src, "opaque type '{}' cannot be optional", .{child_type.fmt(mod)});8479 return sema.fail(block, operand_src, "opaque type '{}' cannot be optional", .{child_type.fmt(pt)});
8392 } else if (child_type.zigTypeTag(mod) == .Null) {8480 } else if (child_type.zigTypeTag(mod) == .Null) {
8393 return sema.fail(block, operand_src, "type '{}' cannot be optional", .{child_type.fmt(mod)});8481 return sema.fail(block, operand_src, "type '{}' cannot be optional", .{child_type.fmt(pt)});
8394 }8482 }
8395 const opt_type = try mod.optionalType(child_type.toIntern());8483 const opt_type = try pt.optionalType(child_type.toIntern());
83968484
8397 return Air.internedToRef(opt_type.toIntern());8485 return Air.internedToRef(opt_type.toIntern());
8398}8486}
83998487
8400fn zirArrayInitElemType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {8488fn zirArrayInitElemType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
8401 const mod = sema.mod;8489 const pt = sema.pt;
8490 const mod = pt.zcu;
8402 const bin = sema.code.instructions.items(.data)[@intFromEnum(inst)].bin;8491 const bin = sema.code.instructions.items(.data)[@intFromEnum(inst)].bin;
8403 const maybe_wrapped_indexable_ty = sema.resolveType(block, LazySrcLoc.unneeded, bin.lhs) catch |err| switch (err) {8492 const maybe_wrapped_indexable_ty = sema.resolveType(block, LazySrcLoc.unneeded, bin.lhs) catch |err| switch (err) {
8404 // Since this is a ZIR instruction that returns a type, encountering8493 // Since this is a ZIR instruction that returns a type, encountering
...@@ -8409,7 +8498,7 @@ fn zirArrayInitElemType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Compil...@@ -8409,7 +8498,7 @@ fn zirArrayInitElemType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Compil
8409 else => |e| return e,8498 else => |e| return e,
8410 };8499 };
8411 const indexable_ty = maybe_wrapped_indexable_ty.optEuBaseType(mod);8500 const indexable_ty = maybe_wrapped_indexable_ty.optEuBaseType(mod);
8412 try indexable_ty.resolveFields(mod);8501 try indexable_ty.resolveFields(pt);
8413 assert(indexable_ty.isIndexable(mod)); // validated by a previous instruction8502 assert(indexable_ty.isIndexable(mod)); // validated by a previous instruction
8414 if (indexable_ty.zigTypeTag(mod) == .Struct) {8503 if (indexable_ty.zigTypeTag(mod) == .Struct) {
8415 const elem_type = indexable_ty.structFieldType(@intFromEnum(bin.rhs), mod);8504 const elem_type = indexable_ty.structFieldType(@intFromEnum(bin.rhs), mod);
...@@ -8421,7 +8510,8 @@ fn zirArrayInitElemType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Compil...@@ -8421,7 +8510,8 @@ fn zirArrayInitElemType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Compil
8421}8510}
84228511
8423fn zirElemType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {8512fn zirElemType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
8424 const mod = sema.mod;8513 const pt = sema.pt;
8514 const mod = pt.zcu;
8425 const un_node = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;8515 const un_node = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;
8426 const maybe_wrapped_ptr_ty = sema.resolveType(block, LazySrcLoc.unneeded, un_node.operand) catch |err| switch (err) {8516 const maybe_wrapped_ptr_ty = sema.resolveType(block, LazySrcLoc.unneeded, un_node.operand) catch |err| switch (err) {
8427 error.GenericPoison => return .generic_poison_type,8517 error.GenericPoison => return .generic_poison_type,
...@@ -8439,7 +8529,8 @@ fn zirElemType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -8439,7 +8529,8 @@ fn zirElemType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
8439}8529}
84408530
8441fn zirIndexablePtrElemType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {8531fn zirIndexablePtrElemType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
8442 const mod = sema.mod;8532 const pt = sema.pt;
8533 const mod = pt.zcu;
8443 const un_node = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;8534 const un_node = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;
8444 const src = block.nodeOffset(un_node.src_node);8535 const src = block.nodeOffset(un_node.src_node);
8445 const ptr_ty = sema.resolveType(block, src, un_node.operand) catch |err| switch (err) {8536 const ptr_ty = sema.resolveType(block, src, un_node.operand) catch |err| switch (err) {
...@@ -8455,7 +8546,8 @@ fn zirIndexablePtrElemType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Com...@@ -8455,7 +8546,8 @@ fn zirIndexablePtrElemType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Com
8455}8546}
84568547
8457fn zirVectorElemType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {8548fn zirVectorElemType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
8458 const mod = sema.mod;8549 const pt = sema.pt;
8550 const mod = pt.zcu;
8459 const un_node = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;8551 const un_node = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;
8460 const vec_ty = sema.resolveType(block, LazySrcLoc.unneeded, un_node.operand) catch |err| switch (err) {8552 const vec_ty = sema.resolveType(block, LazySrcLoc.unneeded, un_node.operand) catch |err| switch (err) {
8461 // Since this is a ZIR instruction that returns a type, encountering8553 // Since this is a ZIR instruction that returns a type, encountering
...@@ -8466,13 +8558,12 @@ fn zirVectorElemType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileEr...@@ -8466,13 +8558,12 @@ fn zirVectorElemType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileEr
8466 else => |e| return e,8558 else => |e| return e,
8467 };8559 };
8468 if (!vec_ty.isVector(mod)) {8560 if (!vec_ty.isVector(mod)) {
8469 return sema.fail(block, block.nodeOffset(un_node.src_node), "expected vector type, found '{}'", .{vec_ty.fmt(mod)});8561 return sema.fail(block, block.nodeOffset(un_node.src_node), "expected vector type, found '{}'", .{vec_ty.fmt(pt)});
8470 }8562 }
8471 return Air.internedToRef(vec_ty.childType(mod).toIntern());8563 return Air.internedToRef(vec_ty.childType(mod).toIntern());
8472}8564}
84738565
8474fn zirVectorType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {8566fn zirVectorType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
8475 const mod = sema.mod;
8476 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;8567 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
8477 const len_src = block.builtinCallArgSrc(inst_data.src_node, 0);8568 const len_src = block.builtinCallArgSrc(inst_data.src_node, 0);
8478 const elem_type_src = block.builtinCallArgSrc(inst_data.src_node, 1);8569 const elem_type_src = block.builtinCallArgSrc(inst_data.src_node, 1);
...@@ -8482,7 +8573,7 @@ fn zirVectorType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!...@@ -8482,7 +8573,7 @@ fn zirVectorType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!
8482 }));8573 }));
8483 const elem_type = try sema.resolveType(block, elem_type_src, extra.rhs);8574 const elem_type = try sema.resolveType(block, elem_type_src, extra.rhs);
8484 try sema.checkVectorElemType(block, elem_type_src, elem_type);8575 try sema.checkVectorElemType(block, elem_type_src, elem_type);
8485 const vector_type = try mod.vectorType(.{8576 const vector_type = try sema.pt.vectorType(.{
8486 .len = len,8577 .len = len,
8487 .child = elem_type.toIntern(),8578 .child = elem_type.toIntern(),
8488 });8579 });
...@@ -8502,7 +8593,7 @@ fn zirArrayType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A...@@ -8502,7 +8593,7 @@ fn zirArrayType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
8502 });8593 });
8503 const elem_type = try sema.resolveType(block, elem_src, extra.rhs);8594 const elem_type = try sema.resolveType(block, elem_src, extra.rhs);
8504 try sema.validateArrayElemType(block, elem_type, elem_src);8595 try sema.validateArrayElemType(block, elem_type, elem_src);
8505 const array_ty = try sema.mod.arrayType(.{8596 const array_ty = try sema.pt.arrayType(.{
8506 .len = len,8597 .len = len,
8507 .child = elem_type.toIntern(),8598 .child = elem_type.toIntern(),
8508 });8599 });
...@@ -8529,7 +8620,7 @@ fn zirArrayTypeSentinel(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Compil...@@ -8529,7 +8620,7 @@ fn zirArrayTypeSentinel(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Compil
8529 const sentinel_val = try sema.resolveConstDefinedValue(block, sentinel_src, sentinel, .{8620 const sentinel_val = try sema.resolveConstDefinedValue(block, sentinel_src, sentinel, .{
8530 .needed_comptime_reason = "array sentinel value must be comptime-known",8621 .needed_comptime_reason = "array sentinel value must be comptime-known",
8531 });8622 });
8532 const array_ty = try sema.mod.arrayType(.{8623 const array_ty = try sema.pt.arrayType(.{
8533 .len = len,8624 .len = len,
8534 .sentinel = sentinel_val.toIntern(),8625 .sentinel = sentinel_val.toIntern(),
8535 .child = elem_type.toIntern(),8626 .child = elem_type.toIntern(),
...@@ -8539,9 +8630,10 @@ fn zirArrayTypeSentinel(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Compil...@@ -8539,9 +8630,10 @@ fn zirArrayTypeSentinel(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Compil
8539}8630}
85408631
8541fn validateArrayElemType(sema: *Sema, block: *Block, elem_type: Type, elem_src: LazySrcLoc) !void {8632fn validateArrayElemType(sema: *Sema, block: *Block, elem_type: Type, elem_src: LazySrcLoc) !void {
8542 const mod = sema.mod;8633 const pt = sema.pt;
8634 const mod = pt.zcu;
8543 if (elem_type.zigTypeTag(mod) == .Opaque) {8635 if (elem_type.zigTypeTag(mod) == .Opaque) {
8544 return sema.fail(block, elem_src, "array of opaque type '{}' not allowed", .{elem_type.fmt(mod)});8636 return sema.fail(block, elem_src, "array of opaque type '{}' not allowed", .{elem_type.fmt(pt)});
8545 } else if (elem_type.zigTypeTag(mod) == .NoReturn) {8637 } else if (elem_type.zigTypeTag(mod) == .NoReturn) {
8546 return sema.fail(block, elem_src, "array of 'noreturn' not allowed", .{});8638 return sema.fail(block, elem_src, "array of 'noreturn' not allowed", .{});
8547 }8639 }
...@@ -8567,7 +8659,8 @@ fn zirErrorUnionType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileEr...@@ -8567,7 +8659,8 @@ fn zirErrorUnionType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileEr
8567 const tracy = trace(@src());8659 const tracy = trace(@src());
8568 defer tracy.end();8660 defer tracy.end();
85698661
8570 const mod = sema.mod;8662 const pt = sema.pt;
8663 const mod = pt.zcu;
8571 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;8664 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
8572 const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data;8665 const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data;
8573 const lhs_src = block.src(.{ .node_offset_bin_lhs = inst_data.src_node });8666 const lhs_src = block.src(.{ .node_offset_bin_lhs = inst_data.src_node });
...@@ -8577,40 +8670,42 @@ fn zirErrorUnionType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileEr...@@ -8577,40 +8670,42 @@ fn zirErrorUnionType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileEr
85778670
8578 if (error_set.zigTypeTag(mod) != .ErrorSet) {8671 if (error_set.zigTypeTag(mod) != .ErrorSet) {
8579 return sema.fail(block, lhs_src, "expected error set type, found '{}'", .{8672 return sema.fail(block, lhs_src, "expected error set type, found '{}'", .{
8580 error_set.fmt(mod),8673 error_set.fmt(pt),
8581 });8674 });
8582 }8675 }
8583 try sema.validateErrorUnionPayloadType(block, payload, rhs_src);8676 try sema.validateErrorUnionPayloadType(block, payload, rhs_src);
8584 const err_union_ty = try mod.errorUnionType(error_set, payload);8677 const err_union_ty = try pt.errorUnionType(error_set, payload);
8585 return Air.internedToRef(err_union_ty.toIntern());8678 return Air.internedToRef(err_union_ty.toIntern());
8586}8679}
85878680
8588fn validateErrorUnionPayloadType(sema: *Sema, block: *Block, payload_ty: Type, payload_src: LazySrcLoc) !void {8681fn validateErrorUnionPayloadType(sema: *Sema, block: *Block, payload_ty: Type, payload_src: LazySrcLoc) !void {
8589 const mod = sema.mod;8682 const pt = sema.pt;
8683 const mod = pt.zcu;
8590 if (payload_ty.zigTypeTag(mod) == .Opaque) {8684 if (payload_ty.zigTypeTag(mod) == .Opaque) {
8591 return sema.fail(block, payload_src, "error union with payload of opaque type '{}' not allowed", .{8685 return sema.fail(block, payload_src, "error union with payload of opaque type '{}' not allowed", .{
8592 payload_ty.fmt(mod),8686 payload_ty.fmt(pt),
8593 });8687 });
8594 } else if (payload_ty.zigTypeTag(mod) == .ErrorSet) {8688 } else if (payload_ty.zigTypeTag(mod) == .ErrorSet) {
8595 return sema.fail(block, payload_src, "error union with payload of error set type '{}' not allowed", .{8689 return sema.fail(block, payload_src, "error union with payload of error set type '{}' not allowed", .{
8596 payload_ty.fmt(mod),8690 payload_ty.fmt(pt),
8597 });8691 });
8598 }8692 }
8599}8693}
86008694
8601fn zirErrorValue(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {8695fn zirErrorValue(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
8602 _ = block;8696 _ = block;
8603 const mod = sema.mod;8697 const pt = sema.pt;
8604 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].str_tok;8698 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].str_tok;
8605 const name = try mod.intern_pool.getOrPutString(8699 const name = try pt.zcu.intern_pool.getOrPutString(
8606 sema.gpa,8700 sema.gpa,
8701 pt.tid,
8607 inst_data.get(sema.code),8702 inst_data.get(sema.code),
8608 .no_embedded_nulls,8703 .no_embedded_nulls,
8609 );8704 );
8610 _ = try mod.getErrorValue(name);8705 _ = try pt.zcu.getErrorValue(name);
8611 // Create an error set type with only this error value, and return the value.8706 // Create an error set type with only this error value, and return the value.
8612 const error_set_type = try mod.singleErrorSetType(name);8707 const error_set_type = try pt.singleErrorSetType(name);
8613 return Air.internedToRef((try mod.intern(.{ .err = .{8708 return Air.internedToRef((try pt.intern(.{ .err = .{
8614 .ty = error_set_type.toIntern(),8709 .ty = error_set_type.toIntern(),
8615 .name = name,8710 .name = name,
8616 } })));8711 } })));
...@@ -8620,21 +8715,22 @@ fn zirIntFromError(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstD...@@ -8620,21 +8715,22 @@ fn zirIntFromError(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstD
8620 const tracy = trace(@src());8715 const tracy = trace(@src());
8621 defer tracy.end();8716 defer tracy.end();
86228717
8623 const mod = sema.mod;8718 const pt = sema.pt;
8719 const mod = pt.zcu;
8624 const ip = &mod.intern_pool;8720 const ip = &mod.intern_pool;
8625 const extra = sema.code.extraData(Zir.Inst.UnNode, extended.operand).data;8721 const extra = sema.code.extraData(Zir.Inst.UnNode, extended.operand).data;
8626 const src = block.nodeOffset(extra.node);8722 const src = block.nodeOffset(extra.node);
8627 const operand_src = block.builtinCallArgSrc(extra.node, 0);8723 const operand_src = block.builtinCallArgSrc(extra.node, 0);
8628 const uncasted_operand = try sema.resolveInst(extra.operand);8724 const uncasted_operand = try sema.resolveInst(extra.operand);
8629 const operand = try sema.coerce(block, Type.anyerror, uncasted_operand, operand_src);8725 const operand = try sema.coerce(block, Type.anyerror, uncasted_operand, operand_src);
8630 const err_int_ty = try mod.errorIntType();8726 const err_int_ty = try pt.errorIntType();
86318727
8632 if (try sema.resolveValue(operand)) |val| {8728 if (try sema.resolveValue(operand)) |val| {
8633 if (val.isUndef(mod)) {8729 if (val.isUndef(mod)) {
8634 return mod.undefRef(err_int_ty);8730 return pt.undefRef(err_int_ty);
8635 }8731 }
8636 const err_name = ip.indexToKey(val.toIntern()).err.name;8732 const err_name = ip.indexToKey(val.toIntern()).err.name;
8637 return Air.internedToRef((try mod.intValue(8733 return Air.internedToRef((try pt.intValue(
8638 err_int_ty,8734 err_int_ty,
8639 try mod.getErrorValue(err_name),8735 try mod.getErrorValue(err_name),
8640 )).toIntern());8736 )).toIntern());
...@@ -8646,10 +8742,10 @@ fn zirIntFromError(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstD...@@ -8646,10 +8742,10 @@ fn zirIntFromError(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstD
8646 else => |err_set_ty_index| {8742 else => |err_set_ty_index| {
8647 const names = ip.indexToKey(err_set_ty_index).error_set_type.names;8743 const names = ip.indexToKey(err_set_ty_index).error_set_type.names;
8648 switch (names.len) {8744 switch (names.len) {
8649 0 => return Air.internedToRef((try mod.intValue(err_int_ty, 0)).toIntern()),8745 0 => return Air.internedToRef((try pt.intValue(err_int_ty, 0)).toIntern()),
8650 1 => {8746 1 => {
8651 const int: Module.ErrorInt = @intCast(mod.global_error_set.getIndex(names.get(ip)[0]).?);8747 const int: Module.ErrorInt = @intCast(mod.global_error_set.getIndex(names.get(ip)[0]).?);
8652 return mod.intRef(err_int_ty, int);8748 return pt.intRef(err_int_ty, int);
8653 },8749 },
8654 else => {},8750 else => {},
8655 }8751 }
...@@ -8664,19 +8760,20 @@ fn zirErrorFromInt(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstD...@@ -8664,19 +8760,20 @@ fn zirErrorFromInt(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstD
8664 const tracy = trace(@src());8760 const tracy = trace(@src());
8665 defer tracy.end();8761 defer tracy.end();
86668762
8667 const mod = sema.mod;8763 const pt = sema.pt;
8764 const mod = pt.zcu;
8668 const extra = sema.code.extraData(Zir.Inst.UnNode, extended.operand).data;8765 const extra = sema.code.extraData(Zir.Inst.UnNode, extended.operand).data;
8669 const src = block.nodeOffset(extra.node);8766 const src = block.nodeOffset(extra.node);
8670 const operand_src = block.builtinCallArgSrc(extra.node, 0);8767 const operand_src = block.builtinCallArgSrc(extra.node, 0);
8671 const uncasted_operand = try sema.resolveInst(extra.operand);8768 const uncasted_operand = try sema.resolveInst(extra.operand);
8672 const err_int_ty = try mod.errorIntType();8769 const err_int_ty = try pt.errorIntType();
8673 const operand = try sema.coerce(block, err_int_ty, uncasted_operand, operand_src);8770 const operand = try sema.coerce(block, err_int_ty, uncasted_operand, operand_src);
86748771
8675 if (try sema.resolveDefinedValue(block, operand_src, operand)) |value| {8772 if (try sema.resolveDefinedValue(block, operand_src, operand)) |value| {
8676 const int = try sema.usizeCast(block, operand_src, try value.toUnsignedIntSema(mod));8773 const int = try sema.usizeCast(block, operand_src, try value.toUnsignedIntSema(pt));
8677 if (int > mod.global_error_set.count() or int == 0)8774 if (int > mod.global_error_set.count() or int == 0)
8678 return sema.fail(block, operand_src, "integer value '{d}' represents no error", .{int});8775 return sema.fail(block, operand_src, "integer value '{d}' represents no error", .{int});
8679 return Air.internedToRef((try mod.intern(.{ .err = .{8776 return Air.internedToRef((try pt.intern(.{ .err = .{
8680 .ty = .anyerror_type,8777 .ty = .anyerror_type,
8681 .name = mod.global_error_set.keys()[int],8778 .name = mod.global_error_set.keys()[int],
8682 } })));8779 } })));
...@@ -8684,7 +8781,7 @@ fn zirErrorFromInt(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstD...@@ -8684,7 +8781,7 @@ fn zirErrorFromInt(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstD
8684 try sema.requireRuntimeBlock(block, src, operand_src);8781 try sema.requireRuntimeBlock(block, src, operand_src);
8685 if (block.wantSafety()) {8782 if (block.wantSafety()) {
8686 const is_lt_len = try block.addUnOp(.cmp_lt_errors_len, operand);8783 const is_lt_len = try block.addUnOp(.cmp_lt_errors_len, operand);
8687 const zero_val = Air.internedToRef((try mod.intValue(err_int_ty, 0)).toIntern());8784 const zero_val = Air.internedToRef((try pt.intValue(err_int_ty, 0)).toIntern());
8688 const is_non_zero = try block.addBinOp(.cmp_neq, operand, zero_val);8785 const is_non_zero = try block.addBinOp(.cmp_neq, operand, zero_val);
8689 const ok = try block.addBinOp(.bool_and, is_lt_len, is_non_zero);8786 const ok = try block.addBinOp(.bool_and, is_lt_len, is_non_zero);
8690 try sema.addSafetyCheck(block, src, ok, .invalid_error_code);8787 try sema.addSafetyCheck(block, src, ok, .invalid_error_code);
...@@ -8702,7 +8799,8 @@ fn zirMergeErrorSets(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileEr...@@ -8702,7 +8799,8 @@ fn zirMergeErrorSets(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileEr
8702 const tracy = trace(@src());8799 const tracy = trace(@src());
8703 defer tracy.end();8800 defer tracy.end();
87048801
8705 const mod = sema.mod;8802 const pt = sema.pt;
8803 const mod = pt.zcu;
8706 const ip = &mod.intern_pool;8804 const ip = &mod.intern_pool;
8707 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;8805 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
8708 const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data;8806 const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data;
...@@ -8723,9 +8821,9 @@ fn zirMergeErrorSets(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileEr...@@ -8723,9 +8821,9 @@ fn zirMergeErrorSets(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileEr
8723 const lhs_ty = try sema.analyzeAsType(block, lhs_src, lhs);8821 const lhs_ty = try sema.analyzeAsType(block, lhs_src, lhs);
8724 const rhs_ty = try sema.analyzeAsType(block, rhs_src, rhs);8822 const rhs_ty = try sema.analyzeAsType(block, rhs_src, rhs);
8725 if (lhs_ty.zigTypeTag(mod) != .ErrorSet)8823 if (lhs_ty.zigTypeTag(mod) != .ErrorSet)
8726 return sema.fail(block, lhs_src, "expected error set type, found '{}'", .{lhs_ty.fmt(mod)});8824 return sema.fail(block, lhs_src, "expected error set type, found '{}'", .{lhs_ty.fmt(pt)});
8727 if (rhs_ty.zigTypeTag(mod) != .ErrorSet)8825 if (rhs_ty.zigTypeTag(mod) != .ErrorSet)
8728 return sema.fail(block, rhs_src, "expected error set type, found '{}'", .{rhs_ty.fmt(mod)});8826 return sema.fail(block, rhs_src, "expected error set type, found '{}'", .{rhs_ty.fmt(pt)});
87298827
8730 // Anything merged with anyerror is anyerror.8828 // Anything merged with anyerror is anyerror.
8731 if (lhs_ty.toIntern() == .anyerror_type or rhs_ty.toIntern() == .anyerror_type) {8829 if (lhs_ty.toIntern() == .anyerror_type or rhs_ty.toIntern() == .anyerror_type) {
...@@ -8758,16 +8856,18 @@ fn zirEnumLiteral(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError...@@ -8758,16 +8856,18 @@ fn zirEnumLiteral(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
8758 const tracy = trace(@src());8856 const tracy = trace(@src());
8759 defer tracy.end();8857 defer tracy.end();
87608858
8761 const mod = sema.mod;8859 const pt = sema.pt;
8860 const mod = pt.zcu;
8762 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].str_tok;8861 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].str_tok;
8763 const name = inst_data.get(sema.code);8862 const name = inst_data.get(sema.code);
8764 return Air.internedToRef((try mod.intern(.{8863 return Air.internedToRef((try pt.intern(.{
8765 .enum_literal = try mod.intern_pool.getOrPutString(sema.gpa, name, .no_embedded_nulls),8864 .enum_literal = try mod.intern_pool.getOrPutString(sema.gpa, pt.tid, name, .no_embedded_nulls),
8766 })));8865 })));
8767}8866}
87688867
8769fn zirIntFromEnum(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {8868fn zirIntFromEnum(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
8770 const mod = sema.mod;8869 const pt = sema.pt;
8870 const mod = pt.zcu;
8771 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;8871 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;
8772 const src = block.nodeOffset(inst_data.src_node);8872 const src = block.nodeOffset(inst_data.src_node);
8773 const operand_src = block.builtinCallArgSrc(inst_data.src_node, 0);8873 const operand_src = block.builtinCallArgSrc(inst_data.src_node, 0);
...@@ -8777,7 +8877,7 @@ fn zirIntFromEnum(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError...@@ -8777,7 +8877,7 @@ fn zirIntFromEnum(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
8777 const enum_tag: Air.Inst.Ref = switch (operand_ty.zigTypeTag(mod)) {8877 const enum_tag: Air.Inst.Ref = switch (operand_ty.zigTypeTag(mod)) {
8778 .Enum => operand,8878 .Enum => operand,
8779 .Union => blk: {8879 .Union => blk: {
8780 try operand_ty.resolveFields(mod);8880 try operand_ty.resolveFields(pt);
8781 const tag_ty = operand_ty.unionTagType(mod) orelse {8881 const tag_ty = operand_ty.unionTagType(mod) orelse {
8782 return sema.fail(8882 return sema.fail(
8783 block,8883 block,
...@@ -8791,7 +8891,7 @@ fn zirIntFromEnum(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError...@@ -8791,7 +8891,7 @@ fn zirIntFromEnum(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
8791 },8891 },
8792 else => {8892 else => {
8793 return sema.fail(block, operand_src, "expected enum or tagged union, found '{}'", .{8893 return sema.fail(block, operand_src, "expected enum or tagged union, found '{}'", .{
8794 operand_ty.fmt(mod),8894 operand_ty.fmt(pt),
8795 });8895 });
8796 },8896 },
8797 };8897 };
...@@ -8802,20 +8902,20 @@ fn zirIntFromEnum(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError...@@ -8802,20 +8902,20 @@ fn zirIntFromEnum(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
8802 // https://github.com/ziglang/zig/issues/159098902 // https://github.com/ziglang/zig/issues/15909
8803 if (enum_tag_ty.enumFieldCount(mod) == 0 and !enum_tag_ty.isNonexhaustiveEnum(mod)) {8903 if (enum_tag_ty.enumFieldCount(mod) == 0 and !enum_tag_ty.isNonexhaustiveEnum(mod)) {
8804 return sema.fail(block, operand_src, "cannot use @intFromEnum on empty enum '{}'", .{8904 return sema.fail(block, operand_src, "cannot use @intFromEnum on empty enum '{}'", .{
8805 enum_tag_ty.fmt(mod),8905 enum_tag_ty.fmt(pt),
8806 });8906 });
8807 }8907 }
88088908
8809 if (try sema.typeHasOnePossibleValue(enum_tag_ty)) |opv| {8909 if (try sema.typeHasOnePossibleValue(enum_tag_ty)) |opv| {
8810 return Air.internedToRef((try mod.getCoerced(opv, int_tag_ty)).toIntern());8910 return Air.internedToRef((try pt.getCoerced(opv, int_tag_ty)).toIntern());
8811 }8911 }
88128912
8813 if (try sema.resolveValue(enum_tag)) |enum_tag_val| {8913 if (try sema.resolveValue(enum_tag)) |enum_tag_val| {
8814 if (enum_tag_val.isUndef(mod)) {8914 if (enum_tag_val.isUndef(mod)) {
8815 return mod.undefRef(int_tag_ty);8915 return pt.undefRef(int_tag_ty);
8816 }8916 }
88178917
8818 const val = try enum_tag_val.intFromEnum(enum_tag_ty, mod);8918 const val = try enum_tag_val.intFromEnum(enum_tag_ty, pt);
8819 return Air.internedToRef(val.toIntern());8919 return Air.internedToRef(val.toIntern());
8820 }8920 }
88218921
...@@ -8824,7 +8924,8 @@ fn zirIntFromEnum(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError...@@ -8824,7 +8924,8 @@ fn zirIntFromEnum(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
8824}8924}
88258925
8826fn zirEnumFromInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {8926fn zirEnumFromInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
8827 const mod = sema.mod;8927 const pt = sema.pt;
8928 const mod = pt.zcu;
8828 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;8929 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
8829 const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data;8930 const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data;
8830 const src = block.nodeOffset(inst_data.src_node);8931 const src = block.nodeOffset(inst_data.src_node);
...@@ -8833,7 +8934,7 @@ fn zirEnumFromInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError...@@ -8833,7 +8934,7 @@ fn zirEnumFromInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
8833 const operand = try sema.resolveInst(extra.rhs);8934 const operand = try sema.resolveInst(extra.rhs);
88348935
8835 if (dest_ty.zigTypeTag(mod) != .Enum) {8936 if (dest_ty.zigTypeTag(mod) != .Enum) {
8836 return sema.fail(block, src, "expected enum, found '{}'", .{dest_ty.fmt(mod)});8937 return sema.fail(block, src, "expected enum, found '{}'", .{dest_ty.fmt(pt)});
8837 }8938 }
8838 _ = try sema.checkIntType(block, operand_src, sema.typeOf(operand));8939 _ = try sema.checkIntType(block, operand_src, sema.typeOf(operand));
88398940
...@@ -8841,10 +8942,10 @@ fn zirEnumFromInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError...@@ -8841,10 +8942,10 @@ fn zirEnumFromInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
8841 if (dest_ty.isNonexhaustiveEnum(mod)) {8942 if (dest_ty.isNonexhaustiveEnum(mod)) {
8842 const int_tag_ty = dest_ty.intTagType(mod);8943 const int_tag_ty = dest_ty.intTagType(mod);
8843 if (try sema.intFitsInType(int_val, int_tag_ty, null)) {8944 if (try sema.intFitsInType(int_val, int_tag_ty, null)) {
8844 return Air.internedToRef((try mod.getCoerced(int_val, dest_ty)).toIntern());8945 return Air.internedToRef((try pt.getCoerced(int_val, dest_ty)).toIntern());
8845 }8946 }
8846 return sema.fail(block, src, "int value '{}' out of range of non-exhaustive enum '{}'", .{8947 return sema.fail(block, src, "int value '{}' out of range of non-exhaustive enum '{}'", .{
8847 int_val.fmtValue(mod, sema), dest_ty.fmt(mod),8948 int_val.fmtValue(pt, sema), dest_ty.fmt(pt),
8848 });8949 });
8849 }8950 }
8850 if (int_val.isUndef(mod)) {8951 if (int_val.isUndef(mod)) {
...@@ -8852,10 +8953,10 @@ fn zirEnumFromInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError...@@ -8852,10 +8953,10 @@ fn zirEnumFromInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
8852 }8953 }
8853 if (!(try sema.enumHasInt(dest_ty, int_val))) {8954 if (!(try sema.enumHasInt(dest_ty, int_val))) {
8854 return sema.fail(block, src, "enum '{}' has no tag with value '{}'", .{8955 return sema.fail(block, src, "enum '{}' has no tag with value '{}'", .{
8855 dest_ty.fmt(mod), int_val.fmtValue(mod, sema),8956 dest_ty.fmt(pt), int_val.fmtValue(pt, sema),
8856 });8957 });
8857 }8958 }
8858 return Air.internedToRef((try mod.getCoerced(int_val, dest_ty)).toIntern());8959 return Air.internedToRef((try pt.getCoerced(int_val, dest_ty)).toIntern());
8859 }8960 }
88608961
8861 if (dest_ty.intTagType(mod).zigTypeTag(mod) == .ComptimeInt) {8962 if (dest_ty.intTagType(mod).zigTypeTag(mod) == .ComptimeInt) {
...@@ -8909,7 +9010,8 @@ fn analyzeOptionalPayloadPtr(...@@ -8909,7 +9010,8 @@ fn analyzeOptionalPayloadPtr(
8909 safety_check: bool,9010 safety_check: bool,
8910 initializing: bool,9011 initializing: bool,
8911) CompileError!Air.Inst.Ref {9012) CompileError!Air.Inst.Ref {
8912 const zcu = sema.mod;9013 const pt = sema.pt;
9014 const zcu = pt.zcu;
8913 const optional_ptr_ty = sema.typeOf(optional_ptr);9015 const optional_ptr_ty = sema.typeOf(optional_ptr);
8914 assert(optional_ptr_ty.zigTypeTag(zcu) == .Pointer);9016 assert(optional_ptr_ty.zigTypeTag(zcu) == .Pointer);
89159017
...@@ -8919,7 +9021,7 @@ fn analyzeOptionalPayloadPtr(...@@ -8919,7 +9021,7 @@ fn analyzeOptionalPayloadPtr(
8919 }9021 }
89209022
8921 const child_type = opt_type.optionalChild(zcu);9023 const child_type = opt_type.optionalChild(zcu);
8922 const child_pointer = try zcu.ptrTypeSema(.{9024 const child_pointer = try pt.ptrTypeSema(.{
8923 .child = child_type.toIntern(),9025 .child = child_type.toIntern(),
8924 .flags = .{9026 .flags = .{
8925 .is_const = optional_ptr_ty.isConstPtr(zcu),9027 .is_const = optional_ptr_ty.isConstPtr(zcu),
...@@ -8932,8 +9034,8 @@ fn analyzeOptionalPayloadPtr(...@@ -8932,8 +9034,8 @@ fn analyzeOptionalPayloadPtr(
8932 if (sema.isComptimeMutablePtr(ptr_val)) {9034 if (sema.isComptimeMutablePtr(ptr_val)) {
8933 // Set the optional to non-null at comptime.9035 // Set the optional to non-null at comptime.
8934 // If the payload is OPV, we must use that value instead of undef.9036 // If the payload is OPV, we must use that value instead of undef.
8935 const payload_val = try sema.typeHasOnePossibleValue(child_type) orelse try zcu.undefValue(child_type);9037 const payload_val = try sema.typeHasOnePossibleValue(child_type) orelse try pt.undefValue(child_type);
8936 const opt_val = try zcu.intern(.{ .opt = .{9038 const opt_val = try pt.intern(.{ .opt = .{
8937 .ty = opt_type.toIntern(),9039 .ty = opt_type.toIntern(),
8938 .val = payload_val.toIntern(),9040 .val = payload_val.toIntern(),
8939 } });9041 } });
...@@ -8943,13 +9045,13 @@ fn analyzeOptionalPayloadPtr(...@@ -8943,13 +9045,13 @@ fn analyzeOptionalPayloadPtr(
8943 const opt_payload_ptr = try block.addTyOp(.optional_payload_ptr_set, child_pointer, optional_ptr);9045 const opt_payload_ptr = try block.addTyOp(.optional_payload_ptr_set, child_pointer, optional_ptr);
8944 try sema.checkKnownAllocPtr(block, optional_ptr, opt_payload_ptr);9046 try sema.checkKnownAllocPtr(block, optional_ptr, opt_payload_ptr);
8945 }9047 }
8946 return Air.internedToRef((try ptr_val.ptrOptPayload(zcu)).toIntern());9048 return Air.internedToRef((try ptr_val.ptrOptPayload(pt)).toIntern());
8947 }9049 }
8948 if (try sema.pointerDeref(block, src, ptr_val, optional_ptr_ty)) |val| {9050 if (try sema.pointerDeref(block, src, ptr_val, optional_ptr_ty)) |val| {
8949 if (val.isNull(zcu)) {9051 if (val.isNull(zcu)) {
8950 return sema.fail(block, src, "unable to unwrap null", .{});9052 return sema.fail(block, src, "unable to unwrap null", .{});
8951 }9053 }
8952 return Air.internedToRef((try ptr_val.ptrOptPayload(zcu)).toIntern());9054 return Air.internedToRef((try ptr_val.ptrOptPayload(pt)).toIntern());
8953 }9055 }
8954 }9056 }
89559057
...@@ -8978,7 +9080,8 @@ fn zirOptionalPayload(...@@ -8978,7 +9080,8 @@ fn zirOptionalPayload(
8978 const tracy = trace(@src());9080 const tracy = trace(@src());
8979 defer tracy.end();9081 defer tracy.end();
89809082
8981 const mod = sema.mod;9083 const pt = sema.pt;
9084 const mod = pt.zcu;
8982 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;9085 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;
8983 const src = block.nodeOffset(inst_data.src_node);9086 const src = block.nodeOffset(inst_data.src_node);
8984 const operand = try sema.resolveInst(inst_data.operand);9087 const operand = try sema.resolveInst(inst_data.operand);
...@@ -8992,7 +9095,7 @@ fn zirOptionalPayload(...@@ -8992,7 +9095,7 @@ fn zirOptionalPayload(
8992 // TODO https://github.com/ziglang/zig/issues/65979095 // TODO https://github.com/ziglang/zig/issues/6597
8993 if (true) break :t operand_ty;9096 if (true) break :t operand_ty;
8994 const ptr_info = operand_ty.ptrInfo(mod);9097 const ptr_info = operand_ty.ptrInfo(mod);
8995 break :t try mod.ptrTypeSema(.{9098 break :t try pt.ptrTypeSema(.{
8996 .child = ptr_info.child,9099 .child = ptr_info.child,
8997 .flags = .{9100 .flags = .{
8998 .alignment = ptr_info.flags.alignment,9101 .alignment = ptr_info.flags.alignment,
...@@ -9030,7 +9133,8 @@ fn zirErrUnionPayload(...@@ -9030,7 +9133,8 @@ fn zirErrUnionPayload(
9030 const tracy = trace(@src());9133 const tracy = trace(@src());
9031 defer tracy.end();9134 defer tracy.end();
90329135
9033 const mod = sema.mod;9136 const pt = sema.pt;
9137 const mod = pt.zcu;
9034 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;9138 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;
9035 const src = block.nodeOffset(inst_data.src_node);9139 const src = block.nodeOffset(inst_data.src_node);
9036 const operand = try sema.resolveInst(inst_data.operand);9140 const operand = try sema.resolveInst(inst_data.operand);
...@@ -9038,7 +9142,7 @@ fn zirErrUnionPayload(...@@ -9038,7 +9142,7 @@ fn zirErrUnionPayload(
9038 const err_union_ty = sema.typeOf(operand);9142 const err_union_ty = sema.typeOf(operand);
9039 if (err_union_ty.zigTypeTag(mod) != .ErrorUnion) {9143 if (err_union_ty.zigTypeTag(mod) != .ErrorUnion) {
9040 return sema.fail(block, operand_src, "expected error union type, found '{}'", .{9144 return sema.fail(block, operand_src, "expected error union type, found '{}'", .{
9041 err_union_ty.fmt(mod),9145 err_union_ty.fmt(pt),
9042 });9146 });
9043 }9147 }
9044 return sema.analyzeErrUnionPayload(block, src, err_union_ty, operand, operand_src, false);9148 return sema.analyzeErrUnionPayload(block, src, err_union_ty, operand, operand_src, false);
...@@ -9053,7 +9157,8 @@ fn analyzeErrUnionPayload(...@@ -9053,7 +9157,8 @@ fn analyzeErrUnionPayload(
9053 operand_src: LazySrcLoc,9157 operand_src: LazySrcLoc,
9054 safety_check: bool,9158 safety_check: bool,
9055) CompileError!Air.Inst.Ref {9159) CompileError!Air.Inst.Ref {
9056 const mod = sema.mod;9160 const pt = sema.pt;
9161 const mod = pt.zcu;
9057 const payload_ty = err_union_ty.errorUnionPayload(mod);9162 const payload_ty = err_union_ty.errorUnionPayload(mod);
9058 if (try sema.resolveDefinedValue(block, operand_src, operand)) |val| {9163 if (try sema.resolveDefinedValue(block, operand_src, operand)) |val| {
9059 if (val.getErrorName(mod).unwrap()) |name| {9164 if (val.getErrorName(mod).unwrap()) |name| {
...@@ -9098,19 +9203,20 @@ fn analyzeErrUnionPayloadPtr(...@@ -9098,19 +9203,20 @@ fn analyzeErrUnionPayloadPtr(
9098 safety_check: bool,9203 safety_check: bool,
9099 initializing: bool,9204 initializing: bool,
9100) CompileError!Air.Inst.Ref {9205) CompileError!Air.Inst.Ref {
9101 const zcu = sema.mod;9206 const pt = sema.pt;
9207 const zcu = pt.zcu;
9102 const operand_ty = sema.typeOf(operand);9208 const operand_ty = sema.typeOf(operand);
9103 assert(operand_ty.zigTypeTag(zcu) == .Pointer);9209 assert(operand_ty.zigTypeTag(zcu) == .Pointer);
91049210
9105 if (operand_ty.childType(zcu).zigTypeTag(zcu) != .ErrorUnion) {9211 if (operand_ty.childType(zcu).zigTypeTag(zcu) != .ErrorUnion) {
9106 return sema.fail(block, src, "expected error union type, found '{}'", .{9212 return sema.fail(block, src, "expected error union type, found '{}'", .{
9107 operand_ty.childType(zcu).fmt(zcu),9213 operand_ty.childType(zcu).fmt(pt),
9108 });9214 });
9109 }9215 }
91109216
9111 const err_union_ty = operand_ty.childType(zcu);9217 const err_union_ty = operand_ty.childType(zcu);
9112 const payload_ty = err_union_ty.errorUnionPayload(zcu);9218 const payload_ty = err_union_ty.errorUnionPayload(zcu);
9113 const operand_pointer_ty = try zcu.ptrTypeSema(.{9219 const operand_pointer_ty = try pt.ptrTypeSema(.{
9114 .child = payload_ty.toIntern(),9220 .child = payload_ty.toIntern(),
9115 .flags = .{9221 .flags = .{
9116 .is_const = operand_ty.isConstPtr(zcu),9222 .is_const = operand_ty.isConstPtr(zcu),
...@@ -9123,8 +9229,8 @@ fn analyzeErrUnionPayloadPtr(...@@ -9123,8 +9229,8 @@ fn analyzeErrUnionPayloadPtr(
9123 if (sema.isComptimeMutablePtr(ptr_val)) {9229 if (sema.isComptimeMutablePtr(ptr_val)) {
9124 // Set the error union to non-error at comptime.9230 // Set the error union to non-error at comptime.
9125 // If the payload is OPV, we must use that value instead of undef.9231 // If the payload is OPV, we must use that value instead of undef.
9126 const payload_val = try sema.typeHasOnePossibleValue(payload_ty) orelse try zcu.undefValue(payload_ty);9232 const payload_val = try sema.typeHasOnePossibleValue(payload_ty) orelse try pt.undefValue(payload_ty);
9127 const eu_val = try zcu.intern(.{ .error_union = .{9233 const eu_val = try pt.intern(.{ .error_union = .{
9128 .ty = err_union_ty.toIntern(),9234 .ty = err_union_ty.toIntern(),
9129 .val = .{ .payload = payload_val.toIntern() },9235 .val = .{ .payload = payload_val.toIntern() },
9130 } });9236 } });
...@@ -9135,13 +9241,13 @@ fn analyzeErrUnionPayloadPtr(...@@ -9135,13 +9241,13 @@ fn analyzeErrUnionPayloadPtr(
9135 const eu_payload_ptr = try block.addTyOp(.errunion_payload_ptr_set, operand_pointer_ty, operand);9241 const eu_payload_ptr = try block.addTyOp(.errunion_payload_ptr_set, operand_pointer_ty, operand);
9136 try sema.checkKnownAllocPtr(block, operand, eu_payload_ptr);9242 try sema.checkKnownAllocPtr(block, operand, eu_payload_ptr);
9137 }9243 }
9138 return Air.internedToRef((try ptr_val.ptrEuPayload(zcu)).toIntern());9244 return Air.internedToRef((try ptr_val.ptrEuPayload(pt)).toIntern());
9139 }9245 }
9140 if (try sema.pointerDeref(block, src, ptr_val, operand_ty)) |val| {9246 if (try sema.pointerDeref(block, src, ptr_val, operand_ty)) |val| {
9141 if (val.getErrorName(zcu).unwrap()) |name| {9247 if (val.getErrorName(zcu).unwrap()) |name| {
9142 return sema.failWithComptimeErrorRetTrace(block, src, name);9248 return sema.failWithComptimeErrorRetTrace(block, src, name);
9143 }9249 }
9144 return Air.internedToRef((try ptr_val.ptrEuPayload(zcu)).toIntern());9250 return Air.internedToRef((try ptr_val.ptrEuPayload(pt)).toIntern());
9145 }9251 }
9146 }9252 }
91479253
...@@ -9175,18 +9281,19 @@ fn zirErrUnionCode(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErro...@@ -9175,18 +9281,19 @@ fn zirErrUnionCode(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErro
9175}9281}
91769282
9177fn analyzeErrUnionCode(sema: *Sema, block: *Block, src: LazySrcLoc, operand: Air.Inst.Ref) CompileError!Air.Inst.Ref {9283fn analyzeErrUnionCode(sema: *Sema, block: *Block, src: LazySrcLoc, operand: Air.Inst.Ref) CompileError!Air.Inst.Ref {
9178 const mod = sema.mod;9284 const pt = sema.pt;
9285 const mod = pt.zcu;
9179 const operand_ty = sema.typeOf(operand);9286 const operand_ty = sema.typeOf(operand);
9180 if (operand_ty.zigTypeTag(mod) != .ErrorUnion) {9287 if (operand_ty.zigTypeTag(mod) != .ErrorUnion) {
9181 return sema.fail(block, src, "expected error union type, found '{}'", .{9288 return sema.fail(block, src, "expected error union type, found '{}'", .{
9182 operand_ty.fmt(mod),9289 operand_ty.fmt(pt),
9183 });9290 });
9184 }9291 }
91859292
9186 const result_ty = operand_ty.errorUnionSet(mod);9293 const result_ty = operand_ty.errorUnionSet(mod);
91879294
9188 if (try sema.resolveDefinedValue(block, src, operand)) |val| {9295 if (try sema.resolveDefinedValue(block, src, operand)) |val| {
9189 return Air.internedToRef((try mod.intern(.{ .err = .{9296 return Air.internedToRef((try pt.intern(.{ .err = .{
9190 .ty = result_ty.toIntern(),9297 .ty = result_ty.toIntern(),
9191 .name = mod.intern_pool.indexToKey(val.toIntern()).error_union.val.err_name,9298 .name = mod.intern_pool.indexToKey(val.toIntern()).error_union.val.err_name,
9192 } })));9299 } })));
...@@ -9208,13 +9315,14 @@ fn zirErrUnionCodePtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileE...@@ -9208,13 +9315,14 @@ fn zirErrUnionCodePtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileE
9208}9315}
92099316
9210fn analyzeErrUnionCodePtr(sema: *Sema, block: *Block, src: LazySrcLoc, operand: Air.Inst.Ref) CompileError!Air.Inst.Ref {9317fn analyzeErrUnionCodePtr(sema: *Sema, block: *Block, src: LazySrcLoc, operand: Air.Inst.Ref) CompileError!Air.Inst.Ref {
9211 const mod = sema.mod;9318 const pt = sema.pt;
9319 const mod = pt.zcu;
9212 const operand_ty = sema.typeOf(operand);9320 const operand_ty = sema.typeOf(operand);
9213 assert(operand_ty.zigTypeTag(mod) == .Pointer);9321 assert(operand_ty.zigTypeTag(mod) == .Pointer);
92149322
9215 if (operand_ty.childType(mod).zigTypeTag(mod) != .ErrorUnion) {9323 if (operand_ty.childType(mod).zigTypeTag(mod) != .ErrorUnion) {
9216 return sema.fail(block, src, "expected error union type, found '{}'", .{9324 return sema.fail(block, src, "expected error union type, found '{}'", .{
9217 operand_ty.childType(mod).fmt(mod),9325 operand_ty.childType(mod).fmt(pt),
9218 });9326 });
9219 }9327 }
92209328
...@@ -9223,7 +9331,7 @@ fn analyzeErrUnionCodePtr(sema: *Sema, block: *Block, src: LazySrcLoc, operand:...@@ -9223,7 +9331,7 @@ fn analyzeErrUnionCodePtr(sema: *Sema, block: *Block, src: LazySrcLoc, operand:
9223 if (try sema.resolveDefinedValue(block, src, operand)) |pointer_val| {9331 if (try sema.resolveDefinedValue(block, src, operand)) |pointer_val| {
9224 if (try sema.pointerDeref(block, src, pointer_val, operand_ty)) |val| {9332 if (try sema.pointerDeref(block, src, pointer_val, operand_ty)) |val| {
9225 assert(val.getErrorName(mod) != .none);9333 assert(val.getErrorName(mod) != .none);
9226 return Air.internedToRef((try mod.intern(.{ .err = .{9334 return Air.internedToRef((try pt.intern(.{ .err = .{
9227 .ty = result_ty.toIntern(),9335 .ty = result_ty.toIntern(),
9228 .name = mod.intern_pool.indexToKey(val.toIntern()).error_union.val.err_name,9336 .name = mod.intern_pool.indexToKey(val.toIntern()).error_union.val.err_name,
9229 } })));9337 } })));
...@@ -9240,10 +9348,11 @@ fn zirFunc(...@@ -9240,10 +9348,11 @@ fn zirFunc(
9240 inst: Zir.Inst.Index,9348 inst: Zir.Inst.Index,
9241 inferred_error_set: bool,9349 inferred_error_set: bool,
9242) CompileError!Air.Inst.Ref {9350) CompileError!Air.Inst.Ref {
9243 const mod = sema.mod;9351 const pt = sema.pt;
9352 const mod = pt.zcu;
9244 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;9353 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
9245 const extra = sema.code.extraData(Zir.Inst.Func, inst_data.payload_index);9354 const extra = sema.code.extraData(Zir.Inst.Func, inst_data.payload_index);
9246 const target = sema.mod.getTarget();9355 const target = mod.getTarget();
9247 const ret_ty_src = block.src(.{ .node_offset_fn_type_ret_ty = inst_data.src_node });9356 const ret_ty_src = block.src(.{ .node_offset_fn_type_ret_ty = inst_data.src_node });
92489357
9249 var extra_index = extra.end;9358 var extra_index = extra.end;
...@@ -9372,7 +9481,8 @@ fn handleExternLibName(...@@ -9372,7 +9481,8 @@ fn handleExternLibName(
9372 lib_name: []const u8,9481 lib_name: []const u8,
9373) CompileError!void {9482) CompileError!void {
9374 blk: {9483 blk: {
9375 const mod = sema.mod;9484 const pt = sema.pt;
9485 const mod = pt.zcu;
9376 const comp = mod.comp;9486 const comp = mod.comp;
9377 const target = mod.getTarget();9487 const target = mod.getTarget();
9378 log.debug("extern fn symbol expected in lib '{s}'", .{lib_name});9488 log.debug("extern fn symbol expected in lib '{s}'", .{lib_name});
...@@ -9485,7 +9595,8 @@ fn funcCommon(...@@ -9485,7 +9595,8 @@ fn funcCommon(
9485 noalias_bits: u32,9595 noalias_bits: u32,
9486 is_noinline: bool,9596 is_noinline: bool,
9487) CompileError!Air.Inst.Ref {9597) CompileError!Air.Inst.Ref {
9488 const mod = sema.mod;9598 const pt = sema.pt;
9599 const mod = pt.zcu;
9489 const gpa = sema.gpa;9600 const gpa = sema.gpa;
9490 const target = mod.getTarget();9601 const target = mod.getTarget();
9491 const ip = &mod.intern_pool;9602 const ip = &mod.intern_pool;
...@@ -9539,13 +9650,13 @@ fn funcCommon(...@@ -9539,13 +9650,13 @@ fn funcCommon(
9539 if (!param_ty.isValidParamType(mod)) {9650 if (!param_ty.isValidParamType(mod)) {
9540 const opaque_str = if (param_ty.zigTypeTag(mod) == .Opaque) "opaque " else "";9651 const opaque_str = if (param_ty.zigTypeTag(mod) == .Opaque) "opaque " else "";
9541 return sema.fail(block, param_src, "parameter of {s}type '{}' not allowed", .{9652 return sema.fail(block, param_src, "parameter of {s}type '{}' not allowed", .{
9542 opaque_str, param_ty.fmt(mod),9653 opaque_str, param_ty.fmt(pt),
9543 });9654 });
9544 }9655 }
9545 if (!this_generic and !target_util.fnCallConvAllowsZigTypes(target, cc_resolved) and !try sema.validateExternType(param_ty, .param_ty)) {9656 if (!this_generic and !target_util.fnCallConvAllowsZigTypes(target, cc_resolved) and !try sema.validateExternType(param_ty, .param_ty)) {
9546 const msg = msg: {9657 const msg = msg: {
9547 const msg = try sema.errMsg(param_src, "parameter of type '{}' not allowed in function with calling convention '{s}'", .{9658 const msg = try sema.errMsg(param_src, "parameter of type '{}' not allowed in function with calling convention '{s}'", .{
9548 param_ty.fmt(mod), @tagName(cc_resolved),9659 param_ty.fmt(pt), @tagName(cc_resolved),
9549 });9660 });
9550 errdefer msg.destroy(sema.gpa);9661 errdefer msg.destroy(sema.gpa);
95519662
...@@ -9559,7 +9670,7 @@ fn funcCommon(...@@ -9559,7 +9670,7 @@ fn funcCommon(
9559 if (is_source_decl and requires_comptime and !param_is_comptime and has_body and !block.is_comptime) {9670 if (is_source_decl and requires_comptime and !param_is_comptime and has_body and !block.is_comptime) {
9560 const msg = msg: {9671 const msg = msg: {
9561 const msg = try sema.errMsg(param_src, "parameter of type '{}' must be declared comptime", .{9672 const msg = try sema.errMsg(param_src, "parameter of type '{}' must be declared comptime", .{
9562 param_ty.fmt(mod),9673 param_ty.fmt(pt),
9563 });9674 });
9564 errdefer msg.destroy(sema.gpa);9675 errdefer msg.destroy(sema.gpa);
95659676
...@@ -9580,7 +9691,7 @@ fn funcCommon(...@@ -9580,7 +9691,7 @@ fn funcCommon(
9580 const err_code_size = target.ptrBitWidth();9691 const err_code_size = target.ptrBitWidth();
9581 switch (i) {9692 switch (i) {
9582 0 => if (param_ty.zigTypeTag(mod) != .Pointer) return sema.fail(block, param_src, "first parameter of function with 'Interrupt' calling convention must be a pointer type", .{}),9693 0 => if (param_ty.zigTypeTag(mod) != .Pointer) return sema.fail(block, param_src, "first parameter of function with 'Interrupt' calling convention must be a pointer type", .{}),
9583 1 => if (param_ty.bitSize(mod) != err_code_size) return sema.fail(block, param_src, "second parameter of function with 'Interrupt' calling convention must be a {d}-bit integer", .{err_code_size}),9694 1 => if (param_ty.bitSize(pt) != err_code_size) return sema.fail(block, param_src, "second parameter of function with 'Interrupt' calling convention must be a {d}-bit integer", .{err_code_size}),
9584 else => return sema.fail(block, param_src, "'Interrupt' calling convention supports up to 2 parameters, found {d}", .{i + 1}),9695 else => return sema.fail(block, param_src, "'Interrupt' calling convention supports up to 2 parameters, found {d}", .{i + 1}),
9585 }9696 }
9586 } else return sema.fail(block, param_src, "parameters are not allowed with 'Interrupt' calling convention", .{}),9697 } else return sema.fail(block, param_src, "parameters are not allowed with 'Interrupt' calling convention", .{}),
...@@ -9606,7 +9717,7 @@ fn funcCommon(...@@ -9606,7 +9717,7 @@ fn funcCommon(
9606 if (inferred_error_set) {9717 if (inferred_error_set) {
9607 try sema.validateErrorUnionPayloadType(block, bare_return_type, ret_ty_src);9718 try sema.validateErrorUnionPayloadType(block, bare_return_type, ret_ty_src);
9608 }9719 }
9609 const func_index = try ip.getFuncInstance(gpa, .{9720 const func_index = try ip.getFuncInstance(gpa, pt.tid, .{
9610 .param_types = param_types,9721 .param_types = param_types,
9611 .noalias_bits = noalias_bits,9722 .noalias_bits = noalias_bits,
9612 .bare_return_type = bare_return_type.toIntern(),9723 .bare_return_type = bare_return_type.toIntern(),
...@@ -9655,7 +9766,7 @@ fn funcCommon(...@@ -9655,7 +9766,7 @@ fn funcCommon(
9655 assert(has_body);9766 assert(has_body);
9656 if (!ret_poison)9767 if (!ret_poison)
9657 try sema.validateErrorUnionPayloadType(block, bare_return_type, ret_ty_src);9768 try sema.validateErrorUnionPayloadType(block, bare_return_type, ret_ty_src);
9658 const func_index = try ip.getFuncDeclIes(gpa, .{9769 const func_index = try ip.getFuncDeclIes(gpa, pt.tid, .{
9659 .owner_decl = sema.owner_decl_index,9770 .owner_decl = sema.owner_decl_index,
96609771
9661 .param_types = param_types,9772 .param_types = param_types,
...@@ -9695,7 +9806,7 @@ fn funcCommon(...@@ -9695,7 +9806,7 @@ fn funcCommon(
9695 );9806 );
9696 }9807 }
96979808
9698 const func_ty = try ip.getFuncType(gpa, .{9809 const func_ty = try ip.getFuncType(gpa, pt.tid, .{
9699 .param_types = param_types,9810 .param_types = param_types,
9700 .noalias_bits = noalias_bits,9811 .noalias_bits = noalias_bits,
9701 .comptime_bits = comptime_bits,9812 .comptime_bits = comptime_bits,
...@@ -9718,10 +9829,10 @@ fn funcCommon(...@@ -9718,10 +9829,10 @@ fn funcCommon(
9718 if (opt_lib_name) |lib_name| try sema.handleExternLibName(block, block.src(.{9829 if (opt_lib_name) |lib_name| try sema.handleExternLibName(block, block.src(.{
9719 .node_offset_lib_name = src_node_offset,9830 .node_offset_lib_name = src_node_offset,
9720 }), lib_name);9831 }), lib_name);
9721 const func_index = try ip.getExternFunc(gpa, .{9832 const func_index = try ip.getExternFunc(gpa, pt.tid, .{
9722 .ty = func_ty,9833 .ty = func_ty,
9723 .decl = sema.owner_decl_index,9834 .decl = sema.owner_decl_index,
9724 .lib_name = try mod.intern_pool.getOrPutStringOpt(gpa, opt_lib_name, .no_embedded_nulls),9835 .lib_name = try mod.intern_pool.getOrPutStringOpt(gpa, pt.tid, opt_lib_name, .no_embedded_nulls),
9725 });9836 });
9726 return finishFunc(9837 return finishFunc(
9727 sema,9838 sema,
...@@ -9743,7 +9854,7 @@ fn funcCommon(...@@ -9743,7 +9854,7 @@ fn funcCommon(
9743 }9854 }
97449855
9745 if (has_body) {9856 if (has_body) {
9746 const func_index = try ip.getFuncDecl(gpa, .{9857 const func_index = try ip.getFuncDecl(gpa, pt.tid, .{
9747 .owner_decl = sema.owner_decl_index,9858 .owner_decl = sema.owner_decl_index,
9748 .ty = func_ty,9859 .ty = func_ty,
9749 .cc = cc,9860 .cc = cc,
...@@ -9809,7 +9920,8 @@ fn finishFunc(...@@ -9809,7 +9920,8 @@ fn finishFunc(
9809 is_generic: bool,9920 is_generic: bool,
9810 final_is_generic: bool,9921 final_is_generic: bool,
9811) CompileError!Air.Inst.Ref {9922) CompileError!Air.Inst.Ref {
9812 const mod = sema.mod;9923 const pt = sema.pt;
9924 const mod = pt.zcu;
9813 const ip = &mod.intern_pool;9925 const ip = &mod.intern_pool;
9814 const gpa = sema.gpa;9926 const gpa = sema.gpa;
9815 const target = mod.getTarget();9927 const target = mod.getTarget();
...@@ -9822,7 +9934,7 @@ fn finishFunc(...@@ -9822,7 +9934,7 @@ fn finishFunc(
9822 if (!return_type.isValidReturnType(mod)) {9934 if (!return_type.isValidReturnType(mod)) {
9823 const opaque_str = if (return_type.zigTypeTag(mod) == .Opaque) "opaque " else "";9935 const opaque_str = if (return_type.zigTypeTag(mod) == .Opaque) "opaque " else "";
9824 return sema.fail(block, ret_ty_src, "{s}return type '{}' not allowed", .{9936 return sema.fail(block, ret_ty_src, "{s}return type '{}' not allowed", .{
9825 opaque_str, return_type.fmt(mod),9937 opaque_str, return_type.fmt(pt),
9826 });9938 });
9827 }9939 }
9828 if (!ret_poison and !target_util.fnCallConvAllowsZigTypes(target, cc_resolved) and9940 if (!ret_poison and !target_util.fnCallConvAllowsZigTypes(target, cc_resolved) and
...@@ -9830,7 +9942,7 @@ fn finishFunc(...@@ -9830,7 +9942,7 @@ fn finishFunc(
9830 {9942 {
9831 const msg = msg: {9943 const msg = msg: {
9832 const msg = try sema.errMsg(ret_ty_src, "return type '{}' not allowed in function with calling convention '{s}'", .{9944 const msg = try sema.errMsg(ret_ty_src, "return type '{}' not allowed in function with calling convention '{s}'", .{
9833 return_type.fmt(mod), @tagName(cc_resolved),9945 return_type.fmt(pt), @tagName(cc_resolved),
9834 });9946 });
9835 errdefer msg.destroy(gpa);9947 errdefer msg.destroy(gpa);
98369948
...@@ -9852,7 +9964,7 @@ fn finishFunc(...@@ -9852,7 +9964,7 @@ fn finishFunc(
9852 const msg = try sema.errMsg(9964 const msg = try sema.errMsg(
9853 ret_ty_src,9965 ret_ty_src,
9854 "function with comptime-only return type '{}' requires all parameters to be comptime",9966 "function with comptime-only return type '{}' requires all parameters to be comptime",
9855 .{return_type.fmt(mod)},9967 .{return_type.fmt(pt)},
9856 );9968 );
9857 try sema.explainWhyTypeIsComptime(msg, ret_ty_src, return_type);9969 try sema.explainWhyTypeIsComptime(msg, ret_ty_src, return_type);
98589970
...@@ -9938,8 +10050,8 @@ fn finishFunc(...@@ -9938,8 +10050,8 @@ fn finishFunc(
9938 if (!final_is_generic and sema.wantErrorReturnTracing(return_type)) {10050 if (!final_is_generic and sema.wantErrorReturnTracing(return_type)) {
9939 // Make sure that StackTrace's fields are resolved so that the backend can10051 // Make sure that StackTrace's fields are resolved so that the backend can
9940 // lower this fn type.10052 // lower this fn type.
9941 const unresolved_stack_trace_ty = try mod.getBuiltinType("StackTrace");10053 const unresolved_stack_trace_ty = try pt.getBuiltinType("StackTrace");
9942 try unresolved_stack_trace_ty.resolveFields(mod);10054 try unresolved_stack_trace_ty.resolveFields(pt);
9943 }10055 }
994410056
9945 return Air.internedToRef(if (opt_func_index != .none) opt_func_index else func_ty);10057 return Air.internedToRef(if (opt_func_index != .none) opt_func_index else func_ty);
...@@ -10068,7 +10180,8 @@ fn analyzeAs(...@@ -10068,7 +10180,8 @@ fn analyzeAs(
10068 zir_operand: Zir.Inst.Ref,10180 zir_operand: Zir.Inst.Ref,
10069 no_cast_to_comptime_int: bool,10181 no_cast_to_comptime_int: bool,
10070) CompileError!Air.Inst.Ref {10182) CompileError!Air.Inst.Ref {
10071 const mod = sema.mod;10183 const pt = sema.pt;
10184 const mod = pt.zcu;
10072 const operand = try sema.resolveInst(zir_operand);10185 const operand = try sema.resolveInst(zir_operand);
10073 const operand_air_inst = sema.resolveInst(zir_dest_type) catch |err| switch (err) {10186 const operand_air_inst = sema.resolveInst(zir_dest_type) catch |err| switch (err) {
10074 error.GenericPoison => return operand,10187 error.GenericPoison => return operand,
...@@ -10098,7 +10211,8 @@ fn zirIntFromPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!...@@ -10098,7 +10211,8 @@ fn zirIntFromPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!
10098 const tracy = trace(@src());10211 const tracy = trace(@src());
10099 defer tracy.end();10212 defer tracy.end();
1010010213
10101 const zcu = sema.mod;10214 const pt = sema.pt;
10215 const zcu = pt.zcu;
10102 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;10216 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;
10103 const ptr_src = block.builtinCallArgSrc(inst_data.src_node, 0);10217 const ptr_src = block.builtinCallArgSrc(inst_data.src_node, 0);
10104 const operand = try sema.resolveInst(inst_data.operand);10218 const operand = try sema.resolveInst(inst_data.operand);
...@@ -10106,12 +10220,12 @@ fn zirIntFromPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!...@@ -10106,12 +10220,12 @@ fn zirIntFromPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!
10106 const ptr_ty = operand_ty.scalarType(zcu);10220 const ptr_ty = operand_ty.scalarType(zcu);
10107 const is_vector = operand_ty.zigTypeTag(zcu) == .Vector;10221 const is_vector = operand_ty.zigTypeTag(zcu) == .Vector;
10108 if (!ptr_ty.isPtrAtRuntime(zcu)) {10222 if (!ptr_ty.isPtrAtRuntime(zcu)) {
10109 return sema.fail(block, ptr_src, "expected pointer, found '{}'", .{ptr_ty.fmt(zcu)});10223 return sema.fail(block, ptr_src, "expected pointer, found '{}'", .{ptr_ty.fmt(pt)});
10110 }10224 }
10111 const pointee_ty = ptr_ty.childType(zcu);10225 const pointee_ty = ptr_ty.childType(zcu);
10112 if (try sema.typeRequiresComptime(ptr_ty)) {10226 if (try sema.typeRequiresComptime(ptr_ty)) {
10113 const msg = msg: {10227 const msg = msg: {
10114 const msg = try sema.errMsg(ptr_src, "comptime-only type '{}' has no pointer address", .{pointee_ty.fmt(zcu)});10228 const msg = try sema.errMsg(ptr_src, "comptime-only type '{}' has no pointer address", .{pointee_ty.fmt(pt)});
10115 errdefer msg.destroy(sema.gpa);10229 errdefer msg.destroy(sema.gpa);
10116 try sema.explainWhyTypeIsComptime(msg, ptr_src, pointee_ty);10230 try sema.explainWhyTypeIsComptime(msg, ptr_src, pointee_ty);
10117 break :msg msg;10231 break :msg msg;
...@@ -10121,32 +10235,32 @@ fn zirIntFromPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!...@@ -10121,32 +10235,32 @@ fn zirIntFromPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!
10121 if (try sema.resolveValueIntable(operand)) |operand_val| ct: {10235 if (try sema.resolveValueIntable(operand)) |operand_val| ct: {
10122 if (!is_vector) {10236 if (!is_vector) {
10123 if (operand_val.isUndef(zcu)) {10237 if (operand_val.isUndef(zcu)) {
10124 return Air.internedToRef((try zcu.undefValue(Type.usize)).toIntern());10238 return Air.internedToRef((try pt.undefValue(Type.usize)).toIntern());
10125 }10239 }
10126 return Air.internedToRef((try zcu.intValue(10240 return Air.internedToRef((try pt.intValue(
10127 Type.usize,10241 Type.usize,
10128 (try operand_val.getUnsignedIntAdvanced(zcu, .sema)).?,10242 (try operand_val.getUnsignedIntAdvanced(pt, .sema)).?,
10129 )).toIntern());10243 )).toIntern());
10130 }10244 }
10131 const len = operand_ty.vectorLen(zcu);10245 const len = operand_ty.vectorLen(zcu);
10132 const dest_ty = try zcu.vectorType(.{ .child = .usize_type, .len = len });10246 const dest_ty = try pt.vectorType(.{ .child = .usize_type, .len = len });
10133 const new_elems = try sema.arena.alloc(InternPool.Index, len);10247 const new_elems = try sema.arena.alloc(InternPool.Index, len);
10134 for (new_elems, 0..) |*new_elem, i| {10248 for (new_elems, 0..) |*new_elem, i| {
10135 const ptr_val = try operand_val.elemValue(zcu, i);10249 const ptr_val = try operand_val.elemValue(pt, i);
10136 if (ptr_val.isUndef(zcu)) {10250 if (ptr_val.isUndef(zcu)) {
10137 new_elem.* = (try zcu.undefValue(Type.usize)).toIntern();10251 new_elem.* = (try pt.undefValue(Type.usize)).toIntern();
10138 continue;10252 continue;
10139 }10253 }
10140 const addr = try ptr_val.getUnsignedIntAdvanced(zcu, .sema) orelse {10254 const addr = try ptr_val.getUnsignedIntAdvanced(pt, .sema) orelse {
10141 // A vector element wasn't an integer pointer. This is a runtime operation.10255 // A vector element wasn't an integer pointer. This is a runtime operation.
10142 break :ct;10256 break :ct;
10143 };10257 };
10144 new_elem.* = (try zcu.intValue(10258 new_elem.* = (try pt.intValue(
10145 Type.usize,10259 Type.usize,
10146 addr,10260 addr,
10147 )).toIntern();10261 )).toIntern();
10148 }10262 }
10149 return Air.internedToRef(try zcu.intern(.{ .aggregate = .{10263 return Air.internedToRef(try pt.intern(.{ .aggregate = .{
10150 .ty = dest_ty.toIntern(),10264 .ty = dest_ty.toIntern(),
10151 .storage = .{ .elems = new_elems },10265 .storage = .{ .elems = new_elems },
10152 } }));10266 } }));
...@@ -10157,10 +10271,10 @@ fn zirIntFromPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!...@@ -10157,10 +10271,10 @@ fn zirIntFromPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!
10157 return block.addUnOp(.int_from_ptr, operand);10271 return block.addUnOp(.int_from_ptr, operand);
10158 }10272 }
10159 const len = operand_ty.vectorLen(zcu);10273 const len = operand_ty.vectorLen(zcu);
10160 const dest_ty = try zcu.vectorType(.{ .child = .usize_type, .len = len });10274 const dest_ty = try pt.vectorType(.{ .child = .usize_type, .len = len });
10161 const new_elems = try sema.arena.alloc(Air.Inst.Ref, len);10275 const new_elems = try sema.arena.alloc(Air.Inst.Ref, len);
10162 for (new_elems, 0..) |*new_elem, i| {10276 for (new_elems, 0..) |*new_elem, i| {
10163 const idx_ref = try zcu.intRef(Type.usize, i);10277 const idx_ref = try pt.intRef(Type.usize, i);
10164 const old_elem = try block.addBinOp(.array_elem_val, operand, idx_ref);10278 const old_elem = try block.addBinOp(.array_elem_val, operand, idx_ref);
10165 new_elem.* = try block.addUnOp(.int_from_ptr, old_elem);10279 new_elem.* = try block.addUnOp(.int_from_ptr, old_elem);
10166 }10280 }
...@@ -10171,13 +10285,15 @@ fn zirFieldVal(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -10171,13 +10285,15 @@ fn zirFieldVal(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
10171 const tracy = trace(@src());10285 const tracy = trace(@src());
10172 defer tracy.end();10286 defer tracy.end();
1017310287
10174 const mod = sema.mod;10288 const pt = sema.pt;
10289 const mod = pt.zcu;
10175 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;10290 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
10176 const src = block.nodeOffset(inst_data.src_node);10291 const src = block.nodeOffset(inst_data.src_node);
10177 const field_name_src = block.src(.{ .node_offset_field_name = inst_data.src_node });10292 const field_name_src = block.src(.{ .node_offset_field_name = inst_data.src_node });
10178 const extra = sema.code.extraData(Zir.Inst.Field, inst_data.payload_index).data;10293 const extra = sema.code.extraData(Zir.Inst.Field, inst_data.payload_index).data;
10179 const field_name = try mod.intern_pool.getOrPutString(10294 const field_name = try mod.intern_pool.getOrPutString(
10180 sema.gpa,10295 sema.gpa,
10296 pt.tid,
10181 sema.code.nullTerminatedString(extra.field_name_start),10297 sema.code.nullTerminatedString(extra.field_name_start),
10182 .no_embedded_nulls,10298 .no_embedded_nulls,
10183 );10299 );
...@@ -10189,13 +10305,15 @@ fn zirFieldPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -10189,13 +10305,15 @@ fn zirFieldPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
10189 const tracy = trace(@src());10305 const tracy = trace(@src());
10190 defer tracy.end();10306 defer tracy.end();
1019110307
10192 const mod = sema.mod;10308 const pt = sema.pt;
10309 const mod = pt.zcu;
10193 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;10310 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
10194 const src = block.nodeOffset(inst_data.src_node);10311 const src = block.nodeOffset(inst_data.src_node);
10195 const field_name_src = block.src(.{ .node_offset_field_name = inst_data.src_node });10312 const field_name_src = block.src(.{ .node_offset_field_name = inst_data.src_node });
10196 const extra = sema.code.extraData(Zir.Inst.Field, inst_data.payload_index).data;10313 const extra = sema.code.extraData(Zir.Inst.Field, inst_data.payload_index).data;
10197 const field_name = try mod.intern_pool.getOrPutString(10314 const field_name = try mod.intern_pool.getOrPutString(
10198 sema.gpa,10315 sema.gpa,
10316 pt.tid,
10199 sema.code.nullTerminatedString(extra.field_name_start),10317 sema.code.nullTerminatedString(extra.field_name_start),
10200 .no_embedded_nulls,10318 .no_embedded_nulls,
10201 );10319 );
...@@ -10207,13 +10325,15 @@ fn zirStructInitFieldPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Compi...@@ -10207,13 +10325,15 @@ fn zirStructInitFieldPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Compi
10207 const tracy = trace(@src());10325 const tracy = trace(@src());
10208 defer tracy.end();10326 defer tracy.end();
1020910327
10210 const mod = sema.mod;10328 const pt = sema.pt;
10329 const mod = pt.zcu;
10211 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;10330 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
10212 const src = block.nodeOffset(inst_data.src_node);10331 const src = block.nodeOffset(inst_data.src_node);
10213 const field_name_src = block.src(.{ .node_offset_field_name_init = inst_data.src_node });10332 const field_name_src = block.src(.{ .node_offset_field_name_init = inst_data.src_node });
10214 const extra = sema.code.extraData(Zir.Inst.Field, inst_data.payload_index).data;10333 const extra = sema.code.extraData(Zir.Inst.Field, inst_data.payload_index).data;
10215 const field_name = try mod.intern_pool.getOrPutString(10334 const field_name = try mod.intern_pool.getOrPutString(
10216 sema.gpa,10335 sema.gpa,
10336 pt.tid,
10217 sema.code.nullTerminatedString(extra.field_name_start),10337 sema.code.nullTerminatedString(extra.field_name_start),
10218 .no_embedded_nulls,10338 .no_embedded_nulls,
10219 );10339 );
...@@ -10284,7 +10404,8 @@ fn intCast(...@@ -10284,7 +10404,8 @@ fn intCast(
10284 operand_src: LazySrcLoc,10404 operand_src: LazySrcLoc,
10285 runtime_safety: bool,10405 runtime_safety: bool,
10286) CompileError!Air.Inst.Ref {10406) CompileError!Air.Inst.Ref {
10287 const mod = sema.mod;10407 const pt = sema.pt;
10408 const mod = pt.zcu;
10288 const operand_ty = sema.typeOf(operand);10409 const operand_ty = sema.typeOf(operand);
10289 const dest_scalar_ty = try sema.checkIntOrVectorAllowComptime(block, dest_ty, dest_ty_src);10410 const dest_scalar_ty = try sema.checkIntOrVectorAllowComptime(block, dest_ty, dest_ty_src);
10290 const operand_scalar_ty = try sema.checkIntOrVectorAllowComptime(block, operand_ty, operand_src);10411 const operand_scalar_ty = try sema.checkIntOrVectorAllowComptime(block, operand_ty, operand_src);
...@@ -10307,7 +10428,7 @@ fn intCast(...@@ -10307,7 +10428,7 @@ fn intCast(
1030710428
10308 if (wanted_bits == 0) {10429 if (wanted_bits == 0) {
10309 const ok = if (is_vector) ok: {10430 const ok = if (is_vector) ok: {
10310 const zeros = try sema.splat(operand_ty, try mod.intValue(operand_scalar_ty, 0));10431 const zeros = try sema.splat(operand_ty, try pt.intValue(operand_scalar_ty, 0));
10311 const zero_inst = Air.internedToRef(zeros.toIntern());10432 const zero_inst = Air.internedToRef(zeros.toIntern());
10312 const is_in_range = try block.addCmpVector(operand, zero_inst, .eq);10433 const is_in_range = try block.addCmpVector(operand, zero_inst, .eq);
10313 const all_in_range = try block.addInst(.{10434 const all_in_range = try block.addInst(.{
...@@ -10316,7 +10437,7 @@ fn intCast(...@@ -10316,7 +10437,7 @@ fn intCast(
10316 });10437 });
10317 break :ok all_in_range;10438 break :ok all_in_range;
10318 } else ok: {10439 } else ok: {
10319 const zero_inst = Air.internedToRef((try mod.intValue(operand_ty, 0)).toIntern());10440 const zero_inst = Air.internedToRef((try pt.intValue(operand_ty, 0)).toIntern());
10320 const is_in_range = try block.addBinOp(.cmp_lte, operand, zero_inst);10441 const is_in_range = try block.addBinOp(.cmp_lte, operand, zero_inst);
10321 break :ok is_in_range;10442 break :ok is_in_range;
10322 };10443 };
...@@ -10339,7 +10460,7 @@ fn intCast(...@@ -10339,7 +10460,7 @@ fn intCast(
10339 // range shrinkage10460 // range shrinkage
10340 // requirement: int value fits into target type10461 // requirement: int value fits into target type
10341 if (wanted_value_bits < actual_value_bits) {10462 if (wanted_value_bits < actual_value_bits) {
10342 const dest_max_val_scalar = try dest_scalar_ty.maxIntScalar(mod, operand_scalar_ty);10463 const dest_max_val_scalar = try dest_scalar_ty.maxIntScalar(pt, operand_scalar_ty);
10343 const dest_max_val = try sema.splat(operand_ty, dest_max_val_scalar);10464 const dest_max_val = try sema.splat(operand_ty, dest_max_val_scalar);
10344 const dest_max = Air.internedToRef(dest_max_val.toIntern());10465 const dest_max = Air.internedToRef(dest_max_val.toIntern());
1034510466
...@@ -10348,8 +10469,8 @@ fn intCast(...@@ -10348,8 +10469,8 @@ fn intCast(
1034810469
10349 // Reinterpret the sign-bit as part of the value. This will make10470 // Reinterpret the sign-bit as part of the value. This will make
10350 // negative differences (`operand` > `dest_max`) appear too big.10471 // negative differences (`operand` > `dest_max`) appear too big.
10351 const unsigned_scalar_operand_ty = try mod.intType(.unsigned, actual_bits);10472 const unsigned_scalar_operand_ty = try pt.intType(.unsigned, actual_bits);
10352 const unsigned_operand_ty = if (is_vector) try mod.vectorType(.{10473 const unsigned_operand_ty = if (is_vector) try pt.vectorType(.{
10353 .len = dest_ty.vectorLen(mod),10474 .len = dest_ty.vectorLen(mod),
10354 .child = unsigned_scalar_operand_ty.toIntern(),10475 .child = unsigned_scalar_operand_ty.toIntern(),
10355 }) else unsigned_scalar_operand_ty;10476 }) else unsigned_scalar_operand_ty;
...@@ -10358,14 +10479,14 @@ fn intCast(...@@ -10358,14 +10479,14 @@ fn intCast(
10358 // If the destination type is signed, then we need to double its10479 // If the destination type is signed, then we need to double its
10359 // range to account for negative values.10480 // range to account for negative values.
10360 const dest_range_val = if (wanted_info.signedness == .signed) range_val: {10481 const dest_range_val = if (wanted_info.signedness == .signed) range_val: {
10361 const one_scalar = try mod.intValue(unsigned_scalar_operand_ty, 1);10482 const one_scalar = try pt.intValue(unsigned_scalar_operand_ty, 1);
10362 const one = if (is_vector) Value.fromInterned((try mod.intern(.{ .aggregate = .{10483 const one = if (is_vector) Value.fromInterned(try pt.intern(.{ .aggregate = .{
10363 .ty = unsigned_operand_ty.toIntern(),10484 .ty = unsigned_operand_ty.toIntern(),
10364 .storage = .{ .repeated_elem = one_scalar.toIntern() },10485 .storage = .{ .repeated_elem = one_scalar.toIntern() },
10365 } }))) else one_scalar;10486 } })) else one_scalar;
10366 const range_minus_one = try dest_max_val.shl(one, unsigned_operand_ty, sema.arena, mod);10487 const range_minus_one = try dest_max_val.shl(one, unsigned_operand_ty, sema.arena, pt);
10367 break :range_val try sema.intAdd(range_minus_one, one, unsigned_operand_ty, undefined);10488 break :range_val try sema.intAdd(range_minus_one, one, unsigned_operand_ty, undefined);
10368 } else try mod.getCoerced(dest_max_val, unsigned_operand_ty);10489 } else try pt.getCoerced(dest_max_val, unsigned_operand_ty);
10369 const dest_range = Air.internedToRef(dest_range_val.toIntern());10490 const dest_range = Air.internedToRef(dest_range_val.toIntern());
1037010491
10371 const ok = if (is_vector) ok: {10492 const ok = if (is_vector) ok: {
...@@ -10405,7 +10526,7 @@ fn intCast(...@@ -10405,7 +10526,7 @@ fn intCast(
10405 // no shrinkage, yes sign loss10526 // no shrinkage, yes sign loss
10406 // requirement: signed to unsigned >= 010527 // requirement: signed to unsigned >= 0
10407 const ok = if (is_vector) ok: {10528 const ok = if (is_vector) ok: {
10408 const scalar_zero = try mod.intValue(operand_scalar_ty, 0);10529 const scalar_zero = try pt.intValue(operand_scalar_ty, 0);
10409 const zero_val = try sema.splat(operand_ty, scalar_zero);10530 const zero_val = try sema.splat(operand_ty, scalar_zero);
10410 const zero_inst = Air.internedToRef(zero_val.toIntern());10531 const zero_inst = Air.internedToRef(zero_val.toIntern());
10411 const is_in_range = try block.addCmpVector(operand, zero_inst, .gte);10532 const is_in_range = try block.addCmpVector(operand, zero_inst, .gte);
...@@ -10418,7 +10539,7 @@ fn intCast(...@@ -10418,7 +10539,7 @@ fn intCast(
10418 });10539 });
10419 break :ok all_in_range;10540 break :ok all_in_range;
10420 } else ok: {10541 } else ok: {
10421 const zero_inst = Air.internedToRef((try mod.intValue(operand_ty, 0)).toIntern());10542 const zero_inst = Air.internedToRef((try pt.intValue(operand_ty, 0)).toIntern());
10422 const is_in_range = try block.addBinOp(.cmp_gte, operand, zero_inst);10543 const is_in_range = try block.addBinOp(.cmp_gte, operand, zero_inst);
10423 break :ok is_in_range;10544 break :ok is_in_range;
10424 };10545 };
...@@ -10432,7 +10553,8 @@ fn zirBitcast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air...@@ -10432,7 +10553,8 @@ fn zirBitcast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
10432 const tracy = trace(@src());10553 const tracy = trace(@src());
10433 defer tracy.end();10554 defer tracy.end();
1043410555
10435 const mod = sema.mod;10556 const pt = sema.pt;
10557 const mod = pt.zcu;
10436 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;10558 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
10437 const src = block.nodeOffset(inst_data.src_node);10559 const src = block.nodeOffset(inst_data.src_node);
10438 const operand_src = block.builtinCallArgSrc(inst_data.src_node, 0);10560 const operand_src = block.builtinCallArgSrc(inst_data.src_node, 0);
...@@ -10457,14 +10579,14 @@ fn zirBitcast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air...@@ -10457,14 +10579,14 @@ fn zirBitcast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
10457 .Type,10579 .Type,
10458 .Undefined,10580 .Undefined,
10459 .Void,10581 .Void,
10460 => return sema.fail(block, src, "cannot @bitCast to '{}'", .{dest_ty.fmt(mod)}),10582 => return sema.fail(block, src, "cannot @bitCast to '{}'", .{dest_ty.fmt(pt)}),
1046110583
10462 .Enum => {10584 .Enum => {
10463 const msg = msg: {10585 const msg = msg: {
10464 const msg = try sema.errMsg(src, "cannot @bitCast to '{}'", .{dest_ty.fmt(mod)});10586 const msg = try sema.errMsg(src, "cannot @bitCast to '{}'", .{dest_ty.fmt(pt)});
10465 errdefer msg.destroy(sema.gpa);10587 errdefer msg.destroy(sema.gpa);
10466 switch (operand_ty.zigTypeTag(mod)) {10588 switch (operand_ty.zigTypeTag(mod)) {
10467 .Int, .ComptimeInt => try sema.errNote(src, msg, "use @enumFromInt to cast from '{}'", .{operand_ty.fmt(mod)}),10589 .Int, .ComptimeInt => try sema.errNote(src, msg, "use @enumFromInt to cast from '{}'", .{operand_ty.fmt(pt)}),
10468 else => {},10590 else => {},
10469 }10591 }
1047010592
...@@ -10475,11 +10597,11 @@ fn zirBitcast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air...@@ -10475,11 +10597,11 @@ fn zirBitcast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
1047510597
10476 .Pointer => {10598 .Pointer => {
10477 const msg = msg: {10599 const msg = msg: {
10478 const msg = try sema.errMsg(src, "cannot @bitCast to '{}'", .{dest_ty.fmt(mod)});10600 const msg = try sema.errMsg(src, "cannot @bitCast to '{}'", .{dest_ty.fmt(pt)});
10479 errdefer msg.destroy(sema.gpa);10601 errdefer msg.destroy(sema.gpa);
10480 switch (operand_ty.zigTypeTag(mod)) {10602 switch (operand_ty.zigTypeTag(mod)) {
10481 .Int, .ComptimeInt => try sema.errNote(src, msg, "use @ptrFromInt to cast from '{}'", .{operand_ty.fmt(mod)}),10603 .Int, .ComptimeInt => try sema.errNote(src, msg, "use @ptrFromInt to cast from '{}'", .{operand_ty.fmt(pt)}),
10482 .Pointer => try sema.errNote(src, msg, "use @ptrCast to cast from '{}'", .{operand_ty.fmt(mod)}),10604 .Pointer => try sema.errNote(src, msg, "use @ptrCast to cast from '{}'", .{operand_ty.fmt(pt)}),
10483 else => {},10605 else => {},
10484 }10606 }
1048510607
...@@ -10494,7 +10616,7 @@ fn zirBitcast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air...@@ -10494,7 +10616,7 @@ fn zirBitcast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
10494 else => unreachable,10616 else => unreachable,
10495 };10617 };
10496 return sema.fail(block, src, "cannot @bitCast to '{}'; {s} does not have a guaranteed in-memory layout", .{10618 return sema.fail(block, src, "cannot @bitCast to '{}'; {s} does not have a guaranteed in-memory layout", .{
10497 dest_ty.fmt(mod), container,10619 dest_ty.fmt(pt), container,
10498 });10620 });
10499 },10621 },
1050010622
...@@ -10521,14 +10643,14 @@ fn zirBitcast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air...@@ -10521,14 +10643,14 @@ fn zirBitcast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
10521 .Type,10643 .Type,
10522 .Undefined,10644 .Undefined,
10523 .Void,10645 .Void,
10524 => return sema.fail(block, operand_src, "cannot @bitCast from '{}'", .{operand_ty.fmt(mod)}),10646 => return sema.fail(block, operand_src, "cannot @bitCast from '{}'", .{operand_ty.fmt(pt)}),
1052510647
10526 .Enum => {10648 .Enum => {
10527 const msg = msg: {10649 const msg = msg: {
10528 const msg = try sema.errMsg(operand_src, "cannot @bitCast from '{}'", .{operand_ty.fmt(mod)});10650 const msg = try sema.errMsg(operand_src, "cannot @bitCast from '{}'", .{operand_ty.fmt(pt)});
10529 errdefer msg.destroy(sema.gpa);10651 errdefer msg.destroy(sema.gpa);
10530 switch (dest_ty.zigTypeTag(mod)) {10652 switch (dest_ty.zigTypeTag(mod)) {
10531 .Int, .ComptimeInt => try sema.errNote(operand_src, msg, "use @intFromEnum to cast to '{}'", .{dest_ty.fmt(mod)}),10653 .Int, .ComptimeInt => try sema.errNote(operand_src, msg, "use @intFromEnum to cast to '{}'", .{dest_ty.fmt(pt)}),
10532 else => {},10654 else => {},
10533 }10655 }
1053410656
...@@ -10538,11 +10660,11 @@ fn zirBitcast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air...@@ -10538,11 +10660,11 @@ fn zirBitcast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
10538 },10660 },
10539 .Pointer => {10661 .Pointer => {
10540 const msg = msg: {10662 const msg = msg: {
10541 const msg = try sema.errMsg(operand_src, "cannot @bitCast from '{}'", .{operand_ty.fmt(mod)});10663 const msg = try sema.errMsg(operand_src, "cannot @bitCast from '{}'", .{operand_ty.fmt(pt)});
10542 errdefer msg.destroy(sema.gpa);10664 errdefer msg.destroy(sema.gpa);
10543 switch (dest_ty.zigTypeTag(mod)) {10665 switch (dest_ty.zigTypeTag(mod)) {
10544 .Int, .ComptimeInt => try sema.errNote(operand_src, msg, "use @intFromPtr to cast to '{}'", .{dest_ty.fmt(mod)}),10666 .Int, .ComptimeInt => try sema.errNote(operand_src, msg, "use @intFromPtr to cast to '{}'", .{dest_ty.fmt(pt)}),
10545 .Pointer => try sema.errNote(operand_src, msg, "use @ptrCast to cast to '{}'", .{dest_ty.fmt(mod)}),10667 .Pointer => try sema.errNote(operand_src, msg, "use @ptrCast to cast to '{}'", .{dest_ty.fmt(pt)}),
10546 else => {},10668 else => {},
10547 }10669 }
1054810670
...@@ -10557,7 +10679,7 @@ fn zirBitcast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air...@@ -10557,7 +10679,7 @@ fn zirBitcast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
10557 else => unreachable,10679 else => unreachable,
10558 };10680 };
10559 return sema.fail(block, operand_src, "cannot @bitCast from '{}'; {s} does not have a guaranteed in-memory layout", .{10681 return sema.fail(block, operand_src, "cannot @bitCast from '{}'; {s} does not have a guaranteed in-memory layout", .{
10560 operand_ty.fmt(mod), container,10682 operand_ty.fmt(pt), container,
10561 });10683 });
10562 },10684 },
1056310685
...@@ -10575,7 +10697,8 @@ fn zirFloatCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A...@@ -10575,7 +10697,8 @@ fn zirFloatCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
10575 const tracy = trace(@src());10697 const tracy = trace(@src());
10576 defer tracy.end();10698 defer tracy.end();
1057710699
10578 const mod = sema.mod;10700 const pt = sema.pt;
10701 const mod = pt.zcu;
10579 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;10702 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
10580 const src = block.nodeOffset(inst_data.src_node);10703 const src = block.nodeOffset(inst_data.src_node);
10581 const operand_src = block.builtinCallArgSrc(inst_data.src_node, 0);10704 const operand_src = block.builtinCallArgSrc(inst_data.src_node, 0);
...@@ -10599,7 +10722,7 @@ fn zirFloatCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A...@@ -10599,7 +10722,7 @@ fn zirFloatCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
10599 block,10722 block,
10600 src,10723 src,
10601 "expected float or vector type, found '{}'",10724 "expected float or vector type, found '{}'",
10602 .{dest_ty.fmt(mod)},10725 .{dest_ty.fmt(pt)},
10603 ),10726 ),
10604 };10727 };
1060510728
...@@ -10609,21 +10732,21 @@ fn zirFloatCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A...@@ -10609,21 +10732,21 @@ fn zirFloatCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
10609 block,10732 block,
10610 operand_src,10733 operand_src,
10611 "expected float or vector type, found '{}'",10734 "expected float or vector type, found '{}'",
10612 .{operand_ty.fmt(mod)},10735 .{operand_ty.fmt(pt)},
10613 ),10736 ),
10614 }10737 }
1061510738
10616 if (try sema.resolveValue(operand)) |operand_val| {10739 if (try sema.resolveValue(operand)) |operand_val| {
10617 if (!is_vector) {10740 if (!is_vector) {
10618 return Air.internedToRef((try operand_val.floatCast(dest_ty, mod)).toIntern());10741 return Air.internedToRef((try operand_val.floatCast(dest_ty, pt)).toIntern());
10619 }10742 }
10620 const vec_len = operand_ty.vectorLen(mod);10743 const vec_len = operand_ty.vectorLen(mod);
10621 const new_elems = try sema.arena.alloc(InternPool.Index, vec_len);10744 const new_elems = try sema.arena.alloc(InternPool.Index, vec_len);
10622 for (new_elems, 0..) |*new_elem, i| {10745 for (new_elems, 0..) |*new_elem, i| {
10623 const old_elem = try operand_val.elemValue(mod, i);10746 const old_elem = try operand_val.elemValue(pt, i);
10624 new_elem.* = (try old_elem.floatCast(dest_scalar_ty, mod)).toIntern();10747 new_elem.* = (try old_elem.floatCast(dest_scalar_ty, pt)).toIntern();
10625 }10748 }
10626 return Air.internedToRef(try mod.intern(.{ .aggregate = .{10749 return Air.internedToRef(try pt.intern(.{ .aggregate = .{
10627 .ty = dest_ty.toIntern(),10750 .ty = dest_ty.toIntern(),
10628 .storage = .{ .elems = new_elems },10751 .storage = .{ .elems = new_elems },
10629 } }));10752 } }));
...@@ -10644,7 +10767,7 @@ fn zirFloatCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A...@@ -10644,7 +10767,7 @@ fn zirFloatCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
10644 const vec_len = operand_ty.vectorLen(mod);10767 const vec_len = operand_ty.vectorLen(mod);
10645 const new_elems = try sema.arena.alloc(Air.Inst.Ref, vec_len);10768 const new_elems = try sema.arena.alloc(Air.Inst.Ref, vec_len);
10646 for (new_elems, 0..) |*new_elem, i| {10769 for (new_elems, 0..) |*new_elem, i| {
10647 const idx_ref = try mod.intRef(Type.usize, i);10770 const idx_ref = try pt.intRef(Type.usize, i);
10648 const old_elem = try block.addBinOp(.array_elem_val, operand, idx_ref);10771 const old_elem = try block.addBinOp(.array_elem_val, operand, idx_ref);
10649 new_elem.* = try block.addTyOp(.fptrunc, dest_scalar_ty, old_elem);10772 new_elem.* = try block.addTyOp(.fptrunc, dest_scalar_ty, old_elem);
10650 }10773 }
...@@ -10681,10 +10804,9 @@ fn zirElemValImm(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!...@@ -10681,10 +10804,9 @@ fn zirElemValImm(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!
10681 const tracy = trace(@src());10804 const tracy = trace(@src());
10682 defer tracy.end();10805 defer tracy.end();
1068310806
10684 const mod = sema.mod;
10685 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].elem_val_imm;10807 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].elem_val_imm;
10686 const array = try sema.resolveInst(inst_data.operand);10808 const array = try sema.resolveInst(inst_data.operand);
10687 const elem_index = try mod.intRef(Type.usize, inst_data.idx);10809 const elem_index = try sema.pt.intRef(Type.usize, inst_data.idx);
10688 return sema.elemVal(block, LazySrcLoc.unneeded, array, elem_index, LazySrcLoc.unneeded, false);10810 return sema.elemVal(block, LazySrcLoc.unneeded, array, elem_index, LazySrcLoc.unneeded, false);
10689}10811}
1069010812
...@@ -10692,7 +10814,8 @@ fn zirElemPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air...@@ -10692,7 +10814,8 @@ fn zirElemPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
10692 const tracy = trace(@src());10814 const tracy = trace(@src());
10693 defer tracy.end();10815 defer tracy.end();
1069410816
10695 const mod = sema.mod;10817 const pt = sema.pt;
10818 const mod = pt.zcu;
10696 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;10819 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
10697 const src = block.nodeOffset(inst_data.src_node);10820 const src = block.nodeOffset(inst_data.src_node);
10698 const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data;10821 const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data;
...@@ -10703,7 +10826,7 @@ fn zirElemPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air...@@ -10703,7 +10826,7 @@ fn zirElemPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
10703 const capture_src = block.src(.{ .for_capture_from_input = inst_data.src_node });10826 const capture_src = block.src(.{ .for_capture_from_input = inst_data.src_node });
10704 const msg = msg: {10827 const msg = msg: {
10705 const msg = try sema.errMsg(capture_src, "pointer capture of non pointer type '{}'", .{10828 const msg = try sema.errMsg(capture_src, "pointer capture of non pointer type '{}'", .{
10706 indexable_ty.fmt(mod),10829 indexable_ty.fmt(pt),
10707 });10830 });
10708 errdefer msg.destroy(sema.gpa);10831 errdefer msg.destroy(sema.gpa);
10709 if (indexable_ty.isIndexable(mod)) {10832 if (indexable_ty.isIndexable(mod)) {
...@@ -10734,12 +10857,13 @@ fn zirArrayInitElemPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Compile...@@ -10734,12 +10857,13 @@ fn zirArrayInitElemPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Compile
10734 const tracy = trace(@src());10857 const tracy = trace(@src());
10735 defer tracy.end();10858 defer tracy.end();
1073610859
10737 const mod = sema.mod;10860 const pt = sema.pt;
10861 const mod = pt.zcu;
10738 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;10862 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
10739 const src = block.nodeOffset(inst_data.src_node);10863 const src = block.nodeOffset(inst_data.src_node);
10740 const extra = sema.code.extraData(Zir.Inst.ElemPtrImm, inst_data.payload_index).data;10864 const extra = sema.code.extraData(Zir.Inst.ElemPtrImm, inst_data.payload_index).data;
10741 const array_ptr = try sema.resolveInst(extra.ptr);10865 const array_ptr = try sema.resolveInst(extra.ptr);
10742 const elem_index = try sema.mod.intRef(Type.usize, extra.index);10866 const elem_index = try pt.intRef(Type.usize, extra.index);
10743 const array_ty = sema.typeOf(array_ptr).childType(mod);10867 const array_ty = sema.typeOf(array_ptr).childType(mod);
10744 switch (array_ty.zigTypeTag(mod)) {10868 switch (array_ty.zigTypeTag(mod)) {
10745 .Array, .Vector => {},10869 .Array, .Vector => {},
...@@ -10892,7 +11016,7 @@ const SwitchProngAnalysis = struct {...@@ -10892,7 +11016,7 @@ const SwitchProngAnalysis = struct {
10892 inline_case_capture,11016 inline_case_capture,
10893 );11017 );
1089411018
10895 if (sema.typeOf(capture_ref).isNoReturn(sema.mod)) {11019 if (sema.typeOf(capture_ref).isNoReturn(sema.pt.zcu)) {
10896 // This prong should be unreachable!11020 // This prong should be unreachable!
10897 return .unreachable_value;11021 return .unreachable_value;
10898 }11022 }
...@@ -10948,7 +11072,7 @@ const SwitchProngAnalysis = struct {...@@ -10948,7 +11072,7 @@ const SwitchProngAnalysis = struct {
10948 inline_case_capture,11072 inline_case_capture,
10949 );11073 );
1095011074
10951 if (sema.typeOf(capture_ref).isNoReturn(sema.mod)) {11075 if (sema.typeOf(capture_ref).isNoReturn(sema.pt.zcu)) {
10952 // No need to analyze any further, the prong is unreachable11076 // No need to analyze any further, the prong is unreachable
10953 return;11077 return;
10954 }11078 }
...@@ -10968,7 +11092,8 @@ const SwitchProngAnalysis = struct {...@@ -10968,7 +11092,8 @@ const SwitchProngAnalysis = struct {
10968 inline_case_capture: Air.Inst.Ref,11092 inline_case_capture: Air.Inst.Ref,
10969 ) CompileError!Air.Inst.Ref {11093 ) CompileError!Air.Inst.Ref {
10970 const sema = spa.sema;11094 const sema = spa.sema;
10971 const mod = sema.mod;11095 const pt = sema.pt;
11096 const mod = pt.zcu;
10972 const operand_ty = sema.typeOf(spa.operand);11097 const operand_ty = sema.typeOf(spa.operand);
10973 if (operand_ty.zigTypeTag(mod) != .Union) {11098 if (operand_ty.zigTypeTag(mod) != .Union) {
10974 const tag_capture_src: LazySrcLoc = .{11099 const tag_capture_src: LazySrcLoc = .{
...@@ -10976,7 +11101,7 @@ const SwitchProngAnalysis = struct {...@@ -10976,7 +11101,7 @@ const SwitchProngAnalysis = struct {
10976 .offset = .{ .switch_tag_capture = capture_src.offset.switch_capture },11101 .offset = .{ .switch_tag_capture = capture_src.offset.switch_capture },
10977 };11102 };
10978 return sema.fail(block, tag_capture_src, "cannot capture tag of non-union type '{}'", .{11103 return sema.fail(block, tag_capture_src, "cannot capture tag of non-union type '{}'", .{
10979 operand_ty.fmt(mod),11104 operand_ty.fmt(pt),
10980 });11105 });
10981 }11106 }
10982 assert(inline_case_capture != .none);11107 assert(inline_case_capture != .none);
...@@ -10993,7 +11118,8 @@ const SwitchProngAnalysis = struct {...@@ -10993,7 +11118,8 @@ const SwitchProngAnalysis = struct {
10993 inline_case_capture: Air.Inst.Ref,11118 inline_case_capture: Air.Inst.Ref,
10994 ) CompileError!Air.Inst.Ref {11119 ) CompileError!Air.Inst.Ref {
10995 const sema = spa.sema;11120 const sema = spa.sema;
10996 const zcu = sema.mod;11121 const pt = sema.pt;
11122 const zcu = pt.zcu;
10997 const ip = &zcu.intern_pool;11123 const ip = &zcu.intern_pool;
1099811124
10999 const zir_datas = sema.code.instructions.items(.data);11125 const zir_datas = sema.code.instructions.items(.data);
...@@ -11010,7 +11136,7 @@ const SwitchProngAnalysis = struct {...@@ -11010,7 +11136,7 @@ const SwitchProngAnalysis = struct {
11010 const union_obj = zcu.typeToUnion(operand_ty).?;11136 const union_obj = zcu.typeToUnion(operand_ty).?;
11011 const field_ty = Type.fromInterned(union_obj.field_types.get(ip)[field_index]);11137 const field_ty = Type.fromInterned(union_obj.field_types.get(ip)[field_index]);
11012 if (capture_byref) {11138 if (capture_byref) {
11013 const ptr_field_ty = try zcu.ptrTypeSema(.{11139 const ptr_field_ty = try pt.ptrTypeSema(.{
11014 .child = field_ty.toIntern(),11140 .child = field_ty.toIntern(),
11015 .flags = .{11141 .flags = .{
11016 .is_const = !operand_ptr_ty.ptrIsMutable(zcu),11142 .is_const = !operand_ptr_ty.ptrIsMutable(zcu),
...@@ -11019,7 +11145,7 @@ const SwitchProngAnalysis = struct {...@@ -11019,7 +11145,7 @@ const SwitchProngAnalysis = struct {
11019 },11145 },
11020 });11146 });
11021 if (try sema.resolveDefinedValue(block, operand_src, spa.operand_ptr)) |union_ptr| {11147 if (try sema.resolveDefinedValue(block, operand_src, spa.operand_ptr)) |union_ptr| {
11022 return Air.internedToRef((try union_ptr.ptrField(field_index, zcu)).toIntern());11148 return Air.internedToRef((try union_ptr.ptrField(field_index, pt)).toIntern());
11023 }11149 }
11024 return block.addStructFieldPtr(spa.operand_ptr, field_index, ptr_field_ty);11150 return block.addStructFieldPtr(spa.operand_ptr, field_index, ptr_field_ty);
11025 } else {11151 } else {
...@@ -11078,7 +11204,7 @@ const SwitchProngAnalysis = struct {...@@ -11078,7 +11204,7 @@ const SwitchProngAnalysis = struct {
11078 const dummy_captures = try sema.arena.alloc(Air.Inst.Ref, case_vals.len);11204 const dummy_captures = try sema.arena.alloc(Air.Inst.Ref, case_vals.len);
11079 for (dummy_captures, field_indices) |*dummy, field_idx| {11205 for (dummy_captures, field_indices) |*dummy, field_idx| {
11080 const field_ty = Type.fromInterned(union_obj.field_types.get(ip)[field_idx]);11206 const field_ty = Type.fromInterned(union_obj.field_types.get(ip)[field_idx]);
11081 dummy.* = try zcu.undefRef(field_ty);11207 dummy.* = try pt.undefRef(field_ty);
11082 }11208 }
1108311209
11084 const case_srcs = try sema.arena.alloc(?LazySrcLoc, case_vals.len);11210 const case_srcs = try sema.arena.alloc(?LazySrcLoc, case_vals.len);
...@@ -11113,7 +11239,7 @@ const SwitchProngAnalysis = struct {...@@ -11113,7 +11239,7 @@ const SwitchProngAnalysis = struct {
11113 const dummy_captures = try sema.arena.alloc(Air.Inst.Ref, case_vals.len);11239 const dummy_captures = try sema.arena.alloc(Air.Inst.Ref, case_vals.len);
11114 for (field_indices, dummy_captures) |field_idx, *dummy| {11240 for (field_indices, dummy_captures) |field_idx, *dummy| {
11115 const field_ty = Type.fromInterned(union_obj.field_types.get(ip)[field_idx]);11241 const field_ty = Type.fromInterned(union_obj.field_types.get(ip)[field_idx]);
11116 const field_ptr_ty = try zcu.ptrTypeSema(.{11242 const field_ptr_ty = try pt.ptrTypeSema(.{
11117 .child = field_ty.toIntern(),11243 .child = field_ty.toIntern(),
11118 .flags = .{11244 .flags = .{
11119 .is_const = operand_ptr_info.flags.is_const,11245 .is_const = operand_ptr_info.flags.is_const,
...@@ -11122,7 +11248,7 @@ const SwitchProngAnalysis = struct {...@@ -11122,7 +11248,7 @@ const SwitchProngAnalysis = struct {
11122 .alignment = union_obj.fieldAlign(ip, field_idx),11248 .alignment = union_obj.fieldAlign(ip, field_idx),
11123 },11249 },
11124 });11250 });
11125 dummy.* = try zcu.undefRef(field_ptr_ty);11251 dummy.* = try pt.undefRef(field_ptr_ty);
11126 }11252 }
11127 const case_srcs = try sema.arena.alloc(?LazySrcLoc, case_vals.len);11253 const case_srcs = try sema.arena.alloc(?LazySrcLoc, case_vals.len);
11128 for (case_srcs, 0..) |*case_src, i| {11254 for (case_srcs, 0..) |*case_src, i| {
...@@ -11148,9 +11274,9 @@ const SwitchProngAnalysis = struct {...@@ -11148,9 +11274,9 @@ const SwitchProngAnalysis = struct {
11148 };11274 };
1114911275
11150 if (try sema.resolveDefinedValue(block, operand_src, spa.operand_ptr)) |op_ptr_val| {11276 if (try sema.resolveDefinedValue(block, operand_src, spa.operand_ptr)) |op_ptr_val| {
11151 if (op_ptr_val.isUndef(zcu)) return zcu.undefRef(capture_ptr_ty);11277 if (op_ptr_val.isUndef(zcu)) return pt.undefRef(capture_ptr_ty);
11152 const field_ptr_val = try op_ptr_val.ptrField(first_field_index, zcu);11278 const field_ptr_val = try op_ptr_val.ptrField(first_field_index, pt);
11153 return Air.internedToRef((try zcu.getCoerced(field_ptr_val, capture_ptr_ty)).toIntern());11279 return Air.internedToRef((try pt.getCoerced(field_ptr_val, capture_ptr_ty)).toIntern());
11154 }11280 }
1115511281
11156 try sema.requireRuntimeBlock(block, operand_src, null);11282 try sema.requireRuntimeBlock(block, operand_src, null);
...@@ -11158,9 +11284,9 @@ const SwitchProngAnalysis = struct {...@@ -11158,9 +11284,9 @@ const SwitchProngAnalysis = struct {
11158 }11284 }
1115911285
11160 if (try sema.resolveDefinedValue(block, operand_src, spa.operand)) |operand_val| {11286 if (try sema.resolveDefinedValue(block, operand_src, spa.operand)) |operand_val| {
11161 if (operand_val.isUndef(zcu)) return zcu.undefRef(capture_ty);11287 if (operand_val.isUndef(zcu)) return pt.undefRef(capture_ty);
11162 const union_val = ip.indexToKey(operand_val.toIntern()).un;11288 const union_val = ip.indexToKey(operand_val.toIntern()).un;
11163 if (Value.fromInterned(union_val.tag).isUndef(zcu)) return zcu.undefRef(capture_ty);11289 if (Value.fromInterned(union_val.tag).isUndef(zcu)) return pt.undefRef(capture_ty);
11164 const uncoerced = Air.internedToRef(union_val.val);11290 const uncoerced = Air.internedToRef(union_val.val);
11165 return sema.coerce(block, capture_ty, uncoerced, operand_src);11291 return sema.coerce(block, capture_ty, uncoerced, operand_src);
11166 }11292 }
...@@ -11304,7 +11430,7 @@ const SwitchProngAnalysis = struct {...@@ -11304,7 +11430,7 @@ const SwitchProngAnalysis = struct {
1130411430
11305 if (case_vals.len == 1) {11431 if (case_vals.len == 1) {
11306 const item_val = sema.resolveConstDefinedValue(block, LazySrcLoc.unneeded, case_vals[0], undefined) catch unreachable;11432 const item_val = sema.resolveConstDefinedValue(block, LazySrcLoc.unneeded, case_vals[0], undefined) catch unreachable;
11307 const item_ty = try zcu.singleErrorSetType(item_val.getErrorName(zcu).unwrap().?);11433 const item_ty = try pt.singleErrorSetType(item_val.getErrorName(zcu).unwrap().?);
11308 return sema.bitCast(block, item_ty, spa.operand, operand_src, null);11434 return sema.bitCast(block, item_ty, spa.operand, operand_src, null);
11309 }11435 }
1131011436
...@@ -11314,7 +11440,7 @@ const SwitchProngAnalysis = struct {...@@ -11314,7 +11440,7 @@ const SwitchProngAnalysis = struct {
11314 const err_val = sema.resolveConstDefinedValue(block, LazySrcLoc.unneeded, err, undefined) catch unreachable;11440 const err_val = sema.resolveConstDefinedValue(block, LazySrcLoc.unneeded, err, undefined) catch unreachable;
11315 names.putAssumeCapacityNoClobber(err_val.getErrorName(zcu).unwrap().?, {});11441 names.putAssumeCapacityNoClobber(err_val.getErrorName(zcu).unwrap().?, {});
11316 }11442 }
11317 const error_ty = try zcu.errorSetFromUnsortedNames(names.keys());11443 const error_ty = try pt.errorSetFromUnsortedNames(names.keys());
11318 return sema.bitCast(block, error_ty, spa.operand, operand_src, null);11444 return sema.bitCast(block, error_ty, spa.operand, operand_src, null);
11319 },11445 },
11320 else => {11446 else => {
...@@ -11336,7 +11462,8 @@ fn switchCond(...@@ -11336,7 +11462,8 @@ fn switchCond(
11336 src: LazySrcLoc,11462 src: LazySrcLoc,
11337 operand: Air.Inst.Ref,11463 operand: Air.Inst.Ref,
11338) CompileError!Air.Inst.Ref {11464) CompileError!Air.Inst.Ref {
11339 const mod = sema.mod;11465 const pt = sema.pt;
11466 const mod = pt.zcu;
11340 const operand_ty = sema.typeOf(operand);11467 const operand_ty = sema.typeOf(operand);
11341 switch (operand_ty.zigTypeTag(mod)) {11468 switch (operand_ty.zigTypeTag(mod)) {
11342 .Type,11469 .Type,
...@@ -11353,7 +11480,7 @@ fn switchCond(...@@ -11353,7 +11480,7 @@ fn switchCond(
11353 .Enum,11480 .Enum,
11354 => {11481 => {
11355 if (operand_ty.isSlice(mod)) {11482 if (operand_ty.isSlice(mod)) {
11356 return sema.fail(block, src, "switch on type '{}'", .{operand_ty.fmt(mod)});11483 return sema.fail(block, src, "switch on type '{}'", .{operand_ty.fmt(pt)});
11357 }11484 }
11358 if ((try sema.typeHasOnePossibleValue(operand_ty))) |opv| {11485 if ((try sema.typeHasOnePossibleValue(operand_ty))) |opv| {
11359 return Air.internedToRef(opv.toIntern());11486 return Air.internedToRef(opv.toIntern());
...@@ -11362,7 +11489,7 @@ fn switchCond(...@@ -11362,7 +11489,7 @@ fn switchCond(
11362 },11489 },
1136311490
11364 .Union => {11491 .Union => {
11365 try operand_ty.resolveFields(mod);11492 try operand_ty.resolveFields(pt);
11366 const enum_ty = operand_ty.unionTagType(mod) orelse {11493 const enum_ty = operand_ty.unionTagType(mod) orelse {
11367 const msg = msg: {11494 const msg = msg: {
11368 const msg = try sema.errMsg(src, "switch on union with no attached enum", .{});11495 const msg = try sema.errMsg(src, "switch on union with no attached enum", .{});
...@@ -11388,7 +11515,7 @@ fn switchCond(...@@ -11388,7 +11515,7 @@ fn switchCond(
11388 .Vector,11515 .Vector,
11389 .Frame,11516 .Frame,
11390 .AnyFrame,11517 .AnyFrame,
11391 => return sema.fail(block, src, "switch on type '{}'", .{operand_ty.fmt(mod)}),11518 => return sema.fail(block, src, "switch on type '{}'", .{operand_ty.fmt(pt)}),
11392 }11519 }
11393}11520}
1139411521
...@@ -11398,7 +11525,8 @@ fn zirSwitchBlockErrUnion(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Comp...@@ -11398,7 +11525,8 @@ fn zirSwitchBlockErrUnion(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Comp
11398 const tracy = trace(@src());11525 const tracy = trace(@src());
11399 defer tracy.end();11526 defer tracy.end();
1140011527
11401 const mod = sema.mod;11528 const pt = sema.pt;
11529 const mod = pt.zcu;
11402 const gpa = sema.gpa;11530 const gpa = sema.gpa;
11403 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;11531 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
11404 const switch_src = block.nodeOffset(inst_data.src_node);11532 const switch_src = block.nodeOffset(inst_data.src_node);
...@@ -11489,7 +11617,7 @@ fn zirSwitchBlockErrUnion(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Comp...@@ -11489,7 +11617,7 @@ fn zirSwitchBlockErrUnion(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Comp
1148911617
11490 if (operand_err_set.zigTypeTag(mod) != .ErrorUnion) {11618 if (operand_err_set.zigTypeTag(mod) != .ErrorUnion) {
11491 return sema.fail(block, switch_src, "expected error union type, found '{}'", .{11619 return sema.fail(block, switch_src, "expected error union type, found '{}'", .{
11492 operand_ty.fmt(mod),11620 operand_ty.fmt(pt),
11493 });11621 });
11494 }11622 }
1149511623
...@@ -11571,7 +11699,7 @@ fn zirSwitchBlockErrUnion(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Comp...@@ -11571,7 +11699,7 @@ fn zirSwitchBlockErrUnion(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Comp
11571 if (operand_val.errorUnionIsPayload(mod)) {11699 if (operand_val.errorUnionIsPayload(mod)) {
11572 return sema.resolveBlockBody(block, main_operand_src, &child_block, non_error_case.body, inst, merges);11700 return sema.resolveBlockBody(block, main_operand_src, &child_block, non_error_case.body, inst, merges);
11573 } else {11701 } else {
11574 const err_val = Value.fromInterned(try mod.intern(.{11702 const err_val = Value.fromInterned(try pt.intern(.{
11575 .err = .{11703 .err = .{
11576 .ty = operand_err_set_ty.toIntern(),11704 .ty = operand_err_set_ty.toIntern(),
11577 .name = operand_val.getErrorName(mod).unwrap().?,11705 .name = operand_val.getErrorName(mod).unwrap().?,
...@@ -11708,7 +11836,8 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index, operand_is_r...@@ -11708,7 +11836,8 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index, operand_is_r
11708 const tracy = trace(@src());11836 const tracy = trace(@src());
11709 defer tracy.end();11837 defer tracy.end();
1171011838
11711 const mod = sema.mod;11839 const pt = sema.pt;
11840 const mod = pt.zcu;
11712 const gpa = sema.gpa;11841 const gpa = sema.gpa;
11713 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;11842 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
11714 const src = block.nodeOffset(inst_data.src_node);11843 const src = block.nodeOffset(inst_data.src_node);
...@@ -11783,7 +11912,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index, operand_is_r...@@ -11783,7 +11912,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index, operand_is_r
11783 // Duplicate checking variables later also used for `inline else`.11912 // Duplicate checking variables later also used for `inline else`.
11784 var seen_enum_fields: []?LazySrcLoc = &.{};11913 var seen_enum_fields: []?LazySrcLoc = &.{};
11785 var seen_errors = SwitchErrorSet.init(gpa);11914 var seen_errors = SwitchErrorSet.init(gpa);
11786 var range_set = RangeSet.init(gpa, mod);11915 var range_set = RangeSet.init(gpa, pt);
11787 var true_count: u8 = 0;11916 var true_count: u8 = 0;
11788 var false_count: u8 = 0;11917 var false_count: u8 = 0;
1178911918
...@@ -11924,7 +12053,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index, operand_is_r...@@ -11924,7 +12053,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index, operand_is_r
11924 operand_ty.srcLoc(mod),12053 operand_ty.srcLoc(mod),
11925 msg,12054 msg,
11926 "enum '{}' declared here",12055 "enum '{}' declared here",
11927 .{operand_ty.fmt(mod)},12056 .{operand_ty.fmt(pt)},
11928 );12057 );
11929 break :msg msg;12058 break :msg msg;
11930 };12059 };
...@@ -12030,8 +12159,8 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index, operand_is_r...@@ -12030,8 +12159,8 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index, operand_is_r
1203012159
12031 check_range: {12160 check_range: {
12032 if (operand_ty.zigTypeTag(mod) == .Int) {12161 if (operand_ty.zigTypeTag(mod) == .Int) {
12033 const min_int = try operand_ty.minInt(mod, operand_ty);12162 const min_int = try operand_ty.minInt(pt, operand_ty);
12034 const max_int = try operand_ty.maxInt(mod, operand_ty);12163 const max_int = try operand_ty.maxInt(pt, operand_ty);
12035 if (try range_set.spans(min_int.toIntern(), max_int.toIntern())) {12164 if (try range_set.spans(min_int.toIntern(), max_int.toIntern())) {
12036 if (special_prong == .@"else") {12165 if (special_prong == .@"else") {
12037 return sema.fail(12166 return sema.fail(
...@@ -12136,7 +12265,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index, operand_is_r...@@ -12136,7 +12265,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index, operand_is_r
12136 block,12265 block,
12137 src,12266 src,
12138 "else prong required when switching on type '{}'",12267 "else prong required when switching on type '{}'",
12139 .{operand_ty.fmt(mod)},12268 .{operand_ty.fmt(pt)},
12140 );12269 );
12141 }12270 }
1214212271
...@@ -12212,7 +12341,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index, operand_is_r...@@ -12212,7 +12341,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index, operand_is_r
12212 .ComptimeFloat,12341 .ComptimeFloat,
12213 .Float,12342 .Float,
12214 => return sema.fail(block, operand_src, "invalid switch operand type '{}'", .{12343 => return sema.fail(block, operand_src, "invalid switch operand type '{}'", .{
12215 operand_ty.fmt(mod),12344 operand_ty.fmt(pt),
12216 }),12345 }),
12217 }12346 }
1221812347
...@@ -12386,7 +12515,8 @@ fn analyzeSwitchRuntimeBlock(...@@ -12386,7 +12515,8 @@ fn analyzeSwitchRuntimeBlock(
12386 cond_dbg_node_index: Zir.Inst.Index,12515 cond_dbg_node_index: Zir.Inst.Index,
12387 allow_err_code_unwrap: bool,12516 allow_err_code_unwrap: bool,
12388) CompileError!Air.Inst.Ref {12517) CompileError!Air.Inst.Ref {
12389 const mod = sema.mod;12518 const pt = sema.pt;
12519 const mod = pt.zcu;
12390 const gpa = sema.gpa;12520 const gpa = sema.gpa;
12391 const ip = &mod.intern_pool;12521 const ip = &mod.intern_pool;
1239212522
...@@ -12496,9 +12626,9 @@ fn analyzeSwitchRuntimeBlock(...@@ -12496,9 +12626,9 @@ fn analyzeSwitchRuntimeBlock(
12496 var item = sema.resolveConstDefinedValue(block, LazySrcLoc.unneeded, item_first_ref, undefined) catch unreachable;12626 var item = sema.resolveConstDefinedValue(block, LazySrcLoc.unneeded, item_first_ref, undefined) catch unreachable;
12497 const item_last = sema.resolveConstDefinedValue(block, LazySrcLoc.unneeded, item_last_ref, undefined) catch unreachable;12627 const item_last = sema.resolveConstDefinedValue(block, LazySrcLoc.unneeded, item_last_ref, undefined) catch unreachable;
1249812628
12499 while (item.compareScalar(.lte, item_last, operand_ty, mod)) : ({12629 while (item.compareScalar(.lte, item_last, operand_ty, pt)) : ({
12500 // Previous validation has resolved any possible lazy values.12630 // Previous validation has resolved any possible lazy values.
12501 item = sema.intAddScalar(item, try mod.intValue(operand_ty, 1), operand_ty) catch |err| switch (err) {12631 item = sema.intAddScalar(item, try pt.intValue(operand_ty, 1), operand_ty) catch |err| switch (err) {
12502 error.Overflow => unreachable,12632 error.Overflow => unreachable,
12503 else => |e| return e,12633 else => |e| return e,
12504 };12634 };
...@@ -12537,7 +12667,7 @@ fn analyzeSwitchRuntimeBlock(...@@ -12537,7 +12667,7 @@ fn analyzeSwitchRuntimeBlock(
12537 cases_extra.appendAssumeCapacity(@intFromEnum(item_ref));12667 cases_extra.appendAssumeCapacity(@intFromEnum(item_ref));
12538 cases_extra.appendSliceAssumeCapacity(@ptrCast(case_block.instructions.items));12668 cases_extra.appendSliceAssumeCapacity(@ptrCast(case_block.instructions.items));
1253912669
12540 if (item.compareScalar(.eq, item_last, operand_ty, mod)) break;12670 if (item.compareScalar(.eq, item_last, operand_ty, pt)) break;
12541 }12671 }
12542 }12672 }
1254312673
...@@ -12744,14 +12874,14 @@ fn analyzeSwitchRuntimeBlock(...@@ -12744,14 +12874,14 @@ fn analyzeSwitchRuntimeBlock(
12744 .Enum => {12874 .Enum => {
12745 if (operand_ty.isNonexhaustiveEnum(mod) and !union_originally) {12875 if (operand_ty.isNonexhaustiveEnum(mod) and !union_originally) {
12746 return sema.fail(block, special_prong_src, "cannot enumerate values of type '{}' for 'inline else'", .{12876 return sema.fail(block, special_prong_src, "cannot enumerate values of type '{}' for 'inline else'", .{
12747 operand_ty.fmt(mod),12877 operand_ty.fmt(pt),
12748 });12878 });
12749 }12879 }
12750 for (seen_enum_fields, 0..) |f, i| {12880 for (seen_enum_fields, 0..) |f, i| {
12751 if (f != null) continue;12881 if (f != null) continue;
12752 cases_len += 1;12882 cases_len += 1;
1275312883
12754 const item_val = try mod.enumValueFieldIndex(operand_ty, @intCast(i));12884 const item_val = try pt.enumValueFieldIndex(operand_ty, @intCast(i));
12755 const item_ref = Air.internedToRef(item_val.toIntern());12885 const item_ref = Air.internedToRef(item_val.toIntern());
1275612886
12757 case_block.instructions.shrinkRetainingCapacity(0);12887 case_block.instructions.shrinkRetainingCapacity(0);
...@@ -12793,7 +12923,7 @@ fn analyzeSwitchRuntimeBlock(...@@ -12793,7 +12923,7 @@ fn analyzeSwitchRuntimeBlock(
12793 .ErrorSet => {12923 .ErrorSet => {
12794 if (operand_ty.isAnyError(mod)) {12924 if (operand_ty.isAnyError(mod)) {
12795 return sema.fail(block, special_prong_src, "cannot enumerate values of type '{}' for 'inline else'", .{12925 return sema.fail(block, special_prong_src, "cannot enumerate values of type '{}' for 'inline else'", .{
12796 operand_ty.fmt(mod),12926 operand_ty.fmt(pt),
12797 });12927 });
12798 }12928 }
12799 const error_names = operand_ty.errorSetNames(mod);12929 const error_names = operand_ty.errorSetNames(mod);
...@@ -12802,7 +12932,7 @@ fn analyzeSwitchRuntimeBlock(...@@ -12802,7 +12932,7 @@ fn analyzeSwitchRuntimeBlock(
12802 if (seen_errors.contains(error_name)) continue;12932 if (seen_errors.contains(error_name)) continue;
12803 cases_len += 1;12933 cases_len += 1;
1280412934
12805 const item_val = try mod.intern(.{ .err = .{12935 const item_val = try pt.intern(.{ .err = .{
12806 .ty = operand_ty.toIntern(),12936 .ty = operand_ty.toIntern(),
12807 .name = error_name,12937 .name = error_name,
12808 } });12938 } });
...@@ -12930,7 +13060,7 @@ fn analyzeSwitchRuntimeBlock(...@@ -12930,7 +13060,7 @@ fn analyzeSwitchRuntimeBlock(
12930 }13060 }
12931 },13061 },
12932 else => return sema.fail(block, special_prong_src, "cannot enumerate values of type '{}' for 'inline else'", .{13062 else => return sema.fail(block, special_prong_src, "cannot enumerate values of type '{}' for 'inline else'", .{
12933 operand_ty.fmt(mod),13063 operand_ty.fmt(pt),
12934 }),13064 }),
12935 };13065 };
1293613066
...@@ -13051,7 +13181,7 @@ fn resolveSwitchComptime(...@@ -13051,7 +13181,7 @@ fn resolveSwitchComptime(
1305113181
13052 const item = case_vals.items[scalar_i];13182 const item = case_vals.items[scalar_i];
13053 const item_val = sema.resolveConstDefinedValue(child_block, LazySrcLoc.unneeded, item, undefined) catch unreachable;13183 const item_val = sema.resolveConstDefinedValue(child_block, LazySrcLoc.unneeded, item, undefined) catch unreachable;
13054 if (operand_val.eql(item_val, operand_ty, sema.mod)) {13184 if (operand_val.eql(item_val, operand_ty, sema.pt.zcu)) {
13055 if (err_set) try sema.maybeErrorUnwrapComptime(child_block, body, cond_operand);13185 if (err_set) try sema.maybeErrorUnwrapComptime(child_block, body, cond_operand);
13056 return spa.resolveProngComptime(13186 return spa.resolveProngComptime(
13057 child_block,13187 child_block,
...@@ -13088,7 +13218,7 @@ fn resolveSwitchComptime(...@@ -13088,7 +13218,7 @@ fn resolveSwitchComptime(
13088 for (items) |item| {13218 for (items) |item| {
13089 // Validation above ensured these will succeed.13219 // Validation above ensured these will succeed.
13090 const item_val = sema.resolveConstDefinedValue(child_block, LazySrcLoc.unneeded, item, undefined) catch unreachable;13220 const item_val = sema.resolveConstDefinedValue(child_block, LazySrcLoc.unneeded, item, undefined) catch unreachable;
13091 if (operand_val.eql(item_val, operand_ty, sema.mod)) {13221 if (operand_val.eql(item_val, operand_ty, sema.pt.zcu)) {
13092 if (err_set) try sema.maybeErrorUnwrapComptime(child_block, body, cond_operand);13222 if (err_set) try sema.maybeErrorUnwrapComptime(child_block, body, cond_operand);
13093 return spa.resolveProngComptime(13223 return spa.resolveProngComptime(
13094 child_block,13224 child_block,
...@@ -13162,7 +13292,7 @@ fn resolveSwitchComptime(...@@ -13162,7 +13292,7 @@ fn resolveSwitchComptime(
13162}13292}
1316313293
13164const RangeSetUnhandledIterator = struct {13294const RangeSetUnhandledIterator = struct {
13165 mod: *Module,13295 pt: Zcu.PerThread,
13166 cur: ?InternPool.Index,13296 cur: ?InternPool.Index,
13167 max: InternPool.Index,13297 max: InternPool.Index,
13168 range_i: usize,13298 range_i: usize,
...@@ -13172,13 +13302,13 @@ const RangeSetUnhandledIterator = struct {...@@ -13172,13 +13302,13 @@ const RangeSetUnhandledIterator = struct {
13172 const preallocated_limbs = math.big.int.calcTwosCompLimbCount(128);13302 const preallocated_limbs = math.big.int.calcTwosCompLimbCount(128);
1317313303
13174 fn init(sema: *Sema, ty: Type, range_set: RangeSet) !RangeSetUnhandledIterator {13304 fn init(sema: *Sema, ty: Type, range_set: RangeSet) !RangeSetUnhandledIterator {
13175 const mod = sema.mod;13305 const pt = sema.pt;
13176 const int_type = mod.intern_pool.indexToKey(ty.toIntern()).int_type;13306 const int_type = pt.zcu.intern_pool.indexToKey(ty.toIntern()).int_type;
13177 const needed_limbs = math.big.int.calcTwosCompLimbCount(int_type.bits);13307 const needed_limbs = math.big.int.calcTwosCompLimbCount(int_type.bits);
13178 return .{13308 return .{
13179 .mod = mod,13309 .pt = pt,
13180 .cur = (try ty.minInt(mod, ty)).toIntern(),13310 .cur = (try ty.minInt(pt, ty)).toIntern(),
13181 .max = (try ty.maxInt(mod, ty)).toIntern(),13311 .max = (try ty.maxInt(pt, ty)).toIntern(),
13182 .range_i = 0,13312 .range_i = 0,
13183 .ranges = range_set.ranges.items,13313 .ranges = range_set.ranges.items,
13184 .limbs = if (needed_limbs > preallocated_limbs)13314 .limbs = if (needed_limbs > preallocated_limbs)
...@@ -13190,13 +13320,13 @@ const RangeSetUnhandledIterator = struct {...@@ -13190,13 +13320,13 @@ const RangeSetUnhandledIterator = struct {
1319013320
13191 fn addOne(it: *const RangeSetUnhandledIterator, val: InternPool.Index) !?InternPool.Index {13321 fn addOne(it: *const RangeSetUnhandledIterator, val: InternPool.Index) !?InternPool.Index {
13192 if (val == it.max) return null;13322 if (val == it.max) return null;
13193 const int = it.mod.intern_pool.indexToKey(val).int;13323 const int = it.pt.zcu.intern_pool.indexToKey(val).int;
1319413324
13195 switch (int.storage) {13325 switch (int.storage) {
13196 inline .u64, .i64 => |val_int| {13326 inline .u64, .i64 => |val_int| {
13197 const next_int = @addWithOverflow(val_int, 1);13327 const next_int = @addWithOverflow(val_int, 1);
13198 if (next_int[1] == 0)13328 if (next_int[1] == 0)
13199 return (try it.mod.intValue(Type.fromInterned(int.ty), next_int[0])).toIntern();13329 return (try it.pt.intValue(Type.fromInterned(int.ty), next_int[0])).toIntern();
13200 },13330 },
13201 .big_int => {},13331 .big_int => {},
13202 .lazy_align, .lazy_size => unreachable,13332 .lazy_align, .lazy_size => unreachable,
...@@ -13212,7 +13342,7 @@ const RangeSetUnhandledIterator = struct {...@@ -13212,7 +13342,7 @@ const RangeSetUnhandledIterator = struct {
13212 );13342 );
1321313343
13214 result_bigint.addScalar(val_bigint, 1);13344 result_bigint.addScalar(val_bigint, 1);
13215 return (try it.mod.intValue_big(Type.fromInterned(int.ty), result_bigint.toConst())).toIntern();13345 return (try it.pt.intValue_big(Type.fromInterned(int.ty), result_bigint.toConst())).toIntern();
13216 }13346 }
1321713347
13218 fn next(it: *RangeSetUnhandledIterator) !?InternPool.Index {13348 fn next(it: *RangeSetUnhandledIterator) !?InternPool.Index {
...@@ -13274,7 +13404,8 @@ fn validateErrSetSwitch(...@@ -13274,7 +13404,8 @@ fn validateErrSetSwitch(
13274 has_else: bool,13404 has_else: bool,
13275) CompileError!?Type {13405) CompileError!?Type {
13276 const gpa = sema.gpa;13406 const gpa = sema.gpa;
13277 const mod = sema.mod;13407 const pt = sema.pt;
13408 const mod = pt.zcu;
13278 const ip = &mod.intern_pool;13409 const ip = &mod.intern_pool;
1327913410
13280 const src_node_offset = inst_data.src_node;13411 const src_node_offset = inst_data.src_node;
...@@ -13426,7 +13557,7 @@ fn validateErrSetSwitch(...@@ -13426,7 +13557,7 @@ fn validateErrSetSwitch(
13426 }13557 }
13427 // No need to keep the hash map metadata correct; here we13558 // No need to keep the hash map metadata correct; here we
13428 // extract the (sorted) keys only.13559 // extract the (sorted) keys only.
13429 return try mod.errorSetFromUnsortedNames(names.keys());13560 return try pt.errorSetFromUnsortedNames(names.keys());
13430 },13561 },
13431 }13562 }
13432 return null;13563 return null;
...@@ -13441,7 +13572,6 @@ fn validateSwitchRange(...@@ -13441,7 +13572,6 @@ fn validateSwitchRange(
13441 operand_ty: Type,13572 operand_ty: Type,
13442 item_src: LazySrcLoc,13573 item_src: LazySrcLoc,
13443) CompileError![2]Air.Inst.Ref {13574) CompileError![2]Air.Inst.Ref {
13444 const mod = sema.mod;
13445 const first_src: LazySrcLoc = .{13575 const first_src: LazySrcLoc = .{
13446 .base_node_inst = item_src.base_node_inst,13576 .base_node_inst = item_src.base_node_inst,
13447 .offset = .{ .switch_case_item_range_first = item_src.offset.switch_case_item },13577 .offset = .{ .switch_case_item_range_first = item_src.offset.switch_case_item },
...@@ -13452,7 +13582,7 @@ fn validateSwitchRange(...@@ -13452,7 +13582,7 @@ fn validateSwitchRange(
13452 };13582 };
13453 const first = try sema.resolveSwitchItemVal(block, first_ref, operand_ty, first_src);13583 const first = try sema.resolveSwitchItemVal(block, first_ref, operand_ty, first_src);
13454 const last = try sema.resolveSwitchItemVal(block, last_ref, operand_ty, last_src);13584 const last = try sema.resolveSwitchItemVal(block, last_ref, operand_ty, last_src);
13455 if (try Value.fromInterned(first.val).compareAll(.gt, Value.fromInterned(last.val), operand_ty, mod)) {13585 if (try Value.fromInterned(first.val).compareAll(.gt, Value.fromInterned(last.val), operand_ty, sema.pt)) {
13456 return sema.fail(block, item_src, "range start value is greater than the end value", .{});13586 return sema.fail(block, item_src, "range start value is greater than the end value", .{});
13457 }13587 }
13458 const maybe_prev_src = try range_set.add(first.val, last.val, item_src);13588 const maybe_prev_src = try range_set.add(first.val, last.val, item_src);
...@@ -13483,7 +13613,7 @@ fn validateSwitchItemEnum(...@@ -13483,7 +13613,7 @@ fn validateSwitchItemEnum(
13483 operand_ty: Type,13613 operand_ty: Type,
13484 item_src: LazySrcLoc,13614 item_src: LazySrcLoc,
13485) CompileError!Air.Inst.Ref {13615) CompileError!Air.Inst.Ref {
13486 const ip = &sema.mod.intern_pool;13616 const ip = &sema.pt.zcu.intern_pool;
13487 const item = try sema.resolveSwitchItemVal(block, item_ref, operand_ty, item_src);13617 const item = try sema.resolveSwitchItemVal(block, item_ref, operand_ty, item_src);
13488 const int = ip.indexToKey(item.val).enum_tag.int;13618 const int = ip.indexToKey(item.val).enum_tag.int;
13489 const field_index = ip.loadEnumType(ip.typeOf(item.val)).tagValueIndex(ip, int) orelse {13619 const field_index = ip.loadEnumType(ip.typeOf(item.val)).tagValueIndex(ip, int) orelse {
...@@ -13505,9 +13635,8 @@ fn validateSwitchItemError(...@@ -13505,9 +13635,8 @@ fn validateSwitchItemError(
13505 operand_ty: Type,13635 operand_ty: Type,
13506 item_src: LazySrcLoc,13636 item_src: LazySrcLoc,
13507) CompileError!Air.Inst.Ref {13637) CompileError!Air.Inst.Ref {
13508 const ip = &sema.mod.intern_pool;
13509 const item = try sema.resolveSwitchItemVal(block, item_ref, operand_ty, item_src);13638 const item = try sema.resolveSwitchItemVal(block, item_ref, operand_ty, item_src);
13510 const error_name = ip.indexToKey(item.val).err.name;13639 const error_name = sema.pt.zcu.intern_pool.indexToKey(item.val).err.name;
13511 const maybe_prev_src = if (try seen_errors.fetchPut(error_name, item_src)) |prev|13640 const maybe_prev_src = if (try seen_errors.fetchPut(error_name, item_src)) |prev|
13512 prev.value13641 prev.value
13513 else13642 else
...@@ -13593,7 +13722,7 @@ fn validateSwitchNoRange(...@@ -13593,7 +13722,7 @@ fn validateSwitchNoRange(
13593 const msg = try sema.errMsg(13722 const msg = try sema.errMsg(
13594 operand_src,13723 operand_src,
13595 "ranges not allowed when switching on type '{}'",13724 "ranges not allowed when switching on type '{}'",
13596 .{operand_ty.fmt(sema.mod)},13725 .{operand_ty.fmt(sema.pt)},
13597 );13726 );
13598 errdefer msg.destroy(sema.gpa);13727 errdefer msg.destroy(sema.gpa);
13599 try sema.errNote(13728 try sema.errNote(
...@@ -13615,7 +13744,8 @@ fn maybeErrorUnwrap(...@@ -13615,7 +13744,8 @@ fn maybeErrorUnwrap(
13615 operand_src: LazySrcLoc,13744 operand_src: LazySrcLoc,
13616 allow_err_code_inst: bool,13745 allow_err_code_inst: bool,
13617) !bool {13746) !bool {
13618 const mod = sema.mod;13747 const pt = sema.pt;
13748 const mod = pt.zcu;
13619 if (!mod.backendSupportsFeature(.panic_unwrap_error)) return false;13749 if (!mod.backendSupportsFeature(.panic_unwrap_error)) return false;
1362013750
13621 const tags = sema.code.instructions.items(.tag);13751 const tags = sema.code.instructions.items(.tag);
...@@ -13654,7 +13784,7 @@ fn maybeErrorUnwrap(...@@ -13654,7 +13784,7 @@ fn maybeErrorUnwrap(
13654 return true;13784 return true;
13655 }13785 }
1365613786
13657 const panic_fn = try mod.getBuiltin("panicUnwrapError");13787 const panic_fn = try pt.getBuiltin("panicUnwrapError");
13658 const err_return_trace = try sema.getErrorReturnTrace(block);13788 const err_return_trace = try sema.getErrorReturnTrace(block);
13659 const args: [2]Air.Inst.Ref = .{ err_return_trace, operand };13789 const args: [2]Air.Inst.Ref = .{ err_return_trace, operand };
13660 try sema.callBuiltin(block, operand_src, panic_fn, .auto, &args, .@"safety check");13790 try sema.callBuiltin(block, operand_src, panic_fn, .auto, &args, .@"safety check");
...@@ -13664,7 +13794,7 @@ fn maybeErrorUnwrap(...@@ -13664,7 +13794,7 @@ fn maybeErrorUnwrap(
13664 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;13794 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;
13665 const msg_inst = try sema.resolveInst(inst_data.operand);13795 const msg_inst = try sema.resolveInst(inst_data.operand);
1366613796
13667 const panic_fn = try mod.getBuiltin("panic");13797 const panic_fn = try pt.getBuiltin("panic");
13668 const err_return_trace = try sema.getErrorReturnTrace(block);13798 const err_return_trace = try sema.getErrorReturnTrace(block);
13669 const args: [3]Air.Inst.Ref = .{ msg_inst, err_return_trace, .null_value };13799 const args: [3]Air.Inst.Ref = .{ msg_inst, err_return_trace, .null_value };
13670 try sema.callBuiltin(block, operand_src, panic_fn, .auto, &args, .@"safety check");13800 try sema.callBuiltin(block, operand_src, panic_fn, .auto, &args, .@"safety check");
...@@ -13680,7 +13810,8 @@ fn maybeErrorUnwrap(...@@ -13680,7 +13810,8 @@ fn maybeErrorUnwrap(
13680}13810}
1368113811
13682fn maybeErrorUnwrapCondbr(sema: *Sema, block: *Block, body: []const Zir.Inst.Index, cond: Zir.Inst.Ref, cond_src: LazySrcLoc) !void {13812fn maybeErrorUnwrapCondbr(sema: *Sema, block: *Block, body: []const Zir.Inst.Index, cond: Zir.Inst.Ref, cond_src: LazySrcLoc) !void {
13683 const mod = sema.mod;13813 const pt = sema.pt;
13814 const mod = pt.zcu;
13684 const index = cond.toIndex() orelse return;13815 const index = cond.toIndex() orelse return;
13685 if (sema.code.instructions.items(.tag)[@intFromEnum(index)] != .is_non_err) return;13816 if (sema.code.instructions.items(.tag)[@intFromEnum(index)] != .is_non_err) return;
1368613817
...@@ -13713,14 +13844,15 @@ fn maybeErrorUnwrapComptime(sema: *Sema, block: *Block, body: []const Zir.Inst.I...@@ -13713,14 +13844,15 @@ fn maybeErrorUnwrapComptime(sema: *Sema, block: *Block, body: []const Zir.Inst.I
13713 const src = block.nodeOffset(inst_data.src_node);13844 const src = block.nodeOffset(inst_data.src_node);
1371413845
13715 if (try sema.resolveDefinedValue(block, src, operand)) |val| {13846 if (try sema.resolveDefinedValue(block, src, operand)) |val| {
13716 if (val.getErrorName(sema.mod).unwrap()) |name| {13847 if (val.getErrorName(sema.pt.zcu).unwrap()) |name| {
13717 return sema.failWithComptimeErrorRetTrace(block, src, name);13848 return sema.failWithComptimeErrorRetTrace(block, src, name);
13718 }13849 }
13719 }13850 }
13720}13851}
1372113852
13722fn zirHasField(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {13853fn zirHasField(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
13723 const mod = sema.mod;13854 const pt = sema.pt;
13855 const mod = pt.zcu;
13724 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;13856 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
13725 const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data;13857 const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data;
13726 const ty_src = block.builtinCallArgSrc(inst_data.src_node, 0);13858 const ty_src = block.builtinCallArgSrc(inst_data.src_node, 0);
...@@ -13729,7 +13861,7 @@ fn zirHasField(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -13729,7 +13861,7 @@ fn zirHasField(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
13729 const field_name = try sema.resolveConstStringIntern(block, name_src, extra.rhs, .{13861 const field_name = try sema.resolveConstStringIntern(block, name_src, extra.rhs, .{
13730 .needed_comptime_reason = "field name must be comptime-known",13862 .needed_comptime_reason = "field name must be comptime-known",
13731 });13863 });
13732 try ty.resolveFields(mod);13864 try ty.resolveFields(pt);
13733 const ip = &mod.intern_pool;13865 const ip = &mod.intern_pool;
1373413866
13735 const has_field = hf: {13867 const has_field = hf: {
...@@ -13764,14 +13896,15 @@ fn zirHasField(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -13764,14 +13896,15 @@ fn zirHasField(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
13764 else => {},13896 else => {},
13765 }13897 }
13766 return sema.fail(block, ty_src, "type '{}' does not support '@hasField'", .{13898 return sema.fail(block, ty_src, "type '{}' does not support '@hasField'", .{
13767 ty.fmt(mod),13899 ty.fmt(pt),
13768 });13900 });
13769 };13901 };
13770 return if (has_field) .bool_true else .bool_false;13902 return if (has_field) .bool_true else .bool_false;
13771}13903}
1377213904
13773fn zirHasDecl(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {13905fn zirHasDecl(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
13774 const mod = sema.mod;13906 const pt = sema.pt;
13907 const mod = pt.zcu;
13775 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;13908 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
13776 const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data;13909 const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data;
13777 const src = block.nodeOffset(inst_data.src_node);13910 const src = block.nodeOffset(inst_data.src_node);
...@@ -13804,7 +13937,8 @@ fn zirImport(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air....@@ -13804,7 +13937,8 @@ fn zirImport(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.
13804 const tracy = trace(@src());13937 const tracy = trace(@src());
13805 defer tracy.end();13938 defer tracy.end();
1380613939
13807 const zcu = sema.mod;13940 const pt = sema.pt;
13941 const zcu = pt.zcu;
13808 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].str_tok;13942 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].str_tok;
13809 const operand_src = block.tokenOffset(inst_data.src_tok);13943 const operand_src = block.tokenOffset(inst_data.src_tok);
13810 const operand = inst_data.get(sema.code);13944 const operand = inst_data.get(sema.code);
...@@ -13824,7 +13958,7 @@ fn zirImport(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air....@@ -13824,7 +13958,7 @@ fn zirImport(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.
13824 return sema.fail(block, operand_src, "unable to open '{s}': {s}", .{ operand, @errorName(err) });13958 return sema.fail(block, operand_src, "unable to open '{s}': {s}", .{ operand, @errorName(err) });
13825 },13959 },
13826 };13960 };
13827 try zcu.ensureFileAnalyzed(result.file_index);13961 try pt.ensureFileAnalyzed(result.file_index);
13828 const file_root_decl_index = zcu.fileRootDecl(result.file_index).unwrap().?;13962 const file_root_decl_index = zcu.fileRootDecl(result.file_index).unwrap().?;
13829 return sema.analyzeDeclVal(block, operand_src, file_root_decl_index);13963 return sema.analyzeDeclVal(block, operand_src, file_root_decl_index);
13830}13964}
...@@ -13833,7 +13967,7 @@ fn zirEmbedFile(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A...@@ -13833,7 +13967,7 @@ fn zirEmbedFile(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
13833 const tracy = trace(@src());13967 const tracy = trace(@src());
13834 defer tracy.end();13968 defer tracy.end();
1383513969
13836 const mod = sema.mod;13970 const pt = sema.pt;
13837 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;13971 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;
13838 const operand_src = block.builtinCallArgSrc(inst_data.src_node, 0);13972 const operand_src = block.builtinCallArgSrc(inst_data.src_node, 0);
13839 const name = try sema.resolveConstString(block, operand_src, inst_data.operand, .{13973 const name = try sema.resolveConstString(block, operand_src, inst_data.operand, .{
...@@ -13844,7 +13978,7 @@ fn zirEmbedFile(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A...@@ -13844,7 +13978,7 @@ fn zirEmbedFile(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
13844 return sema.fail(block, operand_src, "file path name cannot be empty", .{});13978 return sema.fail(block, operand_src, "file path name cannot be empty", .{});
13845 }13979 }
1384613980
13847 const val = mod.embedFile(block.getFileScope(mod), name, operand_src) catch |err| switch (err) {13981 const val = pt.embedFile(block.getFileScope(pt.zcu), name, operand_src) catch |err| switch (err) {
13848 error.ImportOutsideModulePath => {13982 error.ImportOutsideModulePath => {
13849 return sema.fail(block, operand_src, "embed of file outside package path: '{s}'", .{name});13983 return sema.fail(block, operand_src, "embed of file outside package path: '{s}'", .{name});
13850 },13984 },
...@@ -13859,16 +13993,18 @@ fn zirEmbedFile(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A...@@ -13859,16 +13993,18 @@ fn zirEmbedFile(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
13859}13993}
1386013994
13861fn zirRetErrValueCode(sema: *Sema, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {13995fn zirRetErrValueCode(sema: *Sema, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
13862 const mod = sema.mod;13996 const pt = sema.pt;
13997 const mod = pt.zcu;
13863 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].str_tok;13998 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].str_tok;
13864 const name = try mod.intern_pool.getOrPutString(13999 const name = try mod.intern_pool.getOrPutString(
13865 sema.gpa,14000 sema.gpa,
14001 pt.tid,
13866 inst_data.get(sema.code),14002 inst_data.get(sema.code),
13867 .no_embedded_nulls,14003 .no_embedded_nulls,
13868 );14004 );
13869 _ = try mod.getErrorValue(name);14005 _ = try mod.getErrorValue(name);
13870 const error_set_type = try mod.singleErrorSetType(name);14006 const error_set_type = try pt.singleErrorSetType(name);
13871 return Air.internedToRef((try mod.intern(.{ .err = .{14007 return Air.internedToRef((try pt.intern(.{ .err = .{
13872 .ty = error_set_type.toIntern(),14008 .ty = error_set_type.toIntern(),
13873 .name = name,14009 .name = name,
13874 } })));14010 } })));
...@@ -13883,7 +14019,8 @@ fn zirShl(...@@ -13883,7 +14019,8 @@ fn zirShl(
13883 const tracy = trace(@src());14019 const tracy = trace(@src());
13884 defer tracy.end();14020 defer tracy.end();
1388514021
13886 const mod = sema.mod;14022 const pt = sema.pt;
14023 const mod = pt.zcu;
13887 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;14024 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
13888 const src = block.nodeOffset(inst_data.src_node);14025 const src = block.nodeOffset(inst_data.src_node);
13889 const lhs_src = block.src(.{ .node_offset_bin_lhs = inst_data.src_node });14026 const lhs_src = block.src(.{ .node_offset_bin_lhs = inst_data.src_node });
...@@ -13906,53 +14043,53 @@ fn zirShl(...@@ -13906,53 +14043,53 @@ fn zirShl(
1390614043
13907 if (maybe_rhs_val) |rhs_val| {14044 if (maybe_rhs_val) |rhs_val| {
13908 if (rhs_val.isUndef(mod)) {14045 if (rhs_val.isUndef(mod)) {
13909 return mod.undefRef(sema.typeOf(lhs));14046 return pt.undefRef(sema.typeOf(lhs));
13910 }14047 }
13911 // If rhs is 0, return lhs without doing any calculations.14048 // If rhs is 0, return lhs without doing any calculations.
13912 if (try rhs_val.compareAllWithZeroSema(.eq, mod)) {14049 if (try rhs_val.compareAllWithZeroSema(.eq, pt)) {
13913 return lhs;14050 return lhs;
13914 }14051 }
13915 if (scalar_ty.zigTypeTag(mod) != .ComptimeInt and air_tag != .shl_sat) {14052 if (scalar_ty.zigTypeTag(mod) != .ComptimeInt and air_tag != .shl_sat) {
13916 const bit_value = try mod.intValue(Type.comptime_int, scalar_ty.intInfo(mod).bits);14053 const bit_value = try pt.intValue(Type.comptime_int, scalar_ty.intInfo(mod).bits);
13917 if (rhs_ty.zigTypeTag(mod) == .Vector) {14054 if (rhs_ty.zigTypeTag(mod) == .Vector) {
13918 var i: usize = 0;14055 var i: usize = 0;
13919 while (i < rhs_ty.vectorLen(mod)) : (i += 1) {14056 while (i < rhs_ty.vectorLen(mod)) : (i += 1) {
13920 const rhs_elem = try rhs_val.elemValue(mod, i);14057 const rhs_elem = try rhs_val.elemValue(pt, i);
13921 if (rhs_elem.compareHetero(.gte, bit_value, mod)) {14058 if (rhs_elem.compareHetero(.gte, bit_value, pt)) {
13922 return sema.fail(block, rhs_src, "shift amount '{}' at index '{d}' is too large for operand type '{}'", .{14059 return sema.fail(block, rhs_src, "shift amount '{}' at index '{d}' is too large for operand type '{}'", .{
13923 rhs_elem.fmtValue(mod, sema),14060 rhs_elem.fmtValue(pt, sema),
13924 i,14061 i,
13925 scalar_ty.fmt(mod),14062 scalar_ty.fmt(pt),
13926 });14063 });
13927 }14064 }
13928 }14065 }
13929 } else if (rhs_val.compareHetero(.gte, bit_value, mod)) {14066 } else if (rhs_val.compareHetero(.gte, bit_value, pt)) {
13930 return sema.fail(block, rhs_src, "shift amount '{}' is too large for operand type '{}'", .{14067 return sema.fail(block, rhs_src, "shift amount '{}' is too large for operand type '{}'", .{
13931 rhs_val.fmtValue(mod, sema),14068 rhs_val.fmtValue(pt, sema),
13932 scalar_ty.fmt(mod),14069 scalar_ty.fmt(pt),
13933 });14070 });
13934 }14071 }
13935 }14072 }
13936 if (rhs_ty.zigTypeTag(mod) == .Vector) {14073 if (rhs_ty.zigTypeTag(mod) == .Vector) {
13937 var i: usize = 0;14074 var i: usize = 0;
13938 while (i < rhs_ty.vectorLen(mod)) : (i += 1) {14075 while (i < rhs_ty.vectorLen(mod)) : (i += 1) {
13939 const rhs_elem = try rhs_val.elemValue(mod, i);14076 const rhs_elem = try rhs_val.elemValue(pt, i);
13940 if (rhs_elem.compareHetero(.lt, try mod.intValue(scalar_rhs_ty, 0), mod)) {14077 if (rhs_elem.compareHetero(.lt, try pt.intValue(scalar_rhs_ty, 0), pt)) {
13941 return sema.fail(block, rhs_src, "shift by negative amount '{}' at index '{d}'", .{14078 return sema.fail(block, rhs_src, "shift by negative amount '{}' at index '{d}'", .{
13942 rhs_elem.fmtValue(mod, sema),14079 rhs_elem.fmtValue(pt, sema),
13943 i,14080 i,
13944 });14081 });
13945 }14082 }
13946 }14083 }
13947 } else if (rhs_val.compareHetero(.lt, try mod.intValue(rhs_ty, 0), mod)) {14084 } else if (rhs_val.compareHetero(.lt, try pt.intValue(rhs_ty, 0), pt)) {
13948 return sema.fail(block, rhs_src, "shift by negative amount '{}'", .{14085 return sema.fail(block, rhs_src, "shift by negative amount '{}'", .{
13949 rhs_val.fmtValue(mod, sema),14086 rhs_val.fmtValue(pt, sema),
13950 });14087 });
13951 }14088 }
13952 }14089 }
1395314090
13954 const runtime_src = if (maybe_lhs_val) |lhs_val| rs: {14091 const runtime_src = if (maybe_lhs_val) |lhs_val| rs: {
13955 if (lhs_val.isUndef(mod)) return mod.undefRef(lhs_ty);14092 if (lhs_val.isUndef(mod)) return pt.undefRef(lhs_ty);
13956 const rhs_val = maybe_rhs_val orelse {14093 const rhs_val = maybe_rhs_val orelse {
13957 if (scalar_ty.zigTypeTag(mod) == .ComptimeInt) {14094 if (scalar_ty.zigTypeTag(mod) == .ComptimeInt) {
13958 return sema.fail(block, src, "LHS of shift must be a fixed-width integer type, or RHS must be comptime-known", .{});14095 return sema.fail(block, src, "LHS of shift must be a fixed-width integer type, or RHS must be comptime-known", .{});
...@@ -13960,17 +14097,17 @@ fn zirShl(...@@ -13960,17 +14097,17 @@ fn zirShl(
13960 break :rs rhs_src;14097 break :rs rhs_src;
13961 };14098 };
13962 const val = if (scalar_ty.zigTypeTag(mod) == .ComptimeInt)14099 const val = if (scalar_ty.zigTypeTag(mod) == .ComptimeInt)
13963 try lhs_val.shl(rhs_val, lhs_ty, sema.arena, mod)14100 try lhs_val.shl(rhs_val, lhs_ty, sema.arena, pt)
13964 else switch (air_tag) {14101 else switch (air_tag) {
13965 .shl_exact => val: {14102 .shl_exact => val: {
13966 const shifted = try lhs_val.shlWithOverflow(rhs_val, lhs_ty, sema.arena, mod);14103 const shifted = try lhs_val.shlWithOverflow(rhs_val, lhs_ty, sema.arena, pt);
13967 if (shifted.overflow_bit.compareAllWithZero(.eq, mod)) {14104 if (shifted.overflow_bit.compareAllWithZero(.eq, pt)) {
13968 break :val shifted.wrapped_result;14105 break :val shifted.wrapped_result;
13969 }14106 }
13970 return sema.fail(block, src, "operation caused overflow", .{});14107 return sema.fail(block, src, "operation caused overflow", .{});
13971 },14108 },
13972 .shl_sat => try lhs_val.shlSat(rhs_val, lhs_ty, sema.arena, mod),14109 .shl_sat => try lhs_val.shlSat(rhs_val, lhs_ty, sema.arena, pt),
13973 .shl => try lhs_val.shlTrunc(rhs_val, lhs_ty, sema.arena, mod),14110 .shl => try lhs_val.shlTrunc(rhs_val, lhs_ty, sema.arena, pt),
13974 else => unreachable,14111 else => unreachable,
13975 };14112 };
13976 return Air.internedToRef(val.toIntern());14113 return Air.internedToRef(val.toIntern());
...@@ -13981,7 +14118,7 @@ fn zirShl(...@@ -13981,7 +14118,7 @@ fn zirShl(
13981 if (rhs_is_comptime_int or14118 if (rhs_is_comptime_int or
13982 scalar_rhs_ty.intInfo(mod).bits > scalar_ty.intInfo(mod).bits)14119 scalar_rhs_ty.intInfo(mod).bits > scalar_ty.intInfo(mod).bits)
13983 {14120 {
13984 const max_int = Air.internedToRef((try lhs_ty.maxInt(mod, lhs_ty)).toIntern());14121 const max_int = Air.internedToRef((try lhs_ty.maxInt(pt, lhs_ty)).toIntern());
13985 const rhs_limited = try sema.analyzeMinMax(block, rhs_src, .min, &.{ rhs, max_int }, &.{ rhs_src, rhs_src });14122 const rhs_limited = try sema.analyzeMinMax(block, rhs_src, .min, &.{ rhs, max_int }, &.{ rhs_src, rhs_src });
13986 break :rhs try sema.intCast(block, src, lhs_ty, rhs_src, rhs_limited, rhs_src, false);14123 break :rhs try sema.intCast(block, src, lhs_ty, rhs_src, rhs_limited, rhs_src, false);
13987 } else {14124 } else {
...@@ -13993,7 +14130,7 @@ fn zirShl(...@@ -13993,7 +14130,7 @@ fn zirShl(
13993 if (block.wantSafety()) {14130 if (block.wantSafety()) {
13994 const bit_count = scalar_ty.intInfo(mod).bits;14131 const bit_count = scalar_ty.intInfo(mod).bits;
13995 if (!std.math.isPowerOfTwo(bit_count)) {14132 if (!std.math.isPowerOfTwo(bit_count)) {
13996 const bit_count_val = try mod.intValue(scalar_rhs_ty, bit_count);14133 const bit_count_val = try pt.intValue(scalar_rhs_ty, bit_count);
13997 const ok = if (rhs_ty.zigTypeTag(mod) == .Vector) ok: {14134 const ok = if (rhs_ty.zigTypeTag(mod) == .Vector) ok: {
13998 const bit_count_inst = Air.internedToRef((try sema.splat(rhs_ty, bit_count_val)).toIntern());14135 const bit_count_inst = Air.internedToRef((try sema.splat(rhs_ty, bit_count_val)).toIntern());
13999 const lt = try block.addCmpVector(rhs, bit_count_inst, .lt);14136 const lt = try block.addCmpVector(rhs, bit_count_inst, .lt);
...@@ -14034,7 +14171,7 @@ fn zirShl(...@@ -14034,7 +14171,7 @@ fn zirShl(
14034 })14171 })
14035 else14172 else
14036 ov_bit;14173 ov_bit;
14037 const zero_ov = Air.internedToRef((try mod.intValue(Type.u1, 0)).toIntern());14174 const zero_ov = Air.internedToRef((try pt.intValue(Type.u1, 0)).toIntern());
14038 const no_ov = try block.addBinOp(.cmp_eq, any_ov_bit, zero_ov);14175 const no_ov = try block.addBinOp(.cmp_eq, any_ov_bit, zero_ov);
1403914176
14040 try sema.addSafetyCheck(block, src, no_ov, .shl_overflow);14177 try sema.addSafetyCheck(block, src, no_ov, .shl_overflow);
...@@ -14053,7 +14190,8 @@ fn zirShr(...@@ -14053,7 +14190,8 @@ fn zirShr(
14053 const tracy = trace(@src());14190 const tracy = trace(@src());
14054 defer tracy.end();14191 defer tracy.end();
1405514192
14056 const mod = sema.mod;14193 const pt = sema.pt;
14194 const mod = pt.zcu;
14057 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;14195 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
14058 const src = block.nodeOffset(inst_data.src_node);14196 const src = block.nodeOffset(inst_data.src_node);
14059 const lhs_src = block.src(.{ .node_offset_bin_lhs = inst_data.src_node });14197 const lhs_src = block.src(.{ .node_offset_bin_lhs = inst_data.src_node });
...@@ -14071,61 +14209,61 @@ fn zirShr(...@@ -14071,61 +14209,61 @@ fn zirShr(
1407114209
14072 const runtime_src = if (maybe_rhs_val) |rhs_val| rs: {14210 const runtime_src = if (maybe_rhs_val) |rhs_val| rs: {
14073 if (rhs_val.isUndef(mod)) {14211 if (rhs_val.isUndef(mod)) {
14074 return mod.undefRef(lhs_ty);14212 return pt.undefRef(lhs_ty);
14075 }14213 }
14076 // If rhs is 0, return lhs without doing any calculations.14214 // If rhs is 0, return lhs without doing any calculations.
14077 if (try rhs_val.compareAllWithZeroSema(.eq, mod)) {14215 if (try rhs_val.compareAllWithZeroSema(.eq, pt)) {
14078 return lhs;14216 return lhs;
14079 }14217 }
14080 if (scalar_ty.zigTypeTag(mod) != .ComptimeInt) {14218 if (scalar_ty.zigTypeTag(mod) != .ComptimeInt) {
14081 const bit_value = try mod.intValue(Type.comptime_int, scalar_ty.intInfo(mod).bits);14219 const bit_value = try pt.intValue(Type.comptime_int, scalar_ty.intInfo(mod).bits);
14082 if (rhs_ty.zigTypeTag(mod) == .Vector) {14220 if (rhs_ty.zigTypeTag(mod) == .Vector) {
14083 var i: usize = 0;14221 var i: usize = 0;
14084 while (i < rhs_ty.vectorLen(mod)) : (i += 1) {14222 while (i < rhs_ty.vectorLen(mod)) : (i += 1) {
14085 const rhs_elem = try rhs_val.elemValue(mod, i);14223 const rhs_elem = try rhs_val.elemValue(pt, i);
14086 if (rhs_elem.compareHetero(.gte, bit_value, mod)) {14224 if (rhs_elem.compareHetero(.gte, bit_value, pt)) {
14087 return sema.fail(block, rhs_src, "shift amount '{}' at index '{d}' is too large for operand type '{}'", .{14225 return sema.fail(block, rhs_src, "shift amount '{}' at index '{d}' is too large for operand type '{}'", .{
14088 rhs_elem.fmtValue(mod, sema),14226 rhs_elem.fmtValue(pt, sema),
14089 i,14227 i,
14090 scalar_ty.fmt(mod),14228 scalar_ty.fmt(pt),
14091 });14229 });
14092 }14230 }
14093 }14231 }
14094 } else if (rhs_val.compareHetero(.gte, bit_value, mod)) {14232 } else if (rhs_val.compareHetero(.gte, bit_value, pt)) {
14095 return sema.fail(block, rhs_src, "shift amount '{}' is too large for operand type '{}'", .{14233 return sema.fail(block, rhs_src, "shift amount '{}' is too large for operand type '{}'", .{
14096 rhs_val.fmtValue(mod, sema),14234 rhs_val.fmtValue(pt, sema),
14097 scalar_ty.fmt(mod),14235 scalar_ty.fmt(pt),
14098 });14236 });
14099 }14237 }
14100 }14238 }
14101 if (rhs_ty.zigTypeTag(mod) == .Vector) {14239 if (rhs_ty.zigTypeTag(mod) == .Vector) {
14102 var i: usize = 0;14240 var i: usize = 0;
14103 while (i < rhs_ty.vectorLen(mod)) : (i += 1) {14241 while (i < rhs_ty.vectorLen(mod)) : (i += 1) {
14104 const rhs_elem = try rhs_val.elemValue(mod, i);14242 const rhs_elem = try rhs_val.elemValue(pt, i);
14105 if (rhs_elem.compareHetero(.lt, try mod.intValue(rhs_ty.childType(mod), 0), mod)) {14243 if (rhs_elem.compareHetero(.lt, try pt.intValue(rhs_ty.childType(mod), 0), pt)) {
14106 return sema.fail(block, rhs_src, "shift by negative amount '{}' at index '{d}'", .{14244 return sema.fail(block, rhs_src, "shift by negative amount '{}' at index '{d}'", .{
14107 rhs_elem.fmtValue(mod, sema),14245 rhs_elem.fmtValue(pt, sema),
14108 i,14246 i,
14109 });14247 });
14110 }14248 }
14111 }14249 }
14112 } else if (rhs_val.compareHetero(.lt, try mod.intValue(rhs_ty, 0), mod)) {14250 } else if (rhs_val.compareHetero(.lt, try pt.intValue(rhs_ty, 0), pt)) {
14113 return sema.fail(block, rhs_src, "shift by negative amount '{}'", .{14251 return sema.fail(block, rhs_src, "shift by negative amount '{}'", .{
14114 rhs_val.fmtValue(mod, sema),14252 rhs_val.fmtValue(pt, sema),
14115 });14253 });
14116 }14254 }
14117 if (maybe_lhs_val) |lhs_val| {14255 if (maybe_lhs_val) |lhs_val| {
14118 if (lhs_val.isUndef(mod)) {14256 if (lhs_val.isUndef(mod)) {
14119 return mod.undefRef(lhs_ty);14257 return pt.undefRef(lhs_ty);
14120 }14258 }
14121 if (air_tag == .shr_exact) {14259 if (air_tag == .shr_exact) {
14122 // Detect if any ones would be shifted out.14260 // Detect if any ones would be shifted out.
14123 const truncated = try lhs_val.intTruncBitsAsValue(lhs_ty, sema.arena, .unsigned, rhs_val, mod);14261 const truncated = try lhs_val.intTruncBitsAsValue(lhs_ty, sema.arena, .unsigned, rhs_val, pt);
14124 if (!(try truncated.compareAllWithZeroSema(.eq, mod))) {14262 if (!(try truncated.compareAllWithZeroSema(.eq, pt))) {
14125 return sema.fail(block, src, "exact shift shifted out 1 bits", .{});14263 return sema.fail(block, src, "exact shift shifted out 1 bits", .{});
14126 }14264 }
14127 }14265 }
14128 const val = try lhs_val.shr(rhs_val, lhs_ty, sema.arena, mod);14266 const val = try lhs_val.shr(rhs_val, lhs_ty, sema.arena, pt);
14129 return Air.internedToRef(val.toIntern());14267 return Air.internedToRef(val.toIntern());
14130 } else {14268 } else {
14131 break :rs lhs_src;14269 break :rs lhs_src;
...@@ -14141,7 +14279,7 @@ fn zirShr(...@@ -14141,7 +14279,7 @@ fn zirShr(
14141 if (block.wantSafety()) {14279 if (block.wantSafety()) {
14142 const bit_count = scalar_ty.intInfo(mod).bits;14280 const bit_count = scalar_ty.intInfo(mod).bits;
14143 if (!std.math.isPowerOfTwo(bit_count)) {14281 if (!std.math.isPowerOfTwo(bit_count)) {
14144 const bit_count_val = try mod.intValue(rhs_ty.scalarType(mod), bit_count);14282 const bit_count_val = try pt.intValue(rhs_ty.scalarType(mod), bit_count);
1414514283
14146 const ok = if (rhs_ty.zigTypeTag(mod) == .Vector) ok: {14284 const ok = if (rhs_ty.zigTypeTag(mod) == .Vector) ok: {
14147 const bit_count_inst = Air.internedToRef((try sema.splat(rhs_ty, bit_count_val)).toIntern());14285 const bit_count_inst = Air.internedToRef((try sema.splat(rhs_ty, bit_count_val)).toIntern());
...@@ -14188,7 +14326,8 @@ fn zirBitwise(...@@ -14188,7 +14326,8 @@ fn zirBitwise(
14188 const tracy = trace(@src());14326 const tracy = trace(@src());
14189 defer tracy.end();14327 defer tracy.end();
1419014328
14191 const mod = sema.mod;14329 const pt = sema.pt;
14330 const mod = pt.zcu;
14192 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;14331 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
14193 const src = block.src(.{ .node_offset_bin_op = inst_data.src_node });14332 const src = block.src(.{ .node_offset_bin_op = inst_data.src_node });
14194 const lhs_src = block.src(.{ .node_offset_bin_lhs = inst_data.src_node });14333 const lhs_src = block.src(.{ .node_offset_bin_lhs = inst_data.src_node });
...@@ -14220,9 +14359,9 @@ fn zirBitwise(...@@ -14220,9 +14359,9 @@ fn zirBitwise(
14220 if (try sema.resolveValueIntable(casted_lhs)) |lhs_val| {14359 if (try sema.resolveValueIntable(casted_lhs)) |lhs_val| {
14221 if (try sema.resolveValueIntable(casted_rhs)) |rhs_val| {14360 if (try sema.resolveValueIntable(casted_rhs)) |rhs_val| {
14222 const result_val = switch (air_tag) {14361 const result_val = switch (air_tag) {
14223 .bit_and => try lhs_val.bitwiseAnd(rhs_val, resolved_type, sema.arena, mod),14362 .bit_and => try lhs_val.bitwiseAnd(rhs_val, resolved_type, sema.arena, pt),
14224 .bit_or => try lhs_val.bitwiseOr(rhs_val, resolved_type, sema.arena, mod),14363 .bit_or => try lhs_val.bitwiseOr(rhs_val, resolved_type, sema.arena, pt),
14225 .xor => try lhs_val.bitwiseXor(rhs_val, resolved_type, sema.arena, mod),14364 .xor => try lhs_val.bitwiseXor(rhs_val, resolved_type, sema.arena, pt),
14226 else => unreachable,14365 else => unreachable,
14227 };14366 };
14228 return Air.internedToRef(result_val.toIntern());14367 return Air.internedToRef(result_val.toIntern());
...@@ -14242,7 +14381,8 @@ fn zirBitNot(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air....@@ -14242,7 +14381,8 @@ fn zirBitNot(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.
14242 const tracy = trace(@src());14381 const tracy = trace(@src());
14243 defer tracy.end();14382 defer tracy.end();
1424414383
14245 const mod = sema.mod;14384 const pt = sema.pt;
14385 const mod = pt.zcu;
14246 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;14386 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;
14247 const src = block.nodeOffset(inst_data.src_node);14387 const src = block.nodeOffset(inst_data.src_node);
14248 const operand_src = block.src(.{ .node_offset_un_op = inst_data.src_node });14388 const operand_src = block.src(.{ .node_offset_un_op = inst_data.src_node });
...@@ -14253,26 +14393,26 @@ fn zirBitNot(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air....@@ -14253,26 +14393,26 @@ fn zirBitNot(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.
1425314393
14254 if (scalar_type.zigTypeTag(mod) != .Int) {14394 if (scalar_type.zigTypeTag(mod) != .Int) {
14255 return sema.fail(block, src, "unable to perform binary not operation on type '{}'", .{14395 return sema.fail(block, src, "unable to perform binary not operation on type '{}'", .{
14256 operand_type.fmt(mod),14396 operand_type.fmt(pt),
14257 });14397 });
14258 }14398 }
1425914399
14260 if (try sema.resolveValue(operand)) |val| {14400 if (try sema.resolveValue(operand)) |val| {
14261 if (val.isUndef(mod)) {14401 if (val.isUndef(mod)) {
14262 return mod.undefRef(operand_type);14402 return pt.undefRef(operand_type);
14263 } else if (operand_type.zigTypeTag(mod) == .Vector) {14403 } else if (operand_type.zigTypeTag(mod) == .Vector) {
14264 const vec_len = try sema.usizeCast(block, operand_src, operand_type.vectorLen(mod));14404 const vec_len = try sema.usizeCast(block, operand_src, operand_type.vectorLen(mod));
14265 const elems = try sema.arena.alloc(InternPool.Index, vec_len);14405 const elems = try sema.arena.alloc(InternPool.Index, vec_len);
14266 for (elems, 0..) |*elem, i| {14406 for (elems, 0..) |*elem, i| {
14267 const elem_val = try val.elemValue(mod, i);14407 const elem_val = try val.elemValue(pt, i);
14268 elem.* = (try elem_val.bitwiseNot(scalar_type, sema.arena, mod)).toIntern();14408 elem.* = (try elem_val.bitwiseNot(scalar_type, sema.arena, pt)).toIntern();
14269 }14409 }
14270 return Air.internedToRef((try mod.intern(.{ .aggregate = .{14410 return Air.internedToRef((try pt.intern(.{ .aggregate = .{
14271 .ty = operand_type.toIntern(),14411 .ty = operand_type.toIntern(),
14272 .storage = .{ .elems = elems },14412 .storage = .{ .elems = elems },
14273 } })));14413 } })));
14274 } else {14414 } else {
14275 const result_val = try val.bitwiseNot(operand_type, sema.arena, mod);14415 const result_val = try val.bitwiseNot(operand_type, sema.arena, pt);
14276 return Air.internedToRef(result_val.toIntern());14416 return Air.internedToRef(result_val.toIntern());
14277 }14417 }
14278 }14418 }
...@@ -14288,7 +14428,8 @@ fn analyzeTupleCat(...@@ -14288,7 +14428,8 @@ fn analyzeTupleCat(
14288 lhs: Air.Inst.Ref,14428 lhs: Air.Inst.Ref,
14289 rhs: Air.Inst.Ref,14429 rhs: Air.Inst.Ref,
14290) CompileError!Air.Inst.Ref {14430) CompileError!Air.Inst.Ref {
14291 const mod = sema.mod;14431 const pt = sema.pt;
14432 const mod = pt.zcu;
14292 const lhs_ty = sema.typeOf(lhs);14433 const lhs_ty = sema.typeOf(lhs);
14293 const rhs_ty = sema.typeOf(rhs);14434 const rhs_ty = sema.typeOf(rhs);
14294 const src = block.nodeOffset(src_node);14435 const src = block.nodeOffset(src_node);
...@@ -14344,14 +14485,14 @@ fn analyzeTupleCat(...@@ -14344,14 +14485,14 @@ fn analyzeTupleCat(
14344 break :rs runtime_src;14485 break :rs runtime_src;
14345 };14486 };
1434614487
14347 const tuple_ty = try mod.intern_pool.getAnonStructType(mod.gpa, .{14488 const tuple_ty = try mod.intern_pool.getAnonStructType(mod.gpa, pt.tid, .{
14348 .types = types,14489 .types = types,
14349 .values = values,14490 .values = values,
14350 .names = &.{},14491 .names = &.{},
14351 });14492 });
1435214493
14353 const runtime_src = opt_runtime_src orelse {14494 const runtime_src = opt_runtime_src orelse {
14354 const tuple_val = try mod.intern(.{ .aggregate = .{14495 const tuple_val = try pt.intern(.{ .aggregate = .{
14355 .ty = tuple_ty,14496 .ty = tuple_ty,
14356 .storage = .{ .elems = values },14497 .storage = .{ .elems = values },
14357 } });14498 } });
...@@ -14386,7 +14527,8 @@ fn zirArrayCat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -14386,7 +14527,8 @@ fn zirArrayCat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
14386 const tracy = trace(@src());14527 const tracy = trace(@src());
14387 defer tracy.end();14528 defer tracy.end();
1438814529
14389 const mod = sema.mod;14530 const pt = sema.pt;
14531 const mod = pt.zcu;
14390 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;14532 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
14391 const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data;14533 const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data;
14392 const lhs = try sema.resolveInst(extra.lhs);14534 const lhs = try sema.resolveInst(extra.lhs);
...@@ -14406,11 +14548,11 @@ fn zirArrayCat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -14406,11 +14548,11 @@ fn zirArrayCat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1440614548
14407 const lhs_info = try sema.getArrayCatInfo(block, lhs_src, lhs, rhs_ty) orelse lhs_info: {14549 const lhs_info = try sema.getArrayCatInfo(block, lhs_src, lhs, rhs_ty) orelse lhs_info: {
14408 if (lhs_is_tuple) break :lhs_info @as(Type.ArrayInfo, undefined);14550 if (lhs_is_tuple) break :lhs_info @as(Type.ArrayInfo, undefined);
14409 return sema.fail(block, lhs_src, "expected indexable; found '{}'", .{lhs_ty.fmt(mod)});14551 return sema.fail(block, lhs_src, "expected indexable; found '{}'", .{lhs_ty.fmt(pt)});
14410 };14552 };
14411 const rhs_info = try sema.getArrayCatInfo(block, rhs_src, rhs, lhs_ty) orelse {14553 const rhs_info = try sema.getArrayCatInfo(block, rhs_src, rhs, lhs_ty) orelse {
14412 assert(!rhs_is_tuple);14554 assert(!rhs_is_tuple);
14413 return sema.fail(block, rhs_src, "expected indexable; found '{}'", .{rhs_ty.fmt(mod)});14555 return sema.fail(block, rhs_src, "expected indexable; found '{}'", .{rhs_ty.fmt(pt)});
14414 };14556 };
1441514557
14416 const resolved_elem_ty = t: {14558 const resolved_elem_ty = t: {
...@@ -14472,7 +14614,7 @@ fn zirArrayCat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -14472,7 +14614,7 @@ fn zirArrayCat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
14472 ),14614 ),
14473 };14615 };
1447414616
14475 const result_ty = try mod.arrayType(.{14617 const result_ty = try pt.arrayType(.{
14476 .len = result_len,14618 .len = result_len,
14477 .sentinel = if (res_sent_val) |v| v.toIntern() else .none,14619 .sentinel = if (res_sent_val) |v| v.toIntern() else .none,
14478 .child = resolved_elem_ty.toIntern(),14620 .child = resolved_elem_ty.toIntern(),
...@@ -14512,7 +14654,7 @@ fn zirArrayCat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -14512,7 +14654,7 @@ fn zirArrayCat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
14512 while (elem_i < lhs_len) : (elem_i += 1) {14654 while (elem_i < lhs_len) : (elem_i += 1) {
14513 const lhs_elem_i = elem_i;14655 const lhs_elem_i = elem_i;
14514 const elem_default_val = if (lhs_is_tuple) lhs_ty.structFieldDefaultValue(lhs_elem_i, mod) else Value.@"unreachable";14656 const elem_default_val = if (lhs_is_tuple) lhs_ty.structFieldDefaultValue(lhs_elem_i, mod) else Value.@"unreachable";
14515 const elem_val = if (elem_default_val.toIntern() == .unreachable_value) try lhs_sub_val.elemValue(mod, lhs_elem_i) else elem_default_val;14657 const elem_val = if (elem_default_val.toIntern() == .unreachable_value) try lhs_sub_val.elemValue(pt, lhs_elem_i) else elem_default_val;
14516 const elem_val_inst = Air.internedToRef(elem_val.toIntern());14658 const elem_val_inst = Air.internedToRef(elem_val.toIntern());
14517 const operand_src = block.src(.{ .array_cat_lhs = .{14659 const operand_src = block.src(.{ .array_cat_lhs = .{
14518 .array_cat_offset = inst_data.src_node,14660 .array_cat_offset = inst_data.src_node,
...@@ -14525,7 +14667,7 @@ fn zirArrayCat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -14525,7 +14667,7 @@ fn zirArrayCat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
14525 while (elem_i < result_len) : (elem_i += 1) {14667 while (elem_i < result_len) : (elem_i += 1) {
14526 const rhs_elem_i = elem_i - lhs_len;14668 const rhs_elem_i = elem_i - lhs_len;
14527 const elem_default_val = if (rhs_is_tuple) rhs_ty.structFieldDefaultValue(rhs_elem_i, mod) else Value.@"unreachable";14669 const elem_default_val = if (rhs_is_tuple) rhs_ty.structFieldDefaultValue(rhs_elem_i, mod) else Value.@"unreachable";
14528 const elem_val = if (elem_default_val.toIntern() == .unreachable_value) try rhs_sub_val.elemValue(mod, rhs_elem_i) else elem_default_val;14670 const elem_val = if (elem_default_val.toIntern() == .unreachable_value) try rhs_sub_val.elemValue(pt, rhs_elem_i) else elem_default_val;
14529 const elem_val_inst = Air.internedToRef(elem_val.toIntern());14671 const elem_val_inst = Air.internedToRef(elem_val.toIntern());
14530 const operand_src = block.src(.{ .array_cat_rhs = .{14672 const operand_src = block.src(.{ .array_cat_rhs = .{
14531 .array_cat_offset = inst_data.src_node,14673 .array_cat_offset = inst_data.src_node,
...@@ -14535,7 +14677,7 @@ fn zirArrayCat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -14535,7 +14677,7 @@ fn zirArrayCat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
14535 const coerced_elem_val = try sema.resolveConstValue(block, operand_src, coerced_elem_val_inst, undefined);14677 const coerced_elem_val = try sema.resolveConstValue(block, operand_src, coerced_elem_val_inst, undefined);
14536 element_vals[elem_i] = coerced_elem_val.toIntern();14678 element_vals[elem_i] = coerced_elem_val.toIntern();
14537 }14679 }
14538 return sema.addConstantMaybeRef(try mod.intern(.{ .aggregate = .{14680 return sema.addConstantMaybeRef(try pt.intern(.{ .aggregate = .{
14539 .ty = result_ty.toIntern(),14681 .ty = result_ty.toIntern(),
14540 .storage = .{ .elems = element_vals },14682 .storage = .{ .elems = element_vals },
14541 } }), ptr_addrspace != null);14683 } }), ptr_addrspace != null);
...@@ -14545,19 +14687,19 @@ fn zirArrayCat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -14545,19 +14687,19 @@ fn zirArrayCat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
14545 try sema.requireRuntimeBlock(block, src, runtime_src);14687 try sema.requireRuntimeBlock(block, src, runtime_src);
1454614688
14547 if (ptr_addrspace) |ptr_as| {14689 if (ptr_addrspace) |ptr_as| {
14548 const alloc_ty = try mod.ptrTypeSema(.{14690 const alloc_ty = try pt.ptrTypeSema(.{
14549 .child = result_ty.toIntern(),14691 .child = result_ty.toIntern(),
14550 .flags = .{ .address_space = ptr_as },14692 .flags = .{ .address_space = ptr_as },
14551 });14693 });
14552 const alloc = try block.addTy(.alloc, alloc_ty);14694 const alloc = try block.addTy(.alloc, alloc_ty);
14553 const elem_ptr_ty = try mod.ptrTypeSema(.{14695 const elem_ptr_ty = try pt.ptrTypeSema(.{
14554 .child = resolved_elem_ty.toIntern(),14696 .child = resolved_elem_ty.toIntern(),
14555 .flags = .{ .address_space = ptr_as },14697 .flags = .{ .address_space = ptr_as },
14556 });14698 });
1455714699
14558 var elem_i: u32 = 0;14700 var elem_i: u32 = 0;
14559 while (elem_i < lhs_len) : (elem_i += 1) {14701 while (elem_i < lhs_len) : (elem_i += 1) {
14560 const elem_index = try mod.intRef(Type.usize, elem_i);14702 const elem_index = try pt.intRef(Type.usize, elem_i);
14561 const elem_ptr = try block.addPtrElemPtr(alloc, elem_index, elem_ptr_ty);14703 const elem_ptr = try block.addPtrElemPtr(alloc, elem_index, elem_ptr_ty);
14562 const operand_src = block.src(.{ .array_cat_lhs = .{14704 const operand_src = block.src(.{ .array_cat_lhs = .{
14563 .array_cat_offset = inst_data.src_node,14705 .array_cat_offset = inst_data.src_node,
...@@ -14568,8 +14710,8 @@ fn zirArrayCat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -14568,8 +14710,8 @@ fn zirArrayCat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
14568 }14710 }
14569 while (elem_i < result_len) : (elem_i += 1) {14711 while (elem_i < result_len) : (elem_i += 1) {
14570 const rhs_elem_i = elem_i - lhs_len;14712 const rhs_elem_i = elem_i - lhs_len;
14571 const elem_index = try mod.intRef(Type.usize, elem_i);14713 const elem_index = try pt.intRef(Type.usize, elem_i);
14572 const rhs_index = try mod.intRef(Type.usize, rhs_elem_i);14714 const rhs_index = try pt.intRef(Type.usize, rhs_elem_i);
14573 const elem_ptr = try block.addPtrElemPtr(alloc, elem_index, elem_ptr_ty);14715 const elem_ptr = try block.addPtrElemPtr(alloc, elem_index, elem_ptr_ty);
14574 const operand_src = block.src(.{ .array_cat_rhs = .{14716 const operand_src = block.src(.{ .array_cat_rhs = .{
14575 .array_cat_offset = inst_data.src_node,14717 .array_cat_offset = inst_data.src_node,
...@@ -14579,9 +14721,9 @@ fn zirArrayCat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -14579,9 +14721,9 @@ fn zirArrayCat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
14579 try sema.storePtr2(block, src, elem_ptr, src, init, operand_src, .store);14721 try sema.storePtr2(block, src, elem_ptr, src, init, operand_src, .store);
14580 }14722 }
14581 if (res_sent_val) |sent_val| {14723 if (res_sent_val) |sent_val| {
14582 const elem_index = try mod.intRef(Type.usize, result_len);14724 const elem_index = try pt.intRef(Type.usize, result_len);
14583 const elem_ptr = try block.addPtrElemPtr(alloc, elem_index, elem_ptr_ty);14725 const elem_ptr = try block.addPtrElemPtr(alloc, elem_index, elem_ptr_ty);
14584 const init = Air.internedToRef((try mod.getCoerced(sent_val, lhs_info.elem_type)).toIntern());14726 const init = Air.internedToRef((try pt.getCoerced(sent_val, lhs_info.elem_type)).toIntern());
14585 try sema.storePtr2(block, src, elem_ptr, src, init, lhs_src, .store);14727 try sema.storePtr2(block, src, elem_ptr, src, init, lhs_src, .store);
14586 }14728 }
1458714729
...@@ -14592,7 +14734,7 @@ fn zirArrayCat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -14592,7 +14734,7 @@ fn zirArrayCat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
14592 {14734 {
14593 var elem_i: u32 = 0;14735 var elem_i: u32 = 0;
14594 while (elem_i < lhs_len) : (elem_i += 1) {14736 while (elem_i < lhs_len) : (elem_i += 1) {
14595 const index = try mod.intRef(Type.usize, elem_i);14737 const index = try pt.intRef(Type.usize, elem_i);
14596 const operand_src = block.src(.{ .array_cat_lhs = .{14738 const operand_src = block.src(.{ .array_cat_lhs = .{
14597 .array_cat_offset = inst_data.src_node,14739 .array_cat_offset = inst_data.src_node,
14598 .elem_index = elem_i,14740 .elem_index = elem_i,
...@@ -14602,7 +14744,7 @@ fn zirArrayCat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -14602,7 +14744,7 @@ fn zirArrayCat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
14602 }14744 }
14603 while (elem_i < result_len) : (elem_i += 1) {14745 while (elem_i < result_len) : (elem_i += 1) {
14604 const rhs_elem_i = elem_i - lhs_len;14746 const rhs_elem_i = elem_i - lhs_len;
14605 const index = try mod.intRef(Type.usize, rhs_elem_i);14747 const index = try pt.intRef(Type.usize, rhs_elem_i);
14606 const operand_src = block.src(.{ .array_cat_rhs = .{14748 const operand_src = block.src(.{ .array_cat_rhs = .{
14607 .array_cat_offset = inst_data.src_node,14749 .array_cat_offset = inst_data.src_node,
14608 .elem_index = @intCast(rhs_elem_i),14750 .elem_index = @intCast(rhs_elem_i),
...@@ -14616,7 +14758,8 @@ fn zirArrayCat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -14616,7 +14758,8 @@ fn zirArrayCat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
14616}14758}
1461714759
14618fn getArrayCatInfo(sema: *Sema, block: *Block, src: LazySrcLoc, operand: Air.Inst.Ref, peer_ty: Type) !?Type.ArrayInfo {14760fn getArrayCatInfo(sema: *Sema, block: *Block, src: LazySrcLoc, operand: Air.Inst.Ref, peer_ty: Type) !?Type.ArrayInfo {
14619 const mod = sema.mod;14761 const pt = sema.pt;
14762 const mod = pt.zcu;
14620 const operand_ty = sema.typeOf(operand);14763 const operand_ty = sema.typeOf(operand);
14621 switch (operand_ty.zigTypeTag(mod)) {14764 switch (operand_ty.zigTypeTag(mod)) {
14622 .Array => return operand_ty.arrayInfo(mod),14765 .Array => return operand_ty.arrayInfo(mod),
...@@ -14633,7 +14776,7 @@ fn getArrayCatInfo(sema: *Sema, block: *Block, src: LazySrcLoc, operand: Air.Ins...@@ -14633,7 +14776,7 @@ fn getArrayCatInfo(sema: *Sema, block: *Block, src: LazySrcLoc, operand: Air.Ins
14633 .none => null,14776 .none => null,
14634 else => Value.fromInterned(ptr_info.sentinel),14777 else => Value.fromInterned(ptr_info.sentinel),
14635 },14778 },
14636 .len = try val.sliceLen(mod),14779 .len = try val.sliceLen(pt),
14637 };14780 };
14638 },14781 },
14639 .One => {14782 .One => {
...@@ -14666,7 +14809,8 @@ fn analyzeTupleMul(...@@ -14666,7 +14809,8 @@ fn analyzeTupleMul(
14666 operand: Air.Inst.Ref,14809 operand: Air.Inst.Ref,
14667 factor: usize,14810 factor: usize,
14668) CompileError!Air.Inst.Ref {14811) CompileError!Air.Inst.Ref {
14669 const mod = sema.mod;14812 const pt = sema.pt;
14813 const mod = pt.zcu;
14670 const operand_ty = sema.typeOf(operand);14814 const operand_ty = sema.typeOf(operand);
14671 const src = block.nodeOffset(src_node);14815 const src = block.nodeOffset(src_node);
14672 const len_src = block.src(.{ .node_offset_bin_rhs = src_node });14816 const len_src = block.src(.{ .node_offset_bin_rhs = src_node });
...@@ -14702,14 +14846,14 @@ fn analyzeTupleMul(...@@ -14702,14 +14846,14 @@ fn analyzeTupleMul(
14702 break :rs runtime_src;14846 break :rs runtime_src;
14703 };14847 };
1470414848
14705 const tuple_ty = try mod.intern_pool.getAnonStructType(mod.gpa, .{14849 const tuple_ty = try mod.intern_pool.getAnonStructType(mod.gpa, pt.tid, .{
14706 .types = types,14850 .types = types,
14707 .values = values,14851 .values = values,
14708 .names = &.{},14852 .names = &.{},
14709 });14853 });
1471014854
14711 const runtime_src = opt_runtime_src orelse {14855 const runtime_src = opt_runtime_src orelse {
14712 const tuple_val = try mod.intern(.{ .aggregate = .{14856 const tuple_val = try pt.intern(.{ .aggregate = .{
14713 .ty = tuple_ty,14857 .ty = tuple_ty,
14714 .storage = .{ .elems = values },14858 .storage = .{ .elems = values },
14715 } });14859 } });
...@@ -14739,7 +14883,8 @@ fn zirArrayMul(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -14739,7 +14883,8 @@ fn zirArrayMul(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
14739 const tracy = trace(@src());14883 const tracy = trace(@src());
14740 defer tracy.end();14884 defer tracy.end();
1474114885
14742 const mod = sema.mod;14886 const pt = sema.pt;
14887 const mod = pt.zcu;
14743 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;14888 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
14744 const extra = sema.code.extraData(Zir.Inst.ArrayMul, inst_data.payload_index).data;14889 const extra = sema.code.extraData(Zir.Inst.ArrayMul, inst_data.payload_index).data;
14745 const uncoerced_lhs = try sema.resolveInst(extra.lhs);14890 const uncoerced_lhs = try sema.resolveInst(extra.lhs);
...@@ -14762,12 +14907,12 @@ fn zirArrayMul(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -14762,12 +14907,12 @@ fn zirArrayMul(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
14762 const lhs_len = uncoerced_lhs_ty.structFieldCount(mod);14907 const lhs_len = uncoerced_lhs_ty.structFieldCount(mod);
14763 const lhs_dest_ty = switch (res_ty.zigTypeTag(mod)) {14908 const lhs_dest_ty = switch (res_ty.zigTypeTag(mod)) {
14764 else => break :no_coerce,14909 else => break :no_coerce,
14765 .Array => try mod.arrayType(.{14910 .Array => try pt.arrayType(.{
14766 .child = res_ty.childType(mod).toIntern(),14911 .child = res_ty.childType(mod).toIntern(),
14767 .len = lhs_len,14912 .len = lhs_len,
14768 .sentinel = if (res_ty.sentinel(mod)) |s| s.toIntern() else .none,14913 .sentinel = if (res_ty.sentinel(mod)) |s| s.toIntern() else .none,
14769 }),14914 }),
14770 .Vector => try mod.vectorType(.{14915 .Vector => try pt.vectorType(.{
14771 .child = res_ty.childType(mod).toIntern(),14916 .child = res_ty.childType(mod).toIntern(),
14772 .len = lhs_len,14917 .len = lhs_len,
14773 }),14918 }),
...@@ -14796,7 +14941,7 @@ fn zirArrayMul(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -14796,7 +14941,7 @@ fn zirArrayMul(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
14796 // Analyze the lhs first, to catch the case that someone tried to do exponentiation14941 // Analyze the lhs first, to catch the case that someone tried to do exponentiation
14797 const lhs_info = try sema.getArrayCatInfo(block, lhs_src, lhs, lhs_ty) orelse {14942 const lhs_info = try sema.getArrayCatInfo(block, lhs_src, lhs, lhs_ty) orelse {
14798 const msg = msg: {14943 const msg = msg: {
14799 const msg = try sema.errMsg(lhs_src, "expected indexable; found '{}'", .{lhs_ty.fmt(mod)});14944 const msg = try sema.errMsg(lhs_src, "expected indexable; found '{}'", .{lhs_ty.fmt(pt)});
14800 errdefer msg.destroy(sema.gpa);14945 errdefer msg.destroy(sema.gpa);
14801 switch (lhs_ty.zigTypeTag(mod)) {14946 switch (lhs_ty.zigTypeTag(mod)) {
14802 .Int, .Float, .ComptimeFloat, .ComptimeInt, .Vector => {14947 .Int, .Float, .ComptimeFloat, .ComptimeInt, .Vector => {
...@@ -14818,7 +14963,7 @@ fn zirArrayMul(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -14818,7 +14963,7 @@ fn zirArrayMul(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
14818 return sema.fail(block, rhs_src, "operation results in overflow", .{});14963 return sema.fail(block, rhs_src, "operation results in overflow", .{});
14819 const result_len = try sema.usizeCast(block, src, result_len_u64);14964 const result_len = try sema.usizeCast(block, src, result_len_u64);
1482014965
14821 const result_ty = try mod.arrayType(.{14966 const result_ty = try pt.arrayType(.{
14822 .len = result_len,14967 .len = result_len,
14823 .sentinel = if (lhs_info.sentinel) |s| s.toIntern() else .none,14968 .sentinel = if (lhs_info.sentinel) |s| s.toIntern() else .none,
14824 .child = lhs_info.elem_type.toIntern(),14969 .child = lhs_info.elem_type.toIntern(),
...@@ -14839,8 +14984,8 @@ fn zirArrayMul(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -14839,8 +14984,8 @@ fn zirArrayMul(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
14839 // Optimization for the common pattern of a single element repeated N times, such14984 // Optimization for the common pattern of a single element repeated N times, such
14840 // as zero-filling a byte array.14985 // as zero-filling a byte array.
14841 if (lhs_len == 1 and lhs_info.sentinel == null) {14986 if (lhs_len == 1 and lhs_info.sentinel == null) {
14842 const elem_val = try lhs_sub_val.elemValue(mod, 0);14987 const elem_val = try lhs_sub_val.elemValue(pt, 0);
14843 break :v try mod.intern(.{ .aggregate = .{14988 break :v try pt.intern(.{ .aggregate = .{
14844 .ty = result_ty.toIntern(),14989 .ty = result_ty.toIntern(),
14845 .storage = .{ .repeated_elem = elem_val.toIntern() },14990 .storage = .{ .repeated_elem = elem_val.toIntern() },
14846 } });14991 } });
...@@ -14851,12 +14996,12 @@ fn zirArrayMul(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -14851,12 +14996,12 @@ fn zirArrayMul(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
14851 while (elem_i < result_len) {14996 while (elem_i < result_len) {
14852 var lhs_i: usize = 0;14997 var lhs_i: usize = 0;
14853 while (lhs_i < lhs_len) : (lhs_i += 1) {14998 while (lhs_i < lhs_len) : (lhs_i += 1) {
14854 const elem_val = try lhs_sub_val.elemValue(mod, lhs_i);14999 const elem_val = try lhs_sub_val.elemValue(pt, lhs_i);
14855 element_vals[elem_i] = elem_val.toIntern();15000 element_vals[elem_i] = elem_val.toIntern();
14856 elem_i += 1;15001 elem_i += 1;
14857 }15002 }
14858 }15003 }
14859 break :v try mod.intern(.{ .aggregate = .{15004 break :v try pt.intern(.{ .aggregate = .{
14860 .ty = result_ty.toIntern(),15005 .ty = result_ty.toIntern(),
14861 .storage = .{ .elems = element_vals },15006 .storage = .{ .elems = element_vals },
14862 } });15007 } });
...@@ -14870,17 +15015,17 @@ fn zirArrayMul(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -14870,17 +15015,17 @@ fn zirArrayMul(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
14870 // to get the same elem values.15015 // to get the same elem values.
14871 const lhs_vals = try sema.arena.alloc(Air.Inst.Ref, lhs_len);15016 const lhs_vals = try sema.arena.alloc(Air.Inst.Ref, lhs_len);
14872 for (lhs_vals, 0..) |*lhs_val, idx| {15017 for (lhs_vals, 0..) |*lhs_val, idx| {
14873 const idx_ref = try mod.intRef(Type.usize, idx);15018 const idx_ref = try pt.intRef(Type.usize, idx);
14874 lhs_val.* = try sema.elemVal(block, lhs_src, lhs, idx_ref, src, false);15019 lhs_val.* = try sema.elemVal(block, lhs_src, lhs, idx_ref, src, false);
14875 }15020 }
1487615021
14877 if (ptr_addrspace) |ptr_as| {15022 if (ptr_addrspace) |ptr_as| {
14878 const alloc_ty = try mod.ptrTypeSema(.{15023 const alloc_ty = try pt.ptrTypeSema(.{
14879 .child = result_ty.toIntern(),15024 .child = result_ty.toIntern(),
14880 .flags = .{ .address_space = ptr_as },15025 .flags = .{ .address_space = ptr_as },
14881 });15026 });
14882 const alloc = try block.addTy(.alloc, alloc_ty);15027 const alloc = try block.addTy(.alloc, alloc_ty);
14883 const elem_ptr_ty = try mod.ptrTypeSema(.{15028 const elem_ptr_ty = try pt.ptrTypeSema(.{
14884 .child = lhs_info.elem_type.toIntern(),15029 .child = lhs_info.elem_type.toIntern(),
14885 .flags = .{ .address_space = ptr_as },15030 .flags = .{ .address_space = ptr_as },
14886 });15031 });
...@@ -14888,14 +15033,14 @@ fn zirArrayMul(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -14888,14 +15033,14 @@ fn zirArrayMul(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
14888 var elem_i: usize = 0;15033 var elem_i: usize = 0;
14889 while (elem_i < result_len) {15034 while (elem_i < result_len) {
14890 for (lhs_vals) |lhs_val| {15035 for (lhs_vals) |lhs_val| {
14891 const elem_index = try mod.intRef(Type.usize, elem_i);15036 const elem_index = try pt.intRef(Type.usize, elem_i);
14892 const elem_ptr = try block.addPtrElemPtr(alloc, elem_index, elem_ptr_ty);15037 const elem_ptr = try block.addPtrElemPtr(alloc, elem_index, elem_ptr_ty);
14893 try sema.storePtr2(block, src, elem_ptr, src, lhs_val, lhs_src, .store);15038 try sema.storePtr2(block, src, elem_ptr, src, lhs_val, lhs_src, .store);
14894 elem_i += 1;15039 elem_i += 1;
14895 }15040 }
14896 }15041 }
14897 if (lhs_info.sentinel) |sent_val| {15042 if (lhs_info.sentinel) |sent_val| {
14898 const elem_index = try mod.intRef(Type.usize, result_len);15043 const elem_index = try pt.intRef(Type.usize, result_len);
14899 const elem_ptr = try block.addPtrElemPtr(alloc, elem_index, elem_ptr_ty);15044 const elem_ptr = try block.addPtrElemPtr(alloc, elem_index, elem_ptr_ty);
14900 const init = Air.internedToRef(sent_val.toIntern());15045 const init = Air.internedToRef(sent_val.toIntern());
14901 try sema.storePtr2(block, src, elem_ptr, src, init, lhs_src, .store);15046 try sema.storePtr2(block, src, elem_ptr, src, init, lhs_src, .store);
...@@ -14912,7 +15057,8 @@ fn zirArrayMul(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -14912,7 +15057,8 @@ fn zirArrayMul(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
14912}15057}
1491315058
14914fn zirNegate(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {15059fn zirNegate(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
14915 const mod = sema.mod;15060 const pt = sema.pt;
15061 const mod = pt.zcu;
14916 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;15062 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;
14917 const src = block.nodeOffset(inst_data.src_node);15063 const src = block.nodeOffset(inst_data.src_node);
14918 const lhs_src = src;15064 const lhs_src = src;
...@@ -14926,25 +15072,26 @@ fn zirNegate(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air....@@ -14926,25 +15072,26 @@ fn zirNegate(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.
14926 .Int, .ComptimeInt, .Float, .ComptimeFloat => false,15072 .Int, .ComptimeInt, .Float, .ComptimeFloat => false,
14927 else => true,15073 else => true,
14928 }) {15074 }) {
14929 return sema.fail(block, src, "negation of type '{}'", .{rhs_ty.fmt(mod)});15075 return sema.fail(block, src, "negation of type '{}'", .{rhs_ty.fmt(pt)});
14930 }15076 }
1493115077
14932 if (rhs_scalar_ty.isAnyFloat()) {15078 if (rhs_scalar_ty.isAnyFloat()) {
14933 // We handle float negation here to ensure negative zero is represented in the bits.15079 // We handle float negation here to ensure negative zero is represented in the bits.
14934 if (try sema.resolveValue(rhs)) |rhs_val| {15080 if (try sema.resolveValue(rhs)) |rhs_val| {
14935 if (rhs_val.isUndef(mod)) return mod.undefRef(rhs_ty);15081 if (rhs_val.isUndef(mod)) return pt.undefRef(rhs_ty);
14936 return Air.internedToRef((try rhs_val.floatNeg(rhs_ty, sema.arena, mod)).toIntern());15082 return Air.internedToRef((try rhs_val.floatNeg(rhs_ty, sema.arena, pt)).toIntern());
14937 }15083 }
14938 try sema.requireRuntimeBlock(block, src, null);15084 try sema.requireRuntimeBlock(block, src, null);
14939 return block.addUnOp(if (block.float_mode == .optimized) .neg_optimized else .neg, rhs);15085 return block.addUnOp(if (block.float_mode == .optimized) .neg_optimized else .neg, rhs);
14940 }15086 }
1494115087
14942 const lhs = Air.internedToRef((try sema.splat(rhs_ty, try mod.intValue(rhs_scalar_ty, 0))).toIntern());15088 const lhs = Air.internedToRef((try sema.splat(rhs_ty, try pt.intValue(rhs_scalar_ty, 0))).toIntern());
14943 return sema.analyzeArithmetic(block, .sub, lhs, rhs, src, lhs_src, rhs_src, true);15089 return sema.analyzeArithmetic(block, .sub, lhs, rhs, src, lhs_src, rhs_src, true);
14944}15090}
1494515091
14946fn zirNegateWrap(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {15092fn zirNegateWrap(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
14947 const mod = sema.mod;15093 const pt = sema.pt;
15094 const mod = pt.zcu;
14948 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;15095 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;
14949 const src = block.nodeOffset(inst_data.src_node);15096 const src = block.nodeOffset(inst_data.src_node);
14950 const lhs_src = src;15097 const lhs_src = src;
...@@ -14956,10 +15103,10 @@ fn zirNegateWrap(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!...@@ -14956,10 +15103,10 @@ fn zirNegateWrap(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!
1495615103
14957 switch (rhs_scalar_ty.zigTypeTag(mod)) {15104 switch (rhs_scalar_ty.zigTypeTag(mod)) {
14958 .Int, .ComptimeInt, .Float, .ComptimeFloat => {},15105 .Int, .ComptimeInt, .Float, .ComptimeFloat => {},
14959 else => return sema.fail(block, src, "negation of type '{}'", .{rhs_ty.fmt(mod)}),15106 else => return sema.fail(block, src, "negation of type '{}'", .{rhs_ty.fmt(pt)}),
14960 }15107 }
1496115108
14962 const lhs = Air.internedToRef((try sema.splat(rhs_ty, try mod.intValue(rhs_scalar_ty, 0))).toIntern());15109 const lhs = Air.internedToRef((try sema.splat(rhs_ty, try pt.intValue(rhs_scalar_ty, 0))).toIntern());
14963 return sema.analyzeArithmetic(block, .subwrap, lhs, rhs, src, lhs_src, rhs_src, true);15110 return sema.analyzeArithmetic(block, .subwrap, lhs, rhs, src, lhs_src, rhs_src, true);
14964}15111}
1496515112
...@@ -14985,7 +15132,8 @@ fn zirArithmetic(...@@ -14985,7 +15132,8 @@ fn zirArithmetic(
14985}15132}
1498615133
14987fn zirDiv(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {15134fn zirDiv(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
14988 const mod = sema.mod;15135 const pt = sema.pt;
15136 const mod = pt.zcu;
14989 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;15137 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
14990 const src = block.src(.{ .node_offset_bin_op = inst_data.src_node });15138 const src = block.src(.{ .node_offset_bin_op = inst_data.src_node });
14991 const lhs_src = block.src(.{ .node_offset_bin_lhs = inst_data.src_node });15139 const lhs_src = block.src(.{ .node_offset_bin_lhs = inst_data.src_node });
...@@ -15026,13 +15174,13 @@ fn zirDiv(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Ins...@@ -15026,13 +15174,13 @@ fn zirDiv(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Ins
15026 // If lhs % rhs is 0, it doesn't matter.15174 // If lhs % rhs is 0, it doesn't matter.
15027 const lhs_val = maybe_lhs_val orelse unreachable;15175 const lhs_val = maybe_lhs_val orelse unreachable;
15028 const rhs_val = maybe_rhs_val orelse unreachable;15176 const rhs_val = maybe_rhs_val orelse unreachable;
15029 const rem = lhs_val.floatRem(rhs_val, resolved_type, sema.arena, mod) catch unreachable;15177 const rem = lhs_val.floatRem(rhs_val, resolved_type, sema.arena, pt) catch unreachable;
15030 if (!rem.compareAllWithZero(.eq, mod)) {15178 if (!rem.compareAllWithZero(.eq, pt)) {
15031 return sema.fail(15179 return sema.fail(
15032 block,15180 block,
15033 src,15181 src,
15034 "ambiguous coercion of division operands '{}' and '{}'; non-zero remainder '{}'",15182 "ambiguous coercion of division operands '{}' and '{}'; non-zero remainder '{}'",
15035 .{ lhs_ty.fmt(mod), rhs_ty.fmt(mod), rem.fmtValue(mod, sema) },15183 .{ lhs_ty.fmt(pt), rhs_ty.fmt(pt), rem.fmtValue(pt, sema) },
15036 );15184 );
15037 }15185 }
15038 }15186 }
...@@ -15068,10 +15216,10 @@ fn zirDiv(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Ins...@@ -15068,10 +15216,10 @@ fn zirDiv(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Ins
15068 .Int, .ComptimeInt, .ComptimeFloat => {15216 .Int, .ComptimeInt, .ComptimeFloat => {
15069 if (maybe_lhs_val) |lhs_val| {15217 if (maybe_lhs_val) |lhs_val| {
15070 if (!lhs_val.isUndef(mod)) {15218 if (!lhs_val.isUndef(mod)) {
15071 if (try lhs_val.compareAllWithZeroSema(.eq, mod)) {15219 if (try lhs_val.compareAllWithZeroSema(.eq, pt)) {
15072 const scalar_zero = switch (scalar_tag) {15220 const scalar_zero = switch (scalar_tag) {
15073 .ComptimeFloat, .Float => try mod.floatValue(resolved_type.scalarType(mod), 0.0),15221 .ComptimeFloat, .Float => try pt.floatValue(resolved_type.scalarType(mod), 0.0),
15074 .ComptimeInt, .Int => try mod.intValue(resolved_type.scalarType(mod), 0),15222 .ComptimeInt, .Int => try pt.intValue(resolved_type.scalarType(mod), 0),
15075 else => unreachable,15223 else => unreachable,
15076 };15224 };
15077 const zero_val = try sema.splat(resolved_type, scalar_zero);15225 const zero_val = try sema.splat(resolved_type, scalar_zero);
...@@ -15083,7 +15231,7 @@ fn zirDiv(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Ins...@@ -15083,7 +15231,7 @@ fn zirDiv(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Ins
15083 if (rhs_val.isUndef(mod)) {15231 if (rhs_val.isUndef(mod)) {
15084 return sema.failWithUseOfUndef(block, rhs_src);15232 return sema.failWithUseOfUndef(block, rhs_src);
15085 }15233 }
15086 if (!(try rhs_val.compareAllWithZeroSema(.neq, mod))) {15234 if (!(try rhs_val.compareAllWithZeroSema(.neq, pt))) {
15087 return sema.failWithDivideByZero(block, rhs_src);15235 return sema.failWithDivideByZero(block, rhs_src);
15088 }15236 }
15089 // TODO: if the RHS is one, return the LHS directly15237 // TODO: if the RHS is one, return the LHS directly
...@@ -15097,25 +15245,25 @@ fn zirDiv(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Ins...@@ -15097,25 +15245,25 @@ fn zirDiv(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Ins
15097 if (lhs_val.isUndef(mod)) {15245 if (lhs_val.isUndef(mod)) {
15098 if (lhs_scalar_ty.isSignedInt(mod) and rhs_scalar_ty.isSignedInt(mod)) {15246 if (lhs_scalar_ty.isSignedInt(mod) and rhs_scalar_ty.isSignedInt(mod)) {
15099 if (maybe_rhs_val) |rhs_val| {15247 if (maybe_rhs_val) |rhs_val| {
15100 if (try sema.compareAll(rhs_val, .neq, try mod.intValue(resolved_type, -1), resolved_type)) {15248 if (try sema.compareAll(rhs_val, .neq, try pt.intValue(resolved_type, -1), resolved_type)) {
15101 return mod.undefRef(resolved_type);15249 return pt.undefRef(resolved_type);
15102 }15250 }
15103 }15251 }
15104 return sema.failWithUseOfUndef(block, rhs_src);15252 return sema.failWithUseOfUndef(block, rhs_src);
15105 }15253 }
15106 return mod.undefRef(resolved_type);15254 return pt.undefRef(resolved_type);
15107 }15255 }
1510815256
15109 if (maybe_rhs_val) |rhs_val| {15257 if (maybe_rhs_val) |rhs_val| {
15110 if (is_int) {15258 if (is_int) {
15111 var overflow_idx: ?usize = null;15259 var overflow_idx: ?usize = null;
15112 const res = try lhs_val.intDiv(rhs_val, resolved_type, &overflow_idx, sema.arena, mod);15260 const res = try lhs_val.intDiv(rhs_val, resolved_type, &overflow_idx, sema.arena, pt);
15113 if (overflow_idx) |vec_idx| {15261 if (overflow_idx) |vec_idx| {
15114 return sema.failWithIntegerOverflow(block, src, resolved_type, res, vec_idx);15262 return sema.failWithIntegerOverflow(block, src, resolved_type, res, vec_idx);
15115 }15263 }
15116 return Air.internedToRef(res.toIntern());15264 return Air.internedToRef(res.toIntern());
15117 } else {15265 } else {
15118 return Air.internedToRef((try lhs_val.floatDiv(rhs_val, resolved_type, sema.arena, mod)).toIntern());15266 return Air.internedToRef((try lhs_val.floatDiv(rhs_val, resolved_type, sema.arena, pt)).toIntern());
15119 }15267 }
15120 } else {15268 } else {
15121 break :rs rhs_src;15269 break :rs rhs_src;
...@@ -15138,7 +15286,7 @@ fn zirDiv(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Ins...@@ -15138,7 +15286,7 @@ fn zirDiv(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Ins
15138 block,15286 block,
15139 src,15287 src,
15140 "division with '{}' and '{}': signed integers must use @divTrunc, @divFloor, or @divExact",15288 "division with '{}' and '{}': signed integers must use @divTrunc, @divFloor, or @divExact",
15141 .{ lhs_ty.fmt(mod), rhs_ty.fmt(mod) },15289 .{ lhs_ty.fmt(pt), rhs_ty.fmt(pt) },
15142 );15290 );
15143 }15291 }
15144 break :blk Air.Inst.Tag.div_trunc;15292 break :blk Air.Inst.Tag.div_trunc;
...@@ -15150,7 +15298,8 @@ fn zirDiv(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Ins...@@ -15150,7 +15298,8 @@ fn zirDiv(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Ins
15150}15298}
1515115299
15152fn zirDivExact(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {15300fn zirDivExact(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
15153 const mod = sema.mod;15301 const pt = sema.pt;
15302 const mod = pt.zcu;
15154 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;15303 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
15155 const src = block.src(.{ .node_offset_bin_op = inst_data.src_node });15304 const src = block.src(.{ .node_offset_bin_op = inst_data.src_node });
15156 const lhs_src = block.src(.{ .node_offset_bin_lhs = inst_data.src_node });15305 const lhs_src = block.src(.{ .node_offset_bin_lhs = inst_data.src_node });
...@@ -15204,10 +15353,10 @@ fn zirDivExact(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -15204,10 +15353,10 @@ fn zirDivExact(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
15204 if (lhs_val.isUndef(mod)) {15353 if (lhs_val.isUndef(mod)) {
15205 return sema.failWithUseOfUndef(block, rhs_src);15354 return sema.failWithUseOfUndef(block, rhs_src);
15206 } else {15355 } else {
15207 if (try lhs_val.compareAllWithZeroSema(.eq, mod)) {15356 if (try lhs_val.compareAllWithZeroSema(.eq, pt)) {
15208 const scalar_zero = switch (scalar_tag) {15357 const scalar_zero = switch (scalar_tag) {
15209 .ComptimeFloat, .Float => try mod.floatValue(resolved_type.scalarType(mod), 0.0),15358 .ComptimeFloat, .Float => try pt.floatValue(resolved_type.scalarType(mod), 0.0),
15210 .ComptimeInt, .Int => try mod.intValue(resolved_type.scalarType(mod), 0),15359 .ComptimeInt, .Int => try pt.intValue(resolved_type.scalarType(mod), 0),
15211 else => unreachable,15360 else => unreachable,
15212 };15361 };
15213 const zero_val = try sema.splat(resolved_type, scalar_zero);15362 const zero_val = try sema.splat(resolved_type, scalar_zero);
...@@ -15219,7 +15368,7 @@ fn zirDivExact(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -15219,7 +15368,7 @@ fn zirDivExact(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
15219 if (rhs_val.isUndef(mod)) {15368 if (rhs_val.isUndef(mod)) {
15220 return sema.failWithUseOfUndef(block, rhs_src);15369 return sema.failWithUseOfUndef(block, rhs_src);
15221 }15370 }
15222 if (!(try rhs_val.compareAllWithZeroSema(.neq, mod))) {15371 if (!(try rhs_val.compareAllWithZeroSema(.neq, pt))) {
15223 return sema.failWithDivideByZero(block, rhs_src);15372 return sema.failWithDivideByZero(block, rhs_src);
15224 }15373 }
15225 // TODO: if the RHS is one, return the LHS directly15374 // TODO: if the RHS is one, return the LHS directly
...@@ -15227,22 +15376,22 @@ fn zirDivExact(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -15227,22 +15376,22 @@ fn zirDivExact(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
15227 if (maybe_lhs_val) |lhs_val| {15376 if (maybe_lhs_val) |lhs_val| {
15228 if (maybe_rhs_val) |rhs_val| {15377 if (maybe_rhs_val) |rhs_val| {
15229 if (is_int) {15378 if (is_int) {
15230 const modulus_val = try lhs_val.intMod(rhs_val, resolved_type, sema.arena, mod);15379 const modulus_val = try lhs_val.intMod(rhs_val, resolved_type, sema.arena, pt);
15231 if (!(modulus_val.compareAllWithZero(.eq, mod))) {15380 if (!(modulus_val.compareAllWithZero(.eq, pt))) {
15232 return sema.fail(block, src, "exact division produced remainder", .{});15381 return sema.fail(block, src, "exact division produced remainder", .{});
15233 }15382 }
15234 var overflow_idx: ?usize = null;15383 var overflow_idx: ?usize = null;
15235 const res = try lhs_val.intDiv(rhs_val, resolved_type, &overflow_idx, sema.arena, mod);15384 const res = try lhs_val.intDiv(rhs_val, resolved_type, &overflow_idx, sema.arena, pt);
15236 if (overflow_idx) |vec_idx| {15385 if (overflow_idx) |vec_idx| {
15237 return sema.failWithIntegerOverflow(block, src, resolved_type, res, vec_idx);15386 return sema.failWithIntegerOverflow(block, src, resolved_type, res, vec_idx);
15238 }15387 }
15239 return Air.internedToRef(res.toIntern());15388 return Air.internedToRef(res.toIntern());
15240 } else {15389 } else {
15241 const modulus_val = try lhs_val.floatMod(rhs_val, resolved_type, sema.arena, mod);15390 const modulus_val = try lhs_val.floatMod(rhs_val, resolved_type, sema.arena, pt);
15242 if (!(modulus_val.compareAllWithZero(.eq, mod))) {15391 if (!(modulus_val.compareAllWithZero(.eq, pt))) {
15243 return sema.fail(block, src, "exact division produced remainder", .{});15392 return sema.fail(block, src, "exact division produced remainder", .{});
15244 }15393 }
15245 return Air.internedToRef((try lhs_val.floatDiv(rhs_val, resolved_type, sema.arena, mod)).toIntern());15394 return Air.internedToRef((try lhs_val.floatDiv(rhs_val, resolved_type, sema.arena, pt)).toIntern());
15246 }15395 }
15247 } else break :rs rhs_src;15396 } else break :rs rhs_src;
15248 } else break :rs lhs_src;15397 } else break :rs lhs_src;
...@@ -15286,8 +15435,8 @@ fn zirDivExact(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -15286,8 +15435,8 @@ fn zirDivExact(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
15286 const remainder = try block.addBinOp(.rem, casted_lhs, casted_rhs);15435 const remainder = try block.addBinOp(.rem, casted_lhs, casted_rhs);
1528715436
15288 const scalar_zero = switch (scalar_tag) {15437 const scalar_zero = switch (scalar_tag) {
15289 .ComptimeFloat, .Float => try mod.floatValue(resolved_type.scalarType(mod), 0.0),15438 .ComptimeFloat, .Float => try pt.floatValue(resolved_type.scalarType(mod), 0.0),
15290 .ComptimeInt, .Int => try mod.intValue(resolved_type.scalarType(mod), 0),15439 .ComptimeInt, .Int => try pt.intValue(resolved_type.scalarType(mod), 0),
15291 else => unreachable,15440 else => unreachable,
15292 };15441 };
15293 if (resolved_type.zigTypeTag(mod) == .Vector) {15442 if (resolved_type.zigTypeTag(mod) == .Vector) {
...@@ -15315,7 +15464,8 @@ fn zirDivExact(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -15315,7 +15464,8 @@ fn zirDivExact(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
15315}15464}
1531615465
15317fn zirDivFloor(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {15466fn zirDivFloor(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
15318 const mod = sema.mod;15467 const pt = sema.pt;
15468 const mod = pt.zcu;
15319 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;15469 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
15320 const src = block.src(.{ .node_offset_bin_op = inst_data.src_node });15470 const src = block.src(.{ .node_offset_bin_op = inst_data.src_node });
15321 const lhs_src = block.src(.{ .node_offset_bin_lhs = inst_data.src_node });15471 const lhs_src = block.src(.{ .node_offset_bin_lhs = inst_data.src_node });
...@@ -15371,10 +15521,10 @@ fn zirDivFloor(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -15371,10 +15521,10 @@ fn zirDivFloor(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
15371 // If the lhs is undefined, result is undefined.15521 // If the lhs is undefined, result is undefined.
15372 if (maybe_lhs_val) |lhs_val| {15522 if (maybe_lhs_val) |lhs_val| {
15373 if (!lhs_val.isUndef(mod)) {15523 if (!lhs_val.isUndef(mod)) {
15374 if (try lhs_val.compareAllWithZeroSema(.eq, mod)) {15524 if (try lhs_val.compareAllWithZeroSema(.eq, pt)) {
15375 const scalar_zero = switch (scalar_tag) {15525 const scalar_zero = switch (scalar_tag) {
15376 .ComptimeFloat, .Float => try mod.floatValue(resolved_type.scalarType(mod), 0.0),15526 .ComptimeFloat, .Float => try pt.floatValue(resolved_type.scalarType(mod), 0.0),
15377 .ComptimeInt, .Int => try mod.intValue(resolved_type.scalarType(mod), 0),15527 .ComptimeInt, .Int => try pt.intValue(resolved_type.scalarType(mod), 0),
15378 else => unreachable,15528 else => unreachable,
15379 };15529 };
15380 const zero_val = try sema.splat(resolved_type, scalar_zero);15530 const zero_val = try sema.splat(resolved_type, scalar_zero);
...@@ -15386,7 +15536,7 @@ fn zirDivFloor(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -15386,7 +15536,7 @@ fn zirDivFloor(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
15386 if (rhs_val.isUndef(mod)) {15536 if (rhs_val.isUndef(mod)) {
15387 return sema.failWithUseOfUndef(block, rhs_src);15537 return sema.failWithUseOfUndef(block, rhs_src);
15388 }15538 }
15389 if (!(try rhs_val.compareAllWithZeroSema(.neq, mod))) {15539 if (!(try rhs_val.compareAllWithZeroSema(.neq, pt))) {
15390 return sema.failWithDivideByZero(block, rhs_src);15540 return sema.failWithDivideByZero(block, rhs_src);
15391 }15541 }
15392 // TODO: if the RHS is one, return the LHS directly15542 // TODO: if the RHS is one, return the LHS directly
...@@ -15395,20 +15545,20 @@ fn zirDivFloor(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -15395,20 +15545,20 @@ fn zirDivFloor(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
15395 if (lhs_val.isUndef(mod)) {15545 if (lhs_val.isUndef(mod)) {
15396 if (lhs_scalar_ty.isSignedInt(mod) and rhs_scalar_ty.isSignedInt(mod)) {15546 if (lhs_scalar_ty.isSignedInt(mod) and rhs_scalar_ty.isSignedInt(mod)) {
15397 if (maybe_rhs_val) |rhs_val| {15547 if (maybe_rhs_val) |rhs_val| {
15398 if (try sema.compareAll(rhs_val, .neq, try mod.intValue(resolved_type, -1), resolved_type)) {15548 if (try sema.compareAll(rhs_val, .neq, try pt.intValue(resolved_type, -1), resolved_type)) {
15399 return mod.undefRef(resolved_type);15549 return pt.undefRef(resolved_type);
15400 }15550 }
15401 }15551 }
15402 return sema.failWithUseOfUndef(block, rhs_src);15552 return sema.failWithUseOfUndef(block, rhs_src);
15403 }15553 }
15404 return mod.undefRef(resolved_type);15554 return pt.undefRef(resolved_type);
15405 }15555 }
1540615556
15407 if (maybe_rhs_val) |rhs_val| {15557 if (maybe_rhs_val) |rhs_val| {
15408 if (is_int) {15558 if (is_int) {
15409 return Air.internedToRef((try lhs_val.intDivFloor(rhs_val, resolved_type, sema.arena, mod)).toIntern());15559 return Air.internedToRef((try lhs_val.intDivFloor(rhs_val, resolved_type, sema.arena, pt)).toIntern());
15410 } else {15560 } else {
15411 return Air.internedToRef((try lhs_val.floatDivFloor(rhs_val, resolved_type, sema.arena, mod)).toIntern());15561 return Air.internedToRef((try lhs_val.floatDivFloor(rhs_val, resolved_type, sema.arena, pt)).toIntern());
15412 }15562 }
15413 } else break :rs rhs_src;15563 } else break :rs rhs_src;
15414 } else break :rs lhs_src;15564 } else break :rs lhs_src;
...@@ -15425,7 +15575,8 @@ fn zirDivFloor(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -15425,7 +15575,8 @@ fn zirDivFloor(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
15425}15575}
1542615576
15427fn zirDivTrunc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {15577fn zirDivTrunc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
15428 const mod = sema.mod;15578 const pt = sema.pt;
15579 const mod = pt.zcu;
15429 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;15580 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
15430 const src = block.src(.{ .node_offset_bin_op = inst_data.src_node });15581 const src = block.src(.{ .node_offset_bin_op = inst_data.src_node });
15431 const lhs_src = block.src(.{ .node_offset_bin_lhs = inst_data.src_node });15582 const lhs_src = block.src(.{ .node_offset_bin_lhs = inst_data.src_node });
...@@ -15481,10 +15632,10 @@ fn zirDivTrunc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -15481,10 +15632,10 @@ fn zirDivTrunc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
15481 // If the lhs is undefined, result is undefined.15632 // If the lhs is undefined, result is undefined.
15482 if (maybe_lhs_val) |lhs_val| {15633 if (maybe_lhs_val) |lhs_val| {
15483 if (!lhs_val.isUndef(mod)) {15634 if (!lhs_val.isUndef(mod)) {
15484 if (try lhs_val.compareAllWithZeroSema(.eq, mod)) {15635 if (try lhs_val.compareAllWithZeroSema(.eq, pt)) {
15485 const scalar_zero = switch (scalar_tag) {15636 const scalar_zero = switch (scalar_tag) {
15486 .ComptimeFloat, .Float => try mod.floatValue(resolved_type.scalarType(mod), 0.0),15637 .ComptimeFloat, .Float => try pt.floatValue(resolved_type.scalarType(mod), 0.0),
15487 .ComptimeInt, .Int => try mod.intValue(resolved_type.scalarType(mod), 0),15638 .ComptimeInt, .Int => try pt.intValue(resolved_type.scalarType(mod), 0),
15488 else => unreachable,15639 else => unreachable,
15489 };15640 };
15490 const zero_val = try sema.splat(resolved_type, scalar_zero);15641 const zero_val = try sema.splat(resolved_type, scalar_zero);
...@@ -15496,7 +15647,7 @@ fn zirDivTrunc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -15496,7 +15647,7 @@ fn zirDivTrunc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
15496 if (rhs_val.isUndef(mod)) {15647 if (rhs_val.isUndef(mod)) {
15497 return sema.failWithUseOfUndef(block, rhs_src);15648 return sema.failWithUseOfUndef(block, rhs_src);
15498 }15649 }
15499 if (!(try rhs_val.compareAllWithZeroSema(.neq, mod))) {15650 if (!(try rhs_val.compareAllWithZeroSema(.neq, pt))) {
15500 return sema.failWithDivideByZero(block, rhs_src);15651 return sema.failWithDivideByZero(block, rhs_src);
15501 }15652 }
15502 }15653 }
...@@ -15504,25 +15655,25 @@ fn zirDivTrunc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -15504,25 +15655,25 @@ fn zirDivTrunc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
15504 if (lhs_val.isUndef(mod)) {15655 if (lhs_val.isUndef(mod)) {
15505 if (lhs_scalar_ty.isSignedInt(mod) and rhs_scalar_ty.isSignedInt(mod)) {15656 if (lhs_scalar_ty.isSignedInt(mod) and rhs_scalar_ty.isSignedInt(mod)) {
15506 if (maybe_rhs_val) |rhs_val| {15657 if (maybe_rhs_val) |rhs_val| {
15507 if (try sema.compareAll(rhs_val, .neq, try mod.intValue(resolved_type, -1), resolved_type)) {15658 if (try sema.compareAll(rhs_val, .neq, try pt.intValue(resolved_type, -1), resolved_type)) {
15508 return mod.undefRef(resolved_type);15659 return pt.undefRef(resolved_type);
15509 }15660 }
15510 }15661 }
15511 return sema.failWithUseOfUndef(block, rhs_src);15662 return sema.failWithUseOfUndef(block, rhs_src);
15512 }15663 }
15513 return mod.undefRef(resolved_type);15664 return pt.undefRef(resolved_type);
15514 }15665 }
1551515666
15516 if (maybe_rhs_val) |rhs_val| {15667 if (maybe_rhs_val) |rhs_val| {
15517 if (is_int) {15668 if (is_int) {
15518 var overflow_idx: ?usize = null;15669 var overflow_idx: ?usize = null;
15519 const res = try lhs_val.intDiv(rhs_val, resolved_type, &overflow_idx, sema.arena, mod);15670 const res = try lhs_val.intDiv(rhs_val, resolved_type, &overflow_idx, sema.arena, pt);
15520 if (overflow_idx) |vec_idx| {15671 if (overflow_idx) |vec_idx| {
15521 return sema.failWithIntegerOverflow(block, src, resolved_type, res, vec_idx);15672 return sema.failWithIntegerOverflow(block, src, resolved_type, res, vec_idx);
15522 }15673 }
15523 return Air.internedToRef(res.toIntern());15674 return Air.internedToRef(res.toIntern());
15524 } else {15675 } else {
15525 return Air.internedToRef((try lhs_val.floatDivTrunc(rhs_val, resolved_type, sema.arena, mod)).toIntern());15676 return Air.internedToRef((try lhs_val.floatDivTrunc(rhs_val, resolved_type, sema.arena, pt)).toIntern());
15526 }15677 }
15527 } else break :rs rhs_src;15678 } else break :rs rhs_src;
15528 } else break :rs lhs_src;15679 } else break :rs lhs_src;
...@@ -15550,7 +15701,8 @@ fn addDivIntOverflowSafety(...@@ -15550,7 +15701,8 @@ fn addDivIntOverflowSafety(
15550 casted_rhs: Air.Inst.Ref,15701 casted_rhs: Air.Inst.Ref,
15551 is_int: bool,15702 is_int: bool,
15552) CompileError!void {15703) CompileError!void {
15553 const mod = sema.mod;15704 const pt = sema.pt;
15705 const mod = pt.zcu;
15554 if (!is_int) return;15706 if (!is_int) return;
1555515707
15556 // If the LHS is unsigned, it cannot cause overflow.15708 // If the LHS is unsigned, it cannot cause overflow.
...@@ -15561,19 +15713,19 @@ fn addDivIntOverflowSafety(...@@ -15561,19 +15713,19 @@ fn addDivIntOverflowSafety(
15561 return;15713 return;
15562 }15714 }
1556315715
15564 const min_int = try resolved_type.minInt(mod, resolved_type);15716 const min_int = try resolved_type.minInt(pt, resolved_type);
15565 const neg_one_scalar = try mod.intValue(lhs_scalar_ty, -1);15717 const neg_one_scalar = try pt.intValue(lhs_scalar_ty, -1);
15566 const neg_one = try sema.splat(resolved_type, neg_one_scalar);15718 const neg_one = try sema.splat(resolved_type, neg_one_scalar);
1556715719
15568 // If the LHS is comptime-known to be not equal to the min int,15720 // If the LHS is comptime-known to be not equal to the min int,
15569 // no overflow is possible.15721 // no overflow is possible.
15570 if (maybe_lhs_val) |lhs_val| {15722 if (maybe_lhs_val) |lhs_val| {
15571 if (try lhs_val.compareAll(.neq, min_int, resolved_type, mod)) return;15723 if (try lhs_val.compareAll(.neq, min_int, resolved_type, pt)) return;
15572 }15724 }
1557315725
15574 // If the RHS is comptime-known to not be equal to -1, no overflow is possible.15726 // If the RHS is comptime-known to not be equal to -1, no overflow is possible.
15575 if (maybe_rhs_val) |rhs_val| {15727 if (maybe_rhs_val) |rhs_val| {
15576 if (try rhs_val.compareAll(.neq, neg_one, resolved_type, mod)) return;15728 if (try rhs_val.compareAll(.neq, neg_one, resolved_type, pt)) return;
15577 }15729 }
1557815730
15579 var ok: Air.Inst.Ref = .none;15731 var ok: Air.Inst.Ref = .none;
...@@ -15634,11 +15786,12 @@ fn addDivByZeroSafety(...@@ -15634,11 +15786,12 @@ fn addDivByZeroSafety(
15634 // emitted above.15786 // emitted above.
15635 if (maybe_rhs_val != null) return;15787 if (maybe_rhs_val != null) return;
1563615788
15637 const mod = sema.mod;15789 const pt = sema.pt;
15790 const mod = pt.zcu;
15638 const scalar_zero = if (is_int)15791 const scalar_zero = if (is_int)
15639 try mod.intValue(resolved_type.scalarType(mod), 0)15792 try pt.intValue(resolved_type.scalarType(mod), 0)
15640 else15793 else
15641 try mod.floatValue(resolved_type.scalarType(mod), 0.0);15794 try pt.floatValue(resolved_type.scalarType(mod), 0.0);
15642 const ok = if (resolved_type.zigTypeTag(mod) == .Vector) ok: {15795 const ok = if (resolved_type.zigTypeTag(mod) == .Vector) ok: {
15643 const zero_val = try sema.splat(resolved_type, scalar_zero);15796 const zero_val = try sema.splat(resolved_type, scalar_zero);
15644 const zero = Air.internedToRef(zero_val.toIntern());15797 const zero = Air.internedToRef(zero_val.toIntern());
...@@ -15666,7 +15819,8 @@ fn airTag(block: *Block, is_int: bool, normal: Air.Inst.Tag, optimized: Air.Inst...@@ -15666,7 +15819,8 @@ fn airTag(block: *Block, is_int: bool, normal: Air.Inst.Tag, optimized: Air.Inst
15666}15819}
1566715820
15668fn zirModRem(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {15821fn zirModRem(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
15669 const mod = sema.mod;15822 const pt = sema.pt;
15823 const mod = pt.zcu;
15670 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;15824 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
15671 const src = block.src(.{ .node_offset_bin_op = inst_data.src_node });15825 const src = block.src(.{ .node_offset_bin_op = inst_data.src_node });
15672 const lhs_src = block.src(.{ .node_offset_bin_lhs = inst_data.src_node });15826 const lhs_src = block.src(.{ .node_offset_bin_lhs = inst_data.src_node });
...@@ -15721,16 +15875,16 @@ fn zirModRem(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air....@@ -15721,16 +15875,16 @@ fn zirModRem(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.
15721 if (lhs_val.isUndef(mod)) {15875 if (lhs_val.isUndef(mod)) {
15722 return sema.failWithUseOfUndef(block, lhs_src);15876 return sema.failWithUseOfUndef(block, lhs_src);
15723 }15877 }
15724 if (try lhs_val.compareAllWithZeroSema(.eq, mod)) {15878 if (try lhs_val.compareAllWithZeroSema(.eq, pt)) {
15725 const scalar_zero = switch (scalar_tag) {15879 const scalar_zero = switch (scalar_tag) {
15726 .ComptimeFloat, .Float => try mod.floatValue(resolved_type.scalarType(mod), 0.0),15880 .ComptimeFloat, .Float => try pt.floatValue(resolved_type.scalarType(mod), 0.0),
15727 .ComptimeInt, .Int => try mod.intValue(resolved_type.scalarType(mod), 0),15881 .ComptimeInt, .Int => try pt.intValue(resolved_type.scalarType(mod), 0),
15728 else => unreachable,15882 else => unreachable,
15729 };15883 };
15730 const zero_val = if (is_vector) Value.fromInterned((try mod.intern(.{ .aggregate = .{15884 const zero_val = if (is_vector) Value.fromInterned(try pt.intern(.{ .aggregate = .{
15731 .ty = resolved_type.toIntern(),15885 .ty = resolved_type.toIntern(),
15732 .storage = .{ .repeated_elem = scalar_zero.toIntern() },15886 .storage = .{ .repeated_elem = scalar_zero.toIntern() },
15733 } }))) else scalar_zero;15887 } })) else scalar_zero;
15734 return Air.internedToRef(zero_val.toIntern());15888 return Air.internedToRef(zero_val.toIntern());
15735 }15889 }
15736 } else if (lhs_scalar_ty.isSignedInt(mod)) {15890 } else if (lhs_scalar_ty.isSignedInt(mod)) {
...@@ -15740,18 +15894,18 @@ fn zirModRem(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air....@@ -15740,18 +15894,18 @@ fn zirModRem(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.
15740 if (rhs_val.isUndef(mod)) {15894 if (rhs_val.isUndef(mod)) {
15741 return sema.failWithUseOfUndef(block, rhs_src);15895 return sema.failWithUseOfUndef(block, rhs_src);
15742 }15896 }
15743 if (!(try rhs_val.compareAllWithZeroSema(.neq, mod))) {15897 if (!(try rhs_val.compareAllWithZeroSema(.neq, pt))) {
15744 return sema.failWithDivideByZero(block, rhs_src);15898 return sema.failWithDivideByZero(block, rhs_src);
15745 }15899 }
15746 if (!(try rhs_val.compareAllWithZeroSema(.gte, mod))) {15900 if (!(try rhs_val.compareAllWithZeroSema(.gte, pt))) {
15747 return sema.failWithModRemNegative(block, rhs_src, lhs_ty, rhs_ty);15901 return sema.failWithModRemNegative(block, rhs_src, lhs_ty, rhs_ty);
15748 }15902 }
15749 if (maybe_lhs_val) |lhs_val| {15903 if (maybe_lhs_val) |lhs_val| {
15750 const rem_result = try sema.intRem(resolved_type, lhs_val, rhs_val);15904 const rem_result = try sema.intRem(resolved_type, lhs_val, rhs_val);
15751 // If this answer could possibly be different by doing `intMod`,15905 // If this answer could possibly be different by doing `intMod`,
15752 // we must emit a compile error. Otherwise, it's OK.15906 // we must emit a compile error. Otherwise, it's OK.
15753 if (!(try lhs_val.compareAllWithZeroSema(.gte, mod)) and15907 if (!(try lhs_val.compareAllWithZeroSema(.gte, pt)) and
15754 !(try rem_result.compareAllWithZeroSema(.eq, mod)))15908 !(try rem_result.compareAllWithZeroSema(.eq, pt)))
15755 {15909 {
15756 return sema.failWithModRemNegative(block, lhs_src, lhs_ty, rhs_ty);15910 return sema.failWithModRemNegative(block, lhs_src, lhs_ty, rhs_ty);
15757 }15911 }
...@@ -15769,17 +15923,17 @@ fn zirModRem(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air....@@ -15769,17 +15923,17 @@ fn zirModRem(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.
15769 if (rhs_val.isUndef(mod)) {15923 if (rhs_val.isUndef(mod)) {
15770 return sema.failWithUseOfUndef(block, rhs_src);15924 return sema.failWithUseOfUndef(block, rhs_src);
15771 }15925 }
15772 if (!(try rhs_val.compareAllWithZeroSema(.neq, mod))) {15926 if (!(try rhs_val.compareAllWithZeroSema(.neq, pt))) {
15773 return sema.failWithDivideByZero(block, rhs_src);15927 return sema.failWithDivideByZero(block, rhs_src);
15774 }15928 }
15775 if (!(try rhs_val.compareAllWithZeroSema(.gte, mod))) {15929 if (!(try rhs_val.compareAllWithZeroSema(.gte, pt))) {
15776 return sema.failWithModRemNegative(block, rhs_src, lhs_ty, rhs_ty);15930 return sema.failWithModRemNegative(block, rhs_src, lhs_ty, rhs_ty);
15777 }15931 }
15778 if (maybe_lhs_val) |lhs_val| {15932 if (maybe_lhs_val) |lhs_val| {
15779 if (lhs_val.isUndef(mod) or !(try lhs_val.compareAllWithZeroSema(.gte, mod))) {15933 if (lhs_val.isUndef(mod) or !(try lhs_val.compareAllWithZeroSema(.gte, pt))) {
15780 return sema.failWithModRemNegative(block, lhs_src, lhs_ty, rhs_ty);15934 return sema.failWithModRemNegative(block, lhs_src, lhs_ty, rhs_ty);
15781 }15935 }
15782 return Air.internedToRef((try lhs_val.floatRem(rhs_val, resolved_type, sema.arena, mod)).toIntern());15936 return Air.internedToRef((try lhs_val.floatRem(rhs_val, resolved_type, sema.arena, pt)).toIntern());
15783 } else {15937 } else {
15784 return sema.failWithModRemNegative(block, lhs_src, lhs_ty, rhs_ty);15938 return sema.failWithModRemNegative(block, lhs_src, lhs_ty, rhs_ty);
15785 }15939 }
...@@ -15804,31 +15958,32 @@ fn intRem(...@@ -15804,31 +15958,32 @@ fn intRem(
15804 lhs: Value,15958 lhs: Value,
15805 rhs: Value,15959 rhs: Value,
15806) CompileError!Value {15960) CompileError!Value {
15807 const mod = sema.mod;15961 const pt = sema.pt;
15962 const mod = pt.zcu;
15808 if (ty.zigTypeTag(mod) == .Vector) {15963 if (ty.zigTypeTag(mod) == .Vector) {
15809 const result_data = try sema.arena.alloc(InternPool.Index, ty.vectorLen(mod));15964 const result_data = try sema.arena.alloc(InternPool.Index, ty.vectorLen(mod));
15810 const scalar_ty = ty.scalarType(mod);15965 const scalar_ty = ty.scalarType(mod);
15811 for (result_data, 0..) |*scalar, i| {15966 for (result_data, 0..) |*scalar, i| {
15812 const lhs_elem = try lhs.elemValue(mod, i);15967 const lhs_elem = try lhs.elemValue(pt, i);
15813 const rhs_elem = try rhs.elemValue(mod, i);15968 const rhs_elem = try rhs.elemValue(pt, i);
15814 scalar.* = (try sema.intRemScalar(lhs_elem, rhs_elem, scalar_ty)).toIntern();15969 scalar.* = (try sema.intRemScalar(lhs_elem, rhs_elem, scalar_ty)).toIntern();
15815 }15970 }
15816 return Value.fromInterned((try mod.intern(.{ .aggregate = .{15971 return Value.fromInterned(try pt.intern(.{ .aggregate = .{
15817 .ty = ty.toIntern(),15972 .ty = ty.toIntern(),
15818 .storage = .{ .elems = result_data },15973 .storage = .{ .elems = result_data },
15819 } })));15974 } }));
15820 }15975 }
15821 return sema.intRemScalar(lhs, rhs, ty);15976 return sema.intRemScalar(lhs, rhs, ty);
15822}15977}
1582315978
15824fn intRemScalar(sema: *Sema, lhs: Value, rhs: Value, scalar_ty: Type) CompileError!Value {15979fn intRemScalar(sema: *Sema, lhs: Value, rhs: Value, scalar_ty: Type) CompileError!Value {
15825 const mod = sema.mod;15980 const pt = sema.pt;
15826 // TODO is this a performance issue? maybe we should try the operation without15981 // TODO is this a performance issue? maybe we should try the operation without
15827 // resorting to BigInt first.15982 // resorting to BigInt first.
15828 var lhs_space: Value.BigIntSpace = undefined;15983 var lhs_space: Value.BigIntSpace = undefined;
15829 var rhs_space: Value.BigIntSpace = undefined;15984 var rhs_space: Value.BigIntSpace = undefined;
15830 const lhs_bigint = try lhs.toBigIntAdvanced(&lhs_space, mod, .sema);15985 const lhs_bigint = try lhs.toBigIntAdvanced(&lhs_space, pt, .sema);
15831 const rhs_bigint = try rhs.toBigIntAdvanced(&rhs_space, mod, .sema);15986 const rhs_bigint = try rhs.toBigIntAdvanced(&rhs_space, pt, .sema);
15832 const limbs_q = try sema.arena.alloc(15987 const limbs_q = try sema.arena.alloc(
15833 math.big.Limb,15988 math.big.Limb,
15834 lhs_bigint.limbs.len,15989 lhs_bigint.limbs.len,
...@@ -15846,11 +16001,12 @@ fn intRemScalar(sema: *Sema, lhs: Value, rhs: Value, scalar_ty: Type) CompileErr...@@ -15846,11 +16001,12 @@ fn intRemScalar(sema: *Sema, lhs: Value, rhs: Value, scalar_ty: Type) CompileErr
15846 var result_q = math.big.int.Mutable{ .limbs = limbs_q, .positive = undefined, .len = undefined };16001 var result_q = math.big.int.Mutable{ .limbs = limbs_q, .positive = undefined, .len = undefined };
15847 var result_r = math.big.int.Mutable{ .limbs = limbs_r, .positive = undefined, .len = undefined };16002 var result_r = math.big.int.Mutable{ .limbs = limbs_r, .positive = undefined, .len = undefined };
15848 result_q.divTrunc(&result_r, lhs_bigint, rhs_bigint, limbs_buffer);16003 result_q.divTrunc(&result_r, lhs_bigint, rhs_bigint, limbs_buffer);
15849 return mod.intValue_big(scalar_ty, result_r.toConst());16004 return pt.intValue_big(scalar_ty, result_r.toConst());
15850}16005}
1585116006
15852fn zirMod(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {16007fn zirMod(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
15853 const mod = sema.mod;16008 const pt = sema.pt;
16009 const mod = pt.zcu;
15854 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;16010 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
15855 const src = block.src(.{ .node_offset_bin_op = inst_data.src_node });16011 const src = block.src(.{ .node_offset_bin_op = inst_data.src_node });
15856 const lhs_src = block.src(.{ .node_offset_bin_lhs = inst_data.src_node });16012 const lhs_src = block.src(.{ .node_offset_bin_lhs = inst_data.src_node });
...@@ -15904,11 +16060,11 @@ fn zirMod(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Ins...@@ -15904,11 +16060,11 @@ fn zirMod(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Ins
15904 if (rhs_val.isUndef(mod)) {16060 if (rhs_val.isUndef(mod)) {
15905 return sema.failWithUseOfUndef(block, rhs_src);16061 return sema.failWithUseOfUndef(block, rhs_src);
15906 }16062 }
15907 if (!(try rhs_val.compareAllWithZeroSema(.neq, mod))) {16063 if (!(try rhs_val.compareAllWithZeroSema(.neq, pt))) {
15908 return sema.failWithDivideByZero(block, rhs_src);16064 return sema.failWithDivideByZero(block, rhs_src);
15909 }16065 }
15910 if (maybe_lhs_val) |lhs_val| {16066 if (maybe_lhs_val) |lhs_val| {
15911 return Air.internedToRef((try lhs_val.intMod(rhs_val, resolved_type, sema.arena, mod)).toIntern());16067 return Air.internedToRef((try lhs_val.intMod(rhs_val, resolved_type, sema.arena, pt)).toIntern());
15912 }16068 }
15913 break :rs lhs_src;16069 break :rs lhs_src;
15914 } else {16070 } else {
...@@ -15920,16 +16076,16 @@ fn zirMod(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Ins...@@ -15920,16 +16076,16 @@ fn zirMod(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Ins
15920 if (rhs_val.isUndef(mod)) {16076 if (rhs_val.isUndef(mod)) {
15921 return sema.failWithUseOfUndef(block, rhs_src);16077 return sema.failWithUseOfUndef(block, rhs_src);
15922 }16078 }
15923 if (!(try rhs_val.compareAllWithZeroSema(.neq, mod))) {16079 if (!(try rhs_val.compareAllWithZeroSema(.neq, pt))) {
15924 return sema.failWithDivideByZero(block, rhs_src);16080 return sema.failWithDivideByZero(block, rhs_src);
15925 }16081 }
15926 }16082 }
15927 if (maybe_lhs_val) |lhs_val| {16083 if (maybe_lhs_val) |lhs_val| {
15928 if (lhs_val.isUndef(mod)) {16084 if (lhs_val.isUndef(mod)) {
15929 return mod.undefRef(resolved_type);16085 return pt.undefRef(resolved_type);
15930 }16086 }
15931 if (maybe_rhs_val) |rhs_val| {16087 if (maybe_rhs_val) |rhs_val| {
15932 return Air.internedToRef((try lhs_val.floatMod(rhs_val, resolved_type, sema.arena, mod)).toIntern());16088 return Air.internedToRef((try lhs_val.floatMod(rhs_val, resolved_type, sema.arena, pt)).toIntern());
15933 } else break :rs rhs_src;16089 } else break :rs rhs_src;
15934 } else break :rs lhs_src;16090 } else break :rs lhs_src;
15935 };16091 };
...@@ -15945,7 +16101,8 @@ fn zirMod(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Ins...@@ -15945,7 +16101,8 @@ fn zirMod(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Ins
15945}16101}
1594616102
15947fn zirRem(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {16103fn zirRem(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
15948 const mod = sema.mod;16104 const pt = sema.pt;
16105 const mod = pt.zcu;
15949 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;16106 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
15950 const src = block.src(.{ .node_offset_bin_op = inst_data.src_node });16107 const src = block.src(.{ .node_offset_bin_op = inst_data.src_node });
15951 const lhs_src = block.src(.{ .node_offset_bin_lhs = inst_data.src_node });16108 const lhs_src = block.src(.{ .node_offset_bin_lhs = inst_data.src_node });
...@@ -15999,7 +16156,7 @@ fn zirRem(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Ins...@@ -15999,7 +16156,7 @@ fn zirRem(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Ins
15999 if (rhs_val.isUndef(mod)) {16156 if (rhs_val.isUndef(mod)) {
16000 return sema.failWithUseOfUndef(block, rhs_src);16157 return sema.failWithUseOfUndef(block, rhs_src);
16001 }16158 }
16002 if (!(try rhs_val.compareAllWithZeroSema(.neq, mod))) {16159 if (!(try rhs_val.compareAllWithZeroSema(.neq, pt))) {
16003 return sema.failWithDivideByZero(block, rhs_src);16160 return sema.failWithDivideByZero(block, rhs_src);
16004 }16161 }
16005 if (maybe_lhs_val) |lhs_val| {16162 if (maybe_lhs_val) |lhs_val| {
...@@ -16015,16 +16172,16 @@ fn zirRem(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Ins...@@ -16015,16 +16172,16 @@ fn zirRem(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Ins
16015 if (rhs_val.isUndef(mod)) {16172 if (rhs_val.isUndef(mod)) {
16016 return sema.failWithUseOfUndef(block, rhs_src);16173 return sema.failWithUseOfUndef(block, rhs_src);
16017 }16174 }
16018 if (!(try rhs_val.compareAllWithZeroSema(.neq, mod))) {16175 if (!(try rhs_val.compareAllWithZeroSema(.neq, pt))) {
16019 return sema.failWithDivideByZero(block, rhs_src);16176 return sema.failWithDivideByZero(block, rhs_src);
16020 }16177 }
16021 }16178 }
16022 if (maybe_lhs_val) |lhs_val| {16179 if (maybe_lhs_val) |lhs_val| {
16023 if (lhs_val.isUndef(mod)) {16180 if (lhs_val.isUndef(mod)) {
16024 return mod.undefRef(resolved_type);16181 return pt.undefRef(resolved_type);
16025 }16182 }
16026 if (maybe_rhs_val) |rhs_val| {16183 if (maybe_rhs_val) |rhs_val| {
16027 return Air.internedToRef((try lhs_val.floatRem(rhs_val, resolved_type, sema.arena, mod)).toIntern());16184 return Air.internedToRef((try lhs_val.floatRem(rhs_val, resolved_type, sema.arena, pt)).toIntern());
16028 } else break :rs rhs_src;16185 } else break :rs rhs_src;
16029 } else break :rs lhs_src;16186 } else break :rs lhs_src;
16030 };16187 };
...@@ -16059,7 +16216,8 @@ fn zirOverflowArithmetic(...@@ -16059,7 +16216,8 @@ fn zirOverflowArithmetic(
1605916216
16060 const lhs_ty = sema.typeOf(uncasted_lhs);16217 const lhs_ty = sema.typeOf(uncasted_lhs);
16061 const rhs_ty = sema.typeOf(uncasted_rhs);16218 const rhs_ty = sema.typeOf(uncasted_rhs);
16062 const mod = sema.mod;16219 const pt = sema.pt;
16220 const mod = pt.zcu;
16063 const ip = &mod.intern_pool;16221 const ip = &mod.intern_pool;
1606416222
16065 try sema.checkVectorizableBinaryOperands(block, src, lhs_ty, rhs_ty, lhs_src, rhs_src);16223 try sema.checkVectorizableBinaryOperands(block, src, lhs_ty, rhs_ty, lhs_src, rhs_src);
...@@ -16081,7 +16239,7 @@ fn zirOverflowArithmetic(...@@ -16081,7 +16239,7 @@ fn zirOverflowArithmetic(
16081 const rhs = try sema.coerce(block, rhs_dest_ty, uncasted_rhs, rhs_src);16239 const rhs = try sema.coerce(block, rhs_dest_ty, uncasted_rhs, rhs_src);
1608216240
16083 if (dest_ty.scalarType(mod).zigTypeTag(mod) != .Int) {16241 if (dest_ty.scalarType(mod).zigTypeTag(mod) != .Int) {
16084 return sema.fail(block, src, "expected vector of integers or integer tag type, found '{}'", .{dest_ty.fmt(mod)});16242 return sema.fail(block, src, "expected vector of integers or integer tag type, found '{}'", .{dest_ty.fmt(pt)});
16085 }16243 }
1608616244
16087 const maybe_lhs_val = try sema.resolveValue(lhs);16245 const maybe_lhs_val = try sema.resolveValue(lhs);
...@@ -16095,19 +16253,19 @@ fn zirOverflowArithmetic(...@@ -16095,19 +16253,19 @@ fn zirOverflowArithmetic(
16095 wrapped: Value = Value.@"unreachable",16253 wrapped: Value = Value.@"unreachable",
16096 overflow_bit: Value,16254 overflow_bit: Value,
16097 } = result: {16255 } = result: {
16098 const zero_bit = try mod.intValue(Type.u1, 0);16256 const zero_bit = try pt.intValue(Type.u1, 0);
16099 switch (zir_tag) {16257 switch (zir_tag) {
16100 .add_with_overflow => {16258 .add_with_overflow => {
16101 // If either of the arguments is zero, `false` is returned and the other is stored16259 // If either of the arguments is zero, `false` is returned and the other is stored
16102 // to the result, even if it is undefined..16260 // to the result, even if it is undefined..
16103 // Otherwise, if either of the argument is undefined, undefined is returned.16261 // Otherwise, if either of the argument is undefined, undefined is returned.
16104 if (maybe_lhs_val) |lhs_val| {16262 if (maybe_lhs_val) |lhs_val| {
16105 if (!lhs_val.isUndef(mod) and (try lhs_val.compareAllWithZeroSema(.eq, mod))) {16263 if (!lhs_val.isUndef(mod) and (try lhs_val.compareAllWithZeroSema(.eq, pt))) {
16106 break :result .{ .overflow_bit = try sema.splat(overflow_ty, zero_bit), .inst = rhs };16264 break :result .{ .overflow_bit = try sema.splat(overflow_ty, zero_bit), .inst = rhs };
16107 }16265 }
16108 }16266 }
16109 if (maybe_rhs_val) |rhs_val| {16267 if (maybe_rhs_val) |rhs_val| {
16110 if (!rhs_val.isUndef(mod) and (try rhs_val.compareAllWithZeroSema(.eq, mod))) {16268 if (!rhs_val.isUndef(mod) and (try rhs_val.compareAllWithZeroSema(.eq, pt))) {
16111 break :result .{ .overflow_bit = try sema.splat(overflow_ty, zero_bit), .inst = lhs };16269 break :result .{ .overflow_bit = try sema.splat(overflow_ty, zero_bit), .inst = lhs };
16112 }16270 }
16113 }16271 }
...@@ -16128,7 +16286,7 @@ fn zirOverflowArithmetic(...@@ -16128,7 +16286,7 @@ fn zirOverflowArithmetic(
16128 if (maybe_rhs_val) |rhs_val| {16286 if (maybe_rhs_val) |rhs_val| {
16129 if (rhs_val.isUndef(mod)) {16287 if (rhs_val.isUndef(mod)) {
16130 break :result .{ .overflow_bit = Value.undef, .wrapped = Value.undef };16288 break :result .{ .overflow_bit = Value.undef, .wrapped = Value.undef };
16131 } else if (try rhs_val.compareAllWithZeroSema(.eq, mod)) {16289 } else if (try rhs_val.compareAllWithZeroSema(.eq, pt)) {
16132 break :result .{ .overflow_bit = try sema.splat(overflow_ty, zero_bit), .inst = lhs };16290 break :result .{ .overflow_bit = try sema.splat(overflow_ty, zero_bit), .inst = lhs };
16133 } else if (maybe_lhs_val) |lhs_val| {16291 } else if (maybe_lhs_val) |lhs_val| {
16134 if (lhs_val.isUndef(mod)) {16292 if (lhs_val.isUndef(mod)) {
...@@ -16144,10 +16302,10 @@ fn zirOverflowArithmetic(...@@ -16144,10 +16302,10 @@ fn zirOverflowArithmetic(
16144 // If either of the arguments is zero, the result is zero and no overflow occured.16302 // If either of the arguments is zero, the result is zero and no overflow occured.
16145 // If either of the arguments is one, the result is the other and no overflow occured.16303 // If either of the arguments is one, the result is the other and no overflow occured.
16146 // Otherwise, if either of the arguments is undefined, both results are undefined.16304 // Otherwise, if either of the arguments is undefined, both results are undefined.
16147 const scalar_one = try mod.intValue(dest_ty.scalarType(mod), 1);16305 const scalar_one = try pt.intValue(dest_ty.scalarType(mod), 1);
16148 if (maybe_lhs_val) |lhs_val| {16306 if (maybe_lhs_val) |lhs_val| {
16149 if (!lhs_val.isUndef(mod)) {16307 if (!lhs_val.isUndef(mod)) {
16150 if (try lhs_val.compareAllWithZeroSema(.eq, mod)) {16308 if (try lhs_val.compareAllWithZeroSema(.eq, pt)) {
16151 break :result .{ .overflow_bit = try sema.splat(overflow_ty, zero_bit), .inst = lhs };16309 break :result .{ .overflow_bit = try sema.splat(overflow_ty, zero_bit), .inst = lhs };
16152 } else if (try sema.compareAll(lhs_val, .eq, try sema.splat(dest_ty, scalar_one), dest_ty)) {16310 } else if (try sema.compareAll(lhs_val, .eq, try sema.splat(dest_ty, scalar_one), dest_ty)) {
16153 break :result .{ .overflow_bit = try sema.splat(overflow_ty, zero_bit), .inst = rhs };16311 break :result .{ .overflow_bit = try sema.splat(overflow_ty, zero_bit), .inst = rhs };
...@@ -16157,7 +16315,7 @@ fn zirOverflowArithmetic(...@@ -16157,7 +16315,7 @@ fn zirOverflowArithmetic(
1615716315
16158 if (maybe_rhs_val) |rhs_val| {16316 if (maybe_rhs_val) |rhs_val| {
16159 if (!rhs_val.isUndef(mod)) {16317 if (!rhs_val.isUndef(mod)) {
16160 if (try rhs_val.compareAllWithZeroSema(.eq, mod)) {16318 if (try rhs_val.compareAllWithZeroSema(.eq, pt)) {
16161 break :result .{ .overflow_bit = try sema.splat(overflow_ty, zero_bit), .inst = rhs };16319 break :result .{ .overflow_bit = try sema.splat(overflow_ty, zero_bit), .inst = rhs };
16162 } else if (try sema.compareAll(rhs_val, .eq, try sema.splat(dest_ty, scalar_one), dest_ty)) {16320 } else if (try sema.compareAll(rhs_val, .eq, try sema.splat(dest_ty, scalar_one), dest_ty)) {
16163 break :result .{ .overflow_bit = try sema.splat(overflow_ty, zero_bit), .inst = lhs };16321 break :result .{ .overflow_bit = try sema.splat(overflow_ty, zero_bit), .inst = lhs };
...@@ -16171,7 +16329,7 @@ fn zirOverflowArithmetic(...@@ -16171,7 +16329,7 @@ fn zirOverflowArithmetic(
16171 break :result .{ .overflow_bit = Value.undef, .wrapped = Value.undef };16329 break :result .{ .overflow_bit = Value.undef, .wrapped = Value.undef };
16172 }16330 }
1617316331
16174 const result = try lhs_val.intMulWithOverflow(rhs_val, dest_ty, sema.arena, mod);16332 const result = try lhs_val.intMulWithOverflow(rhs_val, dest_ty, sema.arena, pt);
16175 break :result .{ .overflow_bit = result.overflow_bit, .wrapped = result.wrapped_result };16333 break :result .{ .overflow_bit = result.overflow_bit, .wrapped = result.wrapped_result };
16176 }16334 }
16177 }16335 }
...@@ -16181,12 +16339,12 @@ fn zirOverflowArithmetic(...@@ -16181,12 +16339,12 @@ fn zirOverflowArithmetic(
16181 // If rhs is zero, the result is lhs (even if undefined) and no overflow occurred.16339 // If rhs is zero, the result is lhs (even if undefined) and no overflow occurred.
16182 // Oterhwise if either of the arguments is undefined, both results are undefined.16340 // Oterhwise if either of the arguments is undefined, both results are undefined.
16183 if (maybe_lhs_val) |lhs_val| {16341 if (maybe_lhs_val) |lhs_val| {
16184 if (!lhs_val.isUndef(mod) and (try lhs_val.compareAllWithZeroSema(.eq, mod))) {16342 if (!lhs_val.isUndef(mod) and (try lhs_val.compareAllWithZeroSema(.eq, pt))) {
16185 break :result .{ .overflow_bit = try sema.splat(overflow_ty, zero_bit), .inst = lhs };16343 break :result .{ .overflow_bit = try sema.splat(overflow_ty, zero_bit), .inst = lhs };
16186 }16344 }
16187 }16345 }
16188 if (maybe_rhs_val) |rhs_val| {16346 if (maybe_rhs_val) |rhs_val| {
16189 if (!rhs_val.isUndef(mod) and (try rhs_val.compareAllWithZeroSema(.eq, mod))) {16347 if (!rhs_val.isUndef(mod) and (try rhs_val.compareAllWithZeroSema(.eq, pt))) {
16190 break :result .{ .overflow_bit = try sema.splat(overflow_ty, zero_bit), .inst = lhs };16348 break :result .{ .overflow_bit = try sema.splat(overflow_ty, zero_bit), .inst = lhs };
16191 }16349 }
16192 }16350 }
...@@ -16196,7 +16354,7 @@ fn zirOverflowArithmetic(...@@ -16196,7 +16354,7 @@ fn zirOverflowArithmetic(
16196 break :result .{ .overflow_bit = Value.undef, .wrapped = Value.undef };16354 break :result .{ .overflow_bit = Value.undef, .wrapped = Value.undef };
16197 }16355 }
1619816356
16199 const result = try lhs_val.shlWithOverflow(rhs_val, dest_ty, sema.arena, mod);16357 const result = try lhs_val.shlWithOverflow(rhs_val, dest_ty, sema.arena, pt);
16200 break :result .{ .overflow_bit = result.overflow_bit, .wrapped = result.wrapped_result };16358 break :result .{ .overflow_bit = result.overflow_bit, .wrapped = result.wrapped_result };
16201 }16359 }
16202 }16360 }
...@@ -16235,7 +16393,7 @@ fn zirOverflowArithmetic(...@@ -16235,7 +16393,7 @@ fn zirOverflowArithmetic(
16235 }16393 }
1623616394
16237 if (result.inst == .none) {16395 if (result.inst == .none) {
16238 return Air.internedToRef((try mod.intern(.{ .aggregate = .{16396 return Air.internedToRef((try pt.intern(.{ .aggregate = .{
16239 .ty = tuple_ty.toIntern(),16397 .ty = tuple_ty.toIntern(),
16240 .storage = .{ .elems = &.{16398 .storage = .{ .elems = &.{
16241 result.wrapped.toIntern(),16399 result.wrapped.toIntern(),
...@@ -16251,9 +16409,10 @@ fn zirOverflowArithmetic(...@@ -16251,9 +16409,10 @@ fn zirOverflowArithmetic(
16251}16409}
1625216410
16253fn splat(sema: *Sema, ty: Type, val: Value) !Value {16411fn splat(sema: *Sema, ty: Type, val: Value) !Value {
16254 const mod = sema.mod;16412 const pt = sema.pt;
16413 const mod = pt.zcu;
16255 if (ty.zigTypeTag(mod) != .Vector) return val;16414 if (ty.zigTypeTag(mod) != .Vector) return val;
16256 const repeated = try mod.intern(.{ .aggregate = .{16415 const repeated = try pt.intern(.{ .aggregate = .{
16257 .ty = ty.toIntern(),16416 .ty = ty.toIntern(),
16258 .storage = .{ .repeated_elem = val.toIntern() },16417 .storage = .{ .repeated_elem = val.toIntern() },
16259 } });16418 } });
...@@ -16261,16 +16420,17 @@ fn splat(sema: *Sema, ty: Type, val: Value) !Value {...@@ -16261,16 +16420,17 @@ fn splat(sema: *Sema, ty: Type, val: Value) !Value {
16261}16420}
1626216421
16263fn overflowArithmeticTupleType(sema: *Sema, ty: Type) !Type {16422fn overflowArithmeticTupleType(sema: *Sema, ty: Type) !Type {
16264 const mod = sema.mod;16423 const pt = sema.pt;
16424 const mod = pt.zcu;
16265 const ip = &mod.intern_pool;16425 const ip = &mod.intern_pool;
16266 const ov_ty = if (ty.zigTypeTag(mod) == .Vector) try mod.vectorType(.{16426 const ov_ty = if (ty.zigTypeTag(mod) == .Vector) try pt.vectorType(.{
16267 .len = ty.vectorLen(mod),16427 .len = ty.vectorLen(mod),
16268 .child = .u1_type,16428 .child = .u1_type,
16269 }) else Type.u1;16429 }) else Type.u1;
1627016430
16271 const types = [2]InternPool.Index{ ty.toIntern(), ov_ty.toIntern() };16431 const types = [2]InternPool.Index{ ty.toIntern(), ov_ty.toIntern() };
16272 const values = [2]InternPool.Index{ .none, .none };16432 const values = [2]InternPool.Index{ .none, .none };
16273 const tuple_ty = try ip.getAnonStructType(mod.gpa, .{16433 const tuple_ty = try ip.getAnonStructType(mod.gpa, pt.tid, .{
16274 .types = &types,16434 .types = &types,
16275 .values = &values,16435 .values = &values,
16276 .names = &.{},16436 .names = &.{},
...@@ -16290,7 +16450,8 @@ fn analyzeArithmetic(...@@ -16290,7 +16450,8 @@ fn analyzeArithmetic(
16290 rhs_src: LazySrcLoc,16450 rhs_src: LazySrcLoc,
16291 want_safety: bool,16451 want_safety: bool,
16292) CompileError!Air.Inst.Ref {16452) CompileError!Air.Inst.Ref {
16293 const mod = sema.mod;16453 const pt = sema.pt;
16454 const mod = pt.zcu;
16294 const lhs_ty = sema.typeOf(lhs);16455 const lhs_ty = sema.typeOf(lhs);
16295 const rhs_ty = sema.typeOf(rhs);16456 const rhs_ty = sema.typeOf(rhs);
16296 const lhs_zig_ty_tag = try lhs_ty.zigTypeTagOrPoison(mod);16457 const lhs_zig_ty_tag = try lhs_ty.zigTypeTagOrPoison(mod);
...@@ -16337,7 +16498,7 @@ fn analyzeArithmetic(...@@ -16337,7 +16498,7 @@ fn analyzeArithmetic(
16337 // overflow (max_int), causing illegal behavior.16498 // overflow (max_int), causing illegal behavior.
16338 // For floats: either operand being undef makes the result undef.16499 // For floats: either operand being undef makes the result undef.
16339 if (maybe_lhs_val) |lhs_val| {16500 if (maybe_lhs_val) |lhs_val| {
16340 if (!lhs_val.isUndef(mod) and (try lhs_val.compareAllWithZeroSema(.eq, mod))) {16501 if (!lhs_val.isUndef(mod) and (try lhs_val.compareAllWithZeroSema(.eq, pt))) {
16341 return casted_rhs;16502 return casted_rhs;
16342 }16503 }
16343 }16504 }
...@@ -16346,10 +16507,10 @@ fn analyzeArithmetic(...@@ -16346,10 +16507,10 @@ fn analyzeArithmetic(
16346 if (is_int) {16507 if (is_int) {
16347 return sema.failWithUseOfUndef(block, rhs_src);16508 return sema.failWithUseOfUndef(block, rhs_src);
16348 } else {16509 } else {
16349 return mod.undefRef(resolved_type);16510 return pt.undefRef(resolved_type);
16350 }16511 }
16351 }16512 }
16352 if (try rhs_val.compareAllWithZeroSema(.eq, mod)) {16513 if (try rhs_val.compareAllWithZeroSema(.eq, pt)) {
16353 return casted_lhs;16514 return casted_lhs;
16354 }16515 }
16355 }16516 }
...@@ -16359,7 +16520,7 @@ fn analyzeArithmetic(...@@ -16359,7 +16520,7 @@ fn analyzeArithmetic(
16359 if (is_int) {16520 if (is_int) {
16360 return sema.failWithUseOfUndef(block, lhs_src);16521 return sema.failWithUseOfUndef(block, lhs_src);
16361 } else {16522 } else {
16362 return mod.undefRef(resolved_type);16523 return pt.undefRef(resolved_type);
16363 }16524 }
16364 }16525 }
16365 if (maybe_rhs_val) |rhs_val| {16526 if (maybe_rhs_val) |rhs_val| {
...@@ -16371,7 +16532,7 @@ fn analyzeArithmetic(...@@ -16371,7 +16532,7 @@ fn analyzeArithmetic(
16371 }16532 }
16372 return Air.internedToRef(sum.toIntern());16533 return Air.internedToRef(sum.toIntern());
16373 } else {16534 } else {
16374 return Air.internedToRef((try Value.floatAdd(lhs_val, rhs_val, resolved_type, sema.arena, mod)).toIntern());16535 return Air.internedToRef((try Value.floatAdd(lhs_val, rhs_val, resolved_type, sema.arena, pt)).toIntern());
16375 }16536 }
16376 } else break :rs .{ rhs_src, air_tag, .add_safe };16537 } else break :rs .{ rhs_src, air_tag, .add_safe };
16377 } else break :rs .{ lhs_src, air_tag, .add_safe };16538 } else break :rs .{ lhs_src, air_tag, .add_safe };
...@@ -16381,15 +16542,15 @@ fn analyzeArithmetic(...@@ -16381,15 +16542,15 @@ fn analyzeArithmetic(
16381 // If either of the operands are zero, the other operand is returned.16542 // If either of the operands are zero, the other operand is returned.
16382 // If either of the operands are undefined, the result is undefined.16543 // If either of the operands are undefined, the result is undefined.
16383 if (maybe_lhs_val) |lhs_val| {16544 if (maybe_lhs_val) |lhs_val| {
16384 if (!lhs_val.isUndef(mod) and (try lhs_val.compareAllWithZeroSema(.eq, mod))) {16545 if (!lhs_val.isUndef(mod) and (try lhs_val.compareAllWithZeroSema(.eq, pt))) {
16385 return casted_rhs;16546 return casted_rhs;
16386 }16547 }
16387 }16548 }
16388 if (maybe_rhs_val) |rhs_val| {16549 if (maybe_rhs_val) |rhs_val| {
16389 if (rhs_val.isUndef(mod)) {16550 if (rhs_val.isUndef(mod)) {
16390 return mod.undefRef(resolved_type);16551 return pt.undefRef(resolved_type);
16391 }16552 }
16392 if (try rhs_val.compareAllWithZeroSema(.eq, mod)) {16553 if (try rhs_val.compareAllWithZeroSema(.eq, pt)) {
16393 return casted_lhs;16554 return casted_lhs;
16394 }16555 }
16395 if (maybe_lhs_val) |lhs_val| {16556 if (maybe_lhs_val) |lhs_val| {
...@@ -16402,26 +16563,26 @@ fn analyzeArithmetic(...@@ -16402,26 +16563,26 @@ fn analyzeArithmetic(
16402 // If either of the operands are zero, then the other operand is returned.16563 // If either of the operands are zero, then the other operand is returned.
16403 // If either of the operands are undefined, the result is undefined.16564 // If either of the operands are undefined, the result is undefined.
16404 if (maybe_lhs_val) |lhs_val| {16565 if (maybe_lhs_val) |lhs_val| {
16405 if (!lhs_val.isUndef(mod) and (try lhs_val.compareAllWithZeroSema(.eq, mod))) {16566 if (!lhs_val.isUndef(mod) and (try lhs_val.compareAllWithZeroSema(.eq, pt))) {
16406 return casted_rhs;16567 return casted_rhs;
16407 }16568 }
16408 }16569 }
16409 if (maybe_rhs_val) |rhs_val| {16570 if (maybe_rhs_val) |rhs_val| {
16410 if (rhs_val.isUndef(mod)) {16571 if (rhs_val.isUndef(mod)) {
16411 return mod.undefRef(resolved_type);16572 return pt.undefRef(resolved_type);
16412 }16573 }
16413 if (try rhs_val.compareAllWithZeroSema(.eq, mod)) {16574 if (try rhs_val.compareAllWithZeroSema(.eq, pt)) {
16414 return casted_lhs;16575 return casted_lhs;
16415 }16576 }
16416 if (maybe_lhs_val) |lhs_val| {16577 if (maybe_lhs_val) |lhs_val| {
16417 if (lhs_val.isUndef(mod)) {16578 if (lhs_val.isUndef(mod)) {
16418 return mod.undefRef(resolved_type);16579 return pt.undefRef(resolved_type);
16419 }16580 }
1642016581
16421 const val = if (scalar_tag == .ComptimeInt)16582 const val = if (scalar_tag == .ComptimeInt)
16422 try sema.intAdd(lhs_val, rhs_val, resolved_type, undefined)16583 try sema.intAdd(lhs_val, rhs_val, resolved_type, undefined)
16423 else16584 else
16424 try lhs_val.intAddSat(rhs_val, resolved_type, sema.arena, mod);16585 try lhs_val.intAddSat(rhs_val, resolved_type, sema.arena, pt);
1642516586
16426 return Air.internedToRef(val.toIntern());16587 return Air.internedToRef(val.toIntern());
16427 } else break :rs .{16588 } else break :rs .{
...@@ -16448,10 +16609,10 @@ fn analyzeArithmetic(...@@ -16448,10 +16609,10 @@ fn analyzeArithmetic(
16448 if (is_int) {16609 if (is_int) {
16449 return sema.failWithUseOfUndef(block, rhs_src);16610 return sema.failWithUseOfUndef(block, rhs_src);
16450 } else {16611 } else {
16451 return mod.undefRef(resolved_type);16612 return pt.undefRef(resolved_type);
16452 }16613 }
16453 }16614 }
16454 if (try rhs_val.compareAllWithZeroSema(.eq, mod)) {16615 if (try rhs_val.compareAllWithZeroSema(.eq, pt)) {
16455 return casted_lhs;16616 return casted_lhs;
16456 }16617 }
16457 }16618 }
...@@ -16461,7 +16622,7 @@ fn analyzeArithmetic(...@@ -16461,7 +16622,7 @@ fn analyzeArithmetic(
16461 if (is_int) {16622 if (is_int) {
16462 return sema.failWithUseOfUndef(block, lhs_src);16623 return sema.failWithUseOfUndef(block, lhs_src);
16463 } else {16624 } else {
16464 return mod.undefRef(resolved_type);16625 return pt.undefRef(resolved_type);
16465 }16626 }
16466 }16627 }
16467 if (maybe_rhs_val) |rhs_val| {16628 if (maybe_rhs_val) |rhs_val| {
...@@ -16473,7 +16634,7 @@ fn analyzeArithmetic(...@@ -16473,7 +16634,7 @@ fn analyzeArithmetic(
16473 }16634 }
16474 return Air.internedToRef(diff.toIntern());16635 return Air.internedToRef(diff.toIntern());
16475 } else {16636 } else {
16476 return Air.internedToRef((try Value.floatSub(lhs_val, rhs_val, resolved_type, sema.arena, mod)).toIntern());16637 return Air.internedToRef((try Value.floatSub(lhs_val, rhs_val, resolved_type, sema.arena, pt)).toIntern());
16477 }16638 }
16478 } else break :rs .{ rhs_src, air_tag, .sub_safe };16639 } else break :rs .{ rhs_src, air_tag, .sub_safe };
16479 } else break :rs .{ lhs_src, air_tag, .sub_safe };16640 } else break :rs .{ lhs_src, air_tag, .sub_safe };
...@@ -16484,15 +16645,15 @@ fn analyzeArithmetic(...@@ -16484,15 +16645,15 @@ fn analyzeArithmetic(
16484 // If either of the operands are undefined, the result is undefined.16645 // If either of the operands are undefined, the result is undefined.
16485 if (maybe_rhs_val) |rhs_val| {16646 if (maybe_rhs_val) |rhs_val| {
16486 if (rhs_val.isUndef(mod)) {16647 if (rhs_val.isUndef(mod)) {
16487 return mod.undefRef(resolved_type);16648 return pt.undefRef(resolved_type);
16488 }16649 }
16489 if (try rhs_val.compareAllWithZeroSema(.eq, mod)) {16650 if (try rhs_val.compareAllWithZeroSema(.eq, pt)) {
16490 return casted_lhs;16651 return casted_lhs;
16491 }16652 }
16492 }16653 }
16493 if (maybe_lhs_val) |lhs_val| {16654 if (maybe_lhs_val) |lhs_val| {
16494 if (lhs_val.isUndef(mod)) {16655 if (lhs_val.isUndef(mod)) {
16495 return mod.undefRef(resolved_type);16656 return pt.undefRef(resolved_type);
16496 }16657 }
16497 if (maybe_rhs_val) |rhs_val| {16658 if (maybe_rhs_val) |rhs_val| {
16498 return Air.internedToRef((try sema.numberSubWrapScalar(lhs_val, rhs_val, resolved_type)).toIntern());16659 return Air.internedToRef((try sema.numberSubWrapScalar(lhs_val, rhs_val, resolved_type)).toIntern());
...@@ -16505,21 +16666,21 @@ fn analyzeArithmetic(...@@ -16505,21 +16666,21 @@ fn analyzeArithmetic(
16505 // If either of the operands are undefined, the result is undefined.16666 // If either of the operands are undefined, the result is undefined.
16506 if (maybe_rhs_val) |rhs_val| {16667 if (maybe_rhs_val) |rhs_val| {
16507 if (rhs_val.isUndef(mod)) {16668 if (rhs_val.isUndef(mod)) {
16508 return mod.undefRef(resolved_type);16669 return pt.undefRef(resolved_type);
16509 }16670 }
16510 if (try rhs_val.compareAllWithZeroSema(.eq, mod)) {16671 if (try rhs_val.compareAllWithZeroSema(.eq, pt)) {
16511 return casted_lhs;16672 return casted_lhs;
16512 }16673 }
16513 }16674 }
16514 if (maybe_lhs_val) |lhs_val| {16675 if (maybe_lhs_val) |lhs_val| {
16515 if (lhs_val.isUndef(mod)) {16676 if (lhs_val.isUndef(mod)) {
16516 return mod.undefRef(resolved_type);16677 return pt.undefRef(resolved_type);
16517 }16678 }
16518 if (maybe_rhs_val) |rhs_val| {16679 if (maybe_rhs_val) |rhs_val| {
16519 const val = if (scalar_tag == .ComptimeInt)16680 const val = if (scalar_tag == .ComptimeInt)
16520 try sema.intSub(lhs_val, rhs_val, resolved_type, undefined)16681 try sema.intSub(lhs_val, rhs_val, resolved_type, undefined)
16521 else16682 else
16522 try lhs_val.intSubSat(rhs_val, resolved_type, sema.arena, mod);16683 try lhs_val.intSubSat(rhs_val, resolved_type, sema.arena, pt);
1652316684
16524 return Air.internedToRef(val.toIntern());16685 return Air.internedToRef(val.toIntern());
16525 } else break :rs .{ rhs_src, .sub_sat, .sub_sat };16686 } else break :rs .{ rhs_src, .sub_sat, .sub_sat };
...@@ -16540,13 +16701,13 @@ fn analyzeArithmetic(...@@ -16540,13 +16701,13 @@ fn analyzeArithmetic(
16540 // the result is nan.16701 // the result is nan.
16541 // If either of the operands are nan, the result is nan.16702 // If either of the operands are nan, the result is nan.
16542 const scalar_zero = switch (scalar_tag) {16703 const scalar_zero = switch (scalar_tag) {
16543 .ComptimeFloat, .Float => try mod.floatValue(scalar_type, 0.0),16704 .ComptimeFloat, .Float => try pt.floatValue(scalar_type, 0.0),
16544 .ComptimeInt, .Int => try mod.intValue(scalar_type, 0),16705 .ComptimeInt, .Int => try pt.intValue(scalar_type, 0),
16545 else => unreachable,16706 else => unreachable,
16546 };16707 };
16547 const scalar_one = switch (scalar_tag) {16708 const scalar_one = switch (scalar_tag) {
16548 .ComptimeFloat, .Float => try mod.floatValue(scalar_type, 1.0),16709 .ComptimeFloat, .Float => try pt.floatValue(scalar_type, 1.0),
16549 .ComptimeInt, .Int => try mod.intValue(scalar_type, 1),16710 .ComptimeInt, .Int => try pt.intValue(scalar_type, 1),
16550 else => unreachable,16711 else => unreachable,
16551 };16712 };
16552 if (maybe_lhs_val) |lhs_val| {16713 if (maybe_lhs_val) |lhs_val| {
...@@ -16554,13 +16715,13 @@ fn analyzeArithmetic(...@@ -16554,13 +16715,13 @@ fn analyzeArithmetic(
16554 if (lhs_val.isNan(mod)) {16715 if (lhs_val.isNan(mod)) {
16555 return Air.internedToRef(lhs_val.toIntern());16716 return Air.internedToRef(lhs_val.toIntern());
16556 }16717 }
16557 if (try lhs_val.compareAllWithZeroSema(.eq, mod)) lz: {16718 if (try lhs_val.compareAllWithZeroSema(.eq, pt)) lz: {
16558 if (maybe_rhs_val) |rhs_val| {16719 if (maybe_rhs_val) |rhs_val| {
16559 if (rhs_val.isNan(mod)) {16720 if (rhs_val.isNan(mod)) {
16560 return Air.internedToRef(rhs_val.toIntern());16721 return Air.internedToRef(rhs_val.toIntern());
16561 }16722 }
16562 if (rhs_val.isInf(mod)) {16723 if (rhs_val.isInf(mod)) {
16563 return Air.internedToRef((try mod.floatValue(resolved_type, std.math.nan(f128))).toIntern());16724 return Air.internedToRef((try pt.floatValue(resolved_type, std.math.nan(f128))).toIntern());
16564 }16725 }
16565 } else if (resolved_type.isAnyFloat()) {16726 } else if (resolved_type.isAnyFloat()) {
16566 break :lz;16727 break :lz;
...@@ -16579,16 +16740,16 @@ fn analyzeArithmetic(...@@ -16579,16 +16740,16 @@ fn analyzeArithmetic(
16579 if (is_int) {16740 if (is_int) {
16580 return sema.failWithUseOfUndef(block, rhs_src);16741 return sema.failWithUseOfUndef(block, rhs_src);
16581 } else {16742 } else {
16582 return mod.undefRef(resolved_type);16743 return pt.undefRef(resolved_type);
16583 }16744 }
16584 }16745 }
16585 if (rhs_val.isNan(mod)) {16746 if (rhs_val.isNan(mod)) {
16586 return Air.internedToRef(rhs_val.toIntern());16747 return Air.internedToRef(rhs_val.toIntern());
16587 }16748 }
16588 if (try rhs_val.compareAllWithZeroSema(.eq, mod)) rz: {16749 if (try rhs_val.compareAllWithZeroSema(.eq, pt)) rz: {
16589 if (maybe_lhs_val) |lhs_val| {16750 if (maybe_lhs_val) |lhs_val| {
16590 if (lhs_val.isInf(mod)) {16751 if (lhs_val.isInf(mod)) {
16591 return Air.internedToRef((try mod.floatValue(resolved_type, std.math.nan(f128))).toIntern());16752 return Air.internedToRef((try pt.floatValue(resolved_type, std.math.nan(f128))).toIntern());
16592 }16753 }
16593 } else if (resolved_type.isAnyFloat()) {16754 } else if (resolved_type.isAnyFloat()) {
16594 break :rz;16755 break :rz;
...@@ -16604,18 +16765,18 @@ fn analyzeArithmetic(...@@ -16604,18 +16765,18 @@ fn analyzeArithmetic(
16604 if (is_int) {16765 if (is_int) {
16605 return sema.failWithUseOfUndef(block, lhs_src);16766 return sema.failWithUseOfUndef(block, lhs_src);
16606 } else {16767 } else {
16607 return mod.undefRef(resolved_type);16768 return pt.undefRef(resolved_type);
16608 }16769 }
16609 }16770 }
16610 if (is_int) {16771 if (is_int) {
16611 var overflow_idx: ?usize = null;16772 var overflow_idx: ?usize = null;
16612 const product = try lhs_val.intMul(rhs_val, resolved_type, &overflow_idx, sema.arena, mod);16773 const product = try lhs_val.intMul(rhs_val, resolved_type, &overflow_idx, sema.arena, pt);
16613 if (overflow_idx) |vec_idx| {16774 if (overflow_idx) |vec_idx| {
16614 return sema.failWithIntegerOverflow(block, src, resolved_type, product, vec_idx);16775 return sema.failWithIntegerOverflow(block, src, resolved_type, product, vec_idx);
16615 }16776 }
16616 return Air.internedToRef(product.toIntern());16777 return Air.internedToRef(product.toIntern());
16617 } else {16778 } else {
16618 return Air.internedToRef((try lhs_val.floatMul(rhs_val, resolved_type, sema.arena, mod)).toIntern());16779 return Air.internedToRef((try lhs_val.floatMul(rhs_val, resolved_type, sema.arena, pt)).toIntern());
16619 }16780 }
16620 } else break :rs .{ lhs_src, air_tag, .mul_safe };16781 } else break :rs .{ lhs_src, air_tag, .mul_safe };
16621 } else break :rs .{ rhs_src, air_tag, .mul_safe };16782 } else break :rs .{ rhs_src, air_tag, .mul_safe };
...@@ -16626,18 +16787,18 @@ fn analyzeArithmetic(...@@ -16626,18 +16787,18 @@ fn analyzeArithmetic(
16626 // If either of the operands are one, result is the other operand.16787 // If either of the operands are one, result is the other operand.
16627 // If either of the operands are undefined, result is undefined.16788 // If either of the operands are undefined, result is undefined.
16628 const scalar_zero = switch (scalar_tag) {16789 const scalar_zero = switch (scalar_tag) {
16629 .ComptimeFloat, .Float => try mod.floatValue(scalar_type, 0.0),16790 .ComptimeFloat, .Float => try pt.floatValue(scalar_type, 0.0),
16630 .ComptimeInt, .Int => try mod.intValue(scalar_type, 0),16791 .ComptimeInt, .Int => try pt.intValue(scalar_type, 0),
16631 else => unreachable,16792 else => unreachable,
16632 };16793 };
16633 const scalar_one = switch (scalar_tag) {16794 const scalar_one = switch (scalar_tag) {
16634 .ComptimeFloat, .Float => try mod.floatValue(scalar_type, 1.0),16795 .ComptimeFloat, .Float => try pt.floatValue(scalar_type, 1.0),
16635 .ComptimeInt, .Int => try mod.intValue(scalar_type, 1),16796 .ComptimeInt, .Int => try pt.intValue(scalar_type, 1),
16636 else => unreachable,16797 else => unreachable,
16637 };16798 };
16638 if (maybe_lhs_val) |lhs_val| {16799 if (maybe_lhs_val) |lhs_val| {
16639 if (!lhs_val.isUndef(mod)) {16800 if (!lhs_val.isUndef(mod)) {
16640 if (try lhs_val.compareAllWithZeroSema(.eq, mod)) {16801 if (try lhs_val.compareAllWithZeroSema(.eq, pt)) {
16641 const zero_val = try sema.splat(resolved_type, scalar_zero);16802 const zero_val = try sema.splat(resolved_type, scalar_zero);
16642 return Air.internedToRef(zero_val.toIntern());16803 return Air.internedToRef(zero_val.toIntern());
16643 }16804 }
...@@ -16648,9 +16809,9 @@ fn analyzeArithmetic(...@@ -16648,9 +16809,9 @@ fn analyzeArithmetic(
16648 }16809 }
16649 if (maybe_rhs_val) |rhs_val| {16810 if (maybe_rhs_val) |rhs_val| {
16650 if (rhs_val.isUndef(mod)) {16811 if (rhs_val.isUndef(mod)) {
16651 return mod.undefRef(resolved_type);16812 return pt.undefRef(resolved_type);
16652 }16813 }
16653 if (try rhs_val.compareAllWithZeroSema(.eq, mod)) {16814 if (try rhs_val.compareAllWithZeroSema(.eq, pt)) {
16654 const zero_val = try sema.splat(resolved_type, scalar_zero);16815 const zero_val = try sema.splat(resolved_type, scalar_zero);
16655 return Air.internedToRef(zero_val.toIntern());16816 return Air.internedToRef(zero_val.toIntern());
16656 }16817 }
...@@ -16659,9 +16820,9 @@ fn analyzeArithmetic(...@@ -16659,9 +16820,9 @@ fn analyzeArithmetic(
16659 }16820 }
16660 if (maybe_lhs_val) |lhs_val| {16821 if (maybe_lhs_val) |lhs_val| {
16661 if (lhs_val.isUndef(mod)) {16822 if (lhs_val.isUndef(mod)) {
16662 return mod.undefRef(resolved_type);16823 return pt.undefRef(resolved_type);
16663 }16824 }
16664 return Air.internedToRef((try lhs_val.numberMulWrap(rhs_val, resolved_type, sema.arena, mod)).toIntern());16825 return Air.internedToRef((try lhs_val.numberMulWrap(rhs_val, resolved_type, sema.arena, pt)).toIntern());
16665 } else break :rs .{ lhs_src, .mul_wrap, .mul_wrap };16826 } else break :rs .{ lhs_src, .mul_wrap, .mul_wrap };
16666 } else break :rs .{ rhs_src, .mul_wrap, .mul_wrap };16827 } else break :rs .{ rhs_src, .mul_wrap, .mul_wrap };
16667 },16828 },
...@@ -16671,18 +16832,18 @@ fn analyzeArithmetic(...@@ -16671,18 +16832,18 @@ fn analyzeArithmetic(
16671 // If either of the operands are one, result is the other operand.16832 // If either of the operands are one, result is the other operand.
16672 // If either of the operands are undefined, result is undefined.16833 // If either of the operands are undefined, result is undefined.
16673 const scalar_zero = switch (scalar_tag) {16834 const scalar_zero = switch (scalar_tag) {
16674 .ComptimeFloat, .Float => try mod.floatValue(scalar_type, 0.0),16835 .ComptimeFloat, .Float => try pt.floatValue(scalar_type, 0.0),
16675 .ComptimeInt, .Int => try mod.intValue(scalar_type, 0),16836 .ComptimeInt, .Int => try pt.intValue(scalar_type, 0),
16676 else => unreachable,16837 else => unreachable,
16677 };16838 };
16678 const scalar_one = switch (scalar_tag) {16839 const scalar_one = switch (scalar_tag) {
16679 .ComptimeFloat, .Float => try mod.floatValue(scalar_type, 1.0),16840 .ComptimeFloat, .Float => try pt.floatValue(scalar_type, 1.0),
16680 .ComptimeInt, .Int => try mod.intValue(scalar_type, 1),16841 .ComptimeInt, .Int => try pt.intValue(scalar_type, 1),
16681 else => unreachable,16842 else => unreachable,
16682 };16843 };
16683 if (maybe_lhs_val) |lhs_val| {16844 if (maybe_lhs_val) |lhs_val| {
16684 if (!lhs_val.isUndef(mod)) {16845 if (!lhs_val.isUndef(mod)) {
16685 if (try lhs_val.compareAllWithZeroSema(.eq, mod)) {16846 if (try lhs_val.compareAllWithZeroSema(.eq, pt)) {
16686 const zero_val = try sema.splat(resolved_type, scalar_zero);16847 const zero_val = try sema.splat(resolved_type, scalar_zero);
16687 return Air.internedToRef(zero_val.toIntern());16848 return Air.internedToRef(zero_val.toIntern());
16688 }16849 }
...@@ -16693,9 +16854,9 @@ fn analyzeArithmetic(...@@ -16693,9 +16854,9 @@ fn analyzeArithmetic(
16693 }16854 }
16694 if (maybe_rhs_val) |rhs_val| {16855 if (maybe_rhs_val) |rhs_val| {
16695 if (rhs_val.isUndef(mod)) {16856 if (rhs_val.isUndef(mod)) {
16696 return mod.undefRef(resolved_type);16857 return pt.undefRef(resolved_type);
16697 }16858 }
16698 if (try rhs_val.compareAllWithZeroSema(.eq, mod)) {16859 if (try rhs_val.compareAllWithZeroSema(.eq, pt)) {
16699 const zero_val = try sema.splat(resolved_type, scalar_zero);16860 const zero_val = try sema.splat(resolved_type, scalar_zero);
16700 return Air.internedToRef(zero_val.toIntern());16861 return Air.internedToRef(zero_val.toIntern());
16701 }16862 }
...@@ -16704,13 +16865,13 @@ fn analyzeArithmetic(...@@ -16704,13 +16865,13 @@ fn analyzeArithmetic(
16704 }16865 }
16705 if (maybe_lhs_val) |lhs_val| {16866 if (maybe_lhs_val) |lhs_val| {
16706 if (lhs_val.isUndef(mod)) {16867 if (lhs_val.isUndef(mod)) {
16707 return mod.undefRef(resolved_type);16868 return pt.undefRef(resolved_type);
16708 }16869 }
1670916870
16710 const val = if (scalar_tag == .ComptimeInt)16871 const val = if (scalar_tag == .ComptimeInt)
16711 try lhs_val.intMul(rhs_val, resolved_type, undefined, sema.arena, mod)16872 try lhs_val.intMul(rhs_val, resolved_type, undefined, sema.arena, pt)
16712 else16873 else
16713 try lhs_val.intMulSat(rhs_val, resolved_type, sema.arena, mod);16874 try lhs_val.intMulSat(rhs_val, resolved_type, sema.arena, pt);
1671416875
16715 return Air.internedToRef(val.toIntern());16876 return Air.internedToRef(val.toIntern());
16716 } else break :rs .{ lhs_src, .mul_sat, .mul_sat };16877 } else break :rs .{ lhs_src, .mul_sat, .mul_sat };
...@@ -16758,7 +16919,7 @@ fn analyzeArithmetic(...@@ -16758,7 +16919,7 @@ fn analyzeArithmetic(
16758 })16919 })
16759 else16920 else
16760 ov_bit;16921 ov_bit;
16761 const zero_ov = Air.internedToRef((try mod.intValue(Type.u1, 0)).toIntern());16922 const zero_ov = Air.internedToRef((try pt.intValue(Type.u1, 0)).toIntern());
16762 const no_ov = try block.addBinOp(.cmp_eq, any_ov_bit, zero_ov);16923 const no_ov = try block.addBinOp(.cmp_eq, any_ov_bit, zero_ov);
1676316924
16764 try sema.addSafetyCheck(block, src, no_ov, .integer_overflow);16925 try sema.addSafetyCheck(block, src, no_ov, .integer_overflow);
...@@ -16782,7 +16943,8 @@ fn analyzePtrArithmetic(...@@ -16782,7 +16943,8 @@ fn analyzePtrArithmetic(
16782 // TODO if the operand is comptime-known to be negative, or is a negative int,16943 // TODO if the operand is comptime-known to be negative, or is a negative int,
16783 // coerce to isize instead of usize.16944 // coerce to isize instead of usize.
16784 const offset = try sema.coerce(block, Type.usize, uncasted_offset, offset_src);16945 const offset = try sema.coerce(block, Type.usize, uncasted_offset, offset_src);
16785 const mod = sema.mod;16946 const pt = sema.pt;
16947 const mod = pt.zcu;
16786 const opt_ptr_val = try sema.resolveValue(ptr);16948 const opt_ptr_val = try sema.resolveValue(ptr);
16787 const opt_off_val = try sema.resolveDefinedValue(block, offset_src, offset);16949 const opt_off_val = try sema.resolveDefinedValue(block, offset_src, offset);
16788 const ptr_ty = sema.typeOf(ptr);16950 const ptr_ty = sema.typeOf(ptr);
...@@ -16800,7 +16962,7 @@ fn analyzePtrArithmetic(...@@ -16800,7 +16962,7 @@ fn analyzePtrArithmetic(
16800 // it being a multiple of the type size.16962 // it being a multiple of the type size.
16801 const elem_size = try sema.typeAbiSize(Type.fromInterned(ptr_info.child));16963 const elem_size = try sema.typeAbiSize(Type.fromInterned(ptr_info.child));
16802 const addend = if (opt_off_val) |off_val| a: {16964 const addend = if (opt_off_val) |off_val| a: {
16803 const off_int = try sema.usizeCast(block, offset_src, try off_val.toUnsignedIntSema(mod));16965 const off_int = try sema.usizeCast(block, offset_src, try off_val.toUnsignedIntSema(pt));
16804 break :a elem_size * off_int;16966 break :a elem_size * off_int;
16805 } else elem_size;16967 } else elem_size;
1680616968
...@@ -16813,7 +16975,7 @@ fn analyzePtrArithmetic(...@@ -16813,7 +16975,7 @@ fn analyzePtrArithmetic(
16813 ));16975 ));
16814 assert(new_align != .none);16976 assert(new_align != .none);
1681516977
16816 break :t try mod.ptrTypeSema(.{16978 break :t try pt.ptrTypeSema(.{
16817 .child = ptr_info.child,16979 .child = ptr_info.child,
16818 .sentinel = ptr_info.sentinel,16980 .sentinel = ptr_info.sentinel,
16819 .flags = .{16981 .flags = .{
...@@ -16830,16 +16992,16 @@ fn analyzePtrArithmetic(...@@ -16830,16 +16992,16 @@ fn analyzePtrArithmetic(
16830 const runtime_src = rs: {16992 const runtime_src = rs: {
16831 if (opt_ptr_val) |ptr_val| {16993 if (opt_ptr_val) |ptr_val| {
16832 if (opt_off_val) |offset_val| {16994 if (opt_off_val) |offset_val| {
16833 if (ptr_val.isUndef(mod)) return mod.undefRef(new_ptr_ty);16995 if (ptr_val.isUndef(mod)) return pt.undefRef(new_ptr_ty);
1683416996
16835 const offset_int = try sema.usizeCast(block, offset_src, try offset_val.toUnsignedIntSema(mod));16997 const offset_int = try sema.usizeCast(block, offset_src, try offset_val.toUnsignedIntSema(pt));
16836 if (offset_int == 0) return ptr;16998 if (offset_int == 0) return ptr;
16837 if (air_tag == .ptr_sub) {16999 if (air_tag == .ptr_sub) {
16838 const elem_size = try sema.typeAbiSize(Type.fromInterned(ptr_info.child));17000 const elem_size = try sema.typeAbiSize(Type.fromInterned(ptr_info.child));
16839 const new_ptr_val = try sema.ptrSubtract(block, op_src, ptr_val, offset_int * elem_size, new_ptr_ty);17001 const new_ptr_val = try sema.ptrSubtract(block, op_src, ptr_val, offset_int * elem_size, new_ptr_ty);
16840 return Air.internedToRef(new_ptr_val.toIntern());17002 return Air.internedToRef(new_ptr_val.toIntern());
16841 } else {17003 } else {
16842 const new_ptr_val = try mod.getCoerced(try ptr_val.ptrElem(offset_int, mod), new_ptr_ty);17004 const new_ptr_val = try pt.getCoerced(try ptr_val.ptrElem(offset_int, pt), new_ptr_ty);
16843 return Air.internedToRef(new_ptr_val.toIntern());17005 return Air.internedToRef(new_ptr_val.toIntern());
16844 }17006 }
16845 } else break :rs offset_src;17007 } else break :rs offset_src;
...@@ -16879,6 +17041,8 @@ fn zirAsm(...@@ -16879,6 +17041,8 @@ fn zirAsm(
16879 const tracy = trace(@src());17041 const tracy = trace(@src());
16880 defer tracy.end();17042 defer tracy.end();
1688117043
17044 const pt = sema.pt;
17045 const mod = pt.zcu;
16882 const extra = sema.code.extraData(Zir.Inst.Asm, extended.operand);17046 const extra = sema.code.extraData(Zir.Inst.Asm, extended.operand);
16883 const src = block.nodeOffset(extra.data.src_node);17047 const src = block.nodeOffset(extra.data.src_node);
16884 const ret_ty_src = block.src(.{ .node_offset_asm_ret_ty = extra.data.src_node });17048 const ret_ty_src = block.src(.{ .node_offset_asm_ret_ty = extra.data.src_node });
...@@ -16910,7 +17074,7 @@ fn zirAsm(...@@ -16910,7 +17074,7 @@ fn zirAsm(
16910 if (is_volatile) {17074 if (is_volatile) {
16911 return sema.fail(block, src, "volatile keyword is redundant on module-level assembly", .{});17075 return sema.fail(block, src, "volatile keyword is redundant on module-level assembly", .{});
16912 }17076 }
16913 try sema.mod.addGlobalAssembly(sema.owner_decl_index, asm_source);17077 try mod.addGlobalAssembly(sema.owner_decl_index, asm_source);
16914 return .void_value;17078 return .void_value;
16915 }17079 }
1691617080
...@@ -16959,7 +17123,6 @@ fn zirAsm(...@@ -16959,7 +17123,6 @@ fn zirAsm(
1695917123
16960 const args = try sema.arena.alloc(Air.Inst.Ref, inputs_len);17124 const args = try sema.arena.alloc(Air.Inst.Ref, inputs_len);
16961 const inputs = try sema.arena.alloc(ConstraintName, inputs_len);17125 const inputs = try sema.arena.alloc(ConstraintName, inputs_len);
16962 const mod = sema.mod;
1696317126
16964 for (args, 0..) |*arg, arg_i| {17127 for (args, 0..) |*arg, arg_i| {
16965 const input = sema.code.extraData(Zir.Inst.Asm.Input, extra_i);17128 const input = sema.code.extraData(Zir.Inst.Asm.Input, extra_i);
...@@ -17049,7 +17212,8 @@ fn zirCmpEq(...@@ -17049,7 +17212,8 @@ fn zirCmpEq(
17049 const tracy = trace(@src());17212 const tracy = trace(@src());
17050 defer tracy.end();17213 defer tracy.end();
1705117214
17052 const mod = sema.mod;17215 const pt = sema.pt;
17216 const mod = pt.zcu;
17053 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;17217 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
17054 const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data;17218 const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data;
17055 const src: LazySrcLoc = block.nodeOffset(inst_data.src_node);17219 const src: LazySrcLoc = block.nodeOffset(inst_data.src_node);
...@@ -17077,7 +17241,7 @@ fn zirCmpEq(...@@ -17077,7 +17241,7 @@ fn zirCmpEq(
1707717241
17078 if (lhs_ty_tag == .Null or rhs_ty_tag == .Null) {17242 if (lhs_ty_tag == .Null or rhs_ty_tag == .Null) {
17079 const non_null_type = if (lhs_ty_tag == .Null) rhs_ty else lhs_ty;17243 const non_null_type = if (lhs_ty_tag == .Null) rhs_ty else lhs_ty;
17080 return sema.fail(block, src, "comparison of '{}' with null", .{non_null_type.fmt(mod)});17244 return sema.fail(block, src, "comparison of '{}' with null", .{non_null_type.fmt(pt)});
17081 }17245 }
1708217246
17083 if (lhs_ty_tag == .Union and (rhs_ty_tag == .EnumLiteral or rhs_ty_tag == .Enum)) {17247 if (lhs_ty_tag == .Union and (rhs_ty_tag == .EnumLiteral or rhs_ty_tag == .Enum)) {
...@@ -17092,7 +17256,7 @@ fn zirCmpEq(...@@ -17092,7 +17256,7 @@ fn zirCmpEq(
17092 if (try sema.resolveValue(lhs)) |lval| {17256 if (try sema.resolveValue(lhs)) |lval| {
17093 if (try sema.resolveValue(rhs)) |rval| {17257 if (try sema.resolveValue(rhs)) |rval| {
17094 if (lval.isUndef(mod) or rval.isUndef(mod)) {17258 if (lval.isUndef(mod) or rval.isUndef(mod)) {
17095 return mod.undefRef(Type.bool);17259 return pt.undefRef(Type.bool);
17096 }17260 }
17097 const lkey = mod.intern_pool.indexToKey(lval.toIntern());17261 const lkey = mod.intern_pool.indexToKey(lval.toIntern());
17098 const rkey = mod.intern_pool.indexToKey(rval.toIntern());17262 const rkey = mod.intern_pool.indexToKey(rval.toIntern());
...@@ -17128,14 +17292,15 @@ fn analyzeCmpUnionTag(...@@ -17128,14 +17292,15 @@ fn analyzeCmpUnionTag(
17128 tag_src: LazySrcLoc,17292 tag_src: LazySrcLoc,
17129 op: std.math.CompareOperator,17293 op: std.math.CompareOperator,
17130) CompileError!Air.Inst.Ref {17294) CompileError!Air.Inst.Ref {
17131 const mod = sema.mod;17295 const pt = sema.pt;
17296 const mod = pt.zcu;
17132 const union_ty = sema.typeOf(un);17297 const union_ty = sema.typeOf(un);
17133 try union_ty.resolveFields(mod);17298 try union_ty.resolveFields(pt);
17134 const union_tag_ty = union_ty.unionTagType(mod) orelse {17299 const union_tag_ty = union_ty.unionTagType(mod) orelse {
17135 const msg = msg: {17300 const msg = msg: {
17136 const msg = try sema.errMsg(un_src, "comparison of union and enum literal is only valid for tagged union types", .{});17301 const msg = try sema.errMsg(un_src, "comparison of union and enum literal is only valid for tagged union types", .{});
17137 errdefer msg.destroy(sema.gpa);17302 errdefer msg.destroy(sema.gpa);
17138 try sema.errNote(union_ty.srcLoc(mod), msg, "union '{}' is not a tagged union", .{union_ty.fmt(mod)});17303 try sema.errNote(union_ty.srcLoc(mod), msg, "union '{}' is not a tagged union", .{union_ty.fmt(pt)});
17139 break :msg msg;17304 break :msg msg;
17140 };17305 };
17141 return sema.failWithOwnedErrorMsg(block, msg);17306 return sema.failWithOwnedErrorMsg(block, msg);
...@@ -17146,7 +17311,7 @@ fn analyzeCmpUnionTag(...@@ -17146,7 +17311,7 @@ fn analyzeCmpUnionTag(
17146 const coerced_union = try sema.coerce(block, union_tag_ty, un, un_src);17311 const coerced_union = try sema.coerce(block, union_tag_ty, un, un_src);
1714717312
17148 if (try sema.resolveValue(coerced_tag)) |enum_val| {17313 if (try sema.resolveValue(coerced_tag)) |enum_val| {
17149 if (enum_val.isUndef(mod)) return mod.undefRef(Type.bool);17314 if (enum_val.isUndef(mod)) return pt.undefRef(Type.bool);
17150 const field_ty = union_ty.unionFieldType(enum_val, mod).?;17315 const field_ty = union_ty.unionFieldType(enum_val, mod).?;
17151 if (field_ty.zigTypeTag(mod) == .NoReturn) {17316 if (field_ty.zigTypeTag(mod) == .NoReturn) {
17152 return .bool_false;17317 return .bool_false;
...@@ -17187,7 +17352,8 @@ fn analyzeCmp(...@@ -17187,7 +17352,8 @@ fn analyzeCmp(
17187 rhs_src: LazySrcLoc,17352 rhs_src: LazySrcLoc,
17188 is_equality_cmp: bool,17353 is_equality_cmp: bool,
17189) CompileError!Air.Inst.Ref {17354) CompileError!Air.Inst.Ref {
17190 const mod = sema.mod;17355 const pt = sema.pt;
17356 const mod = pt.zcu;
17191 const lhs_ty = sema.typeOf(lhs);17357 const lhs_ty = sema.typeOf(lhs);
17192 const rhs_ty = sema.typeOf(rhs);17358 const rhs_ty = sema.typeOf(rhs);
17193 if (lhs_ty.zigTypeTag(mod) != .Optional and rhs_ty.zigTypeTag(mod) != .Optional) {17359 if (lhs_ty.zigTypeTag(mod) != .Optional and rhs_ty.zigTypeTag(mod) != .Optional) {
...@@ -17215,7 +17381,7 @@ fn analyzeCmp(...@@ -17215,7 +17381,7 @@ fn analyzeCmp(
17215 const resolved_type = try sema.resolvePeerTypes(block, src, instructions, .{ .override = &[_]?LazySrcLoc{ lhs_src, rhs_src } });17381 const resolved_type = try sema.resolvePeerTypes(block, src, instructions, .{ .override = &[_]?LazySrcLoc{ lhs_src, rhs_src } });
17216 if (!resolved_type.isSelfComparable(mod, is_equality_cmp)) {17382 if (!resolved_type.isSelfComparable(mod, is_equality_cmp)) {
17217 return sema.fail(block, src, "operator {s} not allowed for type '{}'", .{17383 return sema.fail(block, src, "operator {s} not allowed for type '{}'", .{
17218 compareOperatorName(op), resolved_type.fmt(mod),17384 compareOperatorName(op), resolved_type.fmt(pt),
17219 });17385 });
17220 }17386 }
17221 const casted_lhs = try sema.coerce(block, resolved_type, lhs, lhs_src);17387 const casted_lhs = try sema.coerce(block, resolved_type, lhs, lhs_src);
...@@ -17244,13 +17410,14 @@ fn cmpSelf(...@@ -17244,13 +17410,14 @@ fn cmpSelf(
17244 lhs_src: LazySrcLoc,17410 lhs_src: LazySrcLoc,
17245 rhs_src: LazySrcLoc,17411 rhs_src: LazySrcLoc,
17246) CompileError!Air.Inst.Ref {17412) CompileError!Air.Inst.Ref {
17247 const mod = sema.mod;17413 const pt = sema.pt;
17414 const mod = pt.zcu;
17248 const resolved_type = sema.typeOf(casted_lhs);17415 const resolved_type = sema.typeOf(casted_lhs);
17249 const runtime_src: LazySrcLoc = src: {17416 const runtime_src: LazySrcLoc = src: {
17250 if (try sema.resolveValue(casted_lhs)) |lhs_val| {17417 if (try sema.resolveValue(casted_lhs)) |lhs_val| {
17251 if (lhs_val.isUndef(mod)) return mod.undefRef(Type.bool);17418 if (lhs_val.isUndef(mod)) return pt.undefRef(Type.bool);
17252 if (try sema.resolveValue(casted_rhs)) |rhs_val| {17419 if (try sema.resolveValue(casted_rhs)) |rhs_val| {
17253 if (rhs_val.isUndef(mod)) return mod.undefRef(Type.bool);17420 if (rhs_val.isUndef(mod)) return pt.undefRef(Type.bool);
1725417421
17255 if (resolved_type.zigTypeTag(mod) == .Vector) {17422 if (resolved_type.zigTypeTag(mod) == .Vector) {
17256 const cmp_val = try sema.compareVector(lhs_val, op, rhs_val, resolved_type);17423 const cmp_val = try sema.compareVector(lhs_val, op, rhs_val, resolved_type);
...@@ -17273,7 +17440,7 @@ fn cmpSelf(...@@ -17273,7 +17440,7 @@ fn cmpSelf(
17273 // bool eq/neq more efficiently.17440 // bool eq/neq more efficiently.
17274 if (resolved_type.zigTypeTag(mod) == .Bool) {17441 if (resolved_type.zigTypeTag(mod) == .Bool) {
17275 if (try sema.resolveValue(casted_rhs)) |rhs_val| {17442 if (try sema.resolveValue(casted_rhs)) |rhs_val| {
17276 if (rhs_val.isUndef(mod)) return mod.undefRef(Type.bool);17443 if (rhs_val.isUndef(mod)) return pt.undefRef(Type.bool);
17277 return sema.runtimeBoolCmp(block, src, op, casted_lhs, rhs_val.toBool(), lhs_src);17444 return sema.runtimeBoolCmp(block, src, op, casted_lhs, rhs_val.toBool(), lhs_src);
17278 }17445 }
17279 }17446 }
...@@ -17310,24 +17477,24 @@ fn runtimeBoolCmp(...@@ -17310,24 +17477,24 @@ fn runtimeBoolCmp(
17310}17477}
1731117478
17312fn zirSizeOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {17479fn zirSizeOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
17313 const mod = sema.mod;17480 const pt = sema.pt;
17314 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;17481 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;
17315 const operand_src = block.builtinCallArgSrc(inst_data.src_node, 0);17482 const operand_src = block.builtinCallArgSrc(inst_data.src_node, 0);
17316 const ty = try sema.resolveType(block, operand_src, inst_data.operand);17483 const ty = try sema.resolveType(block, operand_src, inst_data.operand);
17317 switch (ty.zigTypeTag(mod)) {17484 switch (ty.zigTypeTag(pt.zcu)) {
17318 .Fn,17485 .Fn,
17319 .NoReturn,17486 .NoReturn,
17320 .Undefined,17487 .Undefined,
17321 .Null,17488 .Null,
17322 .Opaque,17489 .Opaque,
17323 => return sema.fail(block, operand_src, "no size available for type '{}'", .{ty.fmt(mod)}),17490 => return sema.fail(block, operand_src, "no size available for type '{}'", .{ty.fmt(pt)}),
1732417491
17325 .Type,17492 .Type,
17326 .EnumLiteral,17493 .EnumLiteral,
17327 .ComptimeFloat,17494 .ComptimeFloat,
17328 .ComptimeInt,17495 .ComptimeInt,
17329 .Void,17496 .Void,
17330 => return mod.intRef(Type.comptime_int, 0),17497 => return pt.intRef(Type.comptime_int, 0),
1733117498
17332 .Bool,17499 .Bool,
17333 .Int,17500 .Int,
...@@ -17345,12 +17512,13 @@ fn zirSizeOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air....@@ -17345,12 +17512,13 @@ fn zirSizeOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.
17345 .AnyFrame,17512 .AnyFrame,
17346 => {},17513 => {},
17347 }17514 }
17348 const val = try ty.lazyAbiSize(mod);17515 const val = try ty.lazyAbiSize(pt);
17349 return Air.internedToRef(val.toIntern());17516 return Air.internedToRef(val.toIntern());
17350}17517}
1735117518
17352fn zirBitSizeOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {17519fn zirBitSizeOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
17353 const mod = sema.mod;17520 const pt = sema.pt;
17521 const mod = pt.zcu;
17354 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;17522 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;
17355 const operand_src = block.builtinCallArgSrc(inst_data.src_node, 0);17523 const operand_src = block.builtinCallArgSrc(inst_data.src_node, 0);
17356 const operand_ty = try sema.resolveType(block, operand_src, inst_data.operand);17524 const operand_ty = try sema.resolveType(block, operand_src, inst_data.operand);
...@@ -17360,14 +17528,14 @@ fn zirBitSizeOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A...@@ -17360,14 +17528,14 @@ fn zirBitSizeOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
17360 .Undefined,17528 .Undefined,
17361 .Null,17529 .Null,
17362 .Opaque,17530 .Opaque,
17363 => return sema.fail(block, operand_src, "no size available for type '{}'", .{operand_ty.fmt(mod)}),17531 => return sema.fail(block, operand_src, "no size available for type '{}'", .{operand_ty.fmt(pt)}),
1736417532
17365 .Type,17533 .Type,
17366 .EnumLiteral,17534 .EnumLiteral,
17367 .ComptimeFloat,17535 .ComptimeFloat,
17368 .ComptimeInt,17536 .ComptimeInt,
17369 .Void,17537 .Void,
17370 => return mod.intRef(Type.comptime_int, 0),17538 => return pt.intRef(Type.comptime_int, 0),
1737117539
17372 .Bool,17540 .Bool,
17373 .Int,17541 .Int,
...@@ -17385,8 +17553,8 @@ fn zirBitSizeOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A...@@ -17385,8 +17553,8 @@ fn zirBitSizeOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
17385 .AnyFrame,17553 .AnyFrame,
17386 => {},17554 => {},
17387 }17555 }
17388 const bit_size = try operand_ty.bitSizeAdvanced(mod, .sema);17556 const bit_size = try operand_ty.bitSizeAdvanced(pt, .sema);
17389 return mod.intRef(Type.comptime_int, bit_size);17557 return pt.intRef(Type.comptime_int, bit_size);
17390}17558}
1739117559
17392fn zirThis(17560fn zirThis(
...@@ -17394,14 +17562,16 @@ fn zirThis(...@@ -17394,14 +17562,16 @@ fn zirThis(
17394 block: *Block,17562 block: *Block,
17395 extended: Zir.Inst.Extended.InstData,17563 extended: Zir.Inst.Extended.InstData,
17396) CompileError!Air.Inst.Ref {17564) CompileError!Air.Inst.Ref {
17397 const mod = sema.mod;17565 const pt = sema.pt;
17566 const mod = pt.zcu;
17398 const this_decl_index = mod.namespacePtr(block.namespace).decl_index;17567 const this_decl_index = mod.namespacePtr(block.namespace).decl_index;
17399 const src = block.nodeOffset(@bitCast(extended.operand));17568 const src = block.nodeOffset(@bitCast(extended.operand));
17400 return sema.analyzeDeclVal(block, src, this_decl_index);17569 return sema.analyzeDeclVal(block, src, this_decl_index);
17401}17570}
1740217571
17403fn zirClosureGet(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) CompileError!Air.Inst.Ref {17572fn zirClosureGet(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) CompileError!Air.Inst.Ref {
17404 const mod = sema.mod;17573 const pt = sema.pt;
17574 const mod = pt.zcu;
17405 const ip = &mod.intern_pool;17575 const ip = &mod.intern_pool;
17406 const captures = mod.namespacePtr(block.namespace).getType(mod).getCaptures(mod);17576 const captures = mod.namespacePtr(block.namespace).getType(mod).getCaptures(mod);
1740717577
...@@ -17489,7 +17659,7 @@ fn zirRetAddr(...@@ -17489,7 +17659,7 @@ fn zirRetAddr(
17489 _ = extended;17659 _ = extended;
17490 if (block.is_comptime) {17660 if (block.is_comptime) {
17491 // TODO: we could give a meaningful lazy value here. #1493817661 // TODO: we could give a meaningful lazy value here. #14938
17492 return sema.mod.intRef(Type.usize, 0);17662 return sema.pt.intRef(Type.usize, 0);
17493 } else {17663 } else {
17494 return block.addNoOp(.ret_addr);17664 return block.addNoOp(.ret_addr);
17495 }17665 }
...@@ -17514,7 +17684,8 @@ fn zirBuiltinSrc(...@@ -17514,7 +17684,8 @@ fn zirBuiltinSrc(
17514 const tracy = trace(@src());17684 const tracy = trace(@src());
17515 defer tracy.end();17685 defer tracy.end();
1751617686
17517 const mod = sema.mod;17687 const pt = sema.pt;
17688 const mod = pt.zcu;
17518 const extra = sema.code.extraData(Zir.Inst.Src, extended.operand).data;17689 const extra = sema.code.extraData(Zir.Inst.Src, extended.operand).data;
17519 const fn_owner_decl = mod.funcOwnerDeclPtr(sema.func_index);17690 const fn_owner_decl = mod.funcOwnerDeclPtr(sema.func_index);
17520 const ip = &mod.intern_pool;17691 const ip = &mod.intern_pool;
...@@ -17522,80 +17693,81 @@ fn zirBuiltinSrc(...@@ -17522,80 +17693,81 @@ fn zirBuiltinSrc(
1752217693
17523 const func_name_val = v: {17694 const func_name_val = v: {
17524 const func_name_len = fn_owner_decl.name.length(ip);17695 const func_name_len = fn_owner_decl.name.length(ip);
17525 const array_ty = try ip.get(gpa, .{ .array_type = .{17696 const array_ty = try pt.intern(.{ .array_type = .{
17526 .len = func_name_len,17697 .len = func_name_len,
17527 .sentinel = .zero_u8,17698 .sentinel = .zero_u8,
17528 .child = .u8_type,17699 .child = .u8_type,
17529 } });17700 } });
17530 break :v try ip.get(gpa, .{ .slice = .{17701 break :v try pt.intern(.{ .slice = .{
17531 .ty = .slice_const_u8_sentinel_0_type,17702 .ty = .slice_const_u8_sentinel_0_type,
17532 .ptr = try ip.get(gpa, .{ .ptr = .{17703 .ptr = try pt.intern(.{ .ptr = .{
17533 .ty = .manyptr_const_u8_sentinel_0_type,17704 .ty = .manyptr_const_u8_sentinel_0_type,
17534 .base_addr = .{ .anon_decl = .{17705 .base_addr = .{ .anon_decl = .{
17535 .orig_ty = .slice_const_u8_sentinel_0_type,17706 .orig_ty = .slice_const_u8_sentinel_0_type,
17536 .val = try ip.get(gpa, .{ .aggregate = .{17707 .val = try pt.intern(.{ .aggregate = .{
17537 .ty = array_ty,17708 .ty = array_ty,
17538 .storage = .{ .bytes = fn_owner_decl.name.toString() },17709 .storage = .{ .bytes = fn_owner_decl.name.toString() },
17539 } }),17710 } }),
17540 } },17711 } },
17541 .byte_offset = 0,17712 .byte_offset = 0,
17542 } }),17713 } }),
17543 .len = (try mod.intValue(Type.usize, func_name_len)).toIntern(),17714 .len = (try pt.intValue(Type.usize, func_name_len)).toIntern(),
17544 } });17715 } });
17545 };17716 };
1754617717
17547 const file_name_val = v: {17718 const file_name_val = v: {
17548 // The compiler must not call realpath anywhere.17719 // The compiler must not call realpath anywhere.
17549 const file_name = try fn_owner_decl.getFileScope(mod).fullPath(sema.arena);17720 const file_name = try fn_owner_decl.getFileScope(mod).fullPath(sema.arena);
17550 const array_ty = try ip.get(gpa, .{ .array_type = .{17721 const array_ty = try pt.intern(.{ .array_type = .{
17551 .len = file_name.len,17722 .len = file_name.len,
17552 .sentinel = .zero_u8,17723 .sentinel = .zero_u8,
17553 .child = .u8_type,17724 .child = .u8_type,
17554 } });17725 } });
17555 break :v try ip.get(gpa, .{ .slice = .{17726 break :v try pt.intern(.{ .slice = .{
17556 .ty = .slice_const_u8_sentinel_0_type,17727 .ty = .slice_const_u8_sentinel_0_type,
17557 .ptr = try ip.get(gpa, .{ .ptr = .{17728 .ptr = try pt.intern(.{ .ptr = .{
17558 .ty = .manyptr_const_u8_sentinel_0_type,17729 .ty = .manyptr_const_u8_sentinel_0_type,
17559 .base_addr = .{ .anon_decl = .{17730 .base_addr = .{ .anon_decl = .{
17560 .orig_ty = .slice_const_u8_sentinel_0_type,17731 .orig_ty = .slice_const_u8_sentinel_0_type,
17561 .val = try ip.get(gpa, .{ .aggregate = .{17732 .val = try pt.intern(.{ .aggregate = .{
17562 .ty = array_ty,17733 .ty = array_ty,
17563 .storage = .{17734 .storage = .{
17564 .bytes = try ip.getOrPutString(gpa, file_name, .maybe_embedded_nulls),17735 .bytes = try ip.getOrPutString(gpa, pt.tid, file_name, .maybe_embedded_nulls),
17565 },17736 },
17566 } }),17737 } }),
17567 } },17738 } },
17568 .byte_offset = 0,17739 .byte_offset = 0,
17569 } }),17740 } }),
17570 .len = (try mod.intValue(Type.usize, file_name.len)).toIntern(),17741 .len = (try pt.intValue(Type.usize, file_name.len)).toIntern(),
17571 } });17742 } });
17572 };17743 };
1757317744
17574 const src_loc_ty = try mod.getBuiltinType("SourceLocation");17745 const src_loc_ty = try pt.getBuiltinType("SourceLocation");
17575 const fields = .{17746 const fields = .{
17576 // file: [:0]const u8,17747 // file: [:0]const u8,
17577 file_name_val,17748 file_name_val,
17578 // fn_name: [:0]const u8,17749 // fn_name: [:0]const u8,
17579 func_name_val,17750 func_name_val,
17580 // line: u32,17751 // line: u32,
17581 (try mod.intValue(Type.u32, extra.line + 1)).toIntern(),17752 (try pt.intValue(Type.u32, extra.line + 1)).toIntern(),
17582 // column: u32,17753 // column: u32,
17583 (try mod.intValue(Type.u32, extra.column + 1)).toIntern(),17754 (try pt.intValue(Type.u32, extra.column + 1)).toIntern(),
17584 };17755 };
17585 return Air.internedToRef((try mod.intern(.{ .aggregate = .{17756 return Air.internedToRef((try pt.intern(.{ .aggregate = .{
17586 .ty = src_loc_ty.toIntern(),17757 .ty = src_loc_ty.toIntern(),
17587 .storage = .{ .elems = &fields },17758 .storage = .{ .elems = &fields },
17588 } })));17759 } })));
17589}17760}
1759017761
17591fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {17762fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
17592 const mod = sema.mod;17763 const pt = sema.pt;
17764 const mod = pt.zcu;
17593 const gpa = sema.gpa;17765 const gpa = sema.gpa;
17594 const ip = &mod.intern_pool;17766 const ip = &mod.intern_pool;
17595 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;17767 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;
17596 const src = block.nodeOffset(inst_data.src_node);17768 const src = block.nodeOffset(inst_data.src_node);
17597 const ty = try sema.resolveType(block, src, inst_data.operand);17769 const ty = try sema.resolveType(block, src, inst_data.operand);
17598 const type_info_ty = try mod.getBuiltinType("Type");17770 const type_info_ty = try pt.getBuiltinType("Type");
17599 const type_info_tag_ty = type_info_ty.unionTagType(mod).?;17771 const type_info_tag_ty = type_info_ty.unionTagType(mod).?;
1760017772
17601 if (ty.typeDeclInst(mod)) |type_decl_inst| {17773 if (ty.typeDeclInst(mod)) |type_decl_inst| {
...@@ -17612,9 +17784,9 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -17612,9 +17784,9 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
17612 .Undefined,17784 .Undefined,
17613 .Null,17785 .Null,
17614 .EnumLiteral,17786 .EnumLiteral,
17615 => |type_info_tag| return Air.internedToRef((try mod.intern(.{ .un = .{17787 => |type_info_tag| return Air.internedToRef((try pt.intern(.{ .un = .{
17616 .ty = type_info_ty.toIntern(),17788 .ty = type_info_ty.toIntern(),
17617 .tag = (try mod.enumValueFieldIndex(type_info_tag_ty, @intFromEnum(type_info_tag))).toIntern(),17789 .tag = (try pt.enumValueFieldIndex(type_info_tag_ty, @intFromEnum(type_info_tag))).toIntern(),
17618 .val = .void_value,17790 .val = .void_value,
17619 } }))),17791 } }))),
17620 .Fn => {17792 .Fn => {
...@@ -17622,7 +17794,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -17622,7 +17794,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
17622 block,17794 block,
17623 src,17795 src,
17624 type_info_ty.getNamespaceIndex(mod),17796 type_info_ty.getNamespaceIndex(mod),
17625 try ip.getOrPutString(gpa, "Fn", .no_embedded_nulls),17797 try ip.getOrPutString(gpa, pt.tid, "Fn", .no_embedded_nulls),
17626 )).?;17798 )).?;
17627 try sema.ensureDeclAnalyzed(fn_info_decl_index);17799 try sema.ensureDeclAnalyzed(fn_info_decl_index);
17628 const fn_info_decl = mod.declPtr(fn_info_decl_index);17800 const fn_info_decl = mod.declPtr(fn_info_decl_index);
...@@ -17632,7 +17804,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -17632,7 +17804,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
17632 block,17804 block,
17633 src,17805 src,
17634 fn_info_ty.getNamespaceIndex(mod),17806 fn_info_ty.getNamespaceIndex(mod),
17635 try ip.getOrPutString(gpa, "Param", .no_embedded_nulls),17807 try ip.getOrPutString(gpa, pt.tid, "Param", .no_embedded_nulls),
17636 )).?;17808 )).?;
17637 try sema.ensureDeclAnalyzed(param_info_decl_index);17809 try sema.ensureDeclAnalyzed(param_info_decl_index);
17638 const param_info_decl = mod.declPtr(param_info_decl_index);17810 const param_info_decl = mod.declPtr(param_info_decl_index);
...@@ -17643,8 +17815,8 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -17643,8 +17815,8 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
17643 for (param_vals, 0..) |*param_val, i| {17815 for (param_vals, 0..) |*param_val, i| {
17644 const param_ty = func_ty_info.param_types.get(ip)[i];17816 const param_ty = func_ty_info.param_types.get(ip)[i];
17645 const is_generic = param_ty == .generic_poison_type;17817 const is_generic = param_ty == .generic_poison_type;
17646 const param_ty_val = try ip.get(gpa, .{ .opt = .{17818 const param_ty_val = try pt.intern(.{ .opt = .{
17647 .ty = try ip.get(gpa, .{ .opt_type = .type_type }),17819 .ty = try pt.intern(.{ .opt_type = .type_type }),
17648 .val = if (is_generic) .none else param_ty,17820 .val = if (is_generic) .none else param_ty,
17649 } });17821 } });
1765017822
...@@ -17661,22 +17833,22 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -17661,22 +17833,22 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
17661 // type: ?type,17833 // type: ?type,
17662 param_ty_val,17834 param_ty_val,
17663 };17835 };
17664 param_val.* = try mod.intern(.{ .aggregate = .{17836 param_val.* = try pt.intern(.{ .aggregate = .{
17665 .ty = param_info_ty.toIntern(),17837 .ty = param_info_ty.toIntern(),
17666 .storage = .{ .elems = &param_fields },17838 .storage = .{ .elems = &param_fields },
17667 } });17839 } });
17668 }17840 }
1766917841
17670 const args_val = v: {17842 const args_val = v: {
17671 const new_decl_ty = try mod.arrayType(.{17843 const new_decl_ty = try pt.arrayType(.{
17672 .len = param_vals.len,17844 .len = param_vals.len,
17673 .child = param_info_ty.toIntern(),17845 .child = param_info_ty.toIntern(),
17674 });17846 });
17675 const new_decl_val = try mod.intern(.{ .aggregate = .{17847 const new_decl_val = try pt.intern(.{ .aggregate = .{
17676 .ty = new_decl_ty.toIntern(),17848 .ty = new_decl_ty.toIntern(),
17677 .storage = .{ .elems = param_vals },17849 .storage = .{ .elems = param_vals },
17678 } });17850 } });
17679 const slice_ty = (try mod.ptrTypeSema(.{17851 const slice_ty = (try pt.ptrTypeSema(.{
17680 .child = param_info_ty.toIntern(),17852 .child = param_info_ty.toIntern(),
17681 .flags = .{17853 .flags = .{
17682 .size = .Slice,17854 .size = .Slice,
...@@ -17684,9 +17856,9 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -17684,9 +17856,9 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
17684 },17856 },
17685 })).toIntern();17857 })).toIntern();
17686 const manyptr_ty = Type.fromInterned(slice_ty).slicePtrFieldType(mod).toIntern();17858 const manyptr_ty = Type.fromInterned(slice_ty).slicePtrFieldType(mod).toIntern();
17687 break :v try mod.intern(.{ .slice = .{17859 break :v try pt.intern(.{ .slice = .{
17688 .ty = slice_ty,17860 .ty = slice_ty,
17689 .ptr = try mod.intern(.{ .ptr = .{17861 .ptr = try pt.intern(.{ .ptr = .{
17690 .ty = manyptr_ty,17862 .ty = manyptr_ty,
17691 .base_addr = .{ .anon_decl = .{17863 .base_addr = .{ .anon_decl = .{
17692 .orig_ty = manyptr_ty,17864 .orig_ty = manyptr_ty,
...@@ -17694,23 +17866,23 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -17694,23 +17866,23 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
17694 } },17866 } },
17695 .byte_offset = 0,17867 .byte_offset = 0,
17696 } }),17868 } }),
17697 .len = (try mod.intValue(Type.usize, param_vals.len)).toIntern(),17869 .len = (try pt.intValue(Type.usize, param_vals.len)).toIntern(),
17698 } });17870 } });
17699 };17871 };
1770017872
17701 const ret_ty_opt = try mod.intern(.{ .opt = .{17873 const ret_ty_opt = try pt.intern(.{ .opt = .{
17702 .ty = try ip.get(gpa, .{ .opt_type = .type_type }),17874 .ty = try pt.intern(.{ .opt_type = .type_type }),
17703 .val = if (func_ty_info.return_type == .generic_poison_type)17875 .val = if (func_ty_info.return_type == .generic_poison_type)
17704 .none17876 .none
17705 else17877 else
17706 func_ty_info.return_type,17878 func_ty_info.return_type,
17707 } });17879 } });
1770817880
17709 const callconv_ty = try mod.getBuiltinType("CallingConvention");17881 const callconv_ty = try pt.getBuiltinType("CallingConvention");
1771017882
17711 const field_values = .{17883 const field_values = .{
17712 // calling_convention: CallingConvention,17884 // calling_convention: CallingConvention,
17713 (try mod.enumValueFieldIndex(callconv_ty, @intFromEnum(func_ty_info.cc))).toIntern(),17885 (try pt.enumValueFieldIndex(callconv_ty, @intFromEnum(func_ty_info.cc))).toIntern(),
17714 // is_generic: bool,17886 // is_generic: bool,
17715 Value.makeBool(func_ty_info.is_generic).toIntern(),17887 Value.makeBool(func_ty_info.is_generic).toIntern(),
17716 // is_var_args: bool,17888 // is_var_args: bool,
...@@ -17720,10 +17892,10 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -17720,10 +17892,10 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
17720 // args: []const Fn.Param,17892 // args: []const Fn.Param,
17721 args_val,17893 args_val,
17722 };17894 };
17723 return Air.internedToRef((try mod.intern(.{ .un = .{17895 return Air.internedToRef((try pt.intern(.{ .un = .{
17724 .ty = type_info_ty.toIntern(),17896 .ty = type_info_ty.toIntern(),
17725 .tag = (try mod.enumValueFieldIndex(type_info_tag_ty, @intFromEnum(std.builtin.TypeId.Fn))).toIntern(),17897 .tag = (try pt.enumValueFieldIndex(type_info_tag_ty, @intFromEnum(std.builtin.TypeId.Fn))).toIntern(),
17726 .val = try mod.intern(.{ .aggregate = .{17898 .val = try pt.intern(.{ .aggregate = .{
17727 .ty = fn_info_ty.toIntern(),17899 .ty = fn_info_ty.toIntern(),
17728 .storage = .{ .elems = &field_values },17900 .storage = .{ .elems = &field_values },
17729 } }),17901 } }),
...@@ -17734,24 +17906,24 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -17734,24 +17906,24 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
17734 block,17906 block,
17735 src,17907 src,
17736 type_info_ty.getNamespaceIndex(mod),17908 type_info_ty.getNamespaceIndex(mod),
17737 try ip.getOrPutString(gpa, "Int", .no_embedded_nulls),17909 try ip.getOrPutString(gpa, pt.tid, "Int", .no_embedded_nulls),
17738 )).?;17910 )).?;
17739 try sema.ensureDeclAnalyzed(int_info_decl_index);17911 try sema.ensureDeclAnalyzed(int_info_decl_index);
17740 const int_info_decl = mod.declPtr(int_info_decl_index);17912 const int_info_decl = mod.declPtr(int_info_decl_index);
17741 const int_info_ty = int_info_decl.val.toType();17913 const int_info_ty = int_info_decl.val.toType();
1774217914
17743 const signedness_ty = try mod.getBuiltinType("Signedness");17915 const signedness_ty = try pt.getBuiltinType("Signedness");
17744 const info = ty.intInfo(mod);17916 const info = ty.intInfo(mod);
17745 const field_values = .{17917 const field_values = .{
17746 // signedness: Signedness,17918 // signedness: Signedness,
17747 (try mod.enumValueFieldIndex(signedness_ty, @intFromEnum(info.signedness))).toIntern(),17919 (try pt.enumValueFieldIndex(signedness_ty, @intFromEnum(info.signedness))).toIntern(),
17748 // bits: u16,17920 // bits: u16,
17749 (try mod.intValue(Type.u16, info.bits)).toIntern(),17921 (try pt.intValue(Type.u16, info.bits)).toIntern(),
17750 };17922 };
17751 return Air.internedToRef((try mod.intern(.{ .un = .{17923 return Air.internedToRef((try pt.intern(.{ .un = .{
17752 .ty = type_info_ty.toIntern(),17924 .ty = type_info_ty.toIntern(),
17753 .tag = (try mod.enumValueFieldIndex(type_info_tag_ty, @intFromEnum(std.builtin.TypeId.Int))).toIntern(),17925 .tag = (try pt.enumValueFieldIndex(type_info_tag_ty, @intFromEnum(std.builtin.TypeId.Int))).toIntern(),
17754 .val = try mod.intern(.{ .aggregate = .{17926 .val = try pt.intern(.{ .aggregate = .{
17755 .ty = int_info_ty.toIntern(),17927 .ty = int_info_ty.toIntern(),
17756 .storage = .{ .elems = &field_values },17928 .storage = .{ .elems = &field_values },
17757 } }),17929 } }),
...@@ -17762,7 +17934,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -17762,7 +17934,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
17762 block,17934 block,
17763 src,17935 src,
17764 type_info_ty.getNamespaceIndex(mod),17936 type_info_ty.getNamespaceIndex(mod),
17765 try ip.getOrPutString(gpa, "Float", .no_embedded_nulls),17937 try ip.getOrPutString(gpa, pt.tid, "Float", .no_embedded_nulls),
17766 )).?;17938 )).?;
17767 try sema.ensureDeclAnalyzed(float_info_decl_index);17939 try sema.ensureDeclAnalyzed(float_info_decl_index);
17768 const float_info_decl = mod.declPtr(float_info_decl_index);17940 const float_info_decl = mod.declPtr(float_info_decl_index);
...@@ -17770,12 +17942,12 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -17770,12 +17942,12 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1777017942
17771 const field_vals = .{17943 const field_vals = .{
17772 // bits: u16,17944 // bits: u16,
17773 (try mod.intValue(Type.u16, ty.bitSize(mod))).toIntern(),17945 (try pt.intValue(Type.u16, ty.bitSize(pt))).toIntern(),
17774 };17946 };
17775 return Air.internedToRef((try mod.intern(.{ .un = .{17947 return Air.internedToRef((try pt.intern(.{ .un = .{
17776 .ty = type_info_ty.toIntern(),17948 .ty = type_info_ty.toIntern(),
17777 .tag = (try mod.enumValueFieldIndex(type_info_tag_ty, @intFromEnum(std.builtin.TypeId.Float))).toIntern(),17949 .tag = (try pt.enumValueFieldIndex(type_info_tag_ty, @intFromEnum(std.builtin.TypeId.Float))).toIntern(),
17778 .val = try mod.intern(.{ .aggregate = .{17950 .val = try pt.intern(.{ .aggregate = .{
17779 .ty = float_info_ty.toIntern(),17951 .ty = float_info_ty.toIntern(),
17780 .storage = .{ .elems = &field_vals },17952 .storage = .{ .elems = &field_vals },
17781 } }),17953 } }),
...@@ -17784,17 +17956,17 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -17784,17 +17956,17 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
17784 .Pointer => {17956 .Pointer => {
17785 const info = ty.ptrInfo(mod);17957 const info = ty.ptrInfo(mod);
17786 const alignment = if (info.flags.alignment.toByteUnits()) |alignment|17958 const alignment = if (info.flags.alignment.toByteUnits()) |alignment|
17787 try mod.intValue(Type.comptime_int, alignment)17959 try pt.intValue(Type.comptime_int, alignment)
17788 else17960 else
17789 try Type.fromInterned(info.child).lazyAbiAlignment(mod);17961 try Type.fromInterned(info.child).lazyAbiAlignment(pt);
1779017962
17791 const addrspace_ty = try mod.getBuiltinType("AddressSpace");17963 const addrspace_ty = try pt.getBuiltinType("AddressSpace");
17792 const pointer_ty = t: {17964 const pointer_ty = t: {
17793 const decl_index = (try sema.namespaceLookup(17965 const decl_index = (try sema.namespaceLookup(
17794 block,17966 block,
17795 src,17967 src,
17796 (try mod.getBuiltinType("Type")).getNamespaceIndex(mod),17968 (try pt.getBuiltinType("Type")).getNamespaceIndex(mod),
17797 try ip.getOrPutString(gpa, "Pointer", .no_embedded_nulls),17969 try ip.getOrPutString(gpa, pt.tid, "Pointer", .no_embedded_nulls),
17798 )).?;17970 )).?;
17799 try sema.ensureDeclAnalyzed(decl_index);17971 try sema.ensureDeclAnalyzed(decl_index);
17800 const decl = mod.declPtr(decl_index);17972 const decl = mod.declPtr(decl_index);
...@@ -17805,7 +17977,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -17805,7 +17977,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
17805 block,17977 block,
17806 src,17978 src,
17807 pointer_ty.getNamespaceIndex(mod),17979 pointer_ty.getNamespaceIndex(mod),
17808 try ip.getOrPutString(gpa, "Size", .no_embedded_nulls),17980 try ip.getOrPutString(gpa, pt.tid, "Size", .no_embedded_nulls),
17809 )).?;17981 )).?;
17810 try sema.ensureDeclAnalyzed(decl_index);17982 try sema.ensureDeclAnalyzed(decl_index);
17811 const decl = mod.declPtr(decl_index);17983 const decl = mod.declPtr(decl_index);
...@@ -17814,7 +17986,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -17814,7 +17986,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1781417986
17815 const field_values = .{17987 const field_values = .{
17816 // size: Size,17988 // size: Size,
17817 (try mod.enumValueFieldIndex(ptr_size_ty, @intFromEnum(info.flags.size))).toIntern(),17989 (try pt.enumValueFieldIndex(ptr_size_ty, @intFromEnum(info.flags.size))).toIntern(),
17818 // is_const: bool,17990 // is_const: bool,
17819 Value.makeBool(info.flags.is_const).toIntern(),17991 Value.makeBool(info.flags.is_const).toIntern(),
17820 // is_volatile: bool,17992 // is_volatile: bool,
...@@ -17822,7 +17994,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -17822,7 +17994,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
17822 // alignment: comptime_int,17994 // alignment: comptime_int,
17823 alignment.toIntern(),17995 alignment.toIntern(),
17824 // address_space: AddressSpace17996 // address_space: AddressSpace
17825 (try mod.enumValueFieldIndex(addrspace_ty, @intFromEnum(info.flags.address_space))).toIntern(),17997 (try pt.enumValueFieldIndex(addrspace_ty, @intFromEnum(info.flags.address_space))).toIntern(),
17826 // child: type,17998 // child: type,
17827 info.child,17999 info.child,
17828 // is_allowzero: bool,18000 // is_allowzero: bool,
...@@ -17833,10 +18005,10 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -17833,10 +18005,10 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
17833 else => Value.fromInterned(info.sentinel),18005 else => Value.fromInterned(info.sentinel),
17834 })).toIntern(),18006 })).toIntern(),
17835 };18007 };
17836 return Air.internedToRef((try mod.intern(.{ .un = .{18008 return Air.internedToRef((try pt.intern(.{ .un = .{
17837 .ty = type_info_ty.toIntern(),18009 .ty = type_info_ty.toIntern(),
17838 .tag = (try mod.enumValueFieldIndex(type_info_tag_ty, @intFromEnum(std.builtin.TypeId.Pointer))).toIntern(),18010 .tag = (try pt.enumValueFieldIndex(type_info_tag_ty, @intFromEnum(std.builtin.TypeId.Pointer))).toIntern(),
17839 .val = try mod.intern(.{ .aggregate = .{18011 .val = try pt.intern(.{ .aggregate = .{
17840 .ty = pointer_ty.toIntern(),18012 .ty = pointer_ty.toIntern(),
17841 .storage = .{ .elems = &field_values },18013 .storage = .{ .elems = &field_values },
17842 } }),18014 } }),
...@@ -17848,7 +18020,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -17848,7 +18020,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
17848 block,18020 block,
17849 src,18021 src,
17850 type_info_ty.getNamespaceIndex(mod),18022 type_info_ty.getNamespaceIndex(mod),
17851 try ip.getOrPutString(gpa, "Array", .no_embedded_nulls),18023 try ip.getOrPutString(gpa, pt.tid, "Array", .no_embedded_nulls),
17852 )).?;18024 )).?;
17853 try sema.ensureDeclAnalyzed(array_field_ty_decl_index);18025 try sema.ensureDeclAnalyzed(array_field_ty_decl_index);
17854 const array_field_ty_decl = mod.declPtr(array_field_ty_decl_index);18026 const array_field_ty_decl = mod.declPtr(array_field_ty_decl_index);
...@@ -17858,16 +18030,16 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -17858,16 +18030,16 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
17858 const info = ty.arrayInfo(mod);18030 const info = ty.arrayInfo(mod);
17859 const field_values = .{18031 const field_values = .{
17860 // len: comptime_int,18032 // len: comptime_int,
17861 (try mod.intValue(Type.comptime_int, info.len)).toIntern(),18033 (try pt.intValue(Type.comptime_int, info.len)).toIntern(),
17862 // child: type,18034 // child: type,
17863 info.elem_type.toIntern(),18035 info.elem_type.toIntern(),
17864 // sentinel: ?*const anyopaque,18036 // sentinel: ?*const anyopaque,
17865 (try sema.optRefValue(info.sentinel)).toIntern(),18037 (try sema.optRefValue(info.sentinel)).toIntern(),
17866 };18038 };
17867 return Air.internedToRef((try mod.intern(.{ .un = .{18039 return Air.internedToRef((try pt.intern(.{ .un = .{
17868 .ty = type_info_ty.toIntern(),18040 .ty = type_info_ty.toIntern(),
17869 .tag = (try mod.enumValueFieldIndex(type_info_tag_ty, @intFromEnum(std.builtin.TypeId.Array))).toIntern(),18041 .tag = (try pt.enumValueFieldIndex(type_info_tag_ty, @intFromEnum(std.builtin.TypeId.Array))).toIntern(),
17870 .val = try mod.intern(.{ .aggregate = .{18042 .val = try pt.intern(.{ .aggregate = .{
17871 .ty = array_field_ty.toIntern(),18043 .ty = array_field_ty.toIntern(),
17872 .storage = .{ .elems = &field_values },18044 .storage = .{ .elems = &field_values },
17873 } }),18045 } }),
...@@ -17879,7 +18051,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -17879,7 +18051,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
17879 block,18051 block,
17880 src,18052 src,
17881 type_info_ty.getNamespaceIndex(mod),18053 type_info_ty.getNamespaceIndex(mod),
17882 try ip.getOrPutString(gpa, "Vector", .no_embedded_nulls),18054 try ip.getOrPutString(gpa, pt.tid, "Vector", .no_embedded_nulls),
17883 )).?;18055 )).?;
17884 try sema.ensureDeclAnalyzed(vector_field_ty_decl_index);18056 try sema.ensureDeclAnalyzed(vector_field_ty_decl_index);
17885 const vector_field_ty_decl = mod.declPtr(vector_field_ty_decl_index);18057 const vector_field_ty_decl = mod.declPtr(vector_field_ty_decl_index);
...@@ -17889,14 +18061,14 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -17889,14 +18061,14 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
17889 const info = ty.arrayInfo(mod);18061 const info = ty.arrayInfo(mod);
17890 const field_values = .{18062 const field_values = .{
17891 // len: comptime_int,18063 // len: comptime_int,
17892 (try mod.intValue(Type.comptime_int, info.len)).toIntern(),18064 (try pt.intValue(Type.comptime_int, info.len)).toIntern(),
17893 // child: type,18065 // child: type,
17894 info.elem_type.toIntern(),18066 info.elem_type.toIntern(),
17895 };18067 };
17896 return Air.internedToRef((try mod.intern(.{ .un = .{18068 return Air.internedToRef((try pt.intern(.{ .un = .{
17897 .ty = type_info_ty.toIntern(),18069 .ty = type_info_ty.toIntern(),
17898 .tag = (try mod.enumValueFieldIndex(type_info_tag_ty, @intFromEnum(std.builtin.TypeId.Vector))).toIntern(),18070 .tag = (try pt.enumValueFieldIndex(type_info_tag_ty, @intFromEnum(std.builtin.TypeId.Vector))).toIntern(),
17899 .val = try mod.intern(.{ .aggregate = .{18071 .val = try pt.intern(.{ .aggregate = .{
17900 .ty = vector_field_ty.toIntern(),18072 .ty = vector_field_ty.toIntern(),
17901 .storage = .{ .elems = &field_values },18073 .storage = .{ .elems = &field_values },
17902 } }),18074 } }),
...@@ -17908,7 +18080,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -17908,7 +18080,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
17908 block,18080 block,
17909 src,18081 src,
17910 type_info_ty.getNamespaceIndex(mod),18082 type_info_ty.getNamespaceIndex(mod),
17911 try ip.getOrPutString(gpa, "Optional", .no_embedded_nulls),18083 try ip.getOrPutString(gpa, pt.tid, "Optional", .no_embedded_nulls),
17912 )).?;18084 )).?;
17913 try sema.ensureDeclAnalyzed(optional_field_ty_decl_index);18085 try sema.ensureDeclAnalyzed(optional_field_ty_decl_index);
17914 const optional_field_ty_decl = mod.declPtr(optional_field_ty_decl_index);18086 const optional_field_ty_decl = mod.declPtr(optional_field_ty_decl_index);
...@@ -17919,10 +18091,10 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -17919,10 +18091,10 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
17919 // child: type,18091 // child: type,
17920 ty.optionalChild(mod).toIntern(),18092 ty.optionalChild(mod).toIntern(),
17921 };18093 };
17922 return Air.internedToRef((try mod.intern(.{ .un = .{18094 return Air.internedToRef((try pt.intern(.{ .un = .{
17923 .ty = type_info_ty.toIntern(),18095 .ty = type_info_ty.toIntern(),
17924 .tag = (try mod.enumValueFieldIndex(type_info_tag_ty, @intFromEnum(std.builtin.TypeId.Optional))).toIntern(),18096 .tag = (try pt.enumValueFieldIndex(type_info_tag_ty, @intFromEnum(std.builtin.TypeId.Optional))).toIntern(),
17925 .val = try mod.intern(.{ .aggregate = .{18097 .val = try pt.intern(.{ .aggregate = .{
17926 .ty = optional_field_ty.toIntern(),18098 .ty = optional_field_ty.toIntern(),
17927 .storage = .{ .elems = &field_values },18099 .storage = .{ .elems = &field_values },
17928 } }),18100 } }),
...@@ -17935,7 +18107,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -17935,7 +18107,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
17935 block,18107 block,
17936 src,18108 src,
17937 type_info_ty.getNamespaceIndex(mod),18109 type_info_ty.getNamespaceIndex(mod),
17938 try ip.getOrPutString(gpa, "Error", .no_embedded_nulls),18110 try ip.getOrPutString(gpa, pt.tid, "Error", .no_embedded_nulls),
17939 )).?;18111 )).?;
17940 try sema.ensureDeclAnalyzed(set_field_ty_decl_index);18112 try sema.ensureDeclAnalyzed(set_field_ty_decl_index);
17941 const set_field_ty_decl = mod.declPtr(set_field_ty_decl_index);18113 const set_field_ty_decl = mod.declPtr(set_field_ty_decl_index);
...@@ -17954,18 +18126,18 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -17954,18 +18126,18 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
17954 const error_name = names.get(ip)[error_index];18126 const error_name = names.get(ip)[error_index];
17955 const error_name_len = error_name.length(ip);18127 const error_name_len = error_name.length(ip);
17956 const error_name_val = v: {18128 const error_name_val = v: {
17957 const new_decl_ty = try mod.arrayType(.{18129 const new_decl_ty = try pt.arrayType(.{
17958 .len = error_name_len,18130 .len = error_name_len,
17959 .sentinel = .zero_u8,18131 .sentinel = .zero_u8,
17960 .child = .u8_type,18132 .child = .u8_type,
17961 });18133 });
17962 const new_decl_val = try mod.intern(.{ .aggregate = .{18134 const new_decl_val = try pt.intern(.{ .aggregate = .{
17963 .ty = new_decl_ty.toIntern(),18135 .ty = new_decl_ty.toIntern(),
17964 .storage = .{ .bytes = error_name.toString() },18136 .storage = .{ .bytes = error_name.toString() },
17965 } });18137 } });
17966 break :v try mod.intern(.{ .slice = .{18138 break :v try pt.intern(.{ .slice = .{
17967 .ty = .slice_const_u8_sentinel_0_type,18139 .ty = .slice_const_u8_sentinel_0_type,
17968 .ptr = try mod.intern(.{ .ptr = .{18140 .ptr = try pt.intern(.{ .ptr = .{
17969 .ty = .manyptr_const_u8_sentinel_0_type,18141 .ty = .manyptr_const_u8_sentinel_0_type,
17970 .base_addr = .{ .anon_decl = .{18142 .base_addr = .{ .anon_decl = .{
17971 .val = new_decl_val,18143 .val = new_decl_val,
...@@ -17973,7 +18145,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -17973,7 +18145,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
17973 } },18145 } },
17974 .byte_offset = 0,18146 .byte_offset = 0,
17975 } }),18147 } }),
17976 .len = (try mod.intValue(Type.usize, error_name_len)).toIntern(),18148 .len = (try pt.intValue(Type.usize, error_name_len)).toIntern(),
17977 } });18149 } });
17978 };18150 };
1797918151
...@@ -17981,7 +18153,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -17981,7 +18153,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
17981 // name: [:0]const u8,18153 // name: [:0]const u8,
17982 error_name_val,18154 error_name_val,
17983 };18155 };
17984 field_val.* = try mod.intern(.{ .aggregate = .{18156 field_val.* = try pt.intern(.{ .aggregate = .{
17985 .ty = error_field_ty.toIntern(),18157 .ty = error_field_ty.toIntern(),
17986 .storage = .{ .elems = &error_field_fields },18158 .storage = .{ .elems = &error_field_fields },
17987 } });18159 } });
...@@ -17992,27 +18164,27 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -17992,27 +18164,27 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
17992 };18164 };
1799318165
17994 // Build our ?[]const Error value18166 // Build our ?[]const Error value
17995 const slice_errors_ty = try mod.ptrTypeSema(.{18167 const slice_errors_ty = try pt.ptrTypeSema(.{
17996 .child = error_field_ty.toIntern(),18168 .child = error_field_ty.toIntern(),
17997 .flags = .{18169 .flags = .{
17998 .size = .Slice,18170 .size = .Slice,
17999 .is_const = true,18171 .is_const = true,
18000 },18172 },
18001 });18173 });
18002 const opt_slice_errors_ty = try mod.optionalType(slice_errors_ty.toIntern());18174 const opt_slice_errors_ty = try pt.optionalType(slice_errors_ty.toIntern());
18003 const errors_payload_val: InternPool.Index = if (error_field_vals) |vals| v: {18175 const errors_payload_val: InternPool.Index = if (error_field_vals) |vals| v: {
18004 const array_errors_ty = try mod.arrayType(.{18176 const array_errors_ty = try pt.arrayType(.{
18005 .len = vals.len,18177 .len = vals.len,
18006 .child = error_field_ty.toIntern(),18178 .child = error_field_ty.toIntern(),
18007 });18179 });
18008 const new_decl_val = try mod.intern(.{ .aggregate = .{18180 const new_decl_val = try pt.intern(.{ .aggregate = .{
18009 .ty = array_errors_ty.toIntern(),18181 .ty = array_errors_ty.toIntern(),
18010 .storage = .{ .elems = vals },18182 .storage = .{ .elems = vals },
18011 } });18183 } });
18012 const manyptr_errors_ty = slice_errors_ty.slicePtrFieldType(mod).toIntern();18184 const manyptr_errors_ty = slice_errors_ty.slicePtrFieldType(mod).toIntern();
18013 break :v try mod.intern(.{ .slice = .{18185 break :v try pt.intern(.{ .slice = .{
18014 .ty = slice_errors_ty.toIntern(),18186 .ty = slice_errors_ty.toIntern(),
18015 .ptr = try mod.intern(.{ .ptr = .{18187 .ptr = try pt.intern(.{ .ptr = .{
18016 .ty = manyptr_errors_ty,18188 .ty = manyptr_errors_ty,
18017 .base_addr = .{ .anon_decl = .{18189 .base_addr = .{ .anon_decl = .{
18018 .orig_ty = manyptr_errors_ty,18190 .orig_ty = manyptr_errors_ty,
...@@ -18020,18 +18192,18 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -18020,18 +18192,18 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
18020 } },18192 } },
18021 .byte_offset = 0,18193 .byte_offset = 0,
18022 } }),18194 } }),
18023 .len = (try mod.intValue(Type.usize, vals.len)).toIntern(),18195 .len = (try pt.intValue(Type.usize, vals.len)).toIntern(),
18024 } });18196 } });
18025 } else .none;18197 } else .none;
18026 const errors_val = try mod.intern(.{ .opt = .{18198 const errors_val = try pt.intern(.{ .opt = .{
18027 .ty = opt_slice_errors_ty.toIntern(),18199 .ty = opt_slice_errors_ty.toIntern(),
18028 .val = errors_payload_val,18200 .val = errors_payload_val,
18029 } });18201 } });
1803018202
18031 // Construct Type{ .ErrorSet = errors_val }18203 // Construct Type{ .ErrorSet = errors_val }
18032 return Air.internedToRef((try mod.intern(.{ .un = .{18204 return Air.internedToRef((try pt.intern(.{ .un = .{
18033 .ty = type_info_ty.toIntern(),18205 .ty = type_info_ty.toIntern(),
18034 .tag = (try mod.enumValueFieldIndex(type_info_tag_ty, @intFromEnum(std.builtin.TypeId.ErrorSet))).toIntern(),18206 .tag = (try pt.enumValueFieldIndex(type_info_tag_ty, @intFromEnum(std.builtin.TypeId.ErrorSet))).toIntern(),
18035 .val = errors_val,18207 .val = errors_val,
18036 } })));18208 } })));
18037 },18209 },
...@@ -18041,7 +18213,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -18041,7 +18213,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
18041 block,18213 block,
18042 src,18214 src,
18043 type_info_ty.getNamespaceIndex(mod),18215 type_info_ty.getNamespaceIndex(mod),
18044 try ip.getOrPutString(gpa, "ErrorUnion", .no_embedded_nulls),18216 try ip.getOrPutString(gpa, pt.tid, "ErrorUnion", .no_embedded_nulls),
18045 )).?;18217 )).?;
18046 try sema.ensureDeclAnalyzed(error_union_field_ty_decl_index);18218 try sema.ensureDeclAnalyzed(error_union_field_ty_decl_index);
18047 const error_union_field_ty_decl = mod.declPtr(error_union_field_ty_decl_index);18219 const error_union_field_ty_decl = mod.declPtr(error_union_field_ty_decl_index);
...@@ -18054,10 +18226,10 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -18054,10 +18226,10 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
18054 // payload: type,18226 // payload: type,
18055 ty.errorUnionPayload(mod).toIntern(),18227 ty.errorUnionPayload(mod).toIntern(),
18056 };18228 };
18057 return Air.internedToRef((try mod.intern(.{ .un = .{18229 return Air.internedToRef((try pt.intern(.{ .un = .{
18058 .ty = type_info_ty.toIntern(),18230 .ty = type_info_ty.toIntern(),
18059 .tag = (try mod.enumValueFieldIndex(type_info_tag_ty, @intFromEnum(std.builtin.TypeId.ErrorUnion))).toIntern(),18231 .tag = (try pt.enumValueFieldIndex(type_info_tag_ty, @intFromEnum(std.builtin.TypeId.ErrorUnion))).toIntern(),
18060 .val = try mod.intern(.{ .aggregate = .{18232 .val = try pt.intern(.{ .aggregate = .{
18061 .ty = error_union_field_ty.toIntern(),18233 .ty = error_union_field_ty.toIntern(),
18062 .storage = .{ .elems = &field_values },18234 .storage = .{ .elems = &field_values },
18063 } }),18235 } }),
...@@ -18071,7 +18243,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -18071,7 +18243,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
18071 block,18243 block,
18072 src,18244 src,
18073 type_info_ty.getNamespaceIndex(mod),18245 type_info_ty.getNamespaceIndex(mod),
18074 try ip.getOrPutString(gpa, "EnumField", .no_embedded_nulls),18246 try ip.getOrPutString(gpa, pt.tid, "EnumField", .no_embedded_nulls),
18075 )).?;18247 )).?;
18076 try sema.ensureDeclAnalyzed(enum_field_ty_decl_index);18248 try sema.ensureDeclAnalyzed(enum_field_ty_decl_index);
18077 const enum_field_ty_decl = mod.declPtr(enum_field_ty_decl_index);18249 const enum_field_ty_decl = mod.declPtr(enum_field_ty_decl_index);
...@@ -18082,30 +18254,31 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -18082,30 +18254,31 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
18082 for (enum_field_vals, 0..) |*field_val, tag_index| {18254 for (enum_field_vals, 0..) |*field_val, tag_index| {
18083 const enum_type = ip.loadEnumType(ty.toIntern());18255 const enum_type = ip.loadEnumType(ty.toIntern());
18084 const value_val = if (enum_type.values.len > 0)18256 const value_val = if (enum_type.values.len > 0)
18085 try mod.intern_pool.getCoercedInts(18257 try ip.getCoercedInts(
18086 mod.gpa,18258 mod.gpa,
18087 mod.intern_pool.indexToKey(enum_type.values.get(ip)[tag_index]).int,18259 pt.tid,
18260 ip.indexToKey(enum_type.values.get(ip)[tag_index]).int,
18088 .comptime_int_type,18261 .comptime_int_type,
18089 )18262 )
18090 else18263 else
18091 (try mod.intValue(Type.comptime_int, tag_index)).toIntern();18264 (try pt.intValue(Type.comptime_int, tag_index)).toIntern();
1809218265
18093 // TODO: write something like getCoercedInts to avoid needing to dupe18266 // TODO: write something like getCoercedInts to avoid needing to dupe
18094 const name_val = v: {18267 const name_val = v: {
18095 const tag_name = enum_type.names.get(ip)[tag_index];18268 const tag_name = enum_type.names.get(ip)[tag_index];
18096 const tag_name_len = tag_name.length(ip);18269 const tag_name_len = tag_name.length(ip);
18097 const new_decl_ty = try mod.arrayType(.{18270 const new_decl_ty = try pt.arrayType(.{
18098 .len = tag_name_len,18271 .len = tag_name_len,
18099 .sentinel = .zero_u8,18272 .sentinel = .zero_u8,
18100 .child = .u8_type,18273 .child = .u8_type,
18101 });18274 });
18102 const new_decl_val = try mod.intern(.{ .aggregate = .{18275 const new_decl_val = try pt.intern(.{ .aggregate = .{
18103 .ty = new_decl_ty.toIntern(),18276 .ty = new_decl_ty.toIntern(),
18104 .storage = .{ .bytes = tag_name.toString() },18277 .storage = .{ .bytes = tag_name.toString() },
18105 } });18278 } });
18106 break :v try mod.intern(.{ .slice = .{18279 break :v try pt.intern(.{ .slice = .{
18107 .ty = .slice_const_u8_sentinel_0_type,18280 .ty = .slice_const_u8_sentinel_0_type,
18108 .ptr = try mod.intern(.{ .ptr = .{18281 .ptr = try pt.intern(.{ .ptr = .{
18109 .ty = .manyptr_const_u8_sentinel_0_type,18282 .ty = .manyptr_const_u8_sentinel_0_type,
18110 .base_addr = .{ .anon_decl = .{18283 .base_addr = .{ .anon_decl = .{
18111 .val = new_decl_val,18284 .val = new_decl_val,
...@@ -18113,7 +18286,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -18113,7 +18286,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
18113 } },18286 } },
18114 .byte_offset = 0,18287 .byte_offset = 0,
18115 } }),18288 } }),
18116 .len = (try mod.intValue(Type.usize, tag_name_len)).toIntern(),18289 .len = (try pt.intValue(Type.usize, tag_name_len)).toIntern(),
18117 } });18290 } });
18118 };18291 };
1811918292
...@@ -18123,22 +18296,22 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -18123,22 +18296,22 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
18123 // value: comptime_int,18296 // value: comptime_int,
18124 value_val,18297 value_val,
18125 };18298 };
18126 field_val.* = try mod.intern(.{ .aggregate = .{18299 field_val.* = try pt.intern(.{ .aggregate = .{
18127 .ty = enum_field_ty.toIntern(),18300 .ty = enum_field_ty.toIntern(),
18128 .storage = .{ .elems = &enum_field_fields },18301 .storage = .{ .elems = &enum_field_fields },
18129 } });18302 } });
18130 }18303 }
1813118304
18132 const fields_val = v: {18305 const fields_val = v: {
18133 const fields_array_ty = try mod.arrayType(.{18306 const fields_array_ty = try pt.arrayType(.{
18134 .len = enum_field_vals.len,18307 .len = enum_field_vals.len,
18135 .child = enum_field_ty.toIntern(),18308 .child = enum_field_ty.toIntern(),
18136 });18309 });
18137 const new_decl_val = try mod.intern(.{ .aggregate = .{18310 const new_decl_val = try pt.intern(.{ .aggregate = .{
18138 .ty = fields_array_ty.toIntern(),18311 .ty = fields_array_ty.toIntern(),
18139 .storage = .{ .elems = enum_field_vals },18312 .storage = .{ .elems = enum_field_vals },
18140 } });18313 } });
18141 const slice_ty = (try mod.ptrTypeSema(.{18314 const slice_ty = (try pt.ptrTypeSema(.{
18142 .child = enum_field_ty.toIntern(),18315 .child = enum_field_ty.toIntern(),
18143 .flags = .{18316 .flags = .{
18144 .size = .Slice,18317 .size = .Slice,
...@@ -18146,9 +18319,9 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -18146,9 +18319,9 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
18146 },18319 },
18147 })).toIntern();18320 })).toIntern();
18148 const manyptr_ty = Type.fromInterned(slice_ty).slicePtrFieldType(mod).toIntern();18321 const manyptr_ty = Type.fromInterned(slice_ty).slicePtrFieldType(mod).toIntern();
18149 break :v try mod.intern(.{ .slice = .{18322 break :v try pt.intern(.{ .slice = .{
18150 .ty = slice_ty,18323 .ty = slice_ty,
18151 .ptr = try mod.intern(.{ .ptr = .{18324 .ptr = try pt.intern(.{ .ptr = .{
18152 .ty = manyptr_ty,18325 .ty = manyptr_ty,
18153 .base_addr = .{ .anon_decl = .{18326 .base_addr = .{ .anon_decl = .{
18154 .val = new_decl_val,18327 .val = new_decl_val,
...@@ -18156,7 +18329,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -18156,7 +18329,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
18156 } },18329 } },
18157 .byte_offset = 0,18330 .byte_offset = 0,
18158 } }),18331 } }),
18159 .len = (try mod.intValue(Type.usize, enum_field_vals.len)).toIntern(),18332 .len = (try pt.intValue(Type.usize, enum_field_vals.len)).toIntern(),
18160 } });18333 } });
18161 };18334 };
1816218335
...@@ -18167,7 +18340,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -18167,7 +18340,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
18167 block,18340 block,
18168 src,18341 src,
18169 type_info_ty.getNamespaceIndex(mod),18342 type_info_ty.getNamespaceIndex(mod),
18170 try ip.getOrPutString(gpa, "Enum", .no_embedded_nulls),18343 try ip.getOrPutString(gpa, pt.tid, "Enum", .no_embedded_nulls),
18171 )).?;18344 )).?;
18172 try sema.ensureDeclAnalyzed(type_enum_ty_decl_index);18345 try sema.ensureDeclAnalyzed(type_enum_ty_decl_index);
18173 const type_enum_ty_decl = mod.declPtr(type_enum_ty_decl_index);18346 const type_enum_ty_decl = mod.declPtr(type_enum_ty_decl_index);
...@@ -18184,10 +18357,10 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -18184,10 +18357,10 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
18184 // is_exhaustive: bool,18357 // is_exhaustive: bool,
18185 is_exhaustive.toIntern(),18358 is_exhaustive.toIntern(),
18186 };18359 };
18187 return Air.internedToRef((try mod.intern(.{ .un = .{18360 return Air.internedToRef((try pt.intern(.{ .un = .{
18188 .ty = type_info_ty.toIntern(),18361 .ty = type_info_ty.toIntern(),
18189 .tag = (try mod.enumValueFieldIndex(type_info_tag_ty, @intFromEnum(std.builtin.TypeId.Enum))).toIntern(),18362 .tag = (try pt.enumValueFieldIndex(type_info_tag_ty, @intFromEnum(std.builtin.TypeId.Enum))).toIntern(),
18190 .val = try mod.intern(.{ .aggregate = .{18363 .val = try pt.intern(.{ .aggregate = .{
18191 .ty = type_enum_ty.toIntern(),18364 .ty = type_enum_ty.toIntern(),
18192 .storage = .{ .elems = &field_values },18365 .storage = .{ .elems = &field_values },
18193 } }),18366 } }),
...@@ -18199,7 +18372,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -18199,7 +18372,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
18199 block,18372 block,
18200 src,18373 src,
18201 type_info_ty.getNamespaceIndex(mod),18374 type_info_ty.getNamespaceIndex(mod),
18202 try ip.getOrPutString(gpa, "Union", .no_embedded_nulls),18375 try ip.getOrPutString(gpa, pt.tid, "Union", .no_embedded_nulls),
18203 )).?;18376 )).?;
18204 try sema.ensureDeclAnalyzed(type_union_ty_decl_index);18377 try sema.ensureDeclAnalyzed(type_union_ty_decl_index);
18205 const type_union_ty_decl = mod.declPtr(type_union_ty_decl_index);18378 const type_union_ty_decl = mod.declPtr(type_union_ty_decl_index);
...@@ -18211,14 +18384,14 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -18211,14 +18384,14 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
18211 block,18384 block,
18212 src,18385 src,
18213 type_info_ty.getNamespaceIndex(mod),18386 type_info_ty.getNamespaceIndex(mod),
18214 try ip.getOrPutString(gpa, "UnionField", .no_embedded_nulls),18387 try ip.getOrPutString(gpa, pt.tid, "UnionField", .no_embedded_nulls),
18215 )).?;18388 )).?;
18216 try sema.ensureDeclAnalyzed(union_field_ty_decl_index);18389 try sema.ensureDeclAnalyzed(union_field_ty_decl_index);
18217 const union_field_ty_decl = mod.declPtr(union_field_ty_decl_index);18390 const union_field_ty_decl = mod.declPtr(union_field_ty_decl_index);
18218 break :t union_field_ty_decl.val.toType();18391 break :t union_field_ty_decl.val.toType();
18219 };18392 };
1822018393
18221 try ty.resolveLayout(mod); // Getting alignment requires type layout18394 try ty.resolveLayout(pt); // Getting alignment requires type layout
18222 const union_obj = mod.typeToUnion(ty).?;18395 const union_obj = mod.typeToUnion(ty).?;
18223 const tag_type = union_obj.loadTagType(ip);18396 const tag_type = union_obj.loadTagType(ip);
18224 const layout = union_obj.getLayout(ip);18397 const layout = union_obj.getLayout(ip);
...@@ -18230,18 +18403,18 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -18230,18 +18403,18 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
18230 const name_val = v: {18403 const name_val = v: {
18231 const field_name = tag_type.names.get(ip)[field_index];18404 const field_name = tag_type.names.get(ip)[field_index];
18232 const field_name_len = field_name.length(ip);18405 const field_name_len = field_name.length(ip);
18233 const new_decl_ty = try mod.arrayType(.{18406 const new_decl_ty = try pt.arrayType(.{
18234 .len = field_name_len,18407 .len = field_name_len,
18235 .sentinel = .zero_u8,18408 .sentinel = .zero_u8,
18236 .child = .u8_type,18409 .child = .u8_type,
18237 });18410 });
18238 const new_decl_val = try mod.intern(.{ .aggregate = .{18411 const new_decl_val = try pt.intern(.{ .aggregate = .{
18239 .ty = new_decl_ty.toIntern(),18412 .ty = new_decl_ty.toIntern(),
18240 .storage = .{ .bytes = field_name.toString() },18413 .storage = .{ .bytes = field_name.toString() },
18241 } });18414 } });
18242 break :v try mod.intern(.{ .slice = .{18415 break :v try pt.intern(.{ .slice = .{
18243 .ty = .slice_const_u8_sentinel_0_type,18416 .ty = .slice_const_u8_sentinel_0_type,
18244 .ptr = try mod.intern(.{ .ptr = .{18417 .ptr = try pt.intern(.{ .ptr = .{
18245 .ty = .manyptr_const_u8_sentinel_0_type,18418 .ty = .manyptr_const_u8_sentinel_0_type,
18246 .base_addr = .{ .anon_decl = .{18419 .base_addr = .{ .anon_decl = .{
18247 .val = new_decl_val,18420 .val = new_decl_val,
...@@ -18249,12 +18422,12 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -18249,12 +18422,12 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
18249 } },18422 } },
18250 .byte_offset = 0,18423 .byte_offset = 0,
18251 } }),18424 } }),
18252 .len = (try mod.intValue(Type.usize, field_name_len)).toIntern(),18425 .len = (try pt.intValue(Type.usize, field_name_len)).toIntern(),
18253 } });18426 } });
18254 };18427 };
1825518428
18256 const alignment = switch (layout) {18429 const alignment = switch (layout) {
18257 .auto, .@"extern" => try mod.unionFieldNormalAlignmentAdvanced(union_obj, @intCast(field_index), .sema),18430 .auto, .@"extern" => try pt.unionFieldNormalAlignmentAdvanced(union_obj, @intCast(field_index), .sema),
18258 .@"packed" => .none,18431 .@"packed" => .none,
18259 };18432 };
1826018433
...@@ -18265,24 +18438,24 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -18265,24 +18438,24 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
18265 // type: type,18438 // type: type,
18266 field_ty,18439 field_ty,
18267 // alignment: comptime_int,18440 // alignment: comptime_int,
18268 (try mod.intValue(Type.comptime_int, alignment.toByteUnits() orelse 0)).toIntern(),18441 (try pt.intValue(Type.comptime_int, alignment.toByteUnits() orelse 0)).toIntern(),
18269 };18442 };
18270 field_val.* = try mod.intern(.{ .aggregate = .{18443 field_val.* = try pt.intern(.{ .aggregate = .{
18271 .ty = union_field_ty.toIntern(),18444 .ty = union_field_ty.toIntern(),
18272 .storage = .{ .elems = &union_field_fields },18445 .storage = .{ .elems = &union_field_fields },
18273 } });18446 } });
18274 }18447 }
1827518448
18276 const fields_val = v: {18449 const fields_val = v: {
18277 const array_fields_ty = try mod.arrayType(.{18450 const array_fields_ty = try pt.arrayType(.{
18278 .len = union_field_vals.len,18451 .len = union_field_vals.len,
18279 .child = union_field_ty.toIntern(),18452 .child = union_field_ty.toIntern(),
18280 });18453 });
18281 const new_decl_val = try mod.intern(.{ .aggregate = .{18454 const new_decl_val = try pt.intern(.{ .aggregate = .{
18282 .ty = array_fields_ty.toIntern(),18455 .ty = array_fields_ty.toIntern(),
18283 .storage = .{ .elems = union_field_vals },18456 .storage = .{ .elems = union_field_vals },
18284 } });18457 } });
18285 const slice_ty = (try mod.ptrTypeSema(.{18458 const slice_ty = (try pt.ptrTypeSema(.{
18286 .child = union_field_ty.toIntern(),18459 .child = union_field_ty.toIntern(),
18287 .flags = .{18460 .flags = .{
18288 .size = .Slice,18461 .size = .Slice,
...@@ -18290,9 +18463,9 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -18290,9 +18463,9 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
18290 },18463 },
18291 })).toIntern();18464 })).toIntern();
18292 const manyptr_ty = Type.fromInterned(slice_ty).slicePtrFieldType(mod).toIntern();18465 const manyptr_ty = Type.fromInterned(slice_ty).slicePtrFieldType(mod).toIntern();
18293 break :v try mod.intern(.{ .slice = .{18466 break :v try pt.intern(.{ .slice = .{
18294 .ty = slice_ty,18467 .ty = slice_ty,
18295 .ptr = try mod.intern(.{ .ptr = .{18468 .ptr = try pt.intern(.{ .ptr = .{
18296 .ty = manyptr_ty,18469 .ty = manyptr_ty,
18297 .base_addr = .{ .anon_decl = .{18470 .base_addr = .{ .anon_decl = .{
18298 .orig_ty = manyptr_ty,18471 .orig_ty = manyptr_ty,
...@@ -18300,14 +18473,14 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -18300,14 +18473,14 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
18300 } },18473 } },
18301 .byte_offset = 0,18474 .byte_offset = 0,
18302 } }),18475 } }),
18303 .len = (try mod.intValue(Type.usize, union_field_vals.len)).toIntern(),18476 .len = (try pt.intValue(Type.usize, union_field_vals.len)).toIntern(),
18304 } });18477 } });
18305 };18478 };
1830618479
18307 const decls_val = try sema.typeInfoDecls(block, src, type_info_ty, ty.getNamespaceIndex(mod));18480 const decls_val = try sema.typeInfoDecls(block, src, type_info_ty, ty.getNamespaceIndex(mod));
1830818481
18309 const enum_tag_ty_val = try mod.intern(.{ .opt = .{18482 const enum_tag_ty_val = try pt.intern(.{ .opt = .{
18310 .ty = (try mod.optionalType(.type_type)).toIntern(),18483 .ty = (try pt.optionalType(.type_type)).toIntern(),
18311 .val = if (ty.unionTagType(mod)) |tag_ty| tag_ty.toIntern() else .none,18484 .val = if (ty.unionTagType(mod)) |tag_ty| tag_ty.toIntern() else .none,
18312 } });18485 } });
1831318486
...@@ -18315,8 +18488,8 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -18315,8 +18488,8 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
18315 const decl_index = (try sema.namespaceLookup(18488 const decl_index = (try sema.namespaceLookup(
18316 block,18489 block,
18317 src,18490 src,
18318 (try mod.getBuiltinType("Type")).getNamespaceIndex(mod),18491 (try pt.getBuiltinType("Type")).getNamespaceIndex(mod),
18319 try ip.getOrPutString(gpa, "ContainerLayout", .no_embedded_nulls),18492 try ip.getOrPutString(gpa, pt.tid, "ContainerLayout", .no_embedded_nulls),
18320 )).?;18493 )).?;
18321 try sema.ensureDeclAnalyzed(decl_index);18494 try sema.ensureDeclAnalyzed(decl_index);
18322 const decl = mod.declPtr(decl_index);18495 const decl = mod.declPtr(decl_index);
...@@ -18325,7 +18498,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -18325,7 +18498,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1832518498
18326 const field_values = .{18499 const field_values = .{
18327 // layout: ContainerLayout,18500 // layout: ContainerLayout,
18328 (try mod.enumValueFieldIndex(container_layout_ty, @intFromEnum(layout))).toIntern(),18501 (try pt.enumValueFieldIndex(container_layout_ty, @intFromEnum(layout))).toIntern(),
1832918502
18330 // tag_type: ?type,18503 // tag_type: ?type,
18331 enum_tag_ty_val,18504 enum_tag_ty_val,
...@@ -18334,10 +18507,10 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -18334,10 +18507,10 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
18334 // decls: []const Declaration,18507 // decls: []const Declaration,
18335 decls_val,18508 decls_val,
18336 };18509 };
18337 return Air.internedToRef((try mod.intern(.{ .un = .{18510 return Air.internedToRef((try pt.intern(.{ .un = .{
18338 .ty = type_info_ty.toIntern(),18511 .ty = type_info_ty.toIntern(),
18339 .tag = (try mod.enumValueFieldIndex(type_info_tag_ty, @intFromEnum(std.builtin.TypeId.Union))).toIntern(),18512 .tag = (try pt.enumValueFieldIndex(type_info_tag_ty, @intFromEnum(std.builtin.TypeId.Union))).toIntern(),
18340 .val = try mod.intern(.{ .aggregate = .{18513 .val = try pt.intern(.{ .aggregate = .{
18341 .ty = type_union_ty.toIntern(),18514 .ty = type_union_ty.toIntern(),
18342 .storage = .{ .elems = &field_values },18515 .storage = .{ .elems = &field_values },
18343 } }),18516 } }),
...@@ -18349,7 +18522,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -18349,7 +18522,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
18349 block,18522 block,
18350 src,18523 src,
18351 type_info_ty.getNamespaceIndex(mod),18524 type_info_ty.getNamespaceIndex(mod),
18352 try ip.getOrPutString(gpa, "Struct", .no_embedded_nulls),18525 try ip.getOrPutString(gpa, pt.tid, "Struct", .no_embedded_nulls),
18353 )).?;18526 )).?;
18354 try sema.ensureDeclAnalyzed(type_struct_ty_decl_index);18527 try sema.ensureDeclAnalyzed(type_struct_ty_decl_index);
18355 const type_struct_ty_decl = mod.declPtr(type_struct_ty_decl_index);18528 const type_struct_ty_decl = mod.declPtr(type_struct_ty_decl_index);
...@@ -18361,14 +18534,14 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -18361,14 +18534,14 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
18361 block,18534 block,
18362 src,18535 src,
18363 type_info_ty.getNamespaceIndex(mod),18536 type_info_ty.getNamespaceIndex(mod),
18364 try ip.getOrPutString(gpa, "StructField", .no_embedded_nulls),18537 try ip.getOrPutString(gpa, pt.tid, "StructField", .no_embedded_nulls),
18365 )).?;18538 )).?;
18366 try sema.ensureDeclAnalyzed(struct_field_ty_decl_index);18539 try sema.ensureDeclAnalyzed(struct_field_ty_decl_index);
18367 const struct_field_ty_decl = mod.declPtr(struct_field_ty_decl_index);18540 const struct_field_ty_decl = mod.declPtr(struct_field_ty_decl_index);
18368 break :t struct_field_ty_decl.val.toType();18541 break :t struct_field_ty_decl.val.toType();
18369 };18542 };
1837018543
18371 try ty.resolveLayout(mod); // Getting alignment requires type layout18544 try ty.resolveLayout(pt); // Getting alignment requires type layout
1837218545
18373 var struct_field_vals: []InternPool.Index = &.{};18546 var struct_field_vals: []InternPool.Index = &.{};
18374 defer gpa.free(struct_field_vals);18547 defer gpa.free(struct_field_vals);
...@@ -18383,20 +18556,20 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -18383,20 +18556,20 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
18383 const field_name = if (anon_struct_type.names.len != 0)18556 const field_name = if (anon_struct_type.names.len != 0)
18384 anon_struct_type.names.get(ip)[field_index]18557 anon_struct_type.names.get(ip)[field_index]
18385 else18558 else
18386 try ip.getOrPutStringFmt(gpa, "{d}", .{field_index}, .no_embedded_nulls);18559 try ip.getOrPutStringFmt(gpa, pt.tid, "{d}", .{field_index}, .no_embedded_nulls);
18387 const field_name_len = field_name.length(ip);18560 const field_name_len = field_name.length(ip);
18388 const new_decl_ty = try mod.arrayType(.{18561 const new_decl_ty = try pt.arrayType(.{
18389 .len = field_name_len,18562 .len = field_name_len,
18390 .sentinel = .zero_u8,18563 .sentinel = .zero_u8,
18391 .child = .u8_type,18564 .child = .u8_type,
18392 });18565 });
18393 const new_decl_val = try mod.intern(.{ .aggregate = .{18566 const new_decl_val = try pt.intern(.{ .aggregate = .{
18394 .ty = new_decl_ty.toIntern(),18567 .ty = new_decl_ty.toIntern(),
18395 .storage = .{ .bytes = field_name.toString() },18568 .storage = .{ .bytes = field_name.toString() },
18396 } });18569 } });
18397 break :v try mod.intern(.{ .slice = .{18570 break :v try pt.intern(.{ .slice = .{
18398 .ty = .slice_const_u8_sentinel_0_type,18571 .ty = .slice_const_u8_sentinel_0_type,
18399 .ptr = try mod.intern(.{ .ptr = .{18572 .ptr = try pt.intern(.{ .ptr = .{
18400 .ty = .manyptr_const_u8_sentinel_0_type,18573 .ty = .manyptr_const_u8_sentinel_0_type,
18401 .base_addr = .{ .anon_decl = .{18574 .base_addr = .{ .anon_decl = .{
18402 .val = new_decl_val,18575 .val = new_decl_val,
...@@ -18404,11 +18577,11 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -18404,11 +18577,11 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
18404 } },18577 } },
18405 .byte_offset = 0,18578 .byte_offset = 0,
18406 } }),18579 } }),
18407 .len = (try mod.intValue(Type.usize, field_name_len)).toIntern(),18580 .len = (try pt.intValue(Type.usize, field_name_len)).toIntern(),
18408 } });18581 } });
18409 };18582 };
1841018583
18411 try Type.fromInterned(field_ty).resolveLayout(mod);18584 try Type.fromInterned(field_ty).resolveLayout(pt);
1841218585
18413 const is_comptime = field_val != .none;18586 const is_comptime = field_val != .none;
18414 const opt_default_val = if (is_comptime) Value.fromInterned(field_val) else null;18587 const opt_default_val = if (is_comptime) Value.fromInterned(field_val) else null;
...@@ -18423,9 +18596,9 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -18423,9 +18596,9 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
18423 // is_comptime: bool,18596 // is_comptime: bool,
18424 Value.makeBool(is_comptime).toIntern(),18597 Value.makeBool(is_comptime).toIntern(),
18425 // alignment: comptime_int,18598 // alignment: comptime_int,
18426 (try mod.intValue(Type.comptime_int, Type.fromInterned(field_ty).abiAlignment(mod).toByteUnits() orelse 0)).toIntern(),18599 (try pt.intValue(Type.comptime_int, Type.fromInterned(field_ty).abiAlignment(pt).toByteUnits() orelse 0)).toIntern(),
18427 };18600 };
18428 struct_field_val.* = try mod.intern(.{ .aggregate = .{18601 struct_field_val.* = try pt.intern(.{ .aggregate = .{
18429 .ty = struct_field_ty.toIntern(),18602 .ty = struct_field_ty.toIntern(),
18430 .storage = .{ .elems = &struct_field_fields },18603 .storage = .{ .elems = &struct_field_fields },
18431 } });18604 } });
...@@ -18437,30 +18610,30 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -18437,30 +18610,30 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
18437 };18610 };
18438 struct_field_vals = try gpa.alloc(InternPool.Index, struct_type.field_types.len);18611 struct_field_vals = try gpa.alloc(InternPool.Index, struct_type.field_types.len);
1843918612
18440 try ty.resolveStructFieldInits(mod);18613 try ty.resolveStructFieldInits(pt);
1844118614
18442 for (struct_field_vals, 0..) |*field_val, field_index| {18615 for (struct_field_vals, 0..) |*field_val, field_index| {
18443 const field_name = if (struct_type.fieldName(ip, field_index).unwrap()) |field_name|18616 const field_name = if (struct_type.fieldName(ip, field_index).unwrap()) |field_name|
18444 field_name18617 field_name
18445 else18618 else
18446 try ip.getOrPutStringFmt(gpa, "{d}", .{field_index}, .no_embedded_nulls);18619 try ip.getOrPutStringFmt(gpa, pt.tid, "{d}", .{field_index}, .no_embedded_nulls);
18447 const field_name_len = field_name.length(ip);18620 const field_name_len = field_name.length(ip);
18448 const field_ty = Type.fromInterned(struct_type.field_types.get(ip)[field_index]);18621 const field_ty = Type.fromInterned(struct_type.field_types.get(ip)[field_index]);
18449 const field_init = struct_type.fieldInit(ip, field_index);18622 const field_init = struct_type.fieldInit(ip, field_index);
18450 const field_is_comptime = struct_type.fieldIsComptime(ip, field_index);18623 const field_is_comptime = struct_type.fieldIsComptime(ip, field_index);
18451 const name_val = v: {18624 const name_val = v: {
18452 const new_decl_ty = try mod.arrayType(.{18625 const new_decl_ty = try pt.arrayType(.{
18453 .len = field_name_len,18626 .len = field_name_len,
18454 .sentinel = .zero_u8,18627 .sentinel = .zero_u8,
18455 .child = .u8_type,18628 .child = .u8_type,
18456 });18629 });
18457 const new_decl_val = try mod.intern(.{ .aggregate = .{18630 const new_decl_val = try pt.intern(.{ .aggregate = .{
18458 .ty = new_decl_ty.toIntern(),18631 .ty = new_decl_ty.toIntern(),
18459 .storage = .{ .bytes = field_name.toString() },18632 .storage = .{ .bytes = field_name.toString() },
18460 } });18633 } });
18461 break :v try mod.intern(.{ .slice = .{18634 break :v try pt.intern(.{ .slice = .{
18462 .ty = .slice_const_u8_sentinel_0_type,18635 .ty = .slice_const_u8_sentinel_0_type,
18463 .ptr = try mod.intern(.{ .ptr = .{18636 .ptr = try pt.intern(.{ .ptr = .{
18464 .ty = .manyptr_const_u8_sentinel_0_type,18637 .ty = .manyptr_const_u8_sentinel_0_type,
18465 .base_addr = .{ .anon_decl = .{18638 .base_addr = .{ .anon_decl = .{
18466 .val = new_decl_val,18639 .val = new_decl_val,
...@@ -18468,7 +18641,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -18468,7 +18641,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
18468 } },18641 } },
18469 .byte_offset = 0,18642 .byte_offset = 0,
18470 } }),18643 } }),
18471 .len = (try mod.intValue(Type.usize, field_name_len)).toIntern(),18644 .len = (try pt.intValue(Type.usize, field_name_len)).toIntern(),
18472 } });18645 } });
18473 };18646 };
1847418647
...@@ -18476,7 +18649,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -18476,7 +18649,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
18476 const default_val_ptr = try sema.optRefValue(opt_default_val);18649 const default_val_ptr = try sema.optRefValue(opt_default_val);
18477 const alignment = switch (struct_type.layout) {18650 const alignment = switch (struct_type.layout) {
18478 .@"packed" => .none,18651 .@"packed" => .none,
18479 else => try mod.structFieldAlignmentAdvanced(18652 else => try pt.structFieldAlignmentAdvanced(
18480 struct_type.fieldAlign(ip, field_index),18653 struct_type.fieldAlign(ip, field_index),
18481 field_ty,18654 field_ty,
18482 struct_type.layout,18655 struct_type.layout,
...@@ -18494,9 +18667,9 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -18494,9 +18667,9 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
18494 // is_comptime: bool,18667 // is_comptime: bool,
18495 Value.makeBool(field_is_comptime).toIntern(),18668 Value.makeBool(field_is_comptime).toIntern(),
18496 // alignment: comptime_int,18669 // alignment: comptime_int,
18497 (try mod.intValue(Type.comptime_int, alignment.toByteUnits() orelse 0)).toIntern(),18670 (try pt.intValue(Type.comptime_int, alignment.toByteUnits() orelse 0)).toIntern(),
18498 };18671 };
18499 field_val.* = try mod.intern(.{ .aggregate = .{18672 field_val.* = try pt.intern(.{ .aggregate = .{
18500 .ty = struct_field_ty.toIntern(),18673 .ty = struct_field_ty.toIntern(),
18501 .storage = .{ .elems = &struct_field_fields },18674 .storage = .{ .elems = &struct_field_fields },
18502 } });18675 } });
...@@ -18504,15 +18677,15 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -18504,15 +18677,15 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
18504 }18677 }
1850518678
18506 const fields_val = v: {18679 const fields_val = v: {
18507 const array_fields_ty = try mod.arrayType(.{18680 const array_fields_ty = try pt.arrayType(.{
18508 .len = struct_field_vals.len,18681 .len = struct_field_vals.len,
18509 .child = struct_field_ty.toIntern(),18682 .child = struct_field_ty.toIntern(),
18510 });18683 });
18511 const new_decl_val = try mod.intern(.{ .aggregate = .{18684 const new_decl_val = try pt.intern(.{ .aggregate = .{
18512 .ty = array_fields_ty.toIntern(),18685 .ty = array_fields_ty.toIntern(),
18513 .storage = .{ .elems = struct_field_vals },18686 .storage = .{ .elems = struct_field_vals },
18514 } });18687 } });
18515 const slice_ty = (try mod.ptrTypeSema(.{18688 const slice_ty = (try pt.ptrTypeSema(.{
18516 .child = struct_field_ty.toIntern(),18689 .child = struct_field_ty.toIntern(),
18517 .flags = .{18690 .flags = .{
18518 .size = .Slice,18691 .size = .Slice,
...@@ -18520,9 +18693,9 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -18520,9 +18693,9 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
18520 },18693 },
18521 })).toIntern();18694 })).toIntern();
18522 const manyptr_ty = Type.fromInterned(slice_ty).slicePtrFieldType(mod).toIntern();18695 const manyptr_ty = Type.fromInterned(slice_ty).slicePtrFieldType(mod).toIntern();
18523 break :v try mod.intern(.{ .slice = .{18696 break :v try pt.intern(.{ .slice = .{
18524 .ty = slice_ty,18697 .ty = slice_ty,
18525 .ptr = try mod.intern(.{ .ptr = .{18698 .ptr = try pt.intern(.{ .ptr = .{
18526 .ty = manyptr_ty,18699 .ty = manyptr_ty,
18527 .base_addr = .{ .anon_decl = .{18700 .base_addr = .{ .anon_decl = .{
18528 .orig_ty = manyptr_ty,18701 .orig_ty = manyptr_ty,
...@@ -18530,14 +18703,14 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -18530,14 +18703,14 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
18530 } },18703 } },
18531 .byte_offset = 0,18704 .byte_offset = 0,
18532 } }),18705 } }),
18533 .len = (try mod.intValue(Type.usize, struct_field_vals.len)).toIntern(),18706 .len = (try pt.intValue(Type.usize, struct_field_vals.len)).toIntern(),
18534 } });18707 } });
18535 };18708 };
1853618709
18537 const decls_val = try sema.typeInfoDecls(block, src, type_info_ty, ty.getNamespaceIndex(mod));18710 const decls_val = try sema.typeInfoDecls(block, src, type_info_ty, ty.getNamespaceIndex(mod));
1853818711
18539 const backing_integer_val = try mod.intern(.{ .opt = .{18712 const backing_integer_val = try pt.intern(.{ .opt = .{
18540 .ty = (try mod.optionalType(.type_type)).toIntern(),18713 .ty = (try pt.optionalType(.type_type)).toIntern(),
18541 .val = if (mod.typeToPackedStruct(ty)) |packed_struct| val: {18714 .val = if (mod.typeToPackedStruct(ty)) |packed_struct| val: {
18542 assert(Type.fromInterned(packed_struct.backingIntType(ip).*).isInt(mod));18715 assert(Type.fromInterned(packed_struct.backingIntType(ip).*).isInt(mod));
18543 break :val packed_struct.backingIntType(ip).*;18716 break :val packed_struct.backingIntType(ip).*;
...@@ -18548,8 +18721,8 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -18548,8 +18721,8 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
18548 const decl_index = (try sema.namespaceLookup(18721 const decl_index = (try sema.namespaceLookup(
18549 block,18722 block,
18550 src,18723 src,
18551 (try mod.getBuiltinType("Type")).getNamespaceIndex(mod),18724 (try pt.getBuiltinType("Type")).getNamespaceIndex(mod),
18552 try ip.getOrPutString(gpa, "ContainerLayout", .no_embedded_nulls),18725 try ip.getOrPutString(gpa, pt.tid, "ContainerLayout", .no_embedded_nulls),
18553 )).?;18726 )).?;
18554 try sema.ensureDeclAnalyzed(decl_index);18727 try sema.ensureDeclAnalyzed(decl_index);
18555 const decl = mod.declPtr(decl_index);18728 const decl = mod.declPtr(decl_index);
...@@ -18560,7 +18733,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -18560,7 +18733,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1856018733
18561 const field_values = [_]InternPool.Index{18734 const field_values = [_]InternPool.Index{
18562 // layout: ContainerLayout,18735 // layout: ContainerLayout,
18563 (try mod.enumValueFieldIndex(container_layout_ty, @intFromEnum(layout))).toIntern(),18736 (try pt.enumValueFieldIndex(container_layout_ty, @intFromEnum(layout))).toIntern(),
18564 // backing_integer: ?type,18737 // backing_integer: ?type,
18565 backing_integer_val,18738 backing_integer_val,
18566 // fields: []const StructField,18739 // fields: []const StructField,
...@@ -18570,10 +18743,10 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -18570,10 +18743,10 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
18570 // is_tuple: bool,18743 // is_tuple: bool,
18571 Value.makeBool(ty.isTuple(mod)).toIntern(),18744 Value.makeBool(ty.isTuple(mod)).toIntern(),
18572 };18745 };
18573 return Air.internedToRef((try mod.intern(.{ .un = .{18746 return Air.internedToRef((try pt.intern(.{ .un = .{
18574 .ty = type_info_ty.toIntern(),18747 .ty = type_info_ty.toIntern(),
18575 .tag = (try mod.enumValueFieldIndex(type_info_tag_ty, @intFromEnum(std.builtin.TypeId.Struct))).toIntern(),18748 .tag = (try pt.enumValueFieldIndex(type_info_tag_ty, @intFromEnum(std.builtin.TypeId.Struct))).toIntern(),
18576 .val = try mod.intern(.{ .aggregate = .{18749 .val = try pt.intern(.{ .aggregate = .{
18577 .ty = type_struct_ty.toIntern(),18750 .ty = type_struct_ty.toIntern(),
18578 .storage = .{ .elems = &field_values },18751 .storage = .{ .elems = &field_values },
18579 } }),18752 } }),
...@@ -18585,24 +18758,24 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -18585,24 +18758,24 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
18585 block,18758 block,
18586 src,18759 src,
18587 type_info_ty.getNamespaceIndex(mod),18760 type_info_ty.getNamespaceIndex(mod),
18588 try ip.getOrPutString(gpa, "Opaque", .no_embedded_nulls),18761 try ip.getOrPutString(gpa, pt.tid, "Opaque", .no_embedded_nulls),
18589 )).?;18762 )).?;
18590 try sema.ensureDeclAnalyzed(type_opaque_ty_decl_index);18763 try sema.ensureDeclAnalyzed(type_opaque_ty_decl_index);
18591 const type_opaque_ty_decl = mod.declPtr(type_opaque_ty_decl_index);18764 const type_opaque_ty_decl = mod.declPtr(type_opaque_ty_decl_index);
18592 break :t type_opaque_ty_decl.val.toType();18765 break :t type_opaque_ty_decl.val.toType();
18593 };18766 };
1859418767
18595 try ty.resolveFields(mod);18768 try ty.resolveFields(pt);
18596 const decls_val = try sema.typeInfoDecls(block, src, type_info_ty, ty.getNamespaceIndex(mod));18769 const decls_val = try sema.typeInfoDecls(block, src, type_info_ty, ty.getNamespaceIndex(mod));
1859718770
18598 const field_values = .{18771 const field_values = .{
18599 // decls: []const Declaration,18772 // decls: []const Declaration,
18600 decls_val,18773 decls_val,
18601 };18774 };
18602 return Air.internedToRef((try mod.intern(.{ .un = .{18775 return Air.internedToRef((try pt.intern(.{ .un = .{
18603 .ty = type_info_ty.toIntern(),18776 .ty = type_info_ty.toIntern(),
18604 .tag = (try mod.enumValueFieldIndex(type_info_tag_ty, @intFromEnum(std.builtin.TypeId.Opaque))).toIntern(),18777 .tag = (try pt.enumValueFieldIndex(type_info_tag_ty, @intFromEnum(std.builtin.TypeId.Opaque))).toIntern(),
18605 .val = try mod.intern(.{ .aggregate = .{18778 .val = try pt.intern(.{ .aggregate = .{
18606 .ty = type_opaque_ty.toIntern(),18779 .ty = type_opaque_ty.toIntern(),
18607 .storage = .{ .elems = &field_values },18780 .storage = .{ .elems = &field_values },
18608 } }),18781 } }),
...@@ -18620,7 +18793,8 @@ fn typeInfoDecls(...@@ -18620,7 +18793,8 @@ fn typeInfoDecls(
18620 type_info_ty: Type,18793 type_info_ty: Type,
18621 opt_namespace: InternPool.OptionalNamespaceIndex,18794 opt_namespace: InternPool.OptionalNamespaceIndex,
18622) CompileError!InternPool.Index {18795) CompileError!InternPool.Index {
18623 const mod = sema.mod;18796 const pt = sema.pt;
18797 const mod = pt.zcu;
18624 const gpa = sema.gpa;18798 const gpa = sema.gpa;
1862518799
18626 const declaration_ty = t: {18800 const declaration_ty = t: {
...@@ -18628,7 +18802,7 @@ fn typeInfoDecls(...@@ -18628,7 +18802,7 @@ fn typeInfoDecls(
18628 block,18802 block,
18629 src,18803 src,
18630 type_info_ty.getNamespaceIndex(mod),18804 type_info_ty.getNamespaceIndex(mod),
18631 try mod.intern_pool.getOrPutString(gpa, "Declaration", .no_embedded_nulls),18805 try mod.intern_pool.getOrPutString(gpa, pt.tid, "Declaration", .no_embedded_nulls),
18632 )).?;18806 )).?;
18633 try sema.ensureDeclAnalyzed(declaration_ty_decl_index);18807 try sema.ensureDeclAnalyzed(declaration_ty_decl_index);
18634 const declaration_ty_decl = mod.declPtr(declaration_ty_decl_index);18808 const declaration_ty_decl = mod.declPtr(declaration_ty_decl_index);
...@@ -18643,15 +18817,15 @@ fn typeInfoDecls(...@@ -18643,15 +18817,15 @@ fn typeInfoDecls(
1864318817
18644 try sema.typeInfoNamespaceDecls(block, opt_namespace, declaration_ty, &decl_vals, &seen_namespaces);18818 try sema.typeInfoNamespaceDecls(block, opt_namespace, declaration_ty, &decl_vals, &seen_namespaces);
1864518819
18646 const array_decl_ty = try mod.arrayType(.{18820 const array_decl_ty = try pt.arrayType(.{
18647 .len = decl_vals.items.len,18821 .len = decl_vals.items.len,
18648 .child = declaration_ty.toIntern(),18822 .child = declaration_ty.toIntern(),
18649 });18823 });
18650 const new_decl_val = try mod.intern(.{ .aggregate = .{18824 const new_decl_val = try pt.intern(.{ .aggregate = .{
18651 .ty = array_decl_ty.toIntern(),18825 .ty = array_decl_ty.toIntern(),
18652 .storage = .{ .elems = decl_vals.items },18826 .storage = .{ .elems = decl_vals.items },
18653 } });18827 } });
18654 const slice_ty = (try mod.ptrTypeSema(.{18828 const slice_ty = (try pt.ptrTypeSema(.{
18655 .child = declaration_ty.toIntern(),18829 .child = declaration_ty.toIntern(),
18656 .flags = .{18830 .flags = .{
18657 .size = .Slice,18831 .size = .Slice,
...@@ -18659,9 +18833,9 @@ fn typeInfoDecls(...@@ -18659,9 +18833,9 @@ fn typeInfoDecls(
18659 },18833 },
18660 })).toIntern();18834 })).toIntern();
18661 const manyptr_ty = Type.fromInterned(slice_ty).slicePtrFieldType(mod).toIntern();18835 const manyptr_ty = Type.fromInterned(slice_ty).slicePtrFieldType(mod).toIntern();
18662 return try mod.intern(.{ .slice = .{18836 return try pt.intern(.{ .slice = .{
18663 .ty = slice_ty,18837 .ty = slice_ty,
18664 .ptr = try mod.intern(.{ .ptr = .{18838 .ptr = try pt.intern(.{ .ptr = .{
18665 .ty = manyptr_ty,18839 .ty = manyptr_ty,
18666 .base_addr = .{ .anon_decl = .{18840 .base_addr = .{ .anon_decl = .{
18667 .orig_ty = manyptr_ty,18841 .orig_ty = manyptr_ty,
...@@ -18669,7 +18843,7 @@ fn typeInfoDecls(...@@ -18669,7 +18843,7 @@ fn typeInfoDecls(
18669 } },18843 } },
18670 .byte_offset = 0,18844 .byte_offset = 0,
18671 } }),18845 } }),
18672 .len = (try mod.intValue(Type.usize, decl_vals.items.len)).toIntern(),18846 .len = (try pt.intValue(Type.usize, decl_vals.items.len)).toIntern(),
18673 } });18847 } });
18674}18848}
1867518849
...@@ -18681,7 +18855,8 @@ fn typeInfoNamespaceDecls(...@@ -18681,7 +18855,8 @@ fn typeInfoNamespaceDecls(
18681 decl_vals: *std.ArrayList(InternPool.Index),18855 decl_vals: *std.ArrayList(InternPool.Index),
18682 seen_namespaces: *std.AutoHashMap(*Namespace, void),18856 seen_namespaces: *std.AutoHashMap(*Namespace, void),
18683) !void {18857) !void {
18684 const mod = sema.mod;18858 const pt = sema.pt;
18859 const mod = pt.zcu;
18685 const ip = &mod.intern_pool;18860 const ip = &mod.intern_pool;
1868618861
18687 const namespace_index = opt_namespace_index.unwrap() orelse return;18862 const namespace_index = opt_namespace_index.unwrap() orelse return;
...@@ -18703,18 +18878,18 @@ fn typeInfoNamespaceDecls(...@@ -18703,18 +18878,18 @@ fn typeInfoNamespaceDecls(
18703 if (decl.kind != .named) continue;18878 if (decl.kind != .named) continue;
18704 const name_val = v: {18879 const name_val = v: {
18705 const decl_name_len = decl.name.length(ip);18880 const decl_name_len = decl.name.length(ip);
18706 const new_decl_ty = try mod.arrayType(.{18881 const new_decl_ty = try pt.arrayType(.{
18707 .len = decl_name_len,18882 .len = decl_name_len,
18708 .sentinel = .zero_u8,18883 .sentinel = .zero_u8,
18709 .child = .u8_type,18884 .child = .u8_type,
18710 });18885 });
18711 const new_decl_val = try mod.intern(.{ .aggregate = .{18886 const new_decl_val = try pt.intern(.{ .aggregate = .{
18712 .ty = new_decl_ty.toIntern(),18887 .ty = new_decl_ty.toIntern(),
18713 .storage = .{ .bytes = decl.name.toString() },18888 .storage = .{ .bytes = decl.name.toString() },
18714 } });18889 } });
18715 break :v try mod.intern(.{ .slice = .{18890 break :v try pt.intern(.{ .slice = .{
18716 .ty = .slice_const_u8_sentinel_0_type,18891 .ty = .slice_const_u8_sentinel_0_type,
18717 .ptr = try mod.intern(.{ .ptr = .{18892 .ptr = try pt.intern(.{ .ptr = .{
18718 .ty = .manyptr_const_u8_sentinel_0_type,18893 .ty = .manyptr_const_u8_sentinel_0_type,
18719 .base_addr = .{ .anon_decl = .{18894 .base_addr = .{ .anon_decl = .{
18720 .orig_ty = .slice_const_u8_sentinel_0_type,18895 .orig_ty = .slice_const_u8_sentinel_0_type,
...@@ -18722,7 +18897,7 @@ fn typeInfoNamespaceDecls(...@@ -18722,7 +18897,7 @@ fn typeInfoNamespaceDecls(
18722 } },18897 } },
18723 .byte_offset = 0,18898 .byte_offset = 0,
18724 } }),18899 } }),
18725 .len = (try mod.intValue(Type.usize, decl_name_len)).toIntern(),18900 .len = (try pt.intValue(Type.usize, decl_name_len)).toIntern(),
18726 } });18901 } });
18727 };18902 };
1872818903
...@@ -18730,7 +18905,7 @@ fn typeInfoNamespaceDecls(...@@ -18730,7 +18905,7 @@ fn typeInfoNamespaceDecls(
18730 //name: [:0]const u8,18905 //name: [:0]const u8,
18731 name_val,18906 name_val,
18732 };18907 };
18733 try decl_vals.append(try mod.intern(.{ .aggregate = .{18908 try decl_vals.append(try pt.intern(.{ .aggregate = .{
18734 .ty = declaration_ty.toIntern(),18909 .ty = declaration_ty.toIntern(),
18735 .storage = .{ .elems = &fields },18910 .storage = .{ .elems = &fields },
18736 } }));18911 } }));
...@@ -18782,11 +18957,12 @@ fn zirTypeofLog2IntType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Compil...@@ -18782,11 +18957,12 @@ fn zirTypeofLog2IntType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Compil
18782}18957}
1878318958
18784fn log2IntType(sema: *Sema, block: *Block, operand: Type, src: LazySrcLoc) CompileError!Type {18959fn log2IntType(sema: *Sema, block: *Block, operand: Type, src: LazySrcLoc) CompileError!Type {
18785 const mod = sema.mod;18960 const pt = sema.pt;
18961 const mod = pt.zcu;
18786 switch (operand.zigTypeTag(mod)) {18962 switch (operand.zigTypeTag(mod)) {
18787 .ComptimeInt => return Type.comptime_int,18963 .ComptimeInt => return Type.comptime_int,
18788 .Int => {18964 .Int => {
18789 const bits = operand.bitSize(mod);18965 const bits = operand.bitSize(pt);
18790 const count = if (bits == 0)18966 const count = if (bits == 0)
18791 018967 0
18792 else blk: {18968 else blk: {
...@@ -18797,12 +18973,12 @@ fn log2IntType(sema: *Sema, block: *Block, operand: Type, src: LazySrcLoc) Compi...@@ -18797,12 +18973,12 @@ fn log2IntType(sema: *Sema, block: *Block, operand: Type, src: LazySrcLoc) Compi
18797 }18973 }
18798 break :blk count;18974 break :blk count;
18799 };18975 };
18800 return mod.intType(.unsigned, count);18976 return pt.intType(.unsigned, count);
18801 },18977 },
18802 .Vector => {18978 .Vector => {
18803 const elem_ty = operand.elemType2(mod);18979 const elem_ty = operand.elemType2(mod);
18804 const log2_elem_ty = try sema.log2IntType(block, elem_ty, src);18980 const log2_elem_ty = try sema.log2IntType(block, elem_ty, src);
18805 return mod.vectorType(.{18981 return pt.vectorType(.{
18806 .len = operand.vectorLen(mod),18982 .len = operand.vectorLen(mod),
18807 .child = log2_elem_ty.toIntern(),18983 .child = log2_elem_ty.toIntern(),
18808 });18984 });
...@@ -18813,7 +18989,7 @@ fn log2IntType(sema: *Sema, block: *Block, operand: Type, src: LazySrcLoc) Compi...@@ -18813,7 +18989,7 @@ fn log2IntType(sema: *Sema, block: *Block, operand: Type, src: LazySrcLoc) Compi
18813 block,18989 block,
18814 src,18990 src,
18815 "bit shifting operation expected integer type, found '{}'",18991 "bit shifting operation expected integer type, found '{}'",
18816 .{operand.fmt(mod)},18992 .{operand.fmt(pt)},
18817 );18993 );
18818}18994}
1881918995
...@@ -18865,7 +19041,8 @@ fn zirBoolNot(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air...@@ -18865,7 +19041,8 @@ fn zirBoolNot(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
18865 const tracy = trace(@src());19041 const tracy = trace(@src());
18866 defer tracy.end();19042 defer tracy.end();
1886719043
18868 const mod = sema.mod;19044 const pt = sema.pt;
19045 const mod = pt.zcu;
18869 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;19046 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;
18870 const src = block.nodeOffset(inst_data.src_node);19047 const src = block.nodeOffset(inst_data.src_node);
18871 const operand_src = block.src(.{ .node_offset_un_op = inst_data.src_node });19048 const operand_src = block.src(.{ .node_offset_un_op = inst_data.src_node });
...@@ -18874,7 +19051,7 @@ fn zirBoolNot(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air...@@ -18874,7 +19051,7 @@ fn zirBoolNot(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
18874 const operand = try sema.coerce(block, Type.bool, uncasted_operand, operand_src);19051 const operand = try sema.coerce(block, Type.bool, uncasted_operand, operand_src);
18875 if (try sema.resolveValue(operand)) |val| {19052 if (try sema.resolveValue(operand)) |val| {
18876 return if (val.isUndef(mod))19053 return if (val.isUndef(mod))
18877 mod.undefRef(Type.bool)19054 pt.undefRef(Type.bool)
18878 else if (val.toBool()) .bool_false else .bool_true;19055 else if (val.toBool()) .bool_false else .bool_true;
18879 }19056 }
18880 try sema.requireRuntimeBlock(block, src, null);19057 try sema.requireRuntimeBlock(block, src, null);
...@@ -18890,7 +19067,8 @@ fn zirBoolBr(...@@ -18890,7 +19067,8 @@ fn zirBoolBr(
18890 const tracy = trace(@src());19067 const tracy = trace(@src());
18891 defer tracy.end();19068 defer tracy.end();
1889219069
18893 const mod = sema.mod;19070 const pt = sema.pt;
19071 const mod = pt.zcu;
18894 const gpa = sema.gpa;19072 const gpa = sema.gpa;
1889519073
18896 const datas = sema.code.instructions.items(.data);19074 const datas = sema.code.instructions.items(.data);
...@@ -19006,7 +19184,8 @@ fn finishCondBr(...@@ -19006,7 +19184,8 @@ fn finishCondBr(
19006}19184}
1900719185
19008fn checkNullableType(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type) !void {19186fn checkNullableType(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type) !void {
19009 const mod = sema.mod;19187 const pt = sema.pt;
19188 const mod = pt.zcu;
19010 switch (ty.zigTypeTag(mod)) {19189 switch (ty.zigTypeTag(mod)) {
19011 .Optional, .Null, .Undefined => return,19190 .Optional, .Null, .Undefined => return,
19012 .Pointer => if (ty.isPtrLikeOptional(mod)) return,19191 .Pointer => if (ty.isPtrLikeOptional(mod)) return,
...@@ -19038,7 +19217,8 @@ fn zirIsNonNullPtr(...@@ -19038,7 +19217,8 @@ fn zirIsNonNullPtr(
19038 const tracy = trace(@src());19217 const tracy = trace(@src());
19039 defer tracy.end();19218 defer tracy.end();
1904019219
19041 const mod = sema.mod;19220 const pt = sema.pt;
19221 const mod = pt.zcu;
19042 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;19222 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;
19043 const src = block.nodeOffset(inst_data.src_node);19223 const src = block.nodeOffset(inst_data.src_node);
19044 const ptr = try sema.resolveInst(inst_data.operand);19224 const ptr = try sema.resolveInst(inst_data.operand);
...@@ -19051,11 +19231,12 @@ fn zirIsNonNullPtr(...@@ -19051,11 +19231,12 @@ fn zirIsNonNullPtr(
19051}19231}
1905219232
19053fn checkErrorType(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type) !void {19233fn checkErrorType(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type) !void {
19054 const mod = sema.mod;19234 const pt = sema.pt;
19235 const mod = pt.zcu;
19055 switch (ty.zigTypeTag(mod)) {19236 switch (ty.zigTypeTag(mod)) {
19056 .ErrorSet, .ErrorUnion, .Undefined => return,19237 .ErrorSet, .ErrorUnion, .Undefined => return,
19057 else => return sema.fail(block, src, "expected error union type, found '{}'", .{19238 else => return sema.fail(block, src, "expected error union type, found '{}'", .{
19058 ty.fmt(mod),19239 ty.fmt(pt),
19059 }),19240 }),
19060 }19241 }
19061}19242}
...@@ -19075,7 +19256,8 @@ fn zirIsNonErrPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError...@@ -19075,7 +19256,8 @@ fn zirIsNonErrPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
19075 const tracy = trace(@src());19256 const tracy = trace(@src());
19076 defer tracy.end();19257 defer tracy.end();
1907719258
19078 const mod = sema.mod;19259 const pt = sema.pt;
19260 const mod = pt.zcu;
19079 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;19261 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;
19080 const src = block.nodeOffset(inst_data.src_node);19262 const src = block.nodeOffset(inst_data.src_node);
19081 const ptr = try sema.resolveInst(inst_data.operand);19263 const ptr = try sema.resolveInst(inst_data.operand);
...@@ -19102,7 +19284,8 @@ fn zirCondbr(...@@ -19102,7 +19284,8 @@ fn zirCondbr(
19102 const tracy = trace(@src());19284 const tracy = trace(@src());
19103 defer tracy.end();19285 defer tracy.end();
1910419286
19105 const mod = sema.mod;19287 const pt = sema.pt;
19288 const mod = pt.zcu;
19106 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;19289 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
19107 const cond_src = parent_block.src(.{ .node_offset_if_cond = inst_data.src_node });19290 const cond_src = parent_block.src(.{ .node_offset_if_cond = inst_data.src_node });
19108 const extra = sema.code.extraData(Zir.Inst.CondBr, inst_data.payload_index);19291 const extra = sema.code.extraData(Zir.Inst.CondBr, inst_data.payload_index);
...@@ -19177,10 +19360,11 @@ fn zirTry(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileError!...@@ -19177,10 +19360,11 @@ fn zirTry(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileError!
19177 const body = sema.code.bodySlice(extra.end, extra.data.body_len);19360 const body = sema.code.bodySlice(extra.end, extra.data.body_len);
19178 const err_union = try sema.resolveInst(extra.data.operand);19361 const err_union = try sema.resolveInst(extra.data.operand);
19179 const err_union_ty = sema.typeOf(err_union);19362 const err_union_ty = sema.typeOf(err_union);
19180 const mod = sema.mod;19363 const pt = sema.pt;
19364 const mod = pt.zcu;
19181 if (err_union_ty.zigTypeTag(mod) != .ErrorUnion) {19365 if (err_union_ty.zigTypeTag(mod) != .ErrorUnion) {
19182 return sema.fail(parent_block, operand_src, "expected error union type, found '{}'", .{19366 return sema.fail(parent_block, operand_src, "expected error union type, found '{}'", .{
19183 err_union_ty.fmt(mod),19367 err_union_ty.fmt(pt),
19184 });19368 });
19185 }19369 }
19186 const is_non_err = try sema.analyzeIsNonErrComptimeOnly(parent_block, operand_src, err_union);19370 const is_non_err = try sema.analyzeIsNonErrComptimeOnly(parent_block, operand_src, err_union);
...@@ -19225,10 +19409,11 @@ fn zirTryPtr(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileErr...@@ -19225,10 +19409,11 @@ fn zirTryPtr(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileErr
19225 const operand = try sema.resolveInst(extra.data.operand);19409 const operand = try sema.resolveInst(extra.data.operand);
19226 const err_union = try sema.analyzeLoad(parent_block, src, operand, operand_src);19410 const err_union = try sema.analyzeLoad(parent_block, src, operand, operand_src);
19227 const err_union_ty = sema.typeOf(err_union);19411 const err_union_ty = sema.typeOf(err_union);
19228 const mod = sema.mod;19412 const pt = sema.pt;
19413 const mod = pt.zcu;
19229 if (err_union_ty.zigTypeTag(mod) != .ErrorUnion) {19414 if (err_union_ty.zigTypeTag(mod) != .ErrorUnion) {
19230 return sema.fail(parent_block, operand_src, "expected error union type, found '{}'", .{19415 return sema.fail(parent_block, operand_src, "expected error union type, found '{}'", .{
19231 err_union_ty.fmt(mod),19416 err_union_ty.fmt(pt),
19232 });19417 });
19233 }19418 }
19234 const is_non_err = try sema.analyzeIsNonErrComptimeOnly(parent_block, operand_src, err_union);19419 const is_non_err = try sema.analyzeIsNonErrComptimeOnly(parent_block, operand_src, err_union);
...@@ -19251,7 +19436,7 @@ fn zirTryPtr(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileErr...@@ -19251,7 +19436,7 @@ fn zirTryPtr(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileErr
1925119436
19252 const operand_ty = sema.typeOf(operand);19437 const operand_ty = sema.typeOf(operand);
19253 const ptr_info = operand_ty.ptrInfo(mod);19438 const ptr_info = operand_ty.ptrInfo(mod);
19254 const res_ty = try mod.ptrTypeSema(.{19439 const res_ty = try pt.ptrTypeSema(.{
19255 .child = err_union_ty.errorUnionPayload(mod).toIntern(),19440 .child = err_union_ty.errorUnionPayload(mod).toIntern(),
19256 .flags = .{19441 .flags = .{
19257 .is_const = ptr_info.flags.is_const,19442 .is_const = ptr_info.flags.is_const,
...@@ -19366,18 +19551,20 @@ fn zirRetErrValue(...@@ -19366,18 +19551,20 @@ fn zirRetErrValue(
19366 block: *Block,19551 block: *Block,
19367 inst: Zir.Inst.Index,19552 inst: Zir.Inst.Index,
19368) CompileError!void {19553) CompileError!void {
19369 const mod = sema.mod;19554 const pt = sema.pt;
19555 const mod = pt.zcu;
19370 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].str_tok;19556 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].str_tok;
19371 const src = block.tokenOffset(inst_data.src_tok);19557 const src = block.tokenOffset(inst_data.src_tok);
19372 const err_name = try mod.intern_pool.getOrPutString(19558 const err_name = try mod.intern_pool.getOrPutString(
19373 sema.gpa,19559 sema.gpa,
19560 pt.tid,
19374 inst_data.get(sema.code),19561 inst_data.get(sema.code),
19375 .no_embedded_nulls,19562 .no_embedded_nulls,
19376 );19563 );
19377 _ = try mod.getErrorValue(err_name);19564 _ = try mod.getErrorValue(err_name);
19378 // Return the error code from the function.19565 // Return the error code from the function.
19379 const error_set_type = try mod.singleErrorSetType(err_name);19566 const error_set_type = try pt.singleErrorSetType(err_name);
19380 const result_inst = Air.internedToRef((try mod.intern(.{ .err = .{19567 const result_inst = Air.internedToRef((try pt.intern(.{ .err = .{
19381 .ty = error_set_type.toIntern(),19568 .ty = error_set_type.toIntern(),
19382 .name = err_name,19569 .name = err_name,
19383 } })));19570 } })));
...@@ -19392,7 +19579,8 @@ fn zirRetImplicit(...@@ -19392,7 +19579,8 @@ fn zirRetImplicit(
19392 const tracy = trace(@src());19579 const tracy = trace(@src());
19393 defer tracy.end();19580 defer tracy.end();
1939419581
19395 const mod = sema.mod;19582 const pt = sema.pt;
19583 const mod = pt.zcu;
19396 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_tok;19584 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_tok;
19397 const r_brace_src = block.tokenOffset(inst_data.src_tok);19585 const r_brace_src = block.tokenOffset(inst_data.src_tok);
19398 if (block.inlining == null and sema.func_is_naked) {19586 if (block.inlining == null and sema.func_is_naked) {
...@@ -19412,7 +19600,7 @@ fn zirRetImplicit(...@@ -19412,7 +19600,7 @@ fn zirRetImplicit(
19412 if (base_tag == .NoReturn) {19600 if (base_tag == .NoReturn) {
19413 const msg = msg: {19601 const msg = msg: {
19414 const msg = try sema.errMsg(ret_ty_src, "function declared '{}' implicitly returns", .{19602 const msg = try sema.errMsg(ret_ty_src, "function declared '{}' implicitly returns", .{
19415 sema.fn_ret_ty.fmt(mod),19603 sema.fn_ret_ty.fmt(pt),
19416 });19604 });
19417 errdefer msg.destroy(sema.gpa);19605 errdefer msg.destroy(sema.gpa);
19418 try sema.errNote(r_brace_src, msg, "control flow reaches end of body here", .{});19606 try sema.errNote(r_brace_src, msg, "control flow reaches end of body here", .{});
...@@ -19422,7 +19610,7 @@ fn zirRetImplicit(...@@ -19422,7 +19610,7 @@ fn zirRetImplicit(
19422 } else if (base_tag != .Void) {19610 } else if (base_tag != .Void) {
19423 const msg = msg: {19611 const msg = msg: {
19424 const msg = try sema.errMsg(ret_ty_src, "function with non-void return type '{}' implicitly returns", .{19612 const msg = try sema.errMsg(ret_ty_src, "function with non-void return type '{}' implicitly returns", .{
19425 sema.fn_ret_ty.fmt(mod),19613 sema.fn_ret_ty.fmt(pt),
19426 });19614 });
19427 errdefer msg.destroy(sema.gpa);19615 errdefer msg.destroy(sema.gpa);
19428 try sema.errNote(r_brace_src, msg, "control flow reaches end of body here", .{});19616 try sema.errNote(r_brace_src, msg, "control flow reaches end of body here", .{});
...@@ -19474,7 +19662,7 @@ fn retWithErrTracing(...@@ -19474,7 +19662,7 @@ fn retWithErrTracing(
19474 ret_tag: Air.Inst.Tag,19662 ret_tag: Air.Inst.Tag,
19475 operand: Air.Inst.Ref,19663 operand: Air.Inst.Ref,
19476) CompileError!void {19664) CompileError!void {
19477 const mod = sema.mod;19665 const pt = sema.pt;
19478 const need_check = switch (is_non_err) {19666 const need_check = switch (is_non_err) {
19479 .bool_true => {19667 .bool_true => {
19480 _ = try block.addUnOp(ret_tag, operand);19668 _ = try block.addUnOp(ret_tag, operand);
...@@ -19484,11 +19672,11 @@ fn retWithErrTracing(...@@ -19484,11 +19672,11 @@ fn retWithErrTracing(
19484 else => true,19672 else => true,
19485 };19673 };
19486 const gpa = sema.gpa;19674 const gpa = sema.gpa;
19487 const stack_trace_ty = try mod.getBuiltinType("StackTrace");19675 const stack_trace_ty = try pt.getBuiltinType("StackTrace");
19488 try stack_trace_ty.resolveFields(mod);19676 try stack_trace_ty.resolveFields(pt);
19489 const ptr_stack_trace_ty = try mod.singleMutPtrType(stack_trace_ty);19677 const ptr_stack_trace_ty = try pt.singleMutPtrType(stack_trace_ty);
19490 const err_return_trace = try block.addTy(.err_return_trace, ptr_stack_trace_ty);19678 const err_return_trace = try block.addTy(.err_return_trace, ptr_stack_trace_ty);
19491 const return_err_fn = try mod.getBuiltin("returnError");19679 const return_err_fn = try pt.getBuiltin("returnError");
19492 const args: [1]Air.Inst.Ref = .{err_return_trace};19680 const args: [1]Air.Inst.Ref = .{err_return_trace};
1949319681
19494 if (!need_check) {19682 if (!need_check) {
...@@ -19524,12 +19712,14 @@ fn retWithErrTracing(...@@ -19524,12 +19712,14 @@ fn retWithErrTracing(
19524}19712}
1952519713
19526fn wantErrorReturnTracing(sema: *Sema, fn_ret_ty: Type) bool {19714fn wantErrorReturnTracing(sema: *Sema, fn_ret_ty: Type) bool {
19527 const mod = sema.mod;19715 const pt = sema.pt;
19716 const mod = pt.zcu;
19528 return fn_ret_ty.isError(mod) and mod.comp.config.any_error_tracing;19717 return fn_ret_ty.isError(mod) and mod.comp.config.any_error_tracing;
19529}19718}
1953019719
19531fn zirSaveErrRetIndex(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void {19720fn zirSaveErrRetIndex(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void {
19532 const mod = sema.mod;19721 const pt = sema.pt;
19722 const mod = pt.zcu;
19533 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].save_err_ret_index;19723 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].save_err_ret_index;
1953419724
19535 if (!block.ownerModule().error_tracing) return;19725 if (!block.ownerModule().error_tracing) return;
...@@ -19559,7 +19749,8 @@ fn restoreErrRetIndex(sema: *Sema, start_block: *Block, src: LazySrcLoc, target_...@@ -19559,7 +19749,8 @@ fn restoreErrRetIndex(sema: *Sema, start_block: *Block, src: LazySrcLoc, target_
19559 const tracy = trace(@src());19749 const tracy = trace(@src());
19560 defer tracy.end();19750 defer tracy.end();
1956119751
19562 const mod = sema.mod;19752 const pt = sema.pt;
19753 const mod = pt.zcu;
1956319754
19564 const saved_index = if (target_block.toIndexAllowNone()) |zir_block| b: {19755 const saved_index = if (target_block.toIndexAllowNone()) |zir_block| b: {
19565 var block = start_block;19756 var block = start_block;
...@@ -19597,7 +19788,7 @@ fn restoreErrRetIndex(sema: *Sema, start_block: *Block, src: LazySrcLoc, target_...@@ -19597,7 +19788,7 @@ fn restoreErrRetIndex(sema: *Sema, start_block: *Block, src: LazySrcLoc, target_
19597 if (is_non_error) return;19788 if (is_non_error) return;
1959819789
19599 const saved_index_val = try sema.resolveDefinedValue(start_block, src, saved_index);19790 const saved_index_val = try sema.resolveDefinedValue(start_block, src, saved_index);
19600 const saved_index_int = saved_index_val.?.toUnsignedInt(mod);19791 const saved_index_int = saved_index_val.?.toUnsignedInt(pt);
19601 assert(saved_index_int <= sema.comptime_err_ret_trace.items.len);19792 assert(saved_index_int <= sema.comptime_err_ret_trace.items.len);
19602 sema.comptime_err_ret_trace.items.len = @intCast(saved_index_int);19793 sema.comptime_err_ret_trace.items.len = @intCast(saved_index_int);
19603 return;19794 return;
...@@ -19612,7 +19803,8 @@ fn restoreErrRetIndex(sema: *Sema, start_block: *Block, src: LazySrcLoc, target_...@@ -19612,7 +19803,8 @@ fn restoreErrRetIndex(sema: *Sema, start_block: *Block, src: LazySrcLoc, target_
19612}19803}
1961319804
19614fn addToInferredErrorSet(sema: *Sema, uncasted_operand: Air.Inst.Ref) !void {19805fn addToInferredErrorSet(sema: *Sema, uncasted_operand: Air.Inst.Ref) !void {
19615 const mod = sema.mod;19806 const pt = sema.pt;
19807 const mod = pt.zcu;
19616 const ip = &mod.intern_pool;19808 const ip = &mod.intern_pool;
19617 assert(sema.fn_ret_ty.zigTypeTag(mod) == .ErrorUnion);19809 assert(sema.fn_ret_ty.zigTypeTag(mod) == .ErrorUnion);
19618 const err_set_ty = sema.fn_ret_ty.errorUnionSet(mod).toIntern();19810 const err_set_ty = sema.fn_ret_ty.errorUnionSet(mod).toIntern();
...@@ -19632,7 +19824,8 @@ fn addToInferredErrorSet(sema: *Sema, uncasted_operand: Air.Inst.Ref) !void {...@@ -19632,7 +19824,8 @@ fn addToInferredErrorSet(sema: *Sema, uncasted_operand: Air.Inst.Ref) !void {
1963219824
19633fn addToInferredErrorSetPtr(sema: *Sema, ies: *InferredErrorSet, op_ty: Type) !void {19825fn addToInferredErrorSetPtr(sema: *Sema, ies: *InferredErrorSet, op_ty: Type) !void {
19634 const arena = sema.arena;19826 const arena = sema.arena;
19635 const mod = sema.mod;19827 const pt = sema.pt;
19828 const mod = pt.zcu;
19636 const ip = &mod.intern_pool;19829 const ip = &mod.intern_pool;
19637 switch (op_ty.zigTypeTag(mod)) {19830 switch (op_ty.zigTypeTag(mod)) {
19638 .ErrorSet => try ies.addErrorSet(op_ty, ip, arena),19831 .ErrorSet => try ies.addErrorSet(op_ty, ip, arena),
...@@ -19651,7 +19844,8 @@ fn analyzeRet(...@@ -19651,7 +19844,8 @@ fn analyzeRet(
19651 // Special case for returning an error to an inferred error set; we need to19844 // Special case for returning an error to an inferred error set; we need to
19652 // add the error tag to the inferred error set of the in-scope function, so19845 // add the error tag to the inferred error set of the in-scope function, so
19653 // that the coercion below works correctly.19846 // that the coercion below works correctly.
19654 const mod = sema.mod;19847 const pt = sema.pt;
19848 const mod = pt.zcu;
19655 if (sema.fn_ret_ty_ies != null and sema.fn_ret_ty.zigTypeTag(mod) == .ErrorUnion) {19849 if (sema.fn_ret_ty_ies != null and sema.fn_ret_ty.zigTypeTag(mod) == .ErrorUnion) {
19656 try sema.addToInferredErrorSet(uncasted_operand);19850 try sema.addToInferredErrorSet(uncasted_operand);
19657 }19851 }
...@@ -19691,7 +19885,7 @@ fn analyzeRet(...@@ -19691,7 +19885,7 @@ fn analyzeRet(
19691 return sema.failWithOwnedErrorMsg(block, msg);19885 return sema.failWithOwnedErrorMsg(block, msg);
19692 }19886 }
1969319887
19694 try sema.fn_ret_ty.resolveLayout(mod);19888 try sema.fn_ret_ty.resolveLayout(pt);
1969519889
19696 try sema.validateRuntimeValue(block, operand_src, operand);19890 try sema.validateRuntimeValue(block, operand_src, operand);
1969719891
...@@ -19718,7 +19912,8 @@ fn zirPtrType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air...@@ -19718,7 +19912,8 @@ fn zirPtrType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
19718 const tracy = trace(@src());19912 const tracy = trace(@src());
19719 defer tracy.end();19913 defer tracy.end();
1972019914
19721 const mod = sema.mod;19915 const pt = sema.pt;
19916 const mod = pt.zcu;
19722 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].ptr_type;19917 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].ptr_type;
19723 const extra = sema.code.extraData(Zir.Inst.PtrType, inst_data.payload_index);19918 const extra = sema.code.extraData(Zir.Inst.PtrType, inst_data.payload_index);
19724 const elem_ty_src = block.src(.{ .node_offset_ptr_elem = extra.data.src_node });19919 const elem_ty_src = block.src(.{ .node_offset_ptr_elem = extra.data.src_node });
...@@ -19773,7 +19968,7 @@ fn zirPtrType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air...@@ -19773,7 +19968,7 @@ fn zirPtrType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
19773 },19968 },
19774 else => {},19969 else => {},
19775 }19970 }
19776 const align_bytes = (try val.getUnsignedIntAdvanced(mod, .sema)).?;19971 const align_bytes = (try val.getUnsignedIntAdvanced(pt, .sema)).?;
19777 break :blk try sema.validateAlignAllowZero(block, align_src, align_bytes);19972 break :blk try sema.validateAlignAllowZero(block, align_src, align_bytes);
19778 } else .none;19973 } else .none;
1977919974
...@@ -19804,13 +19999,13 @@ fn zirPtrType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air...@@ -19804,13 +19999,13 @@ fn zirPtrType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
19804 if (host_size != 0) {19999 if (host_size != 0) {
19805 if (bit_offset >= host_size * 8) {20000 if (bit_offset >= host_size * 8) {
19806 return sema.fail(block, bitoffset_src, "packed type '{}' at bit offset {} starts {} bits after the end of a {} byte host integer", .{20001 return sema.fail(block, bitoffset_src, "packed type '{}' at bit offset {} starts {} bits after the end of a {} byte host integer", .{
19807 elem_ty.fmt(mod), bit_offset, bit_offset - host_size * 8, host_size,20002 elem_ty.fmt(pt), bit_offset, bit_offset - host_size * 8, host_size,
19808 });20003 });
19809 }20004 }
19810 const elem_bit_size = try elem_ty.bitSizeAdvanced(mod, .sema);20005 const elem_bit_size = try elem_ty.bitSizeAdvanced(pt, .sema);
19811 if (elem_bit_size > host_size * 8 - bit_offset) {20006 if (elem_bit_size > host_size * 8 - bit_offset) {
19812 return sema.fail(block, bitoffset_src, "packed type '{}' at bit offset {} ends {} bits after the end of a {} byte host integer", .{20007 return sema.fail(block, bitoffset_src, "packed type '{}' at bit offset {} ends {} bits after the end of a {} byte host integer", .{
19813 elem_ty.fmt(mod), bit_offset, elem_bit_size - (host_size * 8 - bit_offset), host_size,20008 elem_ty.fmt(pt), bit_offset, elem_bit_size - (host_size * 8 - bit_offset), host_size,
19814 });20009 });
19815 }20010 }
19816 }20011 }
...@@ -19824,7 +20019,7 @@ fn zirPtrType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air...@@ -19824,7 +20019,7 @@ fn zirPtrType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
19824 } else if (inst_data.size == .C) {20019 } else if (inst_data.size == .C) {
19825 if (!try sema.validateExternType(elem_ty, .other)) {20020 if (!try sema.validateExternType(elem_ty, .other)) {
19826 const msg = msg: {20021 const msg = msg: {
19827 const msg = try sema.errMsg(elem_ty_src, "C pointers cannot point to non-C-ABI-compatible type '{}'", .{elem_ty.fmt(mod)});20022 const msg = try sema.errMsg(elem_ty_src, "C pointers cannot point to non-C-ABI-compatible type '{}'", .{elem_ty.fmt(pt)});
19828 errdefer msg.destroy(sema.gpa);20023 errdefer msg.destroy(sema.gpa);
1982920024
19830 try sema.explainWhyTypeIsNotExtern(msg, elem_ty_src, elem_ty, .other);20025 try sema.explainWhyTypeIsNotExtern(msg, elem_ty_src, elem_ty, .other);
...@@ -19841,14 +20036,14 @@ fn zirPtrType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air...@@ -19841,14 +20036,14 @@ fn zirPtrType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
1984120036
19842 if (host_size != 0 and !try sema.validatePackedType(elem_ty)) {20037 if (host_size != 0 and !try sema.validatePackedType(elem_ty)) {
19843 return sema.failWithOwnedErrorMsg(block, msg: {20038 return sema.failWithOwnedErrorMsg(block, msg: {
19844 const msg = try sema.errMsg(elem_ty_src, "bit-pointer cannot refer to value of type '{}'", .{elem_ty.fmt(mod)});20039 const msg = try sema.errMsg(elem_ty_src, "bit-pointer cannot refer to value of type '{}'", .{elem_ty.fmt(pt)});
19845 errdefer msg.destroy(sema.gpa);20040 errdefer msg.destroy(sema.gpa);
19846 try sema.explainWhyTypeIsNotPacked(msg, elem_ty_src, elem_ty);20041 try sema.explainWhyTypeIsNotPacked(msg, elem_ty_src, elem_ty);
19847 break :msg msg;20042 break :msg msg;
19848 });20043 });
19849 }20044 }
1985020045
19851 const ty = try mod.ptrTypeSema(.{20046 const ty = try pt.ptrTypeSema(.{
19852 .child = elem_ty.toIntern(),20047 .child = elem_ty.toIntern(),
19853 .sentinel = sentinel,20048 .sentinel = sentinel,
19854 .flags = .{20049 .flags = .{
...@@ -19875,7 +20070,8 @@ fn zirStructInitEmpty(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileE...@@ -19875,7 +20070,8 @@ fn zirStructInitEmpty(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileE
19875 const src = block.nodeOffset(inst_data.src_node);20070 const src = block.nodeOffset(inst_data.src_node);
19876 const ty_src = block.src(.{ .node_offset_init_ty = inst_data.src_node });20071 const ty_src = block.src(.{ .node_offset_init_ty = inst_data.src_node });
19877 const obj_ty = try sema.resolveType(block, ty_src, inst_data.operand);20072 const obj_ty = try sema.resolveType(block, ty_src, inst_data.operand);
19878 const mod = sema.mod;20073 const pt = sema.pt;
20074 const mod = pt.zcu;
1987920075
19880 switch (obj_ty.zigTypeTag(mod)) {20076 switch (obj_ty.zigTypeTag(mod)) {
19881 .Struct => return sema.structInitEmpty(block, obj_ty, src, src),20077 .Struct => return sema.structInitEmpty(block, obj_ty, src, src),
...@@ -19890,7 +20086,8 @@ fn zirStructInitEmptyResult(sema: *Sema, block: *Block, inst: Zir.Inst.Index, is...@@ -19890,7 +20086,8 @@ fn zirStructInitEmptyResult(sema: *Sema, block: *Block, inst: Zir.Inst.Index, is
19890 const tracy = trace(@src());20086 const tracy = trace(@src());
19891 defer tracy.end();20087 defer tracy.end();
1989220088
19893 const mod = sema.mod;20089 const pt = sema.pt;
20090 const mod = pt.zcu;
19894 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;20091 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;
19895 const src = block.nodeOffset(inst_data.src_node);20092 const src = block.nodeOffset(inst_data.src_node);
19896 const ty_operand = sema.resolveType(block, src, inst_data.operand) catch |err| switch (err) {20093 const ty_operand = sema.resolveType(block, src, inst_data.operand) catch |err| switch (err) {
...@@ -19905,7 +20102,7 @@ fn zirStructInitEmptyResult(sema: *Sema, block: *Block, inst: Zir.Inst.Index, is...@@ -19905,7 +20102,7 @@ fn zirStructInitEmptyResult(sema: *Sema, block: *Block, inst: Zir.Inst.Index, is
19905 break :ty ptr_ty.childType(mod);20102 break :ty ptr_ty.childType(mod);
19906 }20103 }
19907 // To make `&.{}` a `[:s]T`, the init should be a `[0:s]T`.20104 // To make `&.{}` a `[:s]T`, the init should be a `[0:s]T`.
19908 break :ty try mod.arrayType(.{20105 break :ty try pt.arrayType(.{
19909 .len = 0,20106 .len = 0,
19910 .sentinel = if (ptr_ty.sentinel(mod)) |s| s.toIntern() else .none,20107 .sentinel = if (ptr_ty.sentinel(mod)) |s| s.toIntern() else .none,
19911 .child = ptr_ty.childType(mod).toIntern(),20108 .child = ptr_ty.childType(mod).toIntern(),
...@@ -19936,10 +20133,11 @@ fn structInitEmpty(...@@ -19936,10 +20133,11 @@ fn structInitEmpty(
19936 dest_src: LazySrcLoc,20133 dest_src: LazySrcLoc,
19937 init_src: LazySrcLoc,20134 init_src: LazySrcLoc,
19938) CompileError!Air.Inst.Ref {20135) CompileError!Air.Inst.Ref {
19939 const mod = sema.mod;20136 const pt = sema.pt;
20137 const mod = pt.zcu;
19940 const gpa = sema.gpa;20138 const gpa = sema.gpa;
19941 // This logic must be synchronized with that in `zirStructInit`.20139 // This logic must be synchronized with that in `zirStructInit`.
19942 try struct_ty.resolveFields(mod);20140 try struct_ty.resolveFields(pt);
1994320141
19944 // The init values to use for the struct instance.20142 // The init values to use for the struct instance.
19945 const field_inits = try gpa.alloc(Air.Inst.Ref, struct_ty.structFieldCount(mod));20143 const field_inits = try gpa.alloc(Air.Inst.Ref, struct_ty.structFieldCount(mod));
...@@ -19950,7 +20148,8 @@ fn structInitEmpty(...@@ -19950,7 +20148,8 @@ fn structInitEmpty(
19950}20148}
1995120149
19952fn arrayInitEmpty(sema: *Sema, block: *Block, src: LazySrcLoc, obj_ty: Type) CompileError!Air.Inst.Ref {20150fn arrayInitEmpty(sema: *Sema, block: *Block, src: LazySrcLoc, obj_ty: Type) CompileError!Air.Inst.Ref {
19953 const mod = sema.mod;20151 const pt = sema.pt;
20152 const mod = pt.zcu;
19954 const arr_len = obj_ty.arrayLen(mod);20153 const arr_len = obj_ty.arrayLen(mod);
19955 if (arr_len != 0) {20154 if (arr_len != 0) {
19956 if (obj_ty.zigTypeTag(mod) == .Array) {20155 if (obj_ty.zigTypeTag(mod) == .Array) {
...@@ -19959,21 +20158,22 @@ fn arrayInitEmpty(sema: *Sema, block: *Block, src: LazySrcLoc, obj_ty: Type) Com...@@ -19959,21 +20158,22 @@ fn arrayInitEmpty(sema: *Sema, block: *Block, src: LazySrcLoc, obj_ty: Type) Com
19959 return sema.fail(block, src, "expected {d} vector elements; found 0", .{arr_len});20158 return sema.fail(block, src, "expected {d} vector elements; found 0", .{arr_len});
19960 }20159 }
19961 }20160 }
19962 return Air.internedToRef((try mod.intern(.{ .aggregate = .{20161 return Air.internedToRef((try pt.intern(.{ .aggregate = .{
19963 .ty = obj_ty.toIntern(),20162 .ty = obj_ty.toIntern(),
19964 .storage = .{ .elems = &.{} },20163 .storage = .{ .elems = &.{} },
19965 } })));20164 } })));
19966}20165}
1996720166
19968fn zirUnionInit(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {20167fn zirUnionInit(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
20168 const pt = sema.pt;
19969 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;20169 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
19970 const ty_src = block.builtinCallArgSrc(inst_data.src_node, 0);20170 const ty_src = block.builtinCallArgSrc(inst_data.src_node, 0);
19971 const field_src = block.builtinCallArgSrc(inst_data.src_node, 1);20171 const field_src = block.builtinCallArgSrc(inst_data.src_node, 1);
19972 const init_src = block.builtinCallArgSrc(inst_data.src_node, 2);20172 const init_src = block.builtinCallArgSrc(inst_data.src_node, 2);
19973 const extra = sema.code.extraData(Zir.Inst.UnionInit, inst_data.payload_index).data;20173 const extra = sema.code.extraData(Zir.Inst.UnionInit, inst_data.payload_index).data;
19974 const union_ty = try sema.resolveType(block, ty_src, extra.union_type);20174 const union_ty = try sema.resolveType(block, ty_src, extra.union_type);
19975 if (union_ty.zigTypeTag(sema.mod) != .Union) {20175 if (union_ty.zigTypeTag(pt.zcu) != .Union) {
19976 return sema.fail(block, ty_src, "expected union type, found '{}'", .{union_ty.fmt(sema.mod)});20176 return sema.fail(block, ty_src, "expected union type, found '{}'", .{union_ty.fmt(pt)});
19977 }20177 }
19978 const field_name = try sema.resolveConstStringIntern(block, field_src, extra.field_name, .{20178 const field_name = try sema.resolveConstStringIntern(block, field_src, extra.field_name, .{
19979 .needed_comptime_reason = "name of field being initialized must be comptime-known",20179 .needed_comptime_reason = "name of field being initialized must be comptime-known",
...@@ -19992,7 +20192,8 @@ fn unionInit(...@@ -19992,7 +20192,8 @@ fn unionInit(
19992 field_name: InternPool.NullTerminatedString,20192 field_name: InternPool.NullTerminatedString,
19993 field_src: LazySrcLoc,20193 field_src: LazySrcLoc,
19994) CompileError!Air.Inst.Ref {20194) CompileError!Air.Inst.Ref {
19995 const mod = sema.mod;20195 const pt = sema.pt;
20196 const mod = pt.zcu;
19996 const ip = &mod.intern_pool;20197 const ip = &mod.intern_pool;
19997 const field_index = try sema.unionFieldIndex(block, union_ty, field_name, field_src);20198 const field_index = try sema.unionFieldIndex(block, union_ty, field_name, field_src);
19998 const field_ty = Type.fromInterned(mod.typeToUnion(union_ty).?.field_types.get(ip)[field_index]);20199 const field_ty = Type.fromInterned(mod.typeToUnion(union_ty).?.field_types.get(ip)[field_index]);
...@@ -20000,8 +20201,8 @@ fn unionInit(...@@ -20000,8 +20201,8 @@ fn unionInit(
2000020201
20001 if (try sema.resolveValue(init)) |init_val| {20202 if (try sema.resolveValue(init)) |init_val| {
20002 const tag_ty = union_ty.unionTagTypeHypothetical(mod);20203 const tag_ty = union_ty.unionTagTypeHypothetical(mod);
20003 const tag_val = try mod.enumValueFieldIndex(tag_ty, field_index);20204 const tag_val = try pt.enumValueFieldIndex(tag_ty, field_index);
20004 return Air.internedToRef((try mod.intern(.{ .un = .{20205 return Air.internedToRef((try pt.intern(.{ .un = .{
20005 .ty = union_ty.toIntern(),20206 .ty = union_ty.toIntern(),
20006 .tag = tag_val.toIntern(),20207 .tag = tag_val.toIntern(),
20007 .val = init_val.toIntern(),20208 .val = init_val.toIntern(),
...@@ -20025,7 +20226,8 @@ fn zirStructInit(...@@ -20025,7 +20226,8 @@ fn zirStructInit(
20025 const extra = sema.code.extraData(Zir.Inst.StructInit, inst_data.payload_index);20226 const extra = sema.code.extraData(Zir.Inst.StructInit, inst_data.payload_index);
20026 const src = block.nodeOffset(inst_data.src_node);20227 const src = block.nodeOffset(inst_data.src_node);
2002720228
20028 const mod = sema.mod;20229 const pt = sema.pt;
20230 const mod = pt.zcu;
20029 const ip = &mod.intern_pool;20231 const ip = &mod.intern_pool;
20030 const first_item = sema.code.extraData(Zir.Inst.StructInit.Item, extra.end).data;20232 const first_item = sema.code.extraData(Zir.Inst.StructInit.Item, extra.end).data;
20031 const first_field_type_data = zir_datas[@intFromEnum(first_item.field_type)].pl_node;20233 const first_field_type_data = zir_datas[@intFromEnum(first_item.field_type)].pl_node;
...@@ -20038,7 +20240,7 @@ fn zirStructInit(...@@ -20038,7 +20240,7 @@ fn zirStructInit(
20038 else => |e| return e,20240 else => |e| return e,
20039 };20241 };
20040 const resolved_ty = result_ty.optEuBaseType(mod);20242 const resolved_ty = result_ty.optEuBaseType(mod);
20041 try resolved_ty.resolveLayout(mod);20243 try resolved_ty.resolveLayout(pt);
2004220244
20043 if (resolved_ty.zigTypeTag(mod) == .Struct) {20245 if (resolved_ty.zigTypeTag(mod) == .Struct) {
20044 // This logic must be synchronized with that in `zirStructInitEmpty`.20246 // This logic must be synchronized with that in `zirStructInitEmpty`.
...@@ -20066,6 +20268,7 @@ fn zirStructInit(...@@ -20066,6 +20268,7 @@ fn zirStructInit(
20066 const field_type_extra = sema.code.extraData(Zir.Inst.FieldType, field_type_data.payload_index).data;20268 const field_type_extra = sema.code.extraData(Zir.Inst.FieldType, field_type_data.payload_index).data;
20067 const field_name = try ip.getOrPutString(20269 const field_name = try ip.getOrPutString(
20068 gpa,20270 gpa,
20271 pt.tid,
20069 sema.code.nullTerminatedString(field_type_extra.name_start),20272 sema.code.nullTerminatedString(field_type_extra.name_start),
20070 .no_embedded_nulls,20273 .no_embedded_nulls,
20071 );20274 );
...@@ -20079,8 +20282,8 @@ fn zirStructInit(...@@ -20079,8 +20282,8 @@ fn zirStructInit(
20079 const field_ty = resolved_ty.structFieldType(field_index, mod);20282 const field_ty = resolved_ty.structFieldType(field_index, mod);
20080 field_inits[field_index] = try sema.coerce(block, field_ty, uncoerced_init, field_src);20283 field_inits[field_index] = try sema.coerce(block, field_ty, uncoerced_init, field_src);
20081 if (!is_packed) {20284 if (!is_packed) {
20082 try resolved_ty.resolveStructFieldInits(mod);20285 try resolved_ty.resolveStructFieldInits(pt);
20083 if (try resolved_ty.structFieldValueComptime(mod, field_index)) |default_value| {20286 if (try resolved_ty.structFieldValueComptime(pt, field_index)) |default_value| {
20084 const init_val = (try sema.resolveValue(field_inits[field_index])) orelse {20287 const init_val = (try sema.resolveValue(field_inits[field_index])) orelse {
20085 return sema.failWithNeededComptime(block, field_src, .{20288 return sema.failWithNeededComptime(block, field_src, .{
20086 .needed_comptime_reason = "value stored in comptime field must be comptime-known",20289 .needed_comptime_reason = "value stored in comptime field must be comptime-known",
...@@ -20107,12 +20310,13 @@ fn zirStructInit(...@@ -20107,12 +20310,13 @@ fn zirStructInit(
20107 const field_type_extra = sema.code.extraData(Zir.Inst.FieldType, field_type_data.payload_index).data;20310 const field_type_extra = sema.code.extraData(Zir.Inst.FieldType, field_type_data.payload_index).data;
20108 const field_name = try ip.getOrPutString(20311 const field_name = try ip.getOrPutString(
20109 gpa,20312 gpa,
20313 pt.tid,
20110 sema.code.nullTerminatedString(field_type_extra.name_start),20314 sema.code.nullTerminatedString(field_type_extra.name_start),
20111 .no_embedded_nulls,20315 .no_embedded_nulls,
20112 );20316 );
20113 const field_index = try sema.unionFieldIndex(block, resolved_ty, field_name, field_src);20317 const field_index = try sema.unionFieldIndex(block, resolved_ty, field_name, field_src);
20114 const tag_ty = resolved_ty.unionTagTypeHypothetical(mod);20318 const tag_ty = resolved_ty.unionTagTypeHypothetical(mod);
20115 const tag_val = try mod.enumValueFieldIndex(tag_ty, field_index);20319 const tag_val = try pt.enumValueFieldIndex(tag_ty, field_index);
20116 const field_ty = Type.fromInterned(mod.typeToUnion(resolved_ty).?.field_types.get(ip)[field_index]);20320 const field_ty = Type.fromInterned(mod.typeToUnion(resolved_ty).?.field_types.get(ip)[field_index]);
2011720321
20118 if (field_ty.zigTypeTag(mod) == .NoReturn) {20322 if (field_ty.zigTypeTag(mod) == .NoReturn) {
...@@ -20132,11 +20336,11 @@ fn zirStructInit(...@@ -20132,11 +20336,11 @@ fn zirStructInit(
20132 const init_inst = try sema.coerce(block, field_ty, uncoerced_init_inst, field_src);20336 const init_inst = try sema.coerce(block, field_ty, uncoerced_init_inst, field_src);
2013320337
20134 if (try sema.resolveValue(init_inst)) |val| {20338 if (try sema.resolveValue(init_inst)) |val| {
20135 const struct_val = Value.fromInterned((try mod.intern(.{ .un = .{20339 const struct_val = Value.fromInterned(try pt.intern(.{ .un = .{
20136 .ty = resolved_ty.toIntern(),20340 .ty = resolved_ty.toIntern(),
20137 .tag = tag_val.toIntern(),20341 .tag = tag_val.toIntern(),
20138 .val = val.toIntern(),20342 .val = val.toIntern(),
20139 } })));20343 } }));
20140 const final_val_inst = try sema.coerce(block, result_ty, Air.internedToRef(struct_val.toIntern()), src);20344 const final_val_inst = try sema.coerce(block, result_ty, Air.internedToRef(struct_val.toIntern()), src);
20141 const final_val = (try sema.resolveValue(final_val_inst)).?;20345 const final_val = (try sema.resolveValue(final_val_inst)).?;
20142 return sema.addConstantMaybeRef(final_val.toIntern(), is_ref);20346 return sema.addConstantMaybeRef(final_val.toIntern(), is_ref);
...@@ -20152,7 +20356,7 @@ fn zirStructInit(...@@ -20152,7 +20356,7 @@ fn zirStructInit(
2015220356
20153 if (is_ref) {20357 if (is_ref) {
20154 const target = mod.getTarget();20358 const target = mod.getTarget();
20155 const alloc_ty = try mod.ptrTypeSema(.{20359 const alloc_ty = try pt.ptrTypeSema(.{
20156 .child = result_ty.toIntern(),20360 .child = result_ty.toIntern(),
20157 .flags = .{ .address_space = target_util.defaultAddressSpace(target, .local) },20361 .flags = .{ .address_space = target_util.defaultAddressSpace(target, .local) },
20158 });20362 });
...@@ -20182,7 +20386,8 @@ fn finishStructInit(...@@ -20182,7 +20386,8 @@ fn finishStructInit(
20182 result_ty: Type,20386 result_ty: Type,
20183 is_ref: bool,20387 is_ref: bool,
20184) CompileError!Air.Inst.Ref {20388) CompileError!Air.Inst.Ref {
20185 const mod = sema.mod;20389 const pt = sema.pt;
20390 const mod = pt.zcu;
20186 const ip = &mod.intern_pool;20391 const ip = &mod.intern_pool;
2018720392
20188 var root_msg: ?*Module.ErrorMsg = null;20393 var root_msg: ?*Module.ErrorMsg = null;
...@@ -20242,7 +20447,7 @@ fn finishStructInit(...@@ -20242,7 +20447,7 @@ fn finishStructInit(
20242 continue;20447 continue;
20243 }20448 }
2024420449
20245 try struct_ty.resolveStructFieldInits(mod);20450 try struct_ty.resolveStructFieldInits(pt);
2024620451
20247 const field_init = struct_type.fieldInit(ip, i);20452 const field_init = struct_type.fieldInit(ip, i);
20248 if (field_init == .none) {20453 if (field_init == .none) {
...@@ -20289,7 +20494,7 @@ fn finishStructInit(...@@ -20289,7 +20494,7 @@ fn finishStructInit(
20289 for (elems, field_inits) |*elem, field_init| {20494 for (elems, field_inits) |*elem, field_init| {
20290 elem.* = (sema.resolveValue(field_init) catch unreachable).?.toIntern();20495 elem.* = (sema.resolveValue(field_init) catch unreachable).?.toIntern();
20291 }20496 }
20292 const struct_val = try mod.intern(.{ .aggregate = .{20497 const struct_val = try pt.intern(.{ .aggregate = .{
20293 .ty = struct_ty.toIntern(),20498 .ty = struct_ty.toIntern(),
20294 .storage = .{ .elems = elems },20499 .storage = .{ .elems = elems },
20295 } });20500 } });
...@@ -20312,9 +20517,9 @@ fn finishStructInit(...@@ -20312,9 +20517,9 @@ fn finishStructInit(
20312 }20517 }
2031320518
20314 if (is_ref) {20519 if (is_ref) {
20315 try struct_ty.resolveLayout(mod);20520 try struct_ty.resolveLayout(pt);
20316 const target = sema.mod.getTarget();20521 const target = mod.getTarget();
20317 const alloc_ty = try mod.ptrTypeSema(.{20522 const alloc_ty = try pt.ptrTypeSema(.{
20318 .child = result_ty.toIntern(),20523 .child = result_ty.toIntern(),
20319 .flags = .{ .address_space = target_util.defaultAddressSpace(target, .local) },20524 .flags = .{ .address_space = target_util.defaultAddressSpace(target, .local) },
20320 });20525 });
...@@ -20334,7 +20539,7 @@ fn finishStructInit(...@@ -20334,7 +20539,7 @@ fn finishStructInit(
20334 .init_node_offset = init_src.offset.node_offset.x,20539 .init_node_offset = init_src.offset.node_offset.x,
20335 .elem_index = @intCast(runtime_index),20540 .elem_index = @intCast(runtime_index),
20336 } }));20541 } }));
20337 try struct_ty.resolveStructFieldInits(mod);20542 try struct_ty.resolveStructFieldInits(pt);
20338 const struct_val = try block.addAggregateInit(struct_ty, field_inits);20543 const struct_val = try block.addAggregateInit(struct_ty, field_inits);
20339 return sema.coerce(block, result_ty, struct_val, init_src);20544 return sema.coerce(block, result_ty, struct_val, init_src);
20340}20545}
...@@ -20364,7 +20569,8 @@ fn structInitAnon(...@@ -20364,7 +20569,8 @@ fn structInitAnon(
20364 extra_end: usize,20569 extra_end: usize,
20365 is_ref: bool,20570 is_ref: bool,
20366) CompileError!Air.Inst.Ref {20571) CompileError!Air.Inst.Ref {
20367 const mod = sema.mod;20572 const pt = sema.pt;
20573 const mod = pt.zcu;
20368 const gpa = sema.gpa;20574 const gpa = sema.gpa;
20369 const ip = &mod.intern_pool;20575 const ip = &mod.intern_pool;
20370 const zir_datas = sema.code.instructions.items(.data);20576 const zir_datas = sema.code.instructions.items(.data);
...@@ -20394,7 +20600,7 @@ fn structInitAnon(...@@ -20394,7 +20600,7 @@ fn structInitAnon(
20394 },20600 },
20395 };20601 };
2039620602
20397 field_name.* = try mod.intern_pool.getOrPutString(gpa, name, .no_embedded_nulls);20603 field_name.* = try mod.intern_pool.getOrPutString(gpa, pt.tid, name, .no_embedded_nulls);
2039820604
20399 const init = try sema.resolveInst(item.data.init);20605 const init = try sema.resolveInst(item.data.init);
20400 field_ty.* = sema.typeOf(init).toIntern();20606 field_ty.* = sema.typeOf(init).toIntern();
...@@ -20422,14 +20628,14 @@ fn structInitAnon(...@@ -20422,14 +20628,14 @@ fn structInitAnon(
20422 break :rs runtime_index;20628 break :rs runtime_index;
20423 };20629 };
2042420630
20425 const tuple_ty = try ip.getAnonStructType(gpa, .{20631 const tuple_ty = try ip.getAnonStructType(gpa, pt.tid, .{
20426 .names = names,20632 .names = names,
20427 .types = types,20633 .types = types,
20428 .values = values,20634 .values = values,
20429 });20635 });
2043020636
20431 const runtime_index = opt_runtime_index orelse {20637 const runtime_index = opt_runtime_index orelse {
20432 const tuple_val = try mod.intern(.{ .aggregate = .{20638 const tuple_val = try pt.intern(.{ .aggregate = .{
20433 .ty = tuple_ty,20639 .ty = tuple_ty,
20434 .storage = .{ .elems = values },20640 .storage = .{ .elems = values },
20435 } });20641 } });
...@@ -20443,7 +20649,7 @@ fn structInitAnon(...@@ -20443,7 +20649,7 @@ fn structInitAnon(
2044320649
20444 if (is_ref) {20650 if (is_ref) {
20445 const target = mod.getTarget();20651 const target = mod.getTarget();
20446 const alloc_ty = try mod.ptrTypeSema(.{20652 const alloc_ty = try pt.ptrTypeSema(.{
20447 .child = tuple_ty,20653 .child = tuple_ty,
20448 .flags = .{ .address_space = target_util.defaultAddressSpace(target, .local) },20654 .flags = .{ .address_space = target_util.defaultAddressSpace(target, .local) },
20449 });20655 });
...@@ -20457,7 +20663,7 @@ fn structInitAnon(...@@ -20457,7 +20663,7 @@ fn structInitAnon(
20457 };20663 };
20458 extra_index = item.end;20664 extra_index = item.end;
2045920665
20460 const field_ptr_ty = try mod.ptrTypeSema(.{20666 const field_ptr_ty = try pt.ptrTypeSema(.{
20461 .child = field_ty,20667 .child = field_ty,
20462 .flags = .{ .address_space = target_util.defaultAddressSpace(target, .local) },20668 .flags = .{ .address_space = target_util.defaultAddressSpace(target, .local) },
20463 });20669 });
...@@ -20491,7 +20697,8 @@ fn zirArrayInit(...@@ -20491,7 +20697,8 @@ fn zirArrayInit(
20491 inst: Zir.Inst.Index,20697 inst: Zir.Inst.Index,
20492 is_ref: bool,20698 is_ref: bool,
20493) CompileError!Air.Inst.Ref {20699) CompileError!Air.Inst.Ref {
20494 const mod = sema.mod;20700 const pt = sema.pt;
20701 const mod = pt.zcu;
20495 const gpa = sema.gpa;20702 const gpa = sema.gpa;
20496 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;20703 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
20497 const src = block.nodeOffset(inst_data.src_node);20704 const src = block.nodeOffset(inst_data.src_node);
...@@ -20550,8 +20757,8 @@ fn zirArrayInit(...@@ -20550,8 +20757,8 @@ fn zirArrayInit(
20550 dest.* = try sema.coerce(block, elem_ty, resolved_arg, elem_src);20757 dest.* = try sema.coerce(block, elem_ty, resolved_arg, elem_src);
20551 if (is_tuple) {20758 if (is_tuple) {
20552 if (array_ty.structFieldIsComptime(i, mod))20759 if (array_ty.structFieldIsComptime(i, mod))
20553 try array_ty.resolveStructFieldInits(mod);20760 try array_ty.resolveStructFieldInits(pt);
20554 if (try array_ty.structFieldValueComptime(mod, i)) |field_val| {20761 if (try array_ty.structFieldValueComptime(pt, i)) |field_val| {
20555 const init_val = try sema.resolveValue(dest.*) orelse {20762 const init_val = try sema.resolveValue(dest.*) orelse {
20556 return sema.failWithNeededComptime(block, elem_src, .{20763 return sema.failWithNeededComptime(block, elem_src, .{
20557 .needed_comptime_reason = "value stored in comptime field must be comptime-known",20764 .needed_comptime_reason = "value stored in comptime field must be comptime-known",
...@@ -20581,7 +20788,7 @@ fn zirArrayInit(...@@ -20581,7 +20788,7 @@ fn zirArrayInit(
20581 // We checked that all args are comptime above.20788 // We checked that all args are comptime above.
20582 val.* = (sema.resolveValue(arg) catch unreachable).?.toIntern();20789 val.* = (sema.resolveValue(arg) catch unreachable).?.toIntern();
20583 }20790 }
20584 const arr_val = try mod.intern(.{ .aggregate = .{20791 const arr_val = try pt.intern(.{ .aggregate = .{
20585 .ty = array_ty.toIntern(),20792 .ty = array_ty.toIntern(),
20586 .storage = .{ .elems = elem_vals },20793 .storage = .{ .elems = elem_vals },
20587 } });20794 } });
...@@ -20597,7 +20804,7 @@ fn zirArrayInit(...@@ -20597,7 +20804,7 @@ fn zirArrayInit(
2059720804
20598 if (is_ref) {20805 if (is_ref) {
20599 const target = mod.getTarget();20806 const target = mod.getTarget();
20600 const alloc_ty = try mod.ptrTypeSema(.{20807 const alloc_ty = try pt.ptrTypeSema(.{
20601 .child = result_ty.toIntern(),20808 .child = result_ty.toIntern(),
20602 .flags = .{ .address_space = target_util.defaultAddressSpace(target, .local) },20809 .flags = .{ .address_space = target_util.defaultAddressSpace(target, .local) },
20603 });20810 });
...@@ -20606,27 +20813,27 @@ fn zirArrayInit(...@@ -20606,27 +20813,27 @@ fn zirArrayInit(
2060620813
20607 if (is_tuple) {20814 if (is_tuple) {
20608 for (resolved_args, 0..) |arg, i| {20815 for (resolved_args, 0..) |arg, i| {
20609 const elem_ptr_ty = try mod.ptrTypeSema(.{20816 const elem_ptr_ty = try pt.ptrTypeSema(.{
20610 .child = array_ty.structFieldType(i, mod).toIntern(),20817 .child = array_ty.structFieldType(i, mod).toIntern(),
20611 .flags = .{ .address_space = target_util.defaultAddressSpace(target, .local) },20818 .flags = .{ .address_space = target_util.defaultAddressSpace(target, .local) },
20612 });20819 });
20613 const elem_ptr_ty_ref = Air.internedToRef(elem_ptr_ty.toIntern());20820 const elem_ptr_ty_ref = Air.internedToRef(elem_ptr_ty.toIntern());
2061420821
20615 const index = try mod.intRef(Type.usize, i);20822 const index = try pt.intRef(Type.usize, i);
20616 const elem_ptr = try block.addPtrElemPtrTypeRef(base_ptr, index, elem_ptr_ty_ref);20823 const elem_ptr = try block.addPtrElemPtrTypeRef(base_ptr, index, elem_ptr_ty_ref);
20617 _ = try block.addBinOp(.store, elem_ptr, arg);20824 _ = try block.addBinOp(.store, elem_ptr, arg);
20618 }20825 }
20619 return sema.makePtrConst(block, alloc);20826 return sema.makePtrConst(block, alloc);
20620 }20827 }
2062120828
20622 const elem_ptr_ty = try mod.ptrTypeSema(.{20829 const elem_ptr_ty = try pt.ptrTypeSema(.{
20623 .child = array_ty.elemType2(mod).toIntern(),20830 .child = array_ty.elemType2(mod).toIntern(),
20624 .flags = .{ .address_space = target_util.defaultAddressSpace(target, .local) },20831 .flags = .{ .address_space = target_util.defaultAddressSpace(target, .local) },
20625 });20832 });
20626 const elem_ptr_ty_ref = Air.internedToRef(elem_ptr_ty.toIntern());20833 const elem_ptr_ty_ref = Air.internedToRef(elem_ptr_ty.toIntern());
2062720834
20628 for (resolved_args, 0..) |arg, i| {20835 for (resolved_args, 0..) |arg, i| {
20629 const index = try mod.intRef(Type.usize, i);20836 const index = try pt.intRef(Type.usize, i);
20630 const elem_ptr = try block.addPtrElemPtrTypeRef(base_ptr, index, elem_ptr_ty_ref);20837 const elem_ptr = try block.addPtrElemPtrTypeRef(base_ptr, index, elem_ptr_ty_ref);
20631 _ = try block.addBinOp(.store, elem_ptr, arg);20838 _ = try block.addBinOp(.store, elem_ptr, arg);
20632 }20839 }
...@@ -20656,7 +20863,8 @@ fn arrayInitAnon(...@@ -20656,7 +20863,8 @@ fn arrayInitAnon(
20656 operands: []const Zir.Inst.Ref,20863 operands: []const Zir.Inst.Ref,
20657 is_ref: bool,20864 is_ref: bool,
20658) CompileError!Air.Inst.Ref {20865) CompileError!Air.Inst.Ref {
20659 const mod = sema.mod;20866 const pt = sema.pt;
20867 const mod = pt.zcu;
20660 const gpa = sema.gpa;20868 const gpa = sema.gpa;
20661 const ip = &mod.intern_pool;20869 const ip = &mod.intern_pool;
2066220870
...@@ -20689,14 +20897,14 @@ fn arrayInitAnon(...@@ -20689,14 +20897,14 @@ fn arrayInitAnon(
20689 break :rs runtime_src;20897 break :rs runtime_src;
20690 };20898 };
2069120899
20692 const tuple_ty = try ip.getAnonStructType(gpa, .{20900 const tuple_ty = try ip.getAnonStructType(gpa, pt.tid, .{
20693 .types = types,20901 .types = types,
20694 .values = values,20902 .values = values,
20695 .names = &.{},20903 .names = &.{},
20696 });20904 });
2069720905
20698 const runtime_src = opt_runtime_src orelse {20906 const runtime_src = opt_runtime_src orelse {
20699 const tuple_val = try mod.intern(.{ .aggregate = .{20907 const tuple_val = try pt.intern(.{ .aggregate = .{
20700 .ty = tuple_ty,20908 .ty = tuple_ty,
20701 .storage = .{ .elems = values },20909 .storage = .{ .elems = values },
20702 } });20910 } });
...@@ -20706,15 +20914,15 @@ fn arrayInitAnon(...@@ -20706,15 +20914,15 @@ fn arrayInitAnon(
20706 try sema.requireRuntimeBlock(block, src, runtime_src);20914 try sema.requireRuntimeBlock(block, src, runtime_src);
2070720915
20708 if (is_ref) {20916 if (is_ref) {
20709 const target = sema.mod.getTarget();20917 const target = sema.pt.zcu.getTarget();
20710 const alloc_ty = try mod.ptrTypeSema(.{20918 const alloc_ty = try pt.ptrTypeSema(.{
20711 .child = tuple_ty,20919 .child = tuple_ty,
20712 .flags = .{ .address_space = target_util.defaultAddressSpace(target, .local) },20920 .flags = .{ .address_space = target_util.defaultAddressSpace(target, .local) },
20713 });20921 });
20714 const alloc = try block.addTy(.alloc, alloc_ty);20922 const alloc = try block.addTy(.alloc, alloc_ty);
20715 for (operands, 0..) |operand, i_usize| {20923 for (operands, 0..) |operand, i_usize| {
20716 const i: u32 = @intCast(i_usize);20924 const i: u32 = @intCast(i_usize);
20717 const field_ptr_ty = try mod.ptrTypeSema(.{20925 const field_ptr_ty = try pt.ptrTypeSema(.{
20718 .child = types[i],20926 .child = types[i],
20719 .flags = .{ .address_space = target_util.defaultAddressSpace(target, .local) },20927 .flags = .{ .address_space = target_util.defaultAddressSpace(target, .local) },
20720 });20928 });
...@@ -20752,7 +20960,8 @@ fn zirFieldTypeRef(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErro...@@ -20752,7 +20960,8 @@ fn zirFieldTypeRef(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErro
20752}20960}
2075320961
20754fn zirStructInitFieldType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {20962fn zirStructInitFieldType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
20755 const mod = sema.mod;20963 const pt = sema.pt;
20964 const mod = pt.zcu;
20756 const ip = &mod.intern_pool;20965 const ip = &mod.intern_pool;
20757 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;20966 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
20758 const extra = sema.code.extraData(Zir.Inst.FieldType, inst_data.payload_index).data;20967 const extra = sema.code.extraData(Zir.Inst.FieldType, inst_data.payload_index).data;
...@@ -20768,7 +20977,7 @@ fn zirStructInitFieldType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Comp...@@ -20768,7 +20977,7 @@ fn zirStructInitFieldType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Comp
20768 };20977 };
20769 const aggregate_ty = wrapped_aggregate_ty.optEuBaseType(mod);20978 const aggregate_ty = wrapped_aggregate_ty.optEuBaseType(mod);
20770 const zir_field_name = sema.code.nullTerminatedString(extra.name_start);20979 const zir_field_name = sema.code.nullTerminatedString(extra.name_start);
20771 const field_name = try ip.getOrPutString(sema.gpa, zir_field_name, .no_embedded_nulls);20980 const field_name = try ip.getOrPutString(sema.gpa, pt.tid, zir_field_name, .no_embedded_nulls);
20772 return sema.fieldType(block, aggregate_ty, field_name, field_name_src, ty_src);20981 return sema.fieldType(block, aggregate_ty, field_name, field_name_src, ty_src);
20773}20982}
2077420983
...@@ -20780,11 +20989,12 @@ fn fieldType(...@@ -20780,11 +20989,12 @@ fn fieldType(
20780 field_src: LazySrcLoc,20989 field_src: LazySrcLoc,
20781 ty_src: LazySrcLoc,20990 ty_src: LazySrcLoc,
20782) CompileError!Air.Inst.Ref {20991) CompileError!Air.Inst.Ref {
20783 const mod = sema.mod;20992 const pt = sema.pt;
20993 const mod = pt.zcu;
20784 const ip = &mod.intern_pool;20994 const ip = &mod.intern_pool;
20785 var cur_ty = aggregate_ty;20995 var cur_ty = aggregate_ty;
20786 while (true) {20996 while (true) {
20787 try cur_ty.resolveFields(mod);20997 try cur_ty.resolveFields(pt);
20788 switch (cur_ty.zigTypeTag(mod)) {20998 switch (cur_ty.zigTypeTag(mod)) {
20789 .Struct => switch (ip.indexToKey(cur_ty.toIntern())) {20999 .Struct => switch (ip.indexToKey(cur_ty.toIntern())) {
20790 .anon_struct_type => |anon_struct| {21000 .anon_struct_type => |anon_struct| {
...@@ -20823,7 +21033,7 @@ fn fieldType(...@@ -20823,7 +21033,7 @@ fn fieldType(
20823 else => {},21033 else => {},
20824 }21034 }
20825 return sema.fail(block, ty_src, "expected struct or union; found '{}'", .{21035 return sema.fail(block, ty_src, "expected struct or union; found '{}'", .{
20826 cur_ty.fmt(sema.mod),21036 cur_ty.fmt(pt),
20827 });21037 });
20828 }21038 }
20829}21039}
...@@ -20833,12 +21043,13 @@ fn zirErrorReturnTrace(sema: *Sema, block: *Block) CompileError!Air.Inst.Ref {...@@ -20833,12 +21043,13 @@ fn zirErrorReturnTrace(sema: *Sema, block: *Block) CompileError!Air.Inst.Ref {
20833}21043}
2083421044
20835fn getErrorReturnTrace(sema: *Sema, block: *Block) CompileError!Air.Inst.Ref {21045fn getErrorReturnTrace(sema: *Sema, block: *Block) CompileError!Air.Inst.Ref {
20836 const mod = sema.mod;21046 const pt = sema.pt;
21047 const mod = pt.zcu;
20837 const ip = &mod.intern_pool;21048 const ip = &mod.intern_pool;
20838 const stack_trace_ty = try mod.getBuiltinType("StackTrace");21049 const stack_trace_ty = try pt.getBuiltinType("StackTrace");
20839 try stack_trace_ty.resolveFields(mod);21050 try stack_trace_ty.resolveFields(pt);
20840 const ptr_stack_trace_ty = try mod.singleMutPtrType(stack_trace_ty);21051 const ptr_stack_trace_ty = try pt.singleMutPtrType(stack_trace_ty);
20841 const opt_ptr_stack_trace_ty = try mod.optionalType(ptr_stack_trace_ty.toIntern());21052 const opt_ptr_stack_trace_ty = try pt.optionalType(ptr_stack_trace_ty.toIntern());
2084221053
20843 if (sema.owner_func_index != .none and21054 if (sema.owner_func_index != .none and
20844 ip.funcAnalysis(sema.owner_func_index).calls_or_awaits_errorable_fn and21055 ip.funcAnalysis(sema.owner_func_index).calls_or_awaits_errorable_fn and
...@@ -20846,7 +21057,7 @@ fn getErrorReturnTrace(sema: *Sema, block: *Block) CompileError!Air.Inst.Ref {...@@ -20846,7 +21057,7 @@ fn getErrorReturnTrace(sema: *Sema, block: *Block) CompileError!Air.Inst.Ref {
20846 {21057 {
20847 return block.addTy(.err_return_trace, opt_ptr_stack_trace_ty);21058 return block.addTy(.err_return_trace, opt_ptr_stack_trace_ty);
20848 }21059 }
20849 return Air.internedToRef((try mod.intern(.{ .opt = .{21060 return Air.internedToRef((try pt.intern(.{ .opt = .{
20850 .ty = opt_ptr_stack_trace_ty.toIntern(),21061 .ty = opt_ptr_stack_trace_ty.toIntern(),
20851 .val = .none,21062 .val = .none,
20852 } })));21063 } })));
...@@ -20862,19 +21073,20 @@ fn zirFrame(...@@ -20862,19 +21073,20 @@ fn zirFrame(
20862}21073}
2086321074
20864fn zirAlignOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {21075fn zirAlignOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
20865 const mod = sema.mod;21076 const pt = sema.pt;
20866 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;21077 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;
20867 const operand_src = block.builtinCallArgSrc(inst_data.src_node, 0);21078 const operand_src = block.builtinCallArgSrc(inst_data.src_node, 0);
20868 const ty = try sema.resolveType(block, operand_src, inst_data.operand);21079 const ty = try sema.resolveType(block, operand_src, inst_data.operand);
20869 if (ty.isNoReturn(mod)) {21080 if (ty.isNoReturn(pt.zcu)) {
20870 return sema.fail(block, operand_src, "no align available for type '{}'", .{ty.fmt(sema.mod)});21081 return sema.fail(block, operand_src, "no align available for type '{}'", .{ty.fmt(pt)});
20871 }21082 }
20872 const val = try ty.lazyAbiAlignment(mod);21083 const val = try ty.lazyAbiAlignment(pt);
20873 return Air.internedToRef(val.toIntern());21084 return Air.internedToRef(val.toIntern());
20874}21085}
2087521086
20876fn zirIntFromBool(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {21087fn zirIntFromBool(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
20877 const mod = sema.mod;21088 const pt = sema.pt;
21089 const mod = pt.zcu;
20878 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;21090 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;
20879 const src = block.nodeOffset(inst_data.src_node);21091 const src = block.nodeOffset(inst_data.src_node);
20880 const operand = try sema.resolveInst(inst_data.operand);21092 const operand = try sema.resolveInst(inst_data.operand);
...@@ -20886,25 +21098,25 @@ fn zirIntFromBool(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError...@@ -20886,25 +21098,25 @@ fn zirIntFromBool(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
20886 }21098 }
20887 if (try sema.resolveValue(operand)) |val| {21099 if (try sema.resolveValue(operand)) |val| {
20888 if (!is_vector) {21100 if (!is_vector) {
20889 if (val.isUndef(mod)) return mod.undefRef(Type.u1);21101 if (val.isUndef(mod)) return pt.undefRef(Type.u1);
20890 if (val.toBool()) return Air.internedToRef((try mod.intValue(Type.u1, 1)).toIntern());21102 if (val.toBool()) return Air.internedToRef((try pt.intValue(Type.u1, 1)).toIntern());
20891 return Air.internedToRef((try mod.intValue(Type.u1, 0)).toIntern());21103 return Air.internedToRef((try pt.intValue(Type.u1, 0)).toIntern());
20892 }21104 }
20893 const len = operand_ty.vectorLen(mod);21105 const len = operand_ty.vectorLen(mod);
20894 const dest_ty = try mod.vectorType(.{ .child = .u1_type, .len = len });21106 const dest_ty = try pt.vectorType(.{ .child = .u1_type, .len = len });
20895 if (val.isUndef(mod)) return mod.undefRef(dest_ty);21107 if (val.isUndef(mod)) return pt.undefRef(dest_ty);
20896 const new_elems = try sema.arena.alloc(InternPool.Index, len);21108 const new_elems = try sema.arena.alloc(InternPool.Index, len);
20897 for (new_elems, 0..) |*new_elem, i| {21109 for (new_elems, 0..) |*new_elem, i| {
20898 const old_elem = try val.elemValue(mod, i);21110 const old_elem = try val.elemValue(pt, i);
20899 const new_val = if (old_elem.isUndef(mod))21111 const new_val = if (old_elem.isUndef(mod))
20900 try mod.undefValue(Type.u1)21112 try pt.undefValue(Type.u1)
20901 else if (old_elem.toBool())21113 else if (old_elem.toBool())
20902 try mod.intValue(Type.u1, 1)21114 try pt.intValue(Type.u1, 1)
20903 else21115 else
20904 try mod.intValue(Type.u1, 0);21116 try pt.intValue(Type.u1, 0);
20905 new_elem.* = new_val.toIntern();21117 new_elem.* = new_val.toIntern();
20906 }21118 }
20907 return Air.internedToRef(try mod.intern(.{ .aggregate = .{21119 return Air.internedToRef(try pt.intern(.{ .aggregate = .{
20908 .ty = dest_ty.toIntern(),21120 .ty = dest_ty.toIntern(),
20909 .storage = .{ .elems = new_elems },21121 .storage = .{ .elems = new_elems },
20910 } }));21122 } }));
...@@ -20913,10 +21125,10 @@ fn zirIntFromBool(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError...@@ -20913,10 +21125,10 @@ fn zirIntFromBool(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
20913 return block.addUnOp(.int_from_bool, operand);21125 return block.addUnOp(.int_from_bool, operand);
20914 }21126 }
20915 const len = operand_ty.vectorLen(mod);21127 const len = operand_ty.vectorLen(mod);
20916 const dest_ty = try mod.vectorType(.{ .child = .u1_type, .len = len });21128 const dest_ty = try pt.vectorType(.{ .child = .u1_type, .len = len });
20917 const new_elems = try sema.arena.alloc(Air.Inst.Ref, len);21129 const new_elems = try sema.arena.alloc(Air.Inst.Ref, len);
20918 for (new_elems, 0..) |*new_elem, i| {21130 for (new_elems, 0..) |*new_elem, i| {
20919 const idx_ref = try mod.intRef(Type.usize, i);21131 const idx_ref = try pt.intRef(Type.usize, i);
20920 const old_elem = try block.addBinOp(.array_elem_val, operand, idx_ref);21132 const old_elem = try block.addBinOp(.array_elem_val, operand, idx_ref);
20921 new_elem.* = try block.addUnOp(.int_from_bool, old_elem);21133 new_elem.* = try block.addUnOp(.int_from_bool, old_elem);
20922 }21134 }
...@@ -20930,7 +21142,7 @@ fn zirErrorName(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A...@@ -20930,7 +21142,7 @@ fn zirErrorName(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
20930 const operand = try sema.coerce(block, Type.anyerror, uncoerced_operand, operand_src);21142 const operand = try sema.coerce(block, Type.anyerror, uncoerced_operand, operand_src);
2093121143
20932 if (try sema.resolveDefinedValue(block, operand_src, operand)) |val| {21144 if (try sema.resolveDefinedValue(block, operand_src, operand)) |val| {
20933 const err_name = sema.mod.intern_pool.indexToKey(val.toIntern()).err.name;21145 const err_name = sema.pt.zcu.intern_pool.indexToKey(val.toIntern()).err.name;
20934 return sema.addNullTerminatedStrLit(err_name);21146 return sema.addNullTerminatedStrLit(err_name);
20935 }21147 }
2093621148
...@@ -20944,7 +21156,8 @@ fn zirAbs(...@@ -20944,7 +21156,8 @@ fn zirAbs(
20944 block: *Block,21156 block: *Block,
20945 inst: Zir.Inst.Index,21157 inst: Zir.Inst.Index,
20946) CompileError!Air.Inst.Ref {21158) CompileError!Air.Inst.Ref {
20947 const mod = sema.mod;21159 const pt = sema.pt;
21160 const mod = pt.zcu;
20948 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;21161 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;
20949 const operand = try sema.resolveInst(inst_data.operand);21162 const operand = try sema.resolveInst(inst_data.operand);
20950 const operand_src = block.builtinCallArgSrc(inst_data.src_node, 0);21163 const operand_src = block.builtinCallArgSrc(inst_data.src_node, 0);
...@@ -20953,12 +21166,12 @@ fn zirAbs(...@@ -20953,12 +21166,12 @@ fn zirAbs(
2095321166
20954 const result_ty = switch (scalar_ty.zigTypeTag(mod)) {21167 const result_ty = switch (scalar_ty.zigTypeTag(mod)) {
20955 .ComptimeFloat, .Float, .ComptimeInt => operand_ty,21168 .ComptimeFloat, .Float, .ComptimeInt => operand_ty,
20956 .Int => if (scalar_ty.isSignedInt(mod)) try operand_ty.toUnsigned(mod) else return operand,21169 .Int => if (scalar_ty.isSignedInt(mod)) try operand_ty.toUnsigned(pt) else return operand,
20957 else => return sema.fail(21170 else => return sema.fail(
20958 block,21171 block,
20959 operand_src,21172 operand_src,
20960 "expected integer, float, or vector of either integers or floats, found '{}'",21173 "expected integer, float, or vector of either integers or floats, found '{}'",
20961 .{operand_ty.fmt(mod)},21174 .{operand_ty.fmt(pt)},
20962 ),21175 ),
20963 };21176 };
2096421177
...@@ -20972,30 +21185,31 @@ fn maybeConstantUnaryMath(...@@ -20972,30 +21185,31 @@ fn maybeConstantUnaryMath(
20972 sema: *Sema,21185 sema: *Sema,
20973 operand: Air.Inst.Ref,21186 operand: Air.Inst.Ref,
20974 result_ty: Type,21187 result_ty: Type,
20975 comptime eval: fn (Value, Type, Allocator, *Module) Allocator.Error!Value,21188 comptime eval: fn (Value, Type, Allocator, Zcu.PerThread) Allocator.Error!Value,
20976) CompileError!?Air.Inst.Ref {21189) CompileError!?Air.Inst.Ref {
20977 const mod = sema.mod;21190 const pt = sema.pt;
21191 const mod = pt.zcu;
20978 switch (result_ty.zigTypeTag(mod)) {21192 switch (result_ty.zigTypeTag(mod)) {
20979 .Vector => if (try sema.resolveValue(operand)) |val| {21193 .Vector => if (try sema.resolveValue(operand)) |val| {
20980 const scalar_ty = result_ty.scalarType(mod);21194 const scalar_ty = result_ty.scalarType(mod);
20981 const vec_len = result_ty.vectorLen(mod);21195 const vec_len = result_ty.vectorLen(mod);
20982 if (val.isUndef(mod))21196 if (val.isUndef(mod))
20983 return try mod.undefRef(result_ty);21197 return try pt.undefRef(result_ty);
2098421198
20985 const elems = try sema.arena.alloc(InternPool.Index, vec_len);21199 const elems = try sema.arena.alloc(InternPool.Index, vec_len);
20986 for (elems, 0..) |*elem, i| {21200 for (elems, 0..) |*elem, i| {
20987 const elem_val = try val.elemValue(sema.mod, i);21201 const elem_val = try val.elemValue(pt, i);
20988 elem.* = (try eval(elem_val, scalar_ty, sema.arena, sema.mod)).toIntern();21202 elem.* = (try eval(elem_val, scalar_ty, sema.arena, pt)).toIntern();
20989 }21203 }
20990 return Air.internedToRef((try mod.intern(.{ .aggregate = .{21204 return Air.internedToRef((try pt.intern(.{ .aggregate = .{
20991 .ty = result_ty.toIntern(),21205 .ty = result_ty.toIntern(),
20992 .storage = .{ .elems = elems },21206 .storage = .{ .elems = elems },
20993 } })));21207 } })));
20994 },21208 },
20995 else => if (try sema.resolveValue(operand)) |operand_val| {21209 else => if (try sema.resolveValue(operand)) |operand_val| {
20996 if (operand_val.isUndef(mod))21210 if (operand_val.isUndef(mod))
20997 return try mod.undefRef(result_ty);21211 return try pt.undefRef(result_ty);
20998 const result_val = try eval(operand_val, result_ty, sema.arena, sema.mod);21212 const result_val = try eval(operand_val, result_ty, sema.arena, pt);
20999 return Air.internedToRef(result_val.toIntern());21213 return Air.internedToRef(result_val.toIntern());
21000 },21214 },
21001 }21215 }
...@@ -21007,12 +21221,13 @@ fn zirUnaryMath(...@@ -21007,12 +21221,13 @@ fn zirUnaryMath(
21007 block: *Block,21221 block: *Block,
21008 inst: Zir.Inst.Index,21222 inst: Zir.Inst.Index,
21009 air_tag: Air.Inst.Tag,21223 air_tag: Air.Inst.Tag,
21010 comptime eval: fn (Value, Type, Allocator, *Module) Allocator.Error!Value,21224 comptime eval: fn (Value, Type, Allocator, Zcu.PerThread) Allocator.Error!Value,
21011) CompileError!Air.Inst.Ref {21225) CompileError!Air.Inst.Ref {
21012 const tracy = trace(@src());21226 const tracy = trace(@src());
21013 defer tracy.end();21227 defer tracy.end();
2101421228
21015 const mod = sema.mod;21229 const pt = sema.pt;
21230 const mod = pt.zcu;
21016 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;21231 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;
21017 const operand = try sema.resolveInst(inst_data.operand);21232 const operand = try sema.resolveInst(inst_data.operand);
21018 const operand_src = block.builtinCallArgSrc(inst_data.src_node, 0);21233 const operand_src = block.builtinCallArgSrc(inst_data.src_node, 0);
...@@ -21025,7 +21240,7 @@ fn zirUnaryMath(...@@ -21025,7 +21240,7 @@ fn zirUnaryMath(
21025 block,21240 block,
21026 operand_src,21241 operand_src,
21027 "expected vector of floats or float type, found '{}'",21242 "expected vector of floats or float type, found '{}'",
21028 .{operand_ty.fmt(sema.mod)},21243 .{operand_ty.fmt(pt)},
21029 ),21244 ),
21030 }21245 }
2103121246
...@@ -21041,10 +21256,11 @@ fn zirTagName(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air...@@ -21041,10 +21256,11 @@ fn zirTagName(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
21041 const src = block.nodeOffset(inst_data.src_node);21256 const src = block.nodeOffset(inst_data.src_node);
21042 const operand = try sema.resolveInst(inst_data.operand);21257 const operand = try sema.resolveInst(inst_data.operand);
21043 const operand_ty = sema.typeOf(operand);21258 const operand_ty = sema.typeOf(operand);
21044 const mod = sema.mod;21259 const pt = sema.pt;
21260 const mod = pt.zcu;
21045 const ip = &mod.intern_pool;21261 const ip = &mod.intern_pool;
2104621262
21047 try operand_ty.resolveLayout(mod);21263 try operand_ty.resolveLayout(pt);
21048 const enum_ty = switch (operand_ty.zigTypeTag(mod)) {21264 const enum_ty = switch (operand_ty.zigTypeTag(mod)) {
21049 .EnumLiteral => {21265 .EnumLiteral => {
21050 const val = try sema.resolveConstDefinedValue(block, LazySrcLoc.unneeded, operand, undefined);21266 const val = try sema.resolveConstDefinedValue(block, LazySrcLoc.unneeded, operand, undefined);
...@@ -21053,9 +21269,9 @@ fn zirTagName(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air...@@ -21053,9 +21269,9 @@ fn zirTagName(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
21053 },21269 },
21054 .Enum => operand_ty,21270 .Enum => operand_ty,
21055 .Union => operand_ty.unionTagType(mod) orelse21271 .Union => operand_ty.unionTagType(mod) orelse
21056 return sema.fail(block, src, "union '{}' is untagged", .{operand_ty.fmt(sema.mod)}),21272 return sema.fail(block, src, "union '{}' is untagged", .{operand_ty.fmt(pt)}),
21057 else => return sema.fail(block, operand_src, "expected enum or union; found '{}'", .{21273 else => return sema.fail(block, operand_src, "expected enum or union; found '{}'", .{
21058 operand_ty.fmt(mod),21274 operand_ty.fmt(pt),
21059 }),21275 }),
21060 };21276 };
21061 if (enum_ty.enumFieldCount(mod) == 0) {21277 if (enum_ty.enumFieldCount(mod) == 0) {
...@@ -21063,7 +21279,7 @@ fn zirTagName(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air...@@ -21063,7 +21279,7 @@ fn zirTagName(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
21063 // it prevents a crash.21279 // it prevents a crash.
21064 // https://github.com/ziglang/zig/issues/1590921280 // https://github.com/ziglang/zig/issues/15909
21065 return sema.fail(block, operand_src, "cannot get @tagName of empty enum '{}'", .{21281 return sema.fail(block, operand_src, "cannot get @tagName of empty enum '{}'", .{
21066 enum_ty.fmt(mod),21282 enum_ty.fmt(pt),
21067 });21283 });
21068 }21284 }
21069 const enum_decl_index = enum_ty.getOwnerDecl(mod);21285 const enum_decl_index = enum_ty.getOwnerDecl(mod);
...@@ -21072,7 +21288,7 @@ fn zirTagName(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air...@@ -21072,7 +21288,7 @@ fn zirTagName(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
21072 const field_index = enum_ty.enumTagFieldIndex(val, mod) orelse {21288 const field_index = enum_ty.enumTagFieldIndex(val, mod) orelse {
21073 const msg = msg: {21289 const msg = msg: {
21074 const msg = try sema.errMsg(src, "no field with value '{}' in enum '{}'", .{21290 const msg = try sema.errMsg(src, "no field with value '{}' in enum '{}'", .{
21075 val.fmtValue(sema.mod, sema), mod.declPtr(enum_decl_index).name.fmt(ip),21291 val.fmtValue(pt, sema), mod.declPtr(enum_decl_index).name.fmt(ip),
21076 });21292 });
21077 errdefer msg.destroy(sema.gpa);21293 errdefer msg.destroy(sema.gpa);
21078 try sema.errNote(enum_ty.srcLoc(mod), msg, "declared here", .{});21294 try sema.errNote(enum_ty.srcLoc(mod), msg, "declared here", .{});
...@@ -21085,7 +21301,7 @@ fn zirTagName(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air...@@ -21085,7 +21301,7 @@ fn zirTagName(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
21085 return sema.addNullTerminatedStrLit(field_name);21301 return sema.addNullTerminatedStrLit(field_name);
21086 }21302 }
21087 try sema.requireRuntimeBlock(block, src, operand_src);21303 try sema.requireRuntimeBlock(block, src, operand_src);
21088 if (block.wantSafety() and sema.mod.backendSupportsFeature(.is_named_enum_value)) {21304 if (block.wantSafety() and mod.backendSupportsFeature(.is_named_enum_value)) {
21089 const ok = try block.addUnOp(.is_named_enum_value, casted_operand);21305 const ok = try block.addUnOp(.is_named_enum_value, casted_operand);
21090 try sema.addSafetyCheck(block, src, ok, .invalid_enum_value);21306 try sema.addSafetyCheck(block, src, ok, .invalid_enum_value);
21091 }21307 }
...@@ -21101,7 +21317,8 @@ fn zirReify(...@@ -21101,7 +21317,8 @@ fn zirReify(
21101 extended: Zir.Inst.Extended.InstData,21317 extended: Zir.Inst.Extended.InstData,
21102 inst: Zir.Inst.Index,21318 inst: Zir.Inst.Index,
21103) CompileError!Air.Inst.Ref {21319) CompileError!Air.Inst.Ref {
21104 const mod = sema.mod;21320 const pt = sema.pt;
21321 const mod = pt.zcu;
21105 const gpa = sema.gpa;21322 const gpa = sema.gpa;
21106 const ip = &mod.intern_pool;21323 const ip = &mod.intern_pool;
21107 const name_strategy: Zir.Inst.NameStrategy = @enumFromInt(extended.small);21324 const name_strategy: Zir.Inst.NameStrategy = @enumFromInt(extended.small);
...@@ -21120,7 +21337,7 @@ fn zirReify(...@@ -21120,7 +21337,7 @@ fn zirReify(
21120 },21337 },
21121 },21338 },
21122 };21339 };
21123 const type_info_ty = try mod.getBuiltinType("Type");21340 const type_info_ty = try pt.getBuiltinType("Type");
21124 const uncasted_operand = try sema.resolveInst(extra.operand);21341 const uncasted_operand = try sema.resolveInst(extra.operand);
21125 const type_info = try sema.coerce(block, type_info_ty, uncasted_operand, operand_src);21342 const type_info = try sema.coerce(block, type_info_ty, uncasted_operand, operand_src);
21126 const val = try sema.resolveConstDefinedValue(block, operand_src, type_info, .{21343 const val = try sema.resolveConstDefinedValue(block, operand_src, type_info, .{
...@@ -21145,36 +21362,36 @@ fn zirReify(...@@ -21145,36 +21362,36 @@ fn zirReify(
21145 .Int => {21362 .Int => {
21146 const struct_type = ip.loadStructType(ip.typeOf(union_val.val));21363 const struct_type = ip.loadStructType(ip.typeOf(union_val.val));
21147 const signedness_val = try Value.fromInterned(union_val.val).fieldValue(21364 const signedness_val = try Value.fromInterned(union_val.val).fieldValue(
21148 mod,21365 pt,
21149 struct_type.nameIndex(ip, try ip.getOrPutString(gpa, "signedness", .no_embedded_nulls)).?,21366 struct_type.nameIndex(ip, try ip.getOrPutString(gpa, pt.tid, "signedness", .no_embedded_nulls)).?,
21150 );21367 );
21151 const bits_val = try Value.fromInterned(union_val.val).fieldValue(21368 const bits_val = try Value.fromInterned(union_val.val).fieldValue(
21152 mod,21369 pt,
21153 struct_type.nameIndex(ip, try ip.getOrPutString(gpa, "bits", .no_embedded_nulls)).?,21370 struct_type.nameIndex(ip, try ip.getOrPutString(gpa, pt.tid, "bits", .no_embedded_nulls)).?,
21154 );21371 );
2115521372
21156 const signedness = mod.toEnum(std.builtin.Signedness, signedness_val);21373 const signedness = mod.toEnum(std.builtin.Signedness, signedness_val);
21157 const bits: u16 = @intCast(try bits_val.toUnsignedIntSema(mod));21374 const bits: u16 = @intCast(try bits_val.toUnsignedIntSema(pt));
21158 const ty = try mod.intType(signedness, bits);21375 const ty = try pt.intType(signedness, bits);
21159 return Air.internedToRef(ty.toIntern());21376 return Air.internedToRef(ty.toIntern());
21160 },21377 },
21161 .Vector => {21378 .Vector => {
21162 const struct_type = ip.loadStructType(ip.typeOf(union_val.val));21379 const struct_type = ip.loadStructType(ip.typeOf(union_val.val));
21163 const len_val = try Value.fromInterned(union_val.val).fieldValue(mod, struct_type.nameIndex(21380 const len_val = try Value.fromInterned(union_val.val).fieldValue(pt, struct_type.nameIndex(
21164 ip,21381 ip,
21165 try ip.getOrPutString(gpa, "len", .no_embedded_nulls),21382 try ip.getOrPutString(gpa, pt.tid, "len", .no_embedded_nulls),
21166 ).?);21383 ).?);
21167 const child_val = try Value.fromInterned(union_val.val).fieldValue(mod, struct_type.nameIndex(21384 const child_val = try Value.fromInterned(union_val.val).fieldValue(pt, struct_type.nameIndex(
21168 ip,21385 ip,
21169 try ip.getOrPutString(gpa, "child", .no_embedded_nulls),21386 try ip.getOrPutString(gpa, pt.tid, "child", .no_embedded_nulls),
21170 ).?);21387 ).?);
2117121388
21172 const len: u32 = @intCast(try len_val.toUnsignedIntSema(mod));21389 const len: u32 = @intCast(try len_val.toUnsignedIntSema(pt));
21173 const child_ty = child_val.toType();21390 const child_ty = child_val.toType();
2117421391
21175 try sema.checkVectorElemType(block, src, child_ty);21392 try sema.checkVectorElemType(block, src, child_ty);
2117621393
21177 const ty = try mod.vectorType(.{21394 const ty = try pt.vectorType(.{
21178 .len = len,21395 .len = len,
21179 .child = child_ty.toIntern(),21396 .child = child_ty.toIntern(),
21180 });21397 });
...@@ -21182,12 +21399,12 @@ fn zirReify(...@@ -21182,12 +21399,12 @@ fn zirReify(
21182 },21399 },
21183 .Float => {21400 .Float => {
21184 const struct_type = ip.loadStructType(ip.typeOf(union_val.val));21401 const struct_type = ip.loadStructType(ip.typeOf(union_val.val));
21185 const bits_val = try Value.fromInterned(union_val.val).fieldValue(mod, struct_type.nameIndex(21402 const bits_val = try Value.fromInterned(union_val.val).fieldValue(pt, struct_type.nameIndex(
21186 ip,21403 ip,
21187 try ip.getOrPutString(gpa, "bits", .no_embedded_nulls),21404 try ip.getOrPutString(gpa, pt.tid, "bits", .no_embedded_nulls),
21188 ).?);21405 ).?);
2118921406
21190 const bits: u16 = @intCast(try bits_val.toUnsignedIntSema(mod));21407 const bits: u16 = @intCast(try bits_val.toUnsignedIntSema(pt));
21191 const ty = switch (bits) {21408 const ty = switch (bits) {
21192 16 => Type.f16,21409 16 => Type.f16,
21193 32 => Type.f32,21410 32 => Type.f32,
...@@ -21200,44 +21417,44 @@ fn zirReify(...@@ -21200,44 +21417,44 @@ fn zirReify(
21200 },21417 },
21201 .Pointer => {21418 .Pointer => {
21202 const struct_type = ip.loadStructType(ip.typeOf(union_val.val));21419 const struct_type = ip.loadStructType(ip.typeOf(union_val.val));
21203 const size_val = try Value.fromInterned(union_val.val).fieldValue(mod, struct_type.nameIndex(21420 const size_val = try Value.fromInterned(union_val.val).fieldValue(pt, struct_type.nameIndex(
21204 ip,21421 ip,
21205 try ip.getOrPutString(gpa, "size", .no_embedded_nulls),21422 try ip.getOrPutString(gpa, pt.tid, "size", .no_embedded_nulls),
21206 ).?);21423 ).?);
21207 const is_const_val = try Value.fromInterned(union_val.val).fieldValue(mod, struct_type.nameIndex(21424 const is_const_val = try Value.fromInterned(union_val.val).fieldValue(pt, struct_type.nameIndex(
21208 ip,21425 ip,
21209 try ip.getOrPutString(gpa, "is_const", .no_embedded_nulls),21426 try ip.getOrPutString(gpa, pt.tid, "is_const", .no_embedded_nulls),
21210 ).?);21427 ).?);
21211 const is_volatile_val = try Value.fromInterned(union_val.val).fieldValue(mod, struct_type.nameIndex(21428 const is_volatile_val = try Value.fromInterned(union_val.val).fieldValue(pt, struct_type.nameIndex(
21212 ip,21429 ip,
21213 try ip.getOrPutString(gpa, "is_volatile", .no_embedded_nulls),21430 try ip.getOrPutString(gpa, pt.tid, "is_volatile", .no_embedded_nulls),
21214 ).?);21431 ).?);
21215 const alignment_val = try Value.fromInterned(union_val.val).fieldValue(mod, struct_type.nameIndex(21432 const alignment_val = try Value.fromInterned(union_val.val).fieldValue(pt, struct_type.nameIndex(
21216 ip,21433 ip,
21217 try ip.getOrPutString(gpa, "alignment", .no_embedded_nulls),21434 try ip.getOrPutString(gpa, pt.tid, "alignment", .no_embedded_nulls),
21218 ).?);21435 ).?);
21219 const address_space_val = try Value.fromInterned(union_val.val).fieldValue(mod, struct_type.nameIndex(21436 const address_space_val = try Value.fromInterned(union_val.val).fieldValue(pt, struct_type.nameIndex(
21220 ip,21437 ip,
21221 try ip.getOrPutString(gpa, "address_space", .no_embedded_nulls),21438 try ip.getOrPutString(gpa, pt.tid, "address_space", .no_embedded_nulls),
21222 ).?);21439 ).?);
21223 const child_val = try Value.fromInterned(union_val.val).fieldValue(mod, struct_type.nameIndex(21440 const child_val = try Value.fromInterned(union_val.val).fieldValue(pt, struct_type.nameIndex(
21224 ip,21441 ip,
21225 try ip.getOrPutString(gpa, "child", .no_embedded_nulls),21442 try ip.getOrPutString(gpa, pt.tid, "child", .no_embedded_nulls),
21226 ).?);21443 ).?);
21227 const is_allowzero_val = try Value.fromInterned(union_val.val).fieldValue(mod, struct_type.nameIndex(21444 const is_allowzero_val = try Value.fromInterned(union_val.val).fieldValue(pt, struct_type.nameIndex(
21228 ip,21445 ip,
21229 try ip.getOrPutString(gpa, "is_allowzero", .no_embedded_nulls),21446 try ip.getOrPutString(gpa, pt.tid, "is_allowzero", .no_embedded_nulls),
21230 ).?);21447 ).?);
21231 const sentinel_val = try Value.fromInterned(union_val.val).fieldValue(mod, struct_type.nameIndex(21448 const sentinel_val = try Value.fromInterned(union_val.val).fieldValue(pt, struct_type.nameIndex(
21232 ip,21449 ip,
21233 try ip.getOrPutString(gpa, "sentinel", .no_embedded_nulls),21450 try ip.getOrPutString(gpa, pt.tid, "sentinel", .no_embedded_nulls),
21234 ).?);21451 ).?);
2123521452
21236 if (!try sema.intFitsInType(alignment_val, Type.u32, null)) {21453 if (!try sema.intFitsInType(alignment_val, Type.u32, null)) {
21237 return sema.fail(block, src, "alignment must fit in 'u32'", .{});21454 return sema.fail(block, src, "alignment must fit in 'u32'", .{});
21238 }21455 }
2123921456
21240 const alignment_val_int = (try alignment_val.getUnsignedIntAdvanced(mod, .sema)).?;21457 const alignment_val_int = (try alignment_val.getUnsignedIntAdvanced(pt, .sema)).?;
21241 if (alignment_val_int > 0 and !math.isPowerOfTwo(alignment_val_int)) {21458 if (alignment_val_int > 0 and !math.isPowerOfTwo(alignment_val_int)) {
21242 return sema.fail(block, src, "alignment value '{d}' is not a power of two or zero", .{alignment_val_int});21459 return sema.fail(block, src, "alignment value '{d}' is not a power of two or zero", .{alignment_val_int});
21243 }21460 }
...@@ -21245,7 +21462,7 @@ fn zirReify(...@@ -21245,7 +21462,7 @@ fn zirReify(
2124521462
21246 const elem_ty = child_val.toType();21463 const elem_ty = child_val.toType();
21247 if (abi_align != .none) {21464 if (abi_align != .none) {
21248 try elem_ty.resolveLayout(mod);21465 try elem_ty.resolveLayout(pt);
21249 }21466 }
2125021467
21251 const ptr_size = mod.toEnum(std.builtin.Type.Pointer.Size, size_val);21468 const ptr_size = mod.toEnum(std.builtin.Type.Pointer.Size, size_val);
...@@ -21256,7 +21473,7 @@ fn zirReify(...@@ -21256,7 +21473,7 @@ fn zirReify(
21256 return sema.fail(block, src, "sentinels are only allowed on slices and unknown-length pointers", .{});21473 return sema.fail(block, src, "sentinels are only allowed on slices and unknown-length pointers", .{});
21257 }21474 }
21258 const sentinel_ptr_val = sentinel_val.optionalValue(mod).?;21475 const sentinel_ptr_val = sentinel_val.optionalValue(mod).?;
21259 const ptr_ty = try mod.singleMutPtrType(elem_ty);21476 const ptr_ty = try pt.singleMutPtrType(elem_ty);
21260 const sent_val = (try sema.pointerDeref(block, src, sentinel_ptr_val, ptr_ty)).?;21477 const sent_val = (try sema.pointerDeref(block, src, sentinel_ptr_val, ptr_ty)).?;
21261 break :s sent_val.toIntern();21478 break :s sent_val.toIntern();
21262 }21479 }
...@@ -21274,7 +21491,7 @@ fn zirReify(...@@ -21274,7 +21491,7 @@ fn zirReify(
21274 } else if (ptr_size == .C) {21491 } else if (ptr_size == .C) {
21275 if (!try sema.validateExternType(elem_ty, .other)) {21492 if (!try sema.validateExternType(elem_ty, .other)) {
21276 const msg = msg: {21493 const msg = msg: {
21277 const msg = try sema.errMsg(src, "C pointers cannot point to non-C-ABI-compatible type '{}'", .{elem_ty.fmt(mod)});21494 const msg = try sema.errMsg(src, "C pointers cannot point to non-C-ABI-compatible type '{}'", .{elem_ty.fmt(pt)});
21278 errdefer msg.destroy(gpa);21495 errdefer msg.destroy(gpa);
2127921496
21280 try sema.explainWhyTypeIsNotExtern(msg, src, elem_ty, .other);21497 try sema.explainWhyTypeIsNotExtern(msg, src, elem_ty, .other);
...@@ -21289,7 +21506,7 @@ fn zirReify(...@@ -21289,7 +21506,7 @@ fn zirReify(
21289 }21506 }
21290 }21507 }
2129121508
21292 const ty = try mod.ptrTypeSema(.{21509 const ty = try pt.ptrTypeSema(.{
21293 .child = elem_ty.toIntern(),21510 .child = elem_ty.toIntern(),
21294 .sentinel = actual_sentinel,21511 .sentinel = actual_sentinel,
21295 .flags = .{21512 .flags = .{
...@@ -21305,27 +21522,27 @@ fn zirReify(...@@ -21305,27 +21522,27 @@ fn zirReify(
21305 },21522 },
21306 .Array => {21523 .Array => {
21307 const struct_type = ip.loadStructType(ip.typeOf(union_val.val));21524 const struct_type = ip.loadStructType(ip.typeOf(union_val.val));
21308 const len_val = try Value.fromInterned(union_val.val).fieldValue(mod, struct_type.nameIndex(21525 const len_val = try Value.fromInterned(union_val.val).fieldValue(pt, struct_type.nameIndex(
21309 ip,21526 ip,
21310 try ip.getOrPutString(gpa, "len", .no_embedded_nulls),21527 try ip.getOrPutString(gpa, pt.tid, "len", .no_embedded_nulls),
21311 ).?);21528 ).?);
21312 const child_val = try Value.fromInterned(union_val.val).fieldValue(mod, struct_type.nameIndex(21529 const child_val = try Value.fromInterned(union_val.val).fieldValue(pt, struct_type.nameIndex(
21313 ip,21530 ip,
21314 try ip.getOrPutString(gpa, "child", .no_embedded_nulls),21531 try ip.getOrPutString(gpa, pt.tid, "child", .no_embedded_nulls),
21315 ).?);21532 ).?);
21316 const sentinel_val = try Value.fromInterned(union_val.val).fieldValue(mod, struct_type.nameIndex(21533 const sentinel_val = try Value.fromInterned(union_val.val).fieldValue(pt, struct_type.nameIndex(
21317 ip,21534 ip,
21318 try ip.getOrPutString(gpa, "sentinel", .no_embedded_nulls),21535 try ip.getOrPutString(gpa, pt.tid, "sentinel", .no_embedded_nulls),
21319 ).?);21536 ).?);
2132021537
21321 const len = try len_val.toUnsignedIntSema(mod);21538 const len = try len_val.toUnsignedIntSema(pt);
21322 const child_ty = child_val.toType();21539 const child_ty = child_val.toType();
21323 const sentinel = if (sentinel_val.optionalValue(mod)) |p| blk: {21540 const sentinel = if (sentinel_val.optionalValue(mod)) |p| blk: {
21324 const ptr_ty = try mod.singleMutPtrType(child_ty);21541 const ptr_ty = try pt.singleMutPtrType(child_ty);
21325 break :blk (try sema.pointerDeref(block, src, p, ptr_ty)).?;21542 break :blk (try sema.pointerDeref(block, src, p, ptr_ty)).?;
21326 } else null;21543 } else null;
2132721544
21328 const ty = try mod.arrayType(.{21545 const ty = try pt.arrayType(.{
21329 .len = len,21546 .len = len,
21330 .sentinel = if (sentinel) |s| s.toIntern() else .none,21547 .sentinel = if (sentinel) |s| s.toIntern() else .none,
21331 .child = child_ty.toIntern(),21548 .child = child_ty.toIntern(),
...@@ -21334,25 +21551,25 @@ fn zirReify(...@@ -21334,25 +21551,25 @@ fn zirReify(
21334 },21551 },
21335 .Optional => {21552 .Optional => {
21336 const struct_type = ip.loadStructType(ip.typeOf(union_val.val));21553 const struct_type = ip.loadStructType(ip.typeOf(union_val.val));
21337 const child_val = try Value.fromInterned(union_val.val).fieldValue(mod, struct_type.nameIndex(21554 const child_val = try Value.fromInterned(union_val.val).fieldValue(pt, struct_type.nameIndex(
21338 ip,21555 ip,
21339 try ip.getOrPutString(gpa, "child", .no_embedded_nulls),21556 try ip.getOrPutString(gpa, pt.tid, "child", .no_embedded_nulls),
21340 ).?);21557 ).?);
2134121558
21342 const child_ty = child_val.toType();21559 const child_ty = child_val.toType();
2134321560
21344 const ty = try mod.optionalType(child_ty.toIntern());21561 const ty = try pt.optionalType(child_ty.toIntern());
21345 return Air.internedToRef(ty.toIntern());21562 return Air.internedToRef(ty.toIntern());
21346 },21563 },
21347 .ErrorUnion => {21564 .ErrorUnion => {
21348 const struct_type = ip.loadStructType(ip.typeOf(union_val.val));21565 const struct_type = ip.loadStructType(ip.typeOf(union_val.val));
21349 const error_set_val = try Value.fromInterned(union_val.val).fieldValue(mod, struct_type.nameIndex(21566 const error_set_val = try Value.fromInterned(union_val.val).fieldValue(pt, struct_type.nameIndex(
21350 ip,21567 ip,
21351 try ip.getOrPutString(gpa, "error_set", .no_embedded_nulls),21568 try ip.getOrPutString(gpa, pt.tid, "error_set", .no_embedded_nulls),
21352 ).?);21569 ).?);
21353 const payload_val = try Value.fromInterned(union_val.val).fieldValue(mod, struct_type.nameIndex(21570 const payload_val = try Value.fromInterned(union_val.val).fieldValue(pt, struct_type.nameIndex(
21354 ip,21571 ip,
21355 try ip.getOrPutString(gpa, "payload", .no_embedded_nulls),21572 try ip.getOrPutString(gpa, pt.tid, "payload", .no_embedded_nulls),
21356 ).?);21573 ).?);
2135721574
21358 const error_set_ty = error_set_val.toType();21575 const error_set_ty = error_set_val.toType();
...@@ -21362,7 +21579,7 @@ fn zirReify(...@@ -21362,7 +21579,7 @@ fn zirReify(
21362 return sema.fail(block, src, "Type.ErrorUnion.error_set must be an error set type", .{});21579 return sema.fail(block, src, "Type.ErrorUnion.error_set must be an error set type", .{});
21363 }21580 }
2136421581
21365 const ty = try mod.errorUnionType(error_set_ty, payload_ty);21582 const ty = try pt.errorUnionType(error_set_ty, payload_ty);
21366 return Air.internedToRef(ty.toIntern());21583 return Air.internedToRef(ty.toIntern());
21367 },21584 },
21368 .ErrorSet => {21585 .ErrorSet => {
...@@ -21377,11 +21594,11 @@ fn zirReify(...@@ -21377,11 +21594,11 @@ fn zirReify(
21377 var names: InferredErrorSet.NameMap = .{};21594 var names: InferredErrorSet.NameMap = .{};
21378 try names.ensureUnusedCapacity(sema.arena, len);21595 try names.ensureUnusedCapacity(sema.arena, len);
21379 for (0..len) |i| {21596 for (0..len) |i| {
21380 const elem_val = try names_val.elemValue(mod, i);21597 const elem_val = try names_val.elemValue(pt, i);
21381 const elem_struct_type = ip.loadStructType(ip.typeOf(elem_val.toIntern()));21598 const elem_struct_type = ip.loadStructType(ip.typeOf(elem_val.toIntern()));
21382 const name_val = try elem_val.fieldValue(mod, elem_struct_type.nameIndex(21599 const name_val = try elem_val.fieldValue(pt, elem_struct_type.nameIndex(
21383 ip,21600 ip,
21384 try ip.getOrPutString(gpa, "name", .no_embedded_nulls),21601 try ip.getOrPutString(gpa, pt.tid, "name", .no_embedded_nulls),
21385 ).?);21602 ).?);
2138621603
21387 const name = try sema.sliceToIpString(block, src, name_val, .{21604 const name = try sema.sliceToIpString(block, src, name_val, .{
...@@ -21396,36 +21613,36 @@ fn zirReify(...@@ -21396,36 +21613,36 @@ fn zirReify(
21396 }21613 }
21397 }21614 }
2139821615
21399 const ty = try mod.errorSetFromUnsortedNames(names.keys());21616 const ty = try pt.errorSetFromUnsortedNames(names.keys());
21400 return Air.internedToRef(ty.toIntern());21617 return Air.internedToRef(ty.toIntern());
21401 },21618 },
21402 .Struct => {21619 .Struct => {
21403 const struct_type = ip.loadStructType(ip.typeOf(union_val.val));21620 const struct_type = ip.loadStructType(ip.typeOf(union_val.val));
21404 const layout_val = try Value.fromInterned(union_val.val).fieldValue(mod, struct_type.nameIndex(21621 const layout_val = try Value.fromInterned(union_val.val).fieldValue(pt, struct_type.nameIndex(
21405 ip,21622 ip,
21406 try ip.getOrPutString(gpa, "layout", .no_embedded_nulls),21623 try ip.getOrPutString(gpa, pt.tid, "layout", .no_embedded_nulls),
21407 ).?);21624 ).?);
21408 const backing_integer_val = try Value.fromInterned(union_val.val).fieldValue(mod, struct_type.nameIndex(21625 const backing_integer_val = try Value.fromInterned(union_val.val).fieldValue(pt, struct_type.nameIndex(
21409 ip,21626 ip,
21410 try ip.getOrPutString(gpa, "backing_integer", .no_embedded_nulls),21627 try ip.getOrPutString(gpa, pt.tid, "backing_integer", .no_embedded_nulls),
21411 ).?);21628 ).?);
21412 const fields_val = try Value.fromInterned(union_val.val).fieldValue(mod, struct_type.nameIndex(21629 const fields_val = try Value.fromInterned(union_val.val).fieldValue(pt, struct_type.nameIndex(
21413 ip,21630 ip,
21414 try ip.getOrPutString(gpa, "fields", .no_embedded_nulls),21631 try ip.getOrPutString(gpa, pt.tid, "fields", .no_embedded_nulls),
21415 ).?);21632 ).?);
21416 const decls_val = try Value.fromInterned(union_val.val).fieldValue(mod, struct_type.nameIndex(21633 const decls_val = try Value.fromInterned(union_val.val).fieldValue(pt, struct_type.nameIndex(
21417 ip,21634 ip,
21418 try ip.getOrPutString(gpa, "decls", .no_embedded_nulls),21635 try ip.getOrPutString(gpa, pt.tid, "decls", .no_embedded_nulls),
21419 ).?);21636 ).?);
21420 const is_tuple_val = try Value.fromInterned(union_val.val).fieldValue(mod, struct_type.nameIndex(21637 const is_tuple_val = try Value.fromInterned(union_val.val).fieldValue(pt, struct_type.nameIndex(
21421 ip,21638 ip,
21422 try ip.getOrPutString(gpa, "is_tuple", .no_embedded_nulls),21639 try ip.getOrPutString(gpa, pt.tid, "is_tuple", .no_embedded_nulls),
21423 ).?);21640 ).?);
2142421641
21425 const layout = mod.toEnum(std.builtin.Type.ContainerLayout, layout_val);21642 const layout = mod.toEnum(std.builtin.Type.ContainerLayout, layout_val);
2142621643
21427 // Decls21644 // Decls
21428 if (try decls_val.sliceLen(mod) > 0) {21645 if (try decls_val.sliceLen(pt) > 0) {
21429 return sema.fail(block, src, "reified structs must have no decls", .{});21646 return sema.fail(block, src, "reified structs must have no decls", .{});
21430 }21647 }
2143121648
...@@ -21441,24 +21658,24 @@ fn zirReify(...@@ -21441,24 +21658,24 @@ fn zirReify(
21441 },21658 },
21442 .Enum => {21659 .Enum => {
21443 const struct_type = ip.loadStructType(ip.typeOf(union_val.val));21660 const struct_type = ip.loadStructType(ip.typeOf(union_val.val));
21444 const tag_type_val = try Value.fromInterned(union_val.val).fieldValue(mod, struct_type.nameIndex(21661 const tag_type_val = try Value.fromInterned(union_val.val).fieldValue(pt, struct_type.nameIndex(
21445 ip,21662 ip,
21446 try ip.getOrPutString(gpa, "tag_type", .no_embedded_nulls),21663 try ip.getOrPutString(gpa, pt.tid, "tag_type", .no_embedded_nulls),
21447 ).?);21664 ).?);
21448 const fields_val = try Value.fromInterned(union_val.val).fieldValue(mod, struct_type.nameIndex(21665 const fields_val = try Value.fromInterned(union_val.val).fieldValue(pt, struct_type.nameIndex(
21449 ip,21666 ip,
21450 try ip.getOrPutString(gpa, "fields", .no_embedded_nulls),21667 try ip.getOrPutString(gpa, pt.tid, "fields", .no_embedded_nulls),
21451 ).?);21668 ).?);
21452 const decls_val = try Value.fromInterned(union_val.val).fieldValue(mod, struct_type.nameIndex(21669 const decls_val = try Value.fromInterned(union_val.val).fieldValue(pt, struct_type.nameIndex(
21453 ip,21670 ip,
21454 try ip.getOrPutString(gpa, "decls", .no_embedded_nulls),21671 try ip.getOrPutString(gpa, pt.tid, "decls", .no_embedded_nulls),
21455 ).?);21672 ).?);
21456 const is_exhaustive_val = try Value.fromInterned(union_val.val).fieldValue(mod, struct_type.nameIndex(21673 const is_exhaustive_val = try Value.fromInterned(union_val.val).fieldValue(pt, struct_type.nameIndex(
21457 ip,21674 ip,
21458 try ip.getOrPutString(gpa, "is_exhaustive", .no_embedded_nulls),21675 try ip.getOrPutString(gpa, pt.tid, "is_exhaustive", .no_embedded_nulls),
21459 ).?);21676 ).?);
2146021677
21461 if (try decls_val.sliceLen(mod) > 0) {21678 if (try decls_val.sliceLen(pt) > 0) {
21462 return sema.fail(block, src, "reified enums must have no decls", .{});21679 return sema.fail(block, src, "reified enums must have no decls", .{});
21463 }21680 }
2146421681
...@@ -21470,17 +21687,17 @@ fn zirReify(...@@ -21470,17 +21687,17 @@ fn zirReify(
21470 },21687 },
21471 .Opaque => {21688 .Opaque => {
21472 const struct_type = ip.loadStructType(ip.typeOf(union_val.val));21689 const struct_type = ip.loadStructType(ip.typeOf(union_val.val));
21473 const decls_val = try Value.fromInterned(union_val.val).fieldValue(mod, struct_type.nameIndex(21690 const decls_val = try Value.fromInterned(union_val.val).fieldValue(pt, struct_type.nameIndex(
21474 ip,21691 ip,
21475 try ip.getOrPutString(gpa, "decls", .no_embedded_nulls),21692 try ip.getOrPutString(gpa, pt.tid, "decls", .no_embedded_nulls),
21476 ).?);21693 ).?);
2147721694
21478 // Decls21695 // Decls
21479 if (try decls_val.sliceLen(mod) > 0) {21696 if (try decls_val.sliceLen(pt) > 0) {
21480 return sema.fail(block, src, "reified opaque must have no decls", .{});21697 return sema.fail(block, src, "reified opaque must have no decls", .{});
21481 }21698 }
2148221699
21483 const wip_ty = switch (try ip.getOpaqueType(gpa, .{21700 const wip_ty = switch (try ip.getOpaqueType(gpa, pt.tid, .{
21484 .has_namespace = false,21701 .has_namespace = false,
21485 .key = .{ .reified = .{21702 .key = .{ .reified = .{
21486 .zir_index = try block.trackZir(inst),21703 .zir_index = try block.trackZir(inst),
...@@ -21489,7 +21706,7 @@ fn zirReify(...@@ -21489,7 +21706,7 @@ fn zirReify(
21489 .existing => |ty| return Air.internedToRef(ty),21706 .existing => |ty| return Air.internedToRef(ty),
21490 .wip => |wip| wip,21707 .wip => |wip| wip,
21491 };21708 };
21492 errdefer wip_ty.cancel(ip);21709 errdefer wip_ty.cancel(ip, pt.tid);
2149321710
21494 const new_decl_index = try sema.createAnonymousDeclTypeNamed(21711 const new_decl_index = try sema.createAnonymousDeclTypeNamed(
21495 block,21712 block,
...@@ -21501,30 +21718,30 @@ fn zirReify(...@@ -21501,30 +21718,30 @@ fn zirReify(
21501 mod.declPtr(new_decl_index).owns_tv = true;21718 mod.declPtr(new_decl_index).owns_tv = true;
21502 errdefer mod.abortAnonDecl(new_decl_index);21719 errdefer mod.abortAnonDecl(new_decl_index);
2150321720
21504 try mod.finalizeAnonDecl(new_decl_index);21721 try pt.finalizeAnonDecl(new_decl_index);
2150521722
21506 return Air.internedToRef(wip_ty.finish(ip, new_decl_index, .none));21723 return Air.internedToRef(wip_ty.finish(ip, new_decl_index, .none));
21507 },21724 },
21508 .Union => {21725 .Union => {
21509 const struct_type = ip.loadStructType(ip.typeOf(union_val.val));21726 const struct_type = ip.loadStructType(ip.typeOf(union_val.val));
21510 const layout_val = try Value.fromInterned(union_val.val).fieldValue(mod, struct_type.nameIndex(21727 const layout_val = try Value.fromInterned(union_val.val).fieldValue(pt, struct_type.nameIndex(
21511 ip,21728 ip,
21512 try ip.getOrPutString(gpa, "layout", .no_embedded_nulls),21729 try ip.getOrPutString(gpa, pt.tid, "layout", .no_embedded_nulls),
21513 ).?);21730 ).?);
21514 const tag_type_val = try Value.fromInterned(union_val.val).fieldValue(mod, struct_type.nameIndex(21731 const tag_type_val = try Value.fromInterned(union_val.val).fieldValue(pt, struct_type.nameIndex(
21515 ip,21732 ip,
21516 try ip.getOrPutString(gpa, "tag_type", .no_embedded_nulls),21733 try ip.getOrPutString(gpa, pt.tid, "tag_type", .no_embedded_nulls),
21517 ).?);21734 ).?);
21518 const fields_val = try Value.fromInterned(union_val.val).fieldValue(mod, struct_type.nameIndex(21735 const fields_val = try Value.fromInterned(union_val.val).fieldValue(pt, struct_type.nameIndex(
21519 ip,21736 ip,
21520 try ip.getOrPutString(gpa, "fields", .no_embedded_nulls),21737 try ip.getOrPutString(gpa, pt.tid, "fields", .no_embedded_nulls),
21521 ).?);21738 ).?);
21522 const decls_val = try Value.fromInterned(union_val.val).fieldValue(mod, struct_type.nameIndex(21739 const decls_val = try Value.fromInterned(union_val.val).fieldValue(pt, struct_type.nameIndex(
21523 ip,21740 ip,
21524 try ip.getOrPutString(gpa, "decls", .no_embedded_nulls),21741 try ip.getOrPutString(gpa, pt.tid, "decls", .no_embedded_nulls),
21525 ).?);21742 ).?);
2152621743
21527 if (try decls_val.sliceLen(mod) > 0) {21744 if (try decls_val.sliceLen(pt) > 0) {
21528 return sema.fail(block, src, "reified unions must have no decls", .{});21745 return sema.fail(block, src, "reified unions must have no decls", .{});
21529 }21746 }
21530 const layout = mod.toEnum(std.builtin.Type.ContainerLayout, layout_val);21747 const layout = mod.toEnum(std.builtin.Type.ContainerLayout, layout_val);
...@@ -21537,25 +21754,25 @@ fn zirReify(...@@ -21537,25 +21754,25 @@ fn zirReify(
21537 },21754 },
21538 .Fn => {21755 .Fn => {
21539 const struct_type = ip.loadStructType(ip.typeOf(union_val.val));21756 const struct_type = ip.loadStructType(ip.typeOf(union_val.val));
21540 const calling_convention_val = try Value.fromInterned(union_val.val).fieldValue(mod, struct_type.nameIndex(21757 const calling_convention_val = try Value.fromInterned(union_val.val).fieldValue(pt, struct_type.nameIndex(
21541 ip,21758 ip,
21542 try ip.getOrPutString(gpa, "calling_convention", .no_embedded_nulls),21759 try ip.getOrPutString(gpa, pt.tid, "calling_convention", .no_embedded_nulls),
21543 ).?);21760 ).?);
21544 const is_generic_val = try Value.fromInterned(union_val.val).fieldValue(mod, struct_type.nameIndex(21761 const is_generic_val = try Value.fromInterned(union_val.val).fieldValue(pt, struct_type.nameIndex(
21545 ip,21762 ip,
21546 try ip.getOrPutString(gpa, "is_generic", .no_embedded_nulls),21763 try ip.getOrPutString(gpa, pt.tid, "is_generic", .no_embedded_nulls),
21547 ).?);21764 ).?);
21548 const is_var_args_val = try Value.fromInterned(union_val.val).fieldValue(mod, struct_type.nameIndex(21765 const is_var_args_val = try Value.fromInterned(union_val.val).fieldValue(pt, struct_type.nameIndex(
21549 ip,21766 ip,
21550 try ip.getOrPutString(gpa, "is_var_args", .no_embedded_nulls),21767 try ip.getOrPutString(gpa, pt.tid, "is_var_args", .no_embedded_nulls),
21551 ).?);21768 ).?);
21552 const return_type_val = try Value.fromInterned(union_val.val).fieldValue(mod, struct_type.nameIndex(21769 const return_type_val = try Value.fromInterned(union_val.val).fieldValue(pt, struct_type.nameIndex(
21553 ip,21770 ip,
21554 try ip.getOrPutString(gpa, "return_type", .no_embedded_nulls),21771 try ip.getOrPutString(gpa, pt.tid, "return_type", .no_embedded_nulls),
21555 ).?);21772 ).?);
21556 const params_slice_val = try Value.fromInterned(union_val.val).fieldValue(mod, struct_type.nameIndex(21773 const params_slice_val = try Value.fromInterned(union_val.val).fieldValue(pt, struct_type.nameIndex(
21557 ip,21774 ip,
21558 try ip.getOrPutString(gpa, "params", .no_embedded_nulls),21775 try ip.getOrPutString(gpa, pt.tid, "params", .no_embedded_nulls),
21559 ).?);21776 ).?);
2156021777
21561 const is_generic = is_generic_val.toBool();21778 const is_generic = is_generic_val.toBool();
...@@ -21581,19 +21798,19 @@ fn zirReify(...@@ -21581,19 +21798,19 @@ fn zirReify(
2158121798
21582 var noalias_bits: u32 = 0;21799 var noalias_bits: u32 = 0;
21583 for (param_types, 0..) |*param_type, i| {21800 for (param_types, 0..) |*param_type, i| {
21584 const elem_val = try params_val.elemValue(mod, i);21801 const elem_val = try params_val.elemValue(pt, i);
21585 const elem_struct_type = ip.loadStructType(ip.typeOf(elem_val.toIntern()));21802 const elem_struct_type = ip.loadStructType(ip.typeOf(elem_val.toIntern()));
21586 const param_is_generic_val = try elem_val.fieldValue(mod, elem_struct_type.nameIndex(21803 const param_is_generic_val = try elem_val.fieldValue(pt, elem_struct_type.nameIndex(
21587 ip,21804 ip,
21588 try ip.getOrPutString(gpa, "is_generic", .no_embedded_nulls),21805 try ip.getOrPutString(gpa, pt.tid, "is_generic", .no_embedded_nulls),
21589 ).?);21806 ).?);
21590 const param_is_noalias_val = try elem_val.fieldValue(mod, elem_struct_type.nameIndex(21807 const param_is_noalias_val = try elem_val.fieldValue(pt, elem_struct_type.nameIndex(
21591 ip,21808 ip,
21592 try ip.getOrPutString(gpa, "is_noalias", .no_embedded_nulls),21809 try ip.getOrPutString(gpa, pt.tid, "is_noalias", .no_embedded_nulls),
21593 ).?);21810 ).?);
21594 const opt_param_type_val = try elem_val.fieldValue(mod, elem_struct_type.nameIndex(21811 const opt_param_type_val = try elem_val.fieldValue(pt, elem_struct_type.nameIndex(
21595 ip,21812 ip,
21596 try ip.getOrPutString(gpa, "type", .no_embedded_nulls),21813 try ip.getOrPutString(gpa, pt.tid, "type", .no_embedded_nulls),
21597 ).?);21814 ).?);
2159821815
21599 if (param_is_generic_val.toBool()) {21816 if (param_is_generic_val.toBool()) {
...@@ -21613,7 +21830,7 @@ fn zirReify(...@@ -21613,7 +21830,7 @@ fn zirReify(
21613 }21830 }
21614 }21831 }
2161521832
21616 const ty = try mod.funcType(.{21833 const ty = try pt.funcType(.{
21617 .param_types = param_types,21834 .param_types = param_types,
21618 .noalias_bits = noalias_bits,21835 .noalias_bits = noalias_bits,
21619 .return_type = return_type.toIntern(),21836 .return_type = return_type.toIntern(),
...@@ -21636,7 +21853,8 @@ fn reifyEnum(...@@ -21636,7 +21853,8 @@ fn reifyEnum(
21636 fields_val: Value,21853 fields_val: Value,
21637 name_strategy: Zir.Inst.NameStrategy,21854 name_strategy: Zir.Inst.NameStrategy,
21638) CompileError!Air.Inst.Ref {21855) CompileError!Air.Inst.Ref {
21639 const mod = sema.mod;21856 const pt = sema.pt;
21857 const mod = pt.zcu;
21640 const gpa = sema.gpa;21858 const gpa = sema.gpa;
21641 const ip = &mod.intern_pool;21859 const ip = &mod.intern_pool;
2164221860
...@@ -21656,10 +21874,10 @@ fn reifyEnum(...@@ -21656,10 +21874,10 @@ fn reifyEnum(
21656 std.hash.autoHash(&hasher, fields_len);21874 std.hash.autoHash(&hasher, fields_len);
2165721875
21658 for (0..fields_len) |field_idx| {21876 for (0..fields_len) |field_idx| {
21659 const field_info = try fields_val.elemValue(mod, field_idx);21877 const field_info = try fields_val.elemValue(pt, field_idx);
2166021878
21661 const field_name_val = try field_info.fieldValue(mod, 0);21879 const field_name_val = try field_info.fieldValue(pt, 0);
21662 const field_value_val = try sema.resolveLazyValue(try field_info.fieldValue(mod, 1));21880 const field_value_val = try sema.resolveLazyValue(try field_info.fieldValue(pt, 1));
2166321881
21664 const field_name = try sema.sliceToIpString(block, src, field_name_val, .{21882 const field_name = try sema.sliceToIpString(block, src, field_name_val, .{
21665 .needed_comptime_reason = "enum field name must be comptime-known",21883 .needed_comptime_reason = "enum field name must be comptime-known",
...@@ -21671,7 +21889,7 @@ fn reifyEnum(...@@ -21671,7 +21889,7 @@ fn reifyEnum(
21671 });21889 });
21672 }21890 }
2167321891
21674 const wip_ty = switch (try ip.getEnumType(gpa, .{21892 const wip_ty = switch (try ip.getEnumType(gpa, pt.tid, .{
21675 .has_namespace = false,21893 .has_namespace = false,
21676 .has_values = true,21894 .has_values = true,
21677 .tag_mode = if (is_exhaustive) .explicit else .nonexhaustive,21895 .tag_mode = if (is_exhaustive) .explicit else .nonexhaustive,
...@@ -21684,7 +21902,7 @@ fn reifyEnum(...@@ -21684,7 +21902,7 @@ fn reifyEnum(
21684 .wip => |wip| wip,21902 .wip => |wip| wip,
21685 .existing => |ty| return Air.internedToRef(ty),21903 .existing => |ty| return Air.internedToRef(ty),
21686 };21904 };
21687 errdefer wip_ty.cancel(ip);21905 errdefer wip_ty.cancel(ip, pt.tid);
2168821906
21689 if (tag_ty.zigTypeTag(mod) != .Int) {21907 if (tag_ty.zigTypeTag(mod) != .Int) {
21690 return sema.fail(block, src, "Type.Enum.tag_type must be an integer type", .{});21908 return sema.fail(block, src, "Type.Enum.tag_type must be an integer type", .{});
...@@ -21704,10 +21922,10 @@ fn reifyEnum(...@@ -21704,10 +21922,10 @@ fn reifyEnum(
21704 wip_ty.setTagTy(ip, tag_ty.toIntern());21922 wip_ty.setTagTy(ip, tag_ty.toIntern());
2170521923
21706 for (0..fields_len) |field_idx| {21924 for (0..fields_len) |field_idx| {
21707 const field_info = try fields_val.elemValue(mod, field_idx);21925 const field_info = try fields_val.elemValue(pt, field_idx);
2170821926
21709 const field_name_val = try field_info.fieldValue(mod, 0);21927 const field_name_val = try field_info.fieldValue(pt, 0);
21710 const field_value_val = try sema.resolveLazyValue(try field_info.fieldValue(mod, 1));21928 const field_value_val = try sema.resolveLazyValue(try field_info.fieldValue(pt, 1));
2171121929
21712 // Don't pass a reason; first loop acts as an assertion that this is valid.21930 // Don't pass a reason; first loop acts as an assertion that this is valid.
21713 const field_name = try sema.sliceToIpString(block, src, field_name_val, undefined);21931 const field_name = try sema.sliceToIpString(block, src, field_name_val, undefined);
...@@ -21716,12 +21934,12 @@ fn reifyEnum(...@@ -21716,12 +21934,12 @@ fn reifyEnum(
21716 // TODO: better source location21934 // TODO: better source location
21717 return sema.fail(block, src, "field '{}' with enumeration value '{}' is too large for backing int type '{}'", .{21935 return sema.fail(block, src, "field '{}' with enumeration value '{}' is too large for backing int type '{}'", .{
21718 field_name.fmt(ip),21936 field_name.fmt(ip),
21719 field_value_val.fmtValue(mod, sema),21937 field_value_val.fmtValue(pt, sema),
21720 tag_ty.fmt(mod),21938 tag_ty.fmt(pt),
21721 });21939 });
21722 }21940 }
2172321941
21724 const coerced_field_val = try mod.getCoerced(field_value_val, tag_ty);21942 const coerced_field_val = try pt.getCoerced(field_value_val, tag_ty);
21725 if (wip_ty.nextField(ip, field_name, coerced_field_val.toIntern())) |conflict| {21943 if (wip_ty.nextField(ip, field_name, coerced_field_val.toIntern())) |conflict| {
21726 return sema.failWithOwnedErrorMsg(block, switch (conflict.kind) {21944 return sema.failWithOwnedErrorMsg(block, switch (conflict.kind) {
21727 .name => msg: {21945 .name => msg: {
...@@ -21732,7 +21950,7 @@ fn reifyEnum(...@@ -21732,7 +21950,7 @@ fn reifyEnum(
21732 break :msg msg;21950 break :msg msg;
21733 },21951 },
21734 .value => msg: {21952 .value => msg: {
21735 const msg = try sema.errMsg(src, "enum tag value {} already taken", .{field_value_val.fmtValue(mod, sema)});21953 const msg = try sema.errMsg(src, "enum tag value {} already taken", .{field_value_val.fmtValue(pt, sema)});
21736 errdefer msg.destroy(gpa);21954 errdefer msg.destroy(gpa);
21737 _ = conflict.prev_field_idx; // TODO: this note is incorrect21955 _ = conflict.prev_field_idx; // TODO: this note is incorrect
21738 try sema.errNote(src, msg, "other enum tag value here", .{});21956 try sema.errNote(src, msg, "other enum tag value here", .{});
...@@ -21742,11 +21960,11 @@ fn reifyEnum(...@@ -21742,11 +21960,11 @@ fn reifyEnum(
21742 }21960 }
21743 }21961 }
2174421962
21745 if (!is_exhaustive and fields_len > 1 and std.math.log2_int(u64, fields_len) == tag_ty.bitSize(mod)) {21963 if (!is_exhaustive and fields_len > 1 and std.math.log2_int(u64, fields_len) == tag_ty.bitSize(pt)) {
21746 return sema.fail(block, src, "non-exhaustive enum specified every value", .{});21964 return sema.fail(block, src, "non-exhaustive enum specified every value", .{});
21747 }21965 }
2174821966
21749 try mod.finalizeAnonDecl(new_decl_index);21967 try pt.finalizeAnonDecl(new_decl_index);
21750 return Air.internedToRef(wip_ty.index);21968 return Air.internedToRef(wip_ty.index);
21751}21969}
2175221970
...@@ -21760,7 +21978,8 @@ fn reifyUnion(...@@ -21760,7 +21978,8 @@ fn reifyUnion(
21760 fields_val: Value,21978 fields_val: Value,
21761 name_strategy: Zir.Inst.NameStrategy,21979 name_strategy: Zir.Inst.NameStrategy,
21762) CompileError!Air.Inst.Ref {21980) CompileError!Air.Inst.Ref {
21763 const mod = sema.mod;21981 const pt = sema.pt;
21982 const mod = pt.zcu;
21764 const gpa = sema.gpa;21983 const gpa = sema.gpa;
21765 const ip = &mod.intern_pool;21984 const ip = &mod.intern_pool;
2176621985
...@@ -21782,11 +22001,11 @@ fn reifyUnion(...@@ -21782,11 +22001,11 @@ fn reifyUnion(
21782 var any_aligns = false;22001 var any_aligns = false;
2178322002
21784 for (0..fields_len) |field_idx| {22003 for (0..fields_len) |field_idx| {
21785 const field_info = try fields_val.elemValue(mod, field_idx);22004 const field_info = try fields_val.elemValue(pt, field_idx);
2178622005
21787 const field_name_val = try field_info.fieldValue(mod, 0);22006 const field_name_val = try field_info.fieldValue(pt, 0);
21788 const field_type_val = try field_info.fieldValue(mod, 1);22007 const field_type_val = try field_info.fieldValue(pt, 1);
21789 const field_align_val = try sema.resolveLazyValue(try field_info.fieldValue(mod, 2));22008 const field_align_val = try sema.resolveLazyValue(try field_info.fieldValue(pt, 2));
2179022009
21791 const field_name = try sema.sliceToIpString(block, src, field_name_val, .{22010 const field_name = try sema.sliceToIpString(block, src, field_name_val, .{
21792 .needed_comptime_reason = "union field name must be comptime-known",22011 .needed_comptime_reason = "union field name must be comptime-known",
...@@ -21798,12 +22017,12 @@ fn reifyUnion(...@@ -21798,12 +22017,12 @@ fn reifyUnion(
21798 field_align_val.toIntern(),22017 field_align_val.toIntern(),
21799 });22018 });
2180022019
21801 if (field_align_val.toUnsignedInt(mod) != 0) {22020 if (field_align_val.toUnsignedInt(pt) != 0) {
21802 any_aligns = true;22021 any_aligns = true;
21803 }22022 }
21804 }22023 }
2180522024
21806 const wip_ty = switch (try ip.getUnionType(gpa, .{22025 const wip_ty = switch (try ip.getUnionType(gpa, pt.tid, .{
21807 .flags = .{22026 .flags = .{
21808 .layout = layout,22027 .layout = layout,
21809 .status = .none,22028 .status = .none,
...@@ -21834,7 +22053,7 @@ fn reifyUnion(...@@ -21834,7 +22053,7 @@ fn reifyUnion(
21834 .wip => |wip| wip,22053 .wip => |wip| wip,
21835 .existing => |ty| return Air.internedToRef(ty),22054 .existing => |ty| return Air.internedToRef(ty),
21836 };22055 };
21837 errdefer wip_ty.cancel(ip);22056 errdefer wip_ty.cancel(ip, pt.tid);
2183822057
21839 const new_decl_index = try sema.createAnonymousDeclTypeNamed(22058 const new_decl_index = try sema.createAnonymousDeclTypeNamed(
21840 block,22059 block,
...@@ -21861,10 +22080,10 @@ fn reifyUnion(...@@ -21861,10 +22080,10 @@ fn reifyUnion(
21861 var seen_tags = try std.DynamicBitSetUnmanaged.initEmpty(sema.arena, tag_ty_fields_len);22080 var seen_tags = try std.DynamicBitSetUnmanaged.initEmpty(sema.arena, tag_ty_fields_len);
2186222081
21863 for (field_types, 0..) |*field_ty, field_idx| {22082 for (field_types, 0..) |*field_ty, field_idx| {
21864 const field_info = try fields_val.elemValue(mod, field_idx);22083 const field_info = try fields_val.elemValue(pt, field_idx);
2186522084
21866 const field_name_val = try field_info.fieldValue(mod, 0);22085 const field_name_val = try field_info.fieldValue(pt, 0);
21867 const field_type_val = try field_info.fieldValue(mod, 1);22086 const field_type_val = try field_info.fieldValue(pt, 1);
2186822087
21869 // Don't pass a reason; first loop acts as an assertion that this is valid.22088 // Don't pass a reason; first loop acts as an assertion that this is valid.
21870 const field_name = try sema.sliceToIpString(block, src, field_name_val, undefined);22089 const field_name = try sema.sliceToIpString(block, src, field_name_val, undefined);
...@@ -21872,7 +22091,7 @@ fn reifyUnion(...@@ -21872,7 +22091,7 @@ fn reifyUnion(
21872 const enum_index = enum_tag_ty.enumFieldIndex(field_name, mod) orelse {22091 const enum_index = enum_tag_ty.enumFieldIndex(field_name, mod) orelse {
21873 // TODO: better source location22092 // TODO: better source location
21874 return sema.fail(block, src, "no field named '{}' in enum '{}'", .{22093 return sema.fail(block, src, "no field named '{}' in enum '{}'", .{
21875 field_name.fmt(ip), enum_tag_ty.fmt(mod),22094 field_name.fmt(ip), enum_tag_ty.fmt(pt),
21876 });22095 });
21877 };22096 };
21878 if (seen_tags.isSet(enum_index)) {22097 if (seen_tags.isSet(enum_index)) {
...@@ -21883,7 +22102,7 @@ fn reifyUnion(...@@ -21883,7 +22102,7 @@ fn reifyUnion(
2188322102
21884 field_ty.* = field_type_val.toIntern();22103 field_ty.* = field_type_val.toIntern();
21885 if (any_aligns) {22104 if (any_aligns) {
21886 const byte_align = try (try field_info.fieldValue(mod, 2)).toUnsignedIntSema(mod);22105 const byte_align = try (try field_info.fieldValue(pt, 2)).toUnsignedIntSema(pt);
21887 if (byte_align > 0 and !math.isPowerOfTwo(byte_align)) {22106 if (byte_align > 0 and !math.isPowerOfTwo(byte_align)) {
21888 // TODO: better source location22107 // TODO: better source location
21889 return sema.fail(block, src, "alignment value '{d}' is not a power of two or zero", .{byte_align});22108 return sema.fail(block, src, "alignment value '{d}' is not a power of two or zero", .{byte_align});
...@@ -21913,10 +22132,10 @@ fn reifyUnion(...@@ -21913,10 +22132,10 @@ fn reifyUnion(
21913 try field_names.ensureTotalCapacity(sema.arena, fields_len);22132 try field_names.ensureTotalCapacity(sema.arena, fields_len);
2191422133
21915 for (field_types, 0..) |*field_ty, field_idx| {22134 for (field_types, 0..) |*field_ty, field_idx| {
21916 const field_info = try fields_val.elemValue(mod, field_idx);22135 const field_info = try fields_val.elemValue(pt, field_idx);
2191722136
21918 const field_name_val = try field_info.fieldValue(mod, 0);22137 const field_name_val = try field_info.fieldValue(pt, 0);
21919 const field_type_val = try field_info.fieldValue(mod, 1);22138 const field_type_val = try field_info.fieldValue(pt, 1);
2192022139
21921 // Don't pass a reason; first loop acts as an assertion that this is valid.22140 // Don't pass a reason; first loop acts as an assertion that this is valid.
21922 const field_name = try sema.sliceToIpString(block, src, field_name_val, undefined);22141 const field_name = try sema.sliceToIpString(block, src, field_name_val, undefined);
...@@ -21928,7 +22147,7 @@ fn reifyUnion(...@@ -21928,7 +22147,7 @@ fn reifyUnion(
2192822147
21929 field_ty.* = field_type_val.toIntern();22148 field_ty.* = field_type_val.toIntern();
21930 if (any_aligns) {22149 if (any_aligns) {
21931 const byte_align = try (try field_info.fieldValue(mod, 2)).toUnsignedIntSema(mod);22150 const byte_align = try (try field_info.fieldValue(pt, 2)).toUnsignedIntSema(pt);
21932 if (byte_align > 0 and !math.isPowerOfTwo(byte_align)) {22151 if (byte_align > 0 and !math.isPowerOfTwo(byte_align)) {
21933 // TODO: better source location22152 // TODO: better source location
21934 return sema.fail(block, src, "alignment value '{d}' is not a power of two or zero", .{byte_align});22153 return sema.fail(block, src, "alignment value '{d}' is not a power of two or zero", .{byte_align});
...@@ -21940,7 +22159,7 @@ fn reifyUnion(...@@ -21940,7 +22159,7 @@ fn reifyUnion(
21940 const enum_tag_ty = try sema.generateUnionTagTypeSimple(block, field_names.keys(), mod.declPtr(new_decl_index));22159 const enum_tag_ty = try sema.generateUnionTagTypeSimple(block, field_names.keys(), mod.declPtr(new_decl_index));
21941 break :tag_ty .{ enum_tag_ty, false };22160 break :tag_ty .{ enum_tag_ty, false };
21942 };22161 };
21943 errdefer if (!has_explicit_tag) ip.remove(enum_tag_ty); // remove generated tag type on error22162 errdefer if (!has_explicit_tag) ip.remove(pt.tid, enum_tag_ty); // remove generated tag type on error
2194422163
21945 for (field_types) |field_ty_ip| {22164 for (field_types) |field_ty_ip| {
21946 const field_ty = Type.fromInterned(field_ty_ip);22165 const field_ty = Type.fromInterned(field_ty_ip);
...@@ -21955,7 +22174,7 @@ fn reifyUnion(...@@ -21955,7 +22174,7 @@ fn reifyUnion(
21955 }22174 }
21956 if (layout == .@"extern" and !try sema.validateExternType(field_ty, .union_field)) {22175 if (layout == .@"extern" and !try sema.validateExternType(field_ty, .union_field)) {
21957 return sema.failWithOwnedErrorMsg(block, msg: {22176 return sema.failWithOwnedErrorMsg(block, msg: {
21958 const msg = try sema.errMsg(src, "extern unions cannot contain fields of type '{}'", .{field_ty.fmt(mod)});22177 const msg = try sema.errMsg(src, "extern unions cannot contain fields of type '{}'", .{field_ty.fmt(pt)});
21959 errdefer msg.destroy(gpa);22178 errdefer msg.destroy(gpa);
2196022179
21961 try sema.explainWhyTypeIsNotExtern(msg, src, field_ty, .union_field);22180 try sema.explainWhyTypeIsNotExtern(msg, src, field_ty, .union_field);
...@@ -21965,7 +22184,7 @@ fn reifyUnion(...@@ -21965,7 +22184,7 @@ fn reifyUnion(
21965 });22184 });
21966 } else if (layout == .@"packed" and !try sema.validatePackedType(field_ty)) {22185 } else if (layout == .@"packed" and !try sema.validatePackedType(field_ty)) {
21967 return sema.failWithOwnedErrorMsg(block, msg: {22186 return sema.failWithOwnedErrorMsg(block, msg: {
21968 const msg = try sema.errMsg(src, "packed unions cannot contain fields of type '{}'", .{field_ty.fmt(mod)});22187 const msg = try sema.errMsg(src, "packed unions cannot contain fields of type '{}'", .{field_ty.fmt(pt)});
21969 errdefer msg.destroy(gpa);22188 errdefer msg.destroy(gpa);
2197022189
21971 try sema.explainWhyTypeIsNotPacked(msg, src, field_ty);22190 try sema.explainWhyTypeIsNotPacked(msg, src, field_ty);
...@@ -21984,7 +22203,7 @@ fn reifyUnion(...@@ -21984,7 +22203,7 @@ fn reifyUnion(
21984 loaded_union.tagTypePtr(ip).* = enum_tag_ty;22203 loaded_union.tagTypePtr(ip).* = enum_tag_ty;
21985 loaded_union.flagsPtr(ip).status = .have_field_types;22204 loaded_union.flagsPtr(ip).status = .have_field_types;
2198622205
21987 try mod.finalizeAnonDecl(new_decl_index);22206 try pt.finalizeAnonDecl(new_decl_index);
21988 try mod.comp.work_queue.writeItem(.{ .resolve_type_fully = wip_ty.index });22207 try mod.comp.work_queue.writeItem(.{ .resolve_type_fully = wip_ty.index });
21989 try sema.addReferenceEntry(src, AnalUnit.wrap(.{ .decl = new_decl_index }));22208 try sema.addReferenceEntry(src, AnalUnit.wrap(.{ .decl = new_decl_index }));
21990 return Air.internedToRef(wip_ty.finish(ip, new_decl_index, .none));22209 return Air.internedToRef(wip_ty.finish(ip, new_decl_index, .none));
...@@ -22001,7 +22220,8 @@ fn reifyStruct(...@@ -22001,7 +22220,8 @@ fn reifyStruct(
22001 name_strategy: Zir.Inst.NameStrategy,22220 name_strategy: Zir.Inst.NameStrategy,
22002 is_tuple: bool,22221 is_tuple: bool,
22003) CompileError!Air.Inst.Ref {22222) CompileError!Air.Inst.Ref {
22004 const mod = sema.mod;22223 const pt = sema.pt;
22224 const mod = pt.zcu;
22005 const gpa = sema.gpa;22225 const gpa = sema.gpa;
22006 const ip = &mod.intern_pool;22226 const ip = &mod.intern_pool;
2200722227
...@@ -22026,20 +22246,20 @@ fn reifyStruct(...@@ -22026,20 +22246,20 @@ fn reifyStruct(
22026 var any_aligned_fields = false;22246 var any_aligned_fields = false;
2202722247
22028 for (0..fields_len) |field_idx| {22248 for (0..fields_len) |field_idx| {
22029 const field_info = try fields_val.elemValue(mod, field_idx);22249 const field_info = try fields_val.elemValue(pt, field_idx);
2203022250
22031 const field_name_val = try field_info.fieldValue(mod, 0);22251 const field_name_val = try field_info.fieldValue(pt, 0);
22032 const field_type_val = try field_info.fieldValue(mod, 1);22252 const field_type_val = try field_info.fieldValue(pt, 1);
22033 const field_default_value_val = try field_info.fieldValue(mod, 2);22253 const field_default_value_val = try field_info.fieldValue(pt, 2);
22034 const field_is_comptime_val = try field_info.fieldValue(mod, 3);22254 const field_is_comptime_val = try field_info.fieldValue(pt, 3);
22035 const field_alignment_val = try sema.resolveLazyValue(try field_info.fieldValue(mod, 4));22255 const field_alignment_val = try sema.resolveLazyValue(try field_info.fieldValue(pt, 4));
2203622256
22037 const field_name = try sema.sliceToIpString(block, src, field_name_val, .{22257 const field_name = try sema.sliceToIpString(block, src, field_name_val, .{
22038 .needed_comptime_reason = "struct field name must be comptime-known",22258 .needed_comptime_reason = "struct field name must be comptime-known",
22039 });22259 });
22040 const field_is_comptime = field_is_comptime_val.toBool();22260 const field_is_comptime = field_is_comptime_val.toBool();
22041 const field_default_value: InternPool.Index = if (field_default_value_val.optionalValue(mod)) |ptr_val| d: {22261 const field_default_value: InternPool.Index = if (field_default_value_val.optionalValue(mod)) |ptr_val| d: {
22042 const ptr_ty = try mod.singleConstPtrType(field_type_val.toType());22262 const ptr_ty = try pt.singleConstPtrType(field_type_val.toType());
22043 // We need to do this deref here, so we won't check for this error case later on.22263 // We need to do this deref here, so we won't check for this error case later on.
22044 const val = try sema.pointerDeref(block, src, ptr_val, ptr_ty) orelse return sema.failWithNeededComptime(22264 const val = try sema.pointerDeref(block, src, ptr_val, ptr_ty) orelse return sema.failWithNeededComptime(
22045 block,22265 block,
...@@ -22060,14 +22280,14 @@ fn reifyStruct(...@@ -22060,14 +22280,14 @@ fn reifyStruct(
2206022280
22061 if (field_is_comptime) any_comptime_fields = true;22281 if (field_is_comptime) any_comptime_fields = true;
22062 if (field_default_value != .none) any_default_inits = true;22282 if (field_default_value != .none) any_default_inits = true;
22063 switch (try field_alignment_val.orderAgainstZeroAdvanced(mod, .sema)) {22283 switch (try field_alignment_val.orderAgainstZeroAdvanced(pt, .sema)) {
22064 .eq => {},22284 .eq => {},
22065 .gt => any_aligned_fields = true,22285 .gt => any_aligned_fields = true,
22066 .lt => unreachable,22286 .lt => unreachable,
22067 }22287 }
22068 }22288 }
2206922289
22070 const wip_ty = switch (try ip.getStructType(gpa, .{22290 const wip_ty = switch (try ip.getStructType(gpa, pt.tid, .{
22071 .layout = layout,22291 .layout = layout,
22072 .fields_len = fields_len,22292 .fields_len = fields_len,
22073 .known_non_opv = false,22293 .known_non_opv = false,
...@@ -22086,7 +22306,7 @@ fn reifyStruct(...@@ -22086,7 +22306,7 @@ fn reifyStruct(
22086 .wip => |wip| wip,22306 .wip => |wip| wip,
22087 .existing => |ty| return Air.internedToRef(ty),22307 .existing => |ty| return Air.internedToRef(ty),
22088 };22308 };
22089 errdefer wip_ty.cancel(ip);22309 errdefer wip_ty.cancel(ip, pt.tid);
2209022310
22091 if (is_tuple) switch (layout) {22311 if (is_tuple) switch (layout) {
22092 .@"extern" => return sema.fail(block, src, "extern tuples are not supported", .{}),22312 .@"extern" => return sema.fail(block, src, "extern tuples are not supported", .{}),
...@@ -22107,13 +22327,13 @@ fn reifyStruct(...@@ -22107,13 +22327,13 @@ fn reifyStruct(
22107 const struct_type = ip.loadStructType(wip_ty.index);22327 const struct_type = ip.loadStructType(wip_ty.index);
2210822328
22109 for (0..fields_len) |field_idx| {22329 for (0..fields_len) |field_idx| {
22110 const field_info = try fields_val.elemValue(mod, field_idx);22330 const field_info = try fields_val.elemValue(pt, field_idx);
2211122331
22112 const field_name_val = try field_info.fieldValue(mod, 0);22332 const field_name_val = try field_info.fieldValue(pt, 0);
22113 const field_type_val = try field_info.fieldValue(mod, 1);22333 const field_type_val = try field_info.fieldValue(pt, 1);
22114 const field_default_value_val = try field_info.fieldValue(mod, 2);22334 const field_default_value_val = try field_info.fieldValue(pt, 2);
22115 const field_is_comptime_val = try field_info.fieldValue(mod, 3);22335 const field_is_comptime_val = try field_info.fieldValue(pt, 3);
22116 const field_alignment_val = try field_info.fieldValue(mod, 4);22336 const field_alignment_val = try field_info.fieldValue(pt, 4);
2211722337
22118 const field_ty = field_type_val.toType();22338 const field_ty = field_type_val.toType();
22119 // Don't pass a reason; first loop acts as an assertion that this is valid.22339 // Don't pass a reason; first loop acts as an assertion that this is valid.
...@@ -22143,7 +22363,7 @@ fn reifyStruct(...@@ -22143,7 +22363,7 @@ fn reifyStruct(
22143 return sema.fail(block, src, "alignment must fit in 'u32'", .{});22363 return sema.fail(block, src, "alignment must fit in 'u32'", .{});
22144 }22364 }
2214522365
22146 const byte_align = try field_alignment_val.toUnsignedIntSema(mod);22366 const byte_align = try field_alignment_val.toUnsignedIntSema(pt);
22147 if (byte_align == 0) {22367 if (byte_align == 0) {
22148 if (layout != .@"packed") {22368 if (layout != .@"packed") {
22149 struct_type.field_aligns.get(ip)[field_idx] = .none;22369 struct_type.field_aligns.get(ip)[field_idx] = .none;
...@@ -22168,7 +22388,7 @@ fn reifyStruct(...@@ -22168,7 +22388,7 @@ fn reifyStruct(
22168 const field_default: InternPool.Index = d: {22388 const field_default: InternPool.Index = d: {
22169 if (!any_default_inits) break :d .none;22389 if (!any_default_inits) break :d .none;
22170 const ptr_val = field_default_value_val.optionalValue(mod) orelse break :d .none;22390 const ptr_val = field_default_value_val.optionalValue(mod) orelse break :d .none;
22171 const ptr_ty = try mod.singleConstPtrType(field_ty);22391 const ptr_ty = try pt.singleConstPtrType(field_ty);
22172 // Asserted comptime-dereferencable above.22392 // Asserted comptime-dereferencable above.
22173 const val = (try sema.pointerDeref(block, src, ptr_val, ptr_ty)).?;22393 const val = (try sema.pointerDeref(block, src, ptr_val, ptr_ty)).?;
22174 // We already resolved this for deduplication, so we may as well do it now.22394 // We already resolved this for deduplication, so we may as well do it now.
...@@ -22204,7 +22424,7 @@ fn reifyStruct(...@@ -22204,7 +22424,7 @@ fn reifyStruct(
22204 }22424 }
22205 if (layout == .@"extern" and !try sema.validateExternType(field_ty, .struct_field)) {22425 if (layout == .@"extern" and !try sema.validateExternType(field_ty, .struct_field)) {
22206 return sema.failWithOwnedErrorMsg(block, msg: {22426 return sema.failWithOwnedErrorMsg(block, msg: {
22207 const msg = try sema.errMsg(src, "extern structs cannot contain fields of type '{}'", .{field_ty.fmt(sema.mod)});22427 const msg = try sema.errMsg(src, "extern structs cannot contain fields of type '{}'", .{field_ty.fmt(pt)});
22208 errdefer msg.destroy(gpa);22428 errdefer msg.destroy(gpa);
2220922429
22210 try sema.explainWhyTypeIsNotExtern(msg, src, field_ty, .struct_field);22430 try sema.explainWhyTypeIsNotExtern(msg, src, field_ty, .struct_field);
...@@ -22214,7 +22434,7 @@ fn reifyStruct(...@@ -22214,7 +22434,7 @@ fn reifyStruct(
22214 });22434 });
22215 } else if (layout == .@"packed" and !try sema.validatePackedType(field_ty)) {22435 } else if (layout == .@"packed" and !try sema.validatePackedType(field_ty)) {
22216 return sema.failWithOwnedErrorMsg(block, msg: {22436 return sema.failWithOwnedErrorMsg(block, msg: {
22217 const msg = try sema.errMsg(src, "packed structs cannot contain fields of type '{}'", .{field_ty.fmt(sema.mod)});22437 const msg = try sema.errMsg(src, "packed structs cannot contain fields of type '{}'", .{field_ty.fmt(pt)});
22218 errdefer msg.destroy(gpa);22438 errdefer msg.destroy(gpa);
2221922439
22220 try sema.explainWhyTypeIsNotPacked(msg, src, field_ty);22440 try sema.explainWhyTypeIsNotPacked(msg, src, field_ty);
...@@ -22229,7 +22449,7 @@ fn reifyStruct(...@@ -22229,7 +22449,7 @@ fn reifyStruct(
22229 var fields_bit_sum: u64 = 0;22449 var fields_bit_sum: u64 = 0;
22230 for (0..struct_type.field_types.len) |field_idx| {22450 for (0..struct_type.field_types.len) |field_idx| {
22231 const field_ty = Type.fromInterned(struct_type.field_types.get(ip)[field_idx]);22451 const field_ty = Type.fromInterned(struct_type.field_types.get(ip)[field_idx]);
22232 field_ty.resolveLayout(mod) catch |err| switch (err) {22452 field_ty.resolveLayout(pt) catch |err| switch (err) {
22233 error.AnalysisFail => {22453 error.AnalysisFail => {
22234 const msg = sema.err orelse return err;22454 const msg = sema.err orelse return err;
22235 try sema.errNote(src, msg, "while checking a field of this struct", .{});22455 try sema.errNote(src, msg, "while checking a field of this struct", .{});
...@@ -22237,7 +22457,7 @@ fn reifyStruct(...@@ -22237,7 +22457,7 @@ fn reifyStruct(
22237 },22457 },
22238 else => return err,22458 else => return err,
22239 };22459 };
22240 fields_bit_sum += field_ty.bitSize(mod);22460 fields_bit_sum += field_ty.bitSize(pt);
22241 }22461 }
2224222462
22243 if (opt_backing_int_val.optionalValue(mod)) |backing_int_val| {22463 if (opt_backing_int_val.optionalValue(mod)) |backing_int_val| {
...@@ -22245,20 +22465,21 @@ fn reifyStruct(...@@ -22245,20 +22465,21 @@ fn reifyStruct(
22245 try sema.checkBackingIntType(block, src, backing_int_ty, fields_bit_sum);22465 try sema.checkBackingIntType(block, src, backing_int_ty, fields_bit_sum);
22246 struct_type.backingIntType(ip).* = backing_int_ty.toIntern();22466 struct_type.backingIntType(ip).* = backing_int_ty.toIntern();
22247 } else {22467 } else {
22248 const backing_int_ty = try mod.intType(.unsigned, @intCast(fields_bit_sum));22468 const backing_int_ty = try pt.intType(.unsigned, @intCast(fields_bit_sum));
22249 struct_type.backingIntType(ip).* = backing_int_ty.toIntern();22469 struct_type.backingIntType(ip).* = backing_int_ty.toIntern();
22250 }22470 }
22251 }22471 }
2225222472
22253 try mod.finalizeAnonDecl(new_decl_index);22473 try pt.finalizeAnonDecl(new_decl_index);
22254 try mod.comp.work_queue.writeItem(.{ .resolve_type_fully = wip_ty.index });22474 try mod.comp.work_queue.writeItem(.{ .resolve_type_fully = wip_ty.index });
22255 try sema.addReferenceEntry(src, AnalUnit.wrap(.{ .decl = new_decl_index }));22475 try sema.addReferenceEntry(src, AnalUnit.wrap(.{ .decl = new_decl_index }));
22256 return Air.internedToRef(wip_ty.finish(ip, new_decl_index, .none));22476 return Air.internedToRef(wip_ty.finish(ip, new_decl_index, .none));
22257}22477}
2225822478
22259fn resolveVaListRef(sema: *Sema, block: *Block, src: LazySrcLoc, zir_ref: Zir.Inst.Ref) CompileError!Air.Inst.Ref {22479fn resolveVaListRef(sema: *Sema, block: *Block, src: LazySrcLoc, zir_ref: Zir.Inst.Ref) CompileError!Air.Inst.Ref {
22260 const va_list_ty = try sema.mod.getBuiltinType("VaList");22480 const pt = sema.pt;
22261 const va_list_ptr = try sema.mod.singleMutPtrType(va_list_ty);22481 const va_list_ty = try pt.getBuiltinType("VaList");
22482 const va_list_ptr = try pt.singleMutPtrType(va_list_ty);
2226222483
22263 const inst = try sema.resolveInst(zir_ref);22484 const inst = try sema.resolveInst(zir_ref);
22264 return sema.coerce(block, va_list_ptr, inst, src);22485 return sema.coerce(block, va_list_ptr, inst, src);
...@@ -22275,7 +22496,7 @@ fn zirCVaArg(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) C...@@ -22275,7 +22496,7 @@ fn zirCVaArg(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) C
2227522496
22276 if (!try sema.validateExternType(arg_ty, .param_ty)) {22497 if (!try sema.validateExternType(arg_ty, .param_ty)) {
22277 const msg = msg: {22498 const msg = msg: {
22278 const msg = try sema.errMsg(ty_src, "cannot get '{}' from variadic argument", .{arg_ty.fmt(sema.mod)});22499 const msg = try sema.errMsg(ty_src, "cannot get '{}' from variadic argument", .{arg_ty.fmt(sema.pt)});
22279 errdefer msg.destroy(sema.gpa);22500 errdefer msg.destroy(sema.gpa);
2228022501
22281 try sema.explainWhyTypeIsNotExtern(msg, ty_src, arg_ty, .param_ty);22502 try sema.explainWhyTypeIsNotExtern(msg, ty_src, arg_ty, .param_ty);
...@@ -22296,7 +22517,7 @@ fn zirCVaCopy(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData)...@@ -22296,7 +22517,7 @@ fn zirCVaCopy(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData)
22296 const va_list_src = block.builtinCallArgSrc(extra.node, 0);22517 const va_list_src = block.builtinCallArgSrc(extra.node, 0);
2229722518
22298 const va_list_ref = try sema.resolveVaListRef(block, va_list_src, extra.operand);22519 const va_list_ref = try sema.resolveVaListRef(block, va_list_src, extra.operand);
22299 const va_list_ty = try sema.mod.getBuiltinType("VaList");22520 const va_list_ty = try sema.pt.getBuiltinType("VaList");
2230022521
22301 try sema.requireRuntimeBlock(block, src, null);22522 try sema.requireRuntimeBlock(block, src, null);
22302 return block.addTyOp(.c_va_copy, va_list_ty, va_list_ref);22523 return block.addTyOp(.c_va_copy, va_list_ty, va_list_ref);
...@@ -22316,7 +22537,7 @@ fn zirCVaEnd(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) C...@@ -22316,7 +22537,7 @@ fn zirCVaEnd(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) C
22316fn zirCVaStart(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) CompileError!Air.Inst.Ref {22537fn zirCVaStart(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) CompileError!Air.Inst.Ref {
22317 const src = block.nodeOffset(@bitCast(extended.operand));22538 const src = block.nodeOffset(@bitCast(extended.operand));
2231822539
22319 const va_list_ty = try sema.mod.getBuiltinType("VaList");22540 const va_list_ty = try sema.pt.getBuiltinType("VaList");
22320 try sema.requireRuntimeBlock(block, src, null);22541 try sema.requireRuntimeBlock(block, src, null);
22321 return block.addInst(.{22542 return block.addInst(.{
22322 .tag = .c_va_start,22543 .tag = .c_va_start,
...@@ -22325,14 +22546,15 @@ fn zirCVaStart(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData)...@@ -22325,14 +22546,15 @@ fn zirCVaStart(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData)
22325}22546}
2232622547
22327fn zirTypeName(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {22548fn zirTypeName(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
22328 const mod = sema.mod;22549 const pt = sema.pt;
22550 const mod = pt.zcu;
22329 const ip = &mod.intern_pool;22551 const ip = &mod.intern_pool;
2233022552
22331 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;22553 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;
22332 const ty_src = block.builtinCallArgSrc(inst_data.src_node, 0);22554 const ty_src = block.builtinCallArgSrc(inst_data.src_node, 0);
22333 const ty = try sema.resolveType(block, ty_src, inst_data.operand);22555 const ty = try sema.resolveType(block, ty_src, inst_data.operand);
2233422556
22335 const type_name = try ip.getOrPutStringFmt(sema.gpa, "{}", .{ty.fmt(mod)}, .no_embedded_nulls);22557 const type_name = try ip.getOrPutStringFmt(sema.gpa, pt.tid, "{}", .{ty.fmt(pt)}, .no_embedded_nulls);
22336 return sema.addNullTerminatedStrLit(type_name);22558 return sema.addNullTerminatedStrLit(type_name);
22337}22559}
2233822560
...@@ -22349,7 +22571,8 @@ fn zirFrameSize(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A...@@ -22349,7 +22571,8 @@ fn zirFrameSize(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
22349}22571}
2235022572
22351fn zirIntFromFloat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {22573fn zirIntFromFloat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
22352 const mod = sema.mod;22574 const pt = sema.pt;
22575 const mod = pt.zcu;
22353 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;22576 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
22354 const src = block.nodeOffset(inst_data.src_node);22577 const src = block.nodeOffset(inst_data.src_node);
22355 const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data;22578 const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data;
...@@ -22380,23 +22603,23 @@ fn zirIntFromFloat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErro...@@ -22380,23 +22603,23 @@ fn zirIntFromFloat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErro
22380 if (dest_scalar_ty.intInfo(mod).bits == 0) {22603 if (dest_scalar_ty.intInfo(mod).bits == 0) {
22381 if (!is_vector) {22604 if (!is_vector) {
22382 if (block.wantSafety()) {22605 if (block.wantSafety()) {
22383 const ok = try block.addBinOp(if (block.float_mode == .optimized) .cmp_eq_optimized else .cmp_eq, operand, Air.internedToRef((try mod.floatValue(operand_ty, 0.0)).toIntern()));22606 const ok = try block.addBinOp(if (block.float_mode == .optimized) .cmp_eq_optimized else .cmp_eq, operand, Air.internedToRef((try pt.floatValue(operand_ty, 0.0)).toIntern()));
22384 try sema.addSafetyCheck(block, src, ok, .integer_part_out_of_bounds);22607 try sema.addSafetyCheck(block, src, ok, .integer_part_out_of_bounds);
22385 }22608 }
22386 return Air.internedToRef((try mod.intValue(dest_ty, 0)).toIntern());22609 return Air.internedToRef((try pt.intValue(dest_ty, 0)).toIntern());
22387 }22610 }
22388 if (block.wantSafety()) {22611 if (block.wantSafety()) {
22389 const len = dest_ty.vectorLen(mod);22612 const len = dest_ty.vectorLen(mod);
22390 for (0..len) |i| {22613 for (0..len) |i| {
22391 const idx_ref = try mod.intRef(Type.usize, i);22614 const idx_ref = try pt.intRef(Type.usize, i);
22392 const elem_ref = try block.addBinOp(.array_elem_val, operand, idx_ref);22615 const elem_ref = try block.addBinOp(.array_elem_val, operand, idx_ref);
22393 const ok = try block.addBinOp(if (block.float_mode == .optimized) .cmp_eq_optimized else .cmp_eq, elem_ref, Air.internedToRef((try mod.floatValue(operand_scalar_ty, 0.0)).toIntern()));22616 const ok = try block.addBinOp(if (block.float_mode == .optimized) .cmp_eq_optimized else .cmp_eq, elem_ref, Air.internedToRef((try pt.floatValue(operand_scalar_ty, 0.0)).toIntern()));
22394 try sema.addSafetyCheck(block, src, ok, .integer_part_out_of_bounds);22617 try sema.addSafetyCheck(block, src, ok, .integer_part_out_of_bounds);
22395 }22618 }
22396 }22619 }
22397 return Air.internedToRef(try mod.intern(.{ .aggregate = .{22620 return Air.internedToRef(try pt.intern(.{ .aggregate = .{
22398 .ty = dest_ty.toIntern(),22621 .ty = dest_ty.toIntern(),
22399 .storage = .{ .repeated_elem = (try mod.intValue(dest_scalar_ty, 0)).toIntern() },22622 .storage = .{ .repeated_elem = (try pt.intValue(dest_scalar_ty, 0)).toIntern() },
22400 } }));22623 } }));
22401 }22624 }
22402 if (!is_vector) {22625 if (!is_vector) {
...@@ -22404,8 +22627,8 @@ fn zirIntFromFloat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErro...@@ -22404,8 +22627,8 @@ fn zirIntFromFloat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErro
22404 if (block.wantSafety()) {22627 if (block.wantSafety()) {
22405 const back = try block.addTyOp(.float_from_int, operand_ty, result);22628 const back = try block.addTyOp(.float_from_int, operand_ty, result);
22406 const diff = try block.addBinOp(.sub, operand, back);22629 const diff = try block.addBinOp(.sub, operand, back);
22407 const ok_pos = try block.addBinOp(if (block.float_mode == .optimized) .cmp_lt_optimized else .cmp_lt, diff, Air.internedToRef((try mod.floatValue(operand_ty, 1.0)).toIntern()));22630 const ok_pos = try block.addBinOp(if (block.float_mode == .optimized) .cmp_lt_optimized else .cmp_lt, diff, Air.internedToRef((try pt.floatValue(operand_ty, 1.0)).toIntern()));
22408 const ok_neg = try block.addBinOp(if (block.float_mode == .optimized) .cmp_gt_optimized else .cmp_gt, diff, Air.internedToRef((try mod.floatValue(operand_ty, -1.0)).toIntern()));22631 const ok_neg = try block.addBinOp(if (block.float_mode == .optimized) .cmp_gt_optimized else .cmp_gt, diff, Air.internedToRef((try pt.floatValue(operand_ty, -1.0)).toIntern()));
22409 const ok = try block.addBinOp(.bool_and, ok_pos, ok_neg);22632 const ok = try block.addBinOp(.bool_and, ok_pos, ok_neg);
22410 try sema.addSafetyCheck(block, src, ok, .integer_part_out_of_bounds);22633 try sema.addSafetyCheck(block, src, ok, .integer_part_out_of_bounds);
22411 }22634 }
...@@ -22414,14 +22637,14 @@ fn zirIntFromFloat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErro...@@ -22414,14 +22637,14 @@ fn zirIntFromFloat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErro
22414 const len = dest_ty.vectorLen(mod);22637 const len = dest_ty.vectorLen(mod);
22415 const new_elems = try sema.arena.alloc(Air.Inst.Ref, len);22638 const new_elems = try sema.arena.alloc(Air.Inst.Ref, len);
22416 for (new_elems, 0..) |*new_elem, i| {22639 for (new_elems, 0..) |*new_elem, i| {
22417 const idx_ref = try mod.intRef(Type.usize, i);22640 const idx_ref = try pt.intRef(Type.usize, i);
22418 const old_elem = try block.addBinOp(.array_elem_val, operand, idx_ref);22641 const old_elem = try block.addBinOp(.array_elem_val, operand, idx_ref);
22419 const result = try block.addTyOp(if (block.float_mode == .optimized) .int_from_float_optimized else .int_from_float, dest_scalar_ty, old_elem);22642 const result = try block.addTyOp(if (block.float_mode == .optimized) .int_from_float_optimized else .int_from_float, dest_scalar_ty, old_elem);
22420 if (block.wantSafety()) {22643 if (block.wantSafety()) {
22421 const back = try block.addTyOp(.float_from_int, operand_scalar_ty, result);22644 const back = try block.addTyOp(.float_from_int, operand_scalar_ty, result);
22422 const diff = try block.addBinOp(.sub, old_elem, back);22645 const diff = try block.addBinOp(.sub, old_elem, back);
22423 const ok_pos = try block.addBinOp(if (block.float_mode == .optimized) .cmp_lt_optimized else .cmp_lt, diff, Air.internedToRef((try mod.floatValue(operand_scalar_ty, 1.0)).toIntern()));22646 const ok_pos = try block.addBinOp(if (block.float_mode == .optimized) .cmp_lt_optimized else .cmp_lt, diff, Air.internedToRef((try pt.floatValue(operand_scalar_ty, 1.0)).toIntern()));
22424 const ok_neg = try block.addBinOp(if (block.float_mode == .optimized) .cmp_gt_optimized else .cmp_gt, diff, Air.internedToRef((try mod.floatValue(operand_scalar_ty, -1.0)).toIntern()));22647 const ok_neg = try block.addBinOp(if (block.float_mode == .optimized) .cmp_gt_optimized else .cmp_gt, diff, Air.internedToRef((try pt.floatValue(operand_scalar_ty, -1.0)).toIntern()));
22425 const ok = try block.addBinOp(.bool_and, ok_pos, ok_neg);22648 const ok = try block.addBinOp(.bool_and, ok_pos, ok_neg);
22426 try sema.addSafetyCheck(block, src, ok, .integer_part_out_of_bounds);22649 try sema.addSafetyCheck(block, src, ok, .integer_part_out_of_bounds);
22427 }22650 }
...@@ -22431,7 +22654,8 @@ fn zirIntFromFloat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErro...@@ -22431,7 +22654,8 @@ fn zirIntFromFloat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErro
22431}22654}
2243222655
22433fn zirFloatFromInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {22656fn zirFloatFromInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
22434 const mod = sema.mod;22657 const pt = sema.pt;
22658 const mod = pt.zcu;
22435 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;22659 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
22436 const src = block.nodeOffset(inst_data.src_node);22660 const src = block.nodeOffset(inst_data.src_node);
22437 const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data;22661 const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data;
...@@ -22450,7 +22674,7 @@ fn zirFloatFromInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErro...@@ -22450,7 +22674,7 @@ fn zirFloatFromInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErro
22450 _ = try sema.checkIntType(block, operand_src, operand_scalar_ty);22674 _ = try sema.checkIntType(block, operand_src, operand_scalar_ty);
2245122675
22452 if (try sema.resolveValue(operand)) |operand_val| {22676 if (try sema.resolveValue(operand)) |operand_val| {
22453 const result_val = try operand_val.floatFromIntAdvanced(sema.arena, operand_ty, dest_ty, mod, .sema);22677 const result_val = try operand_val.floatFromIntAdvanced(sema.arena, operand_ty, dest_ty, pt, .sema);
22454 return Air.internedToRef(result_val.toIntern());22678 return Air.internedToRef(result_val.toIntern());
22455 } else if (dest_scalar_ty.zigTypeTag(mod) == .ComptimeFloat) {22679 } else if (dest_scalar_ty.zigTypeTag(mod) == .ComptimeFloat) {
22456 return sema.failWithNeededComptime(block, operand_src, .{22680 return sema.failWithNeededComptime(block, operand_src, .{
...@@ -22465,7 +22689,7 @@ fn zirFloatFromInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErro...@@ -22465,7 +22689,7 @@ fn zirFloatFromInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErro
22465 const len = operand_ty.vectorLen(mod);22689 const len = operand_ty.vectorLen(mod);
22466 const new_elems = try sema.arena.alloc(Air.Inst.Ref, len);22690 const new_elems = try sema.arena.alloc(Air.Inst.Ref, len);
22467 for (new_elems, 0..) |*new_elem, i| {22691 for (new_elems, 0..) |*new_elem, i| {
22468 const idx_ref = try mod.intRef(Type.usize, i);22692 const idx_ref = try pt.intRef(Type.usize, i);
22469 const old_elem = try block.addBinOp(.array_elem_val, operand, idx_ref);22693 const old_elem = try block.addBinOp(.array_elem_val, operand, idx_ref);
22470 new_elem.* = try block.addTyOp(.float_from_int, dest_scalar_ty, old_elem);22694 new_elem.* = try block.addTyOp(.float_from_int, dest_scalar_ty, old_elem);
22471 }22695 }
...@@ -22473,7 +22697,8 @@ fn zirFloatFromInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErro...@@ -22473,7 +22697,8 @@ fn zirFloatFromInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErro
22473}22697}
2247422698
22475fn zirPtrFromInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {22699fn zirPtrFromInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
22476 const mod = sema.mod;22700 const pt = sema.pt;
22701 const mod = pt.zcu;
22477 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;22702 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
22478 const src = block.nodeOffset(inst_data.src_node);22703 const src = block.nodeOffset(inst_data.src_node);
2247922704
...@@ -22489,7 +22714,7 @@ fn zirPtrFromInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!...@@ -22489,7 +22714,7 @@ fn zirPtrFromInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!
22489 const is_vector = dest_ty.zigTypeTag(mod) == .Vector;22714 const is_vector = dest_ty.zigTypeTag(mod) == .Vector;
22490 const operand_ty = if (is_vector) operand_ty: {22715 const operand_ty = if (is_vector) operand_ty: {
22491 const len = dest_ty.vectorLen(mod);22716 const len = dest_ty.vectorLen(mod);
22492 break :operand_ty try mod.vectorType(.{ .child = .usize_type, .len = len });22717 break :operand_ty try pt.vectorType(.{ .child = .usize_type, .len = len });
22493 } else Type.usize;22718 } else Type.usize;
2249422719
22495 const operand_coerced = try sema.coerce(block, operand_ty, operand_res, operand_src);22720 const operand_coerced = try sema.coerce(block, operand_ty, operand_res, operand_src);
...@@ -22498,11 +22723,11 @@ fn zirPtrFromInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!...@@ -22498,11 +22723,11 @@ fn zirPtrFromInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!
22498 try sema.checkPtrType(block, src, ptr_ty, true);22723 try sema.checkPtrType(block, src, ptr_ty, true);
2249922724
22500 const elem_ty = ptr_ty.elemType2(mod);22725 const elem_ty = ptr_ty.elemType2(mod);
22501 const ptr_align = try ptr_ty.ptrAlignmentAdvanced(mod, .sema);22726 const ptr_align = try ptr_ty.ptrAlignmentAdvanced(pt, .sema);
2250222727
22503 if (ptr_ty.isSlice(mod)) {22728 if (ptr_ty.isSlice(mod)) {
22504 const msg = msg: {22729 const msg = msg: {
22505 const msg = try sema.errMsg(src, "integer cannot be converted to slice type '{}'", .{ptr_ty.fmt(sema.mod)});22730 const msg = try sema.errMsg(src, "integer cannot be converted to slice type '{}'", .{ptr_ty.fmt(pt)});
22506 errdefer msg.destroy(sema.gpa);22731 errdefer msg.destroy(sema.gpa);
22507 try sema.errNote(src, msg, "slice length cannot be inferred from address", .{});22732 try sema.errNote(src, msg, "slice length cannot be inferred from address", .{});
22508 break :msg msg;22733 break :msg msg;
...@@ -22518,18 +22743,18 @@ fn zirPtrFromInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!...@@ -22518,18 +22743,18 @@ fn zirPtrFromInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!
22518 const len = dest_ty.vectorLen(mod);22743 const len = dest_ty.vectorLen(mod);
22519 const new_elems = try sema.arena.alloc(InternPool.Index, len);22744 const new_elems = try sema.arena.alloc(InternPool.Index, len);
22520 for (new_elems, 0..) |*new_elem, i| {22745 for (new_elems, 0..) |*new_elem, i| {
22521 const elem = try val.elemValue(mod, i);22746 const elem = try val.elemValue(pt, i);
22522 const ptr_val = try sema.ptrFromIntVal(block, operand_src, elem, ptr_ty, ptr_align);22747 const ptr_val = try sema.ptrFromIntVal(block, operand_src, elem, ptr_ty, ptr_align);
22523 new_elem.* = ptr_val.toIntern();22748 new_elem.* = ptr_val.toIntern();
22524 }22749 }
22525 return Air.internedToRef(try mod.intern(.{ .aggregate = .{22750 return Air.internedToRef(try pt.intern(.{ .aggregate = .{
22526 .ty = dest_ty.toIntern(),22751 .ty = dest_ty.toIntern(),
22527 .storage = .{ .elems = new_elems },22752 .storage = .{ .elems = new_elems },
22528 } }));22753 } }));
22529 }22754 }
22530 if (try sema.typeRequiresComptime(ptr_ty)) {22755 if (try sema.typeRequiresComptime(ptr_ty)) {
22531 return sema.failWithOwnedErrorMsg(block, msg: {22756 return sema.failWithOwnedErrorMsg(block, msg: {
22532 const msg = try sema.errMsg(src, "pointer to comptime-only type '{}' must be comptime-known, but operand is runtime-known", .{ptr_ty.fmt(mod)});22757 const msg = try sema.errMsg(src, "pointer to comptime-only type '{}' must be comptime-known, but operand is runtime-known", .{ptr_ty.fmt(pt)});
22533 errdefer msg.destroy(sema.gpa);22758 errdefer msg.destroy(sema.gpa);
2253422759
22535 try sema.explainWhyTypeIsComptime(msg, src, ptr_ty);22760 try sema.explainWhyTypeIsComptime(msg, src, ptr_ty);
...@@ -22545,7 +22770,7 @@ fn zirPtrFromInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!...@@ -22545,7 +22770,7 @@ fn zirPtrFromInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!
22545 }22770 }
22546 if (ptr_align.compare(.gt, .@"1")) {22771 if (ptr_align.compare(.gt, .@"1")) {
22547 const align_bytes_minus_1 = ptr_align.toByteUnits().? - 1;22772 const align_bytes_minus_1 = ptr_align.toByteUnits().? - 1;
22548 const align_minus_1 = Air.internedToRef((try mod.intValue(Type.usize, align_bytes_minus_1)).toIntern());22773 const align_minus_1 = Air.internedToRef((try pt.intValue(Type.usize, align_bytes_minus_1)).toIntern());
22549 const remainder = try block.addBinOp(.bit_and, operand_coerced, align_minus_1);22774 const remainder = try block.addBinOp(.bit_and, operand_coerced, align_minus_1);
22550 const is_aligned = try block.addBinOp(.cmp_eq, remainder, .zero_usize);22775 const is_aligned = try block.addBinOp(.cmp_eq, remainder, .zero_usize);
22551 try sema.addSafetyCheck(block, src, is_aligned, .incorrect_alignment);22776 try sema.addSafetyCheck(block, src, is_aligned, .incorrect_alignment);
...@@ -22557,7 +22782,7 @@ fn zirPtrFromInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!...@@ -22557,7 +22782,7 @@ fn zirPtrFromInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!
22557 const len = dest_ty.vectorLen(mod);22782 const len = dest_ty.vectorLen(mod);
22558 if (block.wantSafety() and (try sema.typeHasRuntimeBits(elem_ty) or elem_ty.zigTypeTag(mod) == .Fn)) {22783 if (block.wantSafety() and (try sema.typeHasRuntimeBits(elem_ty) or elem_ty.zigTypeTag(mod) == .Fn)) {
22559 for (0..len) |i| {22784 for (0..len) |i| {
22560 const idx_ref = try mod.intRef(Type.usize, i);22785 const idx_ref = try pt.intRef(Type.usize, i);
22561 const elem_coerced = try block.addBinOp(.array_elem_val, operand_coerced, idx_ref);22786 const elem_coerced = try block.addBinOp(.array_elem_val, operand_coerced, idx_ref);
22562 if (!ptr_ty.isAllowzeroPtr(mod)) {22787 if (!ptr_ty.isAllowzeroPtr(mod)) {
22563 const is_non_zero = try block.addBinOp(.cmp_neq, elem_coerced, .zero_usize);22788 const is_non_zero = try block.addBinOp(.cmp_neq, elem_coerced, .zero_usize);
...@@ -22565,7 +22790,7 @@ fn zirPtrFromInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!...@@ -22565,7 +22790,7 @@ fn zirPtrFromInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!
22565 }22790 }
22566 if (ptr_align.compare(.gt, .@"1")) {22791 if (ptr_align.compare(.gt, .@"1")) {
22567 const align_bytes_minus_1 = ptr_align.toByteUnits().? - 1;22792 const align_bytes_minus_1 = ptr_align.toByteUnits().? - 1;
22568 const align_minus_1 = Air.internedToRef((try mod.intValue(Type.usize, align_bytes_minus_1)).toIntern());22793 const align_minus_1 = Air.internedToRef((try pt.intValue(Type.usize, align_bytes_minus_1)).toIntern());
22569 const remainder = try block.addBinOp(.bit_and, elem_coerced, align_minus_1);22794 const remainder = try block.addBinOp(.bit_and, elem_coerced, align_minus_1);
22570 const is_aligned = try block.addBinOp(.cmp_eq, remainder, .zero_usize);22795 const is_aligned = try block.addBinOp(.cmp_eq, remainder, .zero_usize);
22571 try sema.addSafetyCheck(block, src, is_aligned, .incorrect_alignment);22796 try sema.addSafetyCheck(block, src, is_aligned, .incorrect_alignment);
...@@ -22575,7 +22800,7 @@ fn zirPtrFromInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!...@@ -22575,7 +22800,7 @@ fn zirPtrFromInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!
2257522800
22576 const new_elems = try sema.arena.alloc(Air.Inst.Ref, len);22801 const new_elems = try sema.arena.alloc(Air.Inst.Ref, len);
22577 for (new_elems, 0..) |*new_elem, i| {22802 for (new_elems, 0..) |*new_elem, i| {
22578 const idx_ref = try mod.intRef(Type.usize, i);22803 const idx_ref = try pt.intRef(Type.usize, i);
22579 const old_elem = try block.addBinOp(.array_elem_val, operand_coerced, idx_ref);22804 const old_elem = try block.addBinOp(.array_elem_val, operand_coerced, idx_ref);
22580 new_elem.* = try block.addBitCast(ptr_ty, old_elem);22805 new_elem.* = try block.addBitCast(ptr_ty, old_elem);
22581 }22806 }
...@@ -22590,31 +22815,33 @@ fn ptrFromIntVal(...@@ -22590,31 +22815,33 @@ fn ptrFromIntVal(
22590 ptr_ty: Type,22815 ptr_ty: Type,
22591 ptr_align: Alignment,22816 ptr_align: Alignment,
22592) !Value {22817) !Value {
22593 const zcu = sema.mod;22818 const pt = sema.pt;
22819 const zcu = pt.zcu;
22594 if (operand_val.isUndef(zcu)) {22820 if (operand_val.isUndef(zcu)) {
22595 if (ptr_ty.isAllowzeroPtr(zcu) and ptr_align == .@"1") {22821 if (ptr_ty.isAllowzeroPtr(zcu) and ptr_align == .@"1") {
22596 return zcu.undefValue(ptr_ty);22822 return pt.undefValue(ptr_ty);
22597 }22823 }
22598 return sema.failWithUseOfUndef(block, operand_src);22824 return sema.failWithUseOfUndef(block, operand_src);
22599 }22825 }
22600 const addr = try operand_val.toUnsignedIntSema(zcu);22826 const addr = try operand_val.toUnsignedIntSema(pt);
22601 if (!ptr_ty.isAllowzeroPtr(zcu) and addr == 0)22827 if (!ptr_ty.isAllowzeroPtr(zcu) and addr == 0)
22602 return sema.fail(block, operand_src, "pointer type '{}' does not allow address zero", .{ptr_ty.fmt(zcu)});22828 return sema.fail(block, operand_src, "pointer type '{}' does not allow address zero", .{ptr_ty.fmt(pt)});
22603 if (addr != 0 and ptr_align != .none and !ptr_align.check(addr))22829 if (addr != 0 and ptr_align != .none and !ptr_align.check(addr))
22604 return sema.fail(block, operand_src, "pointer type '{}' requires aligned address", .{ptr_ty.fmt(zcu)});22830 return sema.fail(block, operand_src, "pointer type '{}' requires aligned address", .{ptr_ty.fmt(pt)});
2260522831
22606 return switch (ptr_ty.zigTypeTag(zcu)) {22832 return switch (ptr_ty.zigTypeTag(zcu)) {
22607 .Optional => Value.fromInterned((try zcu.intern(.{ .opt = .{22833 .Optional => Value.fromInterned(try pt.intern(.{ .opt = .{
22608 .ty = ptr_ty.toIntern(),22834 .ty = ptr_ty.toIntern(),
22609 .val = if (addr == 0) .none else (try zcu.ptrIntValue(ptr_ty.childType(zcu), addr)).toIntern(),22835 .val = if (addr == 0) .none else (try pt.ptrIntValue(ptr_ty.childType(zcu), addr)).toIntern(),
22610 } }))),22836 } })),
22611 .Pointer => try zcu.ptrIntValue(ptr_ty, addr),22837 .Pointer => try pt.ptrIntValue(ptr_ty, addr),
22612 else => unreachable,22838 else => unreachable,
22613 };22839 };
22614}22840}
2261522841
22616fn zirErrorCast(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) CompileError!Air.Inst.Ref {22842fn zirErrorCast(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) CompileError!Air.Inst.Ref {
22617 const mod = sema.mod;22843 const pt = sema.pt;
22844 const mod = pt.zcu;
22618 const ip = &mod.intern_pool;22845 const ip = &mod.intern_pool;
22619 const extra = sema.code.extraData(Zir.Inst.BinNode, extended.operand).data;22846 const extra = sema.code.extraData(Zir.Inst.BinNode, extended.operand).data;
22620 const src = block.nodeOffset(extra.node);22847 const src = block.nodeOffset(extra.node);
...@@ -22642,8 +22869,8 @@ fn zirErrorCast(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData...@@ -22642,8 +22869,8 @@ fn zirErrorCast(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData
22642 errdefer msg.destroy(sema.gpa);22869 errdefer msg.destroy(sema.gpa);
22643 const dest_ty = base_dest_ty.errorUnionPayload(mod);22870 const dest_ty = base_dest_ty.errorUnionPayload(mod);
22644 const operand_ty = base_operand_ty.errorUnionPayload(mod);22871 const operand_ty = base_operand_ty.errorUnionPayload(mod);
22645 try sema.errNote(src, msg, "destination payload is '{}'", .{dest_ty.fmt(mod)});22872 try sema.errNote(src, msg, "destination payload is '{}'", .{dest_ty.fmt(pt)});
22646 try sema.errNote(src, msg, "operand payload is '{}'", .{operand_ty.fmt(mod)});22873 try sema.errNote(src, msg, "operand payload is '{}'", .{operand_ty.fmt(pt)});
22647 try addDeclaredHereNote(sema, msg, dest_ty);22874 try addDeclaredHereNote(sema, msg, dest_ty);
22648 try addDeclaredHereNote(sema, msg, operand_ty);22875 try addDeclaredHereNote(sema, msg, operand_ty);
22649 break :msg msg;22876 break :msg msg;
...@@ -22684,7 +22911,7 @@ fn zirErrorCast(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData...@@ -22684,7 +22911,7 @@ fn zirErrorCast(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData
22684 };22911 };
22685 if (disjoint and dest_tag != .ErrorUnion) {22912 if (disjoint and dest_tag != .ErrorUnion) {
22686 return sema.fail(block, src, "error sets '{}' and '{}' have no common errors", .{22913 return sema.fail(block, src, "error sets '{}' and '{}' have no common errors", .{
22687 operand_ty.fmt(sema.mod), dest_ty.fmt(sema.mod),22914 operand_ty.fmt(pt), dest_ty.fmt(pt),
22688 });22915 });
22689 }22916 }
2269022917
...@@ -22700,24 +22927,24 @@ fn zirErrorCast(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData...@@ -22700,24 +22927,24 @@ fn zirErrorCast(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData
22700 }22927 }
22701 if (!Type.errorSetHasFieldIp(ip, dest_ty.toIntern(), error_name)) {22928 if (!Type.errorSetHasFieldIp(ip, dest_ty.toIntern(), error_name)) {
22702 return sema.fail(block, src, "'error.{}' not a member of error set '{}'", .{22929 return sema.fail(block, src, "'error.{}' not a member of error set '{}'", .{
22703 error_name.fmt(ip), dest_ty.fmt(sema.mod),22930 error_name.fmt(ip), dest_ty.fmt(pt),
22704 });22931 });
22705 }22932 }
22706 }22933 }
2270722934
22708 return Air.internedToRef((try mod.getCoerced(val, base_dest_ty)).toIntern());22935 return Air.internedToRef((try pt.getCoerced(val, base_dest_ty)).toIntern());
22709 }22936 }
2271022937
22711 try sema.requireRuntimeBlock(block, src, operand_src);22938 try sema.requireRuntimeBlock(block, src, operand_src);
22712 const err_int_ty = try mod.errorIntType();22939 const err_int_ty = try pt.errorIntType();
22713 if (block.wantSafety() and !dest_ty.isAnyError(mod) and22940 if (block.wantSafety() and !dest_ty.isAnyError(mod) and
22714 dest_ty.toIntern() != .adhoc_inferred_error_set_type and22941 dest_ty.toIntern() != .adhoc_inferred_error_set_type and
22715 sema.mod.backendSupportsFeature(.error_set_has_value))22942 mod.backendSupportsFeature(.error_set_has_value))
22716 {22943 {
22717 if (dest_tag == .ErrorUnion) {22944 if (dest_tag == .ErrorUnion) {
22718 const err_code = try sema.analyzeErrUnionCode(block, operand_src, operand);22945 const err_code = try sema.analyzeErrUnionCode(block, operand_src, operand);
22719 const err_int = try block.addBitCast(err_int_ty, err_code);22946 const err_int = try block.addBitCast(err_int_ty, err_code);
22720 const zero_err = try mod.intRef(try mod.errorIntType(), 0);22947 const zero_err = try pt.intRef(try pt.errorIntType(), 0);
2272122948
22722 const is_zero = try block.addBinOp(.cmp_eq, err_int, zero_err);22949 const is_zero = try block.addBinOp(.cmp_eq, err_int, zero_err);
22723 if (disjoint) {22950 if (disjoint) {
...@@ -22786,7 +23013,8 @@ fn ptrCastFull(...@@ -22786,7 +23013,8 @@ fn ptrCastFull(
22786 dest_ty: Type,23013 dest_ty: Type,
22787 operation: []const u8,23014 operation: []const u8,
22788) CompileError!Air.Inst.Ref {23015) CompileError!Air.Inst.Ref {
22789 const mod = sema.mod;23016 const pt = sema.pt;
23017 const mod = pt.zcu;
22790 const operand_ty = sema.typeOf(operand);23018 const operand_ty = sema.typeOf(operand);
2279123019
22792 try sema.checkPtrType(block, src, dest_ty, true);23020 try sema.checkPtrType(block, src, dest_ty, true);
...@@ -22795,8 +23023,8 @@ fn ptrCastFull(...@@ -22795,8 +23023,8 @@ fn ptrCastFull(
22795 const src_info = operand_ty.ptrInfo(mod);23023 const src_info = operand_ty.ptrInfo(mod);
22796 const dest_info = dest_ty.ptrInfo(mod);23024 const dest_info = dest_ty.ptrInfo(mod);
2279723025
22798 try Type.fromInterned(src_info.child).resolveLayout(mod);23026 try Type.fromInterned(src_info.child).resolveLayout(pt);
22799 try Type.fromInterned(dest_info.child).resolveLayout(mod);23027 try Type.fromInterned(dest_info.child).resolveLayout(pt);
2280023028
22801 const src_slice_like = src_info.flags.size == .Slice or23029 const src_slice_like = src_info.flags.size == .Slice or
22802 (src_info.flags.size == .One and Type.fromInterned(src_info.child).zigTypeTag(mod) == .Array);23030 (src_info.flags.size == .One and Type.fromInterned(src_info.child).zigTypeTag(mod) == .Array);
...@@ -22810,12 +23038,12 @@ fn ptrCastFull(...@@ -22810,12 +23038,12 @@ fn ptrCastFull(
2281023038
22811 if (dest_info.flags.size == .Slice) {23039 if (dest_info.flags.size == .Slice) {
22812 const src_elem_size = switch (src_info.flags.size) {23040 const src_elem_size = switch (src_info.flags.size) {
22813 .Slice => Type.fromInterned(src_info.child).abiSize(mod),23041 .Slice => Type.fromInterned(src_info.child).abiSize(pt),
22814 // pointer to array23042 // pointer to array
22815 .One => Type.fromInterned(src_info.child).childType(mod).abiSize(mod),23043 .One => Type.fromInterned(src_info.child).childType(mod).abiSize(pt),
22816 else => unreachable,23044 else => unreachable,
22817 };23045 };
22818 const dest_elem_size = Type.fromInterned(dest_info.child).abiSize(mod);23046 const dest_elem_size = Type.fromInterned(dest_info.child).abiSize(pt);
22819 if (src_elem_size != dest_elem_size) {23047 if (src_elem_size != dest_elem_size) {
22820 return sema.fail(block, src, "TODO: implement {s} between slices changing the length", .{operation});23048 return sema.fail(block, src, "TODO: implement {s} between slices changing the length", .{operation});
22821 }23049 }
...@@ -22867,8 +23095,7 @@ fn ptrCastFull(...@@ -22867,8 +23095,7 @@ fn ptrCastFull(
22867 if (imc_res == .ok) break :check_child;23095 if (imc_res == .ok) break :check_child;
22868 return sema.failWithOwnedErrorMsg(block, msg: {23096 return sema.failWithOwnedErrorMsg(block, msg: {
22869 const msg = try sema.errMsg(src, "pointer element type '{}' cannot coerce into element type '{}'", .{23097 const msg = try sema.errMsg(src, "pointer element type '{}' cannot coerce into element type '{}'", .{
22870 src_child.fmt(mod),23098 src_child.fmt(pt), dest_child.fmt(pt),
22871 dest_child.fmt(mod),
22872 });23099 });
22873 errdefer msg.destroy(sema.gpa);23100 errdefer msg.destroy(sema.gpa);
22874 try imc_res.report(sema, src, msg);23101 try imc_res.report(sema, src, msg);
...@@ -22881,26 +23108,26 @@ fn ptrCastFull(...@@ -22881,26 +23108,26 @@ fn ptrCastFull(
22881 if (dest_info.sentinel == .none) break :check_sent;23108 if (dest_info.sentinel == .none) break :check_sent;
22882 if (src_info.flags.size == .C) break :check_sent;23109 if (src_info.flags.size == .C) break :check_sent;
22883 if (src_info.sentinel != .none) {23110 if (src_info.sentinel != .none) {
22884 const coerced_sent = try mod.intern_pool.getCoerced(sema.gpa, src_info.sentinel, dest_info.child);23111 const coerced_sent = try mod.intern_pool.getCoerced(sema.gpa, pt.tid, src_info.sentinel, dest_info.child);
22885 if (dest_info.sentinel == coerced_sent) break :check_sent;23112 if (dest_info.sentinel == coerced_sent) break :check_sent;
22886 }23113 }
22887 if (src_slice_like and src_info.flags.size == .One and dest_info.flags.size == .Slice) {23114 if (src_slice_like and src_info.flags.size == .One and dest_info.flags.size == .Slice) {
22888 // [*]nT -> []T23115 // [*]nT -> []T
22889 const arr_ty = Type.fromInterned(src_info.child);23116 const arr_ty = Type.fromInterned(src_info.child);
22890 if (arr_ty.sentinel(mod)) |src_sentinel| {23117 if (arr_ty.sentinel(mod)) |src_sentinel| {
22891 const coerced_sent = try mod.intern_pool.getCoerced(sema.gpa, src_sentinel.toIntern(), dest_info.child);23118 const coerced_sent = try mod.intern_pool.getCoerced(sema.gpa, pt.tid, src_sentinel.toIntern(), dest_info.child);
22892 if (dest_info.sentinel == coerced_sent) break :check_sent;23119 if (dest_info.sentinel == coerced_sent) break :check_sent;
22893 }23120 }
22894 }23121 }
22895 return sema.failWithOwnedErrorMsg(block, msg: {23122 return sema.failWithOwnedErrorMsg(block, msg: {
22896 const msg = if (src_info.sentinel == .none) blk: {23123 const msg = if (src_info.sentinel == .none) blk: {
22897 break :blk try sema.errMsg(src, "destination pointer requires '{}' sentinel", .{23124 break :blk try sema.errMsg(src, "destination pointer requires '{}' sentinel", .{
22898 Value.fromInterned(dest_info.sentinel).fmtValue(mod, sema),23125 Value.fromInterned(dest_info.sentinel).fmtValue(pt, sema),
22899 });23126 });
22900 } else blk: {23127 } else blk: {
22901 break :blk try sema.errMsg(src, "pointer sentinel '{}' cannot coerce into pointer sentinel '{}'", .{23128 break :blk try sema.errMsg(src, "pointer sentinel '{}' cannot coerce into pointer sentinel '{}'", .{
22902 Value.fromInterned(src_info.sentinel).fmtValue(mod, sema),23129 Value.fromInterned(src_info.sentinel).fmtValue(pt, sema),
22903 Value.fromInterned(dest_info.sentinel).fmtValue(mod, sema),23130 Value.fromInterned(dest_info.sentinel).fmtValue(pt, sema),
22904 });23131 });
22905 };23132 };
22906 errdefer msg.destroy(sema.gpa);23133 errdefer msg.destroy(sema.gpa);
...@@ -22941,8 +23168,8 @@ fn ptrCastFull(...@@ -22941,8 +23168,8 @@ fn ptrCastFull(
2294123168
22942 return sema.failWithOwnedErrorMsg(block, msg: {23169 return sema.failWithOwnedErrorMsg(block, msg: {
22943 const msg = try sema.errMsg(src, "'{}' could have null values which are illegal in type '{}'", .{23170 const msg = try sema.errMsg(src, "'{}' could have null values which are illegal in type '{}'", .{
22944 operand_ty.fmt(mod),23171 operand_ty.fmt(pt),
22945 dest_ty.fmt(mod),23172 dest_ty.fmt(pt),
22946 });23173 });
22947 errdefer msg.destroy(sema.gpa);23174 errdefer msg.destroy(sema.gpa);
22948 try sema.errNote(src, msg, "use @ptrCast to assert the pointer is not null", .{});23175 try sema.errNote(src, msg, "use @ptrCast to assert the pointer is not null", .{});
...@@ -22956,12 +23183,12 @@ fn ptrCastFull(...@@ -22956,12 +23183,12 @@ fn ptrCastFull(
22956 const src_align = if (src_info.flags.alignment != .none)23183 const src_align = if (src_info.flags.alignment != .none)
22957 src_info.flags.alignment23184 src_info.flags.alignment
22958 else23185 else
22959 Type.fromInterned(src_info.child).abiAlignment(mod);23186 Type.fromInterned(src_info.child).abiAlignment(pt);
2296023187
22961 const dest_align = if (dest_info.flags.alignment != .none)23188 const dest_align = if (dest_info.flags.alignment != .none)
22962 dest_info.flags.alignment23189 dest_info.flags.alignment
22963 else23190 else
22964 Type.fromInterned(dest_info.child).abiAlignment(mod);23191 Type.fromInterned(dest_info.child).abiAlignment(pt);
2296523192
22966 if (!flags.align_cast) {23193 if (!flags.align_cast) {
22967 if (dest_align.compare(.gt, src_align)) {23194 if (dest_align.compare(.gt, src_align)) {
...@@ -22969,10 +23196,10 @@ fn ptrCastFull(...@@ -22969,10 +23196,10 @@ fn ptrCastFull(
22969 const msg = try sema.errMsg(src, "{s} increases pointer alignment", .{operation});23196 const msg = try sema.errMsg(src, "{s} increases pointer alignment", .{operation});
22970 errdefer msg.destroy(sema.gpa);23197 errdefer msg.destroy(sema.gpa);
22971 try sema.errNote(operand_src, msg, "'{}' has alignment '{d}'", .{23198 try sema.errNote(operand_src, msg, "'{}' has alignment '{d}'", .{
22972 operand_ty.fmt(mod), src_align.toByteUnits() orelse 0,23199 operand_ty.fmt(pt), src_align.toByteUnits() orelse 0,
22973 });23200 });
22974 try sema.errNote(src, msg, "'{}' has alignment '{d}'", .{23201 try sema.errNote(src, msg, "'{}' has alignment '{d}'", .{
22975 dest_ty.fmt(mod), dest_align.toByteUnits() orelse 0,23202 dest_ty.fmt(pt), dest_align.toByteUnits() orelse 0,
22976 });23203 });
22977 try sema.errNote(src, msg, "use @alignCast to assert pointer alignment", .{});23204 try sema.errNote(src, msg, "use @alignCast to assert pointer alignment", .{});
22978 break :msg msg;23205 break :msg msg;
...@@ -22986,10 +23213,10 @@ fn ptrCastFull(...@@ -22986,10 +23213,10 @@ fn ptrCastFull(
22986 const msg = try sema.errMsg(src, "{s} changes pointer address space", .{operation});23213 const msg = try sema.errMsg(src, "{s} changes pointer address space", .{operation});
22987 errdefer msg.destroy(sema.gpa);23214 errdefer msg.destroy(sema.gpa);
22988 try sema.errNote(operand_src, msg, "'{}' has address space '{s}'", .{23215 try sema.errNote(operand_src, msg, "'{}' has address space '{s}'", .{
22989 operand_ty.fmt(mod), @tagName(src_info.flags.address_space),23216 operand_ty.fmt(pt), @tagName(src_info.flags.address_space),
22990 });23217 });
22991 try sema.errNote(src, msg, "'{}' has address space '{s}'", .{23218 try sema.errNote(src, msg, "'{}' has address space '{s}'", .{
22992 dest_ty.fmt(mod), @tagName(dest_info.flags.address_space),23219 dest_ty.fmt(pt), @tagName(dest_info.flags.address_space),
22993 });23220 });
22994 try sema.errNote(src, msg, "use @addrSpaceCast to cast pointer address space", .{});23221 try sema.errNote(src, msg, "use @addrSpaceCast to cast pointer address space", .{});
22995 break :msg msg;23222 break :msg msg;
...@@ -23044,9 +23271,9 @@ fn ptrCastFull(...@@ -23044,9 +23271,9 @@ fn ptrCastFull(
23044 // Only convert to a many-pointer at first23271 // Only convert to a many-pointer at first
23045 var info = dest_info;23272 var info = dest_info;
23046 info.flags.size = .Many;23273 info.flags.size = .Many;
23047 const ty = try mod.ptrTypeSema(info);23274 const ty = try pt.ptrTypeSema(info);
23048 if (dest_ty.zigTypeTag(mod) == .Optional) {23275 if (dest_ty.zigTypeTag(mod) == .Optional) {
23049 break :blk try mod.optionalType(ty.toIntern());23276 break :blk try pt.optionalType(ty.toIntern());
23050 } else {23277 } else {
23051 break :blk ty;23278 break :blk ty;
23052 }23279 }
...@@ -23059,10 +23286,10 @@ fn ptrCastFull(...@@ -23059,10 +23286,10 @@ fn ptrCastFull(
23059 return sema.failWithUseOfUndef(block, operand_src);23286 return sema.failWithUseOfUndef(block, operand_src);
23060 }23287 }
23061 if (!dest_ty.ptrAllowsZero(mod) and ptr_val.isNull(mod)) {23288 if (!dest_ty.ptrAllowsZero(mod) and ptr_val.isNull(mod)) {
23062 return sema.fail(block, operand_src, "null pointer casted to type '{}'", .{dest_ty.fmt(mod)});23289 return sema.fail(block, operand_src, "null pointer casted to type '{}'", .{dest_ty.fmt(pt)});
23063 }23290 }
23064 if (dest_align.compare(.gt, src_align)) {23291 if (dest_align.compare(.gt, src_align)) {
23065 if (try ptr_val.getUnsignedIntAdvanced(mod, .sema)) |addr| {23292 if (try ptr_val.getUnsignedIntAdvanced(pt, .sema)) |addr| {
23066 if (!dest_align.check(addr)) {23293 if (!dest_align.check(addr)) {
23067 return sema.fail(block, operand_src, "pointer address 0x{X} is not aligned to {d} bytes", .{23294 return sema.fail(block, operand_src, "pointer address 0x{X} is not aligned to {d} bytes", .{
23068 addr,23295 addr,
...@@ -23072,12 +23299,12 @@ fn ptrCastFull(...@@ -23072,12 +23299,12 @@ fn ptrCastFull(
23072 }23299 }
23073 }23300 }
23074 if (dest_info.flags.size == .Slice and src_info.flags.size != .Slice) {23301 if (dest_info.flags.size == .Slice and src_info.flags.size != .Slice) {
23075 if (ptr_val.isUndef(mod)) return mod.undefRef(dest_ty);23302 if (ptr_val.isUndef(mod)) return pt.undefRef(dest_ty);
23076 const arr_len = try mod.intValue(Type.usize, Type.fromInterned(src_info.child).arrayLen(mod));23303 const arr_len = try pt.intValue(Type.usize, Type.fromInterned(src_info.child).arrayLen(mod));
23077 const ptr_val_key = mod.intern_pool.indexToKey(ptr_val.toIntern()).ptr;23304 const ptr_val_key = mod.intern_pool.indexToKey(ptr_val.toIntern()).ptr;
23078 return Air.internedToRef((try mod.intern(.{ .slice = .{23305 return Air.internedToRef((try pt.intern(.{ .slice = .{
23079 .ty = dest_ty.toIntern(),23306 .ty = dest_ty.toIntern(),
23080 .ptr = try mod.intern(.{ .ptr = .{23307 .ptr = try pt.intern(.{ .ptr = .{
23081 .ty = dest_ty.slicePtrFieldType(mod).toIntern(),23308 .ty = dest_ty.slicePtrFieldType(mod).toIntern(),
23082 .base_addr = ptr_val_key.base_addr,23309 .base_addr = ptr_val_key.base_addr,
23083 .byte_offset = ptr_val_key.byte_offset,23310 .byte_offset = ptr_val_key.byte_offset,
...@@ -23086,7 +23313,7 @@ fn ptrCastFull(...@@ -23086,7 +23313,7 @@ fn ptrCastFull(
23086 } })));23313 } })));
23087 } else {23314 } else {
23088 assert(dest_ptr_ty.eql(dest_ty, mod));23315 assert(dest_ptr_ty.eql(dest_ty, mod));
23089 return Air.internedToRef((try mod.getCoerced(ptr_val, dest_ty)).toIntern());23316 return Air.internedToRef((try pt.getCoerced(ptr_val, dest_ty)).toIntern());
23090 }23317 }
23091 }23318 }
23092 }23319 }
...@@ -23112,7 +23339,7 @@ fn ptrCastFull(...@@ -23112,7 +23339,7 @@ fn ptrCastFull(
23112 try sema.typeHasRuntimeBits(Type.fromInterned(dest_info.child)))23339 try sema.typeHasRuntimeBits(Type.fromInterned(dest_info.child)))
23113 {23340 {
23114 const align_bytes_minus_1 = dest_align.toByteUnits().? - 1;23341 const align_bytes_minus_1 = dest_align.toByteUnits().? - 1;
23115 const align_minus_1 = Air.internedToRef((try mod.intValue(Type.usize, align_bytes_minus_1)).toIntern());23342 const align_minus_1 = Air.internedToRef((try pt.intValue(Type.usize, align_bytes_minus_1)).toIntern());
23116 const ptr_int = try block.addUnOp(.int_from_ptr, ptr);23343 const ptr_int = try block.addUnOp(.int_from_ptr, ptr);
23117 const remainder = try block.addBinOp(.bit_and, ptr_int, align_minus_1);23344 const remainder = try block.addBinOp(.bit_and, ptr_int, align_minus_1);
23118 const is_aligned = try block.addBinOp(.cmp_eq, remainder, .zero_usize);23345 const is_aligned = try block.addBinOp(.cmp_eq, remainder, .zero_usize);
...@@ -23129,9 +23356,9 @@ fn ptrCastFull(...@@ -23129,9 +23356,9 @@ fn ptrCastFull(
23129 // We can't change address spaces with a bitcast, so this requires two instructions23356 // We can't change address spaces with a bitcast, so this requires two instructions
23130 var intermediate_info = src_info;23357 var intermediate_info = src_info;
23131 intermediate_info.flags.address_space = dest_info.flags.address_space;23358 intermediate_info.flags.address_space = dest_info.flags.address_space;
23132 const intermediate_ptr_ty = try mod.ptrTypeSema(intermediate_info);23359 const intermediate_ptr_ty = try pt.ptrTypeSema(intermediate_info);
23133 const intermediate_ty = if (dest_ptr_ty.zigTypeTag(mod) == .Optional) blk: {23360 const intermediate_ty = if (dest_ptr_ty.zigTypeTag(mod) == .Optional) blk: {
23134 break :blk try mod.optionalType(intermediate_ptr_ty.toIntern());23361 break :blk try pt.optionalType(intermediate_ptr_ty.toIntern());
23135 } else intermediate_ptr_ty;23362 } else intermediate_ptr_ty;
23136 const intermediate = try block.addInst(.{23363 const intermediate = try block.addInst(.{
23137 .tag = .addrspace_cast,23364 .tag = .addrspace_cast,
...@@ -23152,7 +23379,7 @@ fn ptrCastFull(...@@ -23152,7 +23379,7 @@ fn ptrCastFull(
23152 if (dest_info.flags.size == .Slice and src_info.flags.size != .Slice) {23379 if (dest_info.flags.size == .Slice and src_info.flags.size != .Slice) {
23153 // We have to construct a slice using the operand's child's array length23380 // We have to construct a slice using the operand's child's array length
23154 // Note that we know from the check at the start of the function that operand_ty is slice-like23381 // Note that we know from the check at the start of the function that operand_ty is slice-like
23155 const arr_len = Air.internedToRef((try mod.intValue(Type.usize, Type.fromInterned(src_info.child).arrayLen(mod))).toIntern());23382 const arr_len = Air.internedToRef((try pt.intValue(Type.usize, Type.fromInterned(src_info.child).arrayLen(mod))).toIntern());
23156 return block.addInst(.{23383 return block.addInst(.{
23157 .tag = .slice,23384 .tag = .slice,
23158 .data = .{ .ty_pl = .{23385 .data = .{ .ty_pl = .{
...@@ -23171,7 +23398,8 @@ fn ptrCastFull(...@@ -23171,7 +23398,8 @@ fn ptrCastFull(
23171}23398}
2317223399
23173fn zirPtrCastNoDest(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) CompileError!Air.Inst.Ref {23400fn zirPtrCastNoDest(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) CompileError!Air.Inst.Ref {
23174 const mod = sema.mod;23401 const pt = sema.pt;
23402 const mod = pt.zcu;
23175 const FlagsInt = @typeInfo(Zir.Inst.FullPtrCastFlags).Struct.backing_integer.?;23403 const FlagsInt = @typeInfo(Zir.Inst.FullPtrCastFlags).Struct.backing_integer.?;
23176 const flags: Zir.Inst.FullPtrCastFlags = @bitCast(@as(FlagsInt, @truncate(extended.small)));23404 const flags: Zir.Inst.FullPtrCastFlags = @bitCast(@as(FlagsInt, @truncate(extended.small)));
23177 const extra = sema.code.extraData(Zir.Inst.UnNode, extended.operand).data;23405 const extra = sema.code.extraData(Zir.Inst.UnNode, extended.operand).data;
...@@ -23186,15 +23414,15 @@ fn zirPtrCastNoDest(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.Inst...@@ -23186,15 +23414,15 @@ fn zirPtrCastNoDest(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.Inst
23186 if (flags.volatile_cast) ptr_info.flags.is_volatile = false;23414 if (flags.volatile_cast) ptr_info.flags.is_volatile = false;
2318723415
23188 const dest_ty = blk: {23416 const dest_ty = blk: {
23189 const dest_ty = try mod.ptrTypeSema(ptr_info);23417 const dest_ty = try pt.ptrTypeSema(ptr_info);
23190 if (operand_ty.zigTypeTag(mod) == .Optional) {23418 if (operand_ty.zigTypeTag(mod) == .Optional) {
23191 break :blk try mod.optionalType(dest_ty.toIntern());23419 break :blk try pt.optionalType(dest_ty.toIntern());
23192 }23420 }
23193 break :blk dest_ty;23421 break :blk dest_ty;
23194 };23422 };
2319523423
23196 if (try sema.resolveValue(operand)) |operand_val| {23424 if (try sema.resolveValue(operand)) |operand_val| {
23197 return Air.internedToRef((try mod.getCoerced(operand_val, dest_ty)).toIntern());23425 return Air.internedToRef((try pt.getCoerced(operand_val, dest_ty)).toIntern());
23198 }23426 }
2319923427
23200 try sema.requireRuntimeBlock(block, src, null);23428 try sema.requireRuntimeBlock(block, src, null);
...@@ -23204,7 +23432,8 @@ fn zirPtrCastNoDest(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.Inst...@@ -23204,7 +23432,8 @@ fn zirPtrCastNoDest(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.Inst
23204}23432}
2320523433
23206fn zirTruncate(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {23434fn zirTruncate(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
23207 const mod = sema.mod;23435 const pt = sema.pt;
23436 const mod = pt.zcu;
23208 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;23437 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
23209 const src = block.nodeOffset(inst_data.src_node);23438 const src = block.nodeOffset(inst_data.src_node);
23210 const operand_src = block.builtinCallArgSrc(inst_data.src_node, 0);23439 const operand_src = block.builtinCallArgSrc(inst_data.src_node, 0);
...@@ -23218,7 +23447,7 @@ fn zirTruncate(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -23218,7 +23447,7 @@ fn zirTruncate(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
23218 const operand_is_vector = operand_ty.zigTypeTag(mod) == .Vector;23447 const operand_is_vector = operand_ty.zigTypeTag(mod) == .Vector;
23219 const dest_is_vector = dest_ty.zigTypeTag(mod) == .Vector;23448 const dest_is_vector = dest_ty.zigTypeTag(mod) == .Vector;
23220 if (operand_is_vector != dest_is_vector) {23449 if (operand_is_vector != dest_is_vector) {
23221 return sema.fail(block, operand_src, "expected type '{}', found '{}'", .{ dest_ty.fmt(mod), operand_ty.fmt(mod) });23450 return sema.fail(block, operand_src, "expected type '{}', found '{}'", .{ dest_ty.fmt(pt), operand_ty.fmt(pt) });
23222 }23451 }
2322323452
23224 if (dest_scalar_ty.zigTypeTag(mod) == .ComptimeInt) {23453 if (dest_scalar_ty.zigTypeTag(mod) == .ComptimeInt) {
...@@ -23239,7 +23468,7 @@ fn zirTruncate(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -23239,7 +23468,7 @@ fn zirTruncate(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
2323923468
23240 if (operand_info.signedness != dest_info.signedness) {23469 if (operand_info.signedness != dest_info.signedness) {
23241 return sema.fail(block, operand_src, "expected {s} integer type, found '{}'", .{23470 return sema.fail(block, operand_src, "expected {s} integer type, found '{}'", .{
23242 @tagName(dest_info.signedness), operand_ty.fmt(mod),23471 @tagName(dest_info.signedness), operand_ty.fmt(pt),
23243 });23472 });
23244 }23473 }
23245 if (operand_info.bits < dest_info.bits) {23474 if (operand_info.bits < dest_info.bits) {
...@@ -23247,7 +23476,7 @@ fn zirTruncate(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -23247,7 +23476,7 @@ fn zirTruncate(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
23247 const msg = try sema.errMsg(23476 const msg = try sema.errMsg(
23248 src,23477 src,
23249 "destination type '{}' has more bits than source type '{}'",23478 "destination type '{}' has more bits than source type '{}'",
23250 .{ dest_ty.fmt(mod), operand_ty.fmt(mod) },23479 .{ dest_ty.fmt(pt), operand_ty.fmt(pt) },
23251 );23480 );
23252 errdefer msg.destroy(sema.gpa);23481 errdefer msg.destroy(sema.gpa);
23253 try sema.errNote(src, msg, "destination type has {d} bits", .{23482 try sema.errNote(src, msg, "destination type has {d} bits", .{
...@@ -23263,20 +23492,20 @@ fn zirTruncate(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -23263,20 +23492,20 @@ fn zirTruncate(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
23263 }23492 }
2326423493
23265 if (try sema.resolveValueIntable(operand)) |val| {23494 if (try sema.resolveValueIntable(operand)) |val| {
23266 if (val.isUndef(mod)) return mod.undefRef(dest_ty);23495 if (val.isUndef(mod)) return pt.undefRef(dest_ty);
23267 if (!dest_is_vector) {23496 if (!dest_is_vector) {
23268 return Air.internedToRef((try mod.getCoerced(23497 return Air.internedToRef((try pt.getCoerced(
23269 try val.intTrunc(operand_ty, sema.arena, dest_info.signedness, dest_info.bits, mod),23498 try val.intTrunc(operand_ty, sema.arena, dest_info.signedness, dest_info.bits, pt),
23270 dest_ty,23499 dest_ty,
23271 )).toIntern());23500 )).toIntern());
23272 }23501 }
23273 const elems = try sema.arena.alloc(InternPool.Index, operand_ty.vectorLen(mod));23502 const elems = try sema.arena.alloc(InternPool.Index, operand_ty.vectorLen(mod));
23274 for (elems, 0..) |*elem, i| {23503 for (elems, 0..) |*elem, i| {
23275 const elem_val = try val.elemValue(mod, i);23504 const elem_val = try val.elemValue(pt, i);
23276 const uncoerced_elem = try elem_val.intTrunc(operand_scalar_ty, sema.arena, dest_info.signedness, dest_info.bits, mod);23505 const uncoerced_elem = try elem_val.intTrunc(operand_scalar_ty, sema.arena, dest_info.signedness, dest_info.bits, pt);
23277 elem.* = (try mod.getCoerced(uncoerced_elem, dest_scalar_ty)).toIntern();23506 elem.* = (try pt.getCoerced(uncoerced_elem, dest_scalar_ty)).toIntern();
23278 }23507 }
23279 return Air.internedToRef((try mod.intern(.{ .aggregate = .{23508 return Air.internedToRef((try pt.intern(.{ .aggregate = .{
23280 .ty = dest_ty.toIntern(),23509 .ty = dest_ty.toIntern(),
23281 .storage = .{ .elems = elems },23510 .storage = .{ .elems = elems },
23282 } })));23511 } })));
...@@ -23291,9 +23520,10 @@ fn zirBitCount(...@@ -23291,9 +23520,10 @@ fn zirBitCount(
23291 block: *Block,23520 block: *Block,
23292 inst: Zir.Inst.Index,23521 inst: Zir.Inst.Index,
23293 air_tag: Air.Inst.Tag,23522 air_tag: Air.Inst.Tag,
23294 comptime comptimeOp: fn (val: Value, ty: Type, mod: *Module) u64,23523 comptime comptimeOp: fn (val: Value, ty: Type, pt: Zcu.PerThread) u64,
23295) CompileError!Air.Inst.Ref {23524) CompileError!Air.Inst.Ref {
23296 const mod = sema.mod;23525 const pt = sema.pt;
23526 const mod = pt.zcu;
23297 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;23527 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;
23298 const src = block.nodeOffset(inst_data.src_node);23528 const src = block.nodeOffset(inst_data.src_node);
23299 const operand_src = block.builtinCallArgSrc(inst_data.src_node, 0);23529 const operand_src = block.builtinCallArgSrc(inst_data.src_node, 0);
...@@ -23306,25 +23536,25 @@ fn zirBitCount(...@@ -23306,25 +23536,25 @@ fn zirBitCount(
23306 return Air.internedToRef(val.toIntern());23536 return Air.internedToRef(val.toIntern());
23307 }23537 }
2330823538
23309 const result_scalar_ty = try mod.smallestUnsignedInt(bits);23539 const result_scalar_ty = try pt.smallestUnsignedInt(bits);
23310 switch (operand_ty.zigTypeTag(mod)) {23540 switch (operand_ty.zigTypeTag(mod)) {
23311 .Vector => {23541 .Vector => {
23312 const vec_len = operand_ty.vectorLen(mod);23542 const vec_len = operand_ty.vectorLen(mod);
23313 const result_ty = try mod.vectorType(.{23543 const result_ty = try pt.vectorType(.{
23314 .len = vec_len,23544 .len = vec_len,
23315 .child = result_scalar_ty.toIntern(),23545 .child = result_scalar_ty.toIntern(),
23316 });23546 });
23317 if (try sema.resolveValue(operand)) |val| {23547 if (try sema.resolveValue(operand)) |val| {
23318 if (val.isUndef(mod)) return mod.undefRef(result_ty);23548 if (val.isUndef(mod)) return pt.undefRef(result_ty);
2331923549
23320 const elems = try sema.arena.alloc(InternPool.Index, vec_len);23550 const elems = try sema.arena.alloc(InternPool.Index, vec_len);
23321 const scalar_ty = operand_ty.scalarType(mod);23551 const scalar_ty = operand_ty.scalarType(mod);
23322 for (elems, 0..) |*elem, i| {23552 for (elems, 0..) |*elem, i| {
23323 const elem_val = try val.elemValue(mod, i);23553 const elem_val = try val.elemValue(pt, i);
23324 const count = comptimeOp(elem_val, scalar_ty, mod);23554 const count = comptimeOp(elem_val, scalar_ty, pt);
23325 elem.* = (try mod.intValue(result_scalar_ty, count)).toIntern();23555 elem.* = (try pt.intValue(result_scalar_ty, count)).toIntern();
23326 }23556 }
23327 return Air.internedToRef((try mod.intern(.{ .aggregate = .{23557 return Air.internedToRef((try pt.intern(.{ .aggregate = .{
23328 .ty = result_ty.toIntern(),23558 .ty = result_ty.toIntern(),
23329 .storage = .{ .elems = elems },23559 .storage = .{ .elems = elems },
23330 } })));23560 } })));
...@@ -23335,8 +23565,8 @@ fn zirBitCount(...@@ -23335,8 +23565,8 @@ fn zirBitCount(
23335 },23565 },
23336 .Int => {23566 .Int => {
23337 if (try sema.resolveValueResolveLazy(operand)) |val| {23567 if (try sema.resolveValueResolveLazy(operand)) |val| {
23338 if (val.isUndef(mod)) return mod.undefRef(result_scalar_ty);23568 if (val.isUndef(mod)) return pt.undefRef(result_scalar_ty);
23339 return mod.intRef(result_scalar_ty, comptimeOp(val, operand_ty, mod));23569 return pt.intRef(result_scalar_ty, comptimeOp(val, operand_ty, pt));
23340 } else {23570 } else {
23341 try sema.requireRuntimeBlock(block, src, operand_src);23571 try sema.requireRuntimeBlock(block, src, operand_src);
23342 return block.addTyOp(air_tag, result_scalar_ty, operand);23572 return block.addTyOp(air_tag, result_scalar_ty, operand);
...@@ -23347,7 +23577,8 @@ fn zirBitCount(...@@ -23347,7 +23577,8 @@ fn zirBitCount(
23347}23577}
2334823578
23349fn zirByteSwap(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {23579fn zirByteSwap(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
23350 const mod = sema.mod;23580 const pt = sema.pt;
23581 const mod = pt.zcu;
23351 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;23582 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;
23352 const src = block.nodeOffset(inst_data.src_node);23583 const src = block.nodeOffset(inst_data.src_node);
23353 const operand_src = block.builtinCallArgSrc(inst_data.src_node, 0);23584 const operand_src = block.builtinCallArgSrc(inst_data.src_node, 0);
...@@ -23360,7 +23591,7 @@ fn zirByteSwap(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -23360,7 +23591,7 @@ fn zirByteSwap(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
23360 block,23591 block,
23361 operand_src,23592 operand_src,
23362 "@byteSwap requires the number of bits to be evenly divisible by 8, but {} has {} bits",23593 "@byteSwap requires the number of bits to be evenly divisible by 8, but {} has {} bits",
23363 .{ scalar_ty.fmt(mod), bits },23594 .{ scalar_ty.fmt(pt), bits },
23364 );23595 );
23365 }23596 }
2336623597
...@@ -23371,8 +23602,8 @@ fn zirByteSwap(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -23371,8 +23602,8 @@ fn zirByteSwap(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
23371 switch (operand_ty.zigTypeTag(mod)) {23602 switch (operand_ty.zigTypeTag(mod)) {
23372 .Int => {23603 .Int => {
23373 const runtime_src = if (try sema.resolveValue(operand)) |val| {23604 const runtime_src = if (try sema.resolveValue(operand)) |val| {
23374 if (val.isUndef(mod)) return mod.undefRef(operand_ty);23605 if (val.isUndef(mod)) return pt.undefRef(operand_ty);
23375 const result_val = try val.byteSwap(operand_ty, mod, sema.arena);23606 const result_val = try val.byteSwap(operand_ty, pt, sema.arena);
23376 return Air.internedToRef(result_val.toIntern());23607 return Air.internedToRef(result_val.toIntern());
23377 } else operand_src;23608 } else operand_src;
2337823609
...@@ -23382,15 +23613,15 @@ fn zirByteSwap(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -23382,15 +23613,15 @@ fn zirByteSwap(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
23382 .Vector => {23613 .Vector => {
23383 const runtime_src = if (try sema.resolveValue(operand)) |val| {23614 const runtime_src = if (try sema.resolveValue(operand)) |val| {
23384 if (val.isUndef(mod))23615 if (val.isUndef(mod))
23385 return mod.undefRef(operand_ty);23616 return pt.undefRef(operand_ty);
2338623617
23387 const vec_len = operand_ty.vectorLen(mod);23618 const vec_len = operand_ty.vectorLen(mod);
23388 const elems = try sema.arena.alloc(InternPool.Index, vec_len);23619 const elems = try sema.arena.alloc(InternPool.Index, vec_len);
23389 for (elems, 0..) |*elem, i| {23620 for (elems, 0..) |*elem, i| {
23390 const elem_val = try val.elemValue(mod, i);23621 const elem_val = try val.elemValue(pt, i);
23391 elem.* = (try elem_val.byteSwap(scalar_ty, mod, sema.arena)).toIntern();23622 elem.* = (try elem_val.byteSwap(scalar_ty, pt, sema.arena)).toIntern();
23392 }23623 }
23393 return Air.internedToRef((try mod.intern(.{ .aggregate = .{23624 return Air.internedToRef((try pt.intern(.{ .aggregate = .{
23394 .ty = operand_ty.toIntern(),23625 .ty = operand_ty.toIntern(),
23395 .storage = .{ .elems = elems },23626 .storage = .{ .elems = elems },
23396 } })));23627 } })));
...@@ -23415,12 +23646,13 @@ fn zirBitReverse(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!...@@ -23415,12 +23646,13 @@ fn zirBitReverse(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!
23415 return Air.internedToRef(val.toIntern());23646 return Air.internedToRef(val.toIntern());
23416 }23647 }
2341723648
23418 const mod = sema.mod;23649 const pt = sema.pt;
23650 const mod = pt.zcu;
23419 switch (operand_ty.zigTypeTag(mod)) {23651 switch (operand_ty.zigTypeTag(mod)) {
23420 .Int => {23652 .Int => {
23421 const runtime_src = if (try sema.resolveValue(operand)) |val| {23653 const runtime_src = if (try sema.resolveValue(operand)) |val| {
23422 if (val.isUndef(mod)) return mod.undefRef(operand_ty);23654 if (val.isUndef(mod)) return pt.undefRef(operand_ty);
23423 const result_val = try val.bitReverse(operand_ty, mod, sema.arena);23655 const result_val = try val.bitReverse(operand_ty, pt, sema.arena);
23424 return Air.internedToRef(result_val.toIntern());23656 return Air.internedToRef(result_val.toIntern());
23425 } else operand_src;23657 } else operand_src;
2342623658
...@@ -23430,15 +23662,15 @@ fn zirBitReverse(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!...@@ -23430,15 +23662,15 @@ fn zirBitReverse(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!
23430 .Vector => {23662 .Vector => {
23431 const runtime_src = if (try sema.resolveValue(operand)) |val| {23663 const runtime_src = if (try sema.resolveValue(operand)) |val| {
23432 if (val.isUndef(mod))23664 if (val.isUndef(mod))
23433 return mod.undefRef(operand_ty);23665 return pt.undefRef(operand_ty);
2343423666
23435 const vec_len = operand_ty.vectorLen(mod);23667 const vec_len = operand_ty.vectorLen(mod);
23436 const elems = try sema.arena.alloc(InternPool.Index, vec_len);23668 const elems = try sema.arena.alloc(InternPool.Index, vec_len);
23437 for (elems, 0..) |*elem, i| {23669 for (elems, 0..) |*elem, i| {
23438 const elem_val = try val.elemValue(mod, i);23670 const elem_val = try val.elemValue(pt, i);
23439 elem.* = (try elem_val.bitReverse(scalar_ty, mod, sema.arena)).toIntern();23671 elem.* = (try elem_val.bitReverse(scalar_ty, pt, sema.arena)).toIntern();
23440 }23672 }
23441 return Air.internedToRef((try mod.intern(.{ .aggregate = .{23673 return Air.internedToRef((try pt.intern(.{ .aggregate = .{
23442 .ty = operand_ty.toIntern(),23674 .ty = operand_ty.toIntern(),
23443 .storage = .{ .elems = elems },23675 .storage = .{ .elems = elems },
23444 } })));23676 } })));
...@@ -23453,13 +23685,13 @@ fn zirBitReverse(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!...@@ -23453,13 +23685,13 @@ fn zirBitReverse(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!
2345323685
23454fn zirBitOffsetOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {23686fn zirBitOffsetOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
23455 const offset = try sema.bitOffsetOf(block, inst);23687 const offset = try sema.bitOffsetOf(block, inst);
23456 return sema.mod.intRef(Type.comptime_int, offset);23688 return sema.pt.intRef(Type.comptime_int, offset);
23457}23689}
2345823690
23459fn zirOffsetOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {23691fn zirOffsetOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
23460 const offset = try sema.bitOffsetOf(block, inst);23692 const offset = try sema.bitOffsetOf(block, inst);
23461 // TODO reminder to make this a compile error for packed structs23693 // TODO reminder to make this a compile error for packed structs
23462 return sema.mod.intRef(Type.comptime_int, offset / 8);23694 return sema.pt.intRef(Type.comptime_int, offset / 8);
23463}23695}
2346423696
23465fn bitOffsetOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!u64 {23697fn bitOffsetOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!u64 {
...@@ -23474,12 +23706,13 @@ fn bitOffsetOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!u6...@@ -23474,12 +23706,13 @@ fn bitOffsetOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!u6
23474 .needed_comptime_reason = "name of field must be comptime-known",23706 .needed_comptime_reason = "name of field must be comptime-known",
23475 });23707 });
2347623708
23477 const mod = sema.mod;23709 const pt = sema.pt;
23710 const mod = pt.zcu;
23478 const ip = &mod.intern_pool;23711 const ip = &mod.intern_pool;
23479 try ty.resolveLayout(mod);23712 try ty.resolveLayout(pt);
23480 switch (ty.zigTypeTag(mod)) {23713 switch (ty.zigTypeTag(mod)) {
23481 .Struct => {},23714 .Struct => {},
23482 else => return sema.fail(block, lhs_src, "expected struct type, found '{}'", .{ty.fmt(mod)}),23715 else => return sema.fail(block, lhs_src, "expected struct type, found '{}'", .{ty.fmt(pt)}),
23483 }23716 }
2348423717
23485 const field_index = if (ty.isTuple(mod)) blk: {23718 const field_index = if (ty.isTuple(mod)) blk: {
...@@ -23502,28 +23735,30 @@ fn bitOffsetOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!u6...@@ -23502,28 +23735,30 @@ fn bitOffsetOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!u6
23502 return bit_sum;23735 return bit_sum;
23503 }23736 }
23504 const field_ty = Type.fromInterned(struct_type.field_types.get(ip)[i]);23737 const field_ty = Type.fromInterned(struct_type.field_types.get(ip)[i]);
23505 bit_sum += field_ty.bitSize(mod);23738 bit_sum += field_ty.bitSize(pt);
23506 } else unreachable;23739 } else unreachable;
23507 },23740 },
23508 else => return ty.structFieldOffset(field_index, mod) * 8,23741 else => return ty.structFieldOffset(field_index, pt) * 8,
23509 }23742 }
23510}23743}
2351123744
23512fn checkNamespaceType(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type) CompileError!void {23745fn checkNamespaceType(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type) CompileError!void {
23513 const mod = sema.mod;23746 const pt = sema.pt;
23747 const mod = pt.zcu;
23514 switch (ty.zigTypeTag(mod)) {23748 switch (ty.zigTypeTag(mod)) {
23515 .Struct, .Enum, .Union, .Opaque => return,23749 .Struct, .Enum, .Union, .Opaque => return,
23516 else => return sema.fail(block, src, "expected struct, enum, union, or opaque; found '{}'", .{ty.fmt(mod)}),23750 else => return sema.fail(block, src, "expected struct, enum, union, or opaque; found '{}'", .{ty.fmt(pt)}),
23517 }23751 }
23518}23752}
2351923753
23520/// Returns `true` if the type was a comptime_int.23754/// Returns `true` if the type was a comptime_int.
23521fn checkIntType(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type) CompileError!bool {23755fn checkIntType(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type) CompileError!bool {
23522 const mod = sema.mod;23756 const pt = sema.pt;
23757 const mod = pt.zcu;
23523 switch (try ty.zigTypeTagOrPoison(mod)) {23758 switch (try ty.zigTypeTagOrPoison(mod)) {
23524 .ComptimeInt => return true,23759 .ComptimeInt => return true,
23525 .Int => return false,23760 .Int => return false,
23526 else => return sema.fail(block, src, "expected integer type, found '{}'", .{ty.fmt(mod)}),23761 else => return sema.fail(block, src, "expected integer type, found '{}'", .{ty.fmt(pt)}),
23527 }23762 }
23528}23763}
2352923764
...@@ -23533,7 +23768,8 @@ fn checkInvalidPtrArithmetic(...@@ -23533,7 +23768,8 @@ fn checkInvalidPtrArithmetic(
23533 src: LazySrcLoc,23768 src: LazySrcLoc,
23534 ty: Type,23769 ty: Type,
23535) CompileError!void {23770) CompileError!void {
23536 const mod = sema.mod;23771 const pt = sema.pt;
23772 const mod = pt.zcu;
23537 switch (try ty.zigTypeTagOrPoison(mod)) {23773 switch (try ty.zigTypeTagOrPoison(mod)) {
23538 .Pointer => switch (ty.ptrSize(mod)) {23774 .Pointer => switch (ty.ptrSize(mod)) {
23539 .One, .Slice => return,23775 .One, .Slice => return,
...@@ -23573,7 +23809,8 @@ fn checkPtrOperand(...@@ -23573,7 +23809,8 @@ fn checkPtrOperand(
23573 ty_src: LazySrcLoc,23809 ty_src: LazySrcLoc,
23574 ty: Type,23810 ty: Type,
23575) CompileError!void {23811) CompileError!void {
23576 const mod = sema.mod;23812 const pt = sema.pt;
23813 const mod = pt.zcu;
23577 switch (ty.zigTypeTag(mod)) {23814 switch (ty.zigTypeTag(mod)) {
23578 .Pointer => return,23815 .Pointer => return,
23579 .Fn => {23816 .Fn => {
...@@ -23581,7 +23818,7 @@ fn checkPtrOperand(...@@ -23581,7 +23818,7 @@ fn checkPtrOperand(
23581 const msg = try sema.errMsg(23818 const msg = try sema.errMsg(
23582 ty_src,23819 ty_src,
23583 "expected pointer, found '{}'",23820 "expected pointer, found '{}'",
23584 .{ty.fmt(mod)},23821 .{ty.fmt(pt)},
23585 );23822 );
23586 errdefer msg.destroy(sema.gpa);23823 errdefer msg.destroy(sema.gpa);
2358723824
...@@ -23594,7 +23831,7 @@ fn checkPtrOperand(...@@ -23594,7 +23831,7 @@ fn checkPtrOperand(
23594 .Optional => if (ty.childType(mod).zigTypeTag(mod) == .Pointer) return,23831 .Optional => if (ty.childType(mod).zigTypeTag(mod) == .Pointer) return,
23595 else => {},23832 else => {},
23596 }23833 }
23597 return sema.fail(block, ty_src, "expected pointer type, found '{}'", .{ty.fmt(mod)});23834 return sema.fail(block, ty_src, "expected pointer type, found '{}'", .{ty.fmt(pt)});
23598}23835}
2359923836
23600fn checkPtrType(23837fn checkPtrType(
...@@ -23604,7 +23841,8 @@ fn checkPtrType(...@@ -23604,7 +23841,8 @@ fn checkPtrType(
23604 ty: Type,23841 ty: Type,
23605 allow_slice: bool,23842 allow_slice: bool,
23606) CompileError!void {23843) CompileError!void {
23607 const mod = sema.mod;23844 const pt = sema.pt;
23845 const mod = pt.zcu;
23608 switch (ty.zigTypeTag(mod)) {23846 switch (ty.zigTypeTag(mod)) {
23609 .Pointer => if (allow_slice or !ty.isSlice(mod)) return,23847 .Pointer => if (allow_slice or !ty.isSlice(mod)) return,
23610 .Fn => {23848 .Fn => {
...@@ -23612,7 +23850,7 @@ fn checkPtrType(...@@ -23612,7 +23850,7 @@ fn checkPtrType(
23612 const msg = try sema.errMsg(23850 const msg = try sema.errMsg(
23613 ty_src,23851 ty_src,
23614 "expected pointer type, found '{}'",23852 "expected pointer type, found '{}'",
23615 .{ty.fmt(mod)},23853 .{ty.fmt(pt)},
23616 );23854 );
23617 errdefer msg.destroy(sema.gpa);23855 errdefer msg.destroy(sema.gpa);
2361823856
...@@ -23625,7 +23863,7 @@ fn checkPtrType(...@@ -23625,7 +23863,7 @@ fn checkPtrType(
23625 .Optional => if (ty.childType(mod).zigTypeTag(mod) == .Pointer) return,23863 .Optional => if (ty.childType(mod).zigTypeTag(mod) == .Pointer) return,
23626 else => {},23864 else => {},
23627 }23865 }
23628 return sema.fail(block, ty_src, "expected pointer type, found '{}'", .{ty.fmt(mod)});23866 return sema.fail(block, ty_src, "expected pointer type, found '{}'", .{ty.fmt(pt)});
23629}23867}
2363023868
23631fn checkVectorElemType(23869fn checkVectorElemType(
...@@ -23634,13 +23872,14 @@ fn checkVectorElemType(...@@ -23634,13 +23872,14 @@ fn checkVectorElemType(
23634 ty_src: LazySrcLoc,23872 ty_src: LazySrcLoc,
23635 ty: Type,23873 ty: Type,
23636) CompileError!void {23874) CompileError!void {
23637 const mod = sema.mod;23875 const pt = sema.pt;
23876 const mod = pt.zcu;
23638 switch (ty.zigTypeTag(mod)) {23877 switch (ty.zigTypeTag(mod)) {
23639 .Int, .Float, .Bool => return,23878 .Int, .Float, .Bool => return,
23640 .Optional, .Pointer => if (ty.isPtrAtRuntime(mod)) return,23879 .Optional, .Pointer => if (ty.isPtrAtRuntime(mod)) return,
23641 else => {},23880 else => {},
23642 }23881 }
23643 return sema.fail(block, ty_src, "expected integer, float, bool, or pointer for the vector element type; found '{}'", .{ty.fmt(mod)});23882 return sema.fail(block, ty_src, "expected integer, float, bool, or pointer for the vector element type; found '{}'", .{ty.fmt(pt)});
23644}23883}
2364523884
23646fn checkFloatType(23885fn checkFloatType(
...@@ -23649,10 +23888,11 @@ fn checkFloatType(...@@ -23649,10 +23888,11 @@ fn checkFloatType(
23649 ty_src: LazySrcLoc,23888 ty_src: LazySrcLoc,
23650 ty: Type,23889 ty: Type,
23651) CompileError!void {23890) CompileError!void {
23652 const mod = sema.mod;23891 const pt = sema.pt;
23892 const mod = pt.zcu;
23653 switch (ty.zigTypeTag(mod)) {23893 switch (ty.zigTypeTag(mod)) {
23654 .ComptimeInt, .ComptimeFloat, .Float => {},23894 .ComptimeInt, .ComptimeFloat, .Float => {},
23655 else => return sema.fail(block, ty_src, "expected float type, found '{}'", .{ty.fmt(mod)}),23895 else => return sema.fail(block, ty_src, "expected float type, found '{}'", .{ty.fmt(pt)}),
23656 }23896 }
23657}23897}
2365823898
...@@ -23662,14 +23902,15 @@ fn checkNumericType(...@@ -23662,14 +23902,15 @@ fn checkNumericType(
23662 ty_src: LazySrcLoc,23902 ty_src: LazySrcLoc,
23663 ty: Type,23903 ty: Type,
23664) CompileError!void {23904) CompileError!void {
23665 const mod = sema.mod;23905 const pt = sema.pt;
23906 const mod = pt.zcu;
23666 switch (ty.zigTypeTag(mod)) {23907 switch (ty.zigTypeTag(mod)) {
23667 .ComptimeFloat, .Float, .ComptimeInt, .Int => {},23908 .ComptimeFloat, .Float, .ComptimeInt, .Int => {},
23668 .Vector => switch (ty.childType(mod).zigTypeTag(mod)) {23909 .Vector => switch (ty.childType(mod).zigTypeTag(mod)) {
23669 .ComptimeFloat, .Float, .ComptimeInt, .Int => {},23910 .ComptimeFloat, .Float, .ComptimeInt, .Int => {},
23670 else => |t| return sema.fail(block, ty_src, "expected number, found '{}'", .{t}),23911 else => |t| return sema.fail(block, ty_src, "expected number, found '{}'", .{t}),
23671 },23912 },
23672 else => return sema.fail(block, ty_src, "expected number, found '{}'", .{ty.fmt(mod)}),23913 else => return sema.fail(block, ty_src, "expected number, found '{}'", .{ty.fmt(pt)}),
23673 }23914 }
23674}23915}
2367523916
...@@ -23683,7 +23924,8 @@ fn checkAtomicPtrOperand(...@@ -23683,7 +23924,8 @@ fn checkAtomicPtrOperand(
23683 ptr_src: LazySrcLoc,23924 ptr_src: LazySrcLoc,
23684 ptr_const: bool,23925 ptr_const: bool,
23685) CompileError!Air.Inst.Ref {23926) CompileError!Air.Inst.Ref {
23686 const mod = sema.mod;23927 const pt = sema.pt;
23928 const mod = pt.zcu;
23687 var diag: Module.AtomicPtrAlignmentDiagnostics = .{};23929 var diag: Module.AtomicPtrAlignmentDiagnostics = .{};
23688 const alignment = mod.atomicPtrAlignment(elem_ty, &diag) catch |err| switch (err) {23930 const alignment = mod.atomicPtrAlignment(elem_ty, &diag) catch |err| switch (err) {
23689 error.OutOfMemory => return error.OutOfMemory,23931 error.OutOfMemory => return error.OutOfMemory,
...@@ -23703,7 +23945,7 @@ fn checkAtomicPtrOperand(...@@ -23703,7 +23945,7 @@ fn checkAtomicPtrOperand(
23703 block,23945 block,
23704 elem_ty_src,23946 elem_ty_src,
23705 "expected bool, integer, float, enum, or pointer type; found '{}'",23947 "expected bool, integer, float, enum, or pointer type; found '{}'",
23706 .{elem_ty.fmt(mod)},23948 .{elem_ty.fmt(pt)},
23707 ),23949 ),
23708 };23950 };
2370923951
...@@ -23719,7 +23961,7 @@ fn checkAtomicPtrOperand(...@@ -23719,7 +23961,7 @@ fn checkAtomicPtrOperand(
23719 const ptr_data = switch (try ptr_ty.zigTypeTagOrPoison(mod)) {23961 const ptr_data = switch (try ptr_ty.zigTypeTagOrPoison(mod)) {
23720 .Pointer => ptr_ty.ptrInfo(mod),23962 .Pointer => ptr_ty.ptrInfo(mod),
23721 else => {23963 else => {
23722 const wanted_ptr_ty = try mod.ptrTypeSema(wanted_ptr_data);23964 const wanted_ptr_ty = try pt.ptrTypeSema(wanted_ptr_data);
23723 _ = try sema.coerce(block, wanted_ptr_ty, ptr, ptr_src);23965 _ = try sema.coerce(block, wanted_ptr_ty, ptr, ptr_src);
23724 unreachable;23966 unreachable;
23725 },23967 },
...@@ -23729,7 +23971,7 @@ fn checkAtomicPtrOperand(...@@ -23729,7 +23971,7 @@ fn checkAtomicPtrOperand(
23729 wanted_ptr_data.flags.is_allowzero = ptr_data.flags.is_allowzero;23971 wanted_ptr_data.flags.is_allowzero = ptr_data.flags.is_allowzero;
23730 wanted_ptr_data.flags.is_volatile = ptr_data.flags.is_volatile;23972 wanted_ptr_data.flags.is_volatile = ptr_data.flags.is_volatile;
2373123973
23732 const wanted_ptr_ty = try mod.ptrTypeSema(wanted_ptr_data);23974 const wanted_ptr_ty = try pt.ptrTypeSema(wanted_ptr_data);
23733 const casted_ptr = try sema.coerce(block, wanted_ptr_ty, ptr, ptr_src);23975 const casted_ptr = try sema.coerce(block, wanted_ptr_ty, ptr, ptr_src);
2373423976
23735 return casted_ptr;23977 return casted_ptr;
...@@ -23754,7 +23996,8 @@ fn checkIntOrVector(...@@ -23754,7 +23996,8 @@ fn checkIntOrVector(
23754 operand: Air.Inst.Ref,23996 operand: Air.Inst.Ref,
23755 operand_src: LazySrcLoc,23997 operand_src: LazySrcLoc,
23756) CompileError!Type {23998) CompileError!Type {
23757 const mod = sema.mod;23999 const pt = sema.pt;
24000 const mod = pt.zcu;
23758 const operand_ty = sema.typeOf(operand);24001 const operand_ty = sema.typeOf(operand);
23759 switch (try operand_ty.zigTypeTagOrPoison(mod)) {24002 switch (try operand_ty.zigTypeTagOrPoison(mod)) {
23760 .Int => return operand_ty,24003 .Int => return operand_ty,
...@@ -23763,12 +24006,12 @@ fn checkIntOrVector(...@@ -23763,12 +24006,12 @@ fn checkIntOrVector(
23763 switch (try elem_ty.zigTypeTagOrPoison(mod)) {24006 switch (try elem_ty.zigTypeTagOrPoison(mod)) {
23764 .Int => return elem_ty,24007 .Int => return elem_ty,
23765 else => return sema.fail(block, operand_src, "expected vector of integers; found vector of '{}'", .{24008 else => return sema.fail(block, operand_src, "expected vector of integers; found vector of '{}'", .{
23766 elem_ty.fmt(mod),24009 elem_ty.fmt(pt),
23767 }),24010 }),
23768 }24011 }
23769 },24012 },
23770 else => return sema.fail(block, operand_src, "expected integer or vector, found '{}'", .{24013 else => return sema.fail(block, operand_src, "expected integer or vector, found '{}'", .{
23771 operand_ty.fmt(mod),24014 operand_ty.fmt(pt),
23772 }),24015 }),
23773 }24016 }
23774}24017}
...@@ -23779,7 +24022,8 @@ fn checkIntOrVectorAllowComptime(...@@ -23779,7 +24022,8 @@ fn checkIntOrVectorAllowComptime(
23779 operand_ty: Type,24022 operand_ty: Type,
23780 operand_src: LazySrcLoc,24023 operand_src: LazySrcLoc,
23781) CompileError!Type {24024) CompileError!Type {
23782 const mod = sema.mod;24025 const pt = sema.pt;
24026 const mod = pt.zcu;
23783 switch (try operand_ty.zigTypeTagOrPoison(mod)) {24027 switch (try operand_ty.zigTypeTagOrPoison(mod)) {
23784 .Int, .ComptimeInt => return operand_ty,24028 .Int, .ComptimeInt => return operand_ty,
23785 .Vector => {24029 .Vector => {
...@@ -23787,12 +24031,12 @@ fn checkIntOrVectorAllowComptime(...@@ -23787,12 +24031,12 @@ fn checkIntOrVectorAllowComptime(
23787 switch (try elem_ty.zigTypeTagOrPoison(mod)) {24031 switch (try elem_ty.zigTypeTagOrPoison(mod)) {
23788 .Int, .ComptimeInt => return elem_ty,24032 .Int, .ComptimeInt => return elem_ty,
23789 else => return sema.fail(block, operand_src, "expected vector of integers; found vector of '{}'", .{24033 else => return sema.fail(block, operand_src, "expected vector of integers; found vector of '{}'", .{
23790 elem_ty.fmt(mod),24034 elem_ty.fmt(pt),
23791 }),24035 }),
23792 }24036 }
23793 },24037 },
23794 else => return sema.fail(block, operand_src, "expected integer or vector, found '{}'", .{24038 else => return sema.fail(block, operand_src, "expected integer or vector, found '{}'", .{
23795 operand_ty.fmt(mod),24039 operand_ty.fmt(pt),
23796 }),24040 }),
23797 }24041 }
23798}24042}
...@@ -23819,7 +24063,8 @@ fn checkSimdBinOp(...@@ -23819,7 +24063,8 @@ fn checkSimdBinOp(
23819 lhs_src: LazySrcLoc,24063 lhs_src: LazySrcLoc,
23820 rhs_src: LazySrcLoc,24064 rhs_src: LazySrcLoc,
23821) CompileError!SimdBinOp {24065) CompileError!SimdBinOp {
23822 const mod = sema.mod;24066 const pt = sema.pt;
24067 const mod = pt.zcu;
23823 const lhs_ty = sema.typeOf(uncasted_lhs);24068 const lhs_ty = sema.typeOf(uncasted_lhs);
23824 const rhs_ty = sema.typeOf(uncasted_rhs);24069 const rhs_ty = sema.typeOf(uncasted_rhs);
2382524070
...@@ -23851,7 +24096,8 @@ fn checkVectorizableBinaryOperands(...@@ -23851,7 +24096,8 @@ fn checkVectorizableBinaryOperands(
23851 lhs_src: LazySrcLoc,24096 lhs_src: LazySrcLoc,
23852 rhs_src: LazySrcLoc,24097 rhs_src: LazySrcLoc,
23853) CompileError!void {24098) CompileError!void {
23854 const mod = sema.mod;24099 const pt = sema.pt;
24100 const mod = pt.zcu;
23855 const lhs_zig_ty_tag = try lhs_ty.zigTypeTagOrPoison(mod);24101 const lhs_zig_ty_tag = try lhs_ty.zigTypeTagOrPoison(mod);
23856 const rhs_zig_ty_tag = try rhs_ty.zigTypeTagOrPoison(mod);24102 const rhs_zig_ty_tag = try rhs_ty.zigTypeTagOrPoison(mod);
23857 if (lhs_zig_ty_tag != .Vector and rhs_zig_ty_tag != .Vector) return;24103 if (lhs_zig_ty_tag != .Vector and rhs_zig_ty_tag != .Vector) return;
...@@ -23881,7 +24127,7 @@ fn checkVectorizableBinaryOperands(...@@ -23881,7 +24127,7 @@ fn checkVectorizableBinaryOperands(
23881 } else {24127 } else {
23882 const msg = msg: {24128 const msg = msg: {
23883 const msg = try sema.errMsg(src, "mixed scalar and vector operands: '{}' and '{}'", .{24129 const msg = try sema.errMsg(src, "mixed scalar and vector operands: '{}' and '{}'", .{
23884 lhs_ty.fmt(mod), rhs_ty.fmt(mod),24130 lhs_ty.fmt(pt), rhs_ty.fmt(pt),
23885 });24131 });
23886 errdefer msg.destroy(sema.gpa);24132 errdefer msg.destroy(sema.gpa);
23887 if (lhs_is_vector) {24133 if (lhs_is_vector) {
...@@ -23903,10 +24149,11 @@ fn resolveExportOptions(...@@ -23903,10 +24149,11 @@ fn resolveExportOptions(
23903 src: LazySrcLoc,24149 src: LazySrcLoc,
23904 zir_ref: Zir.Inst.Ref,24150 zir_ref: Zir.Inst.Ref,
23905) CompileError!Module.Export.Options {24151) CompileError!Module.Export.Options {
23906 const mod = sema.mod;24152 const pt = sema.pt;
24153 const mod = pt.zcu;
23907 const gpa = sema.gpa;24154 const gpa = sema.gpa;
23908 const ip = &mod.intern_pool;24155 const ip = &mod.intern_pool;
23909 const export_options_ty = try mod.getBuiltinType("ExportOptions");24156 const export_options_ty = try pt.getBuiltinType("ExportOptions");
23910 const air_ref = try sema.resolveInst(zir_ref);24157 const air_ref = try sema.resolveInst(zir_ref);
23911 const options = try sema.coerce(block, export_options_ty, air_ref, src);24158 const options = try sema.coerce(block, export_options_ty, air_ref, src);
2391224159
...@@ -23915,18 +24162,18 @@ fn resolveExportOptions(...@@ -23915,18 +24162,18 @@ fn resolveExportOptions(
23915 const section_src = block.src(.{ .init_field_section = src.offset.node_offset_builtin_call_arg.builtin_call_node });24162 const section_src = block.src(.{ .init_field_section = src.offset.node_offset_builtin_call_arg.builtin_call_node });
23916 const visibility_src = block.src(.{ .init_field_visibility = src.offset.node_offset_builtin_call_arg.builtin_call_node });24163 const visibility_src = block.src(.{ .init_field_visibility = src.offset.node_offset_builtin_call_arg.builtin_call_node });
2391724164
23918 const name_operand = try sema.fieldVal(block, src, options, try ip.getOrPutString(gpa, "name", .no_embedded_nulls), name_src);24165 const name_operand = try sema.fieldVal(block, src, options, try ip.getOrPutString(gpa, pt.tid, "name", .no_embedded_nulls), name_src);
23919 const name = try sema.toConstString(block, name_src, name_operand, .{24166 const name = try sema.toConstString(block, name_src, name_operand, .{
23920 .needed_comptime_reason = "name of exported value must be comptime-known",24167 .needed_comptime_reason = "name of exported value must be comptime-known",
23921 });24168 });
2392224169
23923 const linkage_operand = try sema.fieldVal(block, src, options, try ip.getOrPutString(gpa, "linkage", .no_embedded_nulls), linkage_src);24170 const linkage_operand = try sema.fieldVal(block, src, options, try ip.getOrPutString(gpa, pt.tid, "linkage", .no_embedded_nulls), linkage_src);
23924 const linkage_val = try sema.resolveConstDefinedValue(block, linkage_src, linkage_operand, .{24171 const linkage_val = try sema.resolveConstDefinedValue(block, linkage_src, linkage_operand, .{
23925 .needed_comptime_reason = "linkage of exported value must be comptime-known",24172 .needed_comptime_reason = "linkage of exported value must be comptime-known",
23926 });24173 });
23927 const linkage = mod.toEnum(std.builtin.GlobalLinkage, linkage_val);24174 const linkage = mod.toEnum(std.builtin.GlobalLinkage, linkage_val);
2392824175
23929 const section_operand = try sema.fieldVal(block, src, options, try ip.getOrPutString(gpa, "section", .no_embedded_nulls), section_src);24176 const section_operand = try sema.fieldVal(block, src, options, try ip.getOrPutString(gpa, pt.tid, "section", .no_embedded_nulls), section_src);
23930 const section_opt_val = try sema.resolveConstDefinedValue(block, section_src, section_operand, .{24177 const section_opt_val = try sema.resolveConstDefinedValue(block, section_src, section_operand, .{
23931 .needed_comptime_reason = "linksection of exported value must be comptime-known",24178 .needed_comptime_reason = "linksection of exported value must be comptime-known",
23932 });24179 });
...@@ -23937,7 +24184,7 @@ fn resolveExportOptions(...@@ -23937,7 +24184,7 @@ fn resolveExportOptions(
23937 else24184 else
23938 null;24185 null;
2393924186
23940 const visibility_operand = try sema.fieldVal(block, src, options, try ip.getOrPutString(gpa, "visibility", .no_embedded_nulls), visibility_src);24187 const visibility_operand = try sema.fieldVal(block, src, options, try ip.getOrPutString(gpa, pt.tid, "visibility", .no_embedded_nulls), visibility_src);
23941 const visibility_val = try sema.resolveConstDefinedValue(block, visibility_src, visibility_operand, .{24188 const visibility_val = try sema.resolveConstDefinedValue(block, visibility_src, visibility_operand, .{
23942 .needed_comptime_reason = "visibility of exported value must be comptime-known",24189 .needed_comptime_reason = "visibility of exported value must be comptime-known",
23943 });24190 });
...@@ -23954,9 +24201,9 @@ fn resolveExportOptions(...@@ -23954,9 +24201,9 @@ fn resolveExportOptions(
23954 }24201 }
2395524202
23956 return .{24203 return .{
23957 .name = try ip.getOrPutString(gpa, name, .no_embedded_nulls),24204 .name = try ip.getOrPutString(gpa, pt.tid, name, .no_embedded_nulls),
23958 .linkage = linkage,24205 .linkage = linkage,
23959 .section = try ip.getOrPutStringOpt(gpa, section, .no_embedded_nulls),24206 .section = try ip.getOrPutStringOpt(gpa, pt.tid, section, .no_embedded_nulls),
23960 .visibility = visibility,24207 .visibility = visibility,
23961 };24208 };
23962}24209}
...@@ -23969,12 +24216,12 @@ fn resolveBuiltinEnum(...@@ -23969,12 +24216,12 @@ fn resolveBuiltinEnum(
23969 comptime name: []const u8,24216 comptime name: []const u8,
23970 reason: NeededComptimeReason,24217 reason: NeededComptimeReason,
23971) CompileError!@field(std.builtin, name) {24218) CompileError!@field(std.builtin, name) {
23972 const mod = sema.mod;24219 const pt = sema.pt;
23973 const ty = try mod.getBuiltinType(name);24220 const ty = try pt.getBuiltinType(name);
23974 const air_ref = try sema.resolveInst(zir_ref);24221 const air_ref = try sema.resolveInst(zir_ref);
23975 const coerced = try sema.coerce(block, ty, air_ref, src);24222 const coerced = try sema.coerce(block, ty, air_ref, src);
23976 const val = try sema.resolveConstDefinedValue(block, src, coerced, reason);24223 const val = try sema.resolveConstDefinedValue(block, src, coerced, reason);
23977 return mod.toEnum(@field(std.builtin, name), val);24224 return pt.zcu.toEnum(@field(std.builtin, name), val);
23978}24225}
2397924226
23980fn resolveAtomicOrder(24227fn resolveAtomicOrder(
...@@ -24003,7 +24250,8 @@ fn zirCmpxchg(...@@ -24003,7 +24250,8 @@ fn zirCmpxchg(
24003 block: *Block,24250 block: *Block,
24004 extended: Zir.Inst.Extended.InstData,24251 extended: Zir.Inst.Extended.InstData,
24005) CompileError!Air.Inst.Ref {24252) CompileError!Air.Inst.Ref {
24006 const mod = sema.mod;24253 const pt = sema.pt;
24254 const mod = pt.zcu;
24007 const extra = sema.code.extraData(Zir.Inst.Cmpxchg, extended.operand).data;24255 const extra = sema.code.extraData(Zir.Inst.Cmpxchg, extended.operand).data;
24008 const air_tag: Air.Inst.Tag = switch (extended.small) {24256 const air_tag: Air.Inst.Tag = switch (extended.small) {
24009 0 => .cmpxchg_weak,24257 0 => .cmpxchg_weak,
...@@ -24026,7 +24274,7 @@ fn zirCmpxchg(...@@ -24026,7 +24274,7 @@ fn zirCmpxchg(
24026 block,24274 block,
24027 elem_ty_src,24275 elem_ty_src,
24028 "expected bool, integer, enum, or pointer type; found '{}'",24276 "expected bool, integer, enum, or pointer type; found '{}'",
24029 .{elem_ty.fmt(mod)},24277 .{elem_ty.fmt(pt)},
24030 );24278 );
24031 }24279 }
24032 const uncasted_ptr = try sema.resolveInst(extra.ptr);24280 const uncasted_ptr = try sema.resolveInst(extra.ptr);
...@@ -24052,11 +24300,11 @@ fn zirCmpxchg(...@@ -24052,11 +24300,11 @@ fn zirCmpxchg(
24052 return sema.fail(block, failure_order_src, "failure atomic ordering must not be release or acq_rel", .{});24300 return sema.fail(block, failure_order_src, "failure atomic ordering must not be release or acq_rel", .{});
24053 }24301 }
2405424302
24055 const result_ty = try mod.optionalType(elem_ty.toIntern());24303 const result_ty = try pt.optionalType(elem_ty.toIntern());
2405624304
24057 // special case zero bit types24305 // special case zero bit types
24058 if ((try sema.typeHasOnePossibleValue(elem_ty)) != null) {24306 if ((try sema.typeHasOnePossibleValue(elem_ty)) != null) {
24059 return Air.internedToRef((try mod.intern(.{ .opt = .{24307 return Air.internedToRef((try pt.intern(.{ .opt = .{
24060 .ty = result_ty.toIntern(),24308 .ty = result_ty.toIntern(),
24061 .val = .none,24309 .val = .none,
24062 } })));24310 } })));
...@@ -24068,11 +24316,11 @@ fn zirCmpxchg(...@@ -24068,11 +24316,11 @@ fn zirCmpxchg(
24068 if (expected_val.isUndef(mod) or new_val.isUndef(mod)) {24316 if (expected_val.isUndef(mod) or new_val.isUndef(mod)) {
24069 // TODO: this should probably cause the memory stored at the pointer24317 // TODO: this should probably cause the memory stored at the pointer
24070 // to become undef as well24318 // to become undef as well
24071 return mod.undefRef(result_ty);24319 return pt.undefRef(result_ty);
24072 }24320 }
24073 const ptr_ty = sema.typeOf(ptr);24321 const ptr_ty = sema.typeOf(ptr);
24074 const stored_val = (try sema.pointerDeref(block, ptr_src, ptr_val, ptr_ty)) orelse break :rs ptr_src;24322 const stored_val = (try sema.pointerDeref(block, ptr_src, ptr_val, ptr_ty)) orelse break :rs ptr_src;
24075 const result_val = try mod.intern(.{ .opt = .{24323 const result_val = try pt.intern(.{ .opt = .{
24076 .ty = result_ty.toIntern(),24324 .ty = result_ty.toIntern(),
24077 .val = if (stored_val.eql(expected_val, elem_ty, mod)) blk: {24325 .val = if (stored_val.eql(expected_val, elem_ty, mod)) blk: {
24078 try sema.storePtr(block, src, ptr, new_value);24326 try sema.storePtr(block, src, ptr, new_value);
...@@ -24103,17 +24351,18 @@ fn zirCmpxchg(...@@ -24103,17 +24351,18 @@ fn zirCmpxchg(
24103}24351}
2410424352
24105fn zirSplat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {24353fn zirSplat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
24106 const mod = sema.mod;24354 const pt = sema.pt;
24355 const mod = pt.zcu;
24107 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;24356 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
24108 const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data;24357 const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data;
24109 const src = block.nodeOffset(inst_data.src_node);24358 const src = block.nodeOffset(inst_data.src_node);
24110 const scalar_src = block.builtinCallArgSrc(inst_data.src_node, 0);24359 const scalar_src = block.builtinCallArgSrc(inst_data.src_node, 0);
24111 const dest_ty = try sema.resolveDestType(block, src, extra.lhs, .remove_eu_opt, "@splat");24360 const dest_ty = try sema.resolveDestType(block, src, extra.lhs, .remove_eu_opt, "@splat");
2411224361
24113 if (!dest_ty.isVector(mod)) return sema.fail(block, src, "expected vector type, found '{}'", .{dest_ty.fmt(mod)});24362 if (!dest_ty.isVector(mod)) return sema.fail(block, src, "expected vector type, found '{}'", .{dest_ty.fmt(pt)});
2411424363
24115 if (!dest_ty.hasRuntimeBits(mod)) {24364 if (!dest_ty.hasRuntimeBits(pt)) {
24116 const empty_aggregate = try mod.intern(.{ .aggregate = .{24365 const empty_aggregate = try pt.intern(.{ .aggregate = .{
24117 .ty = dest_ty.toIntern(),24366 .ty = dest_ty.toIntern(),
24118 .storage = .{ .elems = &[_]InternPool.Index{} },24367 .storage = .{ .elems = &[_]InternPool.Index{} },
24119 } });24368 } });
...@@ -24124,7 +24373,7 @@ fn zirSplat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I...@@ -24124,7 +24373,7 @@ fn zirSplat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I
24124 const scalar_ty = dest_ty.childType(mod);24373 const scalar_ty = dest_ty.childType(mod);
24125 const scalar = try sema.coerce(block, scalar_ty, operand, scalar_src);24374 const scalar = try sema.coerce(block, scalar_ty, operand, scalar_src);
24126 if (try sema.resolveValue(scalar)) |scalar_val| {24375 if (try sema.resolveValue(scalar)) |scalar_val| {
24127 if (scalar_val.isUndef(mod)) return mod.undefRef(dest_ty);24376 if (scalar_val.isUndef(mod)) return pt.undefRef(dest_ty);
24128 return Air.internedToRef((try sema.splat(dest_ty, scalar_val)).toIntern());24377 return Air.internedToRef((try sema.splat(dest_ty, scalar_val)).toIntern());
24129 }24378 }
2413024379
...@@ -24142,10 +24391,11 @@ fn zirReduce(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air....@@ -24142,10 +24391,11 @@ fn zirReduce(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.
24142 });24391 });
24143 const operand = try sema.resolveInst(extra.rhs);24392 const operand = try sema.resolveInst(extra.rhs);
24144 const operand_ty = sema.typeOf(operand);24393 const operand_ty = sema.typeOf(operand);
24145 const mod = sema.mod;24394 const pt = sema.pt;
24395 const mod = pt.zcu;
2414624396
24147 if (operand_ty.zigTypeTag(mod) != .Vector) {24397 if (operand_ty.zigTypeTag(mod) != .Vector) {
24148 return sema.fail(block, operand_src, "expected vector, found '{}'", .{operand_ty.fmt(mod)});24398 return sema.fail(block, operand_src, "expected vector, found '{}'", .{operand_ty.fmt(pt)});
24149 }24399 }
2415024400
24151 const scalar_ty = operand_ty.childType(mod);24401 const scalar_ty = operand_ty.childType(mod);
...@@ -24155,13 +24405,13 @@ fn zirReduce(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air....@@ -24155,13 +24405,13 @@ fn zirReduce(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.
24155 .And, .Or, .Xor => switch (scalar_ty.zigTypeTag(mod)) {24405 .And, .Or, .Xor => switch (scalar_ty.zigTypeTag(mod)) {
24156 .Int, .Bool => {},24406 .Int, .Bool => {},
24157 else => return sema.fail(block, operand_src, "@reduce operation '{s}' requires integer or boolean operand; found '{}'", .{24407 else => return sema.fail(block, operand_src, "@reduce operation '{s}' requires integer or boolean operand; found '{}'", .{
24158 @tagName(operation), operand_ty.fmt(mod),24408 @tagName(operation), operand_ty.fmt(pt),
24159 }),24409 }),
24160 },24410 },
24161 .Min, .Max, .Add, .Mul => switch (scalar_ty.zigTypeTag(mod)) {24411 .Min, .Max, .Add, .Mul => switch (scalar_ty.zigTypeTag(mod)) {
24162 .Int, .Float => {},24412 .Int, .Float => {},
24163 else => return sema.fail(block, operand_src, "@reduce operation '{s}' requires integer or float operand; found '{}'", .{24413 else => return sema.fail(block, operand_src, "@reduce operation '{s}' requires integer or float operand; found '{}'", .{
24164 @tagName(operation), operand_ty.fmt(mod),24414 @tagName(operation), operand_ty.fmt(pt),
24165 }),24415 }),
24166 },24416 },
24167 }24417 }
...@@ -24174,20 +24424,20 @@ fn zirReduce(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air....@@ -24174,20 +24424,20 @@ fn zirReduce(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.
24174 }24424 }
2417524425
24176 if (try sema.resolveValue(operand)) |operand_val| {24426 if (try sema.resolveValue(operand)) |operand_val| {
24177 if (operand_val.isUndef(mod)) return mod.undefRef(scalar_ty);24427 if (operand_val.isUndef(mod)) return pt.undefRef(scalar_ty);
2417824428
24179 var accum: Value = try operand_val.elemValue(mod, 0);24429 var accum: Value = try operand_val.elemValue(pt, 0);
24180 var i: u32 = 1;24430 var i: u32 = 1;
24181 while (i < vec_len) : (i += 1) {24431 while (i < vec_len) : (i += 1) {
24182 const elem_val = try operand_val.elemValue(mod, i);24432 const elem_val = try operand_val.elemValue(pt, i);
24183 switch (operation) {24433 switch (operation) {
24184 .And => accum = try accum.bitwiseAnd(elem_val, scalar_ty, sema.arena, mod),24434 .And => accum = try accum.bitwiseAnd(elem_val, scalar_ty, sema.arena, pt),
24185 .Or => accum = try accum.bitwiseOr(elem_val, scalar_ty, sema.arena, mod),24435 .Or => accum = try accum.bitwiseOr(elem_val, scalar_ty, sema.arena, pt),
24186 .Xor => accum = try accum.bitwiseXor(elem_val, scalar_ty, sema.arena, mod),24436 .Xor => accum = try accum.bitwiseXor(elem_val, scalar_ty, sema.arena, pt),
24187 .Min => accum = accum.numberMin(elem_val, mod),24437 .Min => accum = accum.numberMin(elem_val, pt),
24188 .Max => accum = accum.numberMax(elem_val, mod),24438 .Max => accum = accum.numberMax(elem_val, pt),
24189 .Add => accum = try sema.numberAddWrapScalar(accum, elem_val, scalar_ty),24439 .Add => accum = try sema.numberAddWrapScalar(accum, elem_val, scalar_ty),
24190 .Mul => accum = try accum.numberMulWrap(elem_val, scalar_ty, sema.arena, mod),24440 .Mul => accum = try accum.numberMulWrap(elem_val, scalar_ty, sema.arena, pt),
24191 }24441 }
24192 }24442 }
24193 return Air.internedToRef(accum.toIntern());24443 return Air.internedToRef(accum.toIntern());
...@@ -24204,7 +24454,8 @@ fn zirReduce(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air....@@ -24204,7 +24454,8 @@ fn zirReduce(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.
24204}24454}
2420524455
24206fn zirShuffle(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {24456fn zirShuffle(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
24207 const mod = sema.mod;24457 const pt = sema.pt;
24458 const mod = pt.zcu;
24208 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;24459 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
24209 const extra = sema.code.extraData(Zir.Inst.Shuffle, inst_data.payload_index).data;24460 const extra = sema.code.extraData(Zir.Inst.Shuffle, inst_data.payload_index).data;
24210 const elem_ty_src = block.builtinCallArgSrc(inst_data.src_node, 0);24461 const elem_ty_src = block.builtinCallArgSrc(inst_data.src_node, 0);
...@@ -24219,9 +24470,9 @@ fn zirShuffle(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air...@@ -24219,9 +24470,9 @@ fn zirShuffle(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
2421924470
24220 const mask_len = switch (sema.typeOf(mask).zigTypeTag(mod)) {24471 const mask_len = switch (sema.typeOf(mask).zigTypeTag(mod)) {
24221 .Array, .Vector => sema.typeOf(mask).arrayLen(mod),24472 .Array, .Vector => sema.typeOf(mask).arrayLen(mod),
24222 else => return sema.fail(block, mask_src, "expected vector or array, found '{}'", .{sema.typeOf(mask).fmt(sema.mod)}),24473 else => return sema.fail(block, mask_src, "expected vector or array, found '{}'", .{sema.typeOf(mask).fmt(pt)}),
24223 };24474 };
24224 mask_ty = try mod.vectorType(.{24475 mask_ty = try pt.vectorType(.{
24225 .len = @intCast(mask_len),24476 .len = @intCast(mask_len),
24226 .child = .i32_type,24477 .child = .i32_type,
24227 });24478 });
...@@ -24242,51 +24493,51 @@ fn analyzeShuffle(...@@ -24242,51 +24493,51 @@ fn analyzeShuffle(
24242 mask: Value,24493 mask: Value,
24243 mask_len: u32,24494 mask_len: u32,
24244) CompileError!Air.Inst.Ref {24495) CompileError!Air.Inst.Ref {
24245 const mod = sema.mod;24496 const pt = sema.pt;
24246 const a_src = block.builtinCallArgSrc(src_node, 1);24497 const a_src = block.builtinCallArgSrc(src_node, 1);
24247 const b_src = block.builtinCallArgSrc(src_node, 2);24498 const b_src = block.builtinCallArgSrc(src_node, 2);
24248 const mask_src = block.builtinCallArgSrc(src_node, 3);24499 const mask_src = block.builtinCallArgSrc(src_node, 3);
24249 var a = a_arg;24500 var a = a_arg;
24250 var b = b_arg;24501 var b = b_arg;
2425124502
24252 const res_ty = try mod.vectorType(.{24503 const res_ty = try pt.vectorType(.{
24253 .len = mask_len,24504 .len = mask_len,
24254 .child = elem_ty.toIntern(),24505 .child = elem_ty.toIntern(),
24255 });24506 });
2425624507
24257 const maybe_a_len = switch (sema.typeOf(a).zigTypeTag(mod)) {24508 const maybe_a_len = switch (sema.typeOf(a).zigTypeTag(pt.zcu)) {
24258 .Array, .Vector => sema.typeOf(a).arrayLen(mod),24509 .Array, .Vector => sema.typeOf(a).arrayLen(pt.zcu),
24259 .Undefined => null,24510 .Undefined => null,
24260 else => return sema.fail(block, a_src, "expected vector or array with element type '{}', found '{}'", .{24511 else => return sema.fail(block, a_src, "expected vector or array with element type '{}', found '{}'", .{
24261 elem_ty.fmt(sema.mod),24512 elem_ty.fmt(pt),
24262 sema.typeOf(a).fmt(sema.mod),24513 sema.typeOf(a).fmt(pt),
24263 }),24514 }),
24264 };24515 };
24265 const maybe_b_len = switch (sema.typeOf(b).zigTypeTag(mod)) {24516 const maybe_b_len = switch (sema.typeOf(b).zigTypeTag(pt.zcu)) {
24266 .Array, .Vector => sema.typeOf(b).arrayLen(mod),24517 .Array, .Vector => sema.typeOf(b).arrayLen(pt.zcu),
24267 .Undefined => null,24518 .Undefined => null,
24268 else => return sema.fail(block, b_src, "expected vector or array with element type '{}', found '{}'", .{24519 else => return sema.fail(block, b_src, "expected vector or array with element type '{}', found '{}'", .{
24269 elem_ty.fmt(sema.mod),24520 elem_ty.fmt(pt),
24270 sema.typeOf(b).fmt(sema.mod),24521 sema.typeOf(b).fmt(pt),
24271 }),24522 }),
24272 };24523 };
24273 if (maybe_a_len == null and maybe_b_len == null) {24524 if (maybe_a_len == null and maybe_b_len == null) {
24274 return mod.undefRef(res_ty);24525 return pt.undefRef(res_ty);
24275 }24526 }
24276 const a_len: u32 = @intCast(maybe_a_len orelse maybe_b_len.?);24527 const a_len: u32 = @intCast(maybe_a_len orelse maybe_b_len.?);
24277 const b_len: u32 = @intCast(maybe_b_len orelse a_len);24528 const b_len: u32 = @intCast(maybe_b_len orelse a_len);
2427824529
24279 const a_ty = try mod.vectorType(.{24530 const a_ty = try pt.vectorType(.{
24280 .len = a_len,24531 .len = a_len,
24281 .child = elem_ty.toIntern(),24532 .child = elem_ty.toIntern(),
24282 });24533 });
24283 const b_ty = try mod.vectorType(.{24534 const b_ty = try pt.vectorType(.{
24284 .len = b_len,24535 .len = b_len,
24285 .child = elem_ty.toIntern(),24536 .child = elem_ty.toIntern(),
24286 });24537 });
2428724538
24288 if (maybe_a_len == null) a = try mod.undefRef(a_ty) else a = try sema.coerce(block, a_ty, a, a_src);24539 if (maybe_a_len == null) a = try pt.undefRef(a_ty) else a = try sema.coerce(block, a_ty, a, a_src);
24289 if (maybe_b_len == null) b = try mod.undefRef(b_ty) else b = try sema.coerce(block, b_ty, b, b_src);24540 if (maybe_b_len == null) b = try pt.undefRef(b_ty) else b = try sema.coerce(block, b_ty, b, b_src);
2429024541
24291 const operand_info = [2]std.meta.Tuple(&.{ u64, LazySrcLoc, Type }){24542 const operand_info = [2]std.meta.Tuple(&.{ u64, LazySrcLoc, Type }){
24292 .{ a_len, a_src, a_ty },24543 .{ a_len, a_src, a_ty },
...@@ -24294,10 +24545,10 @@ fn analyzeShuffle(...@@ -24294,10 +24545,10 @@ fn analyzeShuffle(
24294 };24545 };
2429524546
24296 for (0..@intCast(mask_len)) |i| {24547 for (0..@intCast(mask_len)) |i| {
24297 const elem = try mask.elemValue(sema.mod, i);24548 const elem = try mask.elemValue(pt, i);
24298 if (elem.isUndef(mod)) continue;24549 if (elem.isUndef(pt.zcu)) continue;
24299 const elem_resolved = try sema.resolveLazyValue(elem);24550 const elem_resolved = try sema.resolveLazyValue(elem);
24300 const int = elem_resolved.toSignedInt(mod);24551 const int = elem_resolved.toSignedInt(pt);
24301 var unsigned: u32 = undefined;24552 var unsigned: u32 = undefined;
24302 var chosen: u32 = undefined;24553 var chosen: u32 = undefined;
24303 if (int >= 0) {24554 if (int >= 0) {
...@@ -24314,7 +24565,7 @@ fn analyzeShuffle(...@@ -24314,7 +24565,7 @@ fn analyzeShuffle(
2431424565
24315 try sema.errNote(operand_info[chosen][1], msg, "selected index '{d}' out of bounds of '{}'", .{24566 try sema.errNote(operand_info[chosen][1], msg, "selected index '{d}' out of bounds of '{}'", .{
24316 unsigned,24567 unsigned,
24317 operand_info[chosen][2].fmt(sema.mod),24568 operand_info[chosen][2].fmt(pt),
24318 });24569 });
2431924570
24320 if (chosen == 0) {24571 if (chosen == 0) {
...@@ -24331,16 +24582,16 @@ fn analyzeShuffle(...@@ -24331,16 +24582,16 @@ fn analyzeShuffle(
24331 if (try sema.resolveValue(b)) |b_val| {24582 if (try sema.resolveValue(b)) |b_val| {
24332 const values = try sema.arena.alloc(InternPool.Index, mask_len);24583 const values = try sema.arena.alloc(InternPool.Index, mask_len);
24333 for (values, 0..) |*value, i| {24584 for (values, 0..) |*value, i| {
24334 const mask_elem_val = try mask.elemValue(sema.mod, i);24585 const mask_elem_val = try mask.elemValue(pt, i);
24335 if (mask_elem_val.isUndef(mod)) {24586 if (mask_elem_val.isUndef(pt.zcu)) {
24336 value.* = try mod.intern(.{ .undef = elem_ty.toIntern() });24587 value.* = try pt.intern(.{ .undef = elem_ty.toIntern() });
24337 continue;24588 continue;
24338 }24589 }
24339 const int = mask_elem_val.toSignedInt(mod);24590 const int = mask_elem_val.toSignedInt(pt);
24340 const unsigned: u32 = @intCast(if (int >= 0) int else ~int);24591 const unsigned: u32 = @intCast(if (int >= 0) int else ~int);
24341 values[i] = (try (if (int >= 0) a_val else b_val).elemValue(mod, unsigned)).toIntern();24592 values[i] = (try (if (int >= 0) a_val else b_val).elemValue(pt, unsigned)).toIntern();
24342 }24593 }
24343 return Air.internedToRef((try mod.intern(.{ .aggregate = .{24594 return Air.internedToRef((try pt.intern(.{ .aggregate = .{
24344 .ty = res_ty.toIntern(),24595 .ty = res_ty.toIntern(),
24345 .storage = .{ .elems = values },24596 .storage = .{ .elems = values },
24346 } })));24597 } })));
...@@ -24359,21 +24610,21 @@ fn analyzeShuffle(...@@ -24359,21 +24610,21 @@ fn analyzeShuffle(
2435924610
24360 const expand_mask_values = try sema.arena.alloc(InternPool.Index, max_len);24611 const expand_mask_values = try sema.arena.alloc(InternPool.Index, max_len);
24361 for (@intCast(0)..@intCast(min_len)) |i| {24612 for (@intCast(0)..@intCast(min_len)) |i| {
24362 expand_mask_values[i] = (try mod.intValue(Type.comptime_int, i)).toIntern();24613 expand_mask_values[i] = (try pt.intValue(Type.comptime_int, i)).toIntern();
24363 }24614 }
24364 for (@intCast(min_len)..@intCast(max_len)) |i| {24615 for (@intCast(min_len)..@intCast(max_len)) |i| {
24365 expand_mask_values[i] = (try mod.intValue(Type.comptime_int, -1)).toIntern();24616 expand_mask_values[i] = (try pt.intValue(Type.comptime_int, -1)).toIntern();
24366 }24617 }
24367 const expand_mask = try mod.intern(.{ .aggregate = .{24618 const expand_mask = try pt.intern(.{ .aggregate = .{
24368 .ty = (try mod.vectorType(.{ .len = @intCast(max_len), .child = .comptime_int_type })).toIntern(),24619 .ty = (try pt.vectorType(.{ .len = @intCast(max_len), .child = .comptime_int_type })).toIntern(),
24369 .storage = .{ .elems = expand_mask_values },24620 .storage = .{ .elems = expand_mask_values },
24370 } });24621 } });
2437124622
24372 if (a_len < b_len) {24623 if (a_len < b_len) {
24373 const undef = try mod.undefRef(a_ty);24624 const undef = try pt.undefRef(a_ty);
24374 a = try sema.analyzeShuffle(block, src_node, elem_ty, a, undef, Value.fromInterned(expand_mask), @intCast(max_len));24625 a = try sema.analyzeShuffle(block, src_node, elem_ty, a, undef, Value.fromInterned(expand_mask), @intCast(max_len));
24375 } else {24626 } else {
24376 const undef = try mod.undefRef(b_ty);24627 const undef = try pt.undefRef(b_ty);
24377 b = try sema.analyzeShuffle(block, src_node, elem_ty, b, undef, Value.fromInterned(expand_mask), @intCast(max_len));24628 b = try sema.analyzeShuffle(block, src_node, elem_ty, b, undef, Value.fromInterned(expand_mask), @intCast(max_len));
24378 }24629 }
24379 }24630 }
...@@ -24393,7 +24644,8 @@ fn analyzeShuffle(...@@ -24393,7 +24644,8 @@ fn analyzeShuffle(
24393}24644}
2439424645
24395fn zirSelect(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) CompileError!Air.Inst.Ref {24646fn zirSelect(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) CompileError!Air.Inst.Ref {
24396 const mod = sema.mod;24647 const pt = sema.pt;
24648 const mod = pt.zcu;
24397 const extra = sema.code.extraData(Zir.Inst.Select, extended.operand).data;24649 const extra = sema.code.extraData(Zir.Inst.Select, extended.operand).data;
2439824650
24399 const src = block.nodeOffset(extra.node);24651 const src = block.nodeOffset(extra.node);
...@@ -24409,17 +24661,17 @@ fn zirSelect(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) C...@@ -24409,17 +24661,17 @@ fn zirSelect(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) C
2440924661
24410 const vec_len_u64 = switch (try pred_ty.zigTypeTagOrPoison(mod)) {24662 const vec_len_u64 = switch (try pred_ty.zigTypeTagOrPoison(mod)) {
24411 .Vector, .Array => pred_ty.arrayLen(mod),24663 .Vector, .Array => pred_ty.arrayLen(mod),
24412 else => return sema.fail(block, pred_src, "expected vector or array, found '{}'", .{pred_ty.fmt(mod)}),24664 else => return sema.fail(block, pred_src, "expected vector or array, found '{}'", .{pred_ty.fmt(pt)}),
24413 };24665 };
24414 const vec_len: u32 = @intCast(try sema.usizeCast(block, pred_src, vec_len_u64));24666 const vec_len: u32 = @intCast(try sema.usizeCast(block, pred_src, vec_len_u64));
2441524667
24416 const bool_vec_ty = try mod.vectorType(.{24668 const bool_vec_ty = try pt.vectorType(.{
24417 .len = vec_len,24669 .len = vec_len,
24418 .child = .bool_type,24670 .child = .bool_type,
24419 });24671 });
24420 const pred = try sema.coerce(block, bool_vec_ty, pred_uncoerced, pred_src);24672 const pred = try sema.coerce(block, bool_vec_ty, pred_uncoerced, pred_src);
2442124673
24422 const vec_ty = try mod.vectorType(.{24674 const vec_ty = try pt.vectorType(.{
24423 .len = vec_len,24675 .len = vec_len,
24424 .child = elem_ty.toIntern(),24676 .child = elem_ty.toIntern(),
24425 });24677 });
...@@ -24431,23 +24683,23 @@ fn zirSelect(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) C...@@ -24431,23 +24683,23 @@ fn zirSelect(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) C
24431 const maybe_b = try sema.resolveValue(b);24683 const maybe_b = try sema.resolveValue(b);
2443224684
24433 const runtime_src = if (maybe_pred) |pred_val| rs: {24685 const runtime_src = if (maybe_pred) |pred_val| rs: {
24434 if (pred_val.isUndef(mod)) return mod.undefRef(vec_ty);24686 if (pred_val.isUndef(mod)) return pt.undefRef(vec_ty);
2443524687
24436 if (maybe_a) |a_val| {24688 if (maybe_a) |a_val| {
24437 if (a_val.isUndef(mod)) return mod.undefRef(vec_ty);24689 if (a_val.isUndef(mod)) return pt.undefRef(vec_ty);
2443824690
24439 if (maybe_b) |b_val| {24691 if (maybe_b) |b_val| {
24440 if (b_val.isUndef(mod)) return mod.undefRef(vec_ty);24692 if (b_val.isUndef(mod)) return pt.undefRef(vec_ty);
2444124693
24442 const elems = try sema.gpa.alloc(InternPool.Index, vec_len);24694 const elems = try sema.gpa.alloc(InternPool.Index, vec_len);
24443 defer sema.gpa.free(elems);24695 defer sema.gpa.free(elems);
24444 for (elems, 0..) |*elem, i| {24696 for (elems, 0..) |*elem, i| {
24445 const pred_elem_val = try pred_val.elemValue(mod, i);24697 const pred_elem_val = try pred_val.elemValue(pt, i);
24446 const should_choose_a = pred_elem_val.toBool();24698 const should_choose_a = pred_elem_val.toBool();
24447 elem.* = (try (if (should_choose_a) a_val else b_val).elemValue(mod, i)).toIntern();24699 elem.* = (try (if (should_choose_a) a_val else b_val).elemValue(pt, i)).toIntern();
24448 }24700 }
2444924701
24450 return Air.internedToRef((try mod.intern(.{ .aggregate = .{24702 return Air.internedToRef((try pt.intern(.{ .aggregate = .{
24451 .ty = vec_ty.toIntern(),24703 .ty = vec_ty.toIntern(),
24452 .storage = .{ .elems = elems },24704 .storage = .{ .elems = elems },
24453 } })));24705 } })));
...@@ -24456,16 +24708,16 @@ fn zirSelect(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) C...@@ -24456,16 +24708,16 @@ fn zirSelect(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) C
24456 }24708 }
24457 } else {24709 } else {
24458 if (maybe_b) |b_val| {24710 if (maybe_b) |b_val| {
24459 if (b_val.isUndef(mod)) return mod.undefRef(vec_ty);24711 if (b_val.isUndef(mod)) return pt.undefRef(vec_ty);
24460 }24712 }
24461 break :rs a_src;24713 break :rs a_src;
24462 }24714 }
24463 } else rs: {24715 } else rs: {
24464 if (maybe_a) |a_val| {24716 if (maybe_a) |a_val| {
24465 if (a_val.isUndef(mod)) return mod.undefRef(vec_ty);24717 if (a_val.isUndef(mod)) return pt.undefRef(vec_ty);
24466 }24718 }
24467 if (maybe_b) |b_val| {24719 if (maybe_b) |b_val| {
24468 if (b_val.isUndef(mod)) return mod.undefRef(vec_ty);24720 if (b_val.isUndef(mod)) return pt.undefRef(vec_ty);
24469 }24721 }
24470 break :rs pred_src;24722 break :rs pred_src;
24471 };24723 };
...@@ -24531,7 +24783,8 @@ fn zirAtomicLoad(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!...@@ -24531,7 +24783,8 @@ fn zirAtomicLoad(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!
24531}24783}
2453224784
24533fn zirAtomicRmw(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {24785fn zirAtomicRmw(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
24534 const mod = sema.mod;24786 const pt = sema.pt;
24787 const mod = pt.zcu;
24535 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;24788 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
24536 const extra = sema.code.extraData(Zir.Inst.AtomicRmw, inst_data.payload_index).data;24789 const extra = sema.code.extraData(Zir.Inst.AtomicRmw, inst_data.payload_index).data;
24537 const src = block.nodeOffset(inst_data.src_node);24790 const src = block.nodeOffset(inst_data.src_node);
...@@ -24588,12 +24841,12 @@ fn zirAtomicRmw(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A...@@ -24588,12 +24841,12 @@ fn zirAtomicRmw(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
24588 .Xchg => operand_val,24841 .Xchg => operand_val,
24589 .Add => try sema.numberAddWrapScalar(stored_val, operand_val, elem_ty),24842 .Add => try sema.numberAddWrapScalar(stored_val, operand_val, elem_ty),
24590 .Sub => try sema.numberSubWrapScalar(stored_val, operand_val, elem_ty),24843 .Sub => try sema.numberSubWrapScalar(stored_val, operand_val, elem_ty),
24591 .And => try stored_val.bitwiseAnd (operand_val, elem_ty, sema.arena, mod),24844 .And => try stored_val.bitwiseAnd (operand_val, elem_ty, sema.arena, pt),
24592 .Nand => try stored_val.bitwiseNand (operand_val, elem_ty, sema.arena, mod),24845 .Nand => try stored_val.bitwiseNand (operand_val, elem_ty, sema.arena, pt),
24593 .Or => try stored_val.bitwiseOr (operand_val, elem_ty, sema.arena, mod),24846 .Or => try stored_val.bitwiseOr (operand_val, elem_ty, sema.arena, pt),
24594 .Xor => try stored_val.bitwiseXor (operand_val, elem_ty, sema.arena, mod),24847 .Xor => try stored_val.bitwiseXor (operand_val, elem_ty, sema.arena, pt),
24595 .Max => stored_val.numberMax (operand_val, mod),24848 .Max => stored_val.numberMax (operand_val, pt),
24596 .Min => stored_val.numberMin (operand_val, mod),24849 .Min => stored_val.numberMin (operand_val, pt),
24597 // zig fmt: on24850 // zig fmt: on
24598 };24851 };
24599 try sema.storePtrVal(block, src, ptr_val, new_val, elem_ty);24852 try sema.storePtrVal(block, src, ptr_val, new_val, elem_ty);
...@@ -24669,36 +24922,37 @@ fn zirMulAdd(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air....@@ -24669,36 +24922,37 @@ fn zirMulAdd(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.
24669 const maybe_mulend1 = try sema.resolveValue(mulend1);24922 const maybe_mulend1 = try sema.resolveValue(mulend1);
24670 const maybe_mulend2 = try sema.resolveValue(mulend2);24923 const maybe_mulend2 = try sema.resolveValue(mulend2);
24671 const maybe_addend = try sema.resolveValue(addend);24924 const maybe_addend = try sema.resolveValue(addend);
24672 const mod = sema.mod;24925 const pt = sema.pt;
24926 const mod = pt.zcu;
2467324927
24674 switch (ty.scalarType(mod).zigTypeTag(mod)) {24928 switch (ty.scalarType(mod).zigTypeTag(mod)) {
24675 .ComptimeFloat, .Float => {},24929 .ComptimeFloat, .Float => {},
24676 else => return sema.fail(block, src, "expected vector of floats or float type, found '{}'", .{ty.fmt(sema.mod)}),24930 else => return sema.fail(block, src, "expected vector of floats or float type, found '{}'", .{ty.fmt(pt)}),
24677 }24931 }
2467824932
24679 const runtime_src = if (maybe_mulend1) |mulend1_val| rs: {24933 const runtime_src = if (maybe_mulend1) |mulend1_val| rs: {
24680 if (maybe_mulend2) |mulend2_val| {24934 if (maybe_mulend2) |mulend2_val| {
24681 if (mulend2_val.isUndef(mod)) return mod.undefRef(ty);24935 if (mulend2_val.isUndef(mod)) return pt.undefRef(ty);
2468224936
24683 if (maybe_addend) |addend_val| {24937 if (maybe_addend) |addend_val| {
24684 if (addend_val.isUndef(mod)) return mod.undefRef(ty);24938 if (addend_val.isUndef(mod)) return pt.undefRef(ty);
24685 const result_val = try Value.mulAdd(ty, mulend1_val, mulend2_val, addend_val, sema.arena, sema.mod);24939 const result_val = try Value.mulAdd(ty, mulend1_val, mulend2_val, addend_val, sema.arena, pt);
24686 return Air.internedToRef(result_val.toIntern());24940 return Air.internedToRef(result_val.toIntern());
24687 } else {24941 } else {
24688 break :rs addend_src;24942 break :rs addend_src;
24689 }24943 }
24690 } else {24944 } else {
24691 if (maybe_addend) |addend_val| {24945 if (maybe_addend) |addend_val| {
24692 if (addend_val.isUndef(mod)) return mod.undefRef(ty);24946 if (addend_val.isUndef(mod)) return pt.undefRef(ty);
24693 }24947 }
24694 break :rs mulend2_src;24948 break :rs mulend2_src;
24695 }24949 }
24696 } else rs: {24950 } else rs: {
24697 if (maybe_mulend2) |mulend2_val| {24951 if (maybe_mulend2) |mulend2_val| {
24698 if (mulend2_val.isUndef(mod)) return mod.undefRef(ty);24952 if (mulend2_val.isUndef(mod)) return pt.undefRef(ty);
24699 }24953 }
24700 if (maybe_addend) |addend_val| {24954 if (maybe_addend) |addend_val| {
24701 if (addend_val.isUndef(mod)) return mod.undefRef(ty);24955 if (addend_val.isUndef(mod)) return pt.undefRef(ty);
24702 }24956 }
24703 break :rs mulend1_src;24957 break :rs mulend1_src;
24704 };24958 };
...@@ -24720,7 +24974,8 @@ fn zirBuiltinCall(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError...@@ -24720,7 +24974,8 @@ fn zirBuiltinCall(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
24720 const tracy = trace(@src());24974 const tracy = trace(@src());
24721 defer tracy.end();24975 defer tracy.end();
2472224976
24723 const mod = sema.mod;24977 const pt = sema.pt;
24978 const mod = pt.zcu;
24724 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;24979 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
24725 const modifier_src = block.builtinCallArgSrc(inst_data.src_node, 0);24980 const modifier_src = block.builtinCallArgSrc(inst_data.src_node, 0);
24726 const func_src = block.builtinCallArgSrc(inst_data.src_node, 1);24981 const func_src = block.builtinCallArgSrc(inst_data.src_node, 1);
...@@ -24730,7 +24985,7 @@ fn zirBuiltinCall(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError...@@ -24730,7 +24985,7 @@ fn zirBuiltinCall(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
24730 const extra = sema.code.extraData(Zir.Inst.BuiltinCall, inst_data.payload_index).data;24985 const extra = sema.code.extraData(Zir.Inst.BuiltinCall, inst_data.payload_index).data;
24731 const func = try sema.resolveInst(extra.callee);24986 const func = try sema.resolveInst(extra.callee);
2473224987
24733 const modifier_ty = try mod.getBuiltinType("CallModifier");24988 const modifier_ty = try pt.getBuiltinType("CallModifier");
24734 const air_ref = try sema.resolveInst(extra.modifier);24989 const air_ref = try sema.resolveInst(extra.modifier);
24735 const modifier_ref = try sema.coerce(block, modifier_ty, air_ref, modifier_src);24990 const modifier_ref = try sema.coerce(block, modifier_ty, air_ref, modifier_src);
24736 const modifier_val = try sema.resolveConstDefinedValue(block, modifier_src, modifier_ref, .{24991 const modifier_val = try sema.resolveConstDefinedValue(block, modifier_src, modifier_ref, .{
...@@ -24783,7 +25038,7 @@ fn zirBuiltinCall(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError...@@ -24783,7 +25038,7 @@ fn zirBuiltinCall(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
2478325038
24784 const args_ty = sema.typeOf(args);25039 const args_ty = sema.typeOf(args);
24785 if (!args_ty.isTuple(mod) and args_ty.toIntern() != .empty_struct_type) {25040 if (!args_ty.isTuple(mod) and args_ty.toIntern() != .empty_struct_type) {
24786 return sema.fail(block, args_src, "expected a tuple, found '{}'", .{args_ty.fmt(sema.mod)});25041 return sema.fail(block, args_src, "expected a tuple, found '{}'", .{args_ty.fmt(pt)});
24787 }25042 }
2478825043
24789 const resolved_args: []Air.Inst.Ref = try sema.arena.alloc(Air.Inst.Ref, args_ty.structFieldCount(mod));25044 const resolved_args: []Air.Inst.Ref = try sema.arena.alloc(Air.Inst.Ref, args_ty.structFieldCount(mod));
...@@ -24812,7 +25067,8 @@ fn zirBuiltinCall(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError...@@ -24812,7 +25067,8 @@ fn zirBuiltinCall(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
24812}25067}
2481325068
24814fn zirFieldParentPtr(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) CompileError!Air.Inst.Ref {25069fn zirFieldParentPtr(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) CompileError!Air.Inst.Ref {
24815 const zcu = sema.mod;25070 const pt = sema.pt;
25071 const zcu = pt.zcu;
24816 const ip = &zcu.intern_pool;25072 const ip = &zcu.intern_pool;
2481725073
24818 const extra = sema.code.extraData(Zir.Inst.FieldParentPtr, extended.operand).data;25074 const extra = sema.code.extraData(Zir.Inst.FieldParentPtr, extended.operand).data;
...@@ -24827,14 +25083,14 @@ fn zirFieldParentPtr(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.Ins...@@ -24827,14 +25083,14 @@ fn zirFieldParentPtr(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.Ins
24827 try sema.checkPtrType(block, inst_src, parent_ptr_ty, true);25083 try sema.checkPtrType(block, inst_src, parent_ptr_ty, true);
24828 const parent_ptr_info = parent_ptr_ty.ptrInfo(zcu);25084 const parent_ptr_info = parent_ptr_ty.ptrInfo(zcu);
24829 if (parent_ptr_info.flags.size != .One) {25085 if (parent_ptr_info.flags.size != .One) {
24830 return sema.fail(block, inst_src, "expected single pointer type, found '{}'", .{parent_ptr_ty.fmt(zcu)});25086 return sema.fail(block, inst_src, "expected single pointer type, found '{}'", .{parent_ptr_ty.fmt(pt)});
24831 }25087 }
24832 const parent_ty = Type.fromInterned(parent_ptr_info.child);25088 const parent_ty = Type.fromInterned(parent_ptr_info.child);
24833 switch (parent_ty.zigTypeTag(zcu)) {25089 switch (parent_ty.zigTypeTag(zcu)) {
24834 .Struct, .Union => {},25090 .Struct, .Union => {},
24835 else => return sema.fail(block, inst_src, "expected pointer to struct or union type, found '{}'", .{parent_ptr_ty.fmt(zcu)}),25091 else => return sema.fail(block, inst_src, "expected pointer to struct or union type, found '{}'", .{parent_ptr_ty.fmt(pt)}),
24836 }25092 }
24837 try parent_ty.resolveLayout(zcu);25093 try parent_ty.resolveLayout(pt);
2483825094
24839 const field_name = try sema.resolveConstStringIntern(block, field_name_src, extra.field_name, .{25095 const field_name = try sema.resolveConstStringIntern(block, field_name_src, extra.field_name, .{
24840 .needed_comptime_reason = "field name must be comptime-known",25096 .needed_comptime_reason = "field name must be comptime-known",
...@@ -24865,7 +25121,7 @@ fn zirFieldParentPtr(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.Ins...@@ -24865,7 +25121,7 @@ fn zirFieldParentPtr(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.Ins
24865 var actual_parent_ptr_info: InternPool.Key.PtrType = .{25121 var actual_parent_ptr_info: InternPool.Key.PtrType = .{
24866 .child = parent_ty.toIntern(),25122 .child = parent_ty.toIntern(),
24867 .flags = .{25123 .flags = .{
24868 .alignment = try parent_ptr_ty.ptrAlignmentAdvanced(zcu, .sema),25124 .alignment = try parent_ptr_ty.ptrAlignmentAdvanced(pt, .sema),
24869 .is_const = field_ptr_info.flags.is_const,25125 .is_const = field_ptr_info.flags.is_const,
24870 .is_volatile = field_ptr_info.flags.is_volatile,25126 .is_volatile = field_ptr_info.flags.is_volatile,
24871 .is_allowzero = field_ptr_info.flags.is_allowzero,25127 .is_allowzero = field_ptr_info.flags.is_allowzero,
...@@ -24877,7 +25133,7 @@ fn zirFieldParentPtr(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.Ins...@@ -24877,7 +25133,7 @@ fn zirFieldParentPtr(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.Ins
24877 var actual_field_ptr_info: InternPool.Key.PtrType = .{25133 var actual_field_ptr_info: InternPool.Key.PtrType = .{
24878 .child = field_ty.toIntern(),25134 .child = field_ty.toIntern(),
24879 .flags = .{25135 .flags = .{
24880 .alignment = try field_ptr_ty.ptrAlignmentAdvanced(zcu, .sema),25136 .alignment = try field_ptr_ty.ptrAlignmentAdvanced(pt, .sema),
24881 .is_const = field_ptr_info.flags.is_const,25137 .is_const = field_ptr_info.flags.is_const,
24882 .is_volatile = field_ptr_info.flags.is_volatile,25138 .is_volatile = field_ptr_info.flags.is_volatile,
24883 .is_allowzero = field_ptr_info.flags.is_allowzero,25139 .is_allowzero = field_ptr_info.flags.is_allowzero,
...@@ -24888,13 +25144,13 @@ fn zirFieldParentPtr(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.Ins...@@ -24888,13 +25144,13 @@ fn zirFieldParentPtr(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.Ins
24888 switch (parent_ty.containerLayout(zcu)) {25144 switch (parent_ty.containerLayout(zcu)) {
24889 .auto => {25145 .auto => {
24890 actual_parent_ptr_info.flags.alignment = actual_field_ptr_info.flags.alignment.minStrict(25146 actual_parent_ptr_info.flags.alignment = actual_field_ptr_info.flags.alignment.minStrict(
24891 if (zcu.typeToStruct(parent_ty)) |struct_obj| try zcu.structFieldAlignmentAdvanced(25147 if (zcu.typeToStruct(parent_ty)) |struct_obj| try pt.structFieldAlignmentAdvanced(
24892 struct_obj.fieldAlign(ip, field_index),25148 struct_obj.fieldAlign(ip, field_index),
24893 field_ty,25149 field_ty,
24894 struct_obj.layout,25150 struct_obj.layout,
24895 .sema,25151 .sema,
24896 ) else if (zcu.typeToUnion(parent_ty)) |union_obj|25152 ) else if (zcu.typeToUnion(parent_ty)) |union_obj|
24897 try zcu.unionFieldNormalAlignmentAdvanced(union_obj, field_index, .sema)25153 try pt.unionFieldNormalAlignmentAdvanced(union_obj, field_index, .sema)
24898 else25154 else
24899 actual_field_ptr_info.flags.alignment,25155 actual_field_ptr_info.flags.alignment,
24900 );25156 );
...@@ -24903,7 +25159,7 @@ fn zirFieldParentPtr(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.Ins...@@ -24903,7 +25159,7 @@ fn zirFieldParentPtr(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.Ins
24903 actual_field_ptr_info.packed_offset = .{ .bit_offset = 0, .host_size = 0 };25159 actual_field_ptr_info.packed_offset = .{ .bit_offset = 0, .host_size = 0 };
24904 },25160 },
24905 .@"extern" => {25161 .@"extern" => {
24906 const field_offset = parent_ty.structFieldOffset(field_index, zcu);25162 const field_offset = parent_ty.structFieldOffset(field_index, pt);
24907 actual_parent_ptr_info.flags.alignment = actual_field_ptr_info.flags.alignment.minStrict(if (field_offset > 0)25163 actual_parent_ptr_info.flags.alignment = actual_field_ptr_info.flags.alignment.minStrict(if (field_offset > 0)
24908 Alignment.fromLog2Units(@ctz(field_offset))25164 Alignment.fromLog2Units(@ctz(field_offset))
24909 else25165 else
...@@ -24914,7 +25170,7 @@ fn zirFieldParentPtr(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.Ins...@@ -24914,7 +25170,7 @@ fn zirFieldParentPtr(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.Ins
24914 },25170 },
24915 .@"packed" => {25171 .@"packed" => {
24916 const byte_offset = std.math.divExact(u32, @abs(@as(i32, actual_parent_ptr_info.packed_offset.bit_offset) +25172 const byte_offset = std.math.divExact(u32, @abs(@as(i32, actual_parent_ptr_info.packed_offset.bit_offset) +
24917 (if (zcu.typeToStruct(parent_ty)) |struct_obj| zcu.structPackedFieldBitOffset(struct_obj, field_index) else 0) -25173 (if (zcu.typeToStruct(parent_ty)) |struct_obj| pt.structPackedFieldBitOffset(struct_obj, field_index) else 0) -
24918 actual_field_ptr_info.packed_offset.bit_offset), 8) catch25174 actual_field_ptr_info.packed_offset.bit_offset), 8) catch
24919 return sema.fail(block, inst_src, "pointer bit-offset mismatch", .{});25175 return sema.fail(block, inst_src, "pointer bit-offset mismatch", .{});
24920 actual_parent_ptr_info.flags.alignment = actual_field_ptr_info.flags.alignment.minStrict(if (byte_offset > 0)25176 actual_parent_ptr_info.flags.alignment = actual_field_ptr_info.flags.alignment.minStrict(if (byte_offset > 0)
...@@ -24924,16 +25180,16 @@ fn zirFieldParentPtr(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.Ins...@@ -24924,16 +25180,16 @@ fn zirFieldParentPtr(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.Ins
24924 },25180 },
24925 }25181 }
2492625182
24927 const actual_field_ptr_ty = try zcu.ptrTypeSema(actual_field_ptr_info);25183 const actual_field_ptr_ty = try pt.ptrTypeSema(actual_field_ptr_info);
24928 const casted_field_ptr = try sema.coerce(block, actual_field_ptr_ty, field_ptr, field_ptr_src);25184 const casted_field_ptr = try sema.coerce(block, actual_field_ptr_ty, field_ptr, field_ptr_src);
24929 const actual_parent_ptr_ty = try zcu.ptrTypeSema(actual_parent_ptr_info);25185 const actual_parent_ptr_ty = try pt.ptrTypeSema(actual_parent_ptr_info);
2493025186
24931 const result = if (try sema.resolveDefinedValue(block, field_ptr_src, casted_field_ptr)) |field_ptr_val| result: {25187 const result = if (try sema.resolveDefinedValue(block, field_ptr_src, casted_field_ptr)) |field_ptr_val| result: {
24932 switch (parent_ty.zigTypeTag(zcu)) {25188 switch (parent_ty.zigTypeTag(zcu)) {
24933 .Struct => switch (parent_ty.containerLayout(zcu)) {25189 .Struct => switch (parent_ty.containerLayout(zcu)) {
24934 .auto => {},25190 .auto => {},
24935 .@"extern" => {25191 .@"extern" => {
24936 const byte_offset = parent_ty.structFieldOffset(field_index, zcu);25192 const byte_offset = parent_ty.structFieldOffset(field_index, pt);
24937 const parent_ptr_val = try sema.ptrSubtract(block, field_ptr_src, field_ptr_val, byte_offset, actual_parent_ptr_ty);25193 const parent_ptr_val = try sema.ptrSubtract(block, field_ptr_src, field_ptr_val, byte_offset, actual_parent_ptr_ty);
24938 break :result Air.internedToRef(parent_ptr_val.toIntern());25194 break :result Air.internedToRef(parent_ptr_val.toIntern());
24939 },25195 },
...@@ -24941,7 +25197,7 @@ fn zirFieldParentPtr(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.Ins...@@ -24941,7 +25197,7 @@ fn zirFieldParentPtr(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.Ins
24941 // Logic lifted from type computation above - I'm just assuming it's correct.25197 // Logic lifted from type computation above - I'm just assuming it's correct.
24942 // `catch unreachable` since error case handled above.25198 // `catch unreachable` since error case handled above.
24943 const byte_offset = std.math.divExact(u32, @abs(@as(i32, actual_parent_ptr_info.packed_offset.bit_offset) +25199 const byte_offset = std.math.divExact(u32, @abs(@as(i32, actual_parent_ptr_info.packed_offset.bit_offset) +
24944 zcu.structPackedFieldBitOffset(zcu.typeToStruct(parent_ty).?, field_index) -25200 pt.structPackedFieldBitOffset(zcu.typeToStruct(parent_ty).?, field_index) -
24945 actual_field_ptr_info.packed_offset.bit_offset), 8) catch unreachable;25201 actual_field_ptr_info.packed_offset.bit_offset), 8) catch unreachable;
24946 const parent_ptr_val = try sema.ptrSubtract(block, field_ptr_src, field_ptr_val, byte_offset, actual_parent_ptr_ty);25202 const parent_ptr_val = try sema.ptrSubtract(block, field_ptr_src, field_ptr_val, byte_offset, actual_parent_ptr_ty);
24947 break :result Air.internedToRef(parent_ptr_val.toIntern());25203 break :result Air.internedToRef(parent_ptr_val.toIntern());
...@@ -24951,7 +25207,7 @@ fn zirFieldParentPtr(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.Ins...@@ -24951,7 +25207,7 @@ fn zirFieldParentPtr(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.Ins
24951 .auto => {},25207 .auto => {},
24952 .@"extern", .@"packed" => {25208 .@"extern", .@"packed" => {
24953 // For an extern or packed union, just coerce the pointer.25209 // For an extern or packed union, just coerce the pointer.
24954 const parent_ptr_val = try zcu.getCoerced(field_ptr_val, actual_parent_ptr_ty);25210 const parent_ptr_val = try pt.getCoerced(field_ptr_val, actual_parent_ptr_ty);
24955 break :result Air.internedToRef(parent_ptr_val.toIntern());25211 break :result Air.internedToRef(parent_ptr_val.toIntern());
24956 },25212 },
24957 },25213 },
...@@ -24980,7 +25236,7 @@ fn zirFieldParentPtr(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.Ins...@@ -24980,7 +25236,7 @@ fn zirFieldParentPtr(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.Ins
2498025236
24981 if (field.index != field_index) {25237 if (field.index != field_index) {
24982 return sema.fail(block, inst_src, "field '{}' has index '{d}' but pointer value is index '{d}' of struct '{}'", .{25238 return sema.fail(block, inst_src, "field '{}' has index '{d}' but pointer value is index '{d}' of struct '{}'", .{
24983 field_name.fmt(ip), field_index, field.index, parent_ty.fmt(zcu),25239 field_name.fmt(ip), field_index, field.index, parent_ty.fmt(pt),
24984 });25240 });
24985 }25241 }
24986 break :result try sema.coerce(block, actual_parent_ptr_ty, Air.internedToRef(field.base), inst_src);25242 break :result try sema.coerce(block, actual_parent_ptr_ty, Air.internedToRef(field.base), inst_src);
...@@ -25001,8 +25257,9 @@ fn zirFieldParentPtr(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.Ins...@@ -25001,8 +25257,9 @@ fn zirFieldParentPtr(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.Ins
25001}25257}
2500225258
25003fn ptrSubtract(sema: *Sema, block: *Block, src: LazySrcLoc, ptr_val: Value, byte_subtract: u64, new_ty: Type) !Value {25259fn ptrSubtract(sema: *Sema, block: *Block, src: LazySrcLoc, ptr_val: Value, byte_subtract: u64, new_ty: Type) !Value {
25004 const zcu = sema.mod;25260 const pt = sema.pt;
25005 if (byte_subtract == 0) return zcu.getCoerced(ptr_val, new_ty);25261 const zcu = pt.zcu;
25262 if (byte_subtract == 0) return pt.getCoerced(ptr_val, new_ty);
25006 var ptr = switch (zcu.intern_pool.indexToKey(ptr_val.toIntern())) {25263 var ptr = switch (zcu.intern_pool.indexToKey(ptr_val.toIntern())) {
25007 .undef => return sema.failWithUseOfUndef(block, src),25264 .undef => return sema.failWithUseOfUndef(block, src),
25008 .ptr => |ptr| ptr,25265 .ptr => |ptr| ptr,
...@@ -25018,7 +25275,7 @@ fn ptrSubtract(sema: *Sema, block: *Block, src: LazySrcLoc, ptr_val: Value, byte...@@ -25018,7 +25275,7 @@ fn ptrSubtract(sema: *Sema, block: *Block, src: LazySrcLoc, ptr_val: Value, byte
25018 }25275 }
25019 ptr.byte_offset -= byte_subtract;25276 ptr.byte_offset -= byte_subtract;
25020 ptr.ty = new_ty.toIntern();25277 ptr.ty = new_ty.toIntern();
25021 return Value.fromInterned(try zcu.intern(.{ .ptr = ptr }));25278 return Value.fromInterned(try pt.intern(.{ .ptr = ptr }));
25022}25279}
2502325280
25024fn zirMinMax(25281fn zirMinMax(
...@@ -25072,7 +25329,8 @@ fn analyzeMinMax(...@@ -25072,7 +25329,8 @@ fn analyzeMinMax(
25072) CompileError!Air.Inst.Ref {25329) CompileError!Air.Inst.Ref {
25073 assert(operands.len == operand_srcs.len);25330 assert(operands.len == operand_srcs.len);
25074 assert(operands.len > 0);25331 assert(operands.len > 0);
25075 const mod = sema.mod;25332 const pt = sema.pt;
25333 const mod = pt.zcu;
2507625334
25077 if (operands.len == 1) return operands[0];25335 if (operands.len == 1) return operands[0];
2507825336
...@@ -25115,15 +25373,15 @@ fn analyzeMinMax(...@@ -25115,15 +25373,15 @@ fn analyzeMinMax(
25115 break :refine_bounds;25373 break :refine_bounds;
25116 }25374 }
25117 const scalar_bounds: ?[2]Value = bounds: {25375 const scalar_bounds: ?[2]Value = bounds: {
25118 if (!ty.isVector(mod)) break :bounds try uncoerced_val.intValueBounds(mod);25376 if (!ty.isVector(mod)) break :bounds try uncoerced_val.intValueBounds(pt);
25119 var cur_bounds: [2]Value = try Value.intValueBounds(try uncoerced_val.elemValue(mod, 0), mod) orelse break :bounds null;25377 var cur_bounds: [2]Value = try Value.intValueBounds(try uncoerced_val.elemValue(pt, 0), pt) orelse break :bounds null;
25120 const len = try sema.usizeCast(block, src, ty.vectorLen(mod));25378 const len = try sema.usizeCast(block, src, ty.vectorLen(mod));
25121 for (1..len) |i| {25379 for (1..len) |i| {
25122 const elem = try uncoerced_val.elemValue(mod, i);25380 const elem = try uncoerced_val.elemValue(pt, i);
25123 const elem_bounds = try elem.intValueBounds(mod) orelse break :bounds null;25381 const elem_bounds = try elem.intValueBounds(pt) orelse break :bounds null;
25124 cur_bounds = .{25382 cur_bounds = .{
25125 Value.numberMin(elem_bounds[0], cur_bounds[0], mod),25383 Value.numberMin(elem_bounds[0], cur_bounds[0], pt),
25126 Value.numberMax(elem_bounds[1], cur_bounds[1], mod),25384 Value.numberMax(elem_bounds[1], cur_bounds[1], pt),
25127 };25385 };
25128 }25386 }
25129 break :bounds cur_bounds;25387 break :bounds cur_bounds;
...@@ -25134,8 +25392,8 @@ fn analyzeMinMax(...@@ -25134,8 +25392,8 @@ fn analyzeMinMax(
25134 cur_max_scalar = bounds[1];25392 cur_max_scalar = bounds[1];
25135 bounds_status = .defined;25393 bounds_status = .defined;
25136 } else {25394 } else {
25137 cur_min_scalar = opFunc(cur_min_scalar, bounds[0], mod);25395 cur_min_scalar = opFunc(cur_min_scalar, bounds[0], pt);
25138 cur_max_scalar = opFunc(cur_max_scalar, bounds[1], mod);25396 cur_max_scalar = opFunc(cur_max_scalar, bounds[1], pt);
25139 }25397 }
25140 }25398 }
25141 },25399 },
...@@ -25153,18 +25411,18 @@ fn analyzeMinMax(...@@ -25153,18 +25411,18 @@ fn analyzeMinMax(
25153 const operand_val = try sema.resolveLazyValue(simd_op.rhs_val.?); // we checked the operand was resolvable above25411 const operand_val = try sema.resolveLazyValue(simd_op.rhs_val.?); // we checked the operand was resolvable above
2515425412
25155 const vec_len = simd_op.len orelse {25413 const vec_len = simd_op.len orelse {
25156 const result_val = opFunc(cur_val, operand_val, mod);25414 const result_val = opFunc(cur_val, operand_val, pt);
25157 cur_minmax = Air.internedToRef(result_val.toIntern());25415 cur_minmax = Air.internedToRef(result_val.toIntern());
25158 continue;25416 continue;
25159 };25417 };
25160 const elems = try sema.arena.alloc(InternPool.Index, vec_len);25418 const elems = try sema.arena.alloc(InternPool.Index, vec_len);
25161 for (elems, 0..) |*elem, i| {25419 for (elems, 0..) |*elem, i| {
25162 const lhs_elem_val = try cur_val.elemValue(mod, i);25420 const lhs_elem_val = try cur_val.elemValue(pt, i);
25163 const rhs_elem_val = try operand_val.elemValue(mod, i);25421 const rhs_elem_val = try operand_val.elemValue(pt, i);
25164 const uncoerced_elem = opFunc(lhs_elem_val, rhs_elem_val, mod);25422 const uncoerced_elem = opFunc(lhs_elem_val, rhs_elem_val, pt);
25165 elem.* = (try mod.getCoerced(uncoerced_elem, simd_op.scalar_ty)).toIntern();25423 elem.* = (try pt.getCoerced(uncoerced_elem, simd_op.scalar_ty)).toIntern();
25166 }25424 }
25167 cur_minmax = Air.internedToRef((try mod.intern(.{ .aggregate = .{25425 cur_minmax = Air.internedToRef((try pt.intern(.{ .aggregate = .{
25168 .ty = simd_op.result_ty.toIntern(),25426 .ty = simd_op.result_ty.toIntern(),
25169 .storage = .{ .elems = elems },25427 .storage = .{ .elems = elems },
25170 } })));25428 } })));
...@@ -25191,8 +25449,8 @@ fn analyzeMinMax(...@@ -25191,8 +25449,8 @@ fn analyzeMinMax(
2519125449
25192 assert(bounds_status == .defined); // there was a non-comptime-int integral comptime-known arg25450 assert(bounds_status == .defined); // there was a non-comptime-int integral comptime-known arg
2519325451
25194 const refined_scalar_ty = try mod.intFittingRange(cur_min_scalar, cur_max_scalar);25452 const refined_scalar_ty = try pt.intFittingRange(cur_min_scalar, cur_max_scalar);
25195 const refined_ty = if (orig_ty.isVector(mod)) try mod.vectorType(.{25453 const refined_ty = if (orig_ty.isVector(mod)) try pt.vectorType(.{
25196 .len = orig_ty.vectorLen(mod),25454 .len = orig_ty.vectorLen(mod),
25197 .child = refined_scalar_ty.toIntern(),25455 .child = refined_scalar_ty.toIntern(),
25198 }) else refined_scalar_ty;25456 }) else refined_scalar_ty;
...@@ -25226,8 +25484,8 @@ fn analyzeMinMax(...@@ -25226,8 +25484,8 @@ fn analyzeMinMax(
25226 runtime_known.unset(0); // don't look at this operand in the loop below25484 runtime_known.unset(0); // don't look at this operand in the loop below
25227 const scalar_ty = sema.typeOf(cur_minmax.?).scalarType(mod);25485 const scalar_ty = sema.typeOf(cur_minmax.?).scalarType(mod);
25228 if (scalar_ty.isInt(mod)) {25486 if (scalar_ty.isInt(mod)) {
25229 cur_min_scalar = try scalar_ty.minInt(mod, scalar_ty);25487 cur_min_scalar = try scalar_ty.minInt(pt, scalar_ty);
25230 cur_max_scalar = try scalar_ty.maxInt(mod, scalar_ty);25488 cur_max_scalar = try scalar_ty.maxInt(pt, scalar_ty);
25231 bounds_status = .defined;25489 bounds_status = .defined;
25232 } else {25490 } else {
25233 bounds_status = .non_integral;25491 bounds_status = .non_integral;
...@@ -25242,7 +25500,7 @@ fn analyzeMinMax(...@@ -25242,7 +25500,7 @@ fn analyzeMinMax(
25242 const rhs_src = operand_srcs[idx];25500 const rhs_src = operand_srcs[idx];
25243 const simd_op = try sema.checkSimdBinOp(block, src, lhs, rhs, lhs_src, rhs_src);25501 const simd_op = try sema.checkSimdBinOp(block, src, lhs, rhs, lhs_src, rhs_src);
25244 if (known_undef) {25502 if (known_undef) {
25245 cur_minmax = try mod.undefRef(simd_op.result_ty);25503 cur_minmax = try pt.undefRef(simd_op.result_ty);
25246 } else {25504 } else {
25247 cur_minmax = try block.addBinOp(air_tag, simd_op.lhs, simd_op.rhs);25505 cur_minmax = try block.addBinOp(air_tag, simd_op.lhs, simd_op.rhs);
25248 }25506 }
...@@ -25254,15 +25512,15 @@ fn analyzeMinMax(...@@ -25254,15 +25512,15 @@ fn analyzeMinMax(
25254 bounds_status = .non_integral;25512 bounds_status = .non_integral;
25255 break :refine_bounds;25513 break :refine_bounds;
25256 }25514 }
25257 const scalar_min = try scalar_ty.minInt(mod, scalar_ty);25515 const scalar_min = try scalar_ty.minInt(pt, scalar_ty);
25258 const scalar_max = try scalar_ty.maxInt(mod, scalar_ty);25516 const scalar_max = try scalar_ty.maxInt(pt, scalar_ty);
25259 if (bounds_status == .unknown) {25517 if (bounds_status == .unknown) {
25260 cur_min_scalar = scalar_min;25518 cur_min_scalar = scalar_min;
25261 cur_max_scalar = scalar_max;25519 cur_max_scalar = scalar_max;
25262 bounds_status = .defined;25520 bounds_status = .defined;
25263 } else {25521 } else {
25264 cur_min_scalar = opFunc(cur_min_scalar, scalar_min, mod);25522 cur_min_scalar = opFunc(cur_min_scalar, scalar_min, pt);
25265 cur_max_scalar = opFunc(cur_max_scalar, scalar_max, mod);25523 cur_max_scalar = opFunc(cur_max_scalar, scalar_max, pt);
25266 }25524 }
25267 },25525 },
25268 .non_integral => {},25526 .non_integral => {},
...@@ -25276,8 +25534,8 @@ fn analyzeMinMax(...@@ -25276,8 +25534,8 @@ fn analyzeMinMax(
25276 return cur_minmax.?;25534 return cur_minmax.?;
25277 }25535 }
25278 assert(bounds_status == .defined); // there were integral runtime operands25536 assert(bounds_status == .defined); // there were integral runtime operands
25279 const refined_scalar_ty = try mod.intFittingRange(cur_min_scalar, cur_max_scalar);25537 const refined_scalar_ty = try pt.intFittingRange(cur_min_scalar, cur_max_scalar);
25280 const refined_ty = if (unrefined_ty.isVector(mod)) try mod.vectorType(.{25538 const refined_ty = if (unrefined_ty.isVector(mod)) try pt.vectorType(.{
25281 .len = unrefined_ty.vectorLen(mod),25539 .len = unrefined_ty.vectorLen(mod),
25282 .child = refined_scalar_ty.toIntern(),25540 .child = refined_scalar_ty.toIntern(),
25283 }) else refined_scalar_ty;25541 }) else refined_scalar_ty;
...@@ -25291,15 +25549,16 @@ fn analyzeMinMax(...@@ -25291,15 +25549,16 @@ fn analyzeMinMax(
25291}25549}
2529225550
25293fn upgradeToArrayPtr(sema: *Sema, block: *Block, ptr: Air.Inst.Ref, len: u64) !Air.Inst.Ref {25551fn upgradeToArrayPtr(sema: *Sema, block: *Block, ptr: Air.Inst.Ref, len: u64) !Air.Inst.Ref {
25294 const mod = sema.mod;25552 const pt = sema.pt;
25553 const mod = pt.zcu;
25295 const ptr_ty = sema.typeOf(ptr);25554 const ptr_ty = sema.typeOf(ptr);
25296 const info = ptr_ty.ptrInfo(mod);25555 const info = ptr_ty.ptrInfo(mod);
25297 if (info.flags.size == .One) {25556 if (info.flags.size == .One) {
25298 // Already an array pointer.25557 // Already an array pointer.
25299 return ptr;25558 return ptr;
25300 }25559 }
25301 const new_ty = try mod.ptrTypeSema(.{25560 const new_ty = try pt.ptrTypeSema(.{
25302 .child = (try mod.arrayType(.{25561 .child = (try pt.arrayType(.{
25303 .len = len,25562 .len = len,
25304 .sentinel = info.sentinel,25563 .sentinel = info.sentinel,
25305 .child = info.child,25564 .child = info.child,
...@@ -25331,8 +25590,9 @@ fn zirMemcpy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void...@@ -25331,8 +25590,9 @@ fn zirMemcpy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void
25331 const src_ty = sema.typeOf(src_ptr);25590 const src_ty = sema.typeOf(src_ptr);
25332 const dest_len = try indexablePtrLenOrNone(sema, block, dest_src, dest_ptr);25591 const dest_len = try indexablePtrLenOrNone(sema, block, dest_src, dest_ptr);
25333 const src_len = try indexablePtrLenOrNone(sema, block, src_src, src_ptr);25592 const src_len = try indexablePtrLenOrNone(sema, block, src_src, src_ptr);
25334 const target = sema.mod.getTarget();25593 const pt = sema.pt;
25335 const mod = sema.mod;25594 const mod = pt.zcu;
25595 const target = mod.getTarget();
2533625596
25337 if (dest_ty.isConstPtr(mod)) {25597 if (dest_ty.isConstPtr(mod)) {
25338 return sema.fail(block, dest_src, "cannot memcpy to constant pointer", .{});25598 return sema.fail(block, dest_src, "cannot memcpy to constant pointer", .{});
...@@ -25343,10 +25603,10 @@ fn zirMemcpy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void...@@ -25343,10 +25603,10 @@ fn zirMemcpy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void
25343 const msg = try sema.errMsg(src, "unknown @memcpy length", .{});25603 const msg = try sema.errMsg(src, "unknown @memcpy length", .{});
25344 errdefer msg.destroy(sema.gpa);25604 errdefer msg.destroy(sema.gpa);
25345 try sema.errNote(dest_src, msg, "destination type '{}' provides no length", .{25605 try sema.errNote(dest_src, msg, "destination type '{}' provides no length", .{
25346 dest_ty.fmt(sema.mod),25606 dest_ty.fmt(pt),
25347 });25607 });
25348 try sema.errNote(src_src, msg, "source type '{}' provides no length", .{25608 try sema.errNote(src_src, msg, "source type '{}' provides no length", .{
25349 src_ty.fmt(sema.mod),25609 src_ty.fmt(pt),
25350 });25610 });
25351 break :msg msg;25611 break :msg msg;
25352 };25612 };
...@@ -25365,10 +25625,10 @@ fn zirMemcpy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void...@@ -25365,10 +25625,10 @@ fn zirMemcpy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void
25365 const msg = try sema.errMsg(src, "non-matching @memcpy lengths", .{});25625 const msg = try sema.errMsg(src, "non-matching @memcpy lengths", .{});
25366 errdefer msg.destroy(sema.gpa);25626 errdefer msg.destroy(sema.gpa);
25367 try sema.errNote(dest_src, msg, "length {} here", .{25627 try sema.errNote(dest_src, msg, "length {} here", .{
25368 dest_len_val.fmtValue(sema.mod, sema),25628 dest_len_val.fmtValue(pt, sema),
25369 });25629 });
25370 try sema.errNote(src_src, msg, "length {} here", .{25630 try sema.errNote(src_src, msg, "length {} here", .{
25371 src_len_val.fmtValue(sema.mod, sema),25631 src_len_val.fmtValue(pt, sema),
25372 });25632 });
25373 break :msg msg;25633 break :msg msg;
25374 };25634 };
...@@ -25397,10 +25657,10 @@ fn zirMemcpy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void...@@ -25397,10 +25657,10 @@ fn zirMemcpy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void
25397 const runtime_src = if (try sema.resolveDefinedValue(block, dest_src, dest_ptr)) |dest_ptr_val| rs: {25657 const runtime_src = if (try sema.resolveDefinedValue(block, dest_src, dest_ptr)) |dest_ptr_val| rs: {
25398 if (!sema.isComptimeMutablePtr(dest_ptr_val)) break :rs dest_src;25658 if (!sema.isComptimeMutablePtr(dest_ptr_val)) break :rs dest_src;
25399 if (try sema.resolveDefinedValue(block, src_src, src_ptr)) |_| {25659 if (try sema.resolveDefinedValue(block, src_src, src_ptr)) |_| {
25400 const len_u64 = (try len_val.?.getUnsignedIntAdvanced(mod, .sema)).?;25660 const len_u64 = (try len_val.?.getUnsignedIntAdvanced(pt, .sema)).?;
25401 const len = try sema.usizeCast(block, dest_src, len_u64);25661 const len = try sema.usizeCast(block, dest_src, len_u64);
25402 for (0..len) |i| {25662 for (0..len) |i| {
25403 const elem_index = try mod.intRef(Type.usize, i);25663 const elem_index = try pt.intRef(Type.usize, i);
25404 const dest_elem_ptr = try sema.elemPtrOneLayerOnly(25664 const dest_elem_ptr = try sema.elemPtrOneLayerOnly(
25405 block,25665 block,
25406 src,25666 src,
...@@ -25456,7 +25716,7 @@ fn zirMemcpy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void...@@ -25456,7 +25716,7 @@ fn zirMemcpy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void
25456 var new_dest_ptr = dest_ptr;25716 var new_dest_ptr = dest_ptr;
25457 var new_src_ptr = src_ptr;25717 var new_src_ptr = src_ptr;
25458 if (len_val) |val| {25718 if (len_val) |val| {
25459 const len = try val.toUnsignedIntSema(mod);25719 const len = try val.toUnsignedIntSema(pt);
25460 if (len == 0) {25720 if (len == 0) {
25461 // This AIR instruction guarantees length > 0 if it is comptime-known.25721 // This AIR instruction guarantees length > 0 if it is comptime-known.
25462 return;25722 return;
...@@ -25503,7 +25763,7 @@ fn zirMemcpy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void...@@ -25503,7 +25763,7 @@ fn zirMemcpy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void
25503 assert(dest_manyptr_ty_key.flags.size == .One);25763 assert(dest_manyptr_ty_key.flags.size == .One);
25504 dest_manyptr_ty_key.child = dest_elem_ty.toIntern();25764 dest_manyptr_ty_key.child = dest_elem_ty.toIntern();
25505 dest_manyptr_ty_key.flags.size = .Many;25765 dest_manyptr_ty_key.flags.size = .Many;
25506 break :ptr try sema.coerceCompatiblePtrs(block, try mod.ptrTypeSema(dest_manyptr_ty_key), new_dest_ptr, dest_src);25766 break :ptr try sema.coerceCompatiblePtrs(block, try pt.ptrTypeSema(dest_manyptr_ty_key), new_dest_ptr, dest_src);
25507 } else new_dest_ptr;25767 } else new_dest_ptr;
2550825768
25509 const new_src_ptr_ty = sema.typeOf(new_src_ptr);25769 const new_src_ptr_ty = sema.typeOf(new_src_ptr);
...@@ -25514,7 +25774,7 @@ fn zirMemcpy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void...@@ -25514,7 +25774,7 @@ fn zirMemcpy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void
25514 assert(src_manyptr_ty_key.flags.size == .One);25774 assert(src_manyptr_ty_key.flags.size == .One);
25515 src_manyptr_ty_key.child = src_elem_ty.toIntern();25775 src_manyptr_ty_key.child = src_elem_ty.toIntern();
25516 src_manyptr_ty_key.flags.size = .Many;25776 src_manyptr_ty_key.flags.size = .Many;
25517 break :ptr try sema.coerceCompatiblePtrs(block, try mod.ptrTypeSema(src_manyptr_ty_key), new_src_ptr, src_src);25777 break :ptr try sema.coerceCompatiblePtrs(block, try pt.ptrTypeSema(src_manyptr_ty_key), new_src_ptr, src_src);
25518 } else new_src_ptr;25778 } else new_src_ptr;
2551925779
25520 // ok1: dest >= src + len25780 // ok1: dest >= src + len
...@@ -25537,7 +25797,8 @@ fn zirMemcpy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void...@@ -25537,7 +25797,8 @@ fn zirMemcpy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void
25537}25797}
2553825798
25539fn zirMemset(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void {25799fn zirMemset(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void {
25540 const mod = sema.mod;25800 const pt = sema.pt;
25801 const mod = pt.zcu;
25541 const gpa = sema.gpa;25802 const gpa = sema.gpa;
25542 const ip = &mod.intern_pool;25803 const ip = &mod.intern_pool;
25543 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;25804 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
...@@ -25569,7 +25830,7 @@ fn zirMemset(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void...@@ -25569,7 +25830,7 @@ fn zirMemset(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void
25569 const msg = try sema.errMsg(src, "unknown @memset length", .{});25830 const msg = try sema.errMsg(src, "unknown @memset length", .{});
25570 errdefer msg.destroy(sema.gpa);25831 errdefer msg.destroy(sema.gpa);
25571 try sema.errNote(dest_src, msg, "destination type '{}' provides no length", .{25832 try sema.errNote(dest_src, msg, "destination type '{}' provides no length", .{
25572 dest_ptr_ty.fmt(mod),25833 dest_ptr_ty.fmt(pt),
25573 });25834 });
25574 break :msg msg;25835 break :msg msg;
25575 });25836 });
...@@ -25579,9 +25840,9 @@ fn zirMemset(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void...@@ -25579,9 +25840,9 @@ fn zirMemset(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void
2557925840
25580 const runtime_src = rs: {25841 const runtime_src = rs: {
25581 const ptr_val = try sema.resolveDefinedValue(block, dest_src, dest_ptr) orelse break :rs dest_src;25842 const ptr_val = try sema.resolveDefinedValue(block, dest_src, dest_ptr) orelse break :rs dest_src;
25582 const len_air_ref = try sema.fieldVal(block, src, dest_ptr, try ip.getOrPutString(gpa, "len", .no_embedded_nulls), dest_src);25843 const len_air_ref = try sema.fieldVal(block, src, dest_ptr, try ip.getOrPutString(gpa, pt.tid, "len", .no_embedded_nulls), dest_src);
25583 const len_val = (try sema.resolveDefinedValue(block, dest_src, len_air_ref)) orelse break :rs dest_src;25844 const len_val = (try sema.resolveDefinedValue(block, dest_src, len_air_ref)) orelse break :rs dest_src;
25584 const len_u64 = (try len_val.getUnsignedIntAdvanced(mod, .sema)).?;25845 const len_u64 = (try len_val.getUnsignedIntAdvanced(pt, .sema)).?;
25585 const len = try sema.usizeCast(block, dest_src, len_u64);25846 const len = try sema.usizeCast(block, dest_src, len_u64);
25586 if (len == 0) {25847 if (len == 0) {
25587 // This AIR instruction guarantees length > 0 if it is comptime-known.25848 // This AIR instruction guarantees length > 0 if it is comptime-known.
...@@ -25590,22 +25851,22 @@ fn zirMemset(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void...@@ -25590,22 +25851,22 @@ fn zirMemset(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void
2559025851
25591 if (!sema.isComptimeMutablePtr(ptr_val)) break :rs dest_src;25852 if (!sema.isComptimeMutablePtr(ptr_val)) break :rs dest_src;
25592 const elem_val = try sema.resolveValue(elem) orelse break :rs value_src;25853 const elem_val = try sema.resolveValue(elem) orelse break :rs value_src;
25593 const array_ty = try mod.arrayType(.{25854 const array_ty = try pt.arrayType(.{
25594 .child = dest_elem_ty.toIntern(),25855 .child = dest_elem_ty.toIntern(),
25595 .len = len_u64,25856 .len = len_u64,
25596 });25857 });
25597 const array_val = Value.fromInterned((try mod.intern(.{ .aggregate = .{25858 const array_val = Value.fromInterned(try pt.intern(.{ .aggregate = .{
25598 .ty = array_ty.toIntern(),25859 .ty = array_ty.toIntern(),
25599 .storage = .{ .repeated_elem = elem_val.toIntern() },25860 .storage = .{ .repeated_elem = elem_val.toIntern() },
25600 } })));25861 } }));
25601 const array_ptr_ty = ty: {25862 const array_ptr_ty = ty: {
25602 var info = dest_ptr_ty.ptrInfo(mod);25863 var info = dest_ptr_ty.ptrInfo(mod);
25603 info.flags.size = .One;25864 info.flags.size = .One;
25604 info.child = array_ty.toIntern();25865 info.child = array_ty.toIntern();
25605 break :ty try mod.ptrType(info);25866 break :ty try pt.ptrType(info);
25606 };25867 };
25607 const raw_ptr_val = if (dest_ptr_ty.isSlice(mod)) ptr_val.slicePtr(mod) else ptr_val;25868 const raw_ptr_val = if (dest_ptr_ty.isSlice(mod)) ptr_val.slicePtr(mod) else ptr_val;
25608 const array_ptr_val = try mod.getCoerced(raw_ptr_val, array_ptr_ty);25869 const array_ptr_val = try pt.getCoerced(raw_ptr_val, array_ptr_ty);
25609 return sema.storePtrVal(block, src, array_ptr_val, array_val, array_ty);25870 return sema.storePtrVal(block, src, array_ptr_val, array_val, array_ty);
25610 };25871 };
2561125872
...@@ -25658,7 +25919,8 @@ fn zirVarExtended(...@@ -25658,7 +25919,8 @@ fn zirVarExtended(
25658 block: *Block,25919 block: *Block,
25659 extended: Zir.Inst.Extended.InstData,25920 extended: Zir.Inst.Extended.InstData,
25660) CompileError!Air.Inst.Ref {25921) CompileError!Air.Inst.Ref {
25661 const mod = sema.mod;25922 const pt = sema.pt;
25923 const mod = pt.zcu;
25662 const extra = sema.code.extraData(Zir.Inst.ExtendedVar, extended.operand);25924 const extra = sema.code.extraData(Zir.Inst.ExtendedVar, extended.operand);
25663 const ty_src = block.src(.{ .node_offset_var_decl_ty = 0 });25925 const ty_src = block.src(.{ .node_offset_var_decl_ty = 0 });
25664 const init_src = block.src(.{ .node_offset_var_decl_init = 0 });25926 const init_src = block.src(.{ .node_offset_var_decl_init = 0 });
...@@ -25705,11 +25967,11 @@ fn zirVarExtended(...@@ -25705,11 +25967,11 @@ fn zirVarExtended(
2570525967
25706 try sema.validateVarType(block, ty_src, var_ty, small.is_extern);25968 try sema.validateVarType(block, ty_src, var_ty, small.is_extern);
2570725969
25708 return Air.internedToRef((try mod.intern(.{ .variable = .{25970 return Air.internedToRef((try pt.intern(.{ .variable = .{
25709 .ty = var_ty.toIntern(),25971 .ty = var_ty.toIntern(),
25710 .init = init_val,25972 .init = init_val,
25711 .decl = sema.owner_decl_index,25973 .decl = sema.owner_decl_index,
25712 .lib_name = try mod.intern_pool.getOrPutStringOpt(sema.gpa, lib_name, .no_embedded_nulls),25974 .lib_name = try mod.intern_pool.getOrPutStringOpt(sema.gpa, pt.tid, lib_name, .no_embedded_nulls),
25713 .is_extern = small.is_extern,25975 .is_extern = small.is_extern,
25714 .is_const = small.is_const,25976 .is_const = small.is_const,
25715 .is_threadlocal = small.is_threadlocal,25977 .is_threadlocal = small.is_threadlocal,
...@@ -25721,7 +25983,8 @@ fn zirFuncFancy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A...@@ -25721,7 +25983,8 @@ fn zirFuncFancy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
25721 const tracy = trace(@src());25983 const tracy = trace(@src());
25722 defer tracy.end();25984 defer tracy.end();
2572325985
25724 const mod = sema.mod;25986 const pt = sema.pt;
25987 const mod = pt.zcu;
25725 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;25988 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
25726 const extra = sema.code.extraData(Zir.Inst.FuncFancy, inst_data.payload_index);25989 const extra = sema.code.extraData(Zir.Inst.FuncFancy, inst_data.payload_index);
25727 const target = mod.getTarget();25990 const target = mod.getTarget();
...@@ -25761,7 +26024,7 @@ fn zirFuncFancy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A...@@ -25761,7 +26024,7 @@ fn zirFuncFancy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
25761 if (val.isGenericPoison()) {26024 if (val.isGenericPoison()) {
25762 break :blk null;26025 break :blk null;
25763 }26026 }
25764 const alignment = try sema.validateAlignAllowZero(block, align_src, try val.toUnsignedIntSema(mod));26027 const alignment = try sema.validateAlignAllowZero(block, align_src, try val.toUnsignedIntSema(pt));
25765 const default = target_util.defaultFunctionAlignment(target);26028 const default = target_util.defaultFunctionAlignment(target);
25766 break :blk if (alignment == default) .none else alignment;26029 break :blk if (alignment == default) .none else alignment;
25767 } else if (extra.data.bits.has_align_ref) blk: {26030 } else if (extra.data.bits.has_align_ref) blk: {
...@@ -25781,7 +26044,7 @@ fn zirFuncFancy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A...@@ -25781,7 +26044,7 @@ fn zirFuncFancy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
25781 error.GenericPoison => break :blk null,26044 error.GenericPoison => break :blk null,
25782 else => |e| return e,26045 else => |e| return e,
25783 };26046 };
25784 const alignment = try sema.validateAlignAllowZero(block, align_src, try align_val.toUnsignedIntSema(mod));26047 const alignment = try sema.validateAlignAllowZero(block, align_src, try align_val.toUnsignedIntSema(pt));
25785 const default = target_util.defaultFunctionAlignment(target);26048 const default = target_util.defaultFunctionAlignment(target);
25786 break :blk if (alignment == default) .none else alignment;26049 break :blk if (alignment == default) .none else alignment;
25787 } else .none;26050 } else .none;
...@@ -25857,7 +26120,7 @@ fn zirFuncFancy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A...@@ -25857,7 +26120,7 @@ fn zirFuncFancy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
25857 const body = sema.code.bodySlice(extra_index, body_len);26120 const body = sema.code.bodySlice(extra_index, body_len);
25858 extra_index += body.len;26121 extra_index += body.len;
2585926122
25860 const cc_ty = try mod.getBuiltinType("CallingConvention");26123 const cc_ty = try pt.getBuiltinType("CallingConvention");
25861 const val = try sema.resolveGenericBody(block, cc_src, body, inst, cc_ty, .{26124 const val = try sema.resolveGenericBody(block, cc_src, body, inst, cc_ty, .{
25862 .needed_comptime_reason = "calling convention must be comptime-known",26125 .needed_comptime_reason = "calling convention must be comptime-known",
25863 });26126 });
...@@ -25986,7 +26249,8 @@ fn zirCDefine(...@@ -25986,7 +26249,8 @@ fn zirCDefine(
25986 block: *Block,26249 block: *Block,
25987 extended: Zir.Inst.Extended.InstData,26250 extended: Zir.Inst.Extended.InstData,
25988) CompileError!Air.Inst.Ref {26251) CompileError!Air.Inst.Ref {
25989 const mod = sema.mod;26252 const pt = sema.pt;
26253 const mod = pt.zcu;
25990 const extra = sema.code.extraData(Zir.Inst.BinNode, extended.operand).data;26254 const extra = sema.code.extraData(Zir.Inst.BinNode, extended.operand).data;
25991 const name_src = block.builtinCallArgSrc(extra.node, 0);26255 const name_src = block.builtinCallArgSrc(extra.node, 0);
25992 const val_src = block.builtinCallArgSrc(extra.node, 1);26256 const val_src = block.builtinCallArgSrc(extra.node, 1);
...@@ -26014,7 +26278,7 @@ fn zirWasmMemorySize(...@@ -26014,7 +26278,7 @@ fn zirWasmMemorySize(
26014 const extra = sema.code.extraData(Zir.Inst.UnNode, extended.operand).data;26278 const extra = sema.code.extraData(Zir.Inst.UnNode, extended.operand).data;
26015 const index_src = block.builtinCallArgSrc(extra.node, 0);26279 const index_src = block.builtinCallArgSrc(extra.node, 0);
26016 const builtin_src = block.nodeOffset(extra.node);26280 const builtin_src = block.nodeOffset(extra.node);
26017 const target = sema.mod.getTarget();26281 const target = sema.pt.zcu.getTarget();
26018 if (!target.isWasm()) {26282 if (!target.isWasm()) {
26019 return sema.fail(block, builtin_src, "builtin @wasmMemorySize is available when targeting WebAssembly; targeted CPU architecture is {s}", .{@tagName(target.cpu.arch)});26283 return sema.fail(block, builtin_src, "builtin @wasmMemorySize is available when targeting WebAssembly; targeted CPU architecture is {s}", .{@tagName(target.cpu.arch)});
26020 }26284 }
...@@ -26041,7 +26305,7 @@ fn zirWasmMemoryGrow(...@@ -26041,7 +26305,7 @@ fn zirWasmMemoryGrow(
26041 const builtin_src = block.nodeOffset(extra.node);26305 const builtin_src = block.nodeOffset(extra.node);
26042 const index_src = block.builtinCallArgSrc(extra.node, 0);26306 const index_src = block.builtinCallArgSrc(extra.node, 0);
26043 const delta_src = block.builtinCallArgSrc(extra.node, 1);26307 const delta_src = block.builtinCallArgSrc(extra.node, 1);
26044 const target = sema.mod.getTarget();26308 const target = sema.pt.zcu.getTarget();
26045 if (!target.isWasm()) {26309 if (!target.isWasm()) {
26046 return sema.fail(block, builtin_src, "builtin @wasmMemoryGrow is available when targeting WebAssembly; targeted CPU architecture is {s}", .{@tagName(target.cpu.arch)});26310 return sema.fail(block, builtin_src, "builtin @wasmMemoryGrow is available when targeting WebAssembly; targeted CPU architecture is {s}", .{@tagName(target.cpu.arch)});
26047 }26311 }
...@@ -26067,34 +26331,35 @@ fn resolvePrefetchOptions(...@@ -26067,34 +26331,35 @@ fn resolvePrefetchOptions(
26067 src: LazySrcLoc,26331 src: LazySrcLoc,
26068 zir_ref: Zir.Inst.Ref,26332 zir_ref: Zir.Inst.Ref,
26069) CompileError!std.builtin.PrefetchOptions {26333) CompileError!std.builtin.PrefetchOptions {
26070 const mod = sema.mod;26334 const pt = sema.pt;
26335 const mod = pt.zcu;
26071 const gpa = sema.gpa;26336 const gpa = sema.gpa;
26072 const ip = &mod.intern_pool;26337 const ip = &mod.intern_pool;
26073 const options_ty = try mod.getBuiltinType("PrefetchOptions");26338 const options_ty = try pt.getBuiltinType("PrefetchOptions");
26074 const options = try sema.coerce(block, options_ty, try sema.resolveInst(zir_ref), src);26339 const options = try sema.coerce(block, options_ty, try sema.resolveInst(zir_ref), src);
2607526340
26076 const rw_src = block.src(.{ .init_field_rw = src.offset.node_offset_builtin_call_arg.builtin_call_node });26341 const rw_src = block.src(.{ .init_field_rw = src.offset.node_offset_builtin_call_arg.builtin_call_node });
26077 const locality_src = block.src(.{ .init_field_locality = src.offset.node_offset_builtin_call_arg.builtin_call_node });26342 const locality_src = block.src(.{ .init_field_locality = src.offset.node_offset_builtin_call_arg.builtin_call_node });
26078 const cache_src = block.src(.{ .init_field_cache = src.offset.node_offset_builtin_call_arg.builtin_call_node });26343 const cache_src = block.src(.{ .init_field_cache = src.offset.node_offset_builtin_call_arg.builtin_call_node });
2607926344
26080 const rw = try sema.fieldVal(block, src, options, try ip.getOrPutString(gpa, "rw", .no_embedded_nulls), rw_src);26345 const rw = try sema.fieldVal(block, src, options, try ip.getOrPutString(gpa, pt.tid, "rw", .no_embedded_nulls), rw_src);
26081 const rw_val = try sema.resolveConstDefinedValue(block, rw_src, rw, .{26346 const rw_val = try sema.resolveConstDefinedValue(block, rw_src, rw, .{
26082 .needed_comptime_reason = "prefetch read/write must be comptime-known",26347 .needed_comptime_reason = "prefetch read/write must be comptime-known",
26083 });26348 });
2608426349
26085 const locality = try sema.fieldVal(block, src, options, try ip.getOrPutString(gpa, "locality", .no_embedded_nulls), locality_src);26350 const locality = try sema.fieldVal(block, src, options, try ip.getOrPutString(gpa, pt.tid, "locality", .no_embedded_nulls), locality_src);
26086 const locality_val = try sema.resolveConstDefinedValue(block, locality_src, locality, .{26351 const locality_val = try sema.resolveConstDefinedValue(block, locality_src, locality, .{
26087 .needed_comptime_reason = "prefetch locality must be comptime-known",26352 .needed_comptime_reason = "prefetch locality must be comptime-known",
26088 });26353 });
2608926354
26090 const cache = try sema.fieldVal(block, src, options, try ip.getOrPutString(gpa, "cache", .no_embedded_nulls), cache_src);26355 const cache = try sema.fieldVal(block, src, options, try ip.getOrPutString(gpa, pt.tid, "cache", .no_embedded_nulls), cache_src);
26091 const cache_val = try sema.resolveConstDefinedValue(block, cache_src, cache, .{26356 const cache_val = try sema.resolveConstDefinedValue(block, cache_src, cache, .{
26092 .needed_comptime_reason = "prefetch cache must be comptime-known",26357 .needed_comptime_reason = "prefetch cache must be comptime-known",
26093 });26358 });
2609426359
26095 return std.builtin.PrefetchOptions{26360 return std.builtin.PrefetchOptions{
26096 .rw = mod.toEnum(std.builtin.PrefetchOptions.Rw, rw_val),26361 .rw = mod.toEnum(std.builtin.PrefetchOptions.Rw, rw_val),
26097 .locality = @intCast(try locality_val.toUnsignedIntSema(mod)),26362 .locality = @intCast(try locality_val.toUnsignedIntSema(pt)),
26098 .cache = mod.toEnum(std.builtin.PrefetchOptions.Cache, cache_val),26363 .cache = mod.toEnum(std.builtin.PrefetchOptions.Cache, cache_val),
26099 };26364 };
26100}26365}
...@@ -26138,11 +26403,12 @@ fn resolveExternOptions(...@@ -26138,11 +26403,12 @@ fn resolveExternOptions(
26138 linkage: std.builtin.GlobalLinkage = .strong,26403 linkage: std.builtin.GlobalLinkage = .strong,
26139 is_thread_local: bool = false,26404 is_thread_local: bool = false,
26140} {26405} {
26141 const mod = sema.mod;26406 const pt = sema.pt;
26407 const mod = pt.zcu;
26142 const gpa = sema.gpa;26408 const gpa = sema.gpa;
26143 const ip = &mod.intern_pool;26409 const ip = &mod.intern_pool;
26144 const options_inst = try sema.resolveInst(zir_ref);26410 const options_inst = try sema.resolveInst(zir_ref);
26145 const extern_options_ty = try mod.getBuiltinType("ExternOptions");26411 const extern_options_ty = try pt.getBuiltinType("ExternOptions");
26146 const options = try sema.coerce(block, extern_options_ty, options_inst, src);26412 const options = try sema.coerce(block, extern_options_ty, options_inst, src);
2614726413
26148 const name_src = block.src(.{ .init_field_name = src.offset.node_offset_builtin_call_arg.builtin_call_node });26414 const name_src = block.src(.{ .init_field_name = src.offset.node_offset_builtin_call_arg.builtin_call_node });
...@@ -26150,23 +26416,23 @@ fn resolveExternOptions(...@@ -26150,23 +26416,23 @@ fn resolveExternOptions(
26150 const linkage_src = block.src(.{ .init_field_linkage = src.offset.node_offset_builtin_call_arg.builtin_call_node });26416 const linkage_src = block.src(.{ .init_field_linkage = src.offset.node_offset_builtin_call_arg.builtin_call_node });
26151 const thread_local_src = block.src(.{ .init_field_thread_local = src.offset.node_offset_builtin_call_arg.builtin_call_node });26417 const thread_local_src = block.src(.{ .init_field_thread_local = src.offset.node_offset_builtin_call_arg.builtin_call_node });
2615226418
26153 const name_ref = try sema.fieldVal(block, src, options, try ip.getOrPutString(gpa, "name", .no_embedded_nulls), name_src);26419 const name_ref = try sema.fieldVal(block, src, options, try ip.getOrPutString(gpa, pt.tid, "name", .no_embedded_nulls), name_src);
26154 const name = try sema.toConstString(block, name_src, name_ref, .{26420 const name = try sema.toConstString(block, name_src, name_ref, .{
26155 .needed_comptime_reason = "name of the extern symbol must be comptime-known",26421 .needed_comptime_reason = "name of the extern symbol must be comptime-known",
26156 });26422 });
2615726423
26158 const library_name_inst = try sema.fieldVal(block, src, options, try ip.getOrPutString(gpa, "library_name", .no_embedded_nulls), library_src);26424 const library_name_inst = try sema.fieldVal(block, src, options, try ip.getOrPutString(gpa, pt.tid, "library_name", .no_embedded_nulls), library_src);
26159 const library_name_val = try sema.resolveConstDefinedValue(block, library_src, library_name_inst, .{26425 const library_name_val = try sema.resolveConstDefinedValue(block, library_src, library_name_inst, .{
26160 .needed_comptime_reason = "library in which extern symbol is must be comptime-known",26426 .needed_comptime_reason = "library in which extern symbol is must be comptime-known",
26161 });26427 });
2616226428
26163 const linkage_ref = try sema.fieldVal(block, src, options, try ip.getOrPutString(gpa, "linkage", .no_embedded_nulls), linkage_src);26429 const linkage_ref = try sema.fieldVal(block, src, options, try ip.getOrPutString(gpa, pt.tid, "linkage", .no_embedded_nulls), linkage_src);
26164 const linkage_val = try sema.resolveConstDefinedValue(block, linkage_src, linkage_ref, .{26430 const linkage_val = try sema.resolveConstDefinedValue(block, linkage_src, linkage_ref, .{
26165 .needed_comptime_reason = "linkage of the extern symbol must be comptime-known",26431 .needed_comptime_reason = "linkage of the extern symbol must be comptime-known",
26166 });26432 });
26167 const linkage = mod.toEnum(std.builtin.GlobalLinkage, linkage_val);26433 const linkage = mod.toEnum(std.builtin.GlobalLinkage, linkage_val);
2616826434
26169 const is_thread_local = try sema.fieldVal(block, src, options, try ip.getOrPutString(gpa, "is_thread_local", .no_embedded_nulls), thread_local_src);26435 const is_thread_local = try sema.fieldVal(block, src, options, try ip.getOrPutString(gpa, pt.tid, "is_thread_local", .no_embedded_nulls), thread_local_src);
26170 const is_thread_local_val = try sema.resolveConstDefinedValue(block, thread_local_src, is_thread_local, .{26436 const is_thread_local_val = try sema.resolveConstDefinedValue(block, thread_local_src, is_thread_local, .{
26171 .needed_comptime_reason = "threadlocality of the extern symbol must be comptime-known",26437 .needed_comptime_reason = "threadlocality of the extern symbol must be comptime-known",
26172 });26438 });
...@@ -26191,8 +26457,8 @@ fn resolveExternOptions(...@@ -26191,8 +26457,8 @@ fn resolveExternOptions(
26191 }26457 }
2619226458
26193 return .{26459 return .{
26194 .name = try ip.getOrPutString(gpa, name, .no_embedded_nulls),26460 .name = try ip.getOrPutString(gpa, pt.tid, name, .no_embedded_nulls),
26195 .library_name = try ip.getOrPutStringOpt(gpa, library_name, .no_embedded_nulls),26461 .library_name = try ip.getOrPutStringOpt(gpa, pt.tid, library_name, .no_embedded_nulls),
26196 .linkage = linkage,26462 .linkage = linkage,
26197 .is_thread_local = is_thread_local_val.toBool(),26463 .is_thread_local = is_thread_local_val.toBool(),
26198 };26464 };
...@@ -26203,7 +26469,8 @@ fn zirBuiltinExtern(...@@ -26203,7 +26469,8 @@ fn zirBuiltinExtern(
26203 block: *Block,26469 block: *Block,
26204 extended: Zir.Inst.Extended.InstData,26470 extended: Zir.Inst.Extended.InstData,
26205) CompileError!Air.Inst.Ref {26471) CompileError!Air.Inst.Ref {
26206 const mod = sema.mod;26472 const pt = sema.pt;
26473 const mod = pt.zcu;
26207 const ip = &mod.intern_pool;26474 const ip = &mod.intern_pool;
26208 const extra = sema.code.extraData(Zir.Inst.BinNode, extended.operand).data;26475 const extra = sema.code.extraData(Zir.Inst.BinNode, extended.operand).data;
26209 const ty_src = block.builtinCallArgSrc(extra.node, 0);26476 const ty_src = block.builtinCallArgSrc(extra.node, 0);
...@@ -26215,7 +26482,7 @@ fn zirBuiltinExtern(...@@ -26215,7 +26482,7 @@ fn zirBuiltinExtern(
26215 }26482 }
26216 if (!try sema.validateExternType(ty, .other)) {26483 if (!try sema.validateExternType(ty, .other)) {
26217 const msg = msg: {26484 const msg = msg: {
26218 const msg = try sema.errMsg(ty_src, "extern symbol cannot have type '{}'", .{ty.fmt(mod)});26485 const msg = try sema.errMsg(ty_src, "extern symbol cannot have type '{}'", .{ty.fmt(pt)});
26219 errdefer msg.destroy(sema.gpa);26486 errdefer msg.destroy(sema.gpa);
26220 try sema.explainWhyTypeIsNotExtern(msg, ty_src, ty, .other);26487 try sema.explainWhyTypeIsNotExtern(msg, ty_src, ty, .other);
26221 break :msg msg;26488 break :msg msg;
...@@ -26226,7 +26493,7 @@ fn zirBuiltinExtern(...@@ -26226,7 +26493,7 @@ fn zirBuiltinExtern(
26226 const options = try sema.resolveExternOptions(block, options_src, extra.rhs);26493 const options = try sema.resolveExternOptions(block, options_src, extra.rhs);
2622726494
26228 if (options.linkage == .weak and !ty.ptrAllowsZero(mod)) {26495 if (options.linkage == .weak and !ty.ptrAllowsZero(mod)) {
26229 ty = try mod.optionalType(ty.toIntern());26496 ty = try pt.optionalType(ty.toIntern());
26230 }26497 }
26231 const ptr_info = ty.ptrInfo(mod);26498 const ptr_info = ty.ptrInfo(mod);
2623226499
...@@ -26237,13 +26504,13 @@ fn zirBuiltinExtern(...@@ -26237,13 +26504,13 @@ fn zirBuiltinExtern(
26237 new_decl_index,26504 new_decl_index,
26238 Value.fromInterned(26505 Value.fromInterned(
26239 if (Type.fromInterned(ptr_info.child).zigTypeTag(mod) == .Fn)26506 if (Type.fromInterned(ptr_info.child).zigTypeTag(mod) == .Fn)
26240 try ip.getExternFunc(sema.gpa, .{26507 try ip.getExternFunc(sema.gpa, pt.tid, .{
26241 .ty = ptr_info.child,26508 .ty = ptr_info.child,
26242 .decl = new_decl_index,26509 .decl = new_decl_index,
26243 .lib_name = options.library_name,26510 .lib_name = options.library_name,
26244 })26511 })
26245 else26512 else
26246 try mod.intern(.{ .variable = .{26513 try pt.intern(.{ .variable = .{
26247 .ty = ptr_info.child,26514 .ty = ptr_info.child,
26248 .init = .none,26515 .init = .none,
26249 .decl = new_decl_index,26516 .decl = new_decl_index,
...@@ -26259,9 +26526,9 @@ fn zirBuiltinExtern(...@@ -26259,9 +26526,9 @@ fn zirBuiltinExtern(
26259 new_decl.owns_tv = true;26526 new_decl.owns_tv = true;
26260 // Note that this will queue the anon decl for codegen, so that the backend can26527 // Note that this will queue the anon decl for codegen, so that the backend can
26261 // correctly handle the extern, including duplicate detection.26528 // correctly handle the extern, including duplicate detection.
26262 try mod.finalizeAnonDecl(new_decl_index);26529 try pt.finalizeAnonDecl(new_decl_index);
2626326530
26264 return Air.internedToRef((try mod.getCoerced(Value.fromInterned((try mod.intern(.{ .ptr = .{26531 return Air.internedToRef((try pt.getCoerced(Value.fromInterned(try pt.intern(.{ .ptr = .{
26265 .ty = switch (ip.indexToKey(ty.toIntern())) {26532 .ty = switch (ip.indexToKey(ty.toIntern())) {
26266 .ptr_type => ty.toIntern(),26533 .ptr_type => ty.toIntern(),
26267 .opt_type => |child_type| child_type,26534 .opt_type => |child_type| child_type,
...@@ -26269,7 +26536,7 @@ fn zirBuiltinExtern(...@@ -26269,7 +26536,7 @@ fn zirBuiltinExtern(
26269 },26536 },
26270 .base_addr = .{ .decl = new_decl_index },26537 .base_addr = .{ .decl = new_decl_index },
26271 .byte_offset = 0,26538 .byte_offset = 0,
26272 } }))), ty)).toIntern());26539 } })), ty)).toIntern());
26273}26540}
2627426541
26275fn zirWorkItem(26542fn zirWorkItem(
...@@ -26281,7 +26548,7 @@ fn zirWorkItem(...@@ -26281,7 +26548,7 @@ fn zirWorkItem(
26281 const extra = sema.code.extraData(Zir.Inst.UnNode, extended.operand).data;26548 const extra = sema.code.extraData(Zir.Inst.UnNode, extended.operand).data;
26282 const dimension_src = block.builtinCallArgSrc(extra.node, 0);26549 const dimension_src = block.builtinCallArgSrc(extra.node, 0);
26283 const builtin_src = block.nodeOffset(extra.node);26550 const builtin_src = block.nodeOffset(extra.node);
26284 const target = sema.mod.getTarget();26551 const target = sema.pt.zcu.getTarget();
2628526552
26286 switch (target.cpu.arch) {26553 switch (target.cpu.arch) {
26287 // TODO: Allow for other GPU targets.26554 // TODO: Allow for other GPU targets.
...@@ -26344,11 +26611,12 @@ fn validateVarType(...@@ -26344,11 +26611,12 @@ fn validateVarType(
26344 var_ty: Type,26611 var_ty: Type,
26345 is_extern: bool,26612 is_extern: bool,
26346) CompileError!void {26613) CompileError!void {
26347 const mod = sema.mod;26614 const pt = sema.pt;
26615 const mod = pt.zcu;
26348 if (is_extern) {26616 if (is_extern) {
26349 if (!try sema.validateExternType(var_ty, .other)) {26617 if (!try sema.validateExternType(var_ty, .other)) {
26350 const msg = msg: {26618 const msg = msg: {
26351 const msg = try sema.errMsg(src, "extern variable cannot have type '{}'", .{var_ty.fmt(mod)});26619 const msg = try sema.errMsg(src, "extern variable cannot have type '{}'", .{var_ty.fmt(pt)});
26352 errdefer msg.destroy(sema.gpa);26620 errdefer msg.destroy(sema.gpa);
26353 try sema.explainWhyTypeIsNotExtern(msg, src, var_ty, .other);26621 try sema.explainWhyTypeIsNotExtern(msg, src, var_ty, .other);
26354 break :msg msg;26622 break :msg msg;
...@@ -26361,7 +26629,7 @@ fn validateVarType(...@@ -26361,7 +26629,7 @@ fn validateVarType(
26361 block,26629 block,
26362 src,26630 src,
26363 "non-extern variable with opaque type '{}'",26631 "non-extern variable with opaque type '{}'",
26364 .{var_ty.fmt(mod)},26632 .{var_ty.fmt(pt)},
26365 );26633 );
26366 }26634 }
26367 }26635 }
...@@ -26369,7 +26637,7 @@ fn validateVarType(...@@ -26369,7 +26637,7 @@ fn validateVarType(
26369 if (!try sema.typeRequiresComptime(var_ty)) return;26637 if (!try sema.typeRequiresComptime(var_ty)) return;
2637026638
26371 const msg = msg: {26639 const msg = msg: {
26372 const msg = try sema.errMsg(src, "variable of type '{}' must be const or comptime", .{var_ty.fmt(mod)});26640 const msg = try sema.errMsg(src, "variable of type '{}' must be const or comptime", .{var_ty.fmt(pt)});
26373 errdefer msg.destroy(sema.gpa);26641 errdefer msg.destroy(sema.gpa);
2637426642
26375 try sema.explainWhyTypeIsComptime(msg, src, var_ty);26643 try sema.explainWhyTypeIsComptime(msg, src, var_ty);
...@@ -26393,7 +26661,7 @@ fn explainWhyTypeIsComptime(...@@ -26393,7 +26661,7 @@ fn explainWhyTypeIsComptime(
26393 var type_set = TypeSet{};26661 var type_set = TypeSet{};
26394 defer type_set.deinit(sema.gpa);26662 defer type_set.deinit(sema.gpa);
2639526663
26396 try ty.resolveFully(sema.mod);26664 try ty.resolveFully(sema.pt);
26397 return sema.explainWhyTypeIsComptimeInner(msg, src_loc, ty, &type_set);26665 return sema.explainWhyTypeIsComptimeInner(msg, src_loc, ty, &type_set);
26398}26666}
2639926667
...@@ -26404,7 +26672,8 @@ fn explainWhyTypeIsComptimeInner(...@@ -26404,7 +26672,8 @@ fn explainWhyTypeIsComptimeInner(
26404 ty: Type,26672 ty: Type,
26405 type_set: *TypeSet,26673 type_set: *TypeSet,
26406) CompileError!void {26674) CompileError!void {
26407 const mod = sema.mod;26675 const pt = sema.pt;
26676 const mod = pt.zcu;
26408 const ip = &mod.intern_pool;26677 const ip = &mod.intern_pool;
26409 switch (ty.zigTypeTag(mod)) {26678 switch (ty.zigTypeTag(mod)) {
26410 .Bool,26679 .Bool,
...@@ -26418,9 +26687,7 @@ fn explainWhyTypeIsComptimeInner(...@@ -26418,9 +26687,7 @@ fn explainWhyTypeIsComptimeInner(
26418 => return,26687 => return,
2641926688
26420 .Fn => {26689 .Fn => {
26421 try sema.errNote(src_loc, msg, "use '*const {}' for a function pointer type", .{26690 try sema.errNote(src_loc, msg, "use '*const {}' for a function pointer type", .{ty.fmt(pt)});
26422 ty.fmt(sema.mod),
26423 });
26424 },26691 },
2642526692
26426 .Type => {26693 .Type => {
...@@ -26436,7 +26703,7 @@ fn explainWhyTypeIsComptimeInner(...@@ -26436,7 +26703,7 @@ fn explainWhyTypeIsComptimeInner(
26436 => return,26703 => return,
2643726704
26438 .Opaque => {26705 .Opaque => {
26439 try sema.errNote(src_loc, msg, "opaque type '{}' has undefined size", .{ty.fmt(sema.mod)});26706 try sema.errNote(src_loc, msg, "opaque type '{}' has undefined size", .{ty.fmt(pt)});
26440 },26707 },
2644126708
26442 .Array, .Vector => {26709 .Array, .Vector => {
...@@ -26453,7 +26720,7 @@ fn explainWhyTypeIsComptimeInner(...@@ -26453,7 +26720,7 @@ fn explainWhyTypeIsComptimeInner(
26453 .Inline => try sema.errNote(src_loc, msg, "function has inline calling convention", .{}),26720 .Inline => try sema.errNote(src_loc, msg, "function has inline calling convention", .{}),
26454 else => {},26721 else => {},
26455 }26722 }
26456 if (Type.fromInterned(fn_info.return_type).comptimeOnly(mod)) {26723 if (Type.fromInterned(fn_info.return_type).comptimeOnly(pt)) {
26457 try sema.errNote(src_loc, msg, "function has a comptime-only return type", .{});26724 try sema.errNote(src_loc, msg, "function has a comptime-only return type", .{});
26458 }26725 }
26459 return;26726 return;
...@@ -26526,7 +26793,8 @@ fn validateExternType(...@@ -26526,7 +26793,8 @@ fn validateExternType(
26526 ty: Type,26793 ty: Type,
26527 position: ExternPosition,26794 position: ExternPosition,
26528) !bool {26795) !bool {
26529 const mod = sema.mod;26796 const pt = sema.pt;
26797 const mod = pt.zcu;
26530 switch (ty.zigTypeTag(mod)) {26798 switch (ty.zigTypeTag(mod)) {
26531 .Type,26799 .Type,
26532 .ComptimeFloat,26800 .ComptimeFloat,
...@@ -26557,7 +26825,7 @@ fn validateExternType(...@@ -26557,7 +26825,7 @@ fn validateExternType(
26557 },26825 },
26558 .Fn => {26826 .Fn => {
26559 if (position != .other) return false;26827 if (position != .other) return false;
26560 const target = sema.mod.getTarget();26828 const target = mod.getTarget();
26561 // For now we want to authorize PTX kernel to use zig objects, even if we end up exposing the ABI.26829 // For now we want to authorize PTX kernel to use zig objects, even if we end up exposing the ABI.
26562 // The goal is to experiment with more integrated CPU/GPU code.26830 // The goal is to experiment with more integrated CPU/GPU code.
26563 if (ty.fnCallingConvention(mod) == .Kernel and (target.cpu.arch == .nvptx or target.cpu.arch == .nvptx64)) {26831 if (ty.fnCallingConvention(mod) == .Kernel and (target.cpu.arch == .nvptx or target.cpu.arch == .nvptx64)) {
...@@ -26571,7 +26839,7 @@ fn validateExternType(...@@ -26571,7 +26839,7 @@ fn validateExternType(
26571 .Struct, .Union => switch (ty.containerLayout(mod)) {26839 .Struct, .Union => switch (ty.containerLayout(mod)) {
26572 .@"extern" => return true,26840 .@"extern" => return true,
26573 .@"packed" => {26841 .@"packed" => {
26574 const bit_size = try ty.bitSizeAdvanced(mod, .sema);26842 const bit_size = try ty.bitSizeAdvanced(pt, .sema);
26575 switch (bit_size) {26843 switch (bit_size) {
26576 0, 8, 16, 32, 64, 128 => return true,26844 0, 8, 16, 32, 64, 128 => return true,
26577 else => return false,26845 else => return false,
...@@ -26595,7 +26863,8 @@ fn explainWhyTypeIsNotExtern(...@@ -26595,7 +26863,8 @@ fn explainWhyTypeIsNotExtern(
26595 ty: Type,26863 ty: Type,
26596 position: ExternPosition,26864 position: ExternPosition,
26597) CompileError!void {26865) CompileError!void {
26598 const mod = sema.mod;26866 const pt = sema.pt;
26867 const mod = pt.zcu;
26599 switch (ty.zigTypeTag(mod)) {26868 switch (ty.zigTypeTag(mod)) {
26600 .Opaque,26869 .Opaque,
26601 .Bool,26870 .Bool,
...@@ -26622,7 +26891,7 @@ fn explainWhyTypeIsNotExtern(...@@ -26622,7 +26891,7 @@ fn explainWhyTypeIsNotExtern(
26622 if (!ty.isConstPtr(mod) and pointee_ty.zigTypeTag(mod) == .Fn) {26891 if (!ty.isConstPtr(mod) and pointee_ty.zigTypeTag(mod) == .Fn) {
26623 try sema.errNote(src_loc, msg, "pointer to extern function must be 'const'", .{});26892 try sema.errNote(src_loc, msg, "pointer to extern function must be 'const'", .{});
26624 } else if (try sema.typeRequiresComptime(ty)) {26893 } else if (try sema.typeRequiresComptime(ty)) {
26625 try sema.errNote(src_loc, msg, "pointer to comptime-only type '{}'", .{pointee_ty.fmt(sema.mod)});26894 try sema.errNote(src_loc, msg, "pointer to comptime-only type '{}'", .{pointee_ty.fmt(pt)});
26626 try sema.explainWhyTypeIsComptime(msg, src_loc, ty);26895 try sema.explainWhyTypeIsComptime(msg, src_loc, ty);
26627 }26896 }
26628 try sema.explainWhyTypeIsNotExtern(msg, src_loc, pointee_ty, .other);26897 try sema.explainWhyTypeIsNotExtern(msg, src_loc, pointee_ty, .other);
...@@ -26650,7 +26919,7 @@ fn explainWhyTypeIsNotExtern(...@@ -26650,7 +26919,7 @@ fn explainWhyTypeIsNotExtern(
26650 },26919 },
26651 .Enum => {26920 .Enum => {
26652 const tag_ty = ty.intTagType(mod);26921 const tag_ty = ty.intTagType(mod);
26653 try sema.errNote(src_loc, msg, "enum tag type '{}' is not extern compatible", .{tag_ty.fmt(sema.mod)});26922 try sema.errNote(src_loc, msg, "enum tag type '{}' is not extern compatible", .{tag_ty.fmt(pt)});
26654 try sema.explainWhyTypeIsNotExtern(msg, src_loc, tag_ty, position);26923 try sema.explainWhyTypeIsNotExtern(msg, src_loc, tag_ty, position);
26655 },26924 },
26656 .Struct => try sema.errNote(src_loc, msg, "only extern structs and ABI sized packed structs are extern compatible", .{}),26925 .Struct => try sema.errNote(src_loc, msg, "only extern structs and ABI sized packed structs are extern compatible", .{}),
...@@ -26671,7 +26940,8 @@ fn explainWhyTypeIsNotExtern(...@@ -26671,7 +26940,8 @@ fn explainWhyTypeIsNotExtern(
26671/// Returns true if `ty` is allowed in packed types.26940/// Returns true if `ty` is allowed in packed types.
26672/// Does not require `ty` to be resolved in any way, but may resolve whether it is comptime-only.26941/// Does not require `ty` to be resolved in any way, but may resolve whether it is comptime-only.
26673fn validatePackedType(sema: *Sema, ty: Type) !bool {26942fn validatePackedType(sema: *Sema, ty: Type) !bool {
26674 const zcu = sema.mod;26943 const pt = sema.pt;
26944 const zcu = pt.zcu;
26675 return switch (ty.zigTypeTag(zcu)) {26945 return switch (ty.zigTypeTag(zcu)) {
26676 .Type,26946 .Type,
26677 .ComptimeFloat,26947 .ComptimeFloat,
...@@ -26710,7 +26980,8 @@ fn explainWhyTypeIsNotPacked(...@@ -26710,7 +26980,8 @@ fn explainWhyTypeIsNotPacked(
26710 src_loc: LazySrcLoc,26980 src_loc: LazySrcLoc,
26711 ty: Type,26981 ty: Type,
26712) CompileError!void {26982) CompileError!void {
26713 const mod = sema.mod;26983 const pt = sema.pt;
26984 const mod = pt.zcu;
26714 switch (ty.zigTypeTag(mod)) {26985 switch (ty.zigTypeTag(mod)) {
26715 .Void,26986 .Void,
26716 .Bool,26987 .Bool,
...@@ -26750,10 +27021,11 @@ fn explainWhyTypeIsNotPacked(...@@ -26750,10 +27021,11 @@ fn explainWhyTypeIsNotPacked(
26750}27021}
2675127022
26752fn prepareSimplePanic(sema: *Sema) !void {27023fn prepareSimplePanic(sema: *Sema) !void {
26753 const mod = sema.mod;27024 const pt = sema.pt;
27025 const mod = pt.zcu;
2675427026
26755 if (mod.panic_func_index == .none) {27027 if (mod.panic_func_index == .none) {
26756 const decl_index = (try mod.getBuiltinDecl("panic"));27028 const decl_index = (try pt.getBuiltinDecl("panic"));
26757 // decl_index may be an alias; we must find the decl that actually27029 // decl_index may be an alias; we must find the decl that actually
26758 // owns the function.27030 // owns the function.
26759 try sema.ensureDeclAnalyzed(decl_index);27031 try sema.ensureDeclAnalyzed(decl_index);
...@@ -26766,17 +27038,17 @@ fn prepareSimplePanic(sema: *Sema) !void {...@@ -26766,17 +27038,17 @@ fn prepareSimplePanic(sema: *Sema) !void {
26766 }27038 }
2676727039
26768 if (mod.null_stack_trace == .none) {27040 if (mod.null_stack_trace == .none) {
26769 const stack_trace_ty = try mod.getBuiltinType("StackTrace");27041 const stack_trace_ty = try pt.getBuiltinType("StackTrace");
26770 try stack_trace_ty.resolveFields(mod);27042 try stack_trace_ty.resolveFields(pt);
26771 const target = mod.getTarget();27043 const target = mod.getTarget();
26772 const ptr_stack_trace_ty = try mod.ptrTypeSema(.{27044 const ptr_stack_trace_ty = try pt.ptrTypeSema(.{
26773 .child = stack_trace_ty.toIntern(),27045 .child = stack_trace_ty.toIntern(),
26774 .flags = .{27046 .flags = .{
26775 .address_space = target_util.defaultAddressSpace(target, .global_constant),27047 .address_space = target_util.defaultAddressSpace(target, .global_constant),
26776 },27048 },
26777 });27049 });
26778 const opt_ptr_stack_trace_ty = try mod.optionalType(ptr_stack_trace_ty.toIntern());27050 const opt_ptr_stack_trace_ty = try pt.optionalType(ptr_stack_trace_ty.toIntern());
26779 mod.null_stack_trace = try mod.intern(.{ .opt = .{27051 mod.null_stack_trace = try pt.intern(.{ .opt = .{
26780 .ty = opt_ptr_stack_trace_ty.toIntern(),27052 .ty = opt_ptr_stack_trace_ty.toIntern(),
26781 .val = .none,27053 .val = .none,
26782 } });27054 } });
...@@ -26787,18 +27059,19 @@ fn prepareSimplePanic(sema: *Sema) !void {...@@ -26787,18 +27059,19 @@ fn prepareSimplePanic(sema: *Sema) !void {
26787/// instructions. This function ensures the panic function will be available to27059/// instructions. This function ensures the panic function will be available to
26788/// be called during that time.27060/// be called during that time.
26789fn preparePanicId(sema: *Sema, block: *Block, panic_id: Module.PanicId) !InternPool.DeclIndex {27061fn preparePanicId(sema: *Sema, block: *Block, panic_id: Module.PanicId) !InternPool.DeclIndex {
26790 const mod = sema.mod;27062 const pt = sema.pt;
27063 const mod = pt.zcu;
26791 const gpa = sema.gpa;27064 const gpa = sema.gpa;
26792 if (mod.panic_messages[@intFromEnum(panic_id)].unwrap()) |x| return x;27065 if (mod.panic_messages[@intFromEnum(panic_id)].unwrap()) |x| return x;
2679327066
26794 try sema.prepareSimplePanic();27067 try sema.prepareSimplePanic();
2679527068
26796 const panic_messages_ty = try mod.getBuiltinType("panic_messages");27069 const panic_messages_ty = try pt.getBuiltinType("panic_messages");
26797 const msg_decl_index = (sema.namespaceLookup(27070 const msg_decl_index = (sema.namespaceLookup(
26798 block,27071 block,
26799 LazySrcLoc.unneeded,27072 LazySrcLoc.unneeded,
26800 panic_messages_ty.getNamespaceIndex(mod),27073 panic_messages_ty.getNamespaceIndex(mod),
26801 try mod.intern_pool.getOrPutString(gpa, @tagName(panic_id), .no_embedded_nulls),27074 try mod.intern_pool.getOrPutString(gpa, pt.tid, @tagName(panic_id), .no_embedded_nulls),
26802 ) catch |err| switch (err) {27075 ) catch |err| switch (err) {
26803 error.AnalysisFail => @panic("std.builtin.panic_messages is corrupt"),27076 error.AnalysisFail => @panic("std.builtin.panic_messages is corrupt"),
26804 error.GenericPoison, error.ComptimeReturn, error.ComptimeBreak => unreachable,27077 error.GenericPoison, error.ComptimeReturn, error.ComptimeBreak => unreachable,
...@@ -26892,7 +27165,8 @@ fn addSafetyCheckExtra(...@@ -26892,7 +27165,8 @@ fn addSafetyCheckExtra(
26892}27165}
2689327166
26894fn panicWithMsg(sema: *Sema, block: *Block, src: LazySrcLoc, msg_inst: Air.Inst.Ref, operation: CallOperation) !void {27167fn panicWithMsg(sema: *Sema, block: *Block, src: LazySrcLoc, msg_inst: Air.Inst.Ref, operation: CallOperation) !void {
26895 const mod = sema.mod;27168 const pt = sema.pt;
27169 const mod = pt.zcu;
2689627170
26897 if (!mod.backendSupportsFeature(.panic_fn)) {27171 if (!mod.backendSupportsFeature(.panic_fn)) {
26898 _ = try block.addNoOp(.trap);27172 _ = try block.addNoOp(.trap);
...@@ -26905,8 +27179,8 @@ fn panicWithMsg(sema: *Sema, block: *Block, src: LazySrcLoc, msg_inst: Air.Inst....@@ -26905,8 +27179,8 @@ fn panicWithMsg(sema: *Sema, block: *Block, src: LazySrcLoc, msg_inst: Air.Inst.
26905 const panic_fn = try sema.analyzeDeclVal(block, src, panic_func.owner_decl);27179 const panic_fn = try sema.analyzeDeclVal(block, src, panic_func.owner_decl);
26906 const null_stack_trace = Air.internedToRef(mod.null_stack_trace);27180 const null_stack_trace = Air.internedToRef(mod.null_stack_trace);
2690727181
26908 const opt_usize_ty = try mod.optionalType(.usize_type);27182 const opt_usize_ty = try pt.optionalType(.usize_type);
26909 const null_ret_addr = Air.internedToRef((try mod.intern(.{ .opt = .{27183 const null_ret_addr = Air.internedToRef((try pt.intern(.{ .opt = .{
26910 .ty = opt_usize_ty.toIntern(),27184 .ty = opt_usize_ty.toIntern(),
26911 .val = .none,27185 .val = .none,
26912 } })));27186 } })));
...@@ -26921,9 +27195,10 @@ fn panicUnwrapError(...@@ -26921,9 +27195,10 @@ fn panicUnwrapError(
26921 unwrap_err_tag: Air.Inst.Tag,27195 unwrap_err_tag: Air.Inst.Tag,
26922 is_non_err_tag: Air.Inst.Tag,27196 is_non_err_tag: Air.Inst.Tag,
26923) !void {27197) !void {
27198 const pt = sema.pt;
26924 assert(!parent_block.is_comptime);27199 assert(!parent_block.is_comptime);
26925 const ok = try parent_block.addUnOp(is_non_err_tag, operand);27200 const ok = try parent_block.addUnOp(is_non_err_tag, operand);
26926 if (!sema.mod.comp.formatted_panics) {27201 if (!pt.zcu.comp.formatted_panics) {
26927 return sema.addSafetyCheck(parent_block, src, ok, .unwrap_error);27202 return sema.addSafetyCheck(parent_block, src, ok, .unwrap_error);
26928 }27203 }
26929 const gpa = sema.gpa;27204 const gpa = sema.gpa;
...@@ -26942,10 +27217,10 @@ fn panicUnwrapError(...@@ -26942,10 +27217,10 @@ fn panicUnwrapError(
26942 defer fail_block.instructions.deinit(gpa);27217 defer fail_block.instructions.deinit(gpa);
2694327218
26944 {27219 {
26945 if (!sema.mod.backendSupportsFeature(.panic_unwrap_error)) {27220 if (!pt.zcu.backendSupportsFeature(.panic_unwrap_error)) {
26946 _ = try fail_block.addNoOp(.trap);27221 _ = try fail_block.addNoOp(.trap);
26947 } else {27222 } else {
26948 const panic_fn = try sema.mod.getBuiltin("panicUnwrapError");27223 const panic_fn = try sema.pt.getBuiltin("panicUnwrapError");
26949 const err = try fail_block.addTyOp(unwrap_err_tag, Type.anyerror, operand);27224 const err = try fail_block.addTyOp(unwrap_err_tag, Type.anyerror, operand);
26950 const err_return_trace = try sema.getErrorReturnTrace(&fail_block);27225 const err_return_trace = try sema.getErrorReturnTrace(&fail_block);
26951 const args: [2]Air.Inst.Ref = .{ err_return_trace, err };27226 const args: [2]Air.Inst.Ref = .{ err_return_trace, err };
...@@ -26965,7 +27240,7 @@ fn panicIndexOutOfBounds(...@@ -26965,7 +27240,7 @@ fn panicIndexOutOfBounds(
26965) !void {27240) !void {
26966 assert(!parent_block.is_comptime);27241 assert(!parent_block.is_comptime);
26967 const ok = try parent_block.addBinOp(cmp_op, index, len);27242 const ok = try parent_block.addBinOp(cmp_op, index, len);
26968 if (!sema.mod.comp.formatted_panics) {27243 if (!sema.pt.zcu.comp.formatted_panics) {
26969 return sema.addSafetyCheck(parent_block, src, ok, .index_out_of_bounds);27244 return sema.addSafetyCheck(parent_block, src, ok, .index_out_of_bounds);
26970 }27245 }
26971 try sema.safetyCheckFormatted(parent_block, src, ok, "panicOutOfBounds", &.{ index, len });27246 try sema.safetyCheckFormatted(parent_block, src, ok, "panicOutOfBounds", &.{ index, len });
...@@ -26980,7 +27255,7 @@ fn panicInactiveUnionField(...@@ -26980,7 +27255,7 @@ fn panicInactiveUnionField(
26980) !void {27255) !void {
26981 assert(!parent_block.is_comptime);27256 assert(!parent_block.is_comptime);
26982 const ok = try parent_block.addBinOp(.cmp_eq, active_tag, wanted_tag);27257 const ok = try parent_block.addBinOp(.cmp_eq, active_tag, wanted_tag);
26983 if (!sema.mod.comp.formatted_panics) {27258 if (!sema.pt.zcu.comp.formatted_panics) {
26984 return sema.addSafetyCheck(parent_block, src, ok, .inactive_union_field);27259 return sema.addSafetyCheck(parent_block, src, ok, .inactive_union_field);
26985 }27260 }
26986 try sema.safetyCheckFormatted(parent_block, src, ok, "panicInactiveUnionField", &.{ active_tag, wanted_tag });27261 try sema.safetyCheckFormatted(parent_block, src, ok, "panicInactiveUnionField", &.{ active_tag, wanted_tag });
...@@ -26996,7 +27271,8 @@ fn panicSentinelMismatch(...@@ -26996,7 +27271,8 @@ fn panicSentinelMismatch(
26996 sentinel_index: Air.Inst.Ref,27271 sentinel_index: Air.Inst.Ref,
26997) !void {27272) !void {
26998 assert(!parent_block.is_comptime);27273 assert(!parent_block.is_comptime);
26999 const mod = sema.mod;27274 const pt = sema.pt;
27275 const mod = pt.zcu;
27000 const expected_sentinel_val = maybe_sentinel orelse return;27276 const expected_sentinel_val = maybe_sentinel orelse return;
27001 const expected_sentinel = Air.internedToRef(expected_sentinel_val.toIntern());27277 const expected_sentinel = Air.internedToRef(expected_sentinel_val.toIntern());
2700227278
...@@ -27004,7 +27280,7 @@ fn panicSentinelMismatch(...@@ -27004,7 +27280,7 @@ fn panicSentinelMismatch(
27004 const actual_sentinel = if (ptr_ty.isSlice(mod))27280 const actual_sentinel = if (ptr_ty.isSlice(mod))
27005 try parent_block.addBinOp(.slice_elem_val, ptr, sentinel_index)27281 try parent_block.addBinOp(.slice_elem_val, ptr, sentinel_index)
27006 else blk: {27282 else blk: {
27007 const elem_ptr_ty = try ptr_ty.elemPtrType(null, mod);27283 const elem_ptr_ty = try ptr_ty.elemPtrType(null, pt);
27008 const sentinel_ptr = try parent_block.addPtrElemPtr(ptr, sentinel_index, elem_ptr_ty);27284 const sentinel_ptr = try parent_block.addPtrElemPtr(ptr, sentinel_index, elem_ptr_ty);
27009 break :blk try parent_block.addTyOp(.load, sentinel_ty, sentinel_ptr);27285 break :blk try parent_block.addTyOp(.load, sentinel_ty, sentinel_ptr);
27010 };27286 };
...@@ -27022,13 +27298,13 @@ fn panicSentinelMismatch(...@@ -27022,13 +27298,13 @@ fn panicSentinelMismatch(
27022 } else if (sentinel_ty.isSelfComparable(mod, true))27298 } else if (sentinel_ty.isSelfComparable(mod, true))
27023 try parent_block.addBinOp(.cmp_eq, expected_sentinel, actual_sentinel)27299 try parent_block.addBinOp(.cmp_eq, expected_sentinel, actual_sentinel)
27024 else {27300 else {
27025 const panic_fn = try mod.getBuiltin("checkNonScalarSentinel");27301 const panic_fn = try pt.getBuiltin("checkNonScalarSentinel");
27026 const args: [2]Air.Inst.Ref = .{ expected_sentinel, actual_sentinel };27302 const args: [2]Air.Inst.Ref = .{ expected_sentinel, actual_sentinel };
27027 try sema.callBuiltin(parent_block, src, panic_fn, .auto, &args, .@"safety check");27303 try sema.callBuiltin(parent_block, src, panic_fn, .auto, &args, .@"safety check");
27028 return;27304 return;
27029 };27305 };
2703027306
27031 if (!sema.mod.comp.formatted_panics) {27307 if (!pt.zcu.comp.formatted_panics) {
27032 return sema.addSafetyCheck(parent_block, src, ok, .sentinel_mismatch);27308 return sema.addSafetyCheck(parent_block, src, ok, .sentinel_mismatch);
27033 }27309 }
27034 try sema.safetyCheckFormatted(parent_block, src, ok, "panicSentinelMismatch", &.{ expected_sentinel, actual_sentinel });27310 try sema.safetyCheckFormatted(parent_block, src, ok, "panicSentinelMismatch", &.{ expected_sentinel, actual_sentinel });
...@@ -27042,7 +27318,9 @@ fn safetyCheckFormatted(...@@ -27042,7 +27318,9 @@ fn safetyCheckFormatted(
27042 func: []const u8,27318 func: []const u8,
27043 args: []const Air.Inst.Ref,27319 args: []const Air.Inst.Ref,
27044) CompileError!void {27320) CompileError!void {
27045 assert(sema.mod.comp.formatted_panics);27321 const pt = sema.pt;
27322 const zcu = pt.zcu;
27323 assert(zcu.comp.formatted_panics);
27046 const gpa = sema.gpa;27324 const gpa = sema.gpa;
2704727325
27048 var fail_block: Block = .{27326 var fail_block: Block = .{
...@@ -27058,10 +27336,10 @@ fn safetyCheckFormatted(...@@ -27058,10 +27336,10 @@ fn safetyCheckFormatted(
2705827336
27059 defer fail_block.instructions.deinit(gpa);27337 defer fail_block.instructions.deinit(gpa);
2706027338
27061 if (!sema.mod.backendSupportsFeature(.safety_check_formatted)) {27339 if (!zcu.backendSupportsFeature(.safety_check_formatted)) {
27062 _ = try fail_block.addNoOp(.trap);27340 _ = try fail_block.addNoOp(.trap);
27063 } else {27341 } else {
27064 const panic_fn = try sema.mod.getBuiltin(func);27342 const panic_fn = try pt.getBuiltin(func);
27065 try sema.callBuiltin(&fail_block, src, panic_fn, .auto, args, .@"safety check");27343 try sema.callBuiltin(&fail_block, src, panic_fn, .auto, args, .@"safety check");
27066 }27344 }
27067 try sema.addSafetyCheckExtra(parent_block, ok, &fail_block);27345 try sema.addSafetyCheckExtra(parent_block, ok, &fail_block);
...@@ -27102,7 +27380,8 @@ fn fieldVal(...@@ -27102,7 +27380,8 @@ fn fieldVal(
27102 // When editing this function, note that there is corresponding logic to be edited27380 // When editing this function, note that there is corresponding logic to be edited
27103 // in `fieldPtr`. This function takes a value and returns a value.27381 // in `fieldPtr`. This function takes a value and returns a value.
2710427382
27105 const mod = sema.mod;27383 const pt = sema.pt;
27384 const mod = pt.zcu;
27106 const ip = &mod.intern_pool;27385 const ip = &mod.intern_pool;
27107 const object_src = src; // TODO better source location27386 const object_src = src; // TODO better source location
27108 const object_ty = sema.typeOf(object);27387 const object_ty = sema.typeOf(object);
...@@ -27120,10 +27399,10 @@ fn fieldVal(...@@ -27120,10 +27399,10 @@ fn fieldVal(
27120 switch (inner_ty.zigTypeTag(mod)) {27399 switch (inner_ty.zigTypeTag(mod)) {
27121 .Array => {27400 .Array => {
27122 if (field_name.eqlSlice("len", ip)) {27401 if (field_name.eqlSlice("len", ip)) {
27123 return Air.internedToRef((try mod.intValue(Type.usize, inner_ty.arrayLen(mod))).toIntern());27402 return Air.internedToRef((try pt.intValue(Type.usize, inner_ty.arrayLen(mod))).toIntern());
27124 } else if (field_name.eqlSlice("ptr", ip) and is_pointer_to) {27403 } else if (field_name.eqlSlice("ptr", ip) and is_pointer_to) {
27125 const ptr_info = object_ty.ptrInfo(mod);27404 const ptr_info = object_ty.ptrInfo(mod);
27126 const result_ty = try mod.ptrTypeSema(.{27405 const result_ty = try pt.ptrTypeSema(.{
27127 .child = Type.fromInterned(ptr_info.child).childType(mod).toIntern(),27406 .child = Type.fromInterned(ptr_info.child).childType(mod).toIntern(),
27128 .sentinel = if (inner_ty.sentinel(mod)) |s| s.toIntern() else .none,27407 .sentinel = if (inner_ty.sentinel(mod)) |s| s.toIntern() else .none,
27129 .flags = .{27408 .flags = .{
...@@ -27143,7 +27422,7 @@ fn fieldVal(...@@ -27143,7 +27422,7 @@ fn fieldVal(
27143 block,27422 block,
27144 field_name_src,27423 field_name_src,
27145 "no member named '{}' in '{}'",27424 "no member named '{}' in '{}'",
27146 .{ field_name.fmt(ip), object_ty.fmt(mod) },27425 .{ field_name.fmt(ip), object_ty.fmt(pt) },
27147 );27426 );
27148 }27427 }
27149 },27428 },
...@@ -27167,7 +27446,7 @@ fn fieldVal(...@@ -27167,7 +27446,7 @@ fn fieldVal(
27167 block,27446 block,
27168 field_name_src,27447 field_name_src,
27169 "no member named '{}' in '{}'",27448 "no member named '{}' in '{}'",
27170 .{ field_name.fmt(ip), object_ty.fmt(mod) },27449 .{ field_name.fmt(ip), object_ty.fmt(pt) },
27171 );27450 );
27172 }27451 }
27173 }27452 }
...@@ -27194,7 +27473,7 @@ fn fieldVal(...@@ -27194,7 +27473,7 @@ fn fieldVal(
27194 .error_set_type => |error_set_type| blk: {27473 .error_set_type => |error_set_type| blk: {
27195 if (error_set_type.nameIndex(ip, field_name) != null) break :blk;27474 if (error_set_type.nameIndex(ip, field_name) != null) break :blk;
27196 return sema.fail(block, src, "no error named '{}' in '{}'", .{27475 return sema.fail(block, src, "no error named '{}' in '{}'", .{
27197 field_name.fmt(ip), child_type.fmt(mod),27476 field_name.fmt(ip), child_type.fmt(pt),
27198 });27477 });
27199 },27478 },
27200 .inferred_error_set_type => {27479 .inferred_error_set_type => {
...@@ -27210,8 +27489,8 @@ fn fieldVal(...@@ -27210,8 +27489,8 @@ fn fieldVal(
27210 const error_set_type = if (!child_type.isAnyError(mod))27489 const error_set_type = if (!child_type.isAnyError(mod))
27211 child_type27490 child_type
27212 else27491 else
27213 try mod.singleErrorSetType(field_name);27492 try pt.singleErrorSetType(field_name);
27214 return Air.internedToRef((try mod.intern(.{ .err = .{27493 return Air.internedToRef((try pt.intern(.{ .err = .{
27215 .ty = error_set_type.toIntern(),27494 .ty = error_set_type.toIntern(),
27216 .name = field_name,27495 .name = field_name,
27217 } })));27496 } })));
...@@ -27220,11 +27499,11 @@ fn fieldVal(...@@ -27220,11 +27499,11 @@ fn fieldVal(
27220 if (try sema.namespaceLookupVal(block, src, child_type.getNamespaceIndex(mod), field_name)) |inst| {27499 if (try sema.namespaceLookupVal(block, src, child_type.getNamespaceIndex(mod), field_name)) |inst| {
27221 return inst;27500 return inst;
27222 }27501 }
27223 try child_type.resolveFields(mod);27502 try child_type.resolveFields(pt);
27224 if (child_type.unionTagType(mod)) |enum_ty| {27503 if (child_type.unionTagType(mod)) |enum_ty| {
27225 if (enum_ty.enumFieldIndex(field_name, mod)) |field_index_usize| {27504 if (enum_ty.enumFieldIndex(field_name, mod)) |field_index_usize| {
27226 const field_index: u32 = @intCast(field_index_usize);27505 const field_index: u32 = @intCast(field_index_usize);
27227 return Air.internedToRef((try mod.enumValueFieldIndex(enum_ty, field_index)).toIntern());27506 return Air.internedToRef((try pt.enumValueFieldIndex(enum_ty, field_index)).toIntern());
27228 }27507 }
27229 }27508 }
27230 return sema.failWithBadMemberAccess(block, child_type, field_name_src, field_name);27509 return sema.failWithBadMemberAccess(block, child_type, field_name_src, field_name);
...@@ -27236,7 +27515,7 @@ fn fieldVal(...@@ -27236,7 +27515,7 @@ fn fieldVal(
27236 const field_index_usize = child_type.enumFieldIndex(field_name, mod) orelse27515 const field_index_usize = child_type.enumFieldIndex(field_name, mod) orelse
27237 return sema.failWithBadMemberAccess(block, child_type, field_name_src, field_name);27516 return sema.failWithBadMemberAccess(block, child_type, field_name_src, field_name);
27238 const field_index: u32 = @intCast(field_index_usize);27517 const field_index: u32 = @intCast(field_index_usize);
27239 const enum_val = try mod.enumValueFieldIndex(child_type, field_index);27518 const enum_val = try pt.enumValueFieldIndex(child_type, field_index);
27240 return Air.internedToRef(enum_val.toIntern());27519 return Air.internedToRef(enum_val.toIntern());
27241 },27520 },
27242 .Struct, .Opaque => {27521 .Struct, .Opaque => {
...@@ -27247,7 +27526,7 @@ fn fieldVal(...@@ -27247,7 +27526,7 @@ fn fieldVal(
27247 },27526 },
27248 else => {27527 else => {
27249 const msg = msg: {27528 const msg = msg: {
27250 const msg = try sema.errMsg(src, "type '{}' has no members", .{child_type.fmt(mod)});27529 const msg = try sema.errMsg(src, "type '{}' has no members", .{child_type.fmt(pt)});
27251 errdefer msg.destroy(sema.gpa);27530 errdefer msg.destroy(sema.gpa);
27252 if (child_type.isSlice(mod)) try sema.errNote(src, msg, "slice values have 'len' and 'ptr' members", .{});27531 if (child_type.isSlice(mod)) try sema.errNote(src, msg, "slice values have 'len' and 'ptr' members", .{});
27253 if (child_type.zigTypeTag(mod) == .Array) try sema.errNote(src, msg, "array values have 'len' member", .{});27532 if (child_type.zigTypeTag(mod) == .Array) try sema.errNote(src, msg, "array values have 'len' member", .{});
...@@ -27288,13 +27567,14 @@ fn fieldPtr(...@@ -27288,13 +27567,14 @@ fn fieldPtr(
27288 // When editing this function, note that there is corresponding logic to be edited27567 // When editing this function, note that there is corresponding logic to be edited
27289 // in `fieldVal`. This function takes a pointer and returns a pointer.27568 // in `fieldVal`. This function takes a pointer and returns a pointer.
2729027569
27291 const mod = sema.mod;27570 const pt = sema.pt;
27571 const mod = pt.zcu;
27292 const ip = &mod.intern_pool;27572 const ip = &mod.intern_pool;
27293 const object_ptr_src = src; // TODO better source location27573 const object_ptr_src = src; // TODO better source location
27294 const object_ptr_ty = sema.typeOf(object_ptr);27574 const object_ptr_ty = sema.typeOf(object_ptr);
27295 const object_ty = switch (object_ptr_ty.zigTypeTag(mod)) {27575 const object_ty = switch (object_ptr_ty.zigTypeTag(mod)) {
27296 .Pointer => object_ptr_ty.childType(mod),27576 .Pointer => object_ptr_ty.childType(mod),
27297 else => return sema.fail(block, object_ptr_src, "expected pointer, found '{}'", .{object_ptr_ty.fmt(mod)}),27577 else => return sema.fail(block, object_ptr_src, "expected pointer, found '{}'", .{object_ptr_ty.fmt(pt)}),
27298 };27578 };
2729927579
27300 // Zig allows dereferencing a single pointer during field lookup. Note that27580 // Zig allows dereferencing a single pointer during field lookup. Note that
...@@ -27310,11 +27590,11 @@ fn fieldPtr(...@@ -27310,11 +27590,11 @@ fn fieldPtr(
27310 switch (inner_ty.zigTypeTag(mod)) {27590 switch (inner_ty.zigTypeTag(mod)) {
27311 .Array => {27591 .Array => {
27312 if (field_name.eqlSlice("len", ip)) {27592 if (field_name.eqlSlice("len", ip)) {
27313 const int_val = try mod.intValue(Type.usize, inner_ty.arrayLen(mod));27593 const int_val = try pt.intValue(Type.usize, inner_ty.arrayLen(mod));
27314 return anonDeclRef(sema, int_val.toIntern());27594 return anonDeclRef(sema, int_val.toIntern());
27315 } else if (field_name.eqlSlice("ptr", ip) and is_pointer_to) {27595 } else if (field_name.eqlSlice("ptr", ip) and is_pointer_to) {
27316 const ptr_info = object_ty.ptrInfo(mod);27596 const ptr_info = object_ty.ptrInfo(mod);
27317 const new_ptr_ty = try mod.ptrTypeSema(.{27597 const new_ptr_ty = try pt.ptrTypeSema(.{
27318 .child = Type.fromInterned(ptr_info.child).childType(mod).toIntern(),27598 .child = Type.fromInterned(ptr_info.child).childType(mod).toIntern(),
27319 .sentinel = if (object_ty.sentinel(mod)) |s| s.toIntern() else .none,27599 .sentinel = if (object_ty.sentinel(mod)) |s| s.toIntern() else .none,
27320 .flags = .{27600 .flags = .{
...@@ -27329,7 +27609,7 @@ fn fieldPtr(...@@ -27329,7 +27609,7 @@ fn fieldPtr(
27329 .packed_offset = ptr_info.packed_offset,27609 .packed_offset = ptr_info.packed_offset,
27330 });27610 });
27331 const ptr_ptr_info = object_ptr_ty.ptrInfo(mod);27611 const ptr_ptr_info = object_ptr_ty.ptrInfo(mod);
27332 const result_ty = try mod.ptrTypeSema(.{27612 const result_ty = try pt.ptrTypeSema(.{
27333 .child = new_ptr_ty.toIntern(),27613 .child = new_ptr_ty.toIntern(),
27334 .sentinel = if (object_ptr_ty.sentinel(mod)) |s| s.toIntern() else .none,27614 .sentinel = if (object_ptr_ty.sentinel(mod)) |s| s.toIntern() else .none,
27335 .flags = .{27615 .flags = .{
...@@ -27348,7 +27628,7 @@ fn fieldPtr(...@@ -27348,7 +27628,7 @@ fn fieldPtr(
27348 block,27628 block,
27349 field_name_src,27629 field_name_src,
27350 "no member named '{}' in '{}'",27630 "no member named '{}' in '{}'",
27351 .{ field_name.fmt(ip), object_ty.fmt(mod) },27631 .{ field_name.fmt(ip), object_ty.fmt(pt) },
27352 );27632 );
27353 }27633 }
27354 },27634 },
...@@ -27363,7 +27643,7 @@ fn fieldPtr(...@@ -27363,7 +27643,7 @@ fn fieldPtr(
27363 if (field_name.eqlSlice("ptr", ip)) {27643 if (field_name.eqlSlice("ptr", ip)) {
27364 const slice_ptr_ty = inner_ty.slicePtrFieldType(mod);27644 const slice_ptr_ty = inner_ty.slicePtrFieldType(mod);
2736527645
27366 const result_ty = try mod.ptrTypeSema(.{27646 const result_ty = try pt.ptrTypeSema(.{
27367 .child = slice_ptr_ty.toIntern(),27647 .child = slice_ptr_ty.toIntern(),
27368 .flags = .{27648 .flags = .{
27369 .is_const = !attr_ptr_ty.ptrIsMutable(mod),27649 .is_const = !attr_ptr_ty.ptrIsMutable(mod),
...@@ -27373,7 +27653,7 @@ fn fieldPtr(...@@ -27373,7 +27653,7 @@ fn fieldPtr(
27373 });27653 });
2737427654
27375 if (try sema.resolveDefinedValue(block, object_ptr_src, inner_ptr)) |val| {27655 if (try sema.resolveDefinedValue(block, object_ptr_src, inner_ptr)) |val| {
27376 return Air.internedToRef((try val.ptrField(Value.slice_ptr_index, mod)).toIntern());27656 return Air.internedToRef((try val.ptrField(Value.slice_ptr_index, pt)).toIntern());
27377 }27657 }
27378 try sema.requireRuntimeBlock(block, src, null);27658 try sema.requireRuntimeBlock(block, src, null);
2737927659
...@@ -27381,7 +27661,7 @@ fn fieldPtr(...@@ -27381,7 +27661,7 @@ fn fieldPtr(
27381 try sema.checkKnownAllocPtr(block, inner_ptr, field_ptr);27661 try sema.checkKnownAllocPtr(block, inner_ptr, field_ptr);
27382 return field_ptr;27662 return field_ptr;
27383 } else if (field_name.eqlSlice("len", ip)) {27663 } else if (field_name.eqlSlice("len", ip)) {
27384 const result_ty = try mod.ptrTypeSema(.{27664 const result_ty = try pt.ptrTypeSema(.{
27385 .child = .usize_type,27665 .child = .usize_type,
27386 .flags = .{27666 .flags = .{
27387 .is_const = !attr_ptr_ty.ptrIsMutable(mod),27667 .is_const = !attr_ptr_ty.ptrIsMutable(mod),
...@@ -27391,7 +27671,7 @@ fn fieldPtr(...@@ -27391,7 +27671,7 @@ fn fieldPtr(
27391 });27671 });
2739227672
27393 if (try sema.resolveDefinedValue(block, object_ptr_src, inner_ptr)) |val| {27673 if (try sema.resolveDefinedValue(block, object_ptr_src, inner_ptr)) |val| {
27394 return Air.internedToRef((try val.ptrField(Value.slice_len_index, mod)).toIntern());27674 return Air.internedToRef((try val.ptrField(Value.slice_len_index, pt)).toIntern());
27395 }27675 }
27396 try sema.requireRuntimeBlock(block, src, null);27676 try sema.requireRuntimeBlock(block, src, null);
2739727677
...@@ -27403,7 +27683,7 @@ fn fieldPtr(...@@ -27403,7 +27683,7 @@ fn fieldPtr(
27403 block,27683 block,
27404 field_name_src,27684 field_name_src,
27405 "no member named '{}' in '{}'",27685 "no member named '{}' in '{}'",
27406 .{ field_name.fmt(ip), object_ty.fmt(mod) },27686 .{ field_name.fmt(ip), object_ty.fmt(pt) },
27407 );27687 );
27408 }27688 }
27409 },27689 },
...@@ -27433,7 +27713,7 @@ fn fieldPtr(...@@ -27433,7 +27713,7 @@ fn fieldPtr(
27433 break :blk;27713 break :blk;
27434 }27714 }
27435 return sema.fail(block, src, "no error named '{}' in '{}'", .{27715 return sema.fail(block, src, "no error named '{}' in '{}'", .{
27436 field_name.fmt(ip), child_type.fmt(mod),27716 field_name.fmt(ip), child_type.fmt(pt),
27437 });27717 });
27438 },27718 },
27439 .inferred_error_set_type => {27719 .inferred_error_set_type => {
...@@ -27449,8 +27729,8 @@ fn fieldPtr(...@@ -27449,8 +27729,8 @@ fn fieldPtr(
27449 const error_set_type = if (!child_type.isAnyError(mod))27729 const error_set_type = if (!child_type.isAnyError(mod))
27450 child_type27730 child_type
27451 else27731 else
27452 try mod.singleErrorSetType(field_name);27732 try pt.singleErrorSetType(field_name);
27453 return anonDeclRef(sema, try mod.intern(.{ .err = .{27733 return anonDeclRef(sema, try pt.intern(.{ .err = .{
27454 .ty = error_set_type.toIntern(),27734 .ty = error_set_type.toIntern(),
27455 .name = field_name,27735 .name = field_name,
27456 } }));27736 } }));
...@@ -27459,11 +27739,11 @@ fn fieldPtr(...@@ -27459,11 +27739,11 @@ fn fieldPtr(
27459 if (try sema.namespaceLookupRef(block, src, child_type.getNamespaceIndex(mod), field_name)) |inst| {27739 if (try sema.namespaceLookupRef(block, src, child_type.getNamespaceIndex(mod), field_name)) |inst| {
27460 return inst;27740 return inst;
27461 }27741 }
27462 try child_type.resolveFields(mod);27742 try child_type.resolveFields(pt);
27463 if (child_type.unionTagType(mod)) |enum_ty| {27743 if (child_type.unionTagType(mod)) |enum_ty| {
27464 if (enum_ty.enumFieldIndex(field_name, mod)) |field_index| {27744 if (enum_ty.enumFieldIndex(field_name, mod)) |field_index| {
27465 const field_index_u32: u32 = @intCast(field_index);27745 const field_index_u32: u32 = @intCast(field_index);
27466 const idx_val = try mod.enumValueFieldIndex(enum_ty, field_index_u32);27746 const idx_val = try pt.enumValueFieldIndex(enum_ty, field_index_u32);
27467 return anonDeclRef(sema, idx_val.toIntern());27747 return anonDeclRef(sema, idx_val.toIntern());
27468 }27748 }
27469 }27749 }
...@@ -27477,7 +27757,7 @@ fn fieldPtr(...@@ -27477,7 +27757,7 @@ fn fieldPtr(
27477 return sema.failWithBadMemberAccess(block, child_type, field_name_src, field_name);27757 return sema.failWithBadMemberAccess(block, child_type, field_name_src, field_name);
27478 };27758 };
27479 const field_index_u32: u32 = @intCast(field_index);27759 const field_index_u32: u32 = @intCast(field_index);
27480 const idx_val = try mod.enumValueFieldIndex(child_type, field_index_u32);27760 const idx_val = try pt.enumValueFieldIndex(child_type, field_index_u32);
27481 return anonDeclRef(sema, idx_val.toIntern());27761 return anonDeclRef(sema, idx_val.toIntern());
27482 },27762 },
27483 .Struct, .Opaque => {27763 .Struct, .Opaque => {
...@@ -27486,7 +27766,7 @@ fn fieldPtr(...@@ -27486,7 +27766,7 @@ fn fieldPtr(
27486 }27766 }
27487 return sema.failWithBadMemberAccess(block, child_type, field_name_src, field_name);27767 return sema.failWithBadMemberAccess(block, child_type, field_name_src, field_name);
27488 },27768 },
27489 else => return sema.fail(block, src, "type '{}' has no members", .{child_type.fmt(mod)}),27769 else => return sema.fail(block, src, "type '{}' has no members", .{child_type.fmt(pt)}),
27490 }27770 }
27491 },27771 },
27492 .Struct => {27772 .Struct => {
...@@ -27533,14 +27813,15 @@ fn fieldCallBind(...@@ -27533,14 +27813,15 @@ fn fieldCallBind(
27533 // When editing this function, note that there is corresponding logic to be edited27813 // When editing this function, note that there is corresponding logic to be edited
27534 // in `fieldVal`. This function takes a pointer and returns a pointer.27814 // in `fieldVal`. This function takes a pointer and returns a pointer.
2753527815
27536 const mod = sema.mod;27816 const pt = sema.pt;
27817 const mod = pt.zcu;
27537 const ip = &mod.intern_pool;27818 const ip = &mod.intern_pool;
27538 const raw_ptr_src = src; // TODO better source location27819 const raw_ptr_src = src; // TODO better source location
27539 const raw_ptr_ty = sema.typeOf(raw_ptr);27820 const raw_ptr_ty = sema.typeOf(raw_ptr);
27540 const inner_ty = if (raw_ptr_ty.zigTypeTag(mod) == .Pointer and (raw_ptr_ty.ptrSize(mod) == .One or raw_ptr_ty.ptrSize(mod) == .C))27821 const inner_ty = if (raw_ptr_ty.zigTypeTag(mod) == .Pointer and (raw_ptr_ty.ptrSize(mod) == .One or raw_ptr_ty.ptrSize(mod) == .C))
27541 raw_ptr_ty.childType(mod)27822 raw_ptr_ty.childType(mod)
27542 else27823 else
27543 return sema.fail(block, raw_ptr_src, "expected single pointer, found '{}'", .{raw_ptr_ty.fmt(mod)});27824 return sema.fail(block, raw_ptr_src, "expected single pointer, found '{}'", .{raw_ptr_ty.fmt(pt)});
2754427825
27545 // Optionally dereference a second pointer to get the concrete type.27826 // Optionally dereference a second pointer to get the concrete type.
27546 const is_double_ptr = inner_ty.zigTypeTag(mod) == .Pointer and inner_ty.ptrSize(mod) == .One;27827 const is_double_ptr = inner_ty.zigTypeTag(mod) == .Pointer and inner_ty.ptrSize(mod) == .One;
...@@ -27554,7 +27835,7 @@ fn fieldCallBind(...@@ -27554,7 +27835,7 @@ fn fieldCallBind(
27554 find_field: {27835 find_field: {
27555 switch (concrete_ty.zigTypeTag(mod)) {27836 switch (concrete_ty.zigTypeTag(mod)) {
27556 .Struct => {27837 .Struct => {
27557 try concrete_ty.resolveFields(mod);27838 try concrete_ty.resolveFields(pt);
27558 if (mod.typeToStruct(concrete_ty)) |struct_type| {27839 if (mod.typeToStruct(concrete_ty)) |struct_type| {
27559 const field_index = struct_type.nameIndex(ip, field_name) orelse27840 const field_index = struct_type.nameIndex(ip, field_name) orelse
27560 break :find_field;27841 break :find_field;
...@@ -27563,7 +27844,7 @@ fn fieldCallBind(...@@ -27563,7 +27844,7 @@ fn fieldCallBind(
27563 return sema.finishFieldCallBind(block, src, ptr_ty, field_ty, field_index, object_ptr);27844 return sema.finishFieldCallBind(block, src, ptr_ty, field_ty, field_index, object_ptr);
27564 } else if (concrete_ty.isTuple(mod)) {27845 } else if (concrete_ty.isTuple(mod)) {
27565 if (field_name.eqlSlice("len", ip)) {27846 if (field_name.eqlSlice("len", ip)) {
27566 return .{ .direct = try mod.intRef(Type.usize, concrete_ty.structFieldCount(mod)) };27847 return .{ .direct = try pt.intRef(Type.usize, concrete_ty.structFieldCount(mod)) };
27567 }27848 }
27568 if (field_name.toUnsigned(ip)) |field_index| {27849 if (field_name.toUnsigned(ip)) |field_index| {
27569 if (field_index >= concrete_ty.structFieldCount(mod)) break :find_field;27850 if (field_index >= concrete_ty.structFieldCount(mod)) break :find_field;
...@@ -27580,7 +27861,7 @@ fn fieldCallBind(...@@ -27580,7 +27861,7 @@ fn fieldCallBind(
27580 }27861 }
27581 },27862 },
27582 .Union => {27863 .Union => {
27583 try concrete_ty.resolveFields(mod);27864 try concrete_ty.resolveFields(pt);
27584 const union_obj = mod.typeToUnion(concrete_ty).?;27865 const union_obj = mod.typeToUnion(concrete_ty).?;
27585 _ = union_obj.loadTagType(ip).nameIndex(ip, field_name) orelse break :find_field;27866 _ = union_obj.loadTagType(ip).nameIndex(ip, field_name) orelse break :find_field;
27586 const field_ptr = try unionFieldPtr(sema, block, src, object_ptr, field_name, field_name_src, concrete_ty, false);27867 const field_ptr = try unionFieldPtr(sema, block, src, object_ptr, field_name, field_name_src, concrete_ty, false);
...@@ -27661,7 +27942,7 @@ fn fieldCallBind(...@@ -27661,7 +27942,7 @@ fn fieldCallBind(
27661 const msg = msg: {27942 const msg = msg: {
27662 const msg = try sema.errMsg(src, "no field or member function named '{}' in '{}'", .{27943 const msg = try sema.errMsg(src, "no field or member function named '{}' in '{}'", .{
27663 field_name.fmt(ip),27944 field_name.fmt(ip),
27664 concrete_ty.fmt(mod),27945 concrete_ty.fmt(pt),
27665 });27946 });
27666 errdefer msg.destroy(sema.gpa);27947 errdefer msg.destroy(sema.gpa);
27667 try sema.addDeclaredHereNote(msg, concrete_ty);27948 try sema.addDeclaredHereNote(msg, concrete_ty);
...@@ -27689,8 +27970,9 @@ fn finishFieldCallBind(...@@ -27689,8 +27970,9 @@ fn finishFieldCallBind(
27689 field_index: u32,27970 field_index: u32,
27690 object_ptr: Air.Inst.Ref,27971 object_ptr: Air.Inst.Ref,
27691) CompileError!ResolvedFieldCallee {27972) CompileError!ResolvedFieldCallee {
27692 const mod = sema.mod;27973 const pt = sema.pt;
27693 const ptr_field_ty = try mod.ptrTypeSema(.{27974 const mod = pt.zcu;
27975 const ptr_field_ty = try pt.ptrTypeSema(.{
27694 .child = field_ty.toIntern(),27976 .child = field_ty.toIntern(),
27695 .flags = .{27977 .flags = .{
27696 .is_const = !ptr_ty.ptrIsMutable(mod),27978 .is_const = !ptr_ty.ptrIsMutable(mod),
...@@ -27701,14 +27983,14 @@ fn finishFieldCallBind(...@@ -27701,14 +27983,14 @@ fn finishFieldCallBind(
27701 const container_ty = ptr_ty.childType(mod);27983 const container_ty = ptr_ty.childType(mod);
27702 if (container_ty.zigTypeTag(mod) == .Struct) {27984 if (container_ty.zigTypeTag(mod) == .Struct) {
27703 if (container_ty.structFieldIsComptime(field_index, mod)) {27985 if (container_ty.structFieldIsComptime(field_index, mod)) {
27704 try container_ty.resolveStructFieldInits(mod);27986 try container_ty.resolveStructFieldInits(pt);
27705 const default_val = (try container_ty.structFieldValueComptime(mod, field_index)).?;27987 const default_val = (try container_ty.structFieldValueComptime(pt, field_index)).?;
27706 return .{ .direct = Air.internedToRef(default_val.toIntern()) };27988 return .{ .direct = Air.internedToRef(default_val.toIntern()) };
27707 }27989 }
27708 }27990 }
2770927991
27710 if (try sema.resolveDefinedValue(block, src, object_ptr)) |struct_ptr_val| {27992 if (try sema.resolveDefinedValue(block, src, object_ptr)) |struct_ptr_val| {
27711 const ptr_val = try struct_ptr_val.ptrField(field_index, mod);27993 const ptr_val = try struct_ptr_val.ptrField(field_index, pt);
27712 const pointer = Air.internedToRef(ptr_val.toIntern());27994 const pointer = Air.internedToRef(ptr_val.toIntern());
27713 return .{ .direct = try sema.analyzeLoad(block, src, pointer, src) };27995 return .{ .direct = try sema.analyzeLoad(block, src, pointer, src) };
27714 }27996 }
...@@ -27725,7 +28007,8 @@ fn namespaceLookup(...@@ -27725,7 +28007,8 @@ fn namespaceLookup(
27725 opt_namespace: InternPool.OptionalNamespaceIndex,28007 opt_namespace: InternPool.OptionalNamespaceIndex,
27726 decl_name: InternPool.NullTerminatedString,28008 decl_name: InternPool.NullTerminatedString,
27727) CompileError!?InternPool.DeclIndex {28009) CompileError!?InternPool.DeclIndex {
27728 const mod = sema.mod;28010 const pt = sema.pt;
28011 const mod = pt.zcu;
27729 const gpa = sema.gpa;28012 const gpa = sema.gpa;
27730 if (try sema.lookupInNamespace(block, src, opt_namespace, decl_name, true)) |decl_index| {28013 if (try sema.lookupInNamespace(block, src, opt_namespace, decl_name, true)) |decl_index| {
27731 const decl = mod.declPtr(decl_index);28014 const decl = mod.declPtr(decl_index);
...@@ -27780,16 +28063,17 @@ fn structFieldPtr(...@@ -27780,16 +28063,17 @@ fn structFieldPtr(
27780 struct_ty: Type,28063 struct_ty: Type,
27781 initializing: bool,28064 initializing: bool,
27782) CompileError!Air.Inst.Ref {28065) CompileError!Air.Inst.Ref {
27783 const mod = sema.mod;28066 const pt = sema.pt;
28067 const mod = pt.zcu;
27784 const ip = &mod.intern_pool;28068 const ip = &mod.intern_pool;
27785 assert(struct_ty.zigTypeTag(mod) == .Struct);28069 assert(struct_ty.zigTypeTag(mod) == .Struct);
2778628070
27787 try struct_ty.resolveFields(mod);28071 try struct_ty.resolveFields(pt);
27788 try struct_ty.resolveLayout(mod);28072 try struct_ty.resolveLayout(pt);
2778928073
27790 if (struct_ty.isTuple(mod)) {28074 if (struct_ty.isTuple(mod)) {
27791 if (field_name.eqlSlice("len", ip)) {28075 if (field_name.eqlSlice("len", ip)) {
27792 const len_inst = try mod.intRef(Type.usize, struct_ty.structFieldCount(mod));28076 const len_inst = try pt.intRef(Type.usize, struct_ty.structFieldCount(mod));
27793 return sema.analyzeRef(block, src, len_inst);28077 return sema.analyzeRef(block, src, len_inst);
27794 }28078 }
27795 const field_index = try sema.tupleFieldIndex(block, struct_ty, field_name, field_name_src);28079 const field_index = try sema.tupleFieldIndex(block, struct_ty, field_name, field_name_src);
...@@ -27817,14 +28101,15 @@ fn structFieldPtrByIndex(...@@ -27817,14 +28101,15 @@ fn structFieldPtrByIndex(
27817 struct_ty: Type,28101 struct_ty: Type,
27818 initializing: bool,28102 initializing: bool,
27819) CompileError!Air.Inst.Ref {28103) CompileError!Air.Inst.Ref {
27820 const mod = sema.mod;28104 const pt = sema.pt;
28105 const mod = pt.zcu;
27821 const ip = &mod.intern_pool;28106 const ip = &mod.intern_pool;
27822 if (struct_ty.isAnonStruct(mod)) {28107 if (struct_ty.isAnonStruct(mod)) {
27823 return sema.tupleFieldPtr(block, src, struct_ptr, field_src, field_index, initializing);28108 return sema.tupleFieldPtr(block, src, struct_ptr, field_src, field_index, initializing);
27824 }28109 }
2782528110
27826 if (try sema.resolveDefinedValue(block, src, struct_ptr)) |struct_ptr_val| {28111 if (try sema.resolveDefinedValue(block, src, struct_ptr)) |struct_ptr_val| {
27827 const val = try struct_ptr_val.ptrField(field_index, mod);28112 const val = try struct_ptr_val.ptrField(field_index, pt);
27828 return Air.internedToRef(val.toIntern());28113 return Air.internedToRef(val.toIntern());
27829 }28114 }
2783028115
...@@ -27848,7 +28133,7 @@ fn structFieldPtrByIndex(...@@ -27848,7 +28133,7 @@ fn structFieldPtrByIndex(
27848 try sema.typeAbiAlignment(Type.fromInterned(struct_ptr_ty_info.child));28133 try sema.typeAbiAlignment(Type.fromInterned(struct_ptr_ty_info.child));
2784928134
27850 if (struct_type.layout == .@"packed") {28135 if (struct_type.layout == .@"packed") {
27851 switch (struct_ty.packedStructFieldPtrInfo(struct_ptr_ty, field_index, mod)) {28136 switch (struct_ty.packedStructFieldPtrInfo(struct_ptr_ty, field_index, pt)) {
27852 .bit_ptr => |packed_offset| {28137 .bit_ptr => |packed_offset| {
27853 ptr_ty_data.flags.alignment = parent_align;28138 ptr_ty_data.flags.alignment = parent_align;
27854 ptr_ty_data.packed_offset = packed_offset;28139 ptr_ty_data.packed_offset = packed_offset;
...@@ -27861,14 +28146,14 @@ fn structFieldPtrByIndex(...@@ -27861,14 +28146,14 @@ fn structFieldPtrByIndex(
27861 // For extern structs, field alignment might be bigger than type's28146 // For extern structs, field alignment might be bigger than type's
27862 // natural alignment. Eg, in `extern struct { x: u32, y: u16 }` the28147 // natural alignment. Eg, in `extern struct { x: u32, y: u16 }` the
27863 // second field is aligned as u32.28148 // second field is aligned as u32.
27864 const field_offset = struct_ty.structFieldOffset(field_index, mod);28149 const field_offset = struct_ty.structFieldOffset(field_index, pt);
27865 ptr_ty_data.flags.alignment = if (parent_align == .none)28150 ptr_ty_data.flags.alignment = if (parent_align == .none)
27866 .none28151 .none
27867 else28152 else
27868 @enumFromInt(@min(@intFromEnum(parent_align), @ctz(field_offset)));28153 @enumFromInt(@min(@intFromEnum(parent_align), @ctz(field_offset)));
27869 } else {28154 } else {
27870 // Our alignment is capped at the field alignment.28155 // Our alignment is capped at the field alignment.
27871 const field_align = try mod.structFieldAlignmentAdvanced(28156 const field_align = try pt.structFieldAlignmentAdvanced(
27872 struct_type.fieldAlign(ip, field_index),28157 struct_type.fieldAlign(ip, field_index),
27873 Type.fromInterned(field_ty),28158 Type.fromInterned(field_ty),
27874 struct_type.layout,28159 struct_type.layout,
...@@ -27880,11 +28165,11 @@ fn structFieldPtrByIndex(...@@ -27880,11 +28165,11 @@ fn structFieldPtrByIndex(
27880 field_align.min(parent_align);28165 field_align.min(parent_align);
27881 }28166 }
2788228167
27883 const ptr_field_ty = try mod.ptrTypeSema(ptr_ty_data);28168 const ptr_field_ty = try pt.ptrTypeSema(ptr_ty_data);
2788428169
27885 if (struct_type.fieldIsComptime(ip, field_index)) {28170 if (struct_type.fieldIsComptime(ip, field_index)) {
27886 try struct_ty.resolveStructFieldInits(mod);28171 try struct_ty.resolveStructFieldInits(pt);
27887 const val = try mod.intern(.{ .ptr = .{28172 const val = try pt.intern(.{ .ptr = .{
27888 .ty = ptr_field_ty.toIntern(),28173 .ty = ptr_field_ty.toIntern(),
27889 .base_addr = .{ .comptime_field = struct_type.field_inits.get(ip)[field_index] },28174 .base_addr = .{ .comptime_field = struct_type.field_inits.get(ip)[field_index] },
27890 .byte_offset = 0,28175 .byte_offset = 0,
...@@ -27905,11 +28190,12 @@ fn structFieldVal(...@@ -27905,11 +28190,12 @@ fn structFieldVal(
27905 field_name_src: LazySrcLoc,28190 field_name_src: LazySrcLoc,
27906 struct_ty: Type,28191 struct_ty: Type,
27907) CompileError!Air.Inst.Ref {28192) CompileError!Air.Inst.Ref {
27908 const mod = sema.mod;28193 const pt = sema.pt;
28194 const mod = pt.zcu;
27909 const ip = &mod.intern_pool;28195 const ip = &mod.intern_pool;
27910 assert(struct_ty.zigTypeTag(mod) == .Struct);28196 assert(struct_ty.zigTypeTag(mod) == .Struct);
2791128197
27912 try struct_ty.resolveFields(mod);28198 try struct_ty.resolveFields(pt);
2791328199
27914 switch (ip.indexToKey(struct_ty.toIntern())) {28200 switch (ip.indexToKey(struct_ty.toIntern())) {
27915 .struct_type => {28201 .struct_type => {
...@@ -27920,7 +28206,7 @@ fn structFieldVal(...@@ -27920,7 +28206,7 @@ fn structFieldVal(
27920 const field_index = struct_type.nameIndex(ip, field_name) orelse28206 const field_index = struct_type.nameIndex(ip, field_name) orelse
27921 return sema.failWithBadStructFieldAccess(block, struct_ty, struct_type, field_name_src, field_name);28207 return sema.failWithBadStructFieldAccess(block, struct_ty, struct_type, field_name_src, field_name);
27922 if (struct_type.fieldIsComptime(ip, field_index)) {28208 if (struct_type.fieldIsComptime(ip, field_index)) {
27923 try struct_ty.resolveStructFieldInits(mod);28209 try struct_ty.resolveStructFieldInits(pt);
27924 return Air.internedToRef(struct_type.field_inits.get(ip)[field_index]);28210 return Air.internedToRef(struct_type.field_inits.get(ip)[field_index]);
27925 }28211 }
2792628212
...@@ -27929,15 +28215,15 @@ fn structFieldVal(...@@ -27929,15 +28215,15 @@ fn structFieldVal(
27929 return Air.internedToRef(field_val.toIntern());28215 return Air.internedToRef(field_val.toIntern());
2793028216
27931 if (try sema.resolveValue(struct_byval)) |struct_val| {28217 if (try sema.resolveValue(struct_byval)) |struct_val| {
27932 if (struct_val.isUndef(mod)) return mod.undefRef(field_ty);28218 if (struct_val.isUndef(mod)) return pt.undefRef(field_ty);
27933 if ((try sema.typeHasOnePossibleValue(field_ty))) |opv| {28219 if ((try sema.typeHasOnePossibleValue(field_ty))) |opv| {
27934 return Air.internedToRef(opv.toIntern());28220 return Air.internedToRef(opv.toIntern());
27935 }28221 }
27936 return Air.internedToRef((try struct_val.fieldValue(mod, field_index)).toIntern());28222 return Air.internedToRef((try struct_val.fieldValue(pt, field_index)).toIntern());
27937 }28223 }
2793828224
27939 try sema.requireRuntimeBlock(block, src, null);28225 try sema.requireRuntimeBlock(block, src, null);
27940 try field_ty.resolveLayout(mod);28226 try field_ty.resolveLayout(pt);
27941 return block.addStructFieldVal(struct_byval, field_index, field_ty);28227 return block.addStructFieldVal(struct_byval, field_index, field_ty);
27942 },28228 },
27943 .anon_struct_type => |anon_struct| {28229 .anon_struct_type => |anon_struct| {
...@@ -27961,9 +28247,10 @@ fn tupleFieldVal(...@@ -27961,9 +28247,10 @@ fn tupleFieldVal(
27961 field_name_src: LazySrcLoc,28247 field_name_src: LazySrcLoc,
27962 tuple_ty: Type,28248 tuple_ty: Type,
27963) CompileError!Air.Inst.Ref {28249) CompileError!Air.Inst.Ref {
27964 const mod = sema.mod;28250 const pt = sema.pt;
28251 const mod = pt.zcu;
27965 if (field_name.eqlSlice("len", &mod.intern_pool)) {28252 if (field_name.eqlSlice("len", &mod.intern_pool)) {
27966 return mod.intRef(Type.usize, tuple_ty.structFieldCount(mod));28253 return pt.intRef(Type.usize, tuple_ty.structFieldCount(mod));
27967 }28254 }
27968 const field_index = try sema.tupleFieldIndex(block, tuple_ty, field_name, field_name_src);28255 const field_index = try sema.tupleFieldIndex(block, tuple_ty, field_name, field_name_src);
27969 return sema.tupleFieldValByIndex(block, src, tuple_byval, field_index, tuple_ty);28256 return sema.tupleFieldValByIndex(block, src, tuple_byval, field_index, tuple_ty);
...@@ -27977,18 +28264,18 @@ fn tupleFieldIndex(...@@ -27977,18 +28264,18 @@ fn tupleFieldIndex(
27977 field_name: InternPool.NullTerminatedString,28264 field_name: InternPool.NullTerminatedString,
27978 field_name_src: LazySrcLoc,28265 field_name_src: LazySrcLoc,
27979) CompileError!u32 {28266) CompileError!u32 {
27980 const mod = sema.mod;28267 const pt = sema.pt;
27981 const ip = &mod.intern_pool;28268 const ip = &pt.zcu.intern_pool;
27982 assert(!field_name.eqlSlice("len", ip));28269 assert(!field_name.eqlSlice("len", ip));
27983 if (field_name.toUnsigned(ip)) |field_index| {28270 if (field_name.toUnsigned(ip)) |field_index| {
27984 if (field_index < tuple_ty.structFieldCount(mod)) return field_index;28271 if (field_index < tuple_ty.structFieldCount(pt.zcu)) return field_index;
27985 return sema.fail(block, field_name_src, "index '{}' out of bounds of tuple '{}'", .{28272 return sema.fail(block, field_name_src, "index '{}' out of bounds of tuple '{}'", .{
27986 field_name.fmt(ip), tuple_ty.fmt(mod),28273 field_name.fmt(ip), tuple_ty.fmt(pt),
27987 });28274 });
27988 }28275 }
2798928276
27990 return sema.fail(block, field_name_src, "no field named '{}' in tuple '{}'", .{28277 return sema.fail(block, field_name_src, "no field named '{}' in tuple '{}'", .{
27991 field_name.fmt(ip), tuple_ty.fmt(mod),28278 field_name.fmt(ip), tuple_ty.fmt(pt),
27992 });28279 });
27993}28280}
2799428281
...@@ -28000,12 +28287,13 @@ fn tupleFieldValByIndex(...@@ -28000,12 +28287,13 @@ fn tupleFieldValByIndex(
28000 field_index: u32,28287 field_index: u32,
28001 tuple_ty: Type,28288 tuple_ty: Type,
28002) CompileError!Air.Inst.Ref {28289) CompileError!Air.Inst.Ref {
28003 const mod = sema.mod;28290 const pt = sema.pt;
28291 const mod = pt.zcu;
28004 const field_ty = tuple_ty.structFieldType(field_index, mod);28292 const field_ty = tuple_ty.structFieldType(field_index, mod);
2800528293
28006 if (tuple_ty.structFieldIsComptime(field_index, mod))28294 if (tuple_ty.structFieldIsComptime(field_index, mod))
28007 try tuple_ty.resolveStructFieldInits(mod);28295 try tuple_ty.resolveStructFieldInits(pt);
28008 if (try tuple_ty.structFieldValueComptime(mod, field_index)) |default_value| {28296 if (try tuple_ty.structFieldValueComptime(pt, field_index)) |default_value| {
28009 return Air.internedToRef(default_value.toIntern());28297 return Air.internedToRef(default_value.toIntern());
28010 }28298 }
2801128299
...@@ -28014,9 +28302,9 @@ fn tupleFieldValByIndex(...@@ -28014,9 +28302,9 @@ fn tupleFieldValByIndex(
28014 return Air.internedToRef(opv.toIntern());28302 return Air.internedToRef(opv.toIntern());
28015 }28303 }
28016 return switch (mod.intern_pool.indexToKey(tuple_val.toIntern())) {28304 return switch (mod.intern_pool.indexToKey(tuple_val.toIntern())) {
28017 .undef => mod.undefRef(field_ty),28305 .undef => pt.undefRef(field_ty),
28018 .aggregate => |aggregate| Air.internedToRef(switch (aggregate.storage) {28306 .aggregate => |aggregate| Air.internedToRef(switch (aggregate.storage) {
28019 .bytes => |bytes| try mod.intValue(Type.u8, bytes.at(field_index, &mod.intern_pool)),28307 .bytes => |bytes| try pt.intValue(Type.u8, bytes.at(field_index, &mod.intern_pool)),
28020 .elems => |elems| Value.fromInterned(elems[field_index]),28308 .elems => |elems| Value.fromInterned(elems[field_index]),
28021 .repeated_elem => |elem| Value.fromInterned(elem),28309 .repeated_elem => |elem| Value.fromInterned(elem),
28022 }.toIntern()),28310 }.toIntern()),
...@@ -28025,7 +28313,7 @@ fn tupleFieldValByIndex(...@@ -28025,7 +28313,7 @@ fn tupleFieldValByIndex(
28025 }28313 }
2802628314
28027 try sema.requireRuntimeBlock(block, src, null);28315 try sema.requireRuntimeBlock(block, src, null);
28028 try field_ty.resolveLayout(mod);28316 try field_ty.resolveLayout(pt);
28029 return block.addStructFieldVal(tuple_byval, field_index, field_ty);28317 return block.addStructFieldVal(tuple_byval, field_index, field_ty);
28030}28318}
2803128319
...@@ -28039,18 +28327,19 @@ fn unionFieldPtr(...@@ -28039,18 +28327,19 @@ fn unionFieldPtr(
28039 union_ty: Type,28327 union_ty: Type,
28040 initializing: bool,28328 initializing: bool,
28041) CompileError!Air.Inst.Ref {28329) CompileError!Air.Inst.Ref {
28042 const mod = sema.mod;28330 const pt = sema.pt;
28331 const mod = pt.zcu;
28043 const ip = &mod.intern_pool;28332 const ip = &mod.intern_pool;
2804428333
28045 assert(union_ty.zigTypeTag(mod) == .Union);28334 assert(union_ty.zigTypeTag(mod) == .Union);
2804628335
28047 const union_ptr_ty = sema.typeOf(union_ptr);28336 const union_ptr_ty = sema.typeOf(union_ptr);
28048 const union_ptr_info = union_ptr_ty.ptrInfo(mod);28337 const union_ptr_info = union_ptr_ty.ptrInfo(mod);
28049 try union_ty.resolveFields(mod);28338 try union_ty.resolveFields(pt);
28050 const union_obj = mod.typeToUnion(union_ty).?;28339 const union_obj = mod.typeToUnion(union_ty).?;
28051 const field_index = try sema.unionFieldIndex(block, union_ty, field_name, field_name_src);28340 const field_index = try sema.unionFieldIndex(block, union_ty, field_name, field_name_src);
28052 const field_ty = Type.fromInterned(union_obj.field_types.get(ip)[field_index]);28341 const field_ty = Type.fromInterned(union_obj.field_types.get(ip)[field_index]);
28053 const ptr_field_ty = try mod.ptrTypeSema(.{28342 const ptr_field_ty = try pt.ptrTypeSema(.{
28054 .child = field_ty.toIntern(),28343 .child = field_ty.toIntern(),
28055 .flags = .{28344 .flags = .{
28056 .is_const = union_ptr_info.flags.is_const,28345 .is_const = union_ptr_info.flags.is_const,
...@@ -28061,7 +28350,7 @@ fn unionFieldPtr(...@@ -28061,7 +28350,7 @@ fn unionFieldPtr(
28061 union_ptr_info.flags.alignment28350 union_ptr_info.flags.alignment
28062 else28351 else
28063 try sema.typeAbiAlignment(union_ty);28352 try sema.typeAbiAlignment(union_ty);
28064 const field_align = try mod.unionFieldNormalAlignmentAdvanced(union_obj, field_index, .sema);28353 const field_align = try pt.unionFieldNormalAlignmentAdvanced(union_obj, field_index, .sema);
28065 break :blk union_align.min(field_align);28354 break :blk union_align.min(field_align);
28066 } else union_ptr_info.flags.alignment,28355 } else union_ptr_info.flags.alignment,
28067 },28356 },
...@@ -28087,9 +28376,9 @@ fn unionFieldPtr(...@@ -28087,9 +28376,9 @@ fn unionFieldPtr(
28087 switch (union_obj.getLayout(ip)) {28376 switch (union_obj.getLayout(ip)) {
28088 .auto => if (initializing) {28377 .auto => if (initializing) {
28089 // Store to the union to initialize the tag.28378 // Store to the union to initialize the tag.
28090 const field_tag = try mod.enumValueFieldIndex(Type.fromInterned(union_obj.enum_tag_ty), enum_field_index);28379 const field_tag = try pt.enumValueFieldIndex(Type.fromInterned(union_obj.enum_tag_ty), enum_field_index);
28091 const payload_ty = Type.fromInterned(union_obj.field_types.get(ip)[field_index]);28380 const payload_ty = Type.fromInterned(union_obj.field_types.get(ip)[field_index]);
28092 const new_union_val = try mod.unionValue(union_ty, field_tag, try mod.undefValue(payload_ty));28381 const new_union_val = try pt.unionValue(union_ty, field_tag, try pt.undefValue(payload_ty));
28093 try sema.storePtrVal(block, src, union_ptr_val, new_union_val, union_ty);28382 try sema.storePtrVal(block, src, union_ptr_val, new_union_val, union_ty);
28094 } else {28383 } else {
28095 const union_val = (try sema.pointerDeref(block, src, union_ptr_val, union_ptr_ty)) orelse28384 const union_val = (try sema.pointerDeref(block, src, union_ptr_val, union_ptr_ty)) orelse
...@@ -28098,7 +28387,7 @@ fn unionFieldPtr(...@@ -28098,7 +28387,7 @@ fn unionFieldPtr(
28098 return sema.failWithUseOfUndef(block, src);28387 return sema.failWithUseOfUndef(block, src);
28099 }28388 }
28100 const un = ip.indexToKey(union_val.toIntern()).un;28389 const un = ip.indexToKey(union_val.toIntern()).un;
28101 const field_tag = try mod.enumValueFieldIndex(Type.fromInterned(union_obj.enum_tag_ty), enum_field_index);28390 const field_tag = try pt.enumValueFieldIndex(Type.fromInterned(union_obj.enum_tag_ty), enum_field_index);
28102 const tag_matches = un.tag == field_tag.toIntern();28391 const tag_matches = un.tag == field_tag.toIntern();
28103 if (!tag_matches) {28392 if (!tag_matches) {
28104 const msg = msg: {28393 const msg = msg: {
...@@ -28117,7 +28406,7 @@ fn unionFieldPtr(...@@ -28117,7 +28406,7 @@ fn unionFieldPtr(
28117 },28406 },
28118 .@"packed", .@"extern" => {},28407 .@"packed", .@"extern" => {},
28119 }28408 }
28120 const field_ptr_val = try union_ptr_val.ptrField(field_index, mod);28409 const field_ptr_val = try union_ptr_val.ptrField(field_index, pt);
28121 return Air.internedToRef(field_ptr_val.toIntern());28410 return Air.internedToRef(field_ptr_val.toIntern());
28122 }28411 }
2812328412
...@@ -28125,7 +28414,7 @@ fn unionFieldPtr(...@@ -28125,7 +28414,7 @@ fn unionFieldPtr(
28125 if (!initializing and union_obj.getLayout(ip) == .auto and block.wantSafety() and28414 if (!initializing and union_obj.getLayout(ip) == .auto and block.wantSafety() and
28126 union_ty.unionTagTypeSafety(mod) != null and union_obj.field_types.len > 1)28415 union_ty.unionTagTypeSafety(mod) != null and union_obj.field_types.len > 1)
28127 {28416 {
28128 const wanted_tag_val = try mod.enumValueFieldIndex(Type.fromInterned(union_obj.enum_tag_ty), enum_field_index);28417 const wanted_tag_val = try pt.enumValueFieldIndex(Type.fromInterned(union_obj.enum_tag_ty), enum_field_index);
28129 const wanted_tag = Air.internedToRef(wanted_tag_val.toIntern());28418 const wanted_tag = Air.internedToRef(wanted_tag_val.toIntern());
28130 // TODO would it be better if get_union_tag supported pointers to unions?28419 // TODO would it be better if get_union_tag supported pointers to unions?
28131 const union_val = try block.addTyOp(.load, union_ty, union_ptr);28420 const union_val = try block.addTyOp(.load, union_ty, union_ptr);
...@@ -28148,21 +28437,22 @@ fn unionFieldVal(...@@ -28148,21 +28437,22 @@ fn unionFieldVal(
28148 field_name_src: LazySrcLoc,28437 field_name_src: LazySrcLoc,
28149 union_ty: Type,28438 union_ty: Type,
28150) CompileError!Air.Inst.Ref {28439) CompileError!Air.Inst.Ref {
28151 const zcu = sema.mod;28440 const pt = sema.pt;
28441 const zcu = pt.zcu;
28152 const ip = &zcu.intern_pool;28442 const ip = &zcu.intern_pool;
28153 assert(union_ty.zigTypeTag(zcu) == .Union);28443 assert(union_ty.zigTypeTag(zcu) == .Union);
2815428444
28155 try union_ty.resolveFields(zcu);28445 try union_ty.resolveFields(pt);
28156 const union_obj = zcu.typeToUnion(union_ty).?;28446 const union_obj = zcu.typeToUnion(union_ty).?;
28157 const field_index = try sema.unionFieldIndex(block, union_ty, field_name, field_name_src);28447 const field_index = try sema.unionFieldIndex(block, union_ty, field_name, field_name_src);
28158 const field_ty = Type.fromInterned(union_obj.field_types.get(ip)[field_index]);28448 const field_ty = Type.fromInterned(union_obj.field_types.get(ip)[field_index]);
28159 const enum_field_index: u32 = @intCast(Type.fromInterned(union_obj.enum_tag_ty).enumFieldIndex(field_name, zcu).?);28449 const enum_field_index: u32 = @intCast(Type.fromInterned(union_obj.enum_tag_ty).enumFieldIndex(field_name, zcu).?);
2816028450
28161 if (try sema.resolveValue(union_byval)) |union_val| {28451 if (try sema.resolveValue(union_byval)) |union_val| {
28162 if (union_val.isUndef(zcu)) return zcu.undefRef(field_ty);28452 if (union_val.isUndef(zcu)) return pt.undefRef(field_ty);
2816328453
28164 const un = ip.indexToKey(union_val.toIntern()).un;28454 const un = ip.indexToKey(union_val.toIntern()).un;
28165 const field_tag = try zcu.enumValueFieldIndex(Type.fromInterned(union_obj.enum_tag_ty), enum_field_index);28455 const field_tag = try pt.enumValueFieldIndex(Type.fromInterned(union_obj.enum_tag_ty), enum_field_index);
28166 const tag_matches = un.tag == field_tag.toIntern();28456 const tag_matches = un.tag == field_tag.toIntern();
28167 switch (union_obj.getLayout(ip)) {28457 switch (union_obj.getLayout(ip)) {
28168 .auto => {28458 .auto => {
...@@ -28191,7 +28481,7 @@ fn unionFieldVal(...@@ -28191,7 +28481,7 @@ fn unionFieldVal(
28191 .@"packed" => if (tag_matches) {28481 .@"packed" => if (tag_matches) {
28192 // Fast path - no need to use bitcast logic.28482 // Fast path - no need to use bitcast logic.
28193 return Air.internedToRef(un.val);28483 return Air.internedToRef(un.val);
28194 } else if (try sema.bitCastVal(union_val, field_ty, 0, try union_ty.bitSizeAdvanced(zcu, .sema), 0)) |field_val| {28484 } else if (try sema.bitCastVal(union_val, field_ty, 0, try union_ty.bitSizeAdvanced(pt, .sema), 0)) |field_val| {
28195 return Air.internedToRef(field_val.toIntern());28485 return Air.internedToRef(field_val.toIntern());
28196 },28486 },
28197 }28487 }
...@@ -28201,7 +28491,7 @@ fn unionFieldVal(...@@ -28201,7 +28491,7 @@ fn unionFieldVal(
28201 if (union_obj.getLayout(ip) == .auto and block.wantSafety() and28491 if (union_obj.getLayout(ip) == .auto and block.wantSafety() and
28202 union_ty.unionTagTypeSafety(zcu) != null and union_obj.field_types.len > 1)28492 union_ty.unionTagTypeSafety(zcu) != null and union_obj.field_types.len > 1)
28203 {28493 {
28204 const wanted_tag_val = try zcu.enumValueFieldIndex(Type.fromInterned(union_obj.enum_tag_ty), enum_field_index);28494 const wanted_tag_val = try pt.enumValueFieldIndex(Type.fromInterned(union_obj.enum_tag_ty), enum_field_index);
28205 const wanted_tag = Air.internedToRef(wanted_tag_val.toIntern());28495 const wanted_tag = Air.internedToRef(wanted_tag_val.toIntern());
28206 const active_tag = try block.addTyOp(.get_union_tag, Type.fromInterned(union_obj.enum_tag_ty), union_byval);28496 const active_tag = try block.addTyOp(.get_union_tag, Type.fromInterned(union_obj.enum_tag_ty), union_byval);
28207 try sema.panicInactiveUnionField(block, src, active_tag, wanted_tag);28497 try sema.panicInactiveUnionField(block, src, active_tag, wanted_tag);
...@@ -28210,7 +28500,7 @@ fn unionFieldVal(...@@ -28210,7 +28500,7 @@ fn unionFieldVal(
28210 _ = try block.addNoOp(.unreach);28500 _ = try block.addNoOp(.unreach);
28211 return .unreachable_value;28501 return .unreachable_value;
28212 }28502 }
28213 try field_ty.resolveLayout(zcu);28503 try field_ty.resolveLayout(pt);
28214 return block.addStructFieldVal(union_byval, field_index, field_ty);28504 return block.addStructFieldVal(union_byval, field_index, field_ty);
28215}28505}
2821628506
...@@ -28224,13 +28514,14 @@ fn elemPtr(...@@ -28224,13 +28514,14 @@ fn elemPtr(
28224 init: bool,28514 init: bool,
28225 oob_safety: bool,28515 oob_safety: bool,
28226) CompileError!Air.Inst.Ref {28516) CompileError!Air.Inst.Ref {
28227 const mod = sema.mod;28517 const pt = sema.pt;
28518 const mod = pt.zcu;
28228 const indexable_ptr_src = src; // TODO better source location28519 const indexable_ptr_src = src; // TODO better source location
28229 const indexable_ptr_ty = sema.typeOf(indexable_ptr);28520 const indexable_ptr_ty = sema.typeOf(indexable_ptr);
2823028521
28231 const indexable_ty = switch (indexable_ptr_ty.zigTypeTag(mod)) {28522 const indexable_ty = switch (indexable_ptr_ty.zigTypeTag(mod)) {
28232 .Pointer => indexable_ptr_ty.childType(mod),28523 .Pointer => indexable_ptr_ty.childType(mod),
28233 else => return sema.fail(block, indexable_ptr_src, "expected pointer, found '{}'", .{indexable_ptr_ty.fmt(mod)}),28524 else => return sema.fail(block, indexable_ptr_src, "expected pointer, found '{}'", .{indexable_ptr_ty.fmt(pt)}),
28234 };28525 };
28235 try checkIndexable(sema, block, src, indexable_ty);28526 try checkIndexable(sema, block, src, indexable_ty);
2823628527
...@@ -28241,7 +28532,7 @@ fn elemPtr(...@@ -28241,7 +28532,7 @@ fn elemPtr(
28241 const index_val = try sema.resolveConstDefinedValue(block, elem_index_src, elem_index, .{28532 const index_val = try sema.resolveConstDefinedValue(block, elem_index_src, elem_index, .{
28242 .needed_comptime_reason = "tuple field access index must be comptime-known",28533 .needed_comptime_reason = "tuple field access index must be comptime-known",
28243 });28534 });
28244 const index: u32 = @intCast(try index_val.toUnsignedIntSema(mod));28535 const index: u32 = @intCast(try index_val.toUnsignedIntSema(pt));
28245 break :blk try sema.tupleFieldPtr(block, src, indexable_ptr, elem_index_src, index, init);28536 break :blk try sema.tupleFieldPtr(block, src, indexable_ptr, elem_index_src, index, init);
28246 },28537 },
28247 else => {28538 else => {
...@@ -28267,7 +28558,8 @@ fn elemPtrOneLayerOnly(...@@ -28267,7 +28558,8 @@ fn elemPtrOneLayerOnly(
28267) CompileError!Air.Inst.Ref {28558) CompileError!Air.Inst.Ref {
28268 const indexable_src = src; // TODO better source location28559 const indexable_src = src; // TODO better source location
28269 const indexable_ty = sema.typeOf(indexable);28560 const indexable_ty = sema.typeOf(indexable);
28270 const mod = sema.mod;28561 const pt = sema.pt;
28562 const mod = pt.zcu;
2827128563
28272 try checkIndexable(sema, block, src, indexable_ty);28564 try checkIndexable(sema, block, src, indexable_ty);
2827328565
...@@ -28279,11 +28571,11 @@ fn elemPtrOneLayerOnly(...@@ -28279,11 +28571,11 @@ fn elemPtrOneLayerOnly(
28279 const runtime_src = rs: {28571 const runtime_src = rs: {
28280 const ptr_val = maybe_ptr_val orelse break :rs indexable_src;28572 const ptr_val = maybe_ptr_val orelse break :rs indexable_src;
28281 const index_val = maybe_index_val orelse break :rs elem_index_src;28573 const index_val = maybe_index_val orelse break :rs elem_index_src;
28282 const index: usize = @intCast(try index_val.toUnsignedIntSema(mod));28574 const index: usize = @intCast(try index_val.toUnsignedIntSema(pt));
28283 const elem_ptr = try ptr_val.ptrElem(index, mod);28575 const elem_ptr = try ptr_val.ptrElem(index, pt);
28284 return Air.internedToRef(elem_ptr.toIntern());28576 return Air.internedToRef(elem_ptr.toIntern());
28285 };28577 };
28286 const result_ty = try indexable_ty.elemPtrType(null, mod);28578 const result_ty = try indexable_ty.elemPtrType(null, pt);
2828728579
28288 try sema.requireRuntimeBlock(block, src, runtime_src);28580 try sema.requireRuntimeBlock(block, src, runtime_src);
28289 return block.addPtrElemPtr(indexable, elem_index, result_ty);28581 return block.addPtrElemPtr(indexable, elem_index, result_ty);
...@@ -28297,7 +28589,7 @@ fn elemPtrOneLayerOnly(...@@ -28297,7 +28589,7 @@ fn elemPtrOneLayerOnly(
28297 const index_val = try sema.resolveConstDefinedValue(block, elem_index_src, elem_index, .{28589 const index_val = try sema.resolveConstDefinedValue(block, elem_index_src, elem_index, .{
28298 .needed_comptime_reason = "tuple field access index must be comptime-known",28590 .needed_comptime_reason = "tuple field access index must be comptime-known",
28299 });28591 });
28300 const index: u32 = @intCast(try index_val.toUnsignedIntSema(mod));28592 const index: u32 = @intCast(try index_val.toUnsignedIntSema(pt));
28301 break :blk try sema.tupleFieldPtr(block, indexable_src, indexable, elem_index_src, index, false);28593 break :blk try sema.tupleFieldPtr(block, indexable_src, indexable, elem_index_src, index, false);
28302 },28594 },
28303 else => unreachable, // Guaranteed by checkIndexable28595 else => unreachable, // Guaranteed by checkIndexable
...@@ -28319,7 +28611,8 @@ fn elemVal(...@@ -28319,7 +28611,8 @@ fn elemVal(
28319) CompileError!Air.Inst.Ref {28611) CompileError!Air.Inst.Ref {
28320 const indexable_src = src; // TODO better source location28612 const indexable_src = src; // TODO better source location
28321 const indexable_ty = sema.typeOf(indexable);28613 const indexable_ty = sema.typeOf(indexable);
28322 const mod = sema.mod;28614 const pt = sema.pt;
28615 const mod = pt.zcu;
2832328616
28324 try checkIndexable(sema, block, src, indexable_ty);28617 try checkIndexable(sema, block, src, indexable_ty);
2832528618
...@@ -28337,14 +28630,14 @@ fn elemVal(...@@ -28337,14 +28630,14 @@ fn elemVal(
28337 const runtime_src = rs: {28630 const runtime_src = rs: {
28338 const indexable_val = maybe_indexable_val orelse break :rs indexable_src;28631 const indexable_val = maybe_indexable_val orelse break :rs indexable_src;
28339 const index_val = maybe_index_val orelse break :rs elem_index_src;28632 const index_val = maybe_index_val orelse break :rs elem_index_src;
28340 const index: usize = @intCast(try index_val.toUnsignedIntSema(mod));28633 const index: usize = @intCast(try index_val.toUnsignedIntSema(pt));
28341 const elem_ty = indexable_ty.elemType2(mod);28634 const elem_ty = indexable_ty.elemType2(mod);
28342 const many_ptr_ty = try mod.manyConstPtrType(elem_ty);28635 const many_ptr_ty = try pt.manyConstPtrType(elem_ty);
28343 const many_ptr_val = try mod.getCoerced(indexable_val, many_ptr_ty);28636 const many_ptr_val = try pt.getCoerced(indexable_val, many_ptr_ty);
28344 const elem_ptr_ty = try mod.singleConstPtrType(elem_ty);28637 const elem_ptr_ty = try pt.singleConstPtrType(elem_ty);
28345 const elem_ptr_val = try many_ptr_val.ptrElem(index, mod);28638 const elem_ptr_val = try many_ptr_val.ptrElem(index, pt);
28346 if (try sema.pointerDeref(block, indexable_src, elem_ptr_val, elem_ptr_ty)) |elem_val| {28639 if (try sema.pointerDeref(block, indexable_src, elem_ptr_val, elem_ptr_ty)) |elem_val| {
28347 return Air.internedToRef((try mod.getCoerced(elem_val, elem_ty)).toIntern());28640 return Air.internedToRef((try pt.getCoerced(elem_val, elem_ty)).toIntern());
28348 }28641 }
28349 break :rs indexable_src;28642 break :rs indexable_src;
28350 };28643 };
...@@ -28358,7 +28651,7 @@ fn elemVal(...@@ -28358,7 +28651,7 @@ fn elemVal(
28358 if (inner_ty.zigTypeTag(mod) != .Array) break :arr_sent;28651 if (inner_ty.zigTypeTag(mod) != .Array) break :arr_sent;
28359 const sentinel = inner_ty.sentinel(mod) orelse break :arr_sent;28652 const sentinel = inner_ty.sentinel(mod) orelse break :arr_sent;
28360 const index_val = try sema.resolveDefinedValue(block, elem_index_src, elem_index) orelse break :arr_sent;28653 const index_val = try sema.resolveDefinedValue(block, elem_index_src, elem_index) orelse break :arr_sent;
28361 const index = try sema.usizeCast(block, src, try index_val.toUnsignedIntSema(mod));28654 const index = try sema.usizeCast(block, src, try index_val.toUnsignedIntSema(pt));
28362 if (index != inner_ty.arrayLen(mod)) break :arr_sent;28655 if (index != inner_ty.arrayLen(mod)) break :arr_sent;
28363 return Air.internedToRef(sentinel.toIntern());28656 return Air.internedToRef(sentinel.toIntern());
28364 }28657 }
...@@ -28376,7 +28669,7 @@ fn elemVal(...@@ -28376,7 +28669,7 @@ fn elemVal(
28376 const index_val = try sema.resolveConstDefinedValue(block, elem_index_src, elem_index, .{28669 const index_val = try sema.resolveConstDefinedValue(block, elem_index_src, elem_index, .{
28377 .needed_comptime_reason = "tuple field access index must be comptime-known",28670 .needed_comptime_reason = "tuple field access index must be comptime-known",
28378 });28671 });
28379 const index: u32 = @intCast(try index_val.toUnsignedIntSema(mod));28672 const index: u32 = @intCast(try index_val.toUnsignedIntSema(pt));
28380 return sema.tupleField(block, indexable_src, indexable, elem_index_src, index);28673 return sema.tupleField(block, indexable_src, indexable, elem_index_src, index);
28381 },28674 },
28382 else => unreachable,28675 else => unreachable,
...@@ -28391,13 +28684,12 @@ fn validateRuntimeElemAccess(...@@ -28391,13 +28684,12 @@ fn validateRuntimeElemAccess(
28391 parent_ty: Type,28684 parent_ty: Type,
28392 parent_src: LazySrcLoc,28685 parent_src: LazySrcLoc,
28393) CompileError!void {28686) CompileError!void {
28394 const mod = sema.mod;
28395 if (try sema.typeRequiresComptime(elem_ty)) {28687 if (try sema.typeRequiresComptime(elem_ty)) {
28396 const msg = msg: {28688 const msg = msg: {
28397 const msg = try sema.errMsg(28689 const msg = try sema.errMsg(
28398 elem_index_src,28690 elem_index_src,
28399 "values of type '{}' must be comptime-known, but index value is runtime-known",28691 "values of type '{}' must be comptime-known, but index value is runtime-known",
28400 .{parent_ty.fmt(mod)},28692 .{parent_ty.fmt(sema.pt)},
28401 );28693 );
28402 errdefer msg.destroy(sema.gpa);28694 errdefer msg.destroy(sema.gpa);
2840328695
...@@ -28418,10 +28710,11 @@ fn tupleFieldPtr(...@@ -28418,10 +28710,11 @@ fn tupleFieldPtr(
28418 field_index: u32,28710 field_index: u32,
28419 init: bool,28711 init: bool,
28420) CompileError!Air.Inst.Ref {28712) CompileError!Air.Inst.Ref {
28421 const mod = sema.mod;28713 const pt = sema.pt;
28714 const mod = pt.zcu;
28422 const tuple_ptr_ty = sema.typeOf(tuple_ptr);28715 const tuple_ptr_ty = sema.typeOf(tuple_ptr);
28423 const tuple_ty = tuple_ptr_ty.childType(mod);28716 const tuple_ty = tuple_ptr_ty.childType(mod);
28424 try tuple_ty.resolveFields(mod);28717 try tuple_ty.resolveFields(pt);
28425 const field_count = tuple_ty.structFieldCount(mod);28718 const field_count = tuple_ty.structFieldCount(mod);
2842628719
28427 if (field_count == 0) {28720 if (field_count == 0) {
...@@ -28435,7 +28728,7 @@ fn tupleFieldPtr(...@@ -28435,7 +28728,7 @@ fn tupleFieldPtr(
28435 }28728 }
2843628729
28437 const field_ty = tuple_ty.structFieldType(field_index, mod);28730 const field_ty = tuple_ty.structFieldType(field_index, mod);
28438 const ptr_field_ty = try mod.ptrTypeSema(.{28731 const ptr_field_ty = try pt.ptrTypeSema(.{
28439 .child = field_ty.toIntern(),28732 .child = field_ty.toIntern(),
28440 .flags = .{28733 .flags = .{
28441 .is_const = !tuple_ptr_ty.ptrIsMutable(mod),28734 .is_const = !tuple_ptr_ty.ptrIsMutable(mod),
...@@ -28445,10 +28738,10 @@ fn tupleFieldPtr(...@@ -28445,10 +28738,10 @@ fn tupleFieldPtr(
28445 });28738 });
2844628739
28447 if (tuple_ty.structFieldIsComptime(field_index, mod))28740 if (tuple_ty.structFieldIsComptime(field_index, mod))
28448 try tuple_ty.resolveStructFieldInits(mod);28741 try tuple_ty.resolveStructFieldInits(pt);
2844928742
28450 if (try tuple_ty.structFieldValueComptime(mod, field_index)) |default_val| {28743 if (try tuple_ty.structFieldValueComptime(pt, field_index)) |default_val| {
28451 return Air.internedToRef((try mod.intern(.{ .ptr = .{28744 return Air.internedToRef((try pt.intern(.{ .ptr = .{
28452 .ty = ptr_field_ty.toIntern(),28745 .ty = ptr_field_ty.toIntern(),
28453 .base_addr = .{ .comptime_field = default_val.toIntern() },28746 .base_addr = .{ .comptime_field = default_val.toIntern() },
28454 .byte_offset = 0,28747 .byte_offset = 0,
...@@ -28456,7 +28749,7 @@ fn tupleFieldPtr(...@@ -28456,7 +28749,7 @@ fn tupleFieldPtr(
28456 }28749 }
2845728750
28458 if (try sema.resolveValue(tuple_ptr)) |tuple_ptr_val| {28751 if (try sema.resolveValue(tuple_ptr)) |tuple_ptr_val| {
28459 const field_ptr_val = try tuple_ptr_val.ptrField(field_index, mod);28752 const field_ptr_val = try tuple_ptr_val.ptrField(field_index, pt);
28460 return Air.internedToRef(field_ptr_val.toIntern());28753 return Air.internedToRef(field_ptr_val.toIntern());
28461 }28754 }
2846228755
...@@ -28476,9 +28769,10 @@ fn tupleField(...@@ -28476,9 +28769,10 @@ fn tupleField(
28476 field_index_src: LazySrcLoc,28769 field_index_src: LazySrcLoc,
28477 field_index: u32,28770 field_index: u32,
28478) CompileError!Air.Inst.Ref {28771) CompileError!Air.Inst.Ref {
28479 const mod = sema.mod;28772 const pt = sema.pt;
28773 const mod = pt.zcu;
28480 const tuple_ty = sema.typeOf(tuple);28774 const tuple_ty = sema.typeOf(tuple);
28481 try tuple_ty.resolveFields(mod);28775 try tuple_ty.resolveFields(pt);
28482 const field_count = tuple_ty.structFieldCount(mod);28776 const field_count = tuple_ty.structFieldCount(mod);
2848328777
28484 if (field_count == 0) {28778 if (field_count == 0) {
...@@ -28494,20 +28788,20 @@ fn tupleField(...@@ -28494,20 +28788,20 @@ fn tupleField(
28494 const field_ty = tuple_ty.structFieldType(field_index, mod);28788 const field_ty = tuple_ty.structFieldType(field_index, mod);
2849528789
28496 if (tuple_ty.structFieldIsComptime(field_index, mod))28790 if (tuple_ty.structFieldIsComptime(field_index, mod))
28497 try tuple_ty.resolveStructFieldInits(mod);28791 try tuple_ty.resolveStructFieldInits(pt);
28498 if (try tuple_ty.structFieldValueComptime(mod, field_index)) |default_value| {28792 if (try tuple_ty.structFieldValueComptime(pt, field_index)) |default_value| {
28499 return Air.internedToRef(default_value.toIntern()); // comptime field28793 return Air.internedToRef(default_value.toIntern()); // comptime field
28500 }28794 }
2850128795
28502 if (try sema.resolveValue(tuple)) |tuple_val| {28796 if (try sema.resolveValue(tuple)) |tuple_val| {
28503 if (tuple_val.isUndef(mod)) return mod.undefRef(field_ty);28797 if (tuple_val.isUndef(mod)) return pt.undefRef(field_ty);
28504 return Air.internedToRef((try tuple_val.fieldValue(mod, field_index)).toIntern());28798 return Air.internedToRef((try tuple_val.fieldValue(pt, field_index)).toIntern());
28505 }28799 }
2850628800
28507 try sema.validateRuntimeElemAccess(block, field_index_src, field_ty, tuple_ty, tuple_src);28801 try sema.validateRuntimeElemAccess(block, field_index_src, field_ty, tuple_ty, tuple_src);
2850828802
28509 try sema.requireRuntimeBlock(block, tuple_src, null);28803 try sema.requireRuntimeBlock(block, tuple_src, null);
28510 try field_ty.resolveLayout(mod);28804 try field_ty.resolveLayout(pt);
28511 return block.addStructFieldVal(tuple, field_index, field_ty);28805 return block.addStructFieldVal(tuple, field_index, field_ty);
28512}28806}
2851328807
...@@ -28521,7 +28815,8 @@ fn elemValArray(...@@ -28521,7 +28815,8 @@ fn elemValArray(
28521 elem_index: Air.Inst.Ref,28815 elem_index: Air.Inst.Ref,
28522 oob_safety: bool,28816 oob_safety: bool,
28523) CompileError!Air.Inst.Ref {28817) CompileError!Air.Inst.Ref {
28524 const mod = sema.mod;28818 const pt = sema.pt;
28819 const mod = pt.zcu;
28525 const array_ty = sema.typeOf(array);28820 const array_ty = sema.typeOf(array);
28526 const array_sent = array_ty.sentinel(mod);28821 const array_sent = array_ty.sentinel(mod);
28527 const array_len = array_ty.arrayLen(mod);28822 const array_len = array_ty.arrayLen(mod);
...@@ -28537,7 +28832,7 @@ fn elemValArray(...@@ -28537,7 +28832,7 @@ fn elemValArray(
28537 const maybe_index_val = try sema.resolveDefinedValue(block, elem_index_src, elem_index);28832 const maybe_index_val = try sema.resolveDefinedValue(block, elem_index_src, elem_index);
2853828833
28539 if (maybe_index_val) |index_val| {28834 if (maybe_index_val) |index_val| {
28540 const index: usize = @intCast(try index_val.toUnsignedIntSema(mod));28835 const index: usize = @intCast(try index_val.toUnsignedIntSema(pt));
28541 if (array_sent) |s| {28836 if (array_sent) |s| {
28542 if (index == array_len) {28837 if (index == array_len) {
28543 return Air.internedToRef(s.toIntern());28838 return Air.internedToRef(s.toIntern());
...@@ -28550,11 +28845,11 @@ fn elemValArray(...@@ -28550,11 +28845,11 @@ fn elemValArray(
28550 }28845 }
28551 if (maybe_undef_array_val) |array_val| {28846 if (maybe_undef_array_val) |array_val| {
28552 if (array_val.isUndef(mod)) {28847 if (array_val.isUndef(mod)) {
28553 return mod.undefRef(elem_ty);28848 return pt.undefRef(elem_ty);
28554 }28849 }
28555 if (maybe_index_val) |index_val| {28850 if (maybe_index_val) |index_val| {
28556 const index: usize = @intCast(try index_val.toUnsignedIntSema(mod));28851 const index: usize = @intCast(try index_val.toUnsignedIntSema(pt));
28557 const elem_val = try array_val.elemValue(mod, index);28852 const elem_val = try array_val.elemValue(pt, index);
28558 return Air.internedToRef(elem_val.toIntern());28853 return Air.internedToRef(elem_val.toIntern());
28559 }28854 }
28560 }28855 }
...@@ -28565,7 +28860,7 @@ fn elemValArray(...@@ -28565,7 +28860,7 @@ fn elemValArray(
28565 if (oob_safety and block.wantSafety()) {28860 if (oob_safety and block.wantSafety()) {
28566 // Runtime check is only needed if unable to comptime check28861 // Runtime check is only needed if unable to comptime check
28567 if (maybe_index_val == null) {28862 if (maybe_index_val == null) {
28568 const len_inst = try mod.intRef(Type.usize, array_len);28863 const len_inst = try pt.intRef(Type.usize, array_len);
28569 const cmp_op: Air.Inst.Tag = if (array_sent != null) .cmp_lte else .cmp_lt;28864 const cmp_op: Air.Inst.Tag = if (array_sent != null) .cmp_lte else .cmp_lt;
28570 try sema.panicIndexOutOfBounds(block, src, elem_index, len_inst, cmp_op);28865 try sema.panicIndexOutOfBounds(block, src, elem_index, len_inst, cmp_op);
28571 }28866 }
...@@ -28589,7 +28884,8 @@ fn elemPtrArray(...@@ -28589,7 +28884,8 @@ fn elemPtrArray(
28589 init: bool,28884 init: bool,
28590 oob_safety: bool,28885 oob_safety: bool,
28591) CompileError!Air.Inst.Ref {28886) CompileError!Air.Inst.Ref {
28592 const mod = sema.mod;28887 const pt = sema.pt;
28888 const mod = pt.zcu;
28593 const array_ptr_ty = sema.typeOf(array_ptr);28889 const array_ptr_ty = sema.typeOf(array_ptr);
28594 const array_ty = array_ptr_ty.childType(mod);28890 const array_ty = array_ptr_ty.childType(mod);
28595 const array_sent = array_ty.sentinel(mod) != null;28891 const array_sent = array_ty.sentinel(mod) != null;
...@@ -28603,7 +28899,7 @@ fn elemPtrArray(...@@ -28603,7 +28899,7 @@ fn elemPtrArray(
28603 const maybe_undef_array_ptr_val = try sema.resolveValue(array_ptr);28899 const maybe_undef_array_ptr_val = try sema.resolveValue(array_ptr);
28604 // The index must not be undefined since it can be out of bounds.28900 // The index must not be undefined since it can be out of bounds.
28605 const offset: ?usize = if (try sema.resolveDefinedValue(block, elem_index_src, elem_index)) |index_val| o: {28901 const offset: ?usize = if (try sema.resolveDefinedValue(block, elem_index_src, elem_index)) |index_val| o: {
28606 const index = try sema.usizeCast(block, elem_index_src, try index_val.toUnsignedIntSema(mod));28902 const index = try sema.usizeCast(block, elem_index_src, try index_val.toUnsignedIntSema(pt));
28607 if (index >= array_len_s) {28903 if (index >= array_len_s) {
28608 const sentinel_label: []const u8 = if (array_sent) " +1 (sentinel)" else "";28904 const sentinel_label: []const u8 = if (array_sent) " +1 (sentinel)" else "";
28609 return sema.fail(block, elem_index_src, "index {d} outside array of length {d}{s}", .{ index, array_len, sentinel_label });28905 return sema.fail(block, elem_index_src, "index {d} outside array of length {d}{s}", .{ index, array_len, sentinel_label });
...@@ -28611,14 +28907,14 @@ fn elemPtrArray(...@@ -28611,14 +28907,14 @@ fn elemPtrArray(
28611 break :o index;28907 break :o index;
28612 } else null;28908 } else null;
2861328909
28614 const elem_ptr_ty = try array_ptr_ty.elemPtrType(offset, mod);28910 const elem_ptr_ty = try array_ptr_ty.elemPtrType(offset, pt);
2861528911
28616 if (maybe_undef_array_ptr_val) |array_ptr_val| {28912 if (maybe_undef_array_ptr_val) |array_ptr_val| {
28617 if (array_ptr_val.isUndef(mod)) {28913 if (array_ptr_val.isUndef(mod)) {
28618 return mod.undefRef(elem_ptr_ty);28914 return pt.undefRef(elem_ptr_ty);
28619 }28915 }
28620 if (offset) |index| {28916 if (offset) |index| {
28621 const elem_ptr = try array_ptr_val.ptrElem(index, mod);28917 const elem_ptr = try array_ptr_val.ptrElem(index, pt);
28622 return Air.internedToRef(elem_ptr.toIntern());28918 return Air.internedToRef(elem_ptr.toIntern());
28623 }28919 }
28624 }28920 }
...@@ -28632,7 +28928,7 @@ fn elemPtrArray(...@@ -28632,7 +28928,7 @@ fn elemPtrArray(
2863228928
28633 // Runtime check is only needed if unable to comptime check.28929 // Runtime check is only needed if unable to comptime check.
28634 if (oob_safety and block.wantSafety() and offset == null) {28930 if (oob_safety and block.wantSafety() and offset == null) {
28635 const len_inst = try mod.intRef(Type.usize, array_len);28931 const len_inst = try pt.intRef(Type.usize, array_len);
28636 const cmp_op: Air.Inst.Tag = if (array_sent) .cmp_lte else .cmp_lt;28932 const cmp_op: Air.Inst.Tag = if (array_sent) .cmp_lte else .cmp_lt;
28637 try sema.panicIndexOutOfBounds(block, src, elem_index, len_inst, cmp_op);28933 try sema.panicIndexOutOfBounds(block, src, elem_index, len_inst, cmp_op);
28638 }28934 }
...@@ -28650,7 +28946,8 @@ fn elemValSlice(...@@ -28650,7 +28946,8 @@ fn elemValSlice(
28650 elem_index: Air.Inst.Ref,28946 elem_index: Air.Inst.Ref,
28651 oob_safety: bool,28947 oob_safety: bool,
28652) CompileError!Air.Inst.Ref {28948) CompileError!Air.Inst.Ref {
28653 const mod = sema.mod;28949 const pt = sema.pt;
28950 const mod = pt.zcu;
28654 const slice_ty = sema.typeOf(slice);28951 const slice_ty = sema.typeOf(slice);
28655 const slice_sent = slice_ty.sentinel(mod) != null;28952 const slice_sent = slice_ty.sentinel(mod) != null;
28656 const elem_ty = slice_ty.elemType2(mod);28953 const elem_ty = slice_ty.elemType2(mod);
...@@ -28663,19 +28960,19 @@ fn elemValSlice(...@@ -28663,19 +28960,19 @@ fn elemValSlice(
2866328960
28664 if (maybe_slice_val) |slice_val| {28961 if (maybe_slice_val) |slice_val| {
28665 runtime_src = elem_index_src;28962 runtime_src = elem_index_src;
28666 const slice_len = try slice_val.sliceLen(mod);28963 const slice_len = try slice_val.sliceLen(pt);
28667 const slice_len_s = slice_len + @intFromBool(slice_sent);28964 const slice_len_s = slice_len + @intFromBool(slice_sent);
28668 if (slice_len_s == 0) {28965 if (slice_len_s == 0) {
28669 return sema.fail(block, slice_src, "indexing into empty slice is not allowed", .{});28966 return sema.fail(block, slice_src, "indexing into empty slice is not allowed", .{});
28670 }28967 }
28671 if (maybe_index_val) |index_val| {28968 if (maybe_index_val) |index_val| {
28672 const index: usize = @intCast(try index_val.toUnsignedIntSema(mod));28969 const index: usize = @intCast(try index_val.toUnsignedIntSema(pt));
28673 if (index >= slice_len_s) {28970 if (index >= slice_len_s) {
28674 const sentinel_label: []const u8 = if (slice_sent) " +1 (sentinel)" else "";28971 const sentinel_label: []const u8 = if (slice_sent) " +1 (sentinel)" else "";
28675 return sema.fail(block, elem_index_src, "index {d} outside slice of length {d}{s}", .{ index, slice_len, sentinel_label });28972 return sema.fail(block, elem_index_src, "index {d} outside slice of length {d}{s}", .{ index, slice_len, sentinel_label });
28676 }28973 }
28677 const elem_ptr_ty = try slice_ty.elemPtrType(index, mod);28974 const elem_ptr_ty = try slice_ty.elemPtrType(index, pt);
28678 const elem_ptr_val = try slice_val.ptrElem(index, mod);28975 const elem_ptr_val = try slice_val.ptrElem(index, pt);
28679 if (try sema.pointerDeref(block, slice_src, elem_ptr_val, elem_ptr_ty)) |elem_val| {28976 if (try sema.pointerDeref(block, slice_src, elem_ptr_val, elem_ptr_ty)) |elem_val| {
28680 return Air.internedToRef(elem_val.toIntern());28977 return Air.internedToRef(elem_val.toIntern());
28681 }28978 }
...@@ -28688,7 +28985,7 @@ fn elemValSlice(...@@ -28688,7 +28985,7 @@ fn elemValSlice(
28688 try sema.requireRuntimeBlock(block, src, runtime_src);28985 try sema.requireRuntimeBlock(block, src, runtime_src);
28689 if (oob_safety and block.wantSafety()) {28986 if (oob_safety and block.wantSafety()) {
28690 const len_inst = if (maybe_slice_val) |slice_val|28987 const len_inst = if (maybe_slice_val) |slice_val|
28691 try mod.intRef(Type.usize, try slice_val.sliceLen(mod))28988 try pt.intRef(Type.usize, try slice_val.sliceLen(pt))
28692 else28989 else
28693 try block.addTyOp(.slice_len, Type.usize, slice);28990 try block.addTyOp(.slice_len, Type.usize, slice);
28694 const cmp_op: Air.Inst.Tag = if (slice_sent) .cmp_lte else .cmp_lt;28991 const cmp_op: Air.Inst.Tag = if (slice_sent) .cmp_lte else .cmp_lt;
...@@ -28707,24 +29004,25 @@ fn elemPtrSlice(...@@ -28707,24 +29004,25 @@ fn elemPtrSlice(
28707 elem_index: Air.Inst.Ref,29004 elem_index: Air.Inst.Ref,
28708 oob_safety: bool,29005 oob_safety: bool,
28709) CompileError!Air.Inst.Ref {29006) CompileError!Air.Inst.Ref {
28710 const mod = sema.mod;29007 const pt = sema.pt;
29008 const mod = pt.zcu;
28711 const slice_ty = sema.typeOf(slice);29009 const slice_ty = sema.typeOf(slice);
28712 const slice_sent = slice_ty.sentinel(mod) != null;29010 const slice_sent = slice_ty.sentinel(mod) != null;
2871329011
28714 const maybe_undef_slice_val = try sema.resolveValue(slice);29012 const maybe_undef_slice_val = try sema.resolveValue(slice);
28715 // The index must not be undefined since it can be out of bounds.29013 // The index must not be undefined since it can be out of bounds.
28716 const offset: ?usize = if (try sema.resolveDefinedValue(block, elem_index_src, elem_index)) |index_val| o: {29014 const offset: ?usize = if (try sema.resolveDefinedValue(block, elem_index_src, elem_index)) |index_val| o: {
28717 const index = try sema.usizeCast(block, elem_index_src, try index_val.toUnsignedIntSema(mod));29015 const index = try sema.usizeCast(block, elem_index_src, try index_val.toUnsignedIntSema(pt));
28718 break :o index;29016 break :o index;
28719 } else null;29017 } else null;
2872029018
28721 const elem_ptr_ty = try slice_ty.elemPtrType(offset, mod);29019 const elem_ptr_ty = try slice_ty.elemPtrType(offset, pt);
2872229020
28723 if (maybe_undef_slice_val) |slice_val| {29021 if (maybe_undef_slice_val) |slice_val| {
28724 if (slice_val.isUndef(mod)) {29022 if (slice_val.isUndef(mod)) {
28725 return mod.undefRef(elem_ptr_ty);29023 return pt.undefRef(elem_ptr_ty);
28726 }29024 }
28727 const slice_len = try slice_val.sliceLen(mod);29025 const slice_len = try slice_val.sliceLen(pt);
28728 const slice_len_s = slice_len + @intFromBool(slice_sent);29026 const slice_len_s = slice_len + @intFromBool(slice_sent);
28729 if (slice_len_s == 0) {29027 if (slice_len_s == 0) {
28730 return sema.fail(block, slice_src, "indexing into empty slice is not allowed", .{});29028 return sema.fail(block, slice_src, "indexing into empty slice is not allowed", .{});
...@@ -28734,7 +29032,7 @@ fn elemPtrSlice(...@@ -28734,7 +29032,7 @@ fn elemPtrSlice(
28734 const sentinel_label: []const u8 = if (slice_sent) " +1 (sentinel)" else "";29032 const sentinel_label: []const u8 = if (slice_sent) " +1 (sentinel)" else "";
28735 return sema.fail(block, elem_index_src, "index {d} outside slice of length {d}{s}", .{ index, slice_len, sentinel_label });29033 return sema.fail(block, elem_index_src, "index {d} outside slice of length {d}{s}", .{ index, slice_len, sentinel_label });
28736 }29034 }
28737 const elem_ptr_val = try slice_val.ptrElem(index, mod);29035 const elem_ptr_val = try slice_val.ptrElem(index, pt);
28738 return Air.internedToRef(elem_ptr_val.toIntern());29036 return Air.internedToRef(elem_ptr_val.toIntern());
28739 }29037 }
28740 }29038 }
...@@ -28747,7 +29045,7 @@ fn elemPtrSlice(...@@ -28747,7 +29045,7 @@ fn elemPtrSlice(
28747 const len_inst = len: {29045 const len_inst = len: {
28748 if (maybe_undef_slice_val) |slice_val|29046 if (maybe_undef_slice_val) |slice_val|
28749 if (!slice_val.isUndef(mod))29047 if (!slice_val.isUndef(mod))
28750 break :len try mod.intRef(Type.usize, try slice_val.sliceLen(mod));29048 break :len try pt.intRef(Type.usize, try slice_val.sliceLen(pt));
28751 break :len try block.addTyOp(.slice_len, Type.usize, slice);29049 break :len try block.addTyOp(.slice_len, Type.usize, slice);
28752 };29050 };
28753 const cmp_op: Air.Inst.Tag = if (slice_sent) .cmp_lte else .cmp_lt;29051 const cmp_op: Air.Inst.Tag = if (slice_sent) .cmp_lte else .cmp_lt;
...@@ -28810,11 +29108,12 @@ fn coerceExtra(...@@ -28810,11 +29108,12 @@ fn coerceExtra(
28810 opts: CoerceOpts,29108 opts: CoerceOpts,
28811) CoersionError!Air.Inst.Ref {29109) CoersionError!Air.Inst.Ref {
28812 if (dest_ty.isGenericPoison()) return inst;29110 if (dest_ty.isGenericPoison()) return inst;
28813 const zcu = sema.mod;29111 const pt = sema.pt;
29112 const zcu = pt.zcu;
28814 const dest_ty_src = inst_src; // TODO better source location29113 const dest_ty_src = inst_src; // TODO better source location
28815 try dest_ty.resolveFields(zcu);29114 try dest_ty.resolveFields(pt);
28816 const inst_ty = sema.typeOf(inst);29115 const inst_ty = sema.typeOf(inst);
28817 try inst_ty.resolveFields(zcu);29116 try inst_ty.resolveFields(pt);
28818 const target = zcu.getTarget();29117 const target = zcu.getTarget();
28819 // If the types are the same, we can return the operand.29118 // If the types are the same, we can return the operand.
28820 if (dest_ty.eql(inst_ty, zcu))29119 if (dest_ty.eql(inst_ty, zcu))
...@@ -28838,12 +29137,12 @@ fn coerceExtra(...@@ -28838,12 +29137,12 @@ fn coerceExtra(
28838 if (maybe_inst_val) |val| {29137 if (maybe_inst_val) |val| {
28839 // undefined sets the optional bit also to undefined.29138 // undefined sets the optional bit also to undefined.
28840 if (val.toIntern() == .undef) {29139 if (val.toIntern() == .undef) {
28841 return zcu.undefRef(dest_ty);29140 return pt.undefRef(dest_ty);
28842 }29141 }
2884329142
28844 // null to ?T29143 // null to ?T
28845 if (val.toIntern() == .null_value) {29144 if (val.toIntern() == .null_value) {
28846 return Air.internedToRef((try zcu.intern(.{ .opt = .{29145 return Air.internedToRef((try pt.intern(.{ .opt = .{
28847 .ty = dest_ty.toIntern(),29146 .ty = dest_ty.toIntern(),
28848 .val = .none,29147 .val = .none,
28849 } })));29148 } })));
...@@ -29018,7 +29317,7 @@ fn coerceExtra(...@@ -29018,7 +29317,7 @@ fn coerceExtra(
29018 switch (dest_info.flags.size) {29317 switch (dest_info.flags.size) {
29019 // coercion to C pointer29318 // coercion to C pointer
29020 .C => switch (inst_ty.zigTypeTag(zcu)) {29319 .C => switch (inst_ty.zigTypeTag(zcu)) {
29021 .Null => return Air.internedToRef(try zcu.intern(.{ .ptr = .{29320 .Null => return Air.internedToRef(try pt.intern(.{ .ptr = .{
29022 .ty = dest_ty.toIntern(),29321 .ty = dest_ty.toIntern(),
29023 .base_addr = .int,29322 .base_addr = .int,
29024 .byte_offset = 0,29323 .byte_offset = 0,
...@@ -29063,7 +29362,7 @@ fn coerceExtra(...@@ -29063,7 +29362,7 @@ fn coerceExtra(
29063 if (inst_info.flags.size == .Slice) {29362 if (inst_info.flags.size == .Slice) {
29064 assert(dest_info.sentinel == .none);29363 assert(dest_info.sentinel == .none);
29065 if (inst_info.sentinel == .none or29364 if (inst_info.sentinel == .none or
29066 inst_info.sentinel != (try zcu.intValue(Type.fromInterned(inst_info.child), 0)).toIntern())29365 inst_info.sentinel != (try pt.intValue(Type.fromInterned(inst_info.child), 0)).toIntern())
29067 break :p;29366 break :p;
2906829367
29069 const slice_ptr = try sema.analyzeSlicePtr(block, inst_src, inst, inst_ty);29368 const slice_ptr = try sema.analyzeSlicePtr(block, inst_src, inst, inst_ty);
...@@ -29112,7 +29411,7 @@ fn coerceExtra(...@@ -29112,7 +29411,7 @@ fn coerceExtra(
29112 block,29411 block,
29113 inst_src,29412 inst_src,
29114 "array literal requires address-of operator (&) to coerce to slice type '{}'",29413 "array literal requires address-of operator (&) to coerce to slice type '{}'",
29115 .{dest_ty.fmt(zcu)},29414 .{dest_ty.fmt(pt)},
29116 );29415 );
29117 }29416 }
2911829417
...@@ -29123,10 +29422,10 @@ fn coerceExtra(...@@ -29123,10 +29422,10 @@ fn coerceExtra(
29123 // empty tuple to zero-length slice29422 // empty tuple to zero-length slice
29124 // note that this allows coercing to a mutable slice.29423 // note that this allows coercing to a mutable slice.
29125 if (inst_child_ty.structFieldCount(zcu) == 0) {29424 if (inst_child_ty.structFieldCount(zcu) == 0) {
29126 const align_val = try dest_ty.ptrAlignmentAdvanced(zcu, .sema);29425 const align_val = try dest_ty.ptrAlignmentAdvanced(pt, .sema);
29127 return Air.internedToRef(try zcu.intern(.{ .slice = .{29426 return Air.internedToRef(try pt.intern(.{ .slice = .{
29128 .ty = dest_ty.toIntern(),29427 .ty = dest_ty.toIntern(),
29129 .ptr = try zcu.intern(.{ .ptr = .{29428 .ptr = try pt.intern(.{ .ptr = .{
29130 .ty = dest_ty.slicePtrFieldType(zcu).toIntern(),29429 .ty = dest_ty.slicePtrFieldType(zcu).toIntern(),
29131 .base_addr = .int,29430 .base_addr = .int,
29132 .byte_offset = align_val.toByteUnits().?,29431 .byte_offset = align_val.toByteUnits().?,
...@@ -29138,7 +29437,7 @@ fn coerceExtra(...@@ -29138,7 +29437,7 @@ fn coerceExtra(
29138 // pointer to tuple to slice29437 // pointer to tuple to slice
29139 if (!dest_info.flags.is_const) {29438 if (!dest_info.flags.is_const) {
29140 const err_msg = err_msg: {29439 const err_msg = err_msg: {
29141 const err_msg = try sema.errMsg(inst_src, "cannot cast pointer to tuple to '{}'", .{dest_ty.fmt(zcu)});29440 const err_msg = try sema.errMsg(inst_src, "cannot cast pointer to tuple to '{}'", .{dest_ty.fmt(pt)});
29142 errdefer err_msg.destroy(sema.gpa);29441 errdefer err_msg.destroy(sema.gpa);
29143 try sema.errNote(dest_ty_src, err_msg, "pointers to tuples can only coerce to constant pointers", .{});29442 try sema.errNote(dest_ty_src, err_msg, "pointers to tuples can only coerce to constant pointers", .{});
29144 break :err_msg err_msg;29443 break :err_msg err_msg;
...@@ -29194,12 +29493,12 @@ fn coerceExtra(...@@ -29194,12 +29493,12 @@ fn coerceExtra(
29194 // comptime-known integer to other number29493 // comptime-known integer to other number
29195 if (!(try sema.intFitsInType(val, dest_ty, null))) {29494 if (!(try sema.intFitsInType(val, dest_ty, null))) {
29196 if (!opts.report_err) return error.NotCoercible;29495 if (!opts.report_err) return error.NotCoercible;
29197 return sema.fail(block, inst_src, "type '{}' cannot represent integer value '{}'", .{ dest_ty.fmt(zcu), val.fmtValue(zcu, sema) });29496 return sema.fail(block, inst_src, "type '{}' cannot represent integer value '{}'", .{ dest_ty.fmt(pt), val.fmtValue(pt, sema) });
29198 }29497 }
29199 return switch (zcu.intern_pool.indexToKey(val.toIntern())) {29498 return switch (zcu.intern_pool.indexToKey(val.toIntern())) {
29200 .undef => try zcu.undefRef(dest_ty),29499 .undef => try pt.undefRef(dest_ty),
29201 .int => |int| Air.internedToRef(29500 .int => |int| Air.internedToRef(
29202 try zcu.intern_pool.getCoercedInts(zcu.gpa, int, dest_ty.toIntern()),29501 try zcu.intern_pool.getCoercedInts(zcu.gpa, pt.tid, int, dest_ty.toIntern()),
29203 ),29502 ),
29204 else => unreachable,29503 else => unreachable,
29205 };29504 };
...@@ -29228,18 +29527,18 @@ fn coerceExtra(...@@ -29228,18 +29527,18 @@ fn coerceExtra(
29228 .Float, .ComptimeFloat => switch (inst_ty.zigTypeTag(zcu)) {29527 .Float, .ComptimeFloat => switch (inst_ty.zigTypeTag(zcu)) {
29229 .ComptimeFloat => {29528 .ComptimeFloat => {
29230 const val = try sema.resolveConstDefinedValue(block, LazySrcLoc.unneeded, inst, undefined);29529 const val = try sema.resolveConstDefinedValue(block, LazySrcLoc.unneeded, inst, undefined);
29231 const result_val = try val.floatCast(dest_ty, zcu);29530 const result_val = try val.floatCast(dest_ty, pt);
29232 return Air.internedToRef(result_val.toIntern());29531 return Air.internedToRef(result_val.toIntern());
29233 },29532 },
29234 .Float => {29533 .Float => {
29235 if (maybe_inst_val) |val| {29534 if (maybe_inst_val) |val| {
29236 const result_val = try val.floatCast(dest_ty, zcu);29535 const result_val = try val.floatCast(dest_ty, pt);
29237 if (!val.eql(try result_val.floatCast(inst_ty, zcu), inst_ty, zcu)) {29536 if (!val.eql(try result_val.floatCast(inst_ty, pt), inst_ty, zcu)) {
29238 return sema.fail(29537 return sema.fail(
29239 block,29538 block,
29240 inst_src,29539 inst_src,
29241 "type '{}' cannot represent float value '{}'",29540 "type '{}' cannot represent float value '{}'",
29242 .{ dest_ty.fmt(zcu), val.fmtValue(zcu, sema) },29541 .{ dest_ty.fmt(pt), val.fmtValue(pt, sema) },
29243 );29542 );
29244 }29543 }
29245 return Air.internedToRef(result_val.toIntern());29544 return Air.internedToRef(result_val.toIntern());
...@@ -29268,7 +29567,7 @@ fn coerceExtra(...@@ -29268,7 +29567,7 @@ fn coerceExtra(
29268 }29567 }
29269 break :int;29568 break :int;
29270 };29569 };
29271 const result_val = try val.floatFromIntAdvanced(sema.arena, inst_ty, dest_ty, zcu, .sema);29570 const result_val = try val.floatFromIntAdvanced(sema.arena, inst_ty, dest_ty, pt, .sema);
29272 // TODO implement this compile error29571 // TODO implement this compile error
29273 //const int_again_val = try result_val.intFromFloat(sema.arena, inst_ty);29572 //const int_again_val = try result_val.intFromFloat(sema.arena, inst_ty);
29274 //if (!int_again_val.eql(val, inst_ty, zcu)) {29573 //if (!int_again_val.eql(val, inst_ty, zcu)) {
...@@ -29276,7 +29575,7 @@ fn coerceExtra(...@@ -29276,7 +29575,7 @@ fn coerceExtra(
29276 // block,29575 // block,
29277 // inst_src,29576 // inst_src,
29278 // "type '{}' cannot represent integer value '{}'",29577 // "type '{}' cannot represent integer value '{}'",
29279 // .{ dest_ty.fmt(zcu), val },29578 // .{ dest_ty.fmt(pt), val },
29280 // );29579 // );
29281 //}29580 //}
29282 return Air.internedToRef(result_val.toIntern());29581 return Air.internedToRef(result_val.toIntern());
...@@ -29290,10 +29589,10 @@ fn coerceExtra(...@@ -29290,10 +29589,10 @@ fn coerceExtra(
29290 const string = zcu.intern_pool.indexToKey(val.toIntern()).enum_literal;29589 const string = zcu.intern_pool.indexToKey(val.toIntern()).enum_literal;
29291 const field_index = dest_ty.enumFieldIndex(string, zcu) orelse {29590 const field_index = dest_ty.enumFieldIndex(string, zcu) orelse {
29292 return sema.fail(block, inst_src, "no field named '{}' in enum '{}'", .{29591 return sema.fail(block, inst_src, "no field named '{}' in enum '{}'", .{
29293 string.fmt(&zcu.intern_pool), dest_ty.fmt(zcu),29592 string.fmt(&zcu.intern_pool), dest_ty.fmt(pt),
29294 });29593 });
29295 };29594 };
29296 return Air.internedToRef((try zcu.enumValueFieldIndex(dest_ty, @intCast(field_index))).toIntern());29595 return Air.internedToRef((try pt.enumValueFieldIndex(dest_ty, @intCast(field_index))).toIntern());
29297 },29596 },
29298 .Union => blk: {29597 .Union => blk: {
29299 // union to its own tag type29598 // union to its own tag type
...@@ -29308,12 +29607,12 @@ fn coerceExtra(...@@ -29308,12 +29607,12 @@ fn coerceExtra(
29308 .ErrorUnion => eu: {29607 .ErrorUnion => eu: {
29309 if (maybe_inst_val) |inst_val| {29608 if (maybe_inst_val) |inst_val| {
29310 switch (inst_val.toIntern()) {29609 switch (inst_val.toIntern()) {
29311 .undef => return zcu.undefRef(dest_ty),29610 .undef => return pt.undefRef(dest_ty),
29312 else => switch (zcu.intern_pool.indexToKey(inst_val.toIntern())) {29611 else => switch (zcu.intern_pool.indexToKey(inst_val.toIntern())) {
29313 .error_union => |error_union| switch (error_union.val) {29612 .error_union => |error_union| switch (error_union.val) {
29314 .err_name => |err_name| {29613 .err_name => |err_name| {
29315 const error_set_ty = inst_ty.errorUnionSet(zcu);29614 const error_set_ty = inst_ty.errorUnionSet(zcu);
29316 const error_set_val = Air.internedToRef((try zcu.intern(.{ .err = .{29615 const error_set_val = Air.internedToRef((try pt.intern(.{ .err = .{
29317 .ty = error_set_ty.toIntern(),29616 .ty = error_set_ty.toIntern(),
29318 .name = err_name,29617 .name = err_name,
29319 } })));29618 } })));
...@@ -29370,7 +29669,7 @@ fn coerceExtra(...@@ -29370,7 +29669,7 @@ fn coerceExtra(
2937029669
29371 if (dest_ty.sentinel(zcu)) |dest_sent| {29670 if (dest_ty.sentinel(zcu)) |dest_sent| {
29372 const src_sent = inst_ty.sentinel(zcu) orelse break :array_to_array;29671 const src_sent = inst_ty.sentinel(zcu) orelse break :array_to_array;
29373 if (dest_sent.toIntern() != (try zcu.getCoerced(src_sent, dest_ty.childType(zcu))).toIntern()) {29672 if (dest_sent.toIntern() != (try pt.getCoerced(src_sent, dest_ty.childType(zcu))).toIntern()) {
29374 break :array_to_array;29673 break :array_to_array;
29375 }29674 }
29376 }29675 }
...@@ -29414,7 +29713,7 @@ fn coerceExtra(...@@ -29414,7 +29713,7 @@ fn coerceExtra(
29414 // undefined to anything. We do this after the big switch above so that29713 // undefined to anything. We do this after the big switch above so that
29415 // special logic has a chance to run first, such as `*[N]T` to `[]T` which29714 // special logic has a chance to run first, such as `*[N]T` to `[]T` which
29416 // should initialize the length field of the slice.29715 // should initialize the length field of the slice.
29417 if (maybe_inst_val) |val| if (val.toIntern() == .undef) return zcu.undefRef(dest_ty);29716 if (maybe_inst_val) |val| if (val.toIntern() == .undef) return pt.undefRef(dest_ty);
2941829717
29419 if (!opts.report_err) return error.NotCoercible;29718 if (!opts.report_err) return error.NotCoercible;
2942029719
...@@ -29434,7 +29733,7 @@ fn coerceExtra(...@@ -29434,7 +29733,7 @@ fn coerceExtra(
29434 }29733 }
2943529734
29436 const msg = msg: {29735 const msg = msg: {
29437 const msg = try sema.errMsg(inst_src, "expected type '{}', found '{}'", .{ dest_ty.fmt(zcu), inst_ty.fmt(zcu) });29736 const msg = try sema.errMsg(inst_src, "expected type '{}', found '{}'", .{ dest_ty.fmt(pt), inst_ty.fmt(pt) });
29438 errdefer msg.destroy(sema.gpa);29737 errdefer msg.destroy(sema.gpa);
2943929738
29440 // E!T to T29739 // E!T to T
...@@ -29486,7 +29785,7 @@ fn coerceInMemory(...@@ -29486,7 +29785,7 @@ fn coerceInMemory(
29486 val: Value,29785 val: Value,
29487 dst_ty: Type,29786 dst_ty: Type,
29488) CompileError!Air.Inst.Ref {29787) CompileError!Air.Inst.Ref {
29489 return Air.internedToRef((try sema.mod.getCoerced(val, dst_ty)).toIntern());29788 return Air.internedToRef((try sema.pt.getCoerced(val, dst_ty)).toIntern());
29490}29789}
2949129790
29492const InMemoryCoercionResult = union(enum) {29791const InMemoryCoercionResult = union(enum) {
...@@ -29607,7 +29906,7 @@ const InMemoryCoercionResult = union(enum) {...@@ -29607,7 +29906,7 @@ const InMemoryCoercionResult = union(enum) {
29607 }29906 }
2960829907
29609 fn report(res: *const InMemoryCoercionResult, sema: *Sema, src: LazySrcLoc, msg: *Module.ErrorMsg) !void {29908 fn report(res: *const InMemoryCoercionResult, sema: *Sema, src: LazySrcLoc, msg: *Module.ErrorMsg) !void {
29610 const mod = sema.mod;29909 const pt = sema.pt;
29611 var cur = res;29910 var cur = res;
29612 while (true) switch (cur.*) {29911 while (true) switch (cur.*) {
29613 .ok => unreachable,29912 .ok => unreachable,
...@@ -29624,7 +29923,7 @@ const InMemoryCoercionResult = union(enum) {...@@ -29624,7 +29923,7 @@ const InMemoryCoercionResult = union(enum) {
29624 },29923 },
29625 .error_union_payload => |pair| {29924 .error_union_payload => |pair| {
29626 try sema.errNote(src, msg, "error union payload '{}' cannot cast into error union payload '{}'", .{29925 try sema.errNote(src, msg, "error union payload '{}' cannot cast into error union payload '{}'", .{
29627 pair.actual.fmt(mod), pair.wanted.fmt(mod),29926 pair.actual.fmt(pt), pair.wanted.fmt(pt),
29628 });29927 });
29629 cur = pair.child;29928 cur = pair.child;
29630 },29929 },
...@@ -29637,18 +29936,18 @@ const InMemoryCoercionResult = union(enum) {...@@ -29637,18 +29936,18 @@ const InMemoryCoercionResult = union(enum) {
29637 .array_sentinel => |sentinel| {29936 .array_sentinel => |sentinel| {
29638 if (sentinel.actual.toIntern() != .unreachable_value) {29937 if (sentinel.actual.toIntern() != .unreachable_value) {
29639 try sema.errNote(src, msg, "array sentinel '{}' cannot cast into array sentinel '{}'", .{29938 try sema.errNote(src, msg, "array sentinel '{}' cannot cast into array sentinel '{}'", .{
29640 sentinel.actual.fmtValue(mod, sema), sentinel.wanted.fmtValue(mod, sema),29939 sentinel.actual.fmtValue(pt, sema), sentinel.wanted.fmtValue(pt, sema),
29641 });29940 });
29642 } else {29941 } else {
29643 try sema.errNote(src, msg, "destination array requires '{}' sentinel", .{29942 try sema.errNote(src, msg, "destination array requires '{}' sentinel", .{
29644 sentinel.wanted.fmtValue(mod, sema),29943 sentinel.wanted.fmtValue(pt, sema),
29645 });29944 });
29646 }29945 }
29647 break;29946 break;
29648 },29947 },
29649 .array_elem => |pair| {29948 .array_elem => |pair| {
29650 try sema.errNote(src, msg, "array element type '{}' cannot cast into array element type '{}'", .{29949 try sema.errNote(src, msg, "array element type '{}' cannot cast into array element type '{}'", .{
29651 pair.actual.fmt(mod), pair.wanted.fmt(mod),29950 pair.actual.fmt(pt), pair.wanted.fmt(pt),
29652 });29951 });
29653 cur = pair.child;29952 cur = pair.child;
29654 },29953 },
...@@ -29660,19 +29959,19 @@ const InMemoryCoercionResult = union(enum) {...@@ -29660,19 +29959,19 @@ const InMemoryCoercionResult = union(enum) {
29660 },29959 },
29661 .vector_elem => |pair| {29960 .vector_elem => |pair| {
29662 try sema.errNote(src, msg, "vector element type '{}' cannot cast into vector element type '{}'", .{29961 try sema.errNote(src, msg, "vector element type '{}' cannot cast into vector element type '{}'", .{
29663 pair.actual.fmt(mod), pair.wanted.fmt(mod),29962 pair.actual.fmt(pt), pair.wanted.fmt(pt),
29664 });29963 });
29665 cur = pair.child;29964 cur = pair.child;
29666 },29965 },
29667 .optional_shape => |pair| {29966 .optional_shape => |pair| {
29668 try sema.errNote(src, msg, "optional type child '{}' cannot cast into optional type child '{}'", .{29967 try sema.errNote(src, msg, "optional type child '{}' cannot cast into optional type child '{}'", .{
29669 pair.actual.optionalChild(mod).fmt(mod), pair.wanted.optionalChild(mod).fmt(mod),29968 pair.actual.optionalChild(pt.zcu).fmt(pt), pair.wanted.optionalChild(pt.zcu).fmt(pt),
29670 });29969 });
29671 break;29970 break;
29672 },29971 },
29673 .optional_child => |pair| {29972 .optional_child => |pair| {
29674 try sema.errNote(src, msg, "optional type child '{}' cannot cast into optional type child '{}'", .{29973 try sema.errNote(src, msg, "optional type child '{}' cannot cast into optional type child '{}'", .{
29675 pair.actual.fmt(mod), pair.wanted.fmt(mod),29974 pair.actual.fmt(pt), pair.wanted.fmt(pt),
29676 });29975 });
29677 cur = pair.child;29976 cur = pair.child;
29678 },29977 },
...@@ -29682,7 +29981,7 @@ const InMemoryCoercionResult = union(enum) {...@@ -29682,7 +29981,7 @@ const InMemoryCoercionResult = union(enum) {
29682 },29981 },
29683 .missing_error => |missing_errors| {29982 .missing_error => |missing_errors| {
29684 for (missing_errors) |err| {29983 for (missing_errors) |err| {
29685 try sema.errNote(src, msg, "'error.{}' not a member of destination error set", .{err.fmt(&mod.intern_pool)});29984 try sema.errNote(src, msg, "'error.{}' not a member of destination error set", .{err.fmt(&pt.zcu.intern_pool)});
29686 }29985 }
29687 break;29986 break;
29688 },29987 },
...@@ -29736,7 +30035,7 @@ const InMemoryCoercionResult = union(enum) {...@@ -29736,7 +30035,7 @@ const InMemoryCoercionResult = union(enum) {
29736 },30035 },
29737 .fn_param => |param| {30036 .fn_param => |param| {
29738 try sema.errNote(src, msg, "parameter {d} '{}' cannot cast into '{}'", .{30037 try sema.errNote(src, msg, "parameter {d} '{}' cannot cast into '{}'", .{
29739 param.index, param.actual.fmt(mod), param.wanted.fmt(mod),30038 param.index, param.actual.fmt(pt), param.wanted.fmt(pt),
29740 });30039 });
29741 cur = param.child;30040 cur = param.child;
29742 },30041 },
...@@ -29746,13 +30045,13 @@ const InMemoryCoercionResult = union(enum) {...@@ -29746,13 +30045,13 @@ const InMemoryCoercionResult = union(enum) {
29746 },30045 },
29747 .fn_return_type => |pair| {30046 .fn_return_type => |pair| {
29748 try sema.errNote(src, msg, "return type '{}' cannot cast into return type '{}'", .{30047 try sema.errNote(src, msg, "return type '{}' cannot cast into return type '{}'", .{
29749 pair.actual.fmt(mod), pair.wanted.fmt(mod),30048 pair.actual.fmt(pt), pair.wanted.fmt(pt),
29750 });30049 });
29751 cur = pair.child;30050 cur = pair.child;
29752 },30051 },
29753 .ptr_child => |pair| {30052 .ptr_child => |pair| {
29754 try sema.errNote(src, msg, "pointer type child '{}' cannot cast into pointer type child '{}'", .{30053 try sema.errNote(src, msg, "pointer type child '{}' cannot cast into pointer type child '{}'", .{
29755 pair.actual.fmt(mod), pair.wanted.fmt(mod),30054 pair.actual.fmt(pt), pair.wanted.fmt(pt),
29756 });30055 });
29757 cur = pair.child;30056 cur = pair.child;
29758 },30057 },
...@@ -29763,11 +30062,11 @@ const InMemoryCoercionResult = union(enum) {...@@ -29763,11 +30062,11 @@ const InMemoryCoercionResult = union(enum) {
29763 .ptr_sentinel => |sentinel| {30062 .ptr_sentinel => |sentinel| {
29764 if (sentinel.actual.toIntern() != .unreachable_value) {30063 if (sentinel.actual.toIntern() != .unreachable_value) {
29765 try sema.errNote(src, msg, "pointer sentinel '{}' cannot cast into pointer sentinel '{}'", .{30064 try sema.errNote(src, msg, "pointer sentinel '{}' cannot cast into pointer sentinel '{}'", .{
29766 sentinel.actual.fmtValue(mod, sema), sentinel.wanted.fmtValue(mod, sema),30065 sentinel.actual.fmtValue(pt, sema), sentinel.wanted.fmtValue(pt, sema),
29767 });30066 });
29768 } else {30067 } else {
29769 try sema.errNote(src, msg, "destination pointer requires '{}' sentinel", .{30068 try sema.errNote(src, msg, "destination pointer requires '{}' sentinel", .{
29770 sentinel.wanted.fmtValue(mod, sema),30069 sentinel.wanted.fmtValue(pt, sema),
29771 });30070 });
29772 }30071 }
29773 break;30072 break;
...@@ -29787,15 +30086,15 @@ const InMemoryCoercionResult = union(enum) {...@@ -29787,15 +30086,15 @@ const InMemoryCoercionResult = union(enum) {
29787 break;30086 break;
29788 },30087 },
29789 .ptr_allowzero => |pair| {30088 .ptr_allowzero => |pair| {
29790 const wanted_allow_zero = pair.wanted.ptrAllowsZero(mod);30089 const wanted_allow_zero = pair.wanted.ptrAllowsZero(pt.zcu);
29791 const actual_allow_zero = pair.actual.ptrAllowsZero(mod);30090 const actual_allow_zero = pair.actual.ptrAllowsZero(pt.zcu);
29792 if (actual_allow_zero and !wanted_allow_zero) {30091 if (actual_allow_zero and !wanted_allow_zero) {
29793 try sema.errNote(src, msg, "'{}' could have null values which are illegal in type '{}'", .{30092 try sema.errNote(src, msg, "'{}' could have null values which are illegal in type '{}'", .{
29794 pair.actual.fmt(mod), pair.wanted.fmt(mod),30093 pair.actual.fmt(pt), pair.wanted.fmt(pt),
29795 });30094 });
29796 } else {30095 } else {
29797 try sema.errNote(src, msg, "mutable '{}' allows illegal null values stored to type '{}'", .{30096 try sema.errNote(src, msg, "mutable '{}' allows illegal null values stored to type '{}'", .{
29798 pair.actual.fmt(mod), pair.wanted.fmt(mod),30097 pair.actual.fmt(pt), pair.wanted.fmt(pt),
29799 });30098 });
29800 }30099 }
29801 break;30100 break;
...@@ -29821,13 +30120,13 @@ const InMemoryCoercionResult = union(enum) {...@@ -29821,13 +30120,13 @@ const InMemoryCoercionResult = union(enum) {
29821 },30120 },
29822 .double_ptr_to_anyopaque => |pair| {30121 .double_ptr_to_anyopaque => |pair| {
29823 try sema.errNote(src, msg, "cannot implicitly cast double pointer '{}' to anyopaque pointer '{}'", .{30122 try sema.errNote(src, msg, "cannot implicitly cast double pointer '{}' to anyopaque pointer '{}'", .{
29824 pair.actual.fmt(mod), pair.wanted.fmt(mod),30123 pair.actual.fmt(pt), pair.wanted.fmt(pt),
29825 });30124 });
29826 break;30125 break;
29827 },30126 },
29828 .slice_to_anyopaque => |pair| {30127 .slice_to_anyopaque => |pair| {
29829 try sema.errNote(src, msg, "cannot implicitly cast slice '{}' to anyopaque pointer '{}'", .{30128 try sema.errNote(src, msg, "cannot implicitly cast slice '{}' to anyopaque pointer '{}'", .{
29830 pair.actual.fmt(mod), pair.wanted.fmt(mod),30129 pair.actual.fmt(pt), pair.wanted.fmt(pt),
29831 });30130 });
29832 try sema.errNote(src, msg, "consider using '.ptr'", .{});30131 try sema.errNote(src, msg, "consider using '.ptr'", .{});
29833 break;30132 break;
...@@ -29864,7 +30163,8 @@ pub fn coerceInMemoryAllowed(...@@ -29864,7 +30163,8 @@ pub fn coerceInMemoryAllowed(
29864 dest_src: LazySrcLoc,30163 dest_src: LazySrcLoc,
29865 src_src: LazySrcLoc,30164 src_src: LazySrcLoc,
29866) CompileError!InMemoryCoercionResult {30165) CompileError!InMemoryCoercionResult {
29867 const mod = sema.mod;30166 const pt = sema.pt;
30167 const mod = pt.zcu;
2986830168
29869 if (dest_ty.eql(src_ty, mod))30169 if (dest_ty.eql(src_ty, mod))
29870 return .ok;30170 return .ok;
...@@ -29968,7 +30268,7 @@ pub fn coerceInMemoryAllowed(...@@ -29968,7 +30268,7 @@ pub fn coerceInMemoryAllowed(
29968 (src_info.sentinel != null and30268 (src_info.sentinel != null and
29969 dest_info.sentinel != null and30269 dest_info.sentinel != null and
29970 dest_info.sentinel.?.eql(30270 dest_info.sentinel.?.eql(
29971 try mod.getCoerced(src_info.sentinel.?, dest_info.elem_type),30271 try pt.getCoerced(src_info.sentinel.?, dest_info.elem_type),
29972 dest_info.elem_type,30272 dest_info.elem_type,
29973 mod,30273 mod,
29974 ));30274 ));
...@@ -30045,8 +30345,8 @@ pub fn coerceInMemoryAllowed(...@@ -30045,8 +30345,8 @@ pub fn coerceInMemoryAllowed(
30045 // The memory layout of @Vector(N, iM) is the same as the integer type i(N*M),30345 // The memory layout of @Vector(N, iM) is the same as the integer type i(N*M),
30046 // that is to say, the padding bits are not in the same place as the array [N]iM.30346 // that is to say, the padding bits are not in the same place as the array [N]iM.
30047 // If there's no padding, the bitcast is possible.30347 // If there's no padding, the bitcast is possible.
30048 const elem_bit_size = dest_elem_ty.bitSize(mod);30348 const elem_bit_size = dest_elem_ty.bitSize(pt);
30049 const elem_abi_byte_size = dest_elem_ty.abiSize(mod);30349 const elem_abi_byte_size = dest_elem_ty.abiSize(pt);
30050 if (elem_abi_byte_size * 8 == elem_bit_size)30350 if (elem_abi_byte_size * 8 == elem_bit_size)
30051 return .ok;30351 return .ok;
30052 }30352 }
...@@ -30081,7 +30381,7 @@ pub fn coerceInMemoryAllowed(...@@ -30081,7 +30381,7 @@ pub fn coerceInMemoryAllowed(
30081 const field_count = dest_ty.structFieldCount(mod);30381 const field_count = dest_ty.structFieldCount(mod);
30082 for (0..field_count) |field_idx| {30382 for (0..field_count) |field_idx| {
30083 if (dest_ty.structFieldIsComptime(field_idx, mod) != src_ty.structFieldIsComptime(field_idx, mod)) break :tuple;30383 if (dest_ty.structFieldIsComptime(field_idx, mod) != src_ty.structFieldIsComptime(field_idx, mod)) break :tuple;
30084 if (dest_ty.structFieldAlign(field_idx, mod) != src_ty.structFieldAlign(field_idx, mod)) break :tuple;30384 if (dest_ty.structFieldAlign(field_idx, pt) != src_ty.structFieldAlign(field_idx, pt)) break :tuple;
30085 const dest_field_ty = dest_ty.structFieldType(field_idx, mod);30385 const dest_field_ty = dest_ty.structFieldType(field_idx, mod);
30086 const src_field_ty = src_ty.structFieldType(field_idx, mod);30386 const src_field_ty = src_ty.structFieldType(field_idx, mod);
30087 const field = try sema.coerceInMemoryAllowed(block, dest_field_ty, src_field_ty, dest_is_mut, target, dest_src, src_src);30387 const field = try sema.coerceInMemoryAllowed(block, dest_field_ty, src_field_ty, dest_is_mut, target, dest_src, src_src);
...@@ -30104,7 +30404,8 @@ fn coerceInMemoryAllowedErrorSets(...@@ -30104,7 +30404,8 @@ fn coerceInMemoryAllowedErrorSets(
30104 dest_src: LazySrcLoc,30404 dest_src: LazySrcLoc,
30105 src_src: LazySrcLoc,30405 src_src: LazySrcLoc,
30106) !InMemoryCoercionResult {30406) !InMemoryCoercionResult {
30107 const mod = sema.mod;30407 const pt = sema.pt;
30408 const mod = pt.zcu;
30108 const gpa = sema.gpa;30409 const gpa = sema.gpa;
30109 const ip = &mod.intern_pool;30410 const ip = &mod.intern_pool;
3011030411
...@@ -30202,7 +30503,8 @@ fn coerceInMemoryAllowedFns(...@@ -30202,7 +30503,8 @@ fn coerceInMemoryAllowedFns(
30202 dest_src: LazySrcLoc,30503 dest_src: LazySrcLoc,
30203 src_src: LazySrcLoc,30504 src_src: LazySrcLoc,
30204) !InMemoryCoercionResult {30505) !InMemoryCoercionResult {
30205 const mod = sema.mod;30506 const pt = sema.pt;
30507 const mod = pt.zcu;
30206 const ip = &mod.intern_pool;30508 const ip = &mod.intern_pool;
3020730509
30208 const dest_info = mod.typeToFunc(dest_ty).?;30510 const dest_info = mod.typeToFunc(dest_ty).?;
...@@ -30303,7 +30605,8 @@ fn coerceInMemoryAllowedPtrs(...@@ -30303,7 +30605,8 @@ fn coerceInMemoryAllowedPtrs(
30303 dest_src: LazySrcLoc,30605 dest_src: LazySrcLoc,
30304 src_src: LazySrcLoc,30606 src_src: LazySrcLoc,
30305) !InMemoryCoercionResult {30607) !InMemoryCoercionResult {
30306 const zcu = sema.mod;30608 const pt = sema.pt;
30609 const zcu = pt.zcu;
30307 const dest_info = dest_ptr_ty.ptrInfo(zcu);30610 const dest_info = dest_ptr_ty.ptrInfo(zcu);
30308 const src_info = src_ptr_ty.ptrInfo(zcu);30611 const src_info = src_ptr_ty.ptrInfo(zcu);
3030930612
...@@ -30381,7 +30684,7 @@ fn coerceInMemoryAllowedPtrs(...@@ -30381,7 +30684,7 @@ fn coerceInMemoryAllowedPtrs(
3038130684
30382 const ok_sent = dest_info.sentinel == .none or src_info.flags.size == .C or30685 const ok_sent = dest_info.sentinel == .none or src_info.flags.size == .C or
30383 (src_info.sentinel != .none and30686 (src_info.sentinel != .none and
30384 dest_info.sentinel == try zcu.intern_pool.getCoerced(sema.gpa, src_info.sentinel, dest_info.child));30687 dest_info.sentinel == try zcu.intern_pool.getCoerced(sema.gpa, pt.tid, src_info.sentinel, dest_info.child));
30385 if (!ok_sent) {30688 if (!ok_sent) {
30386 return InMemoryCoercionResult{ .ptr_sentinel = .{30689 return InMemoryCoercionResult{ .ptr_sentinel = .{
30387 .actual = switch (src_info.sentinel) {30690 .actual = switch (src_info.sentinel) {
...@@ -30432,7 +30735,8 @@ fn coerceVarArgParam(...@@ -30432,7 +30735,8 @@ fn coerceVarArgParam(
30432) !Air.Inst.Ref {30735) !Air.Inst.Ref {
30433 if (block.is_typeof) return inst;30736 if (block.is_typeof) return inst;
3043430737
30435 const mod = sema.mod;30738 const pt = sema.pt;
30739 const mod = pt.zcu;
30436 const uncasted_ty = sema.typeOf(inst);30740 const uncasted_ty = sema.typeOf(inst);
30437 const coerced = switch (uncasted_ty.zigTypeTag(mod)) {30741 const coerced = switch (uncasted_ty.zigTypeTag(mod)) {
30438 // TODO consider casting to c_int/f64 if they fit30742 // TODO consider casting to c_int/f64 if they fit
...@@ -30449,9 +30753,9 @@ fn coerceVarArgParam(...@@ -30449,9 +30753,9 @@ fn coerceVarArgParam(
30449 },30753 },
30450 .Array => return sema.fail(block, inst_src, "arrays must be passed by reference to variadic function", .{}),30754 .Array => return sema.fail(block, inst_src, "arrays must be passed by reference to variadic function", .{}),
30451 .Float => float: {30755 .Float => float: {
30452 const target = sema.mod.getTarget();30756 const target = mod.getTarget();
30453 const double_bits = target.c_type_bit_size(.double);30757 const double_bits = target.c_type_bit_size(.double);
30454 const inst_bits = uncasted_ty.floatBits(sema.mod.getTarget());30758 const inst_bits = uncasted_ty.floatBits(target);
30455 if (inst_bits >= double_bits) break :float inst;30759 if (inst_bits >= double_bits) break :float inst;
30456 switch (double_bits) {30760 switch (double_bits) {
30457 32 => break :float try sema.coerce(block, Type.f32, inst, inst_src),30761 32 => break :float try sema.coerce(block, Type.f32, inst, inst_src),
...@@ -30461,7 +30765,7 @@ fn coerceVarArgParam(...@@ -30461,7 +30765,7 @@ fn coerceVarArgParam(
30461 },30765 },
30462 else => if (uncasted_ty.isAbiInt(mod)) int: {30766 else => if (uncasted_ty.isAbiInt(mod)) int: {
30463 if (!try sema.validateExternType(uncasted_ty, .param_ty)) break :int inst;30767 if (!try sema.validateExternType(uncasted_ty, .param_ty)) break :int inst;
30464 const target = sema.mod.getTarget();30768 const target = mod.getTarget();
30465 const uncasted_info = uncasted_ty.intInfo(mod);30769 const uncasted_info = uncasted_ty.intInfo(mod);
30466 if (uncasted_info.bits <= target.c_type_bit_size(switch (uncasted_info.signedness) {30770 if (uncasted_info.bits <= target.c_type_bit_size(switch (uncasted_info.signedness) {
30467 .signed => .int,30771 .signed => .int,
...@@ -30491,7 +30795,7 @@ fn coerceVarArgParam(...@@ -30491,7 +30795,7 @@ fn coerceVarArgParam(
30491 const coerced_ty = sema.typeOf(coerced);30795 const coerced_ty = sema.typeOf(coerced);
30492 if (!try sema.validateExternType(coerced_ty, .param_ty)) {30796 if (!try sema.validateExternType(coerced_ty, .param_ty)) {
30493 const msg = msg: {30797 const msg = msg: {
30494 const msg = try sema.errMsg(inst_src, "cannot pass '{}' to variadic function", .{coerced_ty.fmt(sema.mod)});30798 const msg = try sema.errMsg(inst_src, "cannot pass '{}' to variadic function", .{coerced_ty.fmt(pt)});
30495 errdefer msg.destroy(sema.gpa);30799 errdefer msg.destroy(sema.gpa);
3049630800
30497 try sema.explainWhyTypeIsNotExtern(msg, inst_src, coerced_ty, .param_ty);30801 try sema.explainWhyTypeIsNotExtern(msg, inst_src, coerced_ty, .param_ty);
...@@ -30526,7 +30830,8 @@ fn storePtr2(...@@ -30526,7 +30830,8 @@ fn storePtr2(
30526 operand_src: LazySrcLoc,30830 operand_src: LazySrcLoc,
30527 air_tag: Air.Inst.Tag,30831 air_tag: Air.Inst.Tag,
30528) CompileError!void {30832) CompileError!void {
30529 const mod = sema.mod;30833 const pt = sema.pt;
30834 const mod = pt.zcu;
30530 const ptr_ty = sema.typeOf(ptr);30835 const ptr_ty = sema.typeOf(ptr);
30531 if (ptr_ty.isConstPtr(mod))30836 if (ptr_ty.isConstPtr(mod))
30532 return sema.fail(block, ptr_src, "cannot assign to constant", .{});30837 return sema.fail(block, ptr_src, "cannot assign to constant", .{});
...@@ -30548,7 +30853,7 @@ fn storePtr2(...@@ -30548,7 +30853,7 @@ fn storePtr2(
30548 while (i < field_count) : (i += 1) {30853 while (i < field_count) : (i += 1) {
30549 const elem_src = operand_src; // TODO better source location30854 const elem_src = operand_src; // TODO better source location
30550 const elem = try sema.tupleField(block, operand_src, uncasted_operand, elem_src, i);30855 const elem = try sema.tupleField(block, operand_src, uncasted_operand, elem_src, i);
30551 const elem_index = try mod.intRef(Type.usize, i);30856 const elem_index = try pt.intRef(Type.usize, i);
30552 const elem_ptr = try sema.elemPtr(block, ptr_src, ptr, elem_index, elem_src, false, true);30857 const elem_ptr = try sema.elemPtr(block, ptr_src, ptr, elem_index, elem_src, false, true);
30553 try sema.storePtr2(block, src, elem_ptr, elem_src, elem, elem_src, .store);30858 try sema.storePtr2(block, src, elem_ptr, elem_src, elem, elem_src, .store);
30554 }30859 }
...@@ -30620,7 +30925,7 @@ fn storePtr2(...@@ -30620,7 +30925,7 @@ fn storePtr2(
30620 return;30925 return;
30621 }30926 }
30622 return sema.fail(block, ptr_src, "unable to determine vector element index of type '{}'", .{30927 return sema.fail(block, ptr_src, "unable to determine vector element index of type '{}'", .{
30623 ptr_ty.fmt(sema.mod),30928 ptr_ty.fmt(pt),
30624 });30929 });
30625 }30930 }
3062630931
...@@ -30734,7 +31039,8 @@ fn markMaybeComptimeAllocRuntime(sema: *Sema, block: *Block, alloc_inst: Air.Ins...@@ -30734,7 +31039,8 @@ fn markMaybeComptimeAllocRuntime(sema: *Sema, block: *Block, alloc_inst: Air.Ins
30734/// pointer. Only if the final element type matches the vector element type, and the31039/// pointer. Only if the final element type matches the vector element type, and the
30735/// lengths match.31040/// lengths match.
30736fn obtainBitCastedVectorPtr(sema: *Sema, ptr: Air.Inst.Ref) ?Air.Inst.Ref {31041fn obtainBitCastedVectorPtr(sema: *Sema, ptr: Air.Inst.Ref) ?Air.Inst.Ref {
30737 const mod = sema.mod;31042 const pt = sema.pt;
31043 const mod = pt.zcu;
30738 const array_ty = sema.typeOf(ptr).childType(mod);31044 const array_ty = sema.typeOf(ptr).childType(mod);
30739 if (array_ty.zigTypeTag(mod) != .Array) return null;31045 if (array_ty.zigTypeTag(mod) != .Array) return null;
30740 var ptr_ref = ptr;31046 var ptr_ref = ptr;
...@@ -30751,7 +31057,7 @@ fn obtainBitCastedVectorPtr(sema: *Sema, ptr: Air.Inst.Ref) ?Air.Inst.Ref {...@@ -30751,7 +31057,7 @@ fn obtainBitCastedVectorPtr(sema: *Sema, ptr: Air.Inst.Ref) ?Air.Inst.Ref {
3075131057
30752 // We have a pointer-to-array and a pointer-to-vector. If the elements and31058 // We have a pointer-to-array and a pointer-to-vector. If the elements and
30753 // lengths match, return the result.31059 // lengths match, return the result.
30754 if (array_ty.childType(mod).eql(vector_ty.childType(mod), sema.mod) and31060 if (array_ty.childType(mod).eql(vector_ty.childType(mod), mod) and
30755 array_ty.arrayLen(mod) == vector_ty.vectorLen(mod))31061 array_ty.arrayLen(mod) == vector_ty.vectorLen(mod))
30756 {31062 {
30757 return ptr_ref;31063 return ptr_ref;
...@@ -30770,17 +31076,18 @@ fn storePtrVal(...@@ -30770,17 +31076,18 @@ fn storePtrVal(
30770 operand_val: Value,31076 operand_val: Value,
30771 operand_ty: Type,31077 operand_ty: Type,
30772) !void {31078) !void {
30773 const zcu = sema.mod;31079 const pt = sema.pt;
31080 const zcu = pt.zcu;
30774 const ip = &zcu.intern_pool;31081 const ip = &zcu.intern_pool;
30775 // TODO: audit use sites to eliminate this coercion31082 // TODO: audit use sites to eliminate this coercion
30776 const coerced_operand_val = try zcu.getCoerced(operand_val, operand_ty);31083 const coerced_operand_val = try pt.getCoerced(operand_val, operand_ty);
30777 // TODO: audit use sites to eliminate this coercion31084 // TODO: audit use sites to eliminate this coercion
30778 const ptr_ty = try zcu.ptrType(info: {31085 const ptr_ty = try pt.ptrType(info: {
30779 var info = ptr_val.typeOf(zcu).ptrInfo(zcu);31086 var info = ptr_val.typeOf(zcu).ptrInfo(zcu);
30780 info.child = operand_ty.toIntern();31087 info.child = operand_ty.toIntern();
30781 break :info info;31088 break :info info;
30782 });31089 });
30783 const coerced_ptr_val = try zcu.getCoerced(ptr_val, ptr_ty);31090 const coerced_ptr_val = try pt.getCoerced(ptr_val, ptr_ty);
3078431091
30785 switch (try sema.storeComptimePtr(block, src, coerced_ptr_val, coerced_operand_val)) {31092 switch (try sema.storeComptimePtr(block, src, coerced_ptr_val, coerced_operand_val)) {
30786 .success => {},31093 .success => {},
...@@ -30800,13 +31107,13 @@ fn storePtrVal(...@@ -30800,13 +31107,13 @@ fn storePtrVal(
30800 block,31107 block,
30801 src,31108 src,
30802 "comptime dereference requires '{}' to have a well-defined layout",31109 "comptime dereference requires '{}' to have a well-defined layout",
30803 .{ty.fmt(zcu)},31110 .{ty.fmt(pt)},
30804 ),31111 ),
30805 .out_of_bounds => |ty| return sema.fail(31112 .out_of_bounds => |ty| return sema.fail(
30806 block,31113 block,
30807 src,31114 src,
30808 "dereference of '{}' exceeds bounds of containing decl of type '{}'",31115 "dereference of '{}' exceeds bounds of containing decl of type '{}'",
30809 .{ ptr_ty.fmt(zcu), ty.fmt(zcu) },31116 .{ ptr_ty.fmt(pt), ty.fmt(pt) },
30810 ),31117 ),
30811 .exceeds_host_size => return sema.fail(block, src, "bit-pointer target exceeds host size", .{}),31118 .exceeds_host_size => return sema.fail(block, src, "bit-pointer target exceeds host size", .{}),
30812 }31119 }
...@@ -30820,31 +31127,32 @@ fn bitCast(...@@ -30820,31 +31127,32 @@ fn bitCast(
30820 inst_src: LazySrcLoc,31127 inst_src: LazySrcLoc,
30821 operand_src: ?LazySrcLoc,31128 operand_src: ?LazySrcLoc,
30822) CompileError!Air.Inst.Ref {31129) CompileError!Air.Inst.Ref {
30823 const zcu = sema.mod;31130 const pt = sema.pt;
30824 try dest_ty.resolveLayout(zcu);31131 const zcu = pt.zcu;
31132 try dest_ty.resolveLayout(pt);
3082531133
30826 const old_ty = sema.typeOf(inst);31134 const old_ty = sema.typeOf(inst);
30827 try old_ty.resolveLayout(zcu);31135 try old_ty.resolveLayout(pt);
3082831136
30829 const dest_bits = dest_ty.bitSize(zcu);31137 const dest_bits = dest_ty.bitSize(pt);
30830 const old_bits = old_ty.bitSize(zcu);31138 const old_bits = old_ty.bitSize(pt);
3083131139
30832 if (old_bits != dest_bits) {31140 if (old_bits != dest_bits) {
30833 return sema.fail(block, inst_src, "@bitCast size mismatch: destination type '{}' has {d} bits but source type '{}' has {d} bits", .{31141 return sema.fail(block, inst_src, "@bitCast size mismatch: destination type '{}' has {d} bits but source type '{}' has {d} bits", .{
30834 dest_ty.fmt(zcu),31142 dest_ty.fmt(pt),
30835 dest_bits,31143 dest_bits,
30836 old_ty.fmt(zcu),31144 old_ty.fmt(pt),
30837 old_bits,31145 old_bits,
30838 });31146 });
30839 }31147 }
3084031148
30841 if (try sema.resolveValue(inst)) |val| {31149 if (try sema.resolveValue(inst)) |val| {
30842 if (val.isUndef(zcu))31150 if (val.isUndef(zcu))
30843 return zcu.undefRef(dest_ty);31151 return pt.undefRef(dest_ty);
30844 if (old_ty.zigTypeTag(zcu) == .ErrorSet and dest_ty.zigTypeTag(zcu) == .ErrorSet) {31152 if (old_ty.zigTypeTag(zcu) == .ErrorSet and dest_ty.zigTypeTag(zcu) == .ErrorSet) {
30845 // Special case: we sometimes call `bitCast` on error set values, but they31153 // Special case: we sometimes call `bitCast` on error set values, but they
30846 // don't have a well-defined layout, so we can't use `bitCastVal` on them.31154 // don't have a well-defined layout, so we can't use `bitCastVal` on them.
30847 return Air.internedToRef((try zcu.getCoerced(val, dest_ty)).toIntern());31155 return Air.internedToRef((try pt.getCoerced(val, dest_ty)).toIntern());
30848 }31156 }
30849 if (try sema.bitCastVal(val, dest_ty, 0, 0, 0)) |result_val| {31157 if (try sema.bitCastVal(val, dest_ty, 0, 0, 0)) |result_val| {
30850 return Air.internedToRef(result_val.toIntern());31158 return Air.internedToRef(result_val.toIntern());
...@@ -30862,16 +31170,17 @@ fn coerceArrayPtrToSlice(...@@ -30862,16 +31170,17 @@ fn coerceArrayPtrToSlice(
30862 inst: Air.Inst.Ref,31170 inst: Air.Inst.Ref,
30863 inst_src: LazySrcLoc,31171 inst_src: LazySrcLoc,
30864) CompileError!Air.Inst.Ref {31172) CompileError!Air.Inst.Ref {
30865 const mod = sema.mod;31173 const pt = sema.pt;
31174 const mod = pt.zcu;
30866 if (try sema.resolveValue(inst)) |val| {31175 if (try sema.resolveValue(inst)) |val| {
30867 const ptr_array_ty = sema.typeOf(inst);31176 const ptr_array_ty = sema.typeOf(inst);
30868 const array_ty = ptr_array_ty.childType(mod);31177 const array_ty = ptr_array_ty.childType(mod);
30869 const slice_ptr_ty = dest_ty.slicePtrFieldType(mod);31178 const slice_ptr_ty = dest_ty.slicePtrFieldType(mod);
30870 const slice_ptr = try mod.getCoerced(val, slice_ptr_ty);31179 const slice_ptr = try pt.getCoerced(val, slice_ptr_ty);
30871 const slice_val = try mod.intern(.{ .slice = .{31180 const slice_val = try pt.intern(.{ .slice = .{
30872 .ty = dest_ty.toIntern(),31181 .ty = dest_ty.toIntern(),
30873 .ptr = slice_ptr.toIntern(),31182 .ptr = slice_ptr.toIntern(),
30874 .len = (try mod.intValue(Type.usize, array_ty.arrayLen(mod))).toIntern(),31183 .len = (try pt.intValue(Type.usize, array_ty.arrayLen(mod))).toIntern(),
30875 } });31184 } });
30876 return Air.internedToRef(slice_val);31185 return Air.internedToRef(slice_val);
30877 }31186 }
...@@ -30880,7 +31189,8 @@ fn coerceArrayPtrToSlice(...@@ -30880,7 +31189,8 @@ fn coerceArrayPtrToSlice(
30880}31189}
3088131190
30882fn checkPtrAttributes(sema: *Sema, dest_ty: Type, inst_ty: Type, in_memory_result: *InMemoryCoercionResult) bool {31191fn checkPtrAttributes(sema: *Sema, dest_ty: Type, inst_ty: Type, in_memory_result: *InMemoryCoercionResult) bool {
30883 const mod = sema.mod;31192 const pt = sema.pt;
31193 const mod = pt.zcu;
30884 const dest_info = dest_ty.ptrInfo(mod);31194 const dest_info = dest_ty.ptrInfo(mod);
30885 const inst_info = inst_ty.ptrInfo(mod);31195 const inst_info = inst_ty.ptrInfo(mod);
30886 const len0 = (Type.fromInterned(inst_info.child).zigTypeTag(mod) == .Array and (Type.fromInterned(inst_info.child).arrayLenIncludingSentinel(mod) == 0 or31196 const len0 = (Type.fromInterned(inst_info.child).zigTypeTag(mod) == .Array and (Type.fromInterned(inst_info.child).arrayLenIncludingSentinel(mod) == 0 or
...@@ -30913,12 +31223,12 @@ fn checkPtrAttributes(sema: *Sema, dest_ty: Type, inst_ty: Type, in_memory_resul...@@ -30913,12 +31223,12 @@ fn checkPtrAttributes(sema: *Sema, dest_ty: Type, inst_ty: Type, in_memory_resul
30913 const inst_align = if (inst_info.flags.alignment != .none)31223 const inst_align = if (inst_info.flags.alignment != .none)
30914 inst_info.flags.alignment31224 inst_info.flags.alignment
30915 else31225 else
30916 Type.fromInterned(inst_info.child).abiAlignment(mod);31226 Type.fromInterned(inst_info.child).abiAlignment(pt);
3091731227
30918 const dest_align = if (dest_info.flags.alignment != .none)31228 const dest_align = if (dest_info.flags.alignment != .none)
30919 dest_info.flags.alignment31229 dest_info.flags.alignment
30920 else31230 else
30921 Type.fromInterned(dest_info.child).abiAlignment(mod);31231 Type.fromInterned(dest_info.child).abiAlignment(pt);
3092231232
30923 if (dest_align.compare(.gt, inst_align)) {31233 if (dest_align.compare(.gt, inst_align)) {
30924 in_memory_result.* = .{ .ptr_alignment = .{31234 in_memory_result.* = .{ .ptr_alignment = .{
...@@ -30937,15 +31247,16 @@ fn coerceCompatiblePtrs(...@@ -30937,15 +31247,16 @@ fn coerceCompatiblePtrs(
30937 inst: Air.Inst.Ref,31247 inst: Air.Inst.Ref,
30938 inst_src: LazySrcLoc,31248 inst_src: LazySrcLoc,
30939) !Air.Inst.Ref {31249) !Air.Inst.Ref {
30940 const mod = sema.mod;31250 const pt = sema.pt;
31251 const mod = pt.zcu;
30941 const inst_ty = sema.typeOf(inst);31252 const inst_ty = sema.typeOf(inst);
30942 if (try sema.resolveValue(inst)) |val| {31253 if (try sema.resolveValue(inst)) |val| {
30943 if (!val.isUndef(mod) and val.isNull(mod) and !dest_ty.isAllowzeroPtr(mod)) {31254 if (!val.isUndef(mod) and val.isNull(mod) and !dest_ty.isAllowzeroPtr(mod)) {
30944 return sema.fail(block, inst_src, "null pointer casted to type '{}'", .{dest_ty.fmt(sema.mod)});31255 return sema.fail(block, inst_src, "null pointer casted to type '{}'", .{dest_ty.fmt(pt)});
30945 }31256 }
30946 // The comptime Value representation is compatible with both types.31257 // The comptime Value representation is compatible with both types.
30947 return Air.internedToRef(31258 return Air.internedToRef(
30948 (try mod.getCoerced(val, dest_ty)).toIntern(),31259 (try pt.getCoerced(val, dest_ty)).toIntern(),
30949 );31260 );
30950 }31261 }
30951 try sema.requireRuntimeBlock(block, inst_src, null);31262 try sema.requireRuntimeBlock(block, inst_src, null);
...@@ -30979,14 +31290,15 @@ fn coerceEnumToUnion(...@@ -30979,14 +31290,15 @@ fn coerceEnumToUnion(
30979 inst: Air.Inst.Ref,31290 inst: Air.Inst.Ref,
30980 inst_src: LazySrcLoc,31291 inst_src: LazySrcLoc,
30981) !Air.Inst.Ref {31292) !Air.Inst.Ref {
30982 const mod = sema.mod;31293 const pt = sema.pt;
31294 const mod = pt.zcu;
30983 const ip = &mod.intern_pool;31295 const ip = &mod.intern_pool;
30984 const inst_ty = sema.typeOf(inst);31296 const inst_ty = sema.typeOf(inst);
3098531297
30986 const tag_ty = union_ty.unionTagType(mod) orelse {31298 const tag_ty = union_ty.unionTagType(mod) orelse {
30987 const msg = msg: {31299 const msg = msg: {
30988 const msg = try sema.errMsg(inst_src, "expected type '{}', found '{}'", .{31300 const msg = try sema.errMsg(inst_src, "expected type '{}', found '{}'", .{
30989 union_ty.fmt(sema.mod), inst_ty.fmt(sema.mod),31301 union_ty.fmt(pt), inst_ty.fmt(pt),
30990 });31302 });
30991 errdefer msg.destroy(sema.gpa);31303 errdefer msg.destroy(sema.gpa);
30992 try sema.errNote(union_ty_src, msg, "cannot coerce enum to untagged union", .{});31304 try sema.errNote(union_ty_src, msg, "cannot coerce enum to untagged union", .{});
...@@ -30998,15 +31310,15 @@ fn coerceEnumToUnion(...@@ -30998,15 +31310,15 @@ fn coerceEnumToUnion(
3099831310
30999 const enum_tag = try sema.coerce(block, tag_ty, inst, inst_src);31311 const enum_tag = try sema.coerce(block, tag_ty, inst, inst_src);
31000 if (try sema.resolveDefinedValue(block, inst_src, enum_tag)) |val| {31312 if (try sema.resolveDefinedValue(block, inst_src, enum_tag)) |val| {
31001 const field_index = union_ty.unionTagFieldIndex(val, sema.mod) orelse {31313 const field_index = union_ty.unionTagFieldIndex(val, pt.zcu) orelse {
31002 return sema.fail(block, inst_src, "union '{}' has no tag with value '{}'", .{31314 return sema.fail(block, inst_src, "union '{}' has no tag with value '{}'", .{
31003 union_ty.fmt(sema.mod), val.fmtValue(sema.mod, sema),31315 union_ty.fmt(pt), val.fmtValue(pt, sema),
31004 });31316 });
31005 };31317 };
3100631318
31007 const union_obj = mod.typeToUnion(union_ty).?;31319 const union_obj = mod.typeToUnion(union_ty).?;
31008 const field_ty = Type.fromInterned(union_obj.field_types.get(ip)[field_index]);31320 const field_ty = Type.fromInterned(union_obj.field_types.get(ip)[field_index]);
31009 try field_ty.resolveFields(mod);31321 try field_ty.resolveFields(pt);
31010 if (field_ty.zigTypeTag(mod) == .NoReturn) {31322 if (field_ty.zigTypeTag(mod) == .NoReturn) {
31011 const msg = msg: {31323 const msg = msg: {
31012 const msg = try sema.errMsg(inst_src, "cannot initialize 'noreturn' field of union", .{});31324 const msg = try sema.errMsg(inst_src, "cannot initialize 'noreturn' field of union", .{});
...@@ -31025,8 +31337,8 @@ fn coerceEnumToUnion(...@@ -31025,8 +31337,8 @@ fn coerceEnumToUnion(
31025 const msg = msg: {31337 const msg = msg: {
31026 const field_name = union_obj.loadTagType(ip).names.get(ip)[field_index];31338 const field_name = union_obj.loadTagType(ip).names.get(ip)[field_index];
31027 const msg = try sema.errMsg(inst_src, "coercion from enum '{}' to union '{}' must initialize '{}' field '{}'", .{31339 const msg = try sema.errMsg(inst_src, "coercion from enum '{}' to union '{}' must initialize '{}' field '{}'", .{
31028 inst_ty.fmt(sema.mod), union_ty.fmt(sema.mod),31340 inst_ty.fmt(pt), union_ty.fmt(pt),
31029 field_ty.fmt(sema.mod), field_name.fmt(ip),31341 field_ty.fmt(pt), field_name.fmt(ip),
31030 });31342 });
31031 errdefer msg.destroy(sema.gpa);31343 errdefer msg.destroy(sema.gpa);
3103231344
...@@ -31039,7 +31351,7 @@ fn coerceEnumToUnion(...@@ -31039,7 +31351,7 @@ fn coerceEnumToUnion(
31039 return sema.failWithOwnedErrorMsg(block, msg);31351 return sema.failWithOwnedErrorMsg(block, msg);
31040 };31352 };
3104131353
31042 return Air.internedToRef((try mod.unionValue(union_ty, val, opv)).toIntern());31354 return Air.internedToRef((try pt.unionValue(union_ty, val, opv)).toIntern());
31043 }31355 }
3104431356
31045 try sema.requireRuntimeBlock(block, inst_src, null);31357 try sema.requireRuntimeBlock(block, inst_src, null);
...@@ -31047,7 +31359,7 @@ fn coerceEnumToUnion(...@@ -31047,7 +31359,7 @@ fn coerceEnumToUnion(
31047 if (tag_ty.isNonexhaustiveEnum(mod)) {31359 if (tag_ty.isNonexhaustiveEnum(mod)) {
31048 const msg = msg: {31360 const msg = msg: {
31049 const msg = try sema.errMsg(inst_src, "runtime coercion to union '{}' from non-exhaustive enum", .{31361 const msg = try sema.errMsg(inst_src, "runtime coercion to union '{}' from non-exhaustive enum", .{
31050 union_ty.fmt(sema.mod),31362 union_ty.fmt(pt),
31051 });31363 });
31052 errdefer msg.destroy(sema.gpa);31364 errdefer msg.destroy(sema.gpa);
31053 try sema.addDeclaredHereNote(msg, tag_ty);31365 try sema.addDeclaredHereNote(msg, tag_ty);
...@@ -31066,7 +31378,7 @@ fn coerceEnumToUnion(...@@ -31066,7 +31378,7 @@ fn coerceEnumToUnion(
31066 const err_msg = msg orelse try sema.errMsg(31378 const err_msg = msg orelse try sema.errMsg(
31067 inst_src,31379 inst_src,
31068 "runtime coercion from enum '{}' to union '{}' which has a 'noreturn' field",31380 "runtime coercion from enum '{}' to union '{}' which has a 'noreturn' field",
31069 .{ tag_ty.fmt(sema.mod), union_ty.fmt(sema.mod) },31381 .{ tag_ty.fmt(pt), union_ty.fmt(pt) },
31070 );31382 );
31071 msg = err_msg;31383 msg = err_msg;
3107231384
...@@ -31081,7 +31393,7 @@ fn coerceEnumToUnion(...@@ -31081,7 +31393,7 @@ fn coerceEnumToUnion(
31081 }31393 }
3108231394
31083 // If the union has all fields 0 bits, the union value is just the enum value.31395 // If the union has all fields 0 bits, the union value is just the enum value.
31084 if (union_ty.unionHasAllZeroBitFieldTypes(mod)) {31396 if (union_ty.unionHasAllZeroBitFieldTypes(pt)) {
31085 return block.addBitCast(union_ty, enum_tag);31397 return block.addBitCast(union_ty, enum_tag);
31086 }31398 }
3108731399
...@@ -31089,7 +31401,7 @@ fn coerceEnumToUnion(...@@ -31089,7 +31401,7 @@ fn coerceEnumToUnion(
31089 const msg = try sema.errMsg(31401 const msg = try sema.errMsg(
31090 inst_src,31402 inst_src,
31091 "runtime coercion from enum '{}' to union '{}' which has non-void fields",31403 "runtime coercion from enum '{}' to union '{}' which has non-void fields",
31092 .{ tag_ty.fmt(sema.mod), union_ty.fmt(sema.mod) },31404 .{ tag_ty.fmt(pt), union_ty.fmt(pt) },
31093 );31405 );
31094 errdefer msg.destroy(sema.gpa);31406 errdefer msg.destroy(sema.gpa);
3109531407
...@@ -31099,7 +31411,7 @@ fn coerceEnumToUnion(...@@ -31099,7 +31411,7 @@ fn coerceEnumToUnion(
31099 if (!(try sema.typeHasRuntimeBits(field_ty))) continue;31411 if (!(try sema.typeHasRuntimeBits(field_ty))) continue;
31100 try sema.addFieldErrNote(union_ty, field_index, msg, "field '{}' has type '{}'", .{31412 try sema.addFieldErrNote(union_ty, field_index, msg, "field '{}' has type '{}'", .{
31101 field_name.fmt(ip),31413 field_name.fmt(ip),
31102 field_ty.fmt(sema.mod),31414 field_ty.fmt(pt),
31103 });31415 });
31104 }31416 }
31105 try sema.addDeclaredHereNote(msg, union_ty);31417 try sema.addDeclaredHereNote(msg, union_ty);
...@@ -31116,7 +31428,8 @@ fn coerceAnonStructToUnion(...@@ -31116,7 +31428,8 @@ fn coerceAnonStructToUnion(
31116 inst: Air.Inst.Ref,31428 inst: Air.Inst.Ref,
31117 inst_src: LazySrcLoc,31429 inst_src: LazySrcLoc,
31118) !Air.Inst.Ref {31430) !Air.Inst.Ref {
31119 const mod = sema.mod;31431 const pt = sema.pt;
31432 const mod = pt.zcu;
31120 const ip = &mod.intern_pool;31433 const ip = &mod.intern_pool;
31121 const inst_ty = sema.typeOf(inst);31434 const inst_ty = sema.typeOf(inst);
31122 const field_info: union(enum) {31435 const field_info: union(enum) {
...@@ -31174,7 +31487,8 @@ fn coerceAnonStructToUnionPtrs(...@@ -31174,7 +31487,8 @@ fn coerceAnonStructToUnionPtrs(
31174 ptr_anon_struct: Air.Inst.Ref,31487 ptr_anon_struct: Air.Inst.Ref,
31175 anon_struct_src: LazySrcLoc,31488 anon_struct_src: LazySrcLoc,
31176) !Air.Inst.Ref {31489) !Air.Inst.Ref {
31177 const mod = sema.mod;31490 const pt = sema.pt;
31491 const mod = pt.zcu;
31178 const union_ty = ptr_union_ty.childType(mod);31492 const union_ty = ptr_union_ty.childType(mod);
31179 const anon_struct = try sema.analyzeLoad(block, anon_struct_src, ptr_anon_struct, anon_struct_src);31493 const anon_struct = try sema.analyzeLoad(block, anon_struct_src, ptr_anon_struct, anon_struct_src);
31180 const union_inst = try sema.coerceAnonStructToUnion(block, union_ty, union_ty_src, anon_struct, anon_struct_src);31494 const union_inst = try sema.coerceAnonStructToUnion(block, union_ty, union_ty_src, anon_struct, anon_struct_src);
...@@ -31189,7 +31503,8 @@ fn coerceAnonStructToStructPtrs(...@@ -31189,7 +31503,8 @@ fn coerceAnonStructToStructPtrs(
31189 ptr_anon_struct: Air.Inst.Ref,31503 ptr_anon_struct: Air.Inst.Ref,
31190 anon_struct_src: LazySrcLoc,31504 anon_struct_src: LazySrcLoc,
31191) !Air.Inst.Ref {31505) !Air.Inst.Ref {
31192 const mod = sema.mod;31506 const pt = sema.pt;
31507 const mod = pt.zcu;
31193 const struct_ty = ptr_struct_ty.childType(mod);31508 const struct_ty = ptr_struct_ty.childType(mod);
31194 const anon_struct = try sema.analyzeLoad(block, anon_struct_src, ptr_anon_struct, anon_struct_src);31509 const anon_struct = try sema.analyzeLoad(block, anon_struct_src, ptr_anon_struct, anon_struct_src);
31195 const struct_inst = try sema.coerceTupleToStruct(block, struct_ty, anon_struct, anon_struct_src);31510 const struct_inst = try sema.coerceTupleToStruct(block, struct_ty, anon_struct, anon_struct_src);
...@@ -31205,7 +31520,8 @@ fn coerceArrayLike(...@@ -31205,7 +31520,8 @@ fn coerceArrayLike(
31205 inst: Air.Inst.Ref,31520 inst: Air.Inst.Ref,
31206 inst_src: LazySrcLoc,31521 inst_src: LazySrcLoc,
31207) !Air.Inst.Ref {31522) !Air.Inst.Ref {
31208 const mod = sema.mod;31523 const pt = sema.pt;
31524 const mod = pt.zcu;
31209 const inst_ty = sema.typeOf(inst);31525 const inst_ty = sema.typeOf(inst);
31210 const target = mod.getTarget();31526 const target = mod.getTarget();
3121131527
...@@ -31226,7 +31542,7 @@ fn coerceArrayLike(...@@ -31226,7 +31542,7 @@ fn coerceArrayLike(
31226 if (dest_len != inst_len) {31542 if (dest_len != inst_len) {
31227 const msg = msg: {31543 const msg = msg: {
31228 const msg = try sema.errMsg(inst_src, "expected type '{}', found '{}'", .{31544 const msg = try sema.errMsg(inst_src, "expected type '{}', found '{}'", .{
31229 dest_ty.fmt(mod), inst_ty.fmt(mod),31545 dest_ty.fmt(pt), inst_ty.fmt(pt),
31230 });31546 });
31231 errdefer msg.destroy(sema.gpa);31547 errdefer msg.destroy(sema.gpa);
31232 try sema.errNote(dest_ty_src, msg, "destination has length {d}", .{dest_len});31548 try sema.errNote(dest_ty_src, msg, "destination has length {d}", .{dest_len});
...@@ -31270,7 +31586,7 @@ fn coerceArrayLike(...@@ -31270,7 +31586,7 @@ fn coerceArrayLike(
31270 var runtime_src: ?LazySrcLoc = null;31586 var runtime_src: ?LazySrcLoc = null;
3127131587
31272 for (element_vals, element_refs, 0..) |*val, *ref, i| {31588 for (element_vals, element_refs, 0..) |*val, *ref, i| {
31273 const index_ref = Air.internedToRef((try mod.intValue(Type.usize, i)).toIntern());31589 const index_ref = Air.internedToRef((try pt.intValue(Type.usize, i)).toIntern());
31274 const src = inst_src; // TODO better source location31590 const src = inst_src; // TODO better source location
31275 const elem_src = inst_src; // TODO better source location31591 const elem_src = inst_src; // TODO better source location
31276 const elem_ref = try sema.elemValArray(block, src, inst_src, inst, elem_src, index_ref, true);31592 const elem_ref = try sema.elemValArray(block, src, inst_src, inst, elem_src, index_ref, true);
...@@ -31290,7 +31606,7 @@ fn coerceArrayLike(...@@ -31290,7 +31606,7 @@ fn coerceArrayLike(
31290 return block.addAggregateInit(dest_ty, element_refs);31606 return block.addAggregateInit(dest_ty, element_refs);
31291 }31607 }
3129231608
31293 return Air.internedToRef((try mod.intern(.{ .aggregate = .{31609 return Air.internedToRef((try pt.intern(.{ .aggregate = .{
31294 .ty = dest_ty.toIntern(),31610 .ty = dest_ty.toIntern(),
31295 .storage = .{ .elems = element_vals },31611 .storage = .{ .elems = element_vals },
31296 } })));31612 } })));
...@@ -31305,7 +31621,8 @@ fn coerceTupleToArray(...@@ -31305,7 +31621,8 @@ fn coerceTupleToArray(
31305 inst: Air.Inst.Ref,31621 inst: Air.Inst.Ref,
31306 inst_src: LazySrcLoc,31622 inst_src: LazySrcLoc,
31307) !Air.Inst.Ref {31623) !Air.Inst.Ref {
31308 const mod = sema.mod;31624 const pt = sema.pt;
31625 const mod = pt.zcu;
31309 const inst_ty = sema.typeOf(inst);31626 const inst_ty = sema.typeOf(inst);
31310 const inst_len = inst_ty.arrayLen(mod);31627 const inst_len = inst_ty.arrayLen(mod);
31311 const dest_len = dest_ty.arrayLen(mod);31628 const dest_len = dest_ty.arrayLen(mod);
...@@ -31313,7 +31630,7 @@ fn coerceTupleToArray(...@@ -31313,7 +31630,7 @@ fn coerceTupleToArray(
31313 if (dest_len != inst_len) {31630 if (dest_len != inst_len) {
31314 const msg = msg: {31631 const msg = msg: {
31315 const msg = try sema.errMsg(inst_src, "expected type '{}', found '{}'", .{31632 const msg = try sema.errMsg(inst_src, "expected type '{}', found '{}'", .{
31316 dest_ty.fmt(sema.mod), inst_ty.fmt(sema.mod),31633 dest_ty.fmt(pt), inst_ty.fmt(pt),
31317 });31634 });
31318 errdefer msg.destroy(sema.gpa);31635 errdefer msg.destroy(sema.gpa);
31319 try sema.errNote(dest_ty_src, msg, "destination has length {d}", .{dest_len});31636 try sema.errNote(dest_ty_src, msg, "destination has length {d}", .{dest_len});
...@@ -31355,7 +31672,7 @@ fn coerceTupleToArray(...@@ -31355,7 +31672,7 @@ fn coerceTupleToArray(
31355 return block.addAggregateInit(dest_ty, element_refs);31672 return block.addAggregateInit(dest_ty, element_refs);
31356 }31673 }
3135731674
31358 return Air.internedToRef((try mod.intern(.{ .aggregate = .{31675 return Air.internedToRef((try pt.intern(.{ .aggregate = .{
31359 .ty = dest_ty.toIntern(),31676 .ty = dest_ty.toIntern(),
31360 .storage = .{ .elems = element_vals },31677 .storage = .{ .elems = element_vals },
31361 } })));31678 } })));
...@@ -31370,11 +31687,12 @@ fn coerceTupleToSlicePtrs(...@@ -31370,11 +31687,12 @@ fn coerceTupleToSlicePtrs(
31370 ptr_tuple: Air.Inst.Ref,31687 ptr_tuple: Air.Inst.Ref,
31371 tuple_src: LazySrcLoc,31688 tuple_src: LazySrcLoc,
31372) !Air.Inst.Ref {31689) !Air.Inst.Ref {
31373 const mod = sema.mod;31690 const pt = sema.pt;
31691 const mod = pt.zcu;
31374 const tuple_ty = sema.typeOf(ptr_tuple).childType(mod);31692 const tuple_ty = sema.typeOf(ptr_tuple).childType(mod);
31375 const tuple = try sema.analyzeLoad(block, tuple_src, ptr_tuple, tuple_src);31693 const tuple = try sema.analyzeLoad(block, tuple_src, ptr_tuple, tuple_src);
31376 const slice_info = slice_ty.ptrInfo(mod);31694 const slice_info = slice_ty.ptrInfo(mod);
31377 const array_ty = try mod.arrayType(.{31695 const array_ty = try pt.arrayType(.{
31378 .len = tuple_ty.structFieldCount(mod),31696 .len = tuple_ty.structFieldCount(mod),
31379 .sentinel = slice_info.sentinel,31697 .sentinel = slice_info.sentinel,
31380 .child = slice_info.child,31698 .child = slice_info.child,
...@@ -31396,7 +31714,8 @@ fn coerceTupleToArrayPtrs(...@@ -31396,7 +31714,8 @@ fn coerceTupleToArrayPtrs(
31396 ptr_tuple: Air.Inst.Ref,31714 ptr_tuple: Air.Inst.Ref,
31397 tuple_src: LazySrcLoc,31715 tuple_src: LazySrcLoc,
31398) !Air.Inst.Ref {31716) !Air.Inst.Ref {
31399 const mod = sema.mod;31717 const pt = sema.pt;
31718 const mod = pt.zcu;
31400 const tuple = try sema.analyzeLoad(block, tuple_src, ptr_tuple, tuple_src);31719 const tuple = try sema.analyzeLoad(block, tuple_src, ptr_tuple, tuple_src);
31401 const ptr_info = ptr_array_ty.ptrInfo(mod);31720 const ptr_info = ptr_array_ty.ptrInfo(mod);
31402 const array_ty = Type.fromInterned(ptr_info.child);31721 const array_ty = Type.fromInterned(ptr_info.child);
...@@ -31417,10 +31736,11 @@ fn coerceTupleToStruct(...@@ -31417,10 +31736,11 @@ fn coerceTupleToStruct(
31417 inst: Air.Inst.Ref,31736 inst: Air.Inst.Ref,
31418 inst_src: LazySrcLoc,31737 inst_src: LazySrcLoc,
31419) !Air.Inst.Ref {31738) !Air.Inst.Ref {
31420 const mod = sema.mod;31739 const pt = sema.pt;
31740 const mod = pt.zcu;
31421 const ip = &mod.intern_pool;31741 const ip = &mod.intern_pool;
31422 try struct_ty.resolveFields(mod);31742 try struct_ty.resolveFields(pt);
31423 try struct_ty.resolveStructFieldInits(mod);31743 try struct_ty.resolveStructFieldInits(pt);
3142431744
31425 if (struct_ty.isTupleOrAnonStruct(mod)) {31745 if (struct_ty.isTupleOrAnonStruct(mod)) {
31426 return sema.coerceTupleToTuple(block, struct_ty, inst, inst_src);31746 return sema.coerceTupleToTuple(block, struct_ty, inst, inst_src);
...@@ -31444,7 +31764,7 @@ fn coerceTupleToStruct(...@@ -31444,7 +31764,7 @@ fn coerceTupleToStruct(
31444 .anon_struct_type => |anon_struct_type| if (anon_struct_type.names.len > 0)31764 .anon_struct_type => |anon_struct_type| if (anon_struct_type.names.len > 0)
31445 anon_struct_type.names.get(ip)[tuple_field_index]31765 anon_struct_type.names.get(ip)[tuple_field_index]
31446 else31766 else
31447 try ip.getOrPutStringFmt(sema.gpa, "{d}", .{tuple_field_index}, .no_embedded_nulls),31767 try ip.getOrPutStringFmt(sema.gpa, pt.tid, "{d}", .{tuple_field_index}, .no_embedded_nulls),
31448 .struct_type => ip.loadStructType(inst_ty.toIntern()).field_names.get(ip)[tuple_field_index],31768 .struct_type => ip.loadStructType(inst_ty.toIntern()).field_names.get(ip)[tuple_field_index],
31449 else => unreachable,31769 else => unreachable,
31450 };31770 };
...@@ -31461,7 +31781,7 @@ fn coerceTupleToStruct(...@@ -31461,7 +31781,7 @@ fn coerceTupleToStruct(
31461 };31781 };
3146231782
31463 const field_init = Value.fromInterned(struct_type.field_inits.get(ip)[struct_field_index]);31783 const field_init = Value.fromInterned(struct_type.field_inits.get(ip)[struct_field_index]);
31464 if (!init_val.eql(field_init, struct_field_ty, sema.mod)) {31784 if (!init_val.eql(field_init, struct_field_ty, pt.zcu)) {
31465 return sema.failWithInvalidComptimeFieldStore(block, field_src, inst_ty, tuple_field_index);31785 return sema.failWithInvalidComptimeFieldStore(block, field_src, inst_ty, tuple_field_index);
31466 }31786 }
31467 }31787 }
...@@ -31512,7 +31832,7 @@ fn coerceTupleToStruct(...@@ -31512,7 +31832,7 @@ fn coerceTupleToStruct(
31512 return block.addAggregateInit(struct_ty, field_refs);31832 return block.addAggregateInit(struct_ty, field_refs);
31513 }31833 }
3151431834
31515 const struct_val = try mod.intern(.{ .aggregate = .{31835 const struct_val = try pt.intern(.{ .aggregate = .{
31516 .ty = struct_ty.toIntern(),31836 .ty = struct_ty.toIntern(),
31517 .storage = .{ .elems = field_vals },31837 .storage = .{ .elems = field_vals },
31518 } });31838 } });
...@@ -31529,7 +31849,8 @@ fn coerceTupleToTuple(...@@ -31529,7 +31849,8 @@ fn coerceTupleToTuple(
31529 inst: Air.Inst.Ref,31849 inst: Air.Inst.Ref,
31530 inst_src: LazySrcLoc,31850 inst_src: LazySrcLoc,
31531) !Air.Inst.Ref {31851) !Air.Inst.Ref {
31532 const mod = sema.mod;31852 const pt = sema.pt;
31853 const mod = pt.zcu;
31533 const ip = &mod.intern_pool;31854 const ip = &mod.intern_pool;
31534 const dest_field_count = switch (ip.indexToKey(tuple_ty.toIntern())) {31855 const dest_field_count = switch (ip.indexToKey(tuple_ty.toIntern())) {
31535 .anon_struct_type => |anon_struct_type| anon_struct_type.types.len,31856 .anon_struct_type => |anon_struct_type| anon_struct_type.types.len,
...@@ -31556,13 +31877,13 @@ fn coerceTupleToTuple(...@@ -31556,13 +31877,13 @@ fn coerceTupleToTuple(
31556 .anon_struct_type => |anon_struct_type| if (anon_struct_type.names.len > 0)31877 .anon_struct_type => |anon_struct_type| if (anon_struct_type.names.len > 0)
31557 anon_struct_type.names.get(ip)[field_i]31878 anon_struct_type.names.get(ip)[field_i]
31558 else31879 else
31559 try ip.getOrPutStringFmt(sema.gpa, "{d}", .{field_i}, .no_embedded_nulls),31880 try ip.getOrPutStringFmt(sema.gpa, pt.tid, "{d}", .{field_i}, .no_embedded_nulls),
31560 .struct_type => s: {31881 .struct_type => s: {
31561 const struct_type = ip.loadStructType(inst_ty.toIntern());31882 const struct_type = ip.loadStructType(inst_ty.toIntern());
31562 if (struct_type.field_names.len > 0) {31883 if (struct_type.field_names.len > 0) {
31563 break :s struct_type.field_names.get(ip)[field_i];31884 break :s struct_type.field_names.get(ip)[field_i];
31564 } else {31885 } else {
31565 break :s try ip.getOrPutStringFmt(sema.gpa, "{d}", .{field_i}, .no_embedded_nulls);31886 break :s try ip.getOrPutStringFmt(sema.gpa, pt.tid, "{d}", .{field_i}, .no_embedded_nulls);
31566 }31887 }
31567 },31888 },
31568 else => unreachable,31889 else => unreachable,
...@@ -31594,7 +31915,7 @@ fn coerceTupleToTuple(...@@ -31594,7 +31915,7 @@ fn coerceTupleToTuple(
31594 });31915 });
31595 };31916 };
3159631917
31597 if (!init_val.eql(Value.fromInterned(default_val), Type.fromInterned(field_ty), sema.mod)) {31918 if (!init_val.eql(Value.fromInterned(default_val), Type.fromInterned(field_ty), pt.zcu)) {
31598 return sema.failWithInvalidComptimeFieldStore(block, field_src, inst_ty, field_i);31919 return sema.failWithInvalidComptimeFieldStore(block, field_src, inst_ty, field_i);
31599 }31920 }
31600 }31921 }
...@@ -31659,7 +31980,7 @@ fn coerceTupleToTuple(...@@ -31659,7 +31980,7 @@ fn coerceTupleToTuple(
31659 return block.addAggregateInit(tuple_ty, field_refs);31980 return block.addAggregateInit(tuple_ty, field_refs);
31660 }31981 }
3166131982
31662 return Air.internedToRef((try mod.intern(.{ .aggregate = .{31983 return Air.internedToRef((try pt.intern(.{ .aggregate = .{
31663 .ty = tuple_ty.toIntern(),31984 .ty = tuple_ty.toIntern(),
31664 .storage = .{ .elems = field_vals },31985 .storage = .{ .elems = field_vals },
31665 } })));31986 } })));
...@@ -31689,17 +32010,19 @@ fn addReferenceEntry(...@@ -31689,17 +32010,19 @@ fn addReferenceEntry(
31689 src: LazySrcLoc,32010 src: LazySrcLoc,
31690 referenced_unit: AnalUnit,32011 referenced_unit: AnalUnit,
31691) !void {32012) !void {
31692 if (sema.mod.comp.reference_trace == 0) return;32013 const zcu = sema.pt.zcu;
32014 if (zcu.comp.reference_trace == 0) return;
31693 const gop = try sema.references.getOrPut(sema.gpa, referenced_unit);32015 const gop = try sema.references.getOrPut(sema.gpa, referenced_unit);
31694 if (gop.found_existing) return;32016 if (gop.found_existing) return;
31695 // TODO: we need to figure out how to model inline calls here.32017 // TODO: we need to figure out how to model inline calls here.
31696 // They aren't references in the analysis sense, but ought to show up in the reference trace!32018 // They aren't references in the analysis sense, but ought to show up in the reference trace!
31697 // Would representing inline calls in the reference table cause excessive memory usage?32019 // Would representing inline calls in the reference table cause excessive memory usage?
31698 try sema.mod.addUnitReference(sema.ownerUnit(), referenced_unit, src);32020 try zcu.addUnitReference(sema.ownerUnit(), referenced_unit, src);
31699}32021}
3170032022
31701pub fn ensureDeclAnalyzed(sema: *Sema, decl_index: InternPool.DeclIndex) CompileError!void {32023pub fn ensureDeclAnalyzed(sema: *Sema, decl_index: InternPool.DeclIndex) CompileError!void {
31702 const mod = sema.mod;32024 const pt = sema.pt;
32025 const mod = pt.zcu;
31703 const ip = &mod.intern_pool;32026 const ip = &mod.intern_pool;
31704 const decl = mod.declPtr(decl_index);32027 const decl = mod.declPtr(decl_index);
31705 if (decl.analysis == .in_progress) {32028 if (decl.analysis == .in_progress) {
...@@ -31710,7 +32033,7 @@ pub fn ensureDeclAnalyzed(sema: *Sema, decl_index: InternPool.DeclIndex) Compile...@@ -31710,7 +32033,7 @@ pub fn ensureDeclAnalyzed(sema: *Sema, decl_index: InternPool.DeclIndex) Compile
31710 return sema.failWithOwnedErrorMsg(null, msg);32033 return sema.failWithOwnedErrorMsg(null, msg);
31711 }32034 }
3171232035
31713 mod.ensureDeclAnalyzed(decl_index) catch |err| {32036 pt.ensureDeclAnalyzed(decl_index) catch |err| {
31714 if (sema.owner_func_index != .none) {32037 if (sema.owner_func_index != .none) {
31715 ip.funcAnalysis(sema.owner_func_index).state = .dependency_failure;32038 ip.funcAnalysis(sema.owner_func_index).state = .dependency_failure;
31716 } else {32039 } else {
...@@ -31721,9 +32044,10 @@ pub fn ensureDeclAnalyzed(sema: *Sema, decl_index: InternPool.DeclIndex) Compile...@@ -31721,9 +32044,10 @@ pub fn ensureDeclAnalyzed(sema: *Sema, decl_index: InternPool.DeclIndex) Compile
31721}32044}
3172232045
31723fn ensureFuncBodyAnalyzed(sema: *Sema, func: InternPool.Index) CompileError!void {32046fn ensureFuncBodyAnalyzed(sema: *Sema, func: InternPool.Index) CompileError!void {
31724 const mod = sema.mod;32047 const pt = sema.pt;
32048 const mod = pt.zcu;
31725 const ip = &mod.intern_pool;32049 const ip = &mod.intern_pool;
31726 mod.ensureFuncBodyAnalyzed(func) catch |err| {32050 pt.ensureFuncBodyAnalyzed(func) catch |err| {
31727 if (sema.owner_func_index != .none) {32051 if (sema.owner_func_index != .none) {
31728 ip.funcAnalysis(sema.owner_func_index).state = .dependency_failure;32052 ip.funcAnalysis(sema.owner_func_index).state = .dependency_failure;
31729 } else {32053 } else {
...@@ -31734,15 +32058,15 @@ fn ensureFuncBodyAnalyzed(sema: *Sema, func: InternPool.Index) CompileError!void...@@ -31734,15 +32058,15 @@ fn ensureFuncBodyAnalyzed(sema: *Sema, func: InternPool.Index) CompileError!void
31734}32058}
3173532059
31736fn optRefValue(sema: *Sema, opt_val: ?Value) !Value {32060fn optRefValue(sema: *Sema, opt_val: ?Value) !Value {
31737 const mod = sema.mod;32061 const pt = sema.pt;
31738 const ptr_anyopaque_ty = try mod.singleConstPtrType(Type.anyopaque);32062 const ptr_anyopaque_ty = try pt.singleConstPtrType(Type.anyopaque);
31739 return Value.fromInterned((try mod.intern(.{ .opt = .{32063 return Value.fromInterned(try pt.intern(.{ .opt = .{
31740 .ty = (try mod.optionalType(ptr_anyopaque_ty.toIntern())).toIntern(),32064 .ty = (try pt.optionalType(ptr_anyopaque_ty.toIntern())).toIntern(),
31741 .val = if (opt_val) |val| (try mod.getCoerced(32065 .val = if (opt_val) |val| (try pt.getCoerced(
31742 Value.fromInterned(try sema.refValue(val.toIntern())),32066 Value.fromInterned(try sema.refValue(val.toIntern())),
31743 ptr_anyopaque_ty,32067 ptr_anyopaque_ty,
31744 )).toIntern() else .none,32068 )).toIntern() else .none,
31745 } })));32069 } }));
31746}32070}
3174732071
31748fn analyzeDeclRef(sema: *Sema, src: LazySrcLoc, decl_index: InternPool.DeclIndex) CompileError!Air.Inst.Ref {32072fn analyzeDeclRef(sema: *Sema, src: LazySrcLoc, decl_index: InternPool.DeclIndex) CompileError!Air.Inst.Ref {
...@@ -31754,7 +32078,8 @@ fn analyzeDeclRef(sema: *Sema, src: LazySrcLoc, decl_index: InternPool.DeclIndex...@@ -31754,7 +32078,8 @@ fn analyzeDeclRef(sema: *Sema, src: LazySrcLoc, decl_index: InternPool.DeclIndex
31754/// decl_ref to end up in runtime code, the function body must be analyzed: `analyzeDeclRef` wraps32078/// decl_ref to end up in runtime code, the function body must be analyzed: `analyzeDeclRef` wraps
31755/// this function with `analyze_fn_body` set to true.32079/// this function with `analyze_fn_body` set to true.
31756fn analyzeDeclRefInner(sema: *Sema, src: LazySrcLoc, decl_index: InternPool.DeclIndex, analyze_fn_body: bool) CompileError!Air.Inst.Ref {32080fn analyzeDeclRefInner(sema: *Sema, src: LazySrcLoc, decl_index: InternPool.DeclIndex, analyze_fn_body: bool) CompileError!Air.Inst.Ref {
31757 const mod = sema.mod;32081 const pt = sema.pt;
32082 const mod = pt.zcu;
31758 try sema.addReferenceEntry(src, AnalUnit.wrap(.{ .decl = decl_index }));32083 try sema.addReferenceEntry(src, AnalUnit.wrap(.{ .decl = decl_index }));
31759 try sema.ensureDeclAnalyzed(decl_index);32084 try sema.ensureDeclAnalyzed(decl_index);
3176032085
...@@ -31767,7 +32092,7 @@ fn analyzeDeclRefInner(sema: *Sema, src: LazySrcLoc, decl_index: InternPool.Decl...@@ -31767,7 +32092,7 @@ fn analyzeDeclRefInner(sema: *Sema, src: LazySrcLoc, decl_index: InternPool.Decl
31767 });32092 });
31768 // TODO: if this is a `decl_ref` of a non-variable decl, only depend on decl type32093 // TODO: if this is a `decl_ref` of a non-variable decl, only depend on decl type
31769 try sema.declareDependency(.{ .decl_val = decl_index });32094 try sema.declareDependency(.{ .decl_val = decl_index });
31770 const ptr_ty = try mod.ptrTypeSema(.{32095 const ptr_ty = try pt.ptrTypeSema(.{
31771 .child = decl_val.typeOf(mod).toIntern(),32096 .child = decl_val.typeOf(mod).toIntern(),
31772 .flags = .{32097 .flags = .{
31773 .alignment = owner_decl.alignment,32098 .alignment = owner_decl.alignment,
...@@ -31778,7 +32103,7 @@ fn analyzeDeclRefInner(sema: *Sema, src: LazySrcLoc, decl_index: InternPool.Decl...@@ -31778,7 +32103,7 @@ fn analyzeDeclRefInner(sema: *Sema, src: LazySrcLoc, decl_index: InternPool.Decl
31778 if (analyze_fn_body) {32103 if (analyze_fn_body) {
31779 try sema.maybeQueueFuncBodyAnalysis(src, decl_index);32104 try sema.maybeQueueFuncBodyAnalysis(src, decl_index);
31780 }32105 }
31781 return Air.internedToRef((try mod.intern(.{ .ptr = .{32106 return Air.internedToRef((try pt.intern(.{ .ptr = .{
31782 .ty = ptr_ty.toIntern(),32107 .ty = ptr_ty.toIntern(),
31783 .base_addr = .{ .decl = decl_index },32108 .base_addr = .{ .decl = decl_index },
31784 .byte_offset = 0,32109 .byte_offset = 0,
...@@ -31786,7 +32111,7 @@ fn analyzeDeclRefInner(sema: *Sema, src: LazySrcLoc, decl_index: InternPool.Decl...@@ -31786,7 +32111,7 @@ fn analyzeDeclRefInner(sema: *Sema, src: LazySrcLoc, decl_index: InternPool.Decl
31786}32111}
3178732112
31788fn maybeQueueFuncBodyAnalysis(sema: *Sema, src: LazySrcLoc, decl_index: InternPool.DeclIndex) !void {32113fn maybeQueueFuncBodyAnalysis(sema: *Sema, src: LazySrcLoc, decl_index: InternPool.DeclIndex) !void {
31789 const mod = sema.mod;32114 const mod = sema.pt.zcu;
31790 const decl = mod.declPtr(decl_index);32115 const decl = mod.declPtr(decl_index);
31791 const decl_val = try decl.valueOrFail();32116 const decl_val = try decl.valueOrFail();
31792 if (!mod.intern_pool.isFuncBody(decl_val.toIntern())) return;32117 if (!mod.intern_pool.isFuncBody(decl_val.toIntern())) return;
...@@ -31801,7 +32126,8 @@ fn analyzeRef(...@@ -31801,7 +32126,8 @@ fn analyzeRef(
31801 src: LazySrcLoc,32126 src: LazySrcLoc,
31802 operand: Air.Inst.Ref,32127 operand: Air.Inst.Ref,
31803) CompileError!Air.Inst.Ref {32128) CompileError!Air.Inst.Ref {
31804 const mod = sema.mod;32129 const pt = sema.pt;
32130 const mod = pt.zcu;
31805 const operand_ty = sema.typeOf(operand);32131 const operand_ty = sema.typeOf(operand);
3180632132
31807 if (try sema.resolveValue(operand)) |val| {32133 if (try sema.resolveValue(operand)) |val| {
...@@ -31814,14 +32140,14 @@ fn analyzeRef(...@@ -31814,14 +32140,14 @@ fn analyzeRef(
3181432140
31815 try sema.requireRuntimeBlock(block, src, null);32141 try sema.requireRuntimeBlock(block, src, null);
31816 const address_space = target_util.defaultAddressSpace(mod.getTarget(), .local);32142 const address_space = target_util.defaultAddressSpace(mod.getTarget(), .local);
31817 const ptr_type = try mod.ptrTypeSema(.{32143 const ptr_type = try pt.ptrTypeSema(.{
31818 .child = operand_ty.toIntern(),32144 .child = operand_ty.toIntern(),
31819 .flags = .{32145 .flags = .{
31820 .is_const = true,32146 .is_const = true,
31821 .address_space = address_space,32147 .address_space = address_space,
31822 },32148 },
31823 });32149 });
31824 const mut_ptr_type = try mod.ptrTypeSema(.{32150 const mut_ptr_type = try pt.ptrTypeSema(.{
31825 .child = operand_ty.toIntern(),32151 .child = operand_ty.toIntern(),
31826 .flags = .{ .address_space = address_space },32152 .flags = .{ .address_space = address_space },
31827 });32153 });
...@@ -31839,14 +32165,15 @@ fn analyzeLoad(...@@ -31839,14 +32165,15 @@ fn analyzeLoad(
31839 ptr: Air.Inst.Ref,32165 ptr: Air.Inst.Ref,
31840 ptr_src: LazySrcLoc,32166 ptr_src: LazySrcLoc,
31841) CompileError!Air.Inst.Ref {32167) CompileError!Air.Inst.Ref {
31842 const mod = sema.mod;32168 const pt = sema.pt;
32169 const mod = pt.zcu;
31843 const ptr_ty = sema.typeOf(ptr);32170 const ptr_ty = sema.typeOf(ptr);
31844 const elem_ty = switch (ptr_ty.zigTypeTag(mod)) {32171 const elem_ty = switch (ptr_ty.zigTypeTag(mod)) {
31845 .Pointer => ptr_ty.childType(mod),32172 .Pointer => ptr_ty.childType(mod),
31846 else => return sema.fail(block, ptr_src, "expected pointer, found '{}'", .{ptr_ty.fmt(sema.mod)}),32173 else => return sema.fail(block, ptr_src, "expected pointer, found '{}'", .{ptr_ty.fmt(pt)}),
31847 };32174 };
31848 if (elem_ty.zigTypeTag(mod) == .Opaque) {32175 if (elem_ty.zigTypeTag(mod) == .Opaque) {
31849 return sema.fail(block, ptr_src, "cannot load opaque type '{}'", .{elem_ty.fmt(mod)});32176 return sema.fail(block, ptr_src, "cannot load opaque type '{}'", .{elem_ty.fmt(pt)});
31850 }32177 }
3185132178
31852 if (try sema.typeHasOnePossibleValue(elem_ty)) |opv| {32179 if (try sema.typeHasOnePossibleValue(elem_ty)) |opv| {
...@@ -31868,7 +32195,7 @@ fn analyzeLoad(...@@ -31868,7 +32195,7 @@ fn analyzeLoad(
31868 return block.addBinOp(.ptr_elem_val, bin_op.lhs, bin_op.rhs);32195 return block.addBinOp(.ptr_elem_val, bin_op.lhs, bin_op.rhs);
31869 }32196 }
31870 return sema.fail(block, ptr_src, "unable to determine vector element index of type '{}'", .{32197 return sema.fail(block, ptr_src, "unable to determine vector element index of type '{}'", .{
31871 ptr_ty.fmt(sema.mod),32198 ptr_ty.fmt(pt),
31872 });32199 });
31873 }32200 }
3187432201
...@@ -31882,10 +32209,11 @@ fn analyzeSlicePtr(...@@ -31882,10 +32209,11 @@ fn analyzeSlicePtr(
31882 slice: Air.Inst.Ref,32209 slice: Air.Inst.Ref,
31883 slice_ty: Type,32210 slice_ty: Type,
31884) CompileError!Air.Inst.Ref {32211) CompileError!Air.Inst.Ref {
31885 const mod = sema.mod;32212 const pt = sema.pt;
32213 const mod = pt.zcu;
31886 const result_ty = slice_ty.slicePtrFieldType(mod);32214 const result_ty = slice_ty.slicePtrFieldType(mod);
31887 if (try sema.resolveValue(slice)) |val| {32215 if (try sema.resolveValue(slice)) |val| {
31888 if (val.isUndef(mod)) return mod.undefRef(result_ty);32216 if (val.isUndef(mod)) return pt.undefRef(result_ty);
31889 return Air.internedToRef(val.slicePtr(mod).toIntern());32217 return Air.internedToRef(val.slicePtr(mod).toIntern());
31890 }32218 }
31891 try sema.requireRuntimeBlock(block, slice_src, null);32219 try sema.requireRuntimeBlock(block, slice_src, null);
...@@ -31899,11 +32227,12 @@ fn analyzeOptionalSlicePtr(...@@ -31899,11 +32227,12 @@ fn analyzeOptionalSlicePtr(
31899 opt_slice: Air.Inst.Ref,32227 opt_slice: Air.Inst.Ref,
31900 opt_slice_ty: Type,32228 opt_slice_ty: Type,
31901) CompileError!Air.Inst.Ref {32229) CompileError!Air.Inst.Ref {
31902 const mod = sema.mod;32230 const pt = sema.pt;
32231 const mod = pt.zcu;
31903 const result_ty = opt_slice_ty.optionalChild(mod).slicePtrFieldType(mod);32232 const result_ty = opt_slice_ty.optionalChild(mod).slicePtrFieldType(mod);
3190432233
31905 if (try sema.resolveValue(opt_slice)) |opt_val| {32234 if (try sema.resolveValue(opt_slice)) |opt_val| {
31906 if (opt_val.isUndef(mod)) return mod.undefRef(result_ty);32235 if (opt_val.isUndef(mod)) return pt.undefRef(result_ty);
31907 const slice_ptr: InternPool.Index = if (opt_val.optionalValue(mod)) |val|32236 const slice_ptr: InternPool.Index = if (opt_val.optionalValue(mod)) |val|
31908 val.slicePtr(mod).toIntern()32237 val.slicePtr(mod).toIntern()
31909 else32238 else
...@@ -31924,12 +32253,13 @@ fn analyzeSliceLen(...@@ -31924,12 +32253,13 @@ fn analyzeSliceLen(
31924 src: LazySrcLoc,32253 src: LazySrcLoc,
31925 slice_inst: Air.Inst.Ref,32254 slice_inst: Air.Inst.Ref,
31926) CompileError!Air.Inst.Ref {32255) CompileError!Air.Inst.Ref {
31927 const mod = sema.mod;32256 const pt = sema.pt;
32257 const mod = pt.zcu;
31928 if (try sema.resolveValue(slice_inst)) |slice_val| {32258 if (try sema.resolveValue(slice_inst)) |slice_val| {
31929 if (slice_val.isUndef(mod)) {32259 if (slice_val.isUndef(mod)) {
31930 return mod.undefRef(Type.usize);32260 return pt.undefRef(Type.usize);
31931 }32261 }
31932 return mod.intRef(Type.usize, try slice_val.sliceLen(mod));32262 return pt.intRef(Type.usize, try slice_val.sliceLen(pt));
31933 }32263 }
31934 try sema.requireRuntimeBlock(block, src, null);32264 try sema.requireRuntimeBlock(block, src, null);
31935 return block.addTyOp(.slice_len, Type.usize, slice_inst);32265 return block.addTyOp(.slice_len, Type.usize, slice_inst);
...@@ -31942,11 +32272,12 @@ fn analyzeIsNull(...@@ -31942,11 +32272,12 @@ fn analyzeIsNull(
31942 operand: Air.Inst.Ref,32272 operand: Air.Inst.Ref,
31943 invert_logic: bool,32273 invert_logic: bool,
31944) CompileError!Air.Inst.Ref {32274) CompileError!Air.Inst.Ref {
31945 const mod = sema.mod;32275 const pt = sema.pt;
32276 const mod = pt.zcu;
31946 const result_ty = Type.bool;32277 const result_ty = Type.bool;
31947 if (try sema.resolveValue(operand)) |opt_val| {32278 if (try sema.resolveValue(operand)) |opt_val| {
31948 if (opt_val.isUndef(mod)) {32279 if (opt_val.isUndef(mod)) {
31949 return mod.undefRef(result_ty);32280 return pt.undefRef(result_ty);
31950 }32281 }
31951 const is_null = opt_val.isNull(mod);32282 const is_null = opt_val.isNull(mod);
31952 const bool_value = if (invert_logic) !is_null else is_null;32283 const bool_value = if (invert_logic) !is_null else is_null;
...@@ -31972,7 +32303,8 @@ fn analyzePtrIsNonErrComptimeOnly(...@@ -31972,7 +32303,8 @@ fn analyzePtrIsNonErrComptimeOnly(
31972 src: LazySrcLoc,32303 src: LazySrcLoc,
31973 operand: Air.Inst.Ref,32304 operand: Air.Inst.Ref,
31974) CompileError!Air.Inst.Ref {32305) CompileError!Air.Inst.Ref {
31975 const mod = sema.mod;32306 const pt = sema.pt;
32307 const mod = pt.zcu;
31976 const ptr_ty = sema.typeOf(operand);32308 const ptr_ty = sema.typeOf(operand);
31977 assert(ptr_ty.zigTypeTag(mod) == .Pointer);32309 assert(ptr_ty.zigTypeTag(mod) == .Pointer);
31978 const child_ty = ptr_ty.childType(mod);32310 const child_ty = ptr_ty.childType(mod);
...@@ -31994,7 +32326,8 @@ fn analyzeIsNonErrComptimeOnly(...@@ -31994,7 +32326,8 @@ fn analyzeIsNonErrComptimeOnly(
31994 src: LazySrcLoc,32326 src: LazySrcLoc,
31995 operand: Air.Inst.Ref,32327 operand: Air.Inst.Ref,
31996) CompileError!Air.Inst.Ref {32328) CompileError!Air.Inst.Ref {
31997 const mod = sema.mod;32329 const pt = sema.pt;
32330 const mod = pt.zcu;
31998 const ip = &mod.intern_pool;32331 const ip = &mod.intern_pool;
31999 const operand_ty = sema.typeOf(operand);32332 const operand_ty = sema.typeOf(operand);
32000 const ot = operand_ty.zigTypeTag(mod);32333 const ot = operand_ty.zigTypeTag(mod);
...@@ -32014,7 +32347,7 @@ fn analyzeIsNonErrComptimeOnly(...@@ -32014,7 +32347,7 @@ fn analyzeIsNonErrComptimeOnly(
32014 else => {},32347 else => {},
32015 }32348 }
32016 } else if (operand == .undef) {32349 } else if (operand == .undef) {
32017 return mod.undefRef(Type.bool);32350 return pt.undefRef(Type.bool);
32018 } else if (@intFromEnum(operand) < InternPool.static_len) {32351 } else if (@intFromEnum(operand) < InternPool.static_len) {
32019 // None of the ref tags can be errors.32352 // None of the ref tags can be errors.
32020 return .bool_true;32353 return .bool_true;
...@@ -32098,7 +32431,7 @@ fn analyzeIsNonErrComptimeOnly(...@@ -32098,7 +32431,7 @@ fn analyzeIsNonErrComptimeOnly(
3209832431
32099 if (maybe_operand_val) |err_union| {32432 if (maybe_operand_val) |err_union| {
32100 if (err_union.isUndef(mod)) {32433 if (err_union.isUndef(mod)) {
32101 return mod.undefRef(Type.bool);32434 return pt.undefRef(Type.bool);
32102 }32435 }
32103 if (err_union.getErrorName(mod) == .none) {32436 if (err_union.getErrorName(mod) == .none) {
32104 return .bool_true;32437 return .bool_true;
...@@ -32153,13 +32486,14 @@ fn analyzeSlice(...@@ -32153,13 +32486,14 @@ fn analyzeSlice(
32153 end_src: LazySrcLoc,32486 end_src: LazySrcLoc,
32154 by_length: bool,32487 by_length: bool,
32155) CompileError!Air.Inst.Ref {32488) CompileError!Air.Inst.Ref {
32156 const mod = sema.mod;32489 const pt = sema.pt;
32490 const mod = pt.zcu;
32157 // Slice expressions can operate on a variable whose type is an array. This requires32491 // Slice expressions can operate on a variable whose type is an array. This requires
32158 // the slice operand to be a pointer. In the case of a non-array, it will be a double pointer.32492 // the slice operand to be a pointer. In the case of a non-array, it will be a double pointer.
32159 const ptr_ptr_ty = sema.typeOf(ptr_ptr);32493 const ptr_ptr_ty = sema.typeOf(ptr_ptr);
32160 const ptr_ptr_child_ty = switch (ptr_ptr_ty.zigTypeTag(mod)) {32494 const ptr_ptr_child_ty = switch (ptr_ptr_ty.zigTypeTag(mod)) {
32161 .Pointer => ptr_ptr_ty.childType(mod),32495 .Pointer => ptr_ptr_ty.childType(mod),
32162 else => return sema.fail(block, ptr_src, "expected pointer, found '{}'", .{ptr_ptr_ty.fmt(mod)}),32496 else => return sema.fail(block, ptr_src, "expected pointer, found '{}'", .{ptr_ptr_ty.fmt(pt)}),
32163 };32497 };
3216432498
32165 var array_ty = ptr_ptr_child_ty;32499 var array_ty = ptr_ptr_child_ty;
...@@ -32210,8 +32544,8 @@ fn analyzeSlice(...@@ -32210,8 +32544,8 @@ fn analyzeSlice(
32210 msg,32544 msg,
32211 "expected '{}', found '{}'",32545 "expected '{}', found '{}'",
32212 .{32546 .{
32213 Value.zero_comptime_int.fmtValue(mod, sema),32547 Value.zero_comptime_int.fmtValue(pt, sema),
32214 start_value.fmtValue(mod, sema),32548 start_value.fmtValue(pt, sema),
32215 },32549 },
32216 );32550 );
32217 break :msg msg;32551 break :msg msg;
...@@ -32226,8 +32560,8 @@ fn analyzeSlice(...@@ -32226,8 +32560,8 @@ fn analyzeSlice(
32226 msg,32560 msg,
32227 "expected '{}', found '{}'",32561 "expected '{}', found '{}'",
32228 .{32562 .{
32229 Value.one_comptime_int.fmtValue(mod, sema),32563 Value.one_comptime_int.fmtValue(pt, sema),
32230 end_value.fmtValue(mod, sema),32564 end_value.fmtValue(pt, sema),
32231 },32565 },
32232 );32566 );
32233 break :msg msg;32567 break :msg msg;
...@@ -32240,17 +32574,17 @@ fn analyzeSlice(...@@ -32240,17 +32574,17 @@ fn analyzeSlice(
32240 block,32574 block,
32241 end_src,32575 end_src,
32242 "end index {} out of bounds for slice of single-item pointer",32576 "end index {} out of bounds for slice of single-item pointer",
32243 .{end_value.fmtValue(mod, sema)},32577 .{end_value.fmtValue(pt, sema)},
32244 );32578 );
32245 }32579 }
32246 }32580 }
3224732581
32248 array_ty = try mod.arrayType(.{32582 array_ty = try pt.arrayType(.{
32249 .len = 1,32583 .len = 1,
32250 .child = double_child_ty.toIntern(),32584 .child = double_child_ty.toIntern(),
32251 });32585 });
32252 const ptr_info = ptr_ptr_child_ty.ptrInfo(mod);32586 const ptr_info = ptr_ptr_child_ty.ptrInfo(mod);
32253 slice_ty = try mod.ptrType(.{32587 slice_ty = try pt.ptrType(.{
32254 .child = array_ty.toIntern(),32588 .child = array_ty.toIntern(),
32255 .flags = .{32589 .flags = .{
32256 .alignment = ptr_info.flags.alignment,32590 .alignment = ptr_info.flags.alignment,
...@@ -32286,7 +32620,7 @@ fn analyzeSlice(...@@ -32286,7 +32620,7 @@ fn analyzeSlice(
32286 elem_ty = ptr_ptr_child_ty.childType(mod);32620 elem_ty = ptr_ptr_child_ty.childType(mod);
32287 },32621 },
32288 },32622 },
32289 else => return sema.fail(block, src, "slice of non-array type '{}'", .{ptr_ptr_child_ty.fmt(mod)}),32623 else => return sema.fail(block, src, "slice of non-array type '{}'", .{ptr_ptr_child_ty.fmt(pt)}),
32290 }32624 }
3229132625
32292 const ptr = if (slice_ty.isSlice(mod))32626 const ptr = if (slice_ty.isSlice(mod))
...@@ -32297,7 +32631,7 @@ fn analyzeSlice(...@@ -32297,7 +32631,7 @@ fn analyzeSlice(
32297 assert(manyptr_ty_key.flags.size == .One);32631 assert(manyptr_ty_key.flags.size == .One);
32298 manyptr_ty_key.child = elem_ty.toIntern();32632 manyptr_ty_key.child = elem_ty.toIntern();
32299 manyptr_ty_key.flags.size = .Many;32633 manyptr_ty_key.flags.size = .Many;
32300 break :ptr try sema.coerceCompatiblePtrs(block, try mod.ptrTypeSema(manyptr_ty_key), ptr_or_slice, ptr_src);32634 break :ptr try sema.coerceCompatiblePtrs(block, try pt.ptrTypeSema(manyptr_ty_key), ptr_or_slice, ptr_src);
32301 } else ptr_or_slice;32635 } else ptr_or_slice;
3230232636
32303 const start = try sema.coerce(block, Type.usize, uncasted_start, start_src);32637 const start = try sema.coerce(block, Type.usize, uncasted_start, start_src);
...@@ -32311,7 +32645,7 @@ fn analyzeSlice(...@@ -32311,7 +32645,7 @@ fn analyzeSlice(
32311 var end_is_len = uncasted_end_opt == .none;32645 var end_is_len = uncasted_end_opt == .none;
32312 const end = e: {32646 const end = e: {
32313 if (array_ty.zigTypeTag(mod) == .Array) {32647 if (array_ty.zigTypeTag(mod) == .Array) {
32314 const len_val = try mod.intValue(Type.usize, array_ty.arrayLen(mod));32648 const len_val = try pt.intValue(Type.usize, array_ty.arrayLen(mod));
3231532649
32316 if (!end_is_len) {32650 if (!end_is_len) {
32317 const end = if (by_length) end: {32651 const end = if (by_length) end: {
...@@ -32320,7 +32654,7 @@ fn analyzeSlice(...@@ -32320,7 +32654,7 @@ fn analyzeSlice(
32320 break :end try sema.coerce(block, Type.usize, uncasted_end, end_src);32654 break :end try sema.coerce(block, Type.usize, uncasted_end, end_src);
32321 } else try sema.coerce(block, Type.usize, uncasted_end_opt, end_src);32655 } else try sema.coerce(block, Type.usize, uncasted_end_opt, end_src);
32322 if (try sema.resolveDefinedValue(block, end_src, end)) |end_val| {32656 if (try sema.resolveDefinedValue(block, end_src, end)) |end_val| {
32323 const len_s_val = try mod.intValue(32657 const len_s_val = try pt.intValue(
32324 Type.usize,32658 Type.usize,
32325 array_ty.arrayLenIncludingSentinel(mod),32659 array_ty.arrayLenIncludingSentinel(mod),
32326 );32660 );
...@@ -32335,8 +32669,8 @@ fn analyzeSlice(...@@ -32335,8 +32669,8 @@ fn analyzeSlice(
32335 end_src,32669 end_src,
32336 "end index {} out of bounds for array of length {}{s}",32670 "end index {} out of bounds for array of length {}{s}",
32337 .{32671 .{
32338 end_val.fmtValue(mod, sema),32672 end_val.fmtValue(pt, sema),
32339 len_val.fmtValue(mod, sema),32673 len_val.fmtValue(pt, sema),
32340 sentinel_label,32674 sentinel_label,
32341 },32675 },
32342 );32676 );
...@@ -32366,9 +32700,9 @@ fn analyzeSlice(...@@ -32366,9 +32700,9 @@ fn analyzeSlice(
32366 return sema.fail(block, src, "slice of undefined", .{});32700 return sema.fail(block, src, "slice of undefined", .{});
32367 }32701 }
32368 const has_sentinel = slice_ty.sentinel(mod) != null;32702 const has_sentinel = slice_ty.sentinel(mod) != null;
32369 const slice_len = try slice_val.sliceLen(mod);32703 const slice_len = try slice_val.sliceLen(pt);
32370 const len_plus_sent = slice_len + @intFromBool(has_sentinel);32704 const len_plus_sent = slice_len + @intFromBool(has_sentinel);
32371 const slice_len_val_with_sentinel = try mod.intValue(Type.usize, len_plus_sent);32705 const slice_len_val_with_sentinel = try pt.intValue(Type.usize, len_plus_sent);
32372 if (!(try sema.compareAll(end_val, .lte, slice_len_val_with_sentinel, Type.usize))) {32706 if (!(try sema.compareAll(end_val, .lte, slice_len_val_with_sentinel, Type.usize))) {
32373 const sentinel_label: []const u8 = if (has_sentinel)32707 const sentinel_label: []const u8 = if (has_sentinel)
32374 " +1 (sentinel)"32708 " +1 (sentinel)"
...@@ -32380,8 +32714,8 @@ fn analyzeSlice(...@@ -32380,8 +32714,8 @@ fn analyzeSlice(
32380 end_src,32714 end_src,
32381 "end index {} out of bounds for slice of length {d}{s}",32715 "end index {} out of bounds for slice of length {d}{s}",
32382 .{32716 .{
32383 end_val.fmtValue(mod, sema),32717 end_val.fmtValue(pt, sema),
32384 try slice_val.sliceLen(mod),32718 try slice_val.sliceLen(pt),
32385 sentinel_label,32719 sentinel_label,
32386 },32720 },
32387 );32721 );
...@@ -32390,7 +32724,7 @@ fn analyzeSlice(...@@ -32390,7 +32724,7 @@ fn analyzeSlice(
32390 // If the slice has a sentinel, we consider end_is_len32724 // If the slice has a sentinel, we consider end_is_len
32391 // is only true if it equals the length WITHOUT the32725 // is only true if it equals the length WITHOUT the
32392 // sentinel, so we don't add a sentinel type.32726 // sentinel, so we don't add a sentinel type.
32393 const slice_len_val = try mod.intValue(Type.usize, slice_len);32727 const slice_len_val = try pt.intValue(Type.usize, slice_len);
32394 if (end_val.eql(slice_len_val, Type.usize, mod)) {32728 if (end_val.eql(slice_len_val, Type.usize, mod)) {
32395 end_is_len = true;32729 end_is_len = true;
32396 }32730 }
...@@ -32440,21 +32774,21 @@ fn analyzeSlice(...@@ -32440,21 +32774,21 @@ fn analyzeSlice(
32440 start_src,32774 start_src,
32441 "start index {} is larger than end index {}",32775 "start index {} is larger than end index {}",
32442 .{32776 .{
32443 start_val.fmtValue(mod, sema),32777 start_val.fmtValue(pt, sema),
32444 end_val.fmtValue(mod, sema),32778 end_val.fmtValue(pt, sema),
32445 },32779 },
32446 );32780 );
32447 }32781 }
32448 checked_start_lte_end = true;32782 checked_start_lte_end = true;
32449 if (try sema.resolveValue(new_ptr)) |ptr_val| sentinel_check: {32783 if (try sema.resolveValue(new_ptr)) |ptr_val| sentinel_check: {
32450 const expected_sentinel = sentinel orelse break :sentinel_check;32784 const expected_sentinel = sentinel orelse break :sentinel_check;
32451 const start_int = start_val.getUnsignedInt(mod).?;32785 const start_int = start_val.getUnsignedInt(pt).?;
32452 const end_int = end_val.getUnsignedInt(mod).?;32786 const end_int = end_val.getUnsignedInt(pt).?;
32453 const sentinel_index = try sema.usizeCast(block, end_src, end_int - start_int);32787 const sentinel_index = try sema.usizeCast(block, end_src, end_int - start_int);
3245432788
32455 const many_ptr_ty = try mod.manyConstPtrType(elem_ty);32789 const many_ptr_ty = try pt.manyConstPtrType(elem_ty);
32456 const many_ptr_val = try mod.getCoerced(ptr_val, many_ptr_ty);32790 const many_ptr_val = try pt.getCoerced(ptr_val, many_ptr_ty);
32457 const elem_ptr = try many_ptr_val.ptrElem(sentinel_index, mod);32791 const elem_ptr = try many_ptr_val.ptrElem(sentinel_index, pt);
32458 const res = try sema.pointerDerefExtra(block, src, elem_ptr);32792 const res = try sema.pointerDerefExtra(block, src, elem_ptr);
32459 const actual_sentinel = switch (res) {32793 const actual_sentinel = switch (res) {
32460 .runtime_load => break :sentinel_check,32794 .runtime_load => break :sentinel_check,
...@@ -32463,13 +32797,13 @@ fn analyzeSlice(...@@ -32463,13 +32797,13 @@ fn analyzeSlice(
32463 block,32797 block,
32464 src,32798 src,
32465 "comptime dereference requires '{}' to have a well-defined layout",32799 "comptime dereference requires '{}' to have a well-defined layout",
32466 .{ty.fmt(mod)},32800 .{ty.fmt(pt)},
32467 ),32801 ),
32468 .out_of_bounds => |ty| return sema.fail(32802 .out_of_bounds => |ty| return sema.fail(
32469 block,32803 block,
32470 end_src,32804 end_src,
32471 "slice end index {d} exceeds bounds of containing decl of type '{}'",32805 "slice end index {d} exceeds bounds of containing decl of type '{}'",
32472 .{ end_int, ty.fmt(mod) },32806 .{ end_int, ty.fmt(pt) },
32473 ),32807 ),
32474 };32808 };
3247532809
...@@ -32478,8 +32812,8 @@ fn analyzeSlice(...@@ -32478,8 +32812,8 @@ fn analyzeSlice(
32478 const msg = try sema.errMsg(src, "value in memory does not match slice sentinel", .{});32812 const msg = try sema.errMsg(src, "value in memory does not match slice sentinel", .{});
32479 errdefer msg.destroy(sema.gpa);32813 errdefer msg.destroy(sema.gpa);
32480 try sema.errNote(src, msg, "expected '{}', found '{}'", .{32814 try sema.errNote(src, msg, "expected '{}', found '{}'", .{
32481 expected_sentinel.fmtValue(mod, sema),32815 expected_sentinel.fmtValue(pt, sema),
32482 actual_sentinel.fmtValue(mod, sema),32816 actual_sentinel.fmtValue(pt, sema),
32483 });32817 });
3248432818
32485 break :msg msg;32819 break :msg msg;
...@@ -32501,7 +32835,7 @@ fn analyzeSlice(...@@ -32501,7 +32835,7 @@ fn analyzeSlice(
32501 assert(!block.is_comptime);32835 assert(!block.is_comptime);
32502 try sema.requireRuntimeBlock(block, src, runtime_src.?);32836 try sema.requireRuntimeBlock(block, src, runtime_src.?);
32503 const ok = try block.addBinOp(.cmp_lte, start, end);32837 const ok = try block.addBinOp(.cmp_lte, start, end);
32504 if (!sema.mod.comp.formatted_panics) {32838 if (!pt.zcu.comp.formatted_panics) {
32505 try sema.addSafetyCheck(block, src, ok, .start_index_greater_than_end);32839 try sema.addSafetyCheck(block, src, ok, .start_index_greater_than_end);
32506 } else {32840 } else {
32507 try sema.safetyCheckFormatted(block, src, ok, "panicStartGreaterThanEnd", &.{ start, end });32841 try sema.safetyCheckFormatted(block, src, ok, "panicStartGreaterThanEnd", &.{ start, end });
...@@ -32517,10 +32851,10 @@ fn analyzeSlice(...@@ -32517,10 +32851,10 @@ fn analyzeSlice(
32517 const new_allowzero = new_ptr_ty_info.flags.is_allowzero and sema.typeOf(ptr).ptrSize(mod) != .C;32851 const new_allowzero = new_ptr_ty_info.flags.is_allowzero and sema.typeOf(ptr).ptrSize(mod) != .C;
3251832852
32519 if (opt_new_len_val) |new_len_val| {32853 if (opt_new_len_val) |new_len_val| {
32520 const new_len_int = try new_len_val.toUnsignedIntSema(mod);32854 const new_len_int = try new_len_val.toUnsignedIntSema(pt);
3252132855
32522 const return_ty = try mod.ptrTypeSema(.{32856 const return_ty = try pt.ptrTypeSema(.{
32523 .child = (try mod.arrayType(.{32857 .child = (try pt.arrayType(.{
32524 .len = new_len_int,32858 .len = new_len_int,
32525 .sentinel = if (sentinel) |s| s.toIntern() else .none,32859 .sentinel = if (sentinel) |s| s.toIntern() else .none,
32526 .child = elem_ty.toIntern(),32860 .child = elem_ty.toIntern(),
...@@ -32546,7 +32880,7 @@ fn analyzeSlice(...@@ -32546,7 +32880,7 @@ fn analyzeSlice(
3254632880
32547 bounds_check: {32881 bounds_check: {
32548 const actual_len = if (array_ty.zigTypeTag(mod) == .Array)32882 const actual_len = if (array_ty.zigTypeTag(mod) == .Array)
32549 try mod.intRef(Type.usize, array_ty.arrayLenIncludingSentinel(mod))32883 try pt.intRef(Type.usize, array_ty.arrayLenIncludingSentinel(mod))
32550 else if (slice_ty.isSlice(mod)) l: {32884 else if (slice_ty.isSlice(mod)) l: {
32551 const slice_len_inst = try block.addTyOp(.slice_len, Type.usize, ptr_or_slice);32885 const slice_len_inst = try block.addTyOp(.slice_len, Type.usize, ptr_or_slice);
32552 break :l if (slice_ty.sentinel(mod) == null)32886 break :l if (slice_ty.sentinel(mod) == null)
...@@ -32570,18 +32904,18 @@ fn analyzeSlice(...@@ -32570,18 +32904,18 @@ fn analyzeSlice(
32570 };32904 };
3257132905
32572 if (!new_ptr_val.isUndef(mod)) {32906 if (!new_ptr_val.isUndef(mod)) {
32573 return Air.internedToRef((try mod.getCoerced(new_ptr_val, return_ty)).toIntern());32907 return Air.internedToRef((try pt.getCoerced(new_ptr_val, return_ty)).toIntern());
32574 }32908 }
3257532909
32576 // Special case: @as([]i32, undefined)[x..x]32910 // Special case: @as([]i32, undefined)[x..x]
32577 if (new_len_int == 0) {32911 if (new_len_int == 0) {
32578 return mod.undefRef(return_ty);32912 return pt.undefRef(return_ty);
32579 }32913 }
3258032914
32581 return sema.fail(block, src, "non-zero length slice of undefined pointer", .{});32915 return sema.fail(block, src, "non-zero length slice of undefined pointer", .{});
32582 }32916 }
3258332917
32584 const return_ty = try mod.ptrTypeSema(.{32918 const return_ty = try pt.ptrTypeSema(.{
32585 .child = elem_ty.toIntern(),32919 .child = elem_ty.toIntern(),
32586 .sentinel = if (sentinel) |s| s.toIntern() else .none,32920 .sentinel = if (sentinel) |s| s.toIntern() else .none,
32587 .flags = .{32921 .flags = .{
...@@ -32604,12 +32938,12 @@ fn analyzeSlice(...@@ -32604,12 +32938,12 @@ fn analyzeSlice(
3260432938
32605 // requirement: end <= len32939 // requirement: end <= len
32606 const opt_len_inst = if (array_ty.zigTypeTag(mod) == .Array)32940 const opt_len_inst = if (array_ty.zigTypeTag(mod) == .Array)
32607 try mod.intRef(Type.usize, array_ty.arrayLenIncludingSentinel(mod))32941 try pt.intRef(Type.usize, array_ty.arrayLenIncludingSentinel(mod))
32608 else if (slice_ty.isSlice(mod)) blk: {32942 else if (slice_ty.isSlice(mod)) blk: {
32609 if (try sema.resolveDefinedValue(block, src, ptr_or_slice)) |slice_val| {32943 if (try sema.resolveDefinedValue(block, src, ptr_or_slice)) |slice_val| {
32610 // we don't need to add one for sentinels because the32944 // we don't need to add one for sentinels because the
32611 // underlying value data includes the sentinel32945 // underlying value data includes the sentinel
32612 break :blk try mod.intRef(Type.usize, try slice_val.sliceLen(mod));32946 break :blk try pt.intRef(Type.usize, try slice_val.sliceLen(pt));
32613 }32947 }
3261432948
32615 const slice_len_inst = try block.addTyOp(.slice_len, Type.usize, ptr_or_slice);32949 const slice_len_inst = try block.addTyOp(.slice_len, Type.usize, ptr_or_slice);
...@@ -32657,7 +32991,8 @@ fn cmpNumeric(...@@ -32657,7 +32991,8 @@ fn cmpNumeric(
32657 lhs_src: LazySrcLoc,32991 lhs_src: LazySrcLoc,
32658 rhs_src: LazySrcLoc,32992 rhs_src: LazySrcLoc,
32659) CompileError!Air.Inst.Ref {32993) CompileError!Air.Inst.Ref {
32660 const mod = sema.mod;32994 const pt = sema.pt;
32995 const mod = pt.zcu;
32661 const lhs_ty = sema.typeOf(uncasted_lhs);32996 const lhs_ty = sema.typeOf(uncasted_lhs);
32662 const rhs_ty = sema.typeOf(uncasted_rhs);32997 const rhs_ty = sema.typeOf(uncasted_rhs);
3266332998
...@@ -32696,12 +33031,12 @@ fn cmpNumeric(...@@ -32696,12 +33031,12 @@ fn cmpNumeric(
32696 }33031 }
3269733032
32698 if (lhs_val.isUndef(mod) or rhs_val.isUndef(mod)) {33033 if (lhs_val.isUndef(mod) or rhs_val.isUndef(mod)) {
32699 return mod.undefRef(Type.bool);33034 return pt.undefRef(Type.bool);
32700 }33035 }
32701 if (lhs_val.isNan(mod) or rhs_val.isNan(mod)) {33036 if (lhs_val.isNan(mod) or rhs_val.isNan(mod)) {
32702 return if (op == std.math.CompareOperator.neq) .bool_true else .bool_false;33037 return if (op == std.math.CompareOperator.neq) .bool_true else .bool_false;
32703 }33038 }
32704 return if (try Value.compareHeteroAdvanced(lhs_val, op, rhs_val, mod, .sema))33039 return if (try Value.compareHeteroAdvanced(lhs_val, op, rhs_val, pt, .sema))
32705 .bool_true33040 .bool_true
32706 else33041 else
32707 .bool_false;33042 .bool_false;
...@@ -32770,11 +33105,11 @@ fn cmpNumeric(...@@ -32770,11 +33105,11 @@ fn cmpNumeric(
32770 // a signed integer with mantissa bits + 1, and if there was any non-integral part of the float,33105 // a signed integer with mantissa bits + 1, and if there was any non-integral part of the float,
32771 // add/subtract 1.33106 // add/subtract 1.
32772 const lhs_is_signed = if (try sema.resolveDefinedValue(block, lhs_src, lhs)) |lhs_val|33107 const lhs_is_signed = if (try sema.resolveDefinedValue(block, lhs_src, lhs)) |lhs_val|
32773 !(try lhs_val.compareAllWithZeroSema(.gte, mod))33108 !(try lhs_val.compareAllWithZeroSema(.gte, pt))
32774 else33109 else
32775 (lhs_ty.isRuntimeFloat() or lhs_ty.isSignedInt(mod));33110 (lhs_ty.isRuntimeFloat() or lhs_ty.isSignedInt(mod));
32776 const rhs_is_signed = if (try sema.resolveDefinedValue(block, rhs_src, rhs)) |rhs_val|33111 const rhs_is_signed = if (try sema.resolveDefinedValue(block, rhs_src, rhs)) |rhs_val|
32777 !(try rhs_val.compareAllWithZeroSema(.gte, mod))33112 !(try rhs_val.compareAllWithZeroSema(.gte, pt))
32778 else33113 else
32779 (rhs_ty.isRuntimeFloat() or rhs_ty.isSignedInt(mod));33114 (rhs_ty.isRuntimeFloat() or rhs_ty.isSignedInt(mod));
32780 const dest_int_is_signed = lhs_is_signed or rhs_is_signed;33115 const dest_int_is_signed = lhs_is_signed or rhs_is_signed;
...@@ -32784,7 +33119,7 @@ fn cmpNumeric(...@@ -32784,7 +33119,7 @@ fn cmpNumeric(
32784 var lhs_bits: usize = undefined;33119 var lhs_bits: usize = undefined;
32785 if (try sema.resolveValueResolveLazy(lhs)) |lhs_val| {33120 if (try sema.resolveValueResolveLazy(lhs)) |lhs_val| {
32786 if (lhs_val.isUndef(mod))33121 if (lhs_val.isUndef(mod))
32787 return mod.undefRef(Type.bool);33122 return pt.undefRef(Type.bool);
32788 if (lhs_val.isNan(mod)) switch (op) {33123 if (lhs_val.isNan(mod)) switch (op) {
32789 .neq => return .bool_true,33124 .neq => return .bool_true,
32790 else => return .bool_false,33125 else => return .bool_false,
...@@ -32796,7 +33131,7 @@ fn cmpNumeric(...@@ -32796,7 +33131,7 @@ fn cmpNumeric(
32796 .lt, .lte => return if (lhs_val.isNegativeInf(mod)) .bool_true else .bool_false,33131 .lt, .lte => return if (lhs_val.isNegativeInf(mod)) .bool_true else .bool_false,
32797 };33132 };
32798 if (!rhs_is_signed) {33133 if (!rhs_is_signed) {
32799 switch (lhs_val.orderAgainstZero(mod)) {33134 switch (lhs_val.orderAgainstZero(pt)) {
32800 .gt => {},33135 .gt => {},
32801 .eq => switch (op) { // LHS = 0, RHS is unsigned33136 .eq => switch (op) { // LHS = 0, RHS is unsigned
32802 .lte => return .bool_true,33137 .lte => return .bool_true,
...@@ -32818,7 +33153,7 @@ fn cmpNumeric(...@@ -32818,7 +33153,7 @@ fn cmpNumeric(
32818 }33153 }
32819 }33154 }
3282033155
32821 var bigint = try float128IntPartToBigInt(sema.gpa, lhs_val.toFloat(f128, mod));33156 var bigint = try float128IntPartToBigInt(sema.gpa, lhs_val.toFloat(f128, pt));
32822 defer bigint.deinit();33157 defer bigint.deinit();
32823 if (lhs_val.floatHasFraction(mod)) {33158 if (lhs_val.floatHasFraction(mod)) {
32824 if (lhs_is_signed) {33159 if (lhs_is_signed) {
...@@ -32829,7 +33164,7 @@ fn cmpNumeric(...@@ -32829,7 +33164,7 @@ fn cmpNumeric(
32829 }33164 }
32830 lhs_bits = bigint.toConst().bitCountTwosComp();33165 lhs_bits = bigint.toConst().bitCountTwosComp();
32831 } else {33166 } else {
32832 lhs_bits = lhs_val.intBitCountTwosComp(mod);33167 lhs_bits = lhs_val.intBitCountTwosComp(pt);
32833 }33168 }
32834 lhs_bits += @intFromBool(!lhs_is_signed and dest_int_is_signed);33169 lhs_bits += @intFromBool(!lhs_is_signed and dest_int_is_signed);
32835 } else if (lhs_is_float) {33170 } else if (lhs_is_float) {
...@@ -32842,7 +33177,7 @@ fn cmpNumeric(...@@ -32842,7 +33177,7 @@ fn cmpNumeric(
32842 var rhs_bits: usize = undefined;33177 var rhs_bits: usize = undefined;
32843 if (try sema.resolveValueResolveLazy(rhs)) |rhs_val| {33178 if (try sema.resolveValueResolveLazy(rhs)) |rhs_val| {
32844 if (rhs_val.isUndef(mod))33179 if (rhs_val.isUndef(mod))
32845 return mod.undefRef(Type.bool);33180 return pt.undefRef(Type.bool);
32846 if (rhs_val.isNan(mod)) switch (op) {33181 if (rhs_val.isNan(mod)) switch (op) {
32847 .neq => return .bool_true,33182 .neq => return .bool_true,
32848 else => return .bool_false,33183 else => return .bool_false,
...@@ -32854,7 +33189,7 @@ fn cmpNumeric(...@@ -32854,7 +33189,7 @@ fn cmpNumeric(
32854 .lt, .lte => return if (rhs_val.isNegativeInf(mod)) .bool_false else .bool_true,33189 .lt, .lte => return if (rhs_val.isNegativeInf(mod)) .bool_false else .bool_true,
32855 };33190 };
32856 if (!lhs_is_signed) {33191 if (!lhs_is_signed) {
32857 switch (rhs_val.orderAgainstZero(mod)) {33192 switch (rhs_val.orderAgainstZero(pt)) {
32858 .gt => {},33193 .gt => {},
32859 .eq => switch (op) { // RHS = 0, LHS is unsigned33194 .eq => switch (op) { // RHS = 0, LHS is unsigned
32860 .gte => return .bool_true,33195 .gte => return .bool_true,
...@@ -32876,7 +33211,7 @@ fn cmpNumeric(...@@ -32876,7 +33211,7 @@ fn cmpNumeric(
32876 }33211 }
32877 }33212 }
3287833213
32879 var bigint = try float128IntPartToBigInt(sema.gpa, rhs_val.toFloat(f128, mod));33214 var bigint = try float128IntPartToBigInt(sema.gpa, rhs_val.toFloat(f128, pt));
32880 defer bigint.deinit();33215 defer bigint.deinit();
32881 if (rhs_val.floatHasFraction(mod)) {33216 if (rhs_val.floatHasFraction(mod)) {
32882 if (rhs_is_signed) {33217 if (rhs_is_signed) {
...@@ -32887,7 +33222,7 @@ fn cmpNumeric(...@@ -32887,7 +33222,7 @@ fn cmpNumeric(
32887 }33222 }
32888 rhs_bits = bigint.toConst().bitCountTwosComp();33223 rhs_bits = bigint.toConst().bitCountTwosComp();
32889 } else {33224 } else {
32890 rhs_bits = rhs_val.intBitCountTwosComp(mod);33225 rhs_bits = rhs_val.intBitCountTwosComp(pt);
32891 }33226 }
32892 rhs_bits += @intFromBool(!rhs_is_signed and dest_int_is_signed);33227 rhs_bits += @intFromBool(!rhs_is_signed and dest_int_is_signed);
32893 } else if (rhs_is_float) {33228 } else if (rhs_is_float) {
...@@ -32901,7 +33236,7 @@ fn cmpNumeric(...@@ -32901,7 +33236,7 @@ fn cmpNumeric(
32901 const max_bits = @max(lhs_bits, rhs_bits);33236 const max_bits = @max(lhs_bits, rhs_bits);
32902 const casted_bits = std.math.cast(u16, max_bits) orelse return sema.fail(block, src, "{d} exceeds maximum integer bit count", .{max_bits});33237 const casted_bits = std.math.cast(u16, max_bits) orelse return sema.fail(block, src, "{d} exceeds maximum integer bit count", .{max_bits});
32903 const signedness: std.builtin.Signedness = if (dest_int_is_signed) .signed else .unsigned;33238 const signedness: std.builtin.Signedness = if (dest_int_is_signed) .signed else .unsigned;
32904 break :blk try mod.intType(signedness, casted_bits);33239 break :blk try pt.intType(signedness, casted_bits);
32905 };33240 };
32906 const casted_lhs = try sema.coerce(block, dest_ty, lhs, lhs_src);33241 const casted_lhs = try sema.coerce(block, dest_ty, lhs, lhs_src);
32907 const casted_rhs = try sema.coerce(block, dest_ty, rhs, rhs_src);33242 const casted_rhs = try sema.coerce(block, dest_ty, rhs, rhs_src);
...@@ -32920,9 +33255,10 @@ fn compareIntsOnlyPossibleResult(...@@ -32920,9 +33255,10 @@ fn compareIntsOnlyPossibleResult(
32920 op: std.math.CompareOperator,33255 op: std.math.CompareOperator,
32921 rhs_ty: Type,33256 rhs_ty: Type,
32922) Allocator.Error!?bool {33257) Allocator.Error!?bool {
32923 const mod = sema.mod;33258 const pt = sema.pt;
33259 const mod = pt.zcu;
32924 const rhs_info = rhs_ty.intInfo(mod);33260 const rhs_info = rhs_ty.intInfo(mod);
32925 const vs_zero = lhs_val.orderAgainstZeroAdvanced(mod, .sema) catch unreachable;33261 const vs_zero = lhs_val.orderAgainstZeroAdvanced(pt, .sema) catch unreachable;
32926 const is_zero = vs_zero == .eq;33262 const is_zero = vs_zero == .eq;
32927 const is_negative = vs_zero == .lt;33263 const is_negative = vs_zero == .lt;
32928 const is_positive = vs_zero == .gt;33264 const is_positive = vs_zero == .gt;
...@@ -32954,7 +33290,7 @@ fn compareIntsOnlyPossibleResult(...@@ -32954,7 +33290,7 @@ fn compareIntsOnlyPossibleResult(
32954 };33290 };
3295533291
32956 const sign_adj = @intFromBool(!is_negative and rhs_info.signedness == .signed);33292 const sign_adj = @intFromBool(!is_negative and rhs_info.signedness == .signed);
32957 const req_bits = lhs_val.intBitCountTwosComp(mod) + sign_adj;33293 const req_bits = lhs_val.intBitCountTwosComp(pt) + sign_adj;
3295833294
32959 // No sized type can have more than 65535 bits.33295 // No sized type can have more than 65535 bits.
32960 // The RHS type operand is either a runtime value or sized (but undefined) constant.33296 // The RHS type operand is either a runtime value or sized (but undefined) constant.
...@@ -32981,11 +33317,11 @@ fn compareIntsOnlyPossibleResult(...@@ -32981,11 +33317,11 @@ fn compareIntsOnlyPossibleResult(
3298133317
32982 if (req_bits != rhs_info.bits) break :edge .{ false, false };33318 if (req_bits != rhs_info.bits) break :edge .{ false, false };
3298333319
32984 const ty = try mod.intType(33320 const ty = try pt.intType(
32985 if (is_negative) .signed else .unsigned,33321 if (is_negative) .signed else .unsigned,
32986 @intCast(req_bits),33322 @intCast(req_bits),
32987 );33323 );
32988 const pop_count = lhs_val.popCount(ty, mod);33324 const pop_count = lhs_val.popCount(ty, pt);
3298933325
32990 if (is_negative) {33326 if (is_negative) {
32991 break :edge .{ pop_count == 1, false };33327 break :edge .{ pop_count == 1, false };
...@@ -33015,7 +33351,8 @@ fn cmpVector(...@@ -33015,7 +33351,8 @@ fn cmpVector(
33015 lhs_src: LazySrcLoc,33351 lhs_src: LazySrcLoc,
33016 rhs_src: LazySrcLoc,33352 rhs_src: LazySrcLoc,
33017) CompileError!Air.Inst.Ref {33353) CompileError!Air.Inst.Ref {
33018 const mod = sema.mod;33354 const pt = sema.pt;
33355 const mod = pt.zcu;
33019 const lhs_ty = sema.typeOf(lhs);33356 const lhs_ty = sema.typeOf(lhs);
33020 const rhs_ty = sema.typeOf(rhs);33357 const rhs_ty = sema.typeOf(rhs);
33021 assert(lhs_ty.zigTypeTag(mod) == .Vector);33358 assert(lhs_ty.zigTypeTag(mod) == .Vector);
...@@ -33026,7 +33363,7 @@ fn cmpVector(...@@ -33026,7 +33363,7 @@ fn cmpVector(
33026 const casted_lhs = try sema.coerce(block, resolved_ty, lhs, lhs_src);33363 const casted_lhs = try sema.coerce(block, resolved_ty, lhs, lhs_src);
33027 const casted_rhs = try sema.coerce(block, resolved_ty, rhs, rhs_src);33364 const casted_rhs = try sema.coerce(block, resolved_ty, rhs, rhs_src);
3302833365
33029 const result_ty = try mod.vectorType(.{33366 const result_ty = try pt.vectorType(.{
33030 .len = lhs_ty.vectorLen(mod),33367 .len = lhs_ty.vectorLen(mod),
33031 .child = .bool_type,33368 .child = .bool_type,
33032 });33369 });
...@@ -33035,7 +33372,7 @@ fn cmpVector(...@@ -33035,7 +33372,7 @@ fn cmpVector(
33035 if (try sema.resolveValue(casted_lhs)) |lhs_val| {33372 if (try sema.resolveValue(casted_lhs)) |lhs_val| {
33036 if (try sema.resolveValue(casted_rhs)) |rhs_val| {33373 if (try sema.resolveValue(casted_rhs)) |rhs_val| {
33037 if (lhs_val.isUndef(mod) or rhs_val.isUndef(mod)) {33374 if (lhs_val.isUndef(mod) or rhs_val.isUndef(mod)) {
33038 return mod.undefRef(result_ty);33375 return pt.undefRef(result_ty);
33039 }33376 }
33040 const cmp_val = try sema.compareVector(lhs_val, op, rhs_val, resolved_ty);33377 const cmp_val = try sema.compareVector(lhs_val, op, rhs_val, resolved_ty);
33041 return Air.internedToRef(cmp_val.toIntern());33378 return Air.internedToRef(cmp_val.toIntern());
...@@ -33059,7 +33396,7 @@ fn wrapOptional(...@@ -33059,7 +33396,7 @@ fn wrapOptional(
33059 inst_src: LazySrcLoc,33396 inst_src: LazySrcLoc,
33060) !Air.Inst.Ref {33397) !Air.Inst.Ref {
33061 if (try sema.resolveValue(inst)) |val| {33398 if (try sema.resolveValue(inst)) |val| {
33062 return Air.internedToRef((try sema.mod.intern(.{ .opt = .{33399 return Air.internedToRef((try sema.pt.intern(.{ .opt = .{
33063 .ty = dest_ty.toIntern(),33400 .ty = dest_ty.toIntern(),
33064 .val = val.toIntern(),33401 .val = val.toIntern(),
33065 } })));33402 } })));
...@@ -33076,11 +33413,12 @@ fn wrapErrorUnionPayload(...@@ -33076,11 +33413,12 @@ fn wrapErrorUnionPayload(
33076 inst: Air.Inst.Ref,33413 inst: Air.Inst.Ref,
33077 inst_src: LazySrcLoc,33414 inst_src: LazySrcLoc,
33078) !Air.Inst.Ref {33415) !Air.Inst.Ref {
33079 const mod = sema.mod;33416 const pt = sema.pt;
33417 const mod = pt.zcu;
33080 const dest_payload_ty = dest_ty.errorUnionPayload(mod);33418 const dest_payload_ty = dest_ty.errorUnionPayload(mod);
33081 const coerced = try sema.coerceExtra(block, dest_payload_ty, inst, inst_src, .{ .report_err = false });33419 const coerced = try sema.coerceExtra(block, dest_payload_ty, inst, inst_src, .{ .report_err = false });
33082 if (try sema.resolveValue(coerced)) |val| {33420 if (try sema.resolveValue(coerced)) |val| {
33083 return Air.internedToRef((try mod.intern(.{ .error_union = .{33421 return Air.internedToRef((try pt.intern(.{ .error_union = .{
33084 .ty = dest_ty.toIntern(),33422 .ty = dest_ty.toIntern(),
33085 .val = .{ .payload = val.toIntern() },33423 .val = .{ .payload = val.toIntern() },
33086 } })));33424 } })));
...@@ -33096,7 +33434,8 @@ fn wrapErrorUnionSet(...@@ -33096,7 +33434,8 @@ fn wrapErrorUnionSet(
33096 inst: Air.Inst.Ref,33434 inst: Air.Inst.Ref,
33097 inst_src: LazySrcLoc,33435 inst_src: LazySrcLoc,
33098) !Air.Inst.Ref {33436) !Air.Inst.Ref {
33099 const mod = sema.mod;33437 const pt = sema.pt;
33438 const mod = pt.zcu;
33100 const ip = &mod.intern_pool;33439 const ip = &mod.intern_pool;
33101 const inst_ty = sema.typeOf(inst);33440 const inst_ty = sema.typeOf(inst);
33102 const dest_err_set_ty = dest_ty.errorUnionSet(mod);33441 const dest_err_set_ty = dest_ty.errorUnionSet(mod);
...@@ -33140,7 +33479,7 @@ fn wrapErrorUnionSet(...@@ -33140,7 +33479,7 @@ fn wrapErrorUnionSet(
33140 else => unreachable,33479 else => unreachable,
33141 },33480 },
33142 }33481 }
33143 return Air.internedToRef((try mod.intern(.{ .error_union = .{33482 return Air.internedToRef((try pt.intern(.{ .error_union = .{
33144 .ty = dest_ty.toIntern(),33483 .ty = dest_ty.toIntern(),
33145 .val = .{ .err_name = expected_name },33484 .val = .{ .err_name = expected_name },
33146 } })));33485 } })));
...@@ -33158,14 +33497,15 @@ fn unionToTag(...@@ -33158,14 +33497,15 @@ fn unionToTag(
33158 un: Air.Inst.Ref,33497 un: Air.Inst.Ref,
33159 un_src: LazySrcLoc,33498 un_src: LazySrcLoc,
33160) !Air.Inst.Ref {33499) !Air.Inst.Ref {
33161 const mod = sema.mod;33500 const pt = sema.pt;
33501 const mod = pt.zcu;
33162 if ((try sema.typeHasOnePossibleValue(enum_ty))) |opv| {33502 if ((try sema.typeHasOnePossibleValue(enum_ty))) |opv| {
33163 return Air.internedToRef(opv.toIntern());33503 return Air.internedToRef(opv.toIntern());
33164 }33504 }
33165 if (try sema.resolveValue(un)) |un_val| {33505 if (try sema.resolveValue(un)) |un_val| {
33166 const tag_val = un_val.unionTag(mod).?;33506 const tag_val = un_val.unionTag(mod).?;
33167 if (tag_val.isUndef(mod))33507 if (tag_val.isUndef(mod))
33168 return try mod.undefRef(enum_ty);33508 return try pt.undefRef(enum_ty);
33169 return Air.internedToRef(tag_val.toIntern());33509 return Air.internedToRef(tag_val.toIntern());
33170 }33510 }
33171 try sema.requireRuntimeBlock(block, un_src, null);33511 try sema.requireRuntimeBlock(block, un_src, null);
...@@ -33399,7 +33739,7 @@ const PeerResolveResult = union(enum) {...@@ -33399,7 +33739,7 @@ const PeerResolveResult = union(enum) {
33399 instructions: []const Air.Inst.Ref,33739 instructions: []const Air.Inst.Ref,
33400 candidate_srcs: PeerTypeCandidateSrc,33740 candidate_srcs: PeerTypeCandidateSrc,
33401 ) !*Module.ErrorMsg {33741 ) !*Module.ErrorMsg {
33402 const mod = sema.mod;33742 const pt = sema.pt;
3340333743
33404 var opt_msg: ?*Module.ErrorMsg = null;33744 var opt_msg: ?*Module.ErrorMsg = null;
33405 errdefer if (opt_msg) |msg| msg.destroy(sema.gpa);33745 errdefer if (opt_msg) |msg| msg.destroy(sema.gpa);
...@@ -33425,7 +33765,7 @@ const PeerResolveResult = union(enum) {...@@ -33425,7 +33765,7 @@ const PeerResolveResult = union(enum) {
33425 },33765 },
33426 .field_error => |field_error| {33766 .field_error => |field_error| {
33427 const fmt = "struct field '{}' has conflicting types";33767 const fmt = "struct field '{}' has conflicting types";
33428 const args = .{field_error.field_name.fmt(&mod.intern_pool)};33768 const args = .{field_error.field_name.fmt(&pt.zcu.intern_pool)};
33429 if (opt_msg) |msg| {33769 if (opt_msg) |msg| {
33430 try sema.errNote(src, msg, fmt, args);33770 try sema.errNote(src, msg, fmt, args);
33431 } else {33771 } else {
...@@ -33457,8 +33797,8 @@ const PeerResolveResult = union(enum) {...@@ -33457,8 +33797,8 @@ const PeerResolveResult = union(enum) {
3345733797
33458 const fmt = "incompatible types: '{}' and '{}'";33798 const fmt = "incompatible types: '{}' and '{}'";
33459 const args = .{33799 const args = .{
33460 conflict_tys[0].fmt(mod),33800 conflict_tys[0].fmt(pt),
33461 conflict_tys[1].fmt(mod),33801 conflict_tys[1].fmt(pt),
33462 };33802 };
33463 const msg = if (opt_msg) |msg| msg: {33803 const msg = if (opt_msg) |msg| msg: {
33464 try sema.errNote(src, msg, fmt, args);33804 try sema.errNote(src, msg, fmt, args);
...@@ -33469,8 +33809,8 @@ const PeerResolveResult = union(enum) {...@@ -33469,8 +33809,8 @@ const PeerResolveResult = union(enum) {
33469 break :msg msg;33809 break :msg msg;
33470 };33810 };
3347133811
33472 if (conflict_srcs[0]) |src_loc| try sema.errNote(src_loc, msg, "type '{}' here", .{conflict_tys[0].fmt(mod)});33812 if (conflict_srcs[0]) |src_loc| try sema.errNote(src_loc, msg, "type '{}' here", .{conflict_tys[0].fmt(pt)});
33473 if (conflict_srcs[1]) |src_loc| try sema.errNote(src_loc, msg, "type '{}' here", .{conflict_tys[1].fmt(mod)});33813 if (conflict_srcs[1]) |src_loc| try sema.errNote(src_loc, msg, "type '{}' here", .{conflict_tys[1].fmt(pt)});
3347433814
33475 // No child error33815 // No child error
33476 break;33816 break;
...@@ -33517,7 +33857,8 @@ fn resolvePeerTypesInner(...@@ -33517,7 +33857,8 @@ fn resolvePeerTypesInner(
33517 peer_tys: []?Type,33857 peer_tys: []?Type,
33518 peer_vals: []?Value,33858 peer_vals: []?Value,
33519) !PeerResolveResult {33859) !PeerResolveResult {
33520 const mod = sema.mod;33860 const pt = sema.pt;
33861 const mod = pt.zcu;
33521 const ip = &mod.intern_pool;33862 const ip = &mod.intern_pool;
3352233863
33523 var strat_reason: usize = 0;33864 var strat_reason: usize = 0;
...@@ -33581,7 +33922,7 @@ fn resolvePeerTypesInner(...@@ -33581,7 +33922,7 @@ fn resolvePeerTypesInner(
33581 .payload => |payload_ip| val_ptr.* = Value.fromInterned(payload_ip),33922 .payload => |payload_ip| val_ptr.* = Value.fromInterned(payload_ip),
33582 .err_name => val_ptr.* = null,33923 .err_name => val_ptr.* = null,
33583 },33924 },
33584 .undef => val_ptr.* = Value.fromInterned((try sema.mod.intern(.{ .undef = ty_ptr.*.?.toIntern() }))),33925 .undef => val_ptr.* = Value.fromInterned(try pt.intern(.{ .undef = ty_ptr.*.?.toIntern() })),
33585 else => unreachable,33926 else => unreachable,
33586 };33927 };
33587 break :blk set_ty;33928 break :blk set_ty;
...@@ -33604,7 +33945,7 @@ fn resolvePeerTypesInner(...@@ -33604,7 +33945,7 @@ fn resolvePeerTypesInner(
33604 .success => |ty| ty,33945 .success => |ty| ty,
33605 else => |result| return result,33946 else => |result| return result,
33606 };33947 };
33607 return .{ .success = try mod.errorUnionType(final_set.?, final_payload) };33948 return .{ .success = try pt.errorUnionType(final_set.?, final_payload) };
33608 },33949 },
3360933950
33610 .nullable => {33951 .nullable => {
...@@ -33642,7 +33983,7 @@ fn resolvePeerTypesInner(...@@ -33642,7 +33983,7 @@ fn resolvePeerTypesInner(
33642 .success => |ty| ty,33983 .success => |ty| ty,
33643 else => |result| return result,33984 else => |result| return result,
33644 };33985 };
33645 return .{ .success = try mod.optionalType(child_ty.toIntern()) };33986 return .{ .success = try pt.optionalType(child_ty.toIntern()) };
33646 },33987 },
3364733988
33648 .array => {33989 .array => {
...@@ -33730,7 +34071,7 @@ fn resolvePeerTypesInner(...@@ -33730,7 +34071,7 @@ fn resolvePeerTypesInner(
33730 // There should always be at least one array or vector peer34071 // There should always be at least one array or vector peer
33731 assert(opt_first_arr_idx != null);34072 assert(opt_first_arr_idx != null);
3373234073
33733 return .{ .success = try mod.arrayType(.{34074 return .{ .success = try pt.arrayType(.{
33734 .len = len,34075 .len = len,
33735 .child = elem_ty.toIntern(),34076 .child = elem_ty.toIntern(),
33736 .sentinel = if (sentinel) |sent_val| sent_val.toIntern() else .none,34077 .sentinel = if (sentinel) |sent_val| sent_val.toIntern() else .none,
...@@ -33792,7 +34133,7 @@ fn resolvePeerTypesInner(...@@ -33792,7 +34133,7 @@ fn resolvePeerTypesInner(
33792 else => |result| return result,34133 else => |result| return result,
33793 };34134 };
3379434135
33795 return .{ .success = try mod.vectorType(.{34136 return .{ .success = try pt.vectorType(.{
33796 .len = @intCast(len.?),34137 .len = @intCast(len.?),
33797 .child = child_ty.toIntern(),34138 .child = child_ty.toIntern(),
33798 }) };34139 }) };
...@@ -33844,8 +34185,8 @@ fn resolvePeerTypesInner(...@@ -33844,8 +34185,8 @@ fn resolvePeerTypesInner(
33844 }).toIntern();34185 }).toIntern();
3384534186
33846 if (ptr_info.sentinel != .none and peer_info.sentinel != .none) {34187 if (ptr_info.sentinel != .none and peer_info.sentinel != .none) {
33847 const peer_sent = try ip.getCoerced(sema.gpa, ptr_info.sentinel, ptr_info.child);34188 const peer_sent = try ip.getCoerced(sema.gpa, pt.tid, ptr_info.sentinel, ptr_info.child);
33848 const ptr_sent = try ip.getCoerced(sema.gpa, peer_info.sentinel, ptr_info.child);34189 const ptr_sent = try ip.getCoerced(sema.gpa, pt.tid, peer_info.sentinel, ptr_info.child);
33849 if (ptr_sent == peer_sent) {34190 if (ptr_sent == peer_sent) {
33850 ptr_info.sentinel = ptr_sent;34191 ptr_info.sentinel = ptr_sent;
33851 } else {34192 } else {
...@@ -33860,12 +34201,12 @@ fn resolvePeerTypesInner(...@@ -33860,12 +34201,12 @@ fn resolvePeerTypesInner(
33860 if (ptr_info.flags.alignment != .none)34201 if (ptr_info.flags.alignment != .none)
33861 ptr_info.flags.alignment34202 ptr_info.flags.alignment
33862 else34203 else
33863 Type.fromInterned(ptr_info.child).abiAlignment(mod),34204 Type.fromInterned(ptr_info.child).abiAlignment(pt),
3386434205
33865 if (peer_info.flags.alignment != .none)34206 if (peer_info.flags.alignment != .none)
33866 peer_info.flags.alignment34207 peer_info.flags.alignment
33867 else34208 else
33868 Type.fromInterned(peer_info.child).abiAlignment(mod),34209 Type.fromInterned(peer_info.child).abiAlignment(pt),
33869 );34210 );
33870 if (ptr_info.flags.address_space != peer_info.flags.address_space) {34211 if (ptr_info.flags.address_space != peer_info.flags.address_space) {
33871 return .{ .conflict = .{34212 return .{ .conflict = .{
...@@ -33888,7 +34229,7 @@ fn resolvePeerTypesInner(...@@ -33888,7 +34229,7 @@ fn resolvePeerTypesInner(
3388834229
33889 opt_ptr_info = ptr_info;34230 opt_ptr_info = ptr_info;
33890 }34231 }
33891 return .{ .success = try mod.ptrTypeSema(opt_ptr_info.?) };34232 return .{ .success = try pt.ptrTypeSema(opt_ptr_info.?) };
33892 },34233 },
3389334234
33894 .ptr => {34235 .ptr => {
...@@ -34004,7 +34345,7 @@ fn resolvePeerTypesInner(...@@ -34004,7 +34345,7 @@ fn resolvePeerTypesInner(
34004 if (try sema.resolvePairInMemoryCoercible(block, src, cur_arr.elem_ty, peer_arr.elem_ty)) |elem_ty| {34345 if (try sema.resolvePairInMemoryCoercible(block, src, cur_arr.elem_ty, peer_arr.elem_ty)) |elem_ty| {
34005 // *[n:x]T + *[n:y]T = *[n]T34346 // *[n:x]T + *[n:y]T = *[n]T
34006 if (cur_arr.len == peer_arr.len) {34347 if (cur_arr.len == peer_arr.len) {
34007 ptr_info.child = (try mod.arrayType(.{34348 ptr_info.child = (try pt.arrayType(.{
34008 .len = cur_arr.len,34349 .len = cur_arr.len,
34009 .child = elem_ty.toIntern(),34350 .child = elem_ty.toIntern(),
34010 })).toIntern();34351 })).toIntern();
...@@ -34148,12 +34489,12 @@ fn resolvePeerTypesInner(...@@ -34148,12 +34489,12 @@ fn resolvePeerTypesInner(
34148 no_sentinel: {34489 no_sentinel: {
34149 if (peer_sentinel == .none) break :no_sentinel;34490 if (peer_sentinel == .none) break :no_sentinel;
34150 if (cur_sentinel == .none) break :no_sentinel;34491 if (cur_sentinel == .none) break :no_sentinel;
34151 const peer_sent_coerced = try ip.getCoerced(sema.gpa, peer_sentinel, sentinel_ty);34492 const peer_sent_coerced = try ip.getCoerced(sema.gpa, pt.tid, peer_sentinel, sentinel_ty);
34152 const cur_sent_coerced = try ip.getCoerced(sema.gpa, cur_sentinel, sentinel_ty);34493 const cur_sent_coerced = try ip.getCoerced(sema.gpa, pt.tid, cur_sentinel, sentinel_ty);
34153 if (peer_sent_coerced != cur_sent_coerced) break :no_sentinel;34494 if (peer_sent_coerced != cur_sent_coerced) break :no_sentinel;
34154 // Sentinels match34495 // Sentinels match
34155 if (ptr_info.flags.size == .One) switch (ip.indexToKey(ptr_info.child)) {34496 if (ptr_info.flags.size == .One) switch (ip.indexToKey(ptr_info.child)) {
34156 .array_type => |array_type| ptr_info.child = (try mod.arrayType(.{34497 .array_type => |array_type| ptr_info.child = (try pt.arrayType(.{
34157 .len = array_type.len,34498 .len = array_type.len,
34158 .child = array_type.child,34499 .child = array_type.child,
34159 .sentinel = cur_sent_coerced,34500 .sentinel = cur_sent_coerced,
...@@ -34167,7 +34508,7 @@ fn resolvePeerTypesInner(...@@ -34167,7 +34508,7 @@ fn resolvePeerTypesInner(
34167 // Clear existing sentinel34508 // Clear existing sentinel
34168 ptr_info.sentinel = .none;34509 ptr_info.sentinel = .none;
34169 switch (ip.indexToKey(ptr_info.child)) {34510 switch (ip.indexToKey(ptr_info.child)) {
34170 .array_type => |array_type| ptr_info.child = (try mod.arrayType(.{34511 .array_type => |array_type| ptr_info.child = (try pt.arrayType(.{
34171 .len = array_type.len,34512 .len = array_type.len,
34172 .child = array_type.child,34513 .child = array_type.child,
34173 .sentinel = .none,34514 .sentinel = .none,
...@@ -34198,7 +34539,7 @@ fn resolvePeerTypesInner(...@@ -34198,7 +34539,7 @@ fn resolvePeerTypesInner(
34198 },34539 },
34199 }34540 }
3420034541
34201 return .{ .success = try mod.ptrTypeSema(opt_ptr_info.?) };34542 return .{ .success = try pt.ptrTypeSema(opt_ptr_info.?) };
34202 },34543 },
3420334544
34204 .func => {34545 .func => {
...@@ -34517,7 +34858,7 @@ fn resolvePeerTypesInner(...@@ -34517,7 +34858,7 @@ fn resolvePeerTypesInner(
34517 continue;34858 continue;
34518 };34859 };
34519 peer_field_ty.* = ty.structFieldType(field_index, mod);34860 peer_field_ty.* = ty.structFieldType(field_index, mod);
34520 peer_field_val.* = if (opt_val) |val| try val.fieldValue(mod, field_index) else null;34861 peer_field_val.* = if (opt_val) |val| try val.fieldValue(pt, field_index) else null;
34521 }34862 }
3452234863
34523 // Resolve field type recursively34864 // Resolve field type recursively
...@@ -34527,7 +34868,7 @@ fn resolvePeerTypesInner(...@@ -34527,7 +34868,7 @@ fn resolvePeerTypesInner(
34527 const result_buf = try sema.arena.create(PeerResolveResult);34868 const result_buf = try sema.arena.create(PeerResolveResult);
34528 result_buf.* = result;34869 result_buf.* = result;
34529 const field_name = if (is_tuple)34870 const field_name = if (is_tuple)
34530 try ip.getOrPutStringFmt(sema.gpa, "{d}", .{field_index}, .no_embedded_nulls)34871 try ip.getOrPutStringFmt(sema.gpa, pt.tid, "{d}", .{field_index}, .no_embedded_nulls)
34531 else34872 else
34532 field_names[field_index];34873 field_names[field_index];
3453334874
...@@ -34555,9 +34896,9 @@ fn resolvePeerTypesInner(...@@ -34555,9 +34896,9 @@ fn resolvePeerTypesInner(
34555 var comptime_val: ?Value = null;34896 var comptime_val: ?Value = null;
34556 for (peer_tys) |opt_ty| {34897 for (peer_tys) |opt_ty| {
34557 const struct_ty = opt_ty orelse continue;34898 const struct_ty = opt_ty orelse continue;
34558 try struct_ty.resolveStructFieldInits(mod);34899 try struct_ty.resolveStructFieldInits(pt);
3455934900
34560 const uncoerced_field_val = try struct_ty.structFieldValueComptime(mod, field_index) orelse {34901 const uncoerced_field_val = try struct_ty.structFieldValueComptime(pt, field_index) orelse {
34561 comptime_val = null;34902 comptime_val = null;
34562 break;34903 break;
34563 };34904 };
...@@ -34584,7 +34925,7 @@ fn resolvePeerTypesInner(...@@ -34584,7 +34925,7 @@ fn resolvePeerTypesInner(
34584 field_val.* = if (comptime_val) |v| v.toIntern() else .none;34925 field_val.* = if (comptime_val) |v| v.toIntern() else .none;
34585 }34926 }
3458634927
34587 const final_ty = try ip.getAnonStructType(mod.gpa, .{34928 const final_ty = try ip.getAnonStructType(mod.gpa, pt.tid, .{
34588 .types = field_types,34929 .types = field_types,
34589 .names = if (is_tuple) &.{} else field_names,34930 .names = if (is_tuple) &.{} else field_names,
34590 .values = field_vals,34931 .values = field_vals,
...@@ -34628,13 +34969,15 @@ fn maybeMergeErrorSets(sema: *Sema, block: *Block, src: LazySrcLoc, e0: Type, e1...@@ -34628,13 +34969,15 @@ fn maybeMergeErrorSets(sema: *Sema, block: *Block, src: LazySrcLoc, e0: Type, e1
34628}34969}
3462934970
34630fn resolvePairInMemoryCoercible(sema: *Sema, block: *Block, src: LazySrcLoc, ty_a: Type, ty_b: Type) !?Type {34971fn resolvePairInMemoryCoercible(sema: *Sema, block: *Block, src: LazySrcLoc, ty_a: Type, ty_b: Type) !?Type {
34972 const target = sema.pt.zcu.getTarget();
34973
34631 // ty_b -> ty_a34974 // ty_b -> ty_a
34632 if (.ok == try sema.coerceInMemoryAllowed(block, ty_a, ty_b, true, sema.mod.getTarget(), src, src)) {34975 if (.ok == try sema.coerceInMemoryAllowed(block, ty_a, ty_b, true, target, src, src)) {
34633 return ty_a;34976 return ty_a;
34634 }34977 }
3463534978
34636 // ty_a -> ty_b34979 // ty_a -> ty_b
34637 if (.ok == try sema.coerceInMemoryAllowed(block, ty_b, ty_a, true, sema.mod.getTarget(), src, src)) {34980 if (.ok == try sema.coerceInMemoryAllowed(block, ty_b, ty_a, true, target, src, src)) {
34638 return ty_b;34981 return ty_b;
34639 }34982 }
3464034983
...@@ -34647,7 +34990,8 @@ const ArrayLike = struct {...@@ -34647,7 +34990,8 @@ const ArrayLike = struct {
34647 elem_ty: Type,34990 elem_ty: Type,
34648};34991};
34649fn typeIsArrayLike(sema: *Sema, ty: Type) ?ArrayLike {34992fn typeIsArrayLike(sema: *Sema, ty: Type) ?ArrayLike {
34650 const mod = sema.mod;34993 const pt = sema.pt;
34994 const mod = pt.zcu;
34651 return switch (ty.zigTypeTag(mod)) {34995 return switch (ty.zigTypeTag(mod)) {
34652 .Array => .{34996 .Array => .{
34653 .len = ty.arrayLen(mod),34997 .len = ty.arrayLen(mod),
...@@ -34676,7 +35020,8 @@ fn typeIsArrayLike(sema: *Sema, ty: Type) ?ArrayLike {...@@ -34676,7 +35020,8 @@ fn typeIsArrayLike(sema: *Sema, ty: Type) ?ArrayLike {
34676}35020}
3467735021
34678pub fn resolveIes(sema: *Sema, block: *Block, src: LazySrcLoc) CompileError!void {35022pub fn resolveIes(sema: *Sema, block: *Block, src: LazySrcLoc) CompileError!void {
34679 const mod = sema.mod;35023 const pt = sema.pt;
35024 const mod = pt.zcu;
34680 const ip = &mod.intern_pool;35025 const ip = &mod.intern_pool;
3468135026
34682 if (sema.fn_ret_ty_ies) |ies| {35027 if (sema.fn_ret_ty_ies) |ies| {
...@@ -34687,26 +35032,27 @@ pub fn resolveIes(sema: *Sema, block: *Block, src: LazySrcLoc) CompileError!void...@@ -34687,26 +35032,27 @@ pub fn resolveIes(sema: *Sema, block: *Block, src: LazySrcLoc) CompileError!void
34687}35032}
3468835033
34689pub fn resolveFnTypes(sema: *Sema, fn_ty: Type) CompileError!void {35034pub fn resolveFnTypes(sema: *Sema, fn_ty: Type) CompileError!void {
34690 const mod = sema.mod;35035 const pt = sema.pt;
35036 const mod = pt.zcu;
34691 const ip = &mod.intern_pool;35037 const ip = &mod.intern_pool;
34692 const fn_ty_info = mod.typeToFunc(fn_ty).?;35038 const fn_ty_info = mod.typeToFunc(fn_ty).?;
3469335039
34694 try Type.fromInterned(fn_ty_info.return_type).resolveFully(mod);35040 try Type.fromInterned(fn_ty_info.return_type).resolveFully(pt);
3469535041
34696 if (mod.comp.config.any_error_tracing and35042 if (mod.comp.config.any_error_tracing and
34697 Type.fromInterned(fn_ty_info.return_type).isError(mod))35043 Type.fromInterned(fn_ty_info.return_type).isError(mod))
34698 {35044 {
34699 // Ensure the type exists so that backends can assume that.35045 // Ensure the type exists so that backends can assume that.
34700 _ = try mod.getBuiltinType("StackTrace");35046 _ = try pt.getBuiltinType("StackTrace");
34701 }35047 }
3470235048
34703 for (0..fn_ty_info.param_types.len) |i| {35049 for (0..fn_ty_info.param_types.len) |i| {
34704 try Type.fromInterned(fn_ty_info.param_types.get(ip)[i]).resolveFully(mod);35050 try Type.fromInterned(fn_ty_info.param_types.get(ip)[i]).resolveFully(pt);
34705 }35051 }
34706}35052}
3470735053
34708fn resolveLazyValue(sema: *Sema, val: Value) CompileError!Value {35054fn resolveLazyValue(sema: *Sema, val: Value) CompileError!Value {
34709 return val.resolveLazy(sema.arena, sema.mod);35055 return val.resolveLazy(sema.arena, sema.pt);
34710}35056}
3471135057
34712/// Resolve a struct's alignment only without triggering resolution of its layout.35058/// Resolve a struct's alignment only without triggering resolution of its layout.
...@@ -34716,7 +35062,8 @@ pub fn resolveStructAlignment(...@@ -34716,7 +35062,8 @@ pub fn resolveStructAlignment(
34716 ty: InternPool.Index,35062 ty: InternPool.Index,
34717 struct_type: InternPool.LoadedStructType,35063 struct_type: InternPool.LoadedStructType,
34718) SemaError!void {35064) SemaError!void {
34719 const mod = sema.mod;35065 const pt = sema.pt;
35066 const mod = pt.zcu;
34720 const ip = &mod.intern_pool;35067 const ip = &mod.intern_pool;
34721 const target = mod.getTarget();35068 const target = mod.getTarget();
3472235069
...@@ -34754,7 +35101,7 @@ pub fn resolveStructAlignment(...@@ -34754,7 +35101,7 @@ pub fn resolveStructAlignment(
34754 const field_ty = Type.fromInterned(struct_type.field_types.get(ip)[i]);35101 const field_ty = Type.fromInterned(struct_type.field_types.get(ip)[i]);
34755 if (struct_type.fieldIsComptime(ip, i) or try sema.typeRequiresComptime(field_ty))35102 if (struct_type.fieldIsComptime(ip, i) or try sema.typeRequiresComptime(field_ty))
34756 continue;35103 continue;
34757 const field_align = try mod.structFieldAlignmentAdvanced(35104 const field_align = try pt.structFieldAlignmentAdvanced(
34758 struct_type.fieldAlign(ip, i),35105 struct_type.fieldAlign(ip, i),
34759 field_ty,35106 field_ty,
34760 struct_type.layout,35107 struct_type.layout,
...@@ -34767,7 +35114,8 @@ pub fn resolveStructAlignment(...@@ -34767,7 +35114,8 @@ pub fn resolveStructAlignment(
34767}35114}
3476835115
34769pub fn resolveStructLayout(sema: *Sema, ty: Type) SemaError!void {35116pub fn resolveStructLayout(sema: *Sema, ty: Type) SemaError!void {
34770 const zcu = sema.mod;35117 const pt = sema.pt;
35118 const zcu = pt.zcu;
34771 const ip = &zcu.intern_pool;35119 const ip = &zcu.intern_pool;
34772 const struct_type = zcu.typeToStruct(ty) orelse return;35120 const struct_type = zcu.typeToStruct(ty) orelse return;
3477335121
...@@ -34776,10 +35124,10 @@ pub fn resolveStructLayout(sema: *Sema, ty: Type) SemaError!void {...@@ -34776,10 +35124,10 @@ pub fn resolveStructLayout(sema: *Sema, ty: Type) SemaError!void {
34776 if (struct_type.haveLayout(ip))35124 if (struct_type.haveLayout(ip))
34777 return;35125 return;
3477835126
34779 try ty.resolveFields(zcu);35127 try ty.resolveFields(pt);
3478035128
34781 if (struct_type.layout == .@"packed") {35129 if (struct_type.layout == .@"packed") {
34782 semaBackingIntType(zcu, struct_type) catch |err| switch (err) {35130 semaBackingIntType(pt, struct_type) catch |err| switch (err) {
34783 error.OutOfMemory, error.AnalysisFail => |e| return e,35131 error.OutOfMemory, error.AnalysisFail => |e| return e,
34784 error.ComptimeBreak, error.ComptimeReturn, error.GenericPoison => unreachable,35132 error.ComptimeBreak, error.ComptimeReturn, error.GenericPoison => unreachable,
34785 };35133 };
...@@ -34790,7 +35138,7 @@ pub fn resolveStructLayout(sema: *Sema, ty: Type) SemaError!void {...@@ -34790,7 +35138,7 @@ pub fn resolveStructLayout(sema: *Sema, ty: Type) SemaError!void {
34790 const msg = try sema.errMsg(35138 const msg = try sema.errMsg(
34791 ty.srcLoc(zcu),35139 ty.srcLoc(zcu),
34792 "struct '{}' depends on itself",35140 "struct '{}' depends on itself",
34793 .{ty.fmt(zcu)},35141 .{ty.fmt(pt)},
34794 );35142 );
34795 return sema.failWithOwnedErrorMsg(null, msg);35143 return sema.failWithOwnedErrorMsg(null, msg);
34796 }35144 }
...@@ -34818,7 +35166,7 @@ pub fn resolveStructLayout(sema: *Sema, ty: Type) SemaError!void {...@@ -34818,7 +35166,7 @@ pub fn resolveStructLayout(sema: *Sema, ty: Type) SemaError!void {
34818 },35166 },
34819 else => return err,35167 else => return err,
34820 };35168 };
34821 field_align.* = try zcu.structFieldAlignmentAdvanced(35169 field_align.* = try pt.structFieldAlignmentAdvanced(
34822 struct_type.fieldAlign(ip, i),35170 struct_type.fieldAlign(ip, i),
34823 field_ty,35171 field_ty,
34824 struct_type.layout,35172 struct_type.layout,
...@@ -34911,7 +35259,8 @@ pub fn resolveStructLayout(sema: *Sema, ty: Type) SemaError!void {...@@ -34911,7 +35259,8 @@ pub fn resolveStructLayout(sema: *Sema, ty: Type) SemaError!void {
34911 _ = try sema.typeRequiresComptime(ty);35259 _ = try sema.typeRequiresComptime(ty);
34912}35260}
3491335261
34914fn semaBackingIntType(zcu: *Zcu, struct_type: InternPool.LoadedStructType) CompileError!void {35262fn semaBackingIntType(pt: Zcu.PerThread, struct_type: InternPool.LoadedStructType) CompileError!void {
35263 const zcu = pt.zcu;
34915 const gpa = zcu.gpa;35264 const gpa = zcu.gpa;
34916 const ip = &zcu.intern_pool;35265 const ip = &zcu.intern_pool;
3491735266
...@@ -34927,7 +35276,7 @@ fn semaBackingIntType(zcu: *Zcu, struct_type: InternPool.LoadedStructType) Compi...@@ -34927,7 +35276,7 @@ fn semaBackingIntType(zcu: *Zcu, struct_type: InternPool.LoadedStructType) Compi
34927 defer comptime_err_ret_trace.deinit();35276 defer comptime_err_ret_trace.deinit();
3492835277
34929 var sema: Sema = .{35278 var sema: Sema = .{
34930 .mod = zcu,35279 .pt = pt,
34931 .gpa = gpa,35280 .gpa = gpa,
34932 .arena = analysis_arena.allocator(),35281 .arena = analysis_arena.allocator(),
34933 .code = zir,35282 .code = zir,
...@@ -34958,7 +35307,7 @@ fn semaBackingIntType(zcu: *Zcu, struct_type: InternPool.LoadedStructType) Compi...@@ -34958,7 +35307,7 @@ fn semaBackingIntType(zcu: *Zcu, struct_type: InternPool.LoadedStructType) Compi
34958 var accumulator: u64 = 0;35307 var accumulator: u64 = 0;
34959 for (0..struct_type.field_types.len) |i| {35308 for (0..struct_type.field_types.len) |i| {
34960 const field_ty = Type.fromInterned(struct_type.field_types.get(ip)[i]);35309 const field_ty = Type.fromInterned(struct_type.field_types.get(ip)[i]);
34961 accumulator += try field_ty.bitSizeAdvanced(zcu, .sema);35310 accumulator += try field_ty.bitSizeAdvanced(pt, .sema);
34962 }35311 }
34963 break :blk accumulator;35312 break :blk accumulator;
34964 };35313 };
...@@ -35004,7 +35353,7 @@ fn semaBackingIntType(zcu: *Zcu, struct_type: InternPool.LoadedStructType) Compi...@@ -35004,7 +35353,7 @@ fn semaBackingIntType(zcu: *Zcu, struct_type: InternPool.LoadedStructType) Compi
35004 if (fields_bit_sum > std.math.maxInt(u16)) {35353 if (fields_bit_sum > std.math.maxInt(u16)) {
35005 return sema.fail(&block, block.nodeOffset(0), "size of packed struct '{d}' exceeds maximum bit width of 65535", .{fields_bit_sum});35354 return sema.fail(&block, block.nodeOffset(0), "size of packed struct '{d}' exceeds maximum bit width of 65535", .{fields_bit_sum});
35006 }35355 }
35007 const backing_int_ty = try zcu.intType(.unsigned, @intCast(fields_bit_sum));35356 const backing_int_ty = try pt.intType(.unsigned, @intCast(fields_bit_sum));
35008 struct_type.backingIntType(ip).* = backing_int_ty.toIntern();35357 struct_type.backingIntType(ip).* = backing_int_ty.toIntern();
35009 }35358 }
3501035359
...@@ -35012,26 +35361,27 @@ fn semaBackingIntType(zcu: *Zcu, struct_type: InternPool.LoadedStructType) Compi...@@ -35012,26 +35361,27 @@ fn semaBackingIntType(zcu: *Zcu, struct_type: InternPool.LoadedStructType) Compi
35012}35361}
3501335362
35014fn checkBackingIntType(sema: *Sema, block: *Block, src: LazySrcLoc, backing_int_ty: Type, fields_bit_sum: u64) CompileError!void {35363fn checkBackingIntType(sema: *Sema, block: *Block, src: LazySrcLoc, backing_int_ty: Type, fields_bit_sum: u64) CompileError!void {
35015 const mod = sema.mod;35364 const pt = sema.pt;
35365 const mod = pt.zcu;
3501635366
35017 if (!backing_int_ty.isInt(mod)) {35367 if (!backing_int_ty.isInt(mod)) {
35018 return sema.fail(block, src, "expected backing integer type, found '{}'", .{backing_int_ty.fmt(sema.mod)});35368 return sema.fail(block, src, "expected backing integer type, found '{}'", .{backing_int_ty.fmt(pt)});
35019 }35369 }
35020 if (backing_int_ty.bitSize(mod) != fields_bit_sum) {35370 if (backing_int_ty.bitSize(pt) != fields_bit_sum) {
35021 return sema.fail(35371 return sema.fail(
35022 block,35372 block,
35023 src,35373 src,
35024 "backing integer type '{}' has bit size {} but the struct fields have a total bit size of {}",35374 "backing integer type '{}' has bit size {} but the struct fields have a total bit size of {}",
35025 .{ backing_int_ty.fmt(sema.mod), backing_int_ty.bitSize(mod), fields_bit_sum },35375 .{ backing_int_ty.fmt(pt), backing_int_ty.bitSize(pt), fields_bit_sum },
35026 );35376 );
35027 }35377 }
35028}35378}
3502935379
35030fn checkIndexable(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type) !void {35380fn checkIndexable(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type) !void {
35031 const mod = sema.mod;35381 const pt = sema.pt;
35032 if (!ty.isIndexable(mod)) {35382 if (!ty.isIndexable(pt.zcu)) {
35033 const msg = msg: {35383 const msg = msg: {
35034 const msg = try sema.errMsg(src, "type '{}' does not support indexing", .{ty.fmt(sema.mod)});35384 const msg = try sema.errMsg(src, "type '{}' does not support indexing", .{ty.fmt(pt)});
35035 errdefer msg.destroy(sema.gpa);35385 errdefer msg.destroy(sema.gpa);
35036 try sema.errNote(src, msg, "operand must be an array, slice, tuple, or vector", .{});35386 try sema.errNote(src, msg, "operand must be an array, slice, tuple, or vector", .{});
35037 break :msg msg;35387 break :msg msg;
...@@ -35041,7 +35391,8 @@ fn checkIndexable(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type) !void {...@@ -35041,7 +35391,8 @@ fn checkIndexable(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type) !void {
35041}35391}
3504235392
35043fn checkMemOperand(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type) !void {35393fn checkMemOperand(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type) !void {
35044 const mod = sema.mod;35394 const pt = sema.pt;
35395 const mod = pt.zcu;
35045 if (ty.zigTypeTag(mod) == .Pointer) {35396 if (ty.zigTypeTag(mod) == .Pointer) {
35046 switch (ty.ptrSize(mod)) {35397 switch (ty.ptrSize(mod)) {
35047 .Slice, .Many, .C => return,35398 .Slice, .Many, .C => return,
...@@ -35054,7 +35405,7 @@ fn checkMemOperand(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type) !void...@@ -35054,7 +35405,7 @@ fn checkMemOperand(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type) !void
35054 }35405 }
35055 }35406 }
35056 const msg = msg: {35407 const msg = msg: {
35057 const msg = try sema.errMsg(src, "type '{}' is not an indexable pointer", .{ty.fmt(sema.mod)});35408 const msg = try sema.errMsg(src, "type '{}' is not an indexable pointer", .{ty.fmt(pt)});
35058 errdefer msg.destroy(sema.gpa);35409 errdefer msg.destroy(sema.gpa);
35059 try sema.errNote(src, msg, "operand must be a slice, a many pointer or a pointer to an array", .{});35410 try sema.errNote(src, msg, "operand must be a slice, a many pointer or a pointer to an array", .{});
35060 break :msg msg;35411 break :msg msg;
...@@ -35069,9 +35420,9 @@ pub fn resolveUnionAlignment(...@@ -35069,9 +35420,9 @@ pub fn resolveUnionAlignment(
35069 ty: Type,35420 ty: Type,
35070 union_type: InternPool.LoadedUnionType,35421 union_type: InternPool.LoadedUnionType,
35071) SemaError!void {35422) SemaError!void {
35072 const mod = sema.mod;35423 const zcu = sema.pt.zcu;
35073 const ip = &mod.intern_pool;35424 const ip = &zcu.intern_pool;
35074 const target = mod.getTarget();35425 const target = zcu.getTarget();
3507535426
35076 assert(sema.ownerUnit().unwrap().decl == union_type.decl);35427 assert(sema.ownerUnit().unwrap().decl == union_type.decl);
3507735428
...@@ -35108,8 +35459,8 @@ pub fn resolveUnionAlignment(...@@ -35108,8 +35459,8 @@ pub fn resolveUnionAlignment(
3510835459
35109/// This logic must be kept in sync with `Module.getUnionLayout`.35460/// This logic must be kept in sync with `Module.getUnionLayout`.
35110pub fn resolveUnionLayout(sema: *Sema, ty: Type) SemaError!void {35461pub fn resolveUnionLayout(sema: *Sema, ty: Type) SemaError!void {
35111 const zcu = sema.mod;35462 const pt = sema.pt;
35112 const ip = &zcu.intern_pool;35463 const ip = &pt.zcu.intern_pool;
3511335464
35114 try sema.resolveTypeFieldsUnion(ty, ip.loadUnionType(ty.ip_index));35465 try sema.resolveTypeFieldsUnion(ty, ip.loadUnionType(ty.ip_index));
3511535466
...@@ -35122,9 +35473,9 @@ pub fn resolveUnionLayout(sema: *Sema, ty: Type) SemaError!void {...@@ -35122,9 +35473,9 @@ pub fn resolveUnionLayout(sema: *Sema, ty: Type) SemaError!void {
35122 .none, .have_field_types => {},35473 .none, .have_field_types => {},
35123 .field_types_wip, .layout_wip => {35474 .field_types_wip, .layout_wip => {
35124 const msg = try sema.errMsg(35475 const msg = try sema.errMsg(
35125 ty.srcLoc(zcu),35476 ty.srcLoc(pt.zcu),
35126 "union '{}' depends on itself",35477 "union '{}' depends on itself",
35127 .{ty.fmt(zcu)},35478 .{ty.fmt(pt)},
35128 );35479 );
35129 return sema.failWithOwnedErrorMsg(null, msg);35480 return sema.failWithOwnedErrorMsg(null, msg);
35130 },35481 },
...@@ -35143,7 +35494,7 @@ pub fn resolveUnionLayout(sema: *Sema, ty: Type) SemaError!void {...@@ -35143,7 +35494,7 @@ pub fn resolveUnionLayout(sema: *Sema, ty: Type) SemaError!void {
35143 for (0..union_type.field_types.len) |field_index| {35494 for (0..union_type.field_types.len) |field_index| {
35144 const field_ty = Type.fromInterned(union_type.field_types.get(ip)[field_index]);35495 const field_ty = Type.fromInterned(union_type.field_types.get(ip)[field_index]);
3514535496
35146 if (try sema.typeRequiresComptime(field_ty) or field_ty.zigTypeTag(zcu) == .NoReturn) continue; // TODO: should this affect alignment?35497 if (try sema.typeRequiresComptime(field_ty) or field_ty.zigTypeTag(pt.zcu) == .NoReturn) continue; // TODO: should this affect alignment?
3514735498
35148 max_size = @max(max_size, sema.typeAbiSize(field_ty) catch |err| switch (err) {35499 max_size = @max(max_size, sema.typeAbiSize(field_ty) catch |err| switch (err) {
35149 error.AnalysisFail => {35500 error.AnalysisFail => {
...@@ -35185,7 +35536,7 @@ pub fn resolveUnionLayout(sema: *Sema, ty: Type) SemaError!void {...@@ -35185,7 +35536,7 @@ pub fn resolveUnionLayout(sema: *Sema, ty: Type) SemaError!void {
35185 } else {35536 } else {
35186 // {Payload, Tag}35537 // {Payload, Tag}
35187 size += max_size;35538 size += max_size;
35188 size = switch (zcu.getTarget().ofmt) {35539 size = switch (pt.zcu.getTarget().ofmt) {
35189 .c => max_align,35540 .c => max_align,
35190 else => tag_align,35541 else => tag_align,
35191 }.forward(size);35542 }.forward(size);
...@@ -35205,7 +35556,7 @@ pub fn resolveUnionLayout(sema: *Sema, ty: Type) SemaError!void {...@@ -35205,7 +35556,7 @@ pub fn resolveUnionLayout(sema: *Sema, ty: Type) SemaError!void {
3520535556
35206 if (union_type.flagsPtr(ip).assumed_runtime_bits and !(try sema.typeHasRuntimeBits(ty))) {35557 if (union_type.flagsPtr(ip).assumed_runtime_bits and !(try sema.typeHasRuntimeBits(ty))) {
35207 const msg = try sema.errMsg(35558 const msg = try sema.errMsg(
35208 ty.srcLoc(zcu),35559 ty.srcLoc(pt.zcu),
35209 "union layout depends on it having runtime bits",35560 "union layout depends on it having runtime bits",
35210 .{},35561 .{},
35211 );35562 );
...@@ -35213,10 +35564,10 @@ pub fn resolveUnionLayout(sema: *Sema, ty: Type) SemaError!void {...@@ -35213,10 +35564,10 @@ pub fn resolveUnionLayout(sema: *Sema, ty: Type) SemaError!void {
35213 }35564 }
3521435565
35215 if (union_type.flagsPtr(ip).assumed_pointer_aligned and35566 if (union_type.flagsPtr(ip).assumed_pointer_aligned and
35216 alignment.compareStrict(.neq, Alignment.fromByteUnits(@divExact(zcu.getTarget().ptrBitWidth(), 8))))35567 alignment.compareStrict(.neq, Alignment.fromByteUnits(@divExact(pt.zcu.getTarget().ptrBitWidth(), 8))))
35217 {35568 {
35218 const msg = try sema.errMsg(35569 const msg = try sema.errMsg(
35219 ty.srcLoc(zcu),35570 ty.srcLoc(pt.zcu),
35220 "union layout depends on being pointer aligned",35571 "union layout depends on being pointer aligned",
35221 .{},35572 .{},
35222 );35573 );
...@@ -35229,7 +35580,8 @@ pub fn resolveUnionLayout(sema: *Sema, ty: Type) SemaError!void {...@@ -35229,7 +35580,8 @@ pub fn resolveUnionLayout(sema: *Sema, ty: Type) SemaError!void {
35229pub fn resolveStructFully(sema: *Sema, ty: Type) SemaError!void {35580pub fn resolveStructFully(sema: *Sema, ty: Type) SemaError!void {
35230 try sema.resolveStructLayout(ty);35581 try sema.resolveStructLayout(ty);
3523135582
35232 const mod = sema.mod;35583 const pt = sema.pt;
35584 const mod = pt.zcu;
35233 const ip = &mod.intern_pool;35585 const ip = &mod.intern_pool;
35234 const struct_type = mod.typeToStruct(ty).?;35586 const struct_type = mod.typeToStruct(ty).?;
3523535587
...@@ -35244,14 +35596,15 @@ pub fn resolveStructFully(sema: *Sema, ty: Type) SemaError!void {...@@ -35244,14 +35596,15 @@ pub fn resolveStructFully(sema: *Sema, ty: Type) SemaError!void {
3524435596
35245 for (0..struct_type.field_types.len) |i| {35597 for (0..struct_type.field_types.len) |i| {
35246 const field_ty = Type.fromInterned(struct_type.field_types.get(ip)[i]);35598 const field_ty = Type.fromInterned(struct_type.field_types.get(ip)[i]);
35247 try field_ty.resolveFully(mod);35599 try field_ty.resolveFully(pt);
35248 }35600 }
35249}35601}
3525035602
35251pub fn resolveUnionFully(sema: *Sema, ty: Type) SemaError!void {35603pub fn resolveUnionFully(sema: *Sema, ty: Type) SemaError!void {
35252 try sema.resolveUnionLayout(ty);35604 try sema.resolveUnionLayout(ty);
3525335605
35254 const mod = sema.mod;35606 const pt = sema.pt;
35607 const mod = pt.zcu;
35255 const ip = &mod.intern_pool;35608 const ip = &mod.intern_pool;
35256 const union_obj = mod.typeToUnion(ty).?;35609 const union_obj = mod.typeToUnion(ty).?;
3525735610
...@@ -35272,7 +35625,7 @@ pub fn resolveUnionFully(sema: *Sema, ty: Type) SemaError!void {...@@ -35272,7 +35625,7 @@ pub fn resolveUnionFully(sema: *Sema, ty: Type) SemaError!void {
35272 union_obj.flagsPtr(ip).status = .fully_resolved_wip;35625 union_obj.flagsPtr(ip).status = .fully_resolved_wip;
35273 for (0..union_obj.field_types.len) |field_index| {35626 for (0..union_obj.field_types.len) |field_index| {
35274 const field_ty = Type.fromInterned(union_obj.field_types.get(ip)[field_index]);35627 const field_ty = Type.fromInterned(union_obj.field_types.get(ip)[field_index]);
35275 try field_ty.resolveFully(mod);35628 try field_ty.resolveFully(pt);
35276 }35629 }
35277 union_obj.flagsPtr(ip).status = .fully_resolved;35630 union_obj.flagsPtr(ip).status = .fully_resolved;
35278 }35631 }
...@@ -35286,7 +35639,8 @@ pub fn resolveTypeFieldsStruct(...@@ -35286,7 +35639,8 @@ pub fn resolveTypeFieldsStruct(
35286 ty: InternPool.Index,35639 ty: InternPool.Index,
35287 struct_type: InternPool.LoadedStructType,35640 struct_type: InternPool.LoadedStructType,
35288) SemaError!void {35641) SemaError!void {
35289 const zcu = sema.mod;35642 const pt = sema.pt;
35643 const zcu = pt.zcu;
35290 const ip = &zcu.intern_pool;35644 const ip = &zcu.intern_pool;
35291 // If there is no owner decl it means the struct has no fields.35645 // If there is no owner decl it means the struct has no fields.
35292 const owner_decl = struct_type.decl.unwrap() orelse return;35646 const owner_decl = struct_type.decl.unwrap() orelse return;
...@@ -35310,13 +35664,13 @@ pub fn resolveTypeFieldsStruct(...@@ -35310,13 +35664,13 @@ pub fn resolveTypeFieldsStruct(
35310 const msg = try sema.errMsg(35664 const msg = try sema.errMsg(
35311 Type.fromInterned(ty).srcLoc(zcu),35665 Type.fromInterned(ty).srcLoc(zcu),
35312 "struct '{}' depends on itself",35666 "struct '{}' depends on itself",
35313 .{Type.fromInterned(ty).fmt(zcu)},35667 .{Type.fromInterned(ty).fmt(pt)},
35314 );35668 );
35315 return sema.failWithOwnedErrorMsg(null, msg);35669 return sema.failWithOwnedErrorMsg(null, msg);
35316 }35670 }
35317 defer struct_type.clearTypesWip(ip);35671 defer struct_type.clearTypesWip(ip);
3531835672
35319 semaStructFields(zcu, sema.arena, struct_type) catch |err| switch (err) {35673 semaStructFields(pt, sema.arena, struct_type) catch |err| switch (err) {
35320 error.AnalysisFail => {35674 error.AnalysisFail => {
35321 if (zcu.declPtr(owner_decl).analysis == .complete) {35675 if (zcu.declPtr(owner_decl).analysis == .complete) {
35322 zcu.declPtr(owner_decl).analysis = .dependency_failure;35676 zcu.declPtr(owner_decl).analysis = .dependency_failure;
...@@ -35329,7 +35683,8 @@ pub fn resolveTypeFieldsStruct(...@@ -35329,7 +35683,8 @@ pub fn resolveTypeFieldsStruct(
35329}35683}
3533035684
35331pub fn resolveStructFieldInits(sema: *Sema, ty: Type) SemaError!void {35685pub fn resolveStructFieldInits(sema: *Sema, ty: Type) SemaError!void {
35332 const zcu = sema.mod;35686 const pt = sema.pt;
35687 const zcu = pt.zcu;
35333 const ip = &zcu.intern_pool;35688 const ip = &zcu.intern_pool;
35334 const struct_type = zcu.typeToStruct(ty) orelse return;35689 const struct_type = zcu.typeToStruct(ty) orelse return;
35335 const owner_decl = struct_type.decl.unwrap() orelse return;35690 const owner_decl = struct_type.decl.unwrap() orelse return;
...@@ -35345,13 +35700,13 @@ pub fn resolveStructFieldInits(sema: *Sema, ty: Type) SemaError!void {...@@ -35345,13 +35700,13 @@ pub fn resolveStructFieldInits(sema: *Sema, ty: Type) SemaError!void {
35345 const msg = try sema.errMsg(35700 const msg = try sema.errMsg(
35346 ty.srcLoc(zcu),35701 ty.srcLoc(zcu),
35347 "struct '{}' depends on itself",35702 "struct '{}' depends on itself",
35348 .{ty.fmt(zcu)},35703 .{ty.fmt(pt)},
35349 );35704 );
35350 return sema.failWithOwnedErrorMsg(null, msg);35705 return sema.failWithOwnedErrorMsg(null, msg);
35351 }35706 }
35352 defer struct_type.clearInitsWip(ip);35707 defer struct_type.clearInitsWip(ip);
3535335708
35354 semaStructFieldInits(zcu, sema.arena, struct_type) catch |err| switch (err) {35709 semaStructFieldInits(pt, sema.arena, struct_type) catch |err| switch (err) {
35355 error.AnalysisFail => {35710 error.AnalysisFail => {
35356 if (zcu.declPtr(owner_decl).analysis == .complete) {35711 if (zcu.declPtr(owner_decl).analysis == .complete) {
35357 zcu.declPtr(owner_decl).analysis = .dependency_failure;35712 zcu.declPtr(owner_decl).analysis = .dependency_failure;
...@@ -35365,7 +35720,8 @@ pub fn resolveStructFieldInits(sema: *Sema, ty: Type) SemaError!void {...@@ -35365,7 +35720,8 @@ pub fn resolveStructFieldInits(sema: *Sema, ty: Type) SemaError!void {
35365}35720}
3536635721
35367pub fn resolveTypeFieldsUnion(sema: *Sema, ty: Type, union_type: InternPool.LoadedUnionType) SemaError!void {35722pub fn resolveTypeFieldsUnion(sema: *Sema, ty: Type, union_type: InternPool.LoadedUnionType) SemaError!void {
35368 const zcu = sema.mod;35723 const pt = sema.pt;
35724 const zcu = pt.zcu;
35369 const ip = &zcu.intern_pool;35725 const ip = &zcu.intern_pool;
35370 const owner_decl = zcu.declPtr(union_type.decl);35726 const owner_decl = zcu.declPtr(union_type.decl);
3537135727
...@@ -35387,7 +35743,7 @@ pub fn resolveTypeFieldsUnion(sema: *Sema, ty: Type, union_type: InternPool.Load...@@ -35387,7 +35743,7 @@ pub fn resolveTypeFieldsUnion(sema: *Sema, ty: Type, union_type: InternPool.Load
35387 const msg = try sema.errMsg(35743 const msg = try sema.errMsg(
35388 ty.srcLoc(zcu),35744 ty.srcLoc(zcu),
35389 "union '{}' depends on itself",35745 "union '{}' depends on itself",
35390 .{ty.fmt(zcu)},35746 .{ty.fmt(pt)},
35391 );35747 );
35392 return sema.failWithOwnedErrorMsg(null, msg);35748 return sema.failWithOwnedErrorMsg(null, msg);
35393 },35749 },
...@@ -35401,7 +35757,7 @@ pub fn resolveTypeFieldsUnion(sema: *Sema, ty: Type, union_type: InternPool.Load...@@ -35401,7 +35757,7 @@ pub fn resolveTypeFieldsUnion(sema: *Sema, ty: Type, union_type: InternPool.Load
3540135757
35402 union_type.flagsPtr(ip).status = .field_types_wip;35758 union_type.flagsPtr(ip).status = .field_types_wip;
35403 errdefer union_type.flagsPtr(ip).status = .none;35759 errdefer union_type.flagsPtr(ip).status = .none;
35404 semaUnionFields(zcu, sema.arena, union_type) catch |err| switch (err) {35760 semaUnionFields(pt, sema.arena, union_type) catch |err| switch (err) {
35405 error.AnalysisFail => {35761 error.AnalysisFail => {
35406 if (owner_decl.analysis == .complete) {35762 if (owner_decl.analysis == .complete) {
35407 owner_decl.analysis = .dependency_failure;35763 owner_decl.analysis = .dependency_failure;
...@@ -35422,7 +35778,8 @@ fn resolveInferredErrorSet(...@@ -35422,7 +35778,8 @@ fn resolveInferredErrorSet(
35422 src: LazySrcLoc,35778 src: LazySrcLoc,
35423 ies_index: InternPool.Index,35779 ies_index: InternPool.Index,
35424) CompileError!InternPool.Index {35780) CompileError!InternPool.Index {
35425 const mod = sema.mod;35781 const pt = sema.pt;
35782 const mod = pt.zcu;
35426 const ip = &mod.intern_pool;35783 const ip = &mod.intern_pool;
35427 const func_index = ip.iesFuncIndex(ies_index);35784 const func_index = ip.iesFuncIndex(ies_index);
35428 const func = mod.funcInfo(func_index);35785 const func = mod.funcInfo(func_index);
...@@ -35482,8 +35839,8 @@ pub fn resolveInferredErrorSetPtr(...@@ -35482,8 +35839,8 @@ pub fn resolveInferredErrorSetPtr(
35482 src: LazySrcLoc,35839 src: LazySrcLoc,
35483 ies: *InferredErrorSet,35840 ies: *InferredErrorSet,
35484) CompileError!void {35841) CompileError!void {
35485 const mod = sema.mod;35842 const pt = sema.pt;
35486 const ip = &mod.intern_pool;35843 const ip = &pt.zcu.intern_pool;
3548735844
35488 if (ies.resolved != .none) return;35845 if (ies.resolved != .none) return;
3548935846
...@@ -35505,7 +35862,7 @@ pub fn resolveInferredErrorSetPtr(...@@ -35505,7 +35862,7 @@ pub fn resolveInferredErrorSetPtr(
35505 }35862 }
35506 }35863 }
3550735864
35508 const resolved_error_set_ty = try mod.errorSetFromUnsortedNames(ies.errors.keys());35865 const resolved_error_set_ty = try pt.errorSetFromUnsortedNames(ies.errors.keys());
35509 ies.resolved = resolved_error_set_ty.toIntern();35866 ies.resolved = resolved_error_set_ty.toIntern();
35510}35867}
3551135868
...@@ -35515,12 +35872,13 @@ fn resolveAdHocInferredErrorSet(...@@ -35515,12 +35872,13 @@ fn resolveAdHocInferredErrorSet(
35515 src: LazySrcLoc,35872 src: LazySrcLoc,
35516 value: InternPool.Index,35873 value: InternPool.Index,
35517) CompileError!InternPool.Index {35874) CompileError!InternPool.Index {
35518 const mod = sema.mod;35875 const pt = sema.pt;
35876 const mod = pt.zcu;
35519 const gpa = sema.gpa;35877 const gpa = sema.gpa;
35520 const ip = &mod.intern_pool;35878 const ip = &mod.intern_pool;
35521 const new_ty = try resolveAdHocInferredErrorSetTy(sema, block, src, ip.typeOf(value));35879 const new_ty = try resolveAdHocInferredErrorSetTy(sema, block, src, ip.typeOf(value));
35522 if (new_ty == .none) return value;35880 if (new_ty == .none) return value;
35523 return ip.getCoerced(gpa, value, new_ty);35881 return ip.getCoerced(gpa, pt.tid, value, new_ty);
35524}35882}
3552535883
35526fn resolveAdHocInferredErrorSetTy(35884fn resolveAdHocInferredErrorSetTy(
...@@ -35530,8 +35888,8 @@ fn resolveAdHocInferredErrorSetTy(...@@ -35530,8 +35888,8 @@ fn resolveAdHocInferredErrorSetTy(
35530 ty: InternPool.Index,35888 ty: InternPool.Index,
35531) CompileError!InternPool.Index {35889) CompileError!InternPool.Index {
35532 const ies = sema.fn_ret_ty_ies orelse return .none;35890 const ies = sema.fn_ret_ty_ies orelse return .none;
35533 const mod = sema.mod;35891 const pt = sema.pt;
35534 const gpa = sema.gpa;35892 const mod = pt.zcu;
35535 const ip = &mod.intern_pool;35893 const ip = &mod.intern_pool;
35536 const error_union_info = switch (ip.indexToKey(ty)) {35894 const error_union_info = switch (ip.indexToKey(ty)) {
35537 .error_union_type => |x| x,35895 .error_union_type => |x| x,
...@@ -35541,7 +35899,7 @@ fn resolveAdHocInferredErrorSetTy(...@@ -35541,7 +35899,7 @@ fn resolveAdHocInferredErrorSetTy(
35541 return .none;35899 return .none;
3554235900
35543 try sema.resolveInferredErrorSetPtr(block, src, ies);35901 try sema.resolveInferredErrorSetPtr(block, src, ies);
35544 const new_ty = try ip.get(gpa, .{ .error_union_type = .{35902 const new_ty = try pt.intern(.{ .error_union_type = .{
35545 .error_set_type = ies.resolved,35903 .error_set_type = ies.resolved,
35546 .payload_type = error_union_info.payload_type,35904 .payload_type = error_union_info.payload_type,
35547 } });35905 } });
...@@ -35554,7 +35912,8 @@ fn resolveInferredErrorSetTy(...@@ -35554,7 +35912,8 @@ fn resolveInferredErrorSetTy(
35554 src: LazySrcLoc,35912 src: LazySrcLoc,
35555 ty: InternPool.Index,35913 ty: InternPool.Index,
35556) CompileError!InternPool.Index {35914) CompileError!InternPool.Index {
35557 const mod = sema.mod;35915 const pt = sema.pt;
35916 const mod = pt.zcu;
35558 const ip = &mod.intern_pool;35917 const ip = &mod.intern_pool;
35559 if (ty == .anyerror_type) return ty;35918 if (ty == .anyerror_type) return ty;
35560 switch (ip.indexToKey(ty)) {35919 switch (ip.indexToKey(ty)) {
...@@ -35614,10 +35973,11 @@ fn structZirInfo(zir: Zir, zir_index: Zir.Inst.Index) struct {...@@ -35614,10 +35973,11 @@ fn structZirInfo(zir: Zir, zir_index: Zir.Inst.Index) struct {
35614}35973}
3561535974
35616fn semaStructFields(35975fn semaStructFields(
35617 zcu: *Zcu,35976 pt: Zcu.PerThread,
35618 arena: Allocator,35977 arena: Allocator,
35619 struct_type: InternPool.LoadedStructType,35978 struct_type: InternPool.LoadedStructType,
35620) CompileError!void {35979) CompileError!void {
35980 const zcu = pt.zcu;
35621 const gpa = zcu.gpa;35981 const gpa = zcu.gpa;
35622 const ip = &zcu.intern_pool;35982 const ip = &zcu.intern_pool;
35623 const decl_index = struct_type.decl.unwrap() orelse return;35983 const decl_index = struct_type.decl.unwrap() orelse return;
...@@ -35630,7 +35990,7 @@ fn semaStructFields(...@@ -35630,7 +35990,7 @@ fn semaStructFields(
3563035990
35631 if (fields_len == 0) switch (struct_type.layout) {35991 if (fields_len == 0) switch (struct_type.layout) {
35632 .@"packed" => {35992 .@"packed" => {
35633 try semaBackingIntType(zcu, struct_type);35993 try semaBackingIntType(pt, struct_type);
35634 return;35994 return;
35635 },35995 },
35636 .auto, .@"extern" => {35996 .auto, .@"extern" => {
...@@ -35644,7 +36004,7 @@ fn semaStructFields(...@@ -35644,7 +36004,7 @@ fn semaStructFields(
35644 defer comptime_err_ret_trace.deinit();36004 defer comptime_err_ret_trace.deinit();
3564536005
35646 var sema: Sema = .{36006 var sema: Sema = .{
35647 .mod = zcu,36007 .pt = pt,
35648 .gpa = gpa,36008 .gpa = gpa,
35649 .arena = arena,36009 .arena = arena,
35650 .code = zir,36010 .code = zir,
...@@ -35725,7 +36085,7 @@ fn semaStructFields(...@@ -35725,7 +36085,7 @@ fn semaStructFields(
3572536085
35726 // This string needs to outlive the ZIR code.36086 // This string needs to outlive the ZIR code.
35727 if (opt_field_name_zir) |field_name_zir| {36087 if (opt_field_name_zir) |field_name_zir| {
35728 const field_name = try ip.getOrPutString(gpa, field_name_zir, .no_embedded_nulls);36088 const field_name = try ip.getOrPutString(gpa, pt.tid, field_name_zir, .no_embedded_nulls);
35729 assert(struct_type.addFieldName(ip, field_name) == null);36089 assert(struct_type.addFieldName(ip, field_name) == null);
35730 }36090 }
3573136091
...@@ -35789,7 +36149,7 @@ fn semaStructFields(...@@ -35789,7 +36149,7 @@ fn semaStructFields(
35789 switch (struct_type.layout) {36149 switch (struct_type.layout) {
35790 .@"extern" => if (!try sema.validateExternType(field_ty, .struct_field)) {36150 .@"extern" => if (!try sema.validateExternType(field_ty, .struct_field)) {
35791 const msg = msg: {36151 const msg = msg: {
35792 const msg = try sema.errMsg(ty_src, "extern structs cannot contain fields of type '{}'", .{field_ty.fmt(zcu)});36152 const msg = try sema.errMsg(ty_src, "extern structs cannot contain fields of type '{}'", .{field_ty.fmt(pt)});
35793 errdefer msg.destroy(sema.gpa);36153 errdefer msg.destroy(sema.gpa);
3579436154
35795 try sema.explainWhyTypeIsNotExtern(msg, ty_src, field_ty, .struct_field);36155 try sema.explainWhyTypeIsNotExtern(msg, ty_src, field_ty, .struct_field);
...@@ -35801,7 +36161,7 @@ fn semaStructFields(...@@ -35801,7 +36161,7 @@ fn semaStructFields(
35801 },36161 },
35802 .@"packed" => if (!try sema.validatePackedType(field_ty)) {36162 .@"packed" => if (!try sema.validatePackedType(field_ty)) {
35803 const msg = msg: {36163 const msg = msg: {
35804 const msg = try sema.errMsg(ty_src, "packed structs cannot contain fields of type '{}'", .{field_ty.fmt(zcu)});36164 const msg = try sema.errMsg(ty_src, "packed structs cannot contain fields of type '{}'", .{field_ty.fmt(pt)});
35805 errdefer msg.destroy(sema.gpa);36165 errdefer msg.destroy(sema.gpa);
3580636166
35807 try sema.explainWhyTypeIsNotPacked(msg, ty_src, field_ty);36167 try sema.explainWhyTypeIsNotPacked(msg, ty_src, field_ty);
...@@ -35837,10 +36197,11 @@ fn semaStructFields(...@@ -35837,10 +36197,11 @@ fn semaStructFields(
3583736197
35838// This logic must be kept in sync with `semaStructFields`36198// This logic must be kept in sync with `semaStructFields`
35839fn semaStructFieldInits(36199fn semaStructFieldInits(
35840 zcu: *Zcu,36200 pt: Zcu.PerThread,
35841 arena: Allocator,36201 arena: Allocator,
35842 struct_type: InternPool.LoadedStructType,36202 struct_type: InternPool.LoadedStructType,
35843) CompileError!void {36203) CompileError!void {
36204 const zcu = pt.zcu;
35844 const gpa = zcu.gpa;36205 const gpa = zcu.gpa;
35845 const ip = &zcu.intern_pool;36206 const ip = &zcu.intern_pool;
3584636207
...@@ -35857,7 +36218,7 @@ fn semaStructFieldInits(...@@ -35857,7 +36218,7 @@ fn semaStructFieldInits(
35857 defer comptime_err_ret_trace.deinit();36218 defer comptime_err_ret_trace.deinit();
3585836219
35859 var sema: Sema = .{36220 var sema: Sema = .{
35860 .mod = zcu,36221 .pt = pt,
35861 .gpa = gpa,36222 .gpa = gpa,
35862 .arena = arena,36223 .arena = arena,
35863 .code = zir,36224 .code = zir,
...@@ -35977,10 +36338,11 @@ fn semaStructFieldInits(...@@ -35977,10 +36338,11 @@ fn semaStructFieldInits(
35977 try sema.flushExports();36338 try sema.flushExports();
35978}36339}
3597936340
35980fn semaUnionFields(zcu: *Zcu, arena: Allocator, union_type: InternPool.LoadedUnionType) CompileError!void {36341fn semaUnionFields(pt: Zcu.PerThread, arena: Allocator, union_type: InternPool.LoadedUnionType) CompileError!void {
35981 const tracy = trace(@src());36342 const tracy = trace(@src());
35982 defer tracy.end();36343 defer tracy.end();
3598336344
36345 const zcu = pt.zcu;
35984 const gpa = zcu.gpa;36346 const gpa = zcu.gpa;
35985 const ip = &zcu.intern_pool;36347 const ip = &zcu.intern_pool;
35986 const decl_index = union_type.decl;36348 const decl_index = union_type.decl;
...@@ -36034,7 +36396,7 @@ fn semaUnionFields(zcu: *Zcu, arena: Allocator, union_type: InternPool.LoadedUni...@@ -36034,7 +36396,7 @@ fn semaUnionFields(zcu: *Zcu, arena: Allocator, union_type: InternPool.LoadedUni
36034 defer comptime_err_ret_trace.deinit();36396 defer comptime_err_ret_trace.deinit();
3603536397
36036 var sema: Sema = .{36398 var sema: Sema = .{
36037 .mod = zcu,36399 .pt = pt,
36038 .gpa = gpa,36400 .gpa = gpa,
36039 .arena = arena,36401 .arena = arena,
36040 .code = zir,36402 .code = zir,
...@@ -36081,17 +36443,17 @@ fn semaUnionFields(zcu: *Zcu, arena: Allocator, union_type: InternPool.LoadedUni...@@ -36081,17 +36443,17 @@ fn semaUnionFields(zcu: *Zcu, arena: Allocator, union_type: InternPool.LoadedUni
36081 // The provided type is an integer type and we must construct the enum tag type here.36443 // The provided type is an integer type and we must construct the enum tag type here.
36082 int_tag_ty = provided_ty;36444 int_tag_ty = provided_ty;
36083 if (int_tag_ty.zigTypeTag(zcu) != .Int and int_tag_ty.zigTypeTag(zcu) != .ComptimeInt) {36445 if (int_tag_ty.zigTypeTag(zcu) != .Int and int_tag_ty.zigTypeTag(zcu) != .ComptimeInt) {
36084 return sema.fail(&block_scope, tag_ty_src, "expected integer tag type, found '{}'", .{int_tag_ty.fmt(zcu)});36446 return sema.fail(&block_scope, tag_ty_src, "expected integer tag type, found '{}'", .{int_tag_ty.fmt(pt)});
36085 }36447 }
3608636448
36087 if (fields_len > 0) {36449 if (fields_len > 0) {
36088 const field_count_val = try zcu.intValue(Type.comptime_int, fields_len - 1);36450 const field_count_val = try pt.intValue(Type.comptime_int, fields_len - 1);
36089 if (!(try sema.intFitsInType(field_count_val, int_tag_ty, null))) {36451 if (!(try sema.intFitsInType(field_count_val, int_tag_ty, null))) {
36090 const msg = msg: {36452 const msg = msg: {
36091 const msg = try sema.errMsg(tag_ty_src, "specified integer tag type cannot represent every field", .{});36453 const msg = try sema.errMsg(tag_ty_src, "specified integer tag type cannot represent every field", .{});
36092 errdefer msg.destroy(sema.gpa);36454 errdefer msg.destroy(sema.gpa);
36093 try sema.errNote(tag_ty_src, msg, "type '{}' cannot fit values in range 0...{d}", .{36455 try sema.errNote(tag_ty_src, msg, "type '{}' cannot fit values in range 0...{d}", .{
36094 int_tag_ty.fmt(zcu),36456 int_tag_ty.fmt(pt),
36095 fields_len - 1,36457 fields_len - 1,
36096 });36458 });
36097 break :msg msg;36459 break :msg msg;
...@@ -36106,7 +36468,7 @@ fn semaUnionFields(zcu: *Zcu, arena: Allocator, union_type: InternPool.LoadedUni...@@ -36106,7 +36468,7 @@ fn semaUnionFields(zcu: *Zcu, arena: Allocator, union_type: InternPool.LoadedUni
36106 union_type.tagTypePtr(ip).* = provided_ty.toIntern();36468 union_type.tagTypePtr(ip).* = provided_ty.toIntern();
36107 const enum_type = switch (ip.indexToKey(provided_ty.toIntern())) {36469 const enum_type = switch (ip.indexToKey(provided_ty.toIntern())) {
36108 .enum_type => ip.loadEnumType(provided_ty.toIntern()),36470 .enum_type => ip.loadEnumType(provided_ty.toIntern()),
36109 else => return sema.fail(&block_scope, tag_ty_src, "expected enum tag type, found '{}'", .{provided_ty.fmt(zcu)}),36471 else => return sema.fail(&block_scope, tag_ty_src, "expected enum tag type, found '{}'", .{provided_ty.fmt(pt)}),
36110 };36472 };
36111 // The fields of the union must match the enum exactly.36473 // The fields of the union must match the enum exactly.
36112 // A flag per field is used to check for missing and extraneous fields.36474 // A flag per field is used to check for missing and extraneous fields.
...@@ -36202,7 +36564,7 @@ fn semaUnionFields(zcu: *Zcu, arena: Allocator, union_type: InternPool.LoadedUni...@@ -36202,7 +36564,7 @@ fn semaUnionFields(zcu: *Zcu, arena: Allocator, union_type: InternPool.LoadedUni
36202 const val = if (last_tag_val) |val|36564 const val = if (last_tag_val) |val|
36203 try sema.intAdd(val, Value.one_comptime_int, int_tag_ty, undefined)36565 try sema.intAdd(val, Value.one_comptime_int, int_tag_ty, undefined)
36204 else36566 else
36205 try zcu.intValue(int_tag_ty, 0);36567 try pt.intValue(int_tag_ty, 0);
36206 last_tag_val = val;36568 last_tag_val = val;
3620736569
36208 break :blk val;36570 break :blk val;
...@@ -36214,7 +36576,7 @@ fn semaUnionFields(zcu: *Zcu, arena: Allocator, union_type: InternPool.LoadedUni...@@ -36214,7 +36576,7 @@ fn semaUnionFields(zcu: *Zcu, arena: Allocator, union_type: InternPool.LoadedUni
36214 .offset = .{ .container_field_value = @intCast(gop.index) },36576 .offset = .{ .container_field_value = @intCast(gop.index) },
36215 };36577 };
36216 const msg = msg: {36578 const msg = msg: {
36217 const msg = try sema.errMsg(value_src, "enum tag value {} already taken", .{enum_tag_val.fmtValue(zcu, &sema)});36579 const msg = try sema.errMsg(value_src, "enum tag value {} already taken", .{enum_tag_val.fmtValue(pt, &sema)});
36218 errdefer msg.destroy(gpa);36580 errdefer msg.destroy(gpa);
36219 try sema.errNote(other_value_src, msg, "other occurrence here", .{});36581 try sema.errNote(other_value_src, msg, "other occurrence here", .{});
36220 break :msg msg;36582 break :msg msg;
...@@ -36224,7 +36586,7 @@ fn semaUnionFields(zcu: *Zcu, arena: Allocator, union_type: InternPool.LoadedUni...@@ -36224,7 +36586,7 @@ fn semaUnionFields(zcu: *Zcu, arena: Allocator, union_type: InternPool.LoadedUni
36224 }36586 }
3622536587
36226 // This string needs to outlive the ZIR code.36588 // This string needs to outlive the ZIR code.
36227 const field_name = try ip.getOrPutString(gpa, field_name_zir, .no_embedded_nulls);36589 const field_name = try ip.getOrPutString(gpa, pt.tid, field_name_zir, .no_embedded_nulls);
36228 if (enum_field_names.len != 0) {36590 if (enum_field_names.len != 0) {
36229 enum_field_names[field_i] = field_name;36591 enum_field_names[field_i] = field_name;
36230 }36592 }
...@@ -36244,7 +36606,7 @@ fn semaUnionFields(zcu: *Zcu, arena: Allocator, union_type: InternPool.LoadedUni...@@ -36244,7 +36606,7 @@ fn semaUnionFields(zcu: *Zcu, arena: Allocator, union_type: InternPool.LoadedUni
36244 const tag_info = ip.loadEnumType(union_type.tagTypePtr(ip).*);36606 const tag_info = ip.loadEnumType(union_type.tagTypePtr(ip).*);
36245 const enum_index = tag_info.nameIndex(ip, field_name) orelse {36607 const enum_index = tag_info.nameIndex(ip, field_name) orelse {
36246 return sema.fail(&block_scope, name_src, "no field named '{}' in enum '{}'", .{36608 return sema.fail(&block_scope, name_src, "no field named '{}' in enum '{}'", .{
36247 field_name.fmt(ip), Type.fromInterned(union_type.tagTypePtr(ip).*).fmt(zcu),36609 field_name.fmt(ip), Type.fromInterned(union_type.tagTypePtr(ip).*).fmt(pt),
36248 });36610 });
36249 };36611 };
3625036612
...@@ -36286,7 +36648,7 @@ fn semaUnionFields(zcu: *Zcu, arena: Allocator, union_type: InternPool.LoadedUni...@@ -36286,7 +36648,7 @@ fn semaUnionFields(zcu: *Zcu, arena: Allocator, union_type: InternPool.LoadedUni
36286 !try sema.validateExternType(field_ty, .union_field))36648 !try sema.validateExternType(field_ty, .union_field))
36287 {36649 {
36288 const msg = msg: {36650 const msg = msg: {
36289 const msg = try sema.errMsg(type_src, "extern unions cannot contain fields of type '{}'", .{field_ty.fmt(zcu)});36651 const msg = try sema.errMsg(type_src, "extern unions cannot contain fields of type '{}'", .{field_ty.fmt(pt)});
36290 errdefer msg.destroy(sema.gpa);36652 errdefer msg.destroy(sema.gpa);
3629136653
36292 try sema.explainWhyTypeIsNotExtern(msg, type_src, field_ty, .union_field);36654 try sema.explainWhyTypeIsNotExtern(msg, type_src, field_ty, .union_field);
...@@ -36297,7 +36659,7 @@ fn semaUnionFields(zcu: *Zcu, arena: Allocator, union_type: InternPool.LoadedUni...@@ -36297,7 +36659,7 @@ fn semaUnionFields(zcu: *Zcu, arena: Allocator, union_type: InternPool.LoadedUni
36297 return sema.failWithOwnedErrorMsg(&block_scope, msg);36659 return sema.failWithOwnedErrorMsg(&block_scope, msg);
36298 } else if (layout == .@"packed" and !try sema.validatePackedType(field_ty)) {36660 } else if (layout == .@"packed" and !try sema.validatePackedType(field_ty)) {
36299 const msg = msg: {36661 const msg = msg: {
36300 const msg = try sema.errMsg(type_src, "packed unions cannot contain fields of type '{}'", .{field_ty.fmt(zcu)});36662 const msg = try sema.errMsg(type_src, "packed unions cannot contain fields of type '{}'", .{field_ty.fmt(pt)});
36301 errdefer msg.destroy(sema.gpa);36663 errdefer msg.destroy(sema.gpa);
3630236664
36303 try sema.explainWhyTypeIsNotPacked(msg, type_src, field_ty);36665 try sema.explainWhyTypeIsNotPacked(msg, type_src, field_ty);
...@@ -36366,15 +36728,17 @@ fn generateUnionTagTypeNumbered(...@@ -36366,15 +36728,17 @@ fn generateUnionTagTypeNumbered(
36366 enum_field_vals: []const InternPool.Index,36728 enum_field_vals: []const InternPool.Index,
36367 union_owner_decl: *Module.Decl,36729 union_owner_decl: *Module.Decl,
36368) !InternPool.Index {36730) !InternPool.Index {
36369 const mod = sema.mod;36731 const pt = sema.pt;
36732 const mod = pt.zcu;
36370 const gpa = sema.gpa;36733 const gpa = sema.gpa;
36371 const ip = &mod.intern_pool;36734 const ip = &mod.intern_pool;
3637236735
36373 const new_decl_index = try mod.allocateNewDecl(block.namespace);36736 const new_decl_index = try mod.allocateNewDecl(block.namespace);
36374 errdefer mod.destroyDecl(new_decl_index);36737 errdefer mod.destroyDecl(new_decl_index);
36375 const fqn = try union_owner_decl.fullyQualifiedName(mod);36738 const fqn = try union_owner_decl.fullyQualifiedName(pt);
36376 const name = try ip.getOrPutStringFmt(36739 const name = try ip.getOrPutStringFmt(
36377 gpa,36740 gpa,
36741 pt.tid,
36378 "@typeInfo({}).Union.tag_type.?",36742 "@typeInfo({}).Union.tag_type.?",
36379 .{fqn.fmt(ip)},36743 .{fqn.fmt(ip)},
36380 .no_embedded_nulls,36744 .no_embedded_nulls,
...@@ -36390,11 +36754,11 @@ fn generateUnionTagTypeNumbered(...@@ -36390,11 +36754,11 @@ fn generateUnionTagTypeNumbered(
36390 new_decl.owns_tv = true;36754 new_decl.owns_tv = true;
36391 new_decl.name_fully_qualified = true;36755 new_decl.name_fully_qualified = true;
3639236756
36393 const enum_ty = try ip.getGeneratedTagEnumType(gpa, .{36757 const enum_ty = try ip.getGeneratedTagEnumType(gpa, pt.tid, .{
36394 .decl = new_decl_index,36758 .decl = new_decl_index,
36395 .owner_union_ty = union_owner_decl.val.toIntern(),36759 .owner_union_ty = union_owner_decl.val.toIntern(),
36396 .tag_ty = if (enum_field_vals.len == 0)36760 .tag_ty = if (enum_field_vals.len == 0)
36397 (try mod.intType(.unsigned, 0)).toIntern()36761 (try pt.intType(.unsigned, 0)).toIntern()
36398 else36762 else
36399 ip.typeOf(enum_field_vals[0]),36763 ip.typeOf(enum_field_vals[0]),
36400 .names = enum_field_names,36764 .names = enum_field_names,
...@@ -36404,7 +36768,7 @@ fn generateUnionTagTypeNumbered(...@@ -36404,7 +36768,7 @@ fn generateUnionTagTypeNumbered(
3640436768
36405 new_decl.val = Value.fromInterned(enum_ty);36769 new_decl.val = Value.fromInterned(enum_ty);
3640636770
36407 try mod.finalizeAnonDecl(new_decl_index);36771 try pt.finalizeAnonDecl(new_decl_index);
36408 return enum_ty;36772 return enum_ty;
36409}36773}
3641036774
...@@ -36414,16 +36778,18 @@ fn generateUnionTagTypeSimple(...@@ -36414,16 +36778,18 @@ fn generateUnionTagTypeSimple(
36414 enum_field_names: []const InternPool.NullTerminatedString,36778 enum_field_names: []const InternPool.NullTerminatedString,
36415 union_owner_decl: *Module.Decl,36779 union_owner_decl: *Module.Decl,
36416) !InternPool.Index {36780) !InternPool.Index {
36417 const mod = sema.mod;36781 const pt = sema.pt;
36782 const mod = pt.zcu;
36418 const ip = &mod.intern_pool;36783 const ip = &mod.intern_pool;
36419 const gpa = sema.gpa;36784 const gpa = sema.gpa;
3642036785
36421 const new_decl_index = new_decl_index: {36786 const new_decl_index = new_decl_index: {
36422 const fqn = try union_owner_decl.fullyQualifiedName(mod);36787 const fqn = try union_owner_decl.fullyQualifiedName(pt);
36423 const new_decl_index = try mod.allocateNewDecl(block.namespace);36788 const new_decl_index = try mod.allocateNewDecl(block.namespace);
36424 errdefer mod.destroyDecl(new_decl_index);36789 errdefer mod.destroyDecl(new_decl_index);
36425 const name = try ip.getOrPutStringFmt(36790 const name = try ip.getOrPutStringFmt(
36426 gpa,36791 gpa,
36792 pt.tid,
36427 "@typeInfo({}).Union.tag_type.?",36793 "@typeInfo({}).Union.tag_type.?",
36428 .{fqn.fmt(ip)},36794 .{fqn.fmt(ip)},
36429 .no_embedded_nulls,36795 .no_embedded_nulls,
...@@ -36438,13 +36804,13 @@ fn generateUnionTagTypeSimple(...@@ -36438,13 +36804,13 @@ fn generateUnionTagTypeSimple(
36438 };36804 };
36439 errdefer mod.abortAnonDecl(new_decl_index);36805 errdefer mod.abortAnonDecl(new_decl_index);
3644036806
36441 const enum_ty = try ip.getGeneratedTagEnumType(gpa, .{36807 const enum_ty = try ip.getGeneratedTagEnumType(gpa, pt.tid, .{
36442 .decl = new_decl_index,36808 .decl = new_decl_index,
36443 .owner_union_ty = union_owner_decl.val.toIntern(),36809 .owner_union_ty = union_owner_decl.val.toIntern(),
36444 .tag_ty = if (enum_field_names.len == 0)36810 .tag_ty = if (enum_field_names.len == 0)
36445 (try mod.intType(.unsigned, 0)).toIntern()36811 (try pt.intType(.unsigned, 0)).toIntern()
36446 else36812 else
36447 (try mod.smallestUnsignedInt(enum_field_names.len - 1)).toIntern(),36813 (try pt.smallestUnsignedInt(enum_field_names.len - 1)).toIntern(),
36448 .names = enum_field_names,36814 .names = enum_field_names,
36449 .values = &.{},36815 .values = &.{},
36450 .tag_mode = .auto,36816 .tag_mode = .auto,
...@@ -36454,7 +36820,7 @@ fn generateUnionTagTypeSimple(...@@ -36454,7 +36820,7 @@ fn generateUnionTagTypeSimple(
36454 new_decl.owns_tv = true;36820 new_decl.owns_tv = true;
36455 new_decl.val = Value.fromInterned(enum_ty);36821 new_decl.val = Value.fromInterned(enum_ty);
3645636822
36457 try mod.finalizeAnonDecl(new_decl_index);36823 try pt.finalizeAnonDecl(new_decl_index);
36458 return enum_ty;36824 return enum_ty;
36459}36825}
3646036826
...@@ -36464,12 +36830,13 @@ fn generateUnionTagTypeSimple(...@@ -36464,12 +36830,13 @@ fn generateUnionTagTypeSimple(
36464/// that the types are already resolved.36830/// that the types are already resolved.
36465/// TODO assert the return value matches `ty.onePossibleValue`36831/// TODO assert the return value matches `ty.onePossibleValue`
36466pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value {36832pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value {
36467 const zcu = sema.mod;36833 const pt = sema.pt;
36834 const zcu = pt.zcu;
36468 const ip = &zcu.intern_pool;36835 const ip = &zcu.intern_pool;
36469 return switch (ty.toIntern()) {36836 return switch (ty.toIntern()) {
36470 .u0_type,36837 .u0_type,
36471 .i0_type,36838 .i0_type,
36472 => try zcu.intValue(ty, 0),36839 => try pt.intValue(ty, 0),
36473 .u1_type,36840 .u1_type,
36474 .u8_type,36841 .u8_type,
36475 .i8_type,36842 .i8_type,
...@@ -36532,7 +36899,7 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value {...@@ -36532,7 +36899,7 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value {
36532 .anyframe_type => unreachable,36899 .anyframe_type => unreachable,
36533 .null_type => Value.null,36900 .null_type => Value.null,
36534 .undefined_type => Value.undef,36901 .undefined_type => Value.undef,
36535 .optional_noreturn_type => try zcu.nullValue(ty),36902 .optional_noreturn_type => try pt.nullValue(ty),
36536 .generic_poison_type => error.GenericPoison,36903 .generic_poison_type => error.GenericPoison,
36537 .empty_struct_type => Value.empty_struct,36904 .empty_struct_type => Value.empty_struct,
36538 // values, not types36905 // values, not types
...@@ -36558,7 +36925,7 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value {...@@ -36558,7 +36925,7 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value {
36558 .none,36925 .none,
36559 => unreachable,36926 => unreachable,
3656036927
36561 _ => switch (ip.items.items(.tag)[@intFromEnum(ty.toIntern())]) {36928 _ => switch (ty.toIntern().unwrap(ip).getTag(ip)) {
36562 .removed => unreachable,36929 .removed => unreachable,
3656336930
36564 .type_int_signed, // i0 handled above36931 .type_int_signed, // i0 handled above
...@@ -36646,16 +37013,16 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value {...@@ -36646,16 +37013,16 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value {
36646 => switch (ip.indexToKey(ty.toIntern())) {37013 => switch (ip.indexToKey(ty.toIntern())) {
36647 inline .array_type, .vector_type => |seq_type, seq_tag| {37014 inline .array_type, .vector_type => |seq_type, seq_tag| {
36648 const has_sentinel = seq_tag == .array_type and seq_type.sentinel != .none;37015 const has_sentinel = seq_tag == .array_type and seq_type.sentinel != .none;
36649 if (seq_type.len + @intFromBool(has_sentinel) == 0) return Value.fromInterned((try zcu.intern(.{ .aggregate = .{37016 if (seq_type.len + @intFromBool(has_sentinel) == 0) return Value.fromInterned(try pt.intern(.{ .aggregate = .{
36650 .ty = ty.toIntern(),37017 .ty = ty.toIntern(),
36651 .storage = .{ .elems = &.{} },37018 .storage = .{ .elems = &.{} },
36652 } })));37019 } }));
3665337020
36654 if (try sema.typeHasOnePossibleValue(Type.fromInterned(seq_type.child))) |opv| {37021 if (try sema.typeHasOnePossibleValue(Type.fromInterned(seq_type.child))) |opv| {
36655 return Value.fromInterned((try zcu.intern(.{ .aggregate = .{37022 return Value.fromInterned(try pt.intern(.{ .aggregate = .{
36656 .ty = ty.toIntern(),37023 .ty = ty.toIntern(),
36657 .storage = .{ .repeated_elem = opv.toIntern() },37024 .storage = .{ .repeated_elem = opv.toIntern() },
36658 } })));37025 } }));
36659 }37026 }
36660 return null;37027 return null;
36661 },37028 },
...@@ -36663,17 +37030,17 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value {...@@ -36663,17 +37030,17 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value {
36663 .struct_type => {37030 .struct_type => {
36664 // Resolving the layout first helps to avoid loops.37031 // Resolving the layout first helps to avoid loops.
36665 // If the type has a coherent layout, we can recurse through fields safely.37032 // If the type has a coherent layout, we can recurse through fields safely.
36666 try ty.resolveLayout(zcu);37033 try ty.resolveLayout(pt);
3666737034
36668 const struct_type = ip.loadStructType(ty.toIntern());37035 const struct_type = ip.loadStructType(ty.toIntern());
3666937036
36670 if (struct_type.field_types.len == 0) {37037 if (struct_type.field_types.len == 0) {
36671 // In this case the struct has no fields at all and37038 // In this case the struct has no fields at all and
36672 // therefore has one possible value.37039 // therefore has one possible value.
36673 return Value.fromInterned((try zcu.intern(.{ .aggregate = .{37040 return Value.fromInterned(try pt.intern(.{ .aggregate = .{
36674 .ty = ty.toIntern(),37041 .ty = ty.toIntern(),
36675 .storage = .{ .elems = &.{} },37042 .storage = .{ .elems = &.{} },
36676 } })));37043 } }));
36677 }37044 }
3667837045
36679 const field_vals = try sema.arena.alloc(37046 const field_vals = try sema.arena.alloc(
...@@ -36682,7 +37049,7 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value {...@@ -36682,7 +37049,7 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value {
36682 );37049 );
36683 for (field_vals, 0..) |*field_val, i| {37050 for (field_vals, 0..) |*field_val, i| {
36684 if (struct_type.fieldIsComptime(ip, i)) {37051 if (struct_type.fieldIsComptime(ip, i)) {
36685 try ty.resolveStructFieldInits(zcu);37052 try ty.resolveStructFieldInits(pt);
36686 field_val.* = struct_type.field_inits.get(ip)[i];37053 field_val.* = struct_type.field_inits.get(ip)[i];
36687 continue;37054 continue;
36688 }37055 }
...@@ -36694,10 +37061,10 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value {...@@ -36694,10 +37061,10 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value {
3669437061
36695 // In this case the struct has no runtime-known fields and37062 // In this case the struct has no runtime-known fields and
36696 // therefore has one possible value.37063 // therefore has one possible value.
36697 return Value.fromInterned((try zcu.intern(.{ .aggregate = .{37064 return Value.fromInterned(try pt.intern(.{ .aggregate = .{
36698 .ty = ty.toIntern(),37065 .ty = ty.toIntern(),
36699 .storage = .{ .elems = field_vals },37066 .storage = .{ .elems = field_vals },
36700 } })));37067 } }));
36701 },37068 },
3670237069
36703 .anon_struct_type => |tuple| {37070 .anon_struct_type => |tuple| {
...@@ -36707,28 +37074,28 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value {...@@ -36707,28 +37074,28 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value {
36707 // In this case the struct has all comptime-known fields and37074 // In this case the struct has all comptime-known fields and
36708 // therefore has one possible value.37075 // therefore has one possible value.
36709 // TODO: write something like getCoercedInts to avoid needing to dupe37076 // TODO: write something like getCoercedInts to avoid needing to dupe
36710 return Value.fromInterned((try zcu.intern(.{ .aggregate = .{37077 return Value.fromInterned(try pt.intern(.{ .aggregate = .{
36711 .ty = ty.toIntern(),37078 .ty = ty.toIntern(),
36712 .storage = .{ .elems = try sema.arena.dupe(InternPool.Index, tuple.values.get(ip)) },37079 .storage = .{ .elems = try sema.arena.dupe(InternPool.Index, tuple.values.get(ip)) },
36713 } })));37080 } }));
36714 },37081 },
3671537082
36716 .union_type => {37083 .union_type => {
36717 // Resolving the layout first helps to avoid loops.37084 // Resolving the layout first helps to avoid loops.
36718 // If the type has a coherent layout, we can recurse through fields safely.37085 // If the type has a coherent layout, we can recurse through fields safely.
36719 try ty.resolveLayout(zcu);37086 try ty.resolveLayout(pt);
3672037087
36721 const union_obj = ip.loadUnionType(ty.toIntern());37088 const union_obj = ip.loadUnionType(ty.toIntern());
36722 const tag_val = (try sema.typeHasOnePossibleValue(Type.fromInterned(union_obj.tagTypePtr(ip).*))) orelse37089 const tag_val = (try sema.typeHasOnePossibleValue(Type.fromInterned(union_obj.tagTypePtr(ip).*))) orelse
36723 return null;37090 return null;
36724 if (union_obj.field_types.len == 0) {37091 if (union_obj.field_types.len == 0) {
36725 const only = try zcu.intern(.{ .empty_enum_value = ty.toIntern() });37092 const only = try pt.intern(.{ .empty_enum_value = ty.toIntern() });
36726 return Value.fromInterned(only);37093 return Value.fromInterned(only);
36727 }37094 }
36728 const only_field_ty = Type.fromInterned(union_obj.field_types.get(ip)[0]);37095 const only_field_ty = Type.fromInterned(union_obj.field_types.get(ip)[0]);
36729 const val_val = (try sema.typeHasOnePossibleValue(only_field_ty)) orelse37096 const val_val = (try sema.typeHasOnePossibleValue(only_field_ty)) orelse
36730 return null;37097 return null;
36731 const only = try zcu.intern(.{ .un = .{37098 const only = try pt.intern(.{ .un = .{
36732 .ty = ty.toIntern(),37099 .ty = ty.toIntern(),
36733 .tag = tag_val.toIntern(),37100 .tag = tag_val.toIntern(),
36734 .val = val_val.toIntern(),37101 .val = val_val.toIntern(),
...@@ -36743,7 +37110,7 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value {...@@ -36743,7 +37110,7 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value {
36743 if (enum_type.tag_ty == .comptime_int_type) return null;37110 if (enum_type.tag_ty == .comptime_int_type) return null;
3674437111
36745 if (try sema.typeHasOnePossibleValue(Type.fromInterned(enum_type.tag_ty))) |int_opv| {37112 if (try sema.typeHasOnePossibleValue(Type.fromInterned(enum_type.tag_ty))) |int_opv| {
36746 const only = try zcu.intern(.{ .enum_tag = .{37113 const only = try pt.intern(.{ .enum_tag = .{
36747 .ty = ty.toIntern(),37114 .ty = ty.toIntern(),
36748 .int = int_opv.toIntern(),37115 .int = int_opv.toIntern(),
36749 } });37116 } });
...@@ -36753,18 +37120,19 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value {...@@ -36753,18 +37120,19 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value {
36753 return null;37120 return null;
36754 },37121 },
36755 .auto, .explicit => {37122 .auto, .explicit => {
36756 if (Type.fromInterned(enum_type.tag_ty).hasRuntimeBits(zcu)) return null;37123 if (Type.fromInterned(enum_type.tag_ty).hasRuntimeBits(pt)) return null;
3675737124
36758 return Value.fromInterned(switch (enum_type.names.len) {37125 return Value.fromInterned(switch (enum_type.names.len) {
36759 0 => try zcu.intern(.{ .empty_enum_value = ty.toIntern() }),37126 0 => try pt.intern(.{ .empty_enum_value = ty.toIntern() }),
36760 1 => try zcu.intern(.{ .enum_tag = .{37127 1 => try pt.intern(.{ .enum_tag = .{
36761 .ty = ty.toIntern(),37128 .ty = ty.toIntern(),
36762 .int = if (enum_type.values.len == 0)37129 .int = if (enum_type.values.len == 0)
36763 (try zcu.intValue(Type.fromInterned(enum_type.tag_ty), 0)).toIntern()37130 (try pt.intValue(Type.fromInterned(enum_type.tag_ty), 0)).toIntern()
36764 else37131 else
36765 try zcu.intern_pool.getCoercedInts(37132 try ip.getCoercedInts(
36766 zcu.gpa,37133 zcu.gpa,
36767 zcu.intern_pool.indexToKey(enum_type.values.get(ip)[0]).int,37134 pt.tid,
37135 ip.indexToKey(enum_type.values.get(ip)[0]).int,
36768 enum_type.tag_ty,37136 enum_type.tag_ty,
36769 ),37137 ),
36770 } }),37138 } }),
...@@ -36782,7 +37150,7 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value {...@@ -36782,7 +37150,7 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value {
3678237150
36783/// Returns the type of the AIR instruction.37151/// Returns the type of the AIR instruction.
36784fn typeOf(sema: *Sema, inst: Air.Inst.Ref) Type {37152fn typeOf(sema: *Sema, inst: Air.Inst.Ref) Type {
36785 return sema.getTmpAir().typeOf(inst, &sema.mod.intern_pool);37153 return sema.getTmpAir().typeOf(inst, &sema.pt.zcu.intern_pool);
36786}37154}
3678737155
36788pub fn getTmpAir(sema: Sema) Air {37156pub fn getTmpAir(sema: Sema) Air {
...@@ -36838,12 +37206,13 @@ fn analyzeComptimeAlloc(...@@ -36838,12 +37206,13 @@ fn analyzeComptimeAlloc(
36838 var_type: Type,37206 var_type: Type,
36839 alignment: Alignment,37207 alignment: Alignment,
36840) CompileError!Air.Inst.Ref {37208) CompileError!Air.Inst.Ref {
36841 const mod = sema.mod;37209 const pt = sema.pt;
37210 const mod = pt.zcu;
3684237211
36843 // Needed to make an anon decl with type `var_type` (the `finish()` call below).37212 // Needed to make an anon decl with type `var_type` (the `finish()` call below).
36844 _ = try sema.typeHasOnePossibleValue(var_type);37213 _ = try sema.typeHasOnePossibleValue(var_type);
3684537214
36846 const ptr_type = try mod.ptrTypeSema(.{37215 const ptr_type = try pt.ptrTypeSema(.{
36847 .child = var_type.toIntern(),37216 .child = var_type.toIntern(),
36848 .flags = .{37217 .flags = .{
36849 .alignment = alignment,37218 .alignment = alignment,
...@@ -36853,7 +37222,7 @@ fn analyzeComptimeAlloc(...@@ -36853,7 +37222,7 @@ fn analyzeComptimeAlloc(
3685337222
36854 const alloc = try sema.newComptimeAlloc(block, var_type, alignment);37223 const alloc = try sema.newComptimeAlloc(block, var_type, alignment);
3685537224
36856 return Air.internedToRef((try mod.intern(.{ .ptr = .{37225 return Air.internedToRef((try pt.intern(.{ .ptr = .{
36857 .ty = ptr_type.toIntern(),37226 .ty = ptr_type.toIntern(),
36858 .base_addr = .{ .comptime_alloc = alloc },37227 .base_addr = .{ .comptime_alloc = alloc },
36859 .byte_offset = 0,37228 .byte_offset = 0,
...@@ -36896,13 +37265,14 @@ pub fn analyzeAsAddressSpace(...@@ -36896,13 +37265,14 @@ pub fn analyzeAsAddressSpace(
36896 air_ref: Air.Inst.Ref,37265 air_ref: Air.Inst.Ref,
36897 ctx: AddressSpaceContext,37266 ctx: AddressSpaceContext,
36898) !std.builtin.AddressSpace {37267) !std.builtin.AddressSpace {
36899 const mod = sema.mod;37268 const pt = sema.pt;
37269 const mod = pt.zcu;
36900 const coerced = try sema.coerce(block, Type.fromInterned(.address_space_type), air_ref, src);37270 const coerced = try sema.coerce(block, Type.fromInterned(.address_space_type), air_ref, src);
36901 const addrspace_val = try sema.resolveConstDefinedValue(block, src, coerced, .{37271 const addrspace_val = try sema.resolveConstDefinedValue(block, src, coerced, .{
36902 .needed_comptime_reason = "address space must be comptime-known",37272 .needed_comptime_reason = "address space must be comptime-known",
36903 });37273 });
36904 const address_space = mod.toEnum(std.builtin.AddressSpace, addrspace_val);37274 const address_space = mod.toEnum(std.builtin.AddressSpace, addrspace_val);
36905 const target = sema.mod.getTarget();37275 const target = pt.zcu.getTarget();
36906 const arch = target.cpu.arch;37276 const arch = target.cpu.arch;
3690737277
36908 const is_nv = arch == .nvptx or arch == .nvptx64;37278 const is_nv = arch == .nvptx or arch == .nvptx64;
...@@ -36946,7 +37316,8 @@ pub fn analyzeAsAddressSpace(...@@ -36946,7 +37316,8 @@ pub fn analyzeAsAddressSpace(
36946/// Returns `null` if the pointer contents cannot be loaded at comptime.37316/// Returns `null` if the pointer contents cannot be loaded at comptime.
36947fn pointerDeref(sema: *Sema, block: *Block, src: LazySrcLoc, ptr_val: Value, ptr_ty: Type) CompileError!?Value {37317fn pointerDeref(sema: *Sema, block: *Block, src: LazySrcLoc, ptr_val: Value, ptr_ty: Type) CompileError!?Value {
36948 // TODO: audit use sites to eliminate this coercion37318 // TODO: audit use sites to eliminate this coercion
36949 const coerced_ptr_val = try sema.mod.getCoerced(ptr_val, ptr_ty);37319 const pt = sema.pt;
37320 const coerced_ptr_val = try pt.getCoerced(ptr_val, ptr_ty);
36950 switch (try sema.pointerDerefExtra(block, src, coerced_ptr_val)) {37321 switch (try sema.pointerDerefExtra(block, src, coerced_ptr_val)) {
36951 .runtime_load => return null,37322 .runtime_load => return null,
36952 .val => |v| return v,37323 .val => |v| return v,
...@@ -36954,13 +37325,13 @@ fn pointerDeref(sema: *Sema, block: *Block, src: LazySrcLoc, ptr_val: Value, ptr...@@ -36954,13 +37325,13 @@ fn pointerDeref(sema: *Sema, block: *Block, src: LazySrcLoc, ptr_val: Value, ptr
36954 block,37325 block,
36955 src,37326 src,
36956 "comptime dereference requires '{}' to have a well-defined layout",37327 "comptime dereference requires '{}' to have a well-defined layout",
36957 .{ty.fmt(sema.mod)},37328 .{ty.fmt(pt)},
36958 ),37329 ),
36959 .out_of_bounds => |ty| return sema.fail(37330 .out_of_bounds => |ty| return sema.fail(
36960 block,37331 block,
36961 src,37332 src,
36962 "dereference of '{}' exceeds bounds of containing decl of type '{}'",37333 "dereference of '{}' exceeds bounds of containing decl of type '{}'",
36963 .{ ptr_ty.fmt(sema.mod), ty.fmt(sema.mod) },37334 .{ ptr_ty.fmt(pt), ty.fmt(pt) },
36964 ),37335 ),
36965 }37336 }
36966}37337}
...@@ -36973,10 +37344,10 @@ const DerefResult = union(enum) {...@@ -36973,10 +37344,10 @@ const DerefResult = union(enum) {
36973};37344};
3697437345
36975fn pointerDerefExtra(sema: *Sema, block: *Block, src: LazySrcLoc, ptr_val: Value) CompileError!DerefResult {37346fn pointerDerefExtra(sema: *Sema, block: *Block, src: LazySrcLoc, ptr_val: Value) CompileError!DerefResult {
36976 const zcu = sema.mod;37347 const pt = sema.pt;
36977 const ip = &zcu.intern_pool;37348 const ip = &pt.zcu.intern_pool;
36978 switch (try sema.loadComptimePtr(block, src, ptr_val)) {37349 switch (try sema.loadComptimePtr(block, src, ptr_val)) {
36979 .success => |mv| return .{ .val = try mv.intern(zcu, sema.arena) },37350 .success => |mv| return .{ .val = try mv.intern(pt, sema.arena) },
36980 .runtime_load => return .runtime_load,37351 .runtime_load => return .runtime_load,
36981 .undef => return sema.failWithUseOfUndef(block, src),37352 .undef => return sema.failWithUseOfUndef(block, src),
36982 .err_payload => |err_name| return sema.fail(block, src, "attempt to unwrap error: {}", .{err_name.fmt(ip)}),37353 .err_payload => |err_name| return sema.fail(block, src, "attempt to unwrap error: {}", .{err_name.fmt(ip)}),
...@@ -37001,7 +37372,8 @@ fn usizeCast(sema: *Sema, block: *Block, src: LazySrcLoc, int: u64) CompileError...@@ -37001,7 +37372,8 @@ fn usizeCast(sema: *Sema, block: *Block, src: LazySrcLoc, int: u64) CompileError
37001/// a type has zero bits, which can cause a "foo depends on itself" compile error.37372/// a type has zero bits, which can cause a "foo depends on itself" compile error.
37002/// This logic must be kept in sync with `Type.isPtrLikeOptional`.37373/// This logic must be kept in sync with `Type.isPtrLikeOptional`.
37003fn typePtrOrOptionalPtrTy(sema: *Sema, ty: Type) !?Type {37374fn typePtrOrOptionalPtrTy(sema: *Sema, ty: Type) !?Type {
37004 const mod = sema.mod;37375 const pt = sema.pt;
37376 const mod = pt.zcu;
37005 return switch (mod.intern_pool.indexToKey(ty.toIntern())) {37377 return switch (mod.intern_pool.indexToKey(ty.toIntern())) {
37006 .ptr_type => |ptr_type| switch (ptr_type.flags.size) {37378 .ptr_type => |ptr_type| switch (ptr_type.flags.size) {
37007 .One, .Many, .C => ty,37379 .One, .Many, .C => ty,
...@@ -37031,27 +37403,28 @@ fn typePtrOrOptionalPtrTy(sema: *Sema, ty: Type) !?Type {...@@ -37031,27 +37403,28 @@ fn typePtrOrOptionalPtrTy(sema: *Sema, ty: Type) !?Type {
37031/// `generic_poison` will return false.37403/// `generic_poison` will return false.
37032/// May return false negatives when structs and unions are having their field types resolved.37404/// May return false negatives when structs and unions are having their field types resolved.
37033pub fn typeRequiresComptime(sema: *Sema, ty: Type) SemaError!bool {37405pub fn typeRequiresComptime(sema: *Sema, ty: Type) SemaError!bool {
37034 return ty.comptimeOnlyAdvanced(sema.mod, .sema);37406 return ty.comptimeOnlyAdvanced(sema.pt, .sema);
37035}37407}
3703637408
37037pub fn typeHasRuntimeBits(sema: *Sema, ty: Type) SemaError!bool {37409pub fn typeHasRuntimeBits(sema: *Sema, ty: Type) SemaError!bool {
37038 return ty.hasRuntimeBitsAdvanced(sema.mod, false, .sema) catch |err| switch (err) {37410 return ty.hasRuntimeBitsAdvanced(sema.pt, false, .sema) catch |err| switch (err) {
37039 error.NeedLazy => unreachable,37411 error.NeedLazy => unreachable,
37040 else => |e| return e,37412 else => |e| return e,
37041 };37413 };
37042}37414}
3704337415
37044pub fn typeAbiSize(sema: *Sema, ty: Type) SemaError!u64 {37416pub fn typeAbiSize(sema: *Sema, ty: Type) SemaError!u64 {
37045 try ty.resolveLayout(sema.mod);37417 const pt = sema.pt;
37046 return ty.abiSize(sema.mod);37418 try ty.resolveLayout(pt);
37419 return ty.abiSize(pt);
37047}37420}
3704837421
37049pub fn typeAbiAlignment(sema: *Sema, ty: Type) SemaError!Alignment {37422pub fn typeAbiAlignment(sema: *Sema, ty: Type) SemaError!Alignment {
37050 return (try ty.abiAlignmentAdvanced(sema.mod, .sema)).scalar;37423 return (try ty.abiAlignmentAdvanced(sema.pt, .sema)).scalar;
37051}37424}
3705237425
37053pub fn fnHasRuntimeBits(sema: *Sema, ty: Type) CompileError!bool {37426pub fn fnHasRuntimeBits(sema: *Sema, ty: Type) CompileError!bool {
37054 return ty.fnHasRuntimeBitsAdvanced(sema.mod, .sema);37427 return ty.fnHasRuntimeBitsAdvanced(sema.pt, .sema);
37055}37428}
3705637429
37057fn unionFieldIndex(37430fn unionFieldIndex(
...@@ -37061,9 +37434,10 @@ fn unionFieldIndex(...@@ -37061,9 +37434,10 @@ fn unionFieldIndex(
37061 field_name: InternPool.NullTerminatedString,37434 field_name: InternPool.NullTerminatedString,
37062 field_src: LazySrcLoc,37435 field_src: LazySrcLoc,
37063) !u32 {37436) !u32 {
37064 const mod = sema.mod;37437 const pt = sema.pt;
37438 const mod = pt.zcu;
37065 const ip = &mod.intern_pool;37439 const ip = &mod.intern_pool;
37066 try union_ty.resolveFields(mod);37440 try union_ty.resolveFields(pt);
37067 const union_obj = mod.typeToUnion(union_ty).?;37441 const union_obj = mod.typeToUnion(union_ty).?;
37068 const field_index = union_obj.loadTagType(ip).nameIndex(ip, field_name) orelse37442 const field_index = union_obj.loadTagType(ip).nameIndex(ip, field_name) orelse
37069 return sema.failWithBadUnionFieldAccess(block, union_ty, union_obj, field_src, field_name);37443 return sema.failWithBadUnionFieldAccess(block, union_ty, union_obj, field_src, field_name);
...@@ -37077,9 +37451,10 @@ fn structFieldIndex(...@@ -37077,9 +37451,10 @@ fn structFieldIndex(
37077 field_name: InternPool.NullTerminatedString,37451 field_name: InternPool.NullTerminatedString,
37078 field_src: LazySrcLoc,37452 field_src: LazySrcLoc,
37079) !u32 {37453) !u32 {
37080 const mod = sema.mod;37454 const pt = sema.pt;
37455 const mod = pt.zcu;
37081 const ip = &mod.intern_pool;37456 const ip = &mod.intern_pool;
37082 try struct_ty.resolveFields(mod);37457 try struct_ty.resolveFields(pt);
37083 if (struct_ty.isAnonStruct(mod)) {37458 if (struct_ty.isAnonStruct(mod)) {
37084 return sema.anonStructFieldIndex(block, struct_ty, field_name, field_src);37459 return sema.anonStructFieldIndex(block, struct_ty, field_name, field_src);
37085 } else {37460 } else {
...@@ -37096,7 +37471,8 @@ fn anonStructFieldIndex(...@@ -37096,7 +37471,8 @@ fn anonStructFieldIndex(
37096 field_name: InternPool.NullTerminatedString,37471 field_name: InternPool.NullTerminatedString,
37097 field_src: LazySrcLoc,37472 field_src: LazySrcLoc,
37098) !u32 {37473) !u32 {
37099 const mod = sema.mod;37474 const pt = sema.pt;
37475 const mod = pt.zcu;
37100 const ip = &mod.intern_pool;37476 const ip = &mod.intern_pool;
37101 switch (ip.indexToKey(struct_ty.toIntern())) {37477 switch (ip.indexToKey(struct_ty.toIntern())) {
37102 .anon_struct_type => |anon_struct_type| for (anon_struct_type.names.get(ip), 0..) |name, i| {37478 .anon_struct_type => |anon_struct_type| for (anon_struct_type.names.get(ip), 0..) |name, i| {
...@@ -37106,20 +37482,21 @@ fn anonStructFieldIndex(...@@ -37106,20 +37482,21 @@ fn anonStructFieldIndex(
37106 else => unreachable,37482 else => unreachable,
37107 }37483 }
37108 return sema.fail(block, field_src, "no field named '{}' in anonymous struct '{}'", .{37484 return sema.fail(block, field_src, "no field named '{}' in anonymous struct '{}'", .{
37109 field_name.fmt(ip), struct_ty.fmt(sema.mod),37485 field_name.fmt(ip), struct_ty.fmt(pt),
37110 });37486 });
37111}37487}
3711237488
37113/// If the value overflowed the type, returns a comptime_int (or vector thereof) instead, setting37489/// If the value overflowed the type, returns a comptime_int (or vector thereof) instead, setting
37114/// overflow_idx to the vector index the overflow was at (or 0 for a scalar).37490/// overflow_idx to the vector index the overflow was at (or 0 for a scalar).
37115fn intAdd(sema: *Sema, lhs: Value, rhs: Value, ty: Type, overflow_idx: *?usize) !Value {37491fn intAdd(sema: *Sema, lhs: Value, rhs: Value, ty: Type, overflow_idx: *?usize) !Value {
37492 const pt = sema.pt;
37116 var overflow: usize = undefined;37493 var overflow: usize = undefined;
37117 return sema.intAddInner(lhs, rhs, ty, &overflow) catch |err| switch (err) {37494 return sema.intAddInner(lhs, rhs, ty, &overflow) catch |err| switch (err) {
37118 error.Overflow => {37495 error.Overflow => {
37119 const is_vec = ty.isVector(sema.mod);37496 const is_vec = ty.isVector(pt.zcu);
37120 overflow_idx.* = if (is_vec) overflow else 0;37497 overflow_idx.* = if (is_vec) overflow else 0;
37121 const safe_ty = if (is_vec) try sema.mod.vectorType(.{37498 const safe_ty = if (is_vec) try pt.vectorType(.{
37122 .len = ty.vectorLen(sema.mod),37499 .len = ty.vectorLen(pt.zcu),
37123 .child = .comptime_int_type,37500 .child = .comptime_int_type,
37124 }) else Type.comptime_int;37501 }) else Type.comptime_int;
37125 return sema.intAddInner(lhs, rhs, safe_ty, undefined) catch |err1| switch (err1) {37502 return sema.intAddInner(lhs, rhs, safe_ty, undefined) catch |err1| switch (err1) {
...@@ -37132,13 +37509,14 @@ fn intAdd(sema: *Sema, lhs: Value, rhs: Value, ty: Type, overflow_idx: *?usize)...@@ -37132,13 +37509,14 @@ fn intAdd(sema: *Sema, lhs: Value, rhs: Value, ty: Type, overflow_idx: *?usize)
37132}37509}
3713337510
37134fn intAddInner(sema: *Sema, lhs: Value, rhs: Value, ty: Type, overflow_idx: *usize) !Value {37511fn intAddInner(sema: *Sema, lhs: Value, rhs: Value, ty: Type, overflow_idx: *usize) !Value {
37135 const mod = sema.mod;37512 const pt = sema.pt;
37513 const mod = pt.zcu;
37136 if (ty.zigTypeTag(mod) == .Vector) {37514 if (ty.zigTypeTag(mod) == .Vector) {
37137 const result_data = try sema.arena.alloc(InternPool.Index, ty.vectorLen(mod));37515 const result_data = try sema.arena.alloc(InternPool.Index, ty.vectorLen(mod));
37138 const scalar_ty = ty.scalarType(mod);37516 const scalar_ty = ty.scalarType(mod);
37139 for (result_data, 0..) |*scalar, i| {37517 for (result_data, 0..) |*scalar, i| {
37140 const lhs_elem = try lhs.elemValue(mod, i);37518 const lhs_elem = try lhs.elemValue(pt, i);
37141 const rhs_elem = try rhs.elemValue(mod, i);37519 const rhs_elem = try rhs.elemValue(pt, i);
37142 const val = sema.intAddScalar(lhs_elem, rhs_elem, scalar_ty) catch |err| switch (err) {37520 const val = sema.intAddScalar(lhs_elem, rhs_elem, scalar_ty) catch |err| switch (err) {
37143 error.Overflow => {37521 error.Overflow => {
37144 overflow_idx.* = i;37522 overflow_idx.* = i;
...@@ -37148,34 +37526,34 @@ fn intAddInner(sema: *Sema, lhs: Value, rhs: Value, ty: Type, overflow_idx: *usi...@@ -37148,34 +37526,34 @@ fn intAddInner(sema: *Sema, lhs: Value, rhs: Value, ty: Type, overflow_idx: *usi
37148 };37526 };
37149 scalar.* = val.toIntern();37527 scalar.* = val.toIntern();
37150 }37528 }
37151 return Value.fromInterned((try mod.intern(.{ .aggregate = .{37529 return Value.fromInterned(try pt.intern(.{ .aggregate = .{
37152 .ty = ty.toIntern(),37530 .ty = ty.toIntern(),
37153 .storage = .{ .elems = result_data },37531 .storage = .{ .elems = result_data },
37154 } })));37532 } }));
37155 }37533 }
37156 return sema.intAddScalar(lhs, rhs, ty);37534 return sema.intAddScalar(lhs, rhs, ty);
37157}37535}
3715837536
37159fn intAddScalar(sema: *Sema, lhs: Value, rhs: Value, scalar_ty: Type) !Value {37537fn intAddScalar(sema: *Sema, lhs: Value, rhs: Value, scalar_ty: Type) !Value {
37160 const mod = sema.mod;37538 const pt = sema.pt;
37161 if (scalar_ty.toIntern() != .comptime_int_type) {37539 if (scalar_ty.toIntern() != .comptime_int_type) {
37162 const res = try sema.intAddWithOverflowScalar(lhs, rhs, scalar_ty);37540 const res = try sema.intAddWithOverflowScalar(lhs, rhs, scalar_ty);
37163 if (res.overflow_bit.compareAllWithZero(.neq, mod)) return error.Overflow;37541 if (res.overflow_bit.compareAllWithZero(.neq, pt)) return error.Overflow;
37164 return res.wrapped_result;37542 return res.wrapped_result;
37165 }37543 }
37166 // TODO is this a performance issue? maybe we should try the operation without37544 // TODO is this a performance issue? maybe we should try the operation without
37167 // resorting to BigInt first.37545 // resorting to BigInt first.
37168 var lhs_space: Value.BigIntSpace = undefined;37546 var lhs_space: Value.BigIntSpace = undefined;
37169 var rhs_space: Value.BigIntSpace = undefined;37547 var rhs_space: Value.BigIntSpace = undefined;
37170 const lhs_bigint = try lhs.toBigIntAdvanced(&lhs_space, mod, .sema);37548 const lhs_bigint = try lhs.toBigIntAdvanced(&lhs_space, pt, .sema);
37171 const rhs_bigint = try rhs.toBigIntAdvanced(&rhs_space, mod, .sema);37549 const rhs_bigint = try rhs.toBigIntAdvanced(&rhs_space, pt, .sema);
37172 const limbs = try sema.arena.alloc(37550 const limbs = try sema.arena.alloc(
37173 std.math.big.Limb,37551 std.math.big.Limb,
37174 @max(lhs_bigint.limbs.len, rhs_bigint.limbs.len) + 1,37552 @max(lhs_bigint.limbs.len, rhs_bigint.limbs.len) + 1,
37175 );37553 );
37176 var result_bigint = std.math.big.int.Mutable{ .limbs = limbs, .positive = undefined, .len = undefined };37554 var result_bigint = std.math.big.int.Mutable{ .limbs = limbs, .positive = undefined, .len = undefined };
37177 result_bigint.add(lhs_bigint, rhs_bigint);37555 result_bigint.add(lhs_bigint, rhs_bigint);
37178 return mod.intValue_big(scalar_ty, result_bigint.toConst());37556 return pt.intValue_big(scalar_ty, result_bigint.toConst());
37179}37557}
3718037558
37181/// Supports both floats and ints; handles undefined.37559/// Supports both floats and ints; handles undefined.
...@@ -37185,15 +37563,16 @@ fn numberAddWrapScalar(...@@ -37185,15 +37563,16 @@ fn numberAddWrapScalar(
37185 rhs: Value,37563 rhs: Value,
37186 ty: Type,37564 ty: Type,
37187) !Value {37565) !Value {
37188 const mod = sema.mod;37566 const pt = sema.pt;
37189 if (lhs.isUndef(mod) or rhs.isUndef(mod)) return mod.undefValue(ty);37567 const mod = pt.zcu;
37568 if (lhs.isUndef(mod) or rhs.isUndef(mod)) return pt.undefValue(ty);
3719037569
37191 if (ty.zigTypeTag(mod) == .ComptimeInt) {37570 if (ty.zigTypeTag(mod) == .ComptimeInt) {
37192 return sema.intAdd(lhs, rhs, ty, undefined);37571 return sema.intAdd(lhs, rhs, ty, undefined);
37193 }37572 }
3719437573
37195 if (ty.isAnyFloat()) {37574 if (ty.isAnyFloat()) {
37196 return Value.floatAdd(lhs, rhs, ty, sema.arena, mod);37575 return Value.floatAdd(lhs, rhs, ty, sema.arena, pt);
37197 }37576 }
3719837577
37199 const overflow_result = try sema.intAddWithOverflow(lhs, rhs, ty);37578 const overflow_result = try sema.intAddWithOverflow(lhs, rhs, ty);
...@@ -37203,13 +37582,14 @@ fn numberAddWrapScalar(...@@ -37203,13 +37582,14 @@ fn numberAddWrapScalar(
37203/// If the value overflowed the type, returns a comptime_int (or vector thereof) instead, setting37582/// If the value overflowed the type, returns a comptime_int (or vector thereof) instead, setting
37204/// overflow_idx to the vector index the overflow was at (or 0 for a scalar).37583/// overflow_idx to the vector index the overflow was at (or 0 for a scalar).
37205fn intSub(sema: *Sema, lhs: Value, rhs: Value, ty: Type, overflow_idx: *?usize) !Value {37584fn intSub(sema: *Sema, lhs: Value, rhs: Value, ty: Type, overflow_idx: *?usize) !Value {
37585 const pt = sema.pt;
37206 var overflow: usize = undefined;37586 var overflow: usize = undefined;
37207 return sema.intSubInner(lhs, rhs, ty, &overflow) catch |err| switch (err) {37587 return sema.intSubInner(lhs, rhs, ty, &overflow) catch |err| switch (err) {
37208 error.Overflow => {37588 error.Overflow => {
37209 const is_vec = ty.isVector(sema.mod);37589 const is_vec = ty.isVector(pt.zcu);
37210 overflow_idx.* = if (is_vec) overflow else 0;37590 overflow_idx.* = if (is_vec) overflow else 0;
37211 const safe_ty = if (is_vec) try sema.mod.vectorType(.{37591 const safe_ty = if (is_vec) try pt.vectorType(.{
37212 .len = ty.vectorLen(sema.mod),37592 .len = ty.vectorLen(pt.zcu),
37213 .child = .comptime_int_type,37593 .child = .comptime_int_type,
37214 }) else Type.comptime_int;37594 }) else Type.comptime_int;
37215 return sema.intSubInner(lhs, rhs, safe_ty, undefined) catch |err1| switch (err1) {37595 return sema.intSubInner(lhs, rhs, safe_ty, undefined) catch |err1| switch (err1) {
...@@ -37222,13 +37602,13 @@ fn intSub(sema: *Sema, lhs: Value, rhs: Value, ty: Type, overflow_idx: *?usize)...@@ -37222,13 +37602,13 @@ fn intSub(sema: *Sema, lhs: Value, rhs: Value, ty: Type, overflow_idx: *?usize)
37222}37602}
3722337603
37224fn intSubInner(sema: *Sema, lhs: Value, rhs: Value, ty: Type, overflow_idx: *usize) !Value {37604fn intSubInner(sema: *Sema, lhs: Value, rhs: Value, ty: Type, overflow_idx: *usize) !Value {
37225 const mod = sema.mod;37605 const pt = sema.pt;
37226 if (ty.zigTypeTag(mod) == .Vector) {37606 if (ty.zigTypeTag(pt.zcu) == .Vector) {
37227 const result_data = try sema.arena.alloc(InternPool.Index, ty.vectorLen(mod));37607 const result_data = try sema.arena.alloc(InternPool.Index, ty.vectorLen(pt.zcu));
37228 const scalar_ty = ty.scalarType(mod);37608 const scalar_ty = ty.scalarType(pt.zcu);
37229 for (result_data, 0..) |*scalar, i| {37609 for (result_data, 0..) |*scalar, i| {
37230 const lhs_elem = try lhs.elemValue(sema.mod, i);37610 const lhs_elem = try lhs.elemValue(pt, i);
37231 const rhs_elem = try rhs.elemValue(sema.mod, i);37611 const rhs_elem = try rhs.elemValue(pt, i);
37232 const val = sema.intSubScalar(lhs_elem, rhs_elem, scalar_ty) catch |err| switch (err) {37612 const val = sema.intSubScalar(lhs_elem, rhs_elem, scalar_ty) catch |err| switch (err) {
37233 error.Overflow => {37613 error.Overflow => {
37234 overflow_idx.* = i;37614 overflow_idx.* = i;
...@@ -37238,34 +37618,34 @@ fn intSubInner(sema: *Sema, lhs: Value, rhs: Value, ty: Type, overflow_idx: *usi...@@ -37238,34 +37618,34 @@ fn intSubInner(sema: *Sema, lhs: Value, rhs: Value, ty: Type, overflow_idx: *usi
37238 };37618 };
37239 scalar.* = val.toIntern();37619 scalar.* = val.toIntern();
37240 }37620 }
37241 return Value.fromInterned((try mod.intern(.{ .aggregate = .{37621 return Value.fromInterned(try pt.intern(.{ .aggregate = .{
37242 .ty = ty.toIntern(),37622 .ty = ty.toIntern(),
37243 .storage = .{ .elems = result_data },37623 .storage = .{ .elems = result_data },
37244 } })));37624 } }));
37245 }37625 }
37246 return sema.intSubScalar(lhs, rhs, ty);37626 return sema.intSubScalar(lhs, rhs, ty);
37247}37627}
3724837628
37249fn intSubScalar(sema: *Sema, lhs: Value, rhs: Value, scalar_ty: Type) !Value {37629fn intSubScalar(sema: *Sema, lhs: Value, rhs: Value, scalar_ty: Type) !Value {
37250 const mod = sema.mod;37630 const pt = sema.pt;
37251 if (scalar_ty.toIntern() != .comptime_int_type) {37631 if (scalar_ty.toIntern() != .comptime_int_type) {
37252 const res = try sema.intSubWithOverflowScalar(lhs, rhs, scalar_ty);37632 const res = try sema.intSubWithOverflowScalar(lhs, rhs, scalar_ty);
37253 if (res.overflow_bit.compareAllWithZero(.neq, mod)) return error.Overflow;37633 if (res.overflow_bit.compareAllWithZero(.neq, pt)) return error.Overflow;
37254 return res.wrapped_result;37634 return res.wrapped_result;
37255 }37635 }
37256 // TODO is this a performance issue? maybe we should try the operation without37636 // TODO is this a performance issue? maybe we should try the operation without
37257 // resorting to BigInt first.37637 // resorting to BigInt first.
37258 var lhs_space: Value.BigIntSpace = undefined;37638 var lhs_space: Value.BigIntSpace = undefined;
37259 var rhs_space: Value.BigIntSpace = undefined;37639 var rhs_space: Value.BigIntSpace = undefined;
37260 const lhs_bigint = try lhs.toBigIntAdvanced(&lhs_space, mod, .sema);37640 const lhs_bigint = try lhs.toBigIntAdvanced(&lhs_space, pt, .sema);
37261 const rhs_bigint = try rhs.toBigIntAdvanced(&rhs_space, mod, .sema);37641 const rhs_bigint = try rhs.toBigIntAdvanced(&rhs_space, pt, .sema);
37262 const limbs = try sema.arena.alloc(37642 const limbs = try sema.arena.alloc(
37263 std.math.big.Limb,37643 std.math.big.Limb,
37264 @max(lhs_bigint.limbs.len, rhs_bigint.limbs.len) + 1,37644 @max(lhs_bigint.limbs.len, rhs_bigint.limbs.len) + 1,
37265 );37645 );
37266 var result_bigint = std.math.big.int.Mutable{ .limbs = limbs, .positive = undefined, .len = undefined };37646 var result_bigint = std.math.big.int.Mutable{ .limbs = limbs, .positive = undefined, .len = undefined };
37267 result_bigint.sub(lhs_bigint, rhs_bigint);37647 result_bigint.sub(lhs_bigint, rhs_bigint);
37268 return mod.intValue_big(scalar_ty, result_bigint.toConst());37648 return pt.intValue_big(scalar_ty, result_bigint.toConst());
37269}37649}
3727037650
37271/// Supports both floats and ints; handles undefined.37651/// Supports both floats and ints; handles undefined.
...@@ -37275,15 +37655,16 @@ fn numberSubWrapScalar(...@@ -37275,15 +37655,16 @@ fn numberSubWrapScalar(
37275 rhs: Value,37655 rhs: Value,
37276 ty: Type,37656 ty: Type,
37277) !Value {37657) !Value {
37278 const mod = sema.mod;37658 const pt = sema.pt;
37279 if (lhs.isUndef(mod) or rhs.isUndef(mod)) return mod.undefValue(ty);37659 const mod = pt.zcu;
37660 if (lhs.isUndef(mod) or rhs.isUndef(mod)) return pt.undefValue(ty);
3728037661
37281 if (ty.zigTypeTag(mod) == .ComptimeInt) {37662 if (ty.zigTypeTag(mod) == .ComptimeInt) {
37282 return sema.intSub(lhs, rhs, ty, undefined);37663 return sema.intSub(lhs, rhs, ty, undefined);
37283 }37664 }
3728437665
37285 if (ty.isAnyFloat()) {37666 if (ty.isAnyFloat()) {
37286 return Value.floatSub(lhs, rhs, ty, sema.arena, mod);37667 return Value.floatSub(lhs, rhs, ty, sema.arena, pt);
37287 }37668 }
3728837669
37289 const overflow_result = try sema.intSubWithOverflow(lhs, rhs, ty);37670 const overflow_result = try sema.intSubWithOverflow(lhs, rhs, ty);
...@@ -37296,28 +37677,29 @@ fn intSubWithOverflow(...@@ -37296,28 +37677,29 @@ fn intSubWithOverflow(
37296 rhs: Value,37677 rhs: Value,
37297 ty: Type,37678 ty: Type,
37298) !Value.OverflowArithmeticResult {37679) !Value.OverflowArithmeticResult {
37299 const mod = sema.mod;37680 const pt = sema.pt;
37681 const mod = pt.zcu;
37300 if (ty.zigTypeTag(mod) == .Vector) {37682 if (ty.zigTypeTag(mod) == .Vector) {
37301 const vec_len = ty.vectorLen(mod);37683 const vec_len = ty.vectorLen(mod);
37302 const overflowed_data = try sema.arena.alloc(InternPool.Index, vec_len);37684 const overflowed_data = try sema.arena.alloc(InternPool.Index, vec_len);
37303 const result_data = try sema.arena.alloc(InternPool.Index, vec_len);37685 const result_data = try sema.arena.alloc(InternPool.Index, vec_len);
37304 const scalar_ty = ty.scalarType(mod);37686 const scalar_ty = ty.scalarType(mod);
37305 for (overflowed_data, result_data, 0..) |*of, *scalar, i| {37687 for (overflowed_data, result_data, 0..) |*of, *scalar, i| {
37306 const lhs_elem = try lhs.elemValue(sema.mod, i);37688 const lhs_elem = try lhs.elemValue(pt, i);
37307 const rhs_elem = try rhs.elemValue(sema.mod, i);37689 const rhs_elem = try rhs.elemValue(pt, i);
37308 const of_math_result = try sema.intSubWithOverflowScalar(lhs_elem, rhs_elem, scalar_ty);37690 const of_math_result = try sema.intSubWithOverflowScalar(lhs_elem, rhs_elem, scalar_ty);
37309 of.* = of_math_result.overflow_bit.toIntern();37691 of.* = of_math_result.overflow_bit.toIntern();
37310 scalar.* = of_math_result.wrapped_result.toIntern();37692 scalar.* = of_math_result.wrapped_result.toIntern();
37311 }37693 }
37312 return Value.OverflowArithmeticResult{37694 return Value.OverflowArithmeticResult{
37313 .overflow_bit = Value.fromInterned((try mod.intern(.{ .aggregate = .{37695 .overflow_bit = Value.fromInterned(try pt.intern(.{ .aggregate = .{
37314 .ty = (try mod.vectorType(.{ .len = vec_len, .child = .u1_type })).toIntern(),37696 .ty = (try pt.vectorType(.{ .len = vec_len, .child = .u1_type })).toIntern(),
37315 .storage = .{ .elems = overflowed_data },37697 .storage = .{ .elems = overflowed_data },
37316 } }))),37698 } })),
37317 .wrapped_result = Value.fromInterned((try mod.intern(.{ .aggregate = .{37699 .wrapped_result = Value.fromInterned(try pt.intern(.{ .aggregate = .{
37318 .ty = ty.toIntern(),37700 .ty = ty.toIntern(),
37319 .storage = .{ .elems = result_data },37701 .storage = .{ .elems = result_data },
37320 } }))),37702 } })),
37321 };37703 };
37322 }37704 }
37323 return sema.intSubWithOverflowScalar(lhs, rhs, ty);37705 return sema.intSubWithOverflowScalar(lhs, rhs, ty);
...@@ -37329,29 +37711,30 @@ fn intSubWithOverflowScalar(...@@ -37329,29 +37711,30 @@ fn intSubWithOverflowScalar(
37329 rhs: Value,37711 rhs: Value,
37330 ty: Type,37712 ty: Type,
37331) !Value.OverflowArithmeticResult {37713) !Value.OverflowArithmeticResult {
37332 const mod = sema.mod;37714 const pt = sema.pt;
37715 const mod = pt.zcu;
37333 const info = ty.intInfo(mod);37716 const info = ty.intInfo(mod);
3733437717
37335 if (lhs.isUndef(mod) or rhs.isUndef(mod)) {37718 if (lhs.isUndef(mod) or rhs.isUndef(mod)) {
37336 return .{37719 return .{
37337 .overflow_bit = try mod.undefValue(Type.u1),37720 .overflow_bit = try pt.undefValue(Type.u1),
37338 .wrapped_result = try mod.undefValue(ty),37721 .wrapped_result = try pt.undefValue(ty),
37339 };37722 };
37340 }37723 }
3734137724
37342 var lhs_space: Value.BigIntSpace = undefined;37725 var lhs_space: Value.BigIntSpace = undefined;
37343 var rhs_space: Value.BigIntSpace = undefined;37726 var rhs_space: Value.BigIntSpace = undefined;
37344 const lhs_bigint = try lhs.toBigIntAdvanced(&lhs_space, mod, .sema);37727 const lhs_bigint = try lhs.toBigIntAdvanced(&lhs_space, pt, .sema);
37345 const rhs_bigint = try rhs.toBigIntAdvanced(&rhs_space, mod, .sema);37728 const rhs_bigint = try rhs.toBigIntAdvanced(&rhs_space, pt, .sema);
37346 const limbs = try sema.arena.alloc(37729 const limbs = try sema.arena.alloc(
37347 std.math.big.Limb,37730 std.math.big.Limb,
37348 std.math.big.int.calcTwosCompLimbCount(info.bits),37731 std.math.big.int.calcTwosCompLimbCount(info.bits),
37349 );37732 );
37350 var result_bigint = std.math.big.int.Mutable{ .limbs = limbs, .positive = undefined, .len = undefined };37733 var result_bigint = std.math.big.int.Mutable{ .limbs = limbs, .positive = undefined, .len = undefined };
37351 const overflowed = result_bigint.subWrap(lhs_bigint, rhs_bigint, info.signedness, info.bits);37734 const overflowed = result_bigint.subWrap(lhs_bigint, rhs_bigint, info.signedness, info.bits);
37352 const wrapped_result = try mod.intValue_big(ty, result_bigint.toConst());37735 const wrapped_result = try pt.intValue_big(ty, result_bigint.toConst());
37353 return Value.OverflowArithmeticResult{37736 return Value.OverflowArithmeticResult{
37354 .overflow_bit = try mod.intValue(Type.u1, @intFromBool(overflowed)),37737 .overflow_bit = try pt.intValue(Type.u1, @intFromBool(overflowed)),
37355 .wrapped_result = wrapped_result,37738 .wrapped_result = wrapped_result,
37356 };37739 };
37357}37740}
...@@ -37367,17 +37750,18 @@ fn intFromFloat(...@@ -37367,17 +37750,18 @@ fn intFromFloat(
37367 int_ty: Type,37750 int_ty: Type,
37368 mode: IntFromFloatMode,37751 mode: IntFromFloatMode,
37369) CompileError!Value {37752) CompileError!Value {
37370 const mod = sema.mod;37753 const pt = sema.pt;
37754 const mod = pt.zcu;
37371 if (float_ty.zigTypeTag(mod) == .Vector) {37755 if (float_ty.zigTypeTag(mod) == .Vector) {
37372 const result_data = try sema.arena.alloc(InternPool.Index, float_ty.vectorLen(mod));37756 const result_data = try sema.arena.alloc(InternPool.Index, float_ty.vectorLen(mod));
37373 for (result_data, 0..) |*scalar, i| {37757 for (result_data, 0..) |*scalar, i| {
37374 const elem_val = try val.elemValue(sema.mod, i);37758 const elem_val = try val.elemValue(pt, i);
37375 scalar.* = (try sema.intFromFloatScalar(block, src, elem_val, int_ty.scalarType(mod), mode)).toIntern();37759 scalar.* = (try sema.intFromFloatScalar(block, src, elem_val, int_ty.scalarType(mod), mode)).toIntern();
37376 }37760 }
37377 return Value.fromInterned((try mod.intern(.{ .aggregate = .{37761 return Value.fromInterned(try pt.intern(.{ .aggregate = .{
37378 .ty = int_ty.toIntern(),37762 .ty = int_ty.toIntern(),
37379 .storage = .{ .elems = result_data },37763 .storage = .{ .elems = result_data },
37380 } })));37764 } }));
37381 }37765 }
37382 return sema.intFromFloatScalar(block, src, val, int_ty, mode);37766 return sema.intFromFloatScalar(block, src, val, int_ty, mode);
37383}37767}
...@@ -37415,7 +37799,8 @@ fn intFromFloatScalar(...@@ -37415,7 +37799,8 @@ fn intFromFloatScalar(
37415 int_ty: Type,37799 int_ty: Type,
37416 mode: IntFromFloatMode,37800 mode: IntFromFloatMode,
37417) CompileError!Value {37801) CompileError!Value {
37418 const mod = sema.mod;37802 const pt = sema.pt;
37803 const mod = pt.zcu;
3741937804
37420 if (val.isUndef(mod)) return sema.failWithUseOfUndef(block, src);37805 if (val.isUndef(mod)) return sema.failWithUseOfUndef(block, src);
3742137806
...@@ -37423,32 +37808,32 @@ fn intFromFloatScalar(...@@ -37423,32 +37808,32 @@ fn intFromFloatScalar(
37423 block,37808 block,
37424 src,37809 src,
37425 "fractional component prevents float value '{}' from coercion to type '{}'",37810 "fractional component prevents float value '{}' from coercion to type '{}'",
37426 .{ val.fmtValue(mod, sema), int_ty.fmt(mod) },37811 .{ val.fmtValue(pt, sema), int_ty.fmt(pt) },
37427 );37812 );
3742837813
37429 const float = val.toFloat(f128, mod);37814 const float = val.toFloat(f128, pt);
37430 if (std.math.isNan(float)) {37815 if (std.math.isNan(float)) {
37431 return sema.fail(block, src, "float value NaN cannot be stored in integer type '{}'", .{37816 return sema.fail(block, src, "float value NaN cannot be stored in integer type '{}'", .{
37432 int_ty.fmt(sema.mod),37817 int_ty.fmt(pt),
37433 });37818 });
37434 }37819 }
37435 if (std.math.isInf(float)) {37820 if (std.math.isInf(float)) {
37436 return sema.fail(block, src, "float value Inf cannot be stored in integer type '{}'", .{37821 return sema.fail(block, src, "float value Inf cannot be stored in integer type '{}'", .{
37437 int_ty.fmt(sema.mod),37822 int_ty.fmt(pt),
37438 });37823 });
37439 }37824 }
3744037825
37441 var big_int = try float128IntPartToBigInt(sema.arena, float);37826 var big_int = try float128IntPartToBigInt(sema.arena, float);
37442 defer big_int.deinit();37827 defer big_int.deinit();
3744337828
37444 const cti_result = try mod.intValue_big(Type.comptime_int, big_int.toConst());37829 const cti_result = try pt.intValue_big(Type.comptime_int, big_int.toConst());
3744537830
37446 if (!(try sema.intFitsInType(cti_result, int_ty, null))) {37831 if (!(try sema.intFitsInType(cti_result, int_ty, null))) {
37447 return sema.fail(block, src, "float value '{}' cannot be stored in integer type '{}'", .{37832 return sema.fail(block, src, "float value '{}' cannot be stored in integer type '{}'", .{
37448 val.fmtValue(sema.mod, sema), int_ty.fmt(sema.mod),37833 val.fmtValue(pt, sema), int_ty.fmt(pt),
37449 });37834 });
37450 }37835 }
37451 return mod.getCoerced(cti_result, int_ty);37836 return pt.getCoerced(cti_result, int_ty);
37452}37837}
3745337838
37454/// Asserts the value is an integer, and the destination type is ComptimeInt or Int.37839/// Asserts the value is an integer, and the destination type is ComptimeInt or Int.
...@@ -37461,7 +37846,8 @@ fn intFitsInType(...@@ -37461,7 +37846,8 @@ fn intFitsInType(
37461 ty: Type,37846 ty: Type,
37462 vector_index: ?*usize,37847 vector_index: ?*usize,
37463) CompileError!bool {37848) CompileError!bool {
37464 const mod = sema.mod;37849 const pt = sema.pt;
37850 const mod = pt.zcu;
37465 if (ty.toIntern() == .comptime_int_type) return true;37851 if (ty.toIntern() == .comptime_int_type) return true;
37466 const info = ty.intInfo(mod);37852 const info = ty.intInfo(mod);
37467 switch (val.toIntern()) {37853 switch (val.toIntern()) {
...@@ -37528,22 +37914,23 @@ fn intFitsInType(...@@ -37528,22 +37914,23 @@ fn intFitsInType(
37528}37914}
3752937915
37530fn intInRange(sema: *Sema, tag_ty: Type, int_val: Value, end: usize) !bool {37916fn intInRange(sema: *Sema, tag_ty: Type, int_val: Value, end: usize) !bool {
37531 const mod = sema.mod;37917 const pt = sema.pt;
37532 if (!(try int_val.compareAllWithZeroSema(.gte, mod))) return false;37918 if (!(try int_val.compareAllWithZeroSema(.gte, pt))) return false;
37533 const end_val = try mod.intValue(tag_ty, end);37919 const end_val = try pt.intValue(tag_ty, end);
37534 if (!(try sema.compareAll(int_val, .lt, end_val, tag_ty))) return false;37920 if (!(try sema.compareAll(int_val, .lt, end_val, tag_ty))) return false;
37535 return true;37921 return true;
37536}37922}
3753737923
37538/// Asserts the type is an enum.37924/// Asserts the type is an enum.
37539fn enumHasInt(sema: *Sema, ty: Type, int: Value) CompileError!bool {37925fn enumHasInt(sema: *Sema, ty: Type, int: Value) CompileError!bool {
37540 const mod = sema.mod;37926 const pt = sema.pt;
37927 const mod = pt.zcu;
37541 const enum_type = mod.intern_pool.loadEnumType(ty.toIntern());37928 const enum_type = mod.intern_pool.loadEnumType(ty.toIntern());
37542 assert(enum_type.tag_mode != .nonexhaustive);37929 assert(enum_type.tag_mode != .nonexhaustive);
37543 // The `tagValueIndex` function call below relies on the type being the integer tag type.37930 // The `tagValueIndex` function call below relies on the type being the integer tag type.
37544 // `getCoerced` assumes the value will fit the new type.37931 // `getCoerced` assumes the value will fit the new type.
37545 if (!(try sema.intFitsInType(int, Type.fromInterned(enum_type.tag_ty), null))) return false;37932 if (!(try sema.intFitsInType(int, Type.fromInterned(enum_type.tag_ty), null))) return false;
37546 const int_coerced = try mod.getCoerced(int, Type.fromInterned(enum_type.tag_ty));37933 const int_coerced = try pt.getCoerced(int, Type.fromInterned(enum_type.tag_ty));
3754737934
37548 return enum_type.tagValueIndex(&mod.intern_pool, int_coerced.toIntern()) != null;37935 return enum_type.tagValueIndex(&mod.intern_pool, int_coerced.toIntern()) != null;
37549}37936}
...@@ -37554,28 +37941,29 @@ fn intAddWithOverflow(...@@ -37554,28 +37941,29 @@ fn intAddWithOverflow(
37554 rhs: Value,37941 rhs: Value,
37555 ty: Type,37942 ty: Type,
37556) !Value.OverflowArithmeticResult {37943) !Value.OverflowArithmeticResult {
37557 const mod = sema.mod;37944 const pt = sema.pt;
37945 const mod = pt.zcu;
37558 if (ty.zigTypeTag(mod) == .Vector) {37946 if (ty.zigTypeTag(mod) == .Vector) {
37559 const vec_len = ty.vectorLen(mod);37947 const vec_len = ty.vectorLen(mod);
37560 const overflowed_data = try sema.arena.alloc(InternPool.Index, vec_len);37948 const overflowed_data = try sema.arena.alloc(InternPool.Index, vec_len);
37561 const result_data = try sema.arena.alloc(InternPool.Index, vec_len);37949 const result_data = try sema.arena.alloc(InternPool.Index, vec_len);
37562 const scalar_ty = ty.scalarType(mod);37950 const scalar_ty = ty.scalarType(mod);
37563 for (overflowed_data, result_data, 0..) |*of, *scalar, i| {37951 for (overflowed_data, result_data, 0..) |*of, *scalar, i| {
37564 const lhs_elem = try lhs.elemValue(sema.mod, i);37952 const lhs_elem = try lhs.elemValue(pt, i);
37565 const rhs_elem = try rhs.elemValue(sema.mod, i);37953 const rhs_elem = try rhs.elemValue(pt, i);
37566 const of_math_result = try sema.intAddWithOverflowScalar(lhs_elem, rhs_elem, scalar_ty);37954 const of_math_result = try sema.intAddWithOverflowScalar(lhs_elem, rhs_elem, scalar_ty);
37567 of.* = of_math_result.overflow_bit.toIntern();37955 of.* = of_math_result.overflow_bit.toIntern();
37568 scalar.* = of_math_result.wrapped_result.toIntern();37956 scalar.* = of_math_result.wrapped_result.toIntern();
37569 }37957 }
37570 return Value.OverflowArithmeticResult{37958 return Value.OverflowArithmeticResult{
37571 .overflow_bit = Value.fromInterned((try mod.intern(.{ .aggregate = .{37959 .overflow_bit = Value.fromInterned(try pt.intern(.{ .aggregate = .{
37572 .ty = (try mod.vectorType(.{ .len = vec_len, .child = .u1_type })).toIntern(),37960 .ty = (try pt.vectorType(.{ .len = vec_len, .child = .u1_type })).toIntern(),
37573 .storage = .{ .elems = overflowed_data },37961 .storage = .{ .elems = overflowed_data },
37574 } }))),37962 } })),
37575 .wrapped_result = Value.fromInterned((try mod.intern(.{ .aggregate = .{37963 .wrapped_result = Value.fromInterned(try pt.intern(.{ .aggregate = .{
37576 .ty = ty.toIntern(),37964 .ty = ty.toIntern(),
37577 .storage = .{ .elems = result_data },37965 .storage = .{ .elems = result_data },
37578 } }))),37966 } })),
37579 };37967 };
37580 }37968 }
37581 return sema.intAddWithOverflowScalar(lhs, rhs, ty);37969 return sema.intAddWithOverflowScalar(lhs, rhs, ty);
...@@ -37587,29 +37975,30 @@ fn intAddWithOverflowScalar(...@@ -37587,29 +37975,30 @@ fn intAddWithOverflowScalar(
37587 rhs: Value,37975 rhs: Value,
37588 ty: Type,37976 ty: Type,
37589) !Value.OverflowArithmeticResult {37977) !Value.OverflowArithmeticResult {
37590 const mod = sema.mod;37978 const pt = sema.pt;
37979 const mod = pt.zcu;
37591 const info = ty.intInfo(mod);37980 const info = ty.intInfo(mod);
3759237981
37593 if (lhs.isUndef(mod) or rhs.isUndef(mod)) {37982 if (lhs.isUndef(mod) or rhs.isUndef(mod)) {
37594 return .{37983 return .{
37595 .overflow_bit = try mod.undefValue(Type.u1),37984 .overflow_bit = try pt.undefValue(Type.u1),
37596 .wrapped_result = try mod.undefValue(ty),37985 .wrapped_result = try pt.undefValue(ty),
37597 };37986 };
37598 }37987 }
3759937988
37600 var lhs_space: Value.BigIntSpace = undefined;37989 var lhs_space: Value.BigIntSpace = undefined;
37601 var rhs_space: Value.BigIntSpace = undefined;37990 var rhs_space: Value.BigIntSpace = undefined;
37602 const lhs_bigint = try lhs.toBigIntAdvanced(&lhs_space, mod, .sema);37991 const lhs_bigint = try lhs.toBigIntAdvanced(&lhs_space, pt, .sema);
37603 const rhs_bigint = try rhs.toBigIntAdvanced(&rhs_space, mod, .sema);37992 const rhs_bigint = try rhs.toBigIntAdvanced(&rhs_space, pt, .sema);
37604 const limbs = try sema.arena.alloc(37993 const limbs = try sema.arena.alloc(
37605 std.math.big.Limb,37994 std.math.big.Limb,
37606 std.math.big.int.calcTwosCompLimbCount(info.bits),37995 std.math.big.int.calcTwosCompLimbCount(info.bits),
37607 );37996 );
37608 var result_bigint = std.math.big.int.Mutable{ .limbs = limbs, .positive = undefined, .len = undefined };37997 var result_bigint = std.math.big.int.Mutable{ .limbs = limbs, .positive = undefined, .len = undefined };
37609 const overflowed = result_bigint.addWrap(lhs_bigint, rhs_bigint, info.signedness, info.bits);37998 const overflowed = result_bigint.addWrap(lhs_bigint, rhs_bigint, info.signedness, info.bits);
37610 const result = try mod.intValue_big(ty, result_bigint.toConst());37999 const result = try pt.intValue_big(ty, result_bigint.toConst());
37611 return Value.OverflowArithmeticResult{38000 return Value.OverflowArithmeticResult{
37612 .overflow_bit = try mod.intValue(Type.u1, @intFromBool(overflowed)),38001 .overflow_bit = try pt.intValue(Type.u1, @intFromBool(overflowed)),
37613 .wrapped_result = result,38002 .wrapped_result = result,
37614 };38003 };
37615}38004}
...@@ -37625,12 +38014,13 @@ fn compareAll(...@@ -37625,12 +38014,13 @@ fn compareAll(
37625 rhs: Value,38014 rhs: Value,
37626 ty: Type,38015 ty: Type,
37627) CompileError!bool {38016) CompileError!bool {
37628 const mod = sema.mod;38017 const pt = sema.pt;
38018 const mod = pt.zcu;
37629 if (ty.zigTypeTag(mod) == .Vector) {38019 if (ty.zigTypeTag(mod) == .Vector) {
37630 var i: usize = 0;38020 var i: usize = 0;
37631 while (i < ty.vectorLen(mod)) : (i += 1) {38021 while (i < ty.vectorLen(mod)) : (i += 1) {
37632 const lhs_elem = try lhs.elemValue(sema.mod, i);38022 const lhs_elem = try lhs.elemValue(pt, i);
37633 const rhs_elem = try rhs.elemValue(sema.mod, i);38023 const rhs_elem = try rhs.elemValue(pt, i);
37634 if (!(try sema.compareScalar(lhs_elem, op, rhs_elem, ty.scalarType(mod)))) {38024 if (!(try sema.compareScalar(lhs_elem, op, rhs_elem, ty.scalarType(mod)))) {
37635 return false;38025 return false;
37636 }38026 }
...@@ -37648,13 +38038,13 @@ fn compareScalar(...@@ -37648,13 +38038,13 @@ fn compareScalar(
37648 rhs: Value,38038 rhs: Value,
37649 ty: Type,38039 ty: Type,
37650) CompileError!bool {38040) CompileError!bool {
37651 const mod = sema.mod;38041 const pt = sema.pt;
37652 const coerced_lhs = try mod.getCoerced(lhs, ty);38042 const coerced_lhs = try pt.getCoerced(lhs, ty);
37653 const coerced_rhs = try mod.getCoerced(rhs, ty);38043 const coerced_rhs = try pt.getCoerced(rhs, ty);
37654 switch (op) {38044 switch (op) {
37655 .eq => return sema.valuesEqual(coerced_lhs, coerced_rhs, ty),38045 .eq => return sema.valuesEqual(coerced_lhs, coerced_rhs, ty),
37656 .neq => return !(try sema.valuesEqual(coerced_lhs, coerced_rhs, ty)),38046 .neq => return !(try sema.valuesEqual(coerced_lhs, coerced_rhs, ty)),
37657 else => return Value.compareHeteroAdvanced(coerced_lhs, op, coerced_rhs, mod, .sema),38047 else => return Value.compareHeteroAdvanced(coerced_lhs, op, coerced_rhs, pt, .sema),
37658 }38048 }
37659}38049}
3766038050
...@@ -37664,7 +38054,7 @@ fn valuesEqual(...@@ -37664,7 +38054,7 @@ fn valuesEqual(
37664 rhs: Value,38054 rhs: Value,
37665 ty: Type,38055 ty: Type,
37666) CompileError!bool {38056) CompileError!bool {
37667 return lhs.eql(rhs, ty, sema.mod);38057 return lhs.eql(rhs, ty, sema.pt.zcu);
37668}38058}
3766938059
37670/// Asserts the values are comparable vectors of type `ty`.38060/// Asserts the values are comparable vectors of type `ty`.
...@@ -37675,29 +38065,30 @@ fn compareVector(...@@ -37675,29 +38065,30 @@ fn compareVector(
37675 rhs: Value,38065 rhs: Value,
37676 ty: Type,38066 ty: Type,
37677) !Value {38067) !Value {
37678 const mod = sema.mod;38068 const pt = sema.pt;
38069 const mod = pt.zcu;
37679 assert(ty.zigTypeTag(mod) == .Vector);38070 assert(ty.zigTypeTag(mod) == .Vector);
37680 const result_data = try sema.arena.alloc(InternPool.Index, ty.vectorLen(mod));38071 const result_data = try sema.arena.alloc(InternPool.Index, ty.vectorLen(mod));
37681 for (result_data, 0..) |*scalar, i| {38072 for (result_data, 0..) |*scalar, i| {
37682 const lhs_elem = try lhs.elemValue(sema.mod, i);38073 const lhs_elem = try lhs.elemValue(pt, i);
37683 const rhs_elem = try rhs.elemValue(sema.mod, i);38074 const rhs_elem = try rhs.elemValue(pt, i);
37684 const res_bool = try sema.compareScalar(lhs_elem, op, rhs_elem, ty.scalarType(mod));38075 const res_bool = try sema.compareScalar(lhs_elem, op, rhs_elem, ty.scalarType(mod));
37685 scalar.* = Value.makeBool(res_bool).toIntern();38076 scalar.* = Value.makeBool(res_bool).toIntern();
37686 }38077 }
37687 return Value.fromInterned((try mod.intern(.{ .aggregate = .{38078 return Value.fromInterned(try pt.intern(.{ .aggregate = .{
37688 .ty = (try mod.vectorType(.{ .len = ty.vectorLen(mod), .child = .bool_type })).toIntern(),38079 .ty = (try pt.vectorType(.{ .len = ty.vectorLen(mod), .child = .bool_type })).toIntern(),
37689 .storage = .{ .elems = result_data },38080 .storage = .{ .elems = result_data },
37690 } })));38081 } }));
37691}38082}
3769238083
37693/// Merge lhs with rhs.38084/// Merge lhs with rhs.
37694/// Asserts that lhs and rhs are both error sets and are resolved.38085/// Asserts that lhs and rhs are both error sets and are resolved.
37695fn errorSetMerge(sema: *Sema, lhs: Type, rhs: Type) !Type {38086fn errorSetMerge(sema: *Sema, lhs: Type, rhs: Type) !Type {
37696 const mod = sema.mod;38087 const pt = sema.pt;
37697 const ip = &mod.intern_pool;38088 const ip = &pt.zcu.intern_pool;
37698 const arena = sema.arena;38089 const arena = sema.arena;
37699 const lhs_names = lhs.errorSetNames(mod);38090 const lhs_names = lhs.errorSetNames(pt.zcu);
37700 const rhs_names = rhs.errorSetNames(mod);38091 const rhs_names = rhs.errorSetNames(pt.zcu);
37701 var names: InferredErrorSet.NameMap = .{};38092 var names: InferredErrorSet.NameMap = .{};
37702 try names.ensureUnusedCapacity(arena, lhs_names.len);38093 try names.ensureUnusedCapacity(arena, lhs_names.len);
3770338094
...@@ -37708,7 +38099,7 @@ fn errorSetMerge(sema: *Sema, lhs: Type, rhs: Type) !Type {...@@ -37708,7 +38099,7 @@ fn errorSetMerge(sema: *Sema, lhs: Type, rhs: Type) !Type {
37708 try names.put(arena, rhs_names.get(ip)[rhs_index], {});38099 try names.put(arena, rhs_names.get(ip)[rhs_index], {});
37709 }38100 }
3771038101
37711 return mod.errorSetFromUnsortedNames(names.keys());38102 return pt.errorSetFromUnsortedNames(names.keys());
37712}38103}
3771338104
37714/// Avoids crashing the compiler when asking if inferred allocations are noreturn.38105/// Avoids crashing the compiler when asking if inferred allocations are noreturn.
...@@ -37718,7 +38109,7 @@ fn isNoReturn(sema: *Sema, ref: Air.Inst.Ref) bool {...@@ -37718,7 +38109,7 @@ fn isNoReturn(sema: *Sema, ref: Air.Inst.Ref) bool {
37718 .inferred_alloc, .inferred_alloc_comptime => return false,38109 .inferred_alloc, .inferred_alloc_comptime => return false,
37719 else => {},38110 else => {},
37720 };38111 };
37721 return sema.typeOf(ref).isNoReturn(sema.mod);38112 return sema.typeOf(ref).isNoReturn(sema.pt.zcu);
37722}38113}
3772338114
37724/// Avoids crashing the compiler when asking if inferred allocations are known to be a certain zig type.38115/// Avoids crashing the compiler when asking if inferred allocations are known to be a certain zig type.
...@@ -37727,11 +38118,12 @@ fn isKnownZigType(sema: *Sema, ref: Air.Inst.Ref, tag: std.builtin.TypeId) bool...@@ -37727,11 +38118,12 @@ fn isKnownZigType(sema: *Sema, ref: Air.Inst.Ref, tag: std.builtin.TypeId) bool
37727 .inferred_alloc, .inferred_alloc_comptime => return false,38118 .inferred_alloc, .inferred_alloc_comptime => return false,
37728 else => {},38119 else => {},
37729 };38120 };
37730 return sema.typeOf(ref).zigTypeTag(sema.mod) == tag;38121 return sema.typeOf(ref).zigTypeTag(sema.pt.zcu) == tag;
37731}38122}
3773238123
37733pub fn declareDependency(sema: *Sema, dependee: InternPool.Dependee) !void {38124pub fn declareDependency(sema: *Sema, dependee: InternPool.Dependee) !void {
37734 if (!sema.mod.comp.debug_incremental) return;38125 const zcu = sema.pt.zcu;
38126 if (!zcu.comp.debug_incremental) return;
3773538127
37736 // Avoid creating dependencies on ourselves. This situation can arise when we analyze the fields38128 // Avoid creating dependencies on ourselves. This situation can arise when we analyze the fields
37737 // of a type and they use `@This()`. This dependency would be unnecessary, and in fact would38129 // of a type and they use `@This()`. This dependency would be unnecessary, and in fact would
...@@ -37747,11 +38139,11 @@ pub fn declareDependency(sema: *Sema, dependee: InternPool.Dependee) !void {...@@ -37747,11 +38139,11 @@ pub fn declareDependency(sema: *Sema, dependee: InternPool.Dependee) !void {
37747 else38139 else
37748 .{ .decl = sema.owner_decl_index },38140 .{ .decl = sema.owner_decl_index },
37749 );38141 );
37750 try sema.mod.intern_pool.addDependency(sema.gpa, depender, dependee);38142 try zcu.intern_pool.addDependency(sema.gpa, depender, dependee);
37751}38143}
3775238144
37753fn isComptimeMutablePtr(sema: *Sema, val: Value) bool {38145fn isComptimeMutablePtr(sema: *Sema, val: Value) bool {
37754 return switch (sema.mod.intern_pool.indexToKey(val.toIntern())) {38146 return switch (sema.pt.zcu.intern_pool.indexToKey(val.toIntern())) {
37755 .slice => |slice| sema.isComptimeMutablePtr(Value.fromInterned(slice.ptr)),38147 .slice => |slice| sema.isComptimeMutablePtr(Value.fromInterned(slice.ptr)),
37756 .ptr => |ptr| switch (ptr.base_addr) {38148 .ptr => |ptr| switch (ptr.base_addr) {
37757 .anon_decl, .decl, .int => false,38149 .anon_decl, .decl, .int => false,
...@@ -37766,7 +38158,7 @@ fn isComptimeMutablePtr(sema: *Sema, val: Value) bool {...@@ -37766,7 +38158,7 @@ fn isComptimeMutablePtr(sema: *Sema, val: Value) bool {
3776638158
37767fn checkRuntimeValue(sema: *Sema, ptr: Air.Inst.Ref) bool {38159fn checkRuntimeValue(sema: *Sema, ptr: Air.Inst.Ref) bool {
37768 const val = ptr.toInterned() orelse return true;38160 const val = ptr.toInterned() orelse return true;
37769 return !Value.fromInterned(val).canMutateComptimeVarState(sema.mod);38161 return !Value.fromInterned(val).canMutateComptimeVarState(sema.pt.zcu);
37770}38162}
3777138163
37772fn validateRuntimeValue(sema: *Sema, block: *Block, val_src: LazySrcLoc, val: Air.Inst.Ref) CompileError!void {38164fn validateRuntimeValue(sema: *Sema, block: *Block, val_src: LazySrcLoc, val: Air.Inst.Ref) CompileError!void {
...@@ -37781,7 +38173,8 @@ fn validateRuntimeValue(sema: *Sema, block: *Block, val_src: LazySrcLoc, val: Ai...@@ -37781,7 +38173,8 @@ fn validateRuntimeValue(sema: *Sema, block: *Block, val_src: LazySrcLoc, val: Ai
3778138173
37782/// Returns true if any value contained in `val` is undefined.38174/// Returns true if any value contained in `val` is undefined.
37783fn anyUndef(sema: *Sema, block: *Block, src: LazySrcLoc, val: Value) !bool {38175fn anyUndef(sema: *Sema, block: *Block, src: LazySrcLoc, val: Value) !bool {
37784 const mod = sema.mod;38176 const pt = sema.pt;
38177 const mod = pt.zcu;
37785 return switch (mod.intern_pool.indexToKey(val.toIntern())) {38178 return switch (mod.intern_pool.indexToKey(val.toIntern())) {
37786 .undef => true,38179 .undef => true,
37787 .simple_value => |v| v == .undefined,38180 .simple_value => |v| v == .undefined,
...@@ -37807,13 +38200,14 @@ fn sliceToIpString(...@@ -37807,13 +38200,14 @@ fn sliceToIpString(
37807 slice_val: Value,38200 slice_val: Value,
37808 reason: NeededComptimeReason,38201 reason: NeededComptimeReason,
37809) CompileError!InternPool.NullTerminatedString {38202) CompileError!InternPool.NullTerminatedString {
37810 const zcu = sema.mod;38203 const pt = sema.pt;
38204 const zcu = pt.zcu;
37811 const slice_ty = slice_val.typeOf(zcu);38205 const slice_ty = slice_val.typeOf(zcu);
37812 assert(slice_ty.isSlice(zcu));38206 assert(slice_ty.isSlice(zcu));
37813 assert(slice_ty.childType(zcu).toIntern() == .u8_type);38207 assert(slice_ty.childType(zcu).toIntern() == .u8_type);
37814 const array_val = try sema.derefSliceAsArray(block, src, slice_val, reason);38208 const array_val = try sema.derefSliceAsArray(block, src, slice_val, reason);
37815 const array_ty = array_val.typeOf(zcu);38209 const array_ty = array_val.typeOf(zcu);
37816 return array_val.toIpString(array_ty, zcu);38210 return array_val.toIpString(array_ty, pt);
37817}38211}
3781838212
37819/// Given a slice value, attempts to dereference it into a comptime-known array.38213/// Given a slice value, attempts to dereference it into a comptime-known array.
...@@ -37840,7 +38234,8 @@ fn maybeDerefSliceAsArray(...@@ -37840,7 +38234,8 @@ fn maybeDerefSliceAsArray(
37840 src: LazySrcLoc,38234 src: LazySrcLoc,
37841 slice_val: Value,38235 slice_val: Value,
37842) CompileError!?Value {38236) CompileError!?Value {
37843 const zcu = sema.mod;38237 const pt = sema.pt;
38238 const zcu = pt.zcu;
37844 const ip = &zcu.intern_pool;38239 const ip = &zcu.intern_pool;
37845 assert(slice_val.typeOf(zcu).isSlice(zcu));38240 assert(slice_val.typeOf(zcu).isSlice(zcu));
37846 const slice = switch (ip.indexToKey(slice_val.toIntern())) {38241 const slice = switch (ip.indexToKey(slice_val.toIntern())) {
...@@ -37849,19 +38244,19 @@ fn maybeDerefSliceAsArray(...@@ -37849,19 +38244,19 @@ fn maybeDerefSliceAsArray(
37849 else => unreachable,38244 else => unreachable,
37850 };38245 };
37851 const elem_ty = Type.fromInterned(slice.ty).childType(zcu);38246 const elem_ty = Type.fromInterned(slice.ty).childType(zcu);
37852 const len = try Value.fromInterned(slice.len).toUnsignedIntSema(zcu);38247 const len = try Value.fromInterned(slice.len).toUnsignedIntSema(pt);
37853 const array_ty = try zcu.arrayType(.{38248 const array_ty = try pt.arrayType(.{
37854 .child = elem_ty.toIntern(),38249 .child = elem_ty.toIntern(),
37855 .len = len,38250 .len = len,
37856 });38251 });
37857 const ptr_ty = try zcu.ptrTypeSema(p: {38252 const ptr_ty = try pt.ptrTypeSema(p: {
37858 var p = Type.fromInterned(slice.ty).ptrInfo(zcu);38253 var p = Type.fromInterned(slice.ty).ptrInfo(zcu);
37859 p.flags.size = .One;38254 p.flags.size = .One;
37860 p.child = array_ty.toIntern();38255 p.child = array_ty.toIntern();
37861 p.sentinel = .none;38256 p.sentinel = .none;
37862 break :p p;38257 break :p p;
37863 });38258 });
37864 const casted_ptr = try zcu.getCoerced(Value.fromInterned(slice.ptr), ptr_ty);38259 const casted_ptr = try pt.getCoerced(Value.fromInterned(slice.ptr), ptr_ty);
37865 return sema.pointerDeref(block, src, casted_ptr, ptr_ty);38260 return sema.pointerDeref(block, src, casted_ptr, ptr_ty);
37866}38261}
3786738262
...@@ -37879,7 +38274,7 @@ fn analyzeUnreachable(sema: *Sema, block: *Block, src: LazySrcLoc, safety_check:...@@ -37879,7 +38274,7 @@ fn analyzeUnreachable(sema: *Sema, block: *Block, src: LazySrcLoc, safety_check:
37879pub fn flushExports(sema: *Sema) !void {38274pub fn flushExports(sema: *Sema) !void {
37880 if (sema.exports.items.len == 0) return;38275 if (sema.exports.items.len == 0) return;
3788138276
37882 const zcu = sema.mod;38277 const zcu = sema.pt.zcu;
37883 const gpa = zcu.gpa;38278 const gpa = zcu.gpa;
3788438279
37885 const unit = sema.ownerUnit();38280 const unit = sema.ownerUnit();
src/Sema/bitcast.zig+96-92
...@@ -69,7 +69,8 @@ fn bitCastInner(...@@ -69,7 +69,8 @@ fn bitCastInner(
69 host_bits: u64,69 host_bits: u64,
70 bit_offset: u64,70 bit_offset: u64,
71) BitCastError!Value {71) BitCastError!Value {
72 const zcu = sema.mod;72 const pt = sema.pt;
73 const zcu = pt.zcu;
73 const endian = zcu.getTarget().cpu.arch.endian();74 const endian = zcu.getTarget().cpu.arch.endian();
7475
75 if (dest_ty.toIntern() == val.typeOf(zcu).toIntern() and bit_offset == 0) {76 if (dest_ty.toIntern() == val.typeOf(zcu).toIntern() and bit_offset == 0) {
...@@ -78,29 +79,29 @@ fn bitCastInner(...@@ -78,29 +79,29 @@ fn bitCastInner(
7879
79 const val_ty = val.typeOf(zcu);80 const val_ty = val.typeOf(zcu);
8081
81 try val_ty.resolveLayout(zcu);82 try val_ty.resolveLayout(pt);
82 try dest_ty.resolveLayout(zcu);83 try dest_ty.resolveLayout(pt);
8384
84 assert(val_ty.hasWellDefinedLayout(zcu));85 assert(val_ty.hasWellDefinedLayout(zcu));
8586
86 const abi_pad_bits, const host_pad_bits = if (host_bits > 0)87 const abi_pad_bits, const host_pad_bits = if (host_bits > 0)
87 .{ val_ty.abiSize(zcu) * 8 - host_bits, host_bits - val_ty.bitSize(zcu) }88 .{ val_ty.abiSize(pt) * 8 - host_bits, host_bits - val_ty.bitSize(pt) }
88 else89 else
89 .{ val_ty.abiSize(zcu) * 8 - val_ty.bitSize(zcu), 0 };90 .{ val_ty.abiSize(pt) * 8 - val_ty.bitSize(pt), 0 };
9091
91 const skip_bits = switch (endian) {92 const skip_bits = switch (endian) {
92 .little => bit_offset + byte_offset * 8,93 .little => bit_offset + byte_offset * 8,
93 .big => if (host_bits > 0)94 .big => if (host_bits > 0)
94 val_ty.abiSize(zcu) * 8 - byte_offset * 8 - host_bits + bit_offset95 val_ty.abiSize(pt) * 8 - byte_offset * 8 - host_bits + bit_offset
95 else96 else
96 val_ty.abiSize(zcu) * 8 - byte_offset * 8 - dest_ty.bitSize(zcu),97 val_ty.abiSize(pt) * 8 - byte_offset * 8 - dest_ty.bitSize(pt),
97 };98 };
9899
99 var unpack: UnpackValueBits = .{100 var unpack: UnpackValueBits = .{
100 .zcu = zcu,101 .pt = sema.pt,
101 .arena = sema.arena,102 .arena = sema.arena,
102 .skip_bits = skip_bits,103 .skip_bits = skip_bits,
103 .remaining_bits = dest_ty.bitSize(zcu),104 .remaining_bits = dest_ty.bitSize(pt),
104 .unpacked = std.ArrayList(InternPool.Index).init(sema.arena),105 .unpacked = std.ArrayList(InternPool.Index).init(sema.arena),
105 };106 };
106 switch (endian) {107 switch (endian) {
...@@ -116,7 +117,7 @@ fn bitCastInner(...@@ -116,7 +117,7 @@ fn bitCastInner(
116 try unpack.padding(host_pad_bits);117 try unpack.padding(host_pad_bits);
117118
118 var pack: PackValueBits = .{119 var pack: PackValueBits = .{
119 .zcu = zcu,120 .pt = sema.pt,
120 .arena = sema.arena,121 .arena = sema.arena,
121 .unpacked = unpack.unpacked.items,122 .unpacked = unpack.unpacked.items,
122 };123 };
...@@ -131,33 +132,34 @@ fn bitCastSpliceInner(...@@ -131,33 +132,34 @@ fn bitCastSpliceInner(
131 host_bits: u64,132 host_bits: u64,
132 bit_offset: u64,133 bit_offset: u64,
133) BitCastError!Value {134) BitCastError!Value {
134 const zcu = sema.mod;135 const pt = sema.pt;
136 const zcu = pt.zcu;
135 const endian = zcu.getTarget().cpu.arch.endian();137 const endian = zcu.getTarget().cpu.arch.endian();
136 const val_ty = val.typeOf(zcu);138 const val_ty = val.typeOf(zcu);
137 const splice_val_ty = splice_val.typeOf(zcu);139 const splice_val_ty = splice_val.typeOf(zcu);
138140
139 try val_ty.resolveLayout(zcu);141 try val_ty.resolveLayout(pt);
140 try splice_val_ty.resolveLayout(zcu);142 try splice_val_ty.resolveLayout(pt);
141143
142 const splice_bits = splice_val_ty.bitSize(zcu);144 const splice_bits = splice_val_ty.bitSize(pt);
143145
144 const splice_offset = switch (endian) {146 const splice_offset = switch (endian) {
145 .little => bit_offset + byte_offset * 8,147 .little => bit_offset + byte_offset * 8,
146 .big => if (host_bits > 0)148 .big => if (host_bits > 0)
147 val_ty.abiSize(zcu) * 8 - byte_offset * 8 - host_bits + bit_offset149 val_ty.abiSize(pt) * 8 - byte_offset * 8 - host_bits + bit_offset
148 else150 else
149 val_ty.abiSize(zcu) * 8 - byte_offset * 8 - splice_bits,151 val_ty.abiSize(pt) * 8 - byte_offset * 8 - splice_bits,
150 };152 };
151153
152 assert(splice_offset + splice_bits <= val_ty.abiSize(zcu) * 8);154 assert(splice_offset + splice_bits <= val_ty.abiSize(pt) * 8);
153155
154 const abi_pad_bits, const host_pad_bits = if (host_bits > 0)156 const abi_pad_bits, const host_pad_bits = if (host_bits > 0)
155 .{ val_ty.abiSize(zcu) * 8 - host_bits, host_bits - val_ty.bitSize(zcu) }157 .{ val_ty.abiSize(pt) * 8 - host_bits, host_bits - val_ty.bitSize(pt) }
156 else158 else
157 .{ val_ty.abiSize(zcu) * 8 - val_ty.bitSize(zcu), 0 };159 .{ val_ty.abiSize(pt) * 8 - val_ty.bitSize(pt), 0 };
158160
159 var unpack: UnpackValueBits = .{161 var unpack: UnpackValueBits = .{
160 .zcu = zcu,162 .pt = pt,
161 .arena = sema.arena,163 .arena = sema.arena,
162 .skip_bits = 0,164 .skip_bits = 0,
163 .remaining_bits = splice_offset,165 .remaining_bits = splice_offset,
...@@ -179,7 +181,7 @@ fn bitCastSpliceInner(...@@ -179,7 +181,7 @@ fn bitCastSpliceInner(
179 try unpack.add(splice_val);181 try unpack.add(splice_val);
180182
181 unpack.skip_bits = splice_offset + splice_bits;183 unpack.skip_bits = splice_offset + splice_bits;
182 unpack.remaining_bits = val_ty.abiSize(zcu) * 8 - splice_offset - splice_bits;184 unpack.remaining_bits = val_ty.abiSize(pt) * 8 - splice_offset - splice_bits;
183 switch (endian) {185 switch (endian) {
184 .little => {186 .little => {
185 try unpack.add(val);187 try unpack.add(val);
...@@ -193,7 +195,7 @@ fn bitCastSpliceInner(...@@ -193,7 +195,7 @@ fn bitCastSpliceInner(
193 try unpack.padding(host_pad_bits);195 try unpack.padding(host_pad_bits);
194196
195 var pack: PackValueBits = .{197 var pack: PackValueBits = .{
196 .zcu = zcu,198 .pt = pt,
197 .arena = sema.arena,199 .arena = sema.arena,
198 .unpacked = unpack.unpacked.items,200 .unpacked = unpack.unpacked.items,
199 };201 };
...@@ -209,7 +211,7 @@ fn bitCastSpliceInner(...@@ -209,7 +211,7 @@ fn bitCastSpliceInner(
209/// of values in *packed* memory - therefore, on big-endian targets, the first element of this211/// of values in *packed* memory - therefore, on big-endian targets, the first element of this
210/// list contains bits from the *final* byte of the value.212/// list contains bits from the *final* byte of the value.
211const UnpackValueBits = struct {213const UnpackValueBits = struct {
212 zcu: *Zcu,214 pt: Zcu.PerThread,
213 arena: Allocator,215 arena: Allocator,
214 skip_bits: u64,216 skip_bits: u64,
215 remaining_bits: u64,217 remaining_bits: u64,
...@@ -217,7 +219,8 @@ const UnpackValueBits = struct {...@@ -217,7 +219,8 @@ const UnpackValueBits = struct {
217 unpacked: std.ArrayList(InternPool.Index),219 unpacked: std.ArrayList(InternPool.Index),
218220
219 fn add(unpack: *UnpackValueBits, val: Value) BitCastError!void {221 fn add(unpack: *UnpackValueBits, val: Value) BitCastError!void {
220 const zcu = unpack.zcu;222 const pt = unpack.pt;
223 const zcu = pt.zcu;
221 const endian = zcu.getTarget().cpu.arch.endian();224 const endian = zcu.getTarget().cpu.arch.endian();
222 const ip = &zcu.intern_pool;225 const ip = &zcu.intern_pool;
223226
...@@ -226,7 +229,7 @@ const UnpackValueBits = struct {...@@ -226,7 +229,7 @@ const UnpackValueBits = struct {
226 }229 }
227230
228 const ty = val.typeOf(zcu);231 const ty = val.typeOf(zcu);
229 const bit_size = ty.bitSize(zcu);232 const bit_size = ty.bitSize(pt);
230233
231 if (unpack.skip_bits >= bit_size) {234 if (unpack.skip_bits >= bit_size) {
232 unpack.skip_bits -= bit_size;235 unpack.skip_bits -= bit_size;
...@@ -279,7 +282,7 @@ const UnpackValueBits = struct {...@@ -279,7 +282,7 @@ const UnpackValueBits = struct {
279 .little => i,282 .little => i,
280 .big => len - i - 1,283 .big => len - i - 1,
281 };284 };
282 const elem_val = try val.elemValue(zcu, real_idx);285 const elem_val = try val.elemValue(pt, real_idx);
283 try unpack.add(elem_val);286 try unpack.add(elem_val);
284 }287 }
285 },288 },
...@@ -288,7 +291,7 @@ const UnpackValueBits = struct {...@@ -288,7 +291,7 @@ const UnpackValueBits = struct {
288 // The final element does not have trailing padding.291 // The final element does not have trailing padding.
289 // Elements are reversed in packed memory on BE targets.292 // Elements are reversed in packed memory on BE targets.
290 const elem_ty = ty.childType(zcu);293 const elem_ty = ty.childType(zcu);
291 const pad_bits = elem_ty.abiSize(zcu) * 8 - elem_ty.bitSize(zcu);294 const pad_bits = elem_ty.abiSize(pt) * 8 - elem_ty.bitSize(pt);
292 const len = ty.arrayLen(zcu);295 const len = ty.arrayLen(zcu);
293 const maybe_sent = ty.sentinel(zcu);296 const maybe_sent = ty.sentinel(zcu);
294297
...@@ -303,7 +306,7 @@ const UnpackValueBits = struct {...@@ -303,7 +306,7 @@ const UnpackValueBits = struct {
303 .little => i,306 .little => i,
304 .big => len - i - 1,307 .big => len - i - 1,
305 };308 };
306 const elem_val = try val.elemValue(zcu, @intCast(real_idx));309 const elem_val = try val.elemValue(pt, @intCast(real_idx));
307 try unpack.add(elem_val);310 try unpack.add(elem_val);
308 if (i != len - 1) try unpack.padding(pad_bits);311 if (i != len - 1) try unpack.padding(pad_bits);
309 }312 }
...@@ -320,12 +323,12 @@ const UnpackValueBits = struct {...@@ -320,12 +323,12 @@ const UnpackValueBits = struct {
320 var cur_bit_off: u64 = 0;323 var cur_bit_off: u64 = 0;
321 var it = zcu.typeToStruct(ty).?.iterateRuntimeOrder(ip);324 var it = zcu.typeToStruct(ty).?.iterateRuntimeOrder(ip);
322 while (it.next()) |field_idx| {325 while (it.next()) |field_idx| {
323 const want_bit_off = ty.structFieldOffset(field_idx, zcu) * 8;326 const want_bit_off = ty.structFieldOffset(field_idx, pt) * 8;
324 const pad_bits = want_bit_off - cur_bit_off;327 const pad_bits = want_bit_off - cur_bit_off;
325 const field_val = try val.fieldValue(zcu, field_idx);328 const field_val = try val.fieldValue(pt, field_idx);
326 try unpack.padding(pad_bits);329 try unpack.padding(pad_bits);
327 try unpack.add(field_val);330 try unpack.add(field_val);
328 cur_bit_off = want_bit_off + field_val.typeOf(zcu).bitSize(zcu);331 cur_bit_off = want_bit_off + field_val.typeOf(zcu).bitSize(pt);
329 }332 }
330 // Add trailing padding bits.333 // Add trailing padding bits.
331 try unpack.padding(bit_size - cur_bit_off);334 try unpack.padding(bit_size - cur_bit_off);
...@@ -334,13 +337,13 @@ const UnpackValueBits = struct {...@@ -334,13 +337,13 @@ const UnpackValueBits = struct {
334 var cur_bit_off: u64 = bit_size;337 var cur_bit_off: u64 = bit_size;
335 var it = zcu.typeToStruct(ty).?.iterateRuntimeOrderReverse(ip);338 var it = zcu.typeToStruct(ty).?.iterateRuntimeOrderReverse(ip);
336 while (it.next()) |field_idx| {339 while (it.next()) |field_idx| {
337 const field_val = try val.fieldValue(zcu, field_idx);340 const field_val = try val.fieldValue(pt, field_idx);
338 const field_ty = field_val.typeOf(zcu);341 const field_ty = field_val.typeOf(zcu);
339 const want_bit_off = ty.structFieldOffset(field_idx, zcu) * 8 + field_ty.bitSize(zcu);342 const want_bit_off = ty.structFieldOffset(field_idx, pt) * 8 + field_ty.bitSize(pt);
340 const pad_bits = cur_bit_off - want_bit_off;343 const pad_bits = cur_bit_off - want_bit_off;
341 try unpack.padding(pad_bits);344 try unpack.padding(pad_bits);
342 try unpack.add(field_val);345 try unpack.add(field_val);
343 cur_bit_off = want_bit_off - field_ty.bitSize(zcu);346 cur_bit_off = want_bit_off - field_ty.bitSize(pt);
344 }347 }
345 assert(cur_bit_off == 0);348 assert(cur_bit_off == 0);
346 },349 },
...@@ -349,7 +352,7 @@ const UnpackValueBits = struct {...@@ -349,7 +352,7 @@ const UnpackValueBits = struct {
349 // Just add all fields in order. There are no padding bits.352 // Just add all fields in order. There are no padding bits.
350 // This is identical between LE and BE targets.353 // This is identical between LE and BE targets.
351 for (0..ty.structFieldCount(zcu)) |i| {354 for (0..ty.structFieldCount(zcu)) |i| {
352 const field_val = try val.fieldValue(zcu, i);355 const field_val = try val.fieldValue(pt, i);
353 try unpack.add(field_val);356 try unpack.add(field_val);
354 }357 }
355 },358 },
...@@ -363,7 +366,7 @@ const UnpackValueBits = struct {...@@ -363,7 +366,7 @@ const UnpackValueBits = struct {
363 // This correctly handles the case where `tag == .none`, since the payload is then366 // This correctly handles the case where `tag == .none`, since the payload is then
364 // either an integer or a byte array, both of which we can unpack.367 // either an integer or a byte array, both of which we can unpack.
365 const payload_val = Value.fromInterned(un.val);368 const payload_val = Value.fromInterned(un.val);
366 const pad_bits = bit_size - payload_val.typeOf(zcu).bitSize(zcu);369 const pad_bits = bit_size - payload_val.typeOf(zcu).bitSize(pt);
367 if (endian == .little or ty.containerLayout(zcu) == .@"packed") {370 if (endian == .little or ty.containerLayout(zcu) == .@"packed") {
368 try unpack.add(payload_val);371 try unpack.add(payload_val);
369 try unpack.padding(pad_bits);372 try unpack.padding(pad_bits);
...@@ -377,31 +380,31 @@ const UnpackValueBits = struct {...@@ -377,31 +380,31 @@ const UnpackValueBits = struct {
377380
378 fn padding(unpack: *UnpackValueBits, pad_bits: u64) BitCastError!void {381 fn padding(unpack: *UnpackValueBits, pad_bits: u64) BitCastError!void {
379 if (pad_bits == 0) return;382 if (pad_bits == 0) return;
380 const zcu = unpack.zcu;383 const pt = unpack.pt;
381 // Figure out how many full bytes and leftover bits there are.384 // Figure out how many full bytes and leftover bits there are.
382 const bytes = pad_bits / 8;385 const bytes = pad_bits / 8;
383 const bits = pad_bits % 8;386 const bits = pad_bits % 8;
384 // Add undef u8 values for the bytes...387 // Add undef u8 values for the bytes...
385 const undef_u8 = try zcu.undefValue(Type.u8);388 const undef_u8 = try pt.undefValue(Type.u8);
386 for (0..@intCast(bytes)) |_| {389 for (0..@intCast(bytes)) |_| {
387 try unpack.primitive(undef_u8);390 try unpack.primitive(undef_u8);
388 }391 }
389 // ...and an undef int for the leftover bits.392 // ...and an undef int for the leftover bits.
390 if (bits == 0) return;393 if (bits == 0) return;
391 const bits_ty = try zcu.intType(.unsigned, @intCast(bits));394 const bits_ty = try pt.intType(.unsigned, @intCast(bits));
392 const bits_val = try zcu.undefValue(bits_ty);395 const bits_val = try pt.undefValue(bits_ty);
393 try unpack.primitive(bits_val);396 try unpack.primitive(bits_val);
394 }397 }
395398
396 fn primitive(unpack: *UnpackValueBits, val: Value) BitCastError!void {399 fn primitive(unpack: *UnpackValueBits, val: Value) BitCastError!void {
397 const zcu = unpack.zcu;400 const pt = unpack.pt;
398401
399 if (unpack.remaining_bits == 0) {402 if (unpack.remaining_bits == 0) {
400 return;403 return;
401 }404 }
402405
403 const ty = val.typeOf(zcu);406 const ty = val.typeOf(pt.zcu);
404 const bit_size = ty.bitSize(zcu);407 const bit_size = ty.bitSize(pt);
405408
406 // Note that this skips all zero-bit types.409 // Note that this skips all zero-bit types.
407 if (unpack.skip_bits >= bit_size) {410 if (unpack.skip_bits >= bit_size) {
...@@ -425,21 +428,21 @@ const UnpackValueBits = struct {...@@ -425,21 +428,21 @@ const UnpackValueBits = struct {
425 }428 }
426429
427 fn splitPrimitive(unpack: *UnpackValueBits, val: Value, bit_offset: u64, bit_count: u64) BitCastError!void {430 fn splitPrimitive(unpack: *UnpackValueBits, val: Value, bit_offset: u64, bit_count: u64) BitCastError!void {
428 const zcu = unpack.zcu;431 const pt = unpack.pt;
429 const ty = val.typeOf(zcu);432 const ty = val.typeOf(pt.zcu);
430433
431 const val_bits = ty.bitSize(zcu);434 const val_bits = ty.bitSize(pt);
432 assert(bit_offset + bit_count <= val_bits);435 assert(bit_offset + bit_count <= val_bits);
433436
434 switch (zcu.intern_pool.indexToKey(val.toIntern())) {437 switch (pt.zcu.intern_pool.indexToKey(val.toIntern())) {
435 // In the `ptr` case, this will return `error.ReinterpretDeclRef`438 // In the `ptr` case, this will return `error.ReinterpretDeclRef`
436 // if we're trying to split a non-integer pointer value.439 // if we're trying to split a non-integer pointer value.
437 .int, .float, .enum_tag, .ptr, .opt => {440 .int, .float, .enum_tag, .ptr, .opt => {
438 // This @intCast is okay because no primitive can exceed the size of a u16.441 // This @intCast is okay because no primitive can exceed the size of a u16.
439 const int_ty = try zcu.intType(.unsigned, @intCast(bit_count));442 const int_ty = try unpack.pt.intType(.unsigned, @intCast(bit_count));
440 const buf = try unpack.arena.alloc(u8, @intCast((val_bits + 7) / 8));443 const buf = try unpack.arena.alloc(u8, @intCast((val_bits + 7) / 8));
441 try val.writeToPackedMemory(ty, zcu, buf, 0);444 try val.writeToPackedMemory(ty, unpack.pt, buf, 0);
442 const sub_val = try Value.readFromPackedMemory(int_ty, zcu, buf, @intCast(bit_offset), unpack.arena);445 const sub_val = try Value.readFromPackedMemory(int_ty, unpack.pt, buf, @intCast(bit_offset), unpack.arena);
443 try unpack.primitive(sub_val);446 try unpack.primitive(sub_val);
444 },447 },
445 .undef => try unpack.padding(bit_count),448 .undef => try unpack.padding(bit_count),
...@@ -456,13 +459,14 @@ const UnpackValueBits = struct {...@@ -456,13 +459,14 @@ const UnpackValueBits = struct {
456/// reconstructs a value of an arbitrary type, with correct handling of `undefined`459/// reconstructs a value of an arbitrary type, with correct handling of `undefined`
457/// values and of pointers which align in virtual memory.460/// values and of pointers which align in virtual memory.
458const PackValueBits = struct {461const PackValueBits = struct {
459 zcu: *Zcu,462 pt: Zcu.PerThread,
460 arena: Allocator,463 arena: Allocator,
461 bit_offset: u64 = 0,464 bit_offset: u64 = 0,
462 unpacked: []const InternPool.Index,465 unpacked: []const InternPool.Index,
463466
464 fn get(pack: *PackValueBits, ty: Type) BitCastError!Value {467 fn get(pack: *PackValueBits, ty: Type) BitCastError!Value {
465 const zcu = pack.zcu;468 const pt = pack.pt;
469 const zcu = pt.zcu;
466 const endian = zcu.getTarget().cpu.arch.endian();470 const endian = zcu.getTarget().cpu.arch.endian();
467 const ip = &zcu.intern_pool;471 const ip = &zcu.intern_pool;
468 const arena = pack.arena;472 const arena = pack.arena;
...@@ -485,7 +489,7 @@ const PackValueBits = struct {...@@ -485,7 +489,7 @@ const PackValueBits = struct {
485 }489 }
486 },490 },
487 }491 }
488 return Value.fromInterned(try zcu.intern(.{ .aggregate = .{492 return Value.fromInterned(try pt.intern(.{ .aggregate = .{
489 .ty = ty.toIntern(),493 .ty = ty.toIntern(),
490 .storage = .{ .elems = elems },494 .storage = .{ .elems = elems },
491 } }));495 } }));
...@@ -495,12 +499,12 @@ const PackValueBits = struct {...@@ -495,12 +499,12 @@ const PackValueBits = struct {
495 const len = ty.arrayLen(zcu);499 const len = ty.arrayLen(zcu);
496 const elem_ty = ty.childType(zcu);500 const elem_ty = ty.childType(zcu);
497 const maybe_sent = ty.sentinel(zcu);501 const maybe_sent = ty.sentinel(zcu);
498 const pad_bits = elem_ty.abiSize(zcu) * 8 - elem_ty.bitSize(zcu);502 const pad_bits = elem_ty.abiSize(pt) * 8 - elem_ty.bitSize(pt);
499 const elems = try arena.alloc(InternPool.Index, @intCast(len));503 const elems = try arena.alloc(InternPool.Index, @intCast(len));
500504
501 if (endian == .big and maybe_sent != null) {505 if (endian == .big and maybe_sent != null) {
502 // TODO: validate sentinel was preserved!506 // TODO: validate sentinel was preserved!
503 try pack.padding(elem_ty.bitSize(zcu));507 try pack.padding(elem_ty.bitSize(pt));
504 if (len != 0) try pack.padding(pad_bits);508 if (len != 0) try pack.padding(pad_bits);
505 }509 }
506510
...@@ -516,10 +520,10 @@ const PackValueBits = struct {...@@ -516,10 +520,10 @@ const PackValueBits = struct {
516 if (endian == .little and maybe_sent != null) {520 if (endian == .little and maybe_sent != null) {
517 // TODO: validate sentinel was preserved!521 // TODO: validate sentinel was preserved!
518 if (len != 0) try pack.padding(pad_bits);522 if (len != 0) try pack.padding(pad_bits);
519 try pack.padding(elem_ty.bitSize(zcu));523 try pack.padding(elem_ty.bitSize(pt));
520 }524 }
521525
522 return Value.fromInterned(try zcu.intern(.{ .aggregate = .{526 return Value.fromInterned(try pt.intern(.{ .aggregate = .{
523 .ty = ty.toIntern(),527 .ty = ty.toIntern(),
524 .storage = .{ .elems = elems },528 .storage = .{ .elems = elems },
525 } }));529 } }));
...@@ -534,23 +538,23 @@ const PackValueBits = struct {...@@ -534,23 +538,23 @@ const PackValueBits = struct {
534 var cur_bit_off: u64 = 0;538 var cur_bit_off: u64 = 0;
535 var it = zcu.typeToStruct(ty).?.iterateRuntimeOrder(ip);539 var it = zcu.typeToStruct(ty).?.iterateRuntimeOrder(ip);
536 while (it.next()) |field_idx| {540 while (it.next()) |field_idx| {
537 const want_bit_off = ty.structFieldOffset(field_idx, zcu) * 8;541 const want_bit_off = ty.structFieldOffset(field_idx, pt) * 8;
538 try pack.padding(want_bit_off - cur_bit_off);542 try pack.padding(want_bit_off - cur_bit_off);
539 const field_ty = ty.structFieldType(field_idx, zcu);543 const field_ty = ty.structFieldType(field_idx, zcu);
540 elems[field_idx] = (try pack.get(field_ty)).toIntern();544 elems[field_idx] = (try pack.get(field_ty)).toIntern();
541 cur_bit_off = want_bit_off + field_ty.bitSize(zcu);545 cur_bit_off = want_bit_off + field_ty.bitSize(pt);
542 }546 }
543 try pack.padding(ty.bitSize(zcu) - cur_bit_off);547 try pack.padding(ty.bitSize(pt) - cur_bit_off);
544 },548 },
545 .big => {549 .big => {
546 var cur_bit_off: u64 = ty.bitSize(zcu);550 var cur_bit_off: u64 = ty.bitSize(pt);
547 var it = zcu.typeToStruct(ty).?.iterateRuntimeOrderReverse(ip);551 var it = zcu.typeToStruct(ty).?.iterateRuntimeOrderReverse(ip);
548 while (it.next()) |field_idx| {552 while (it.next()) |field_idx| {
549 const field_ty = ty.structFieldType(field_idx, zcu);553 const field_ty = ty.structFieldType(field_idx, zcu);
550 const want_bit_off = ty.structFieldOffset(field_idx, zcu) * 8 + field_ty.bitSize(zcu);554 const want_bit_off = ty.structFieldOffset(field_idx, pt) * 8 + field_ty.bitSize(pt);
551 try pack.padding(cur_bit_off - want_bit_off);555 try pack.padding(cur_bit_off - want_bit_off);
552 elems[field_idx] = (try pack.get(field_ty)).toIntern();556 elems[field_idx] = (try pack.get(field_ty)).toIntern();
553 cur_bit_off = want_bit_off - field_ty.bitSize(zcu);557 cur_bit_off = want_bit_off - field_ty.bitSize(pt);
554 }558 }
555 assert(cur_bit_off == 0);559 assert(cur_bit_off == 0);
556 },560 },
...@@ -559,10 +563,10 @@ const PackValueBits = struct {...@@ -559,10 +563,10 @@ const PackValueBits = struct {
559 // Fill those values now.563 // Fill those values now.
560 for (elems, 0..) |*elem, field_idx| {564 for (elems, 0..) |*elem, field_idx| {
561 if (elem.* != .none) continue;565 if (elem.* != .none) continue;
562 const val = (try ty.structFieldValueComptime(zcu, field_idx)).?;566 const val = (try ty.structFieldValueComptime(pt, field_idx)).?;
563 elem.* = val.toIntern();567 elem.* = val.toIntern();
564 }568 }
565 return Value.fromInterned(try zcu.intern(.{ .aggregate = .{569 return Value.fromInterned(try pt.intern(.{ .aggregate = .{
566 .ty = ty.toIntern(),570 .ty = ty.toIntern(),
567 .storage = .{ .elems = elems },571 .storage = .{ .elems = elems },
568 } }));572 } }));
...@@ -575,7 +579,7 @@ const PackValueBits = struct {...@@ -575,7 +579,7 @@ const PackValueBits = struct {
575 const field_ty = ty.structFieldType(i, zcu);579 const field_ty = ty.structFieldType(i, zcu);
576 elem.* = (try pack.get(field_ty)).toIntern();580 elem.* = (try pack.get(field_ty)).toIntern();
577 }581 }
578 return Value.fromInterned(try zcu.intern(.{ .aggregate = .{582 return Value.fromInterned(try pt.intern(.{ .aggregate = .{
579 .ty = ty.toIntern(),583 .ty = ty.toIntern(),
580 .storage = .{ .elems = elems },584 .storage = .{ .elems = elems },
581 } }));585 } }));
...@@ -591,7 +595,7 @@ const PackValueBits = struct {...@@ -591,7 +595,7 @@ const PackValueBits = struct {
591 const prev_unpacked = pack.unpacked;595 const prev_unpacked = pack.unpacked;
592 const prev_bit_offset = pack.bit_offset;596 const prev_bit_offset = pack.bit_offset;
593597
594 const backing_ty = try ty.unionBackingType(zcu);598 const backing_ty = try ty.unionBackingType(pt);
595599
596 backing: {600 backing: {
597 const backing_val = pack.get(backing_ty) catch |err| switch (err) {601 const backing_val = pack.get(backing_ty) catch |err| switch (err) {
...@@ -607,7 +611,7 @@ const PackValueBits = struct {...@@ -607,7 +611,7 @@ const PackValueBits = struct {
607 pack.bit_offset = prev_bit_offset;611 pack.bit_offset = prev_bit_offset;
608 break :backing;612 break :backing;
609 }613 }
610 return Value.fromInterned(try zcu.intern(.{ .un = .{614 return Value.fromInterned(try pt.intern(.{ .un = .{
611 .ty = ty.toIntern(),615 .ty = ty.toIntern(),
612 .tag = .none,616 .tag = .none,
613 .val = backing_val.toIntern(),617 .val = backing_val.toIntern(),
...@@ -618,16 +622,16 @@ const PackValueBits = struct {...@@ -618,16 +622,16 @@ const PackValueBits = struct {
618 for (field_order, 0..) |*f, i| f.* = @intCast(i);622 for (field_order, 0..) |*f, i| f.* = @intCast(i);
619 // Sort `field_order` to put the fields with the largest bit sizes first.623 // Sort `field_order` to put the fields with the largest bit sizes first.
620 const SizeSortCtx = struct {624 const SizeSortCtx = struct {
621 zcu: *Zcu,625 pt: Zcu.PerThread,
622 field_types: []const InternPool.Index,626 field_types: []const InternPool.Index,
623 fn lessThan(ctx: @This(), a_idx: u32, b_idx: u32) bool {627 fn lessThan(ctx: @This(), a_idx: u32, b_idx: u32) bool {
624 const a_ty = Type.fromInterned(ctx.field_types[a_idx]);628 const a_ty = Type.fromInterned(ctx.field_types[a_idx]);
625 const b_ty = Type.fromInterned(ctx.field_types[b_idx]);629 const b_ty = Type.fromInterned(ctx.field_types[b_idx]);
626 return a_ty.bitSize(ctx.zcu) > b_ty.bitSize(ctx.zcu);630 return a_ty.bitSize(ctx.pt) > b_ty.bitSize(ctx.pt);
627 }631 }
628 };632 };
629 std.mem.sortUnstable(u32, field_order, SizeSortCtx{633 std.mem.sortUnstable(u32, field_order, SizeSortCtx{
630 .zcu = zcu,634 .pt = pt,
631 .field_types = zcu.typeToUnion(ty).?.field_types.get(ip),635 .field_types = zcu.typeToUnion(ty).?.field_types.get(ip),
632 }, SizeSortCtx.lessThan);636 }, SizeSortCtx.lessThan);
633637
...@@ -635,7 +639,7 @@ const PackValueBits = struct {...@@ -635,7 +639,7 @@ const PackValueBits = struct {
635639
636 for (field_order) |field_idx| {640 for (field_order) |field_idx| {
637 const field_ty = Type.fromInterned(zcu.typeToUnion(ty).?.field_types.get(ip)[field_idx]);641 const field_ty = Type.fromInterned(zcu.typeToUnion(ty).?.field_types.get(ip)[field_idx]);
638 const pad_bits = ty.bitSize(zcu) - field_ty.bitSize(zcu);642 const pad_bits = ty.bitSize(pt) - field_ty.bitSize(pt);
639 if (!padding_after) try pack.padding(pad_bits);643 if (!padding_after) try pack.padding(pad_bits);
640 const field_val = pack.get(field_ty) catch |err| switch (err) {644 const field_val = pack.get(field_ty) catch |err| switch (err) {
641 error.ReinterpretDeclRef => {645 error.ReinterpretDeclRef => {
...@@ -651,8 +655,8 @@ const PackValueBits = struct {...@@ -651,8 +655,8 @@ const PackValueBits = struct {
651 pack.bit_offset = prev_bit_offset;655 pack.bit_offset = prev_bit_offset;
652 continue;656 continue;
653 }657 }
654 const tag_val = try zcu.enumValueFieldIndex(ty.unionTagTypeHypothetical(zcu), field_idx);658 const tag_val = try pt.enumValueFieldIndex(ty.unionTagTypeHypothetical(zcu), field_idx);
655 return Value.fromInterned(try zcu.intern(.{ .un = .{659 return Value.fromInterned(try pt.intern(.{ .un = .{
656 .ty = ty.toIntern(),660 .ty = ty.toIntern(),
657 .tag = tag_val.toIntern(),661 .tag = tag_val.toIntern(),
658 .val = field_val.toIntern(),662 .val = field_val.toIntern(),
...@@ -662,7 +666,7 @@ const PackValueBits = struct {...@@ -662,7 +666,7 @@ const PackValueBits = struct {
662 // No field could represent the value. Just do whatever happens when we try to read666 // No field could represent the value. Just do whatever happens when we try to read
663 // the backing type - either `undefined` or `error.ReinterpretDeclRef`.667 // the backing type - either `undefined` or `error.ReinterpretDeclRef`.
664 const backing_val = try pack.get(backing_ty);668 const backing_val = try pack.get(backing_ty);
665 return Value.fromInterned(try zcu.intern(.{ .un = .{669 return Value.fromInterned(try pt.intern(.{ .un = .{
666 .ty = ty.toIntern(),670 .ty = ty.toIntern(),
667 .tag = .none,671 .tag = .none,
668 .val = backing_val.toIntern(),672 .val = backing_val.toIntern(),
...@@ -677,14 +681,14 @@ const PackValueBits = struct {...@@ -677,14 +681,14 @@ const PackValueBits = struct {
677 }681 }
678682
679 fn primitive(pack: *PackValueBits, want_ty: Type) BitCastError!Value {683 fn primitive(pack: *PackValueBits, want_ty: Type) BitCastError!Value {
680 const zcu = pack.zcu;684 const pt = pack.pt;
681 const vals, const bit_offset = pack.prepareBits(want_ty.bitSize(zcu));685 const vals, const bit_offset = pack.prepareBits(want_ty.bitSize(pt));
682686
683 for (vals) |val| {687 for (vals) |val| {
684 if (!Value.fromInterned(val).isUndef(zcu)) break;688 if (!Value.fromInterned(val).isUndef(pt.zcu)) break;
685 } else {689 } else {
686 // All bits of the value are `undefined`.690 // All bits of the value are `undefined`.
687 return zcu.undefValue(want_ty);691 return pt.undefValue(want_ty);
688 }692 }
689693
690 // TODO: we need to decide how to handle partially-undef values here.694 // TODO: we need to decide how to handle partially-undef values here.
...@@ -702,9 +706,9 @@ const PackValueBits = struct {...@@ -702,9 +706,9 @@ const PackValueBits = struct {
702 ptr_cast: {706 ptr_cast: {
703 if (vals.len != 1) break :ptr_cast;707 if (vals.len != 1) break :ptr_cast;
704 const val = Value.fromInterned(vals[0]);708 const val = Value.fromInterned(vals[0]);
705 if (!val.typeOf(zcu).isPtrAtRuntime(zcu)) break :ptr_cast;709 if (!val.typeOf(pt.zcu).isPtrAtRuntime(pt.zcu)) break :ptr_cast;
706 if (!want_ty.isPtrAtRuntime(zcu)) break :ptr_cast;710 if (!want_ty.isPtrAtRuntime(pt.zcu)) break :ptr_cast;
707 return zcu.getCoerced(val, want_ty);711 return pt.getCoerced(val, want_ty);
708 }712 }
709713
710 // Reinterpret via an in-memory buffer.714 // Reinterpret via an in-memory buffer.
...@@ -712,8 +716,8 @@ const PackValueBits = struct {...@@ -712,8 +716,8 @@ const PackValueBits = struct {
712 var buf_bits: u64 = 0;716 var buf_bits: u64 = 0;
713 for (vals) |ip_val| {717 for (vals) |ip_val| {
714 const val = Value.fromInterned(ip_val);718 const val = Value.fromInterned(ip_val);
715 const ty = val.typeOf(zcu);719 const ty = val.typeOf(pt.zcu);
716 buf_bits += ty.bitSize(zcu);720 buf_bits += ty.bitSize(pt);
717 }721 }
718722
719 const buf = try pack.arena.alloc(u8, @intCast((buf_bits + 7) / 8));723 const buf = try pack.arena.alloc(u8, @intCast((buf_bits + 7) / 8));
...@@ -722,25 +726,25 @@ const PackValueBits = struct {...@@ -722,25 +726,25 @@ const PackValueBits = struct {
722 var cur_bit_off: usize = 0;726 var cur_bit_off: usize = 0;
723 for (vals) |ip_val| {727 for (vals) |ip_val| {
724 const val = Value.fromInterned(ip_val);728 const val = Value.fromInterned(ip_val);
725 const ty = val.typeOf(zcu);729 const ty = val.typeOf(pt.zcu);
726 if (!val.isUndef(zcu)) {730 if (!val.isUndef(pt.zcu)) {
727 try val.writeToPackedMemory(ty, zcu, buf, cur_bit_off);731 try val.writeToPackedMemory(ty, pt, buf, cur_bit_off);
728 }732 }
729 cur_bit_off += @intCast(ty.bitSize(zcu));733 cur_bit_off += @intCast(ty.bitSize(pt));
730 }734 }
731735
732 return Value.readFromPackedMemory(want_ty, zcu, buf, @intCast(bit_offset), pack.arena);736 return Value.readFromPackedMemory(want_ty, pt, buf, @intCast(bit_offset), pack.arena);
733 }737 }
734738
735 fn prepareBits(pack: *PackValueBits, need_bits: u64) struct { []const InternPool.Index, u64 } {739 fn prepareBits(pack: *PackValueBits, need_bits: u64) struct { []const InternPool.Index, u64 } {
736 if (need_bits == 0) return .{ &.{}, 0 };740 if (need_bits == 0) return .{ &.{}, 0 };
737741
738 const zcu = pack.zcu;742 const pt = pack.pt;
739743
740 var bits: u64 = 0;744 var bits: u64 = 0;
741 var len: usize = 0;745 var len: usize = 0;
742 while (bits < pack.bit_offset + need_bits) {746 while (bits < pack.bit_offset + need_bits) {
743 bits += Value.fromInterned(pack.unpacked[len]).typeOf(zcu).bitSize(zcu);747 bits += Value.fromInterned(pack.unpacked[len]).typeOf(pt.zcu).bitSize(pt);
744 len += 1;748 len += 1;
745 }749 }
746750
...@@ -753,7 +757,7 @@ const PackValueBits = struct {...@@ -753,7 +757,7 @@ const PackValueBits = struct {
753 pack.bit_offset = 0;757 pack.bit_offset = 0;
754 } else {758 } else {
755 pack.unpacked = pack.unpacked[len - 1 ..];759 pack.unpacked = pack.unpacked[len - 1 ..];
756 pack.bit_offset = Value.fromInterned(pack.unpacked[0]).typeOf(zcu).bitSize(zcu) - extra_bits;760 pack.bit_offset = Value.fromInterned(pack.unpacked[0]).typeOf(pt.zcu).bitSize(pt) - extra_bits;
757 }761 }
758762
759 return .{ result_vals, result_offset };763 return .{ result_vals, result_offset };
src/Sema/comptime_ptr_access.zig+57-54
...@@ -12,19 +12,19 @@ pub const ComptimeLoadResult = union(enum) {...@@ -12,19 +12,19 @@ pub const ComptimeLoadResult = union(enum) {
12};12};
1313
14pub fn loadComptimePtr(sema: *Sema, block: *Block, src: LazySrcLoc, ptr: Value) !ComptimeLoadResult {14pub fn loadComptimePtr(sema: *Sema, block: *Block, src: LazySrcLoc, ptr: Value) !ComptimeLoadResult {
15 const zcu = sema.mod;15 const pt = sema.pt;
16 const ptr_info = ptr.typeOf(zcu).ptrInfo(zcu);16 const ptr_info = ptr.typeOf(pt.zcu).ptrInfo(pt.zcu);
17 // TODO: host size for vectors is terrible17 // TODO: host size for vectors is terrible
18 const host_bits = switch (ptr_info.flags.vector_index) {18 const host_bits = switch (ptr_info.flags.vector_index) {
19 .none => ptr_info.packed_offset.host_size * 8,19 .none => ptr_info.packed_offset.host_size * 8,
20 else => ptr_info.packed_offset.host_size * Type.fromInterned(ptr_info.child).bitSize(zcu),20 else => ptr_info.packed_offset.host_size * Type.fromInterned(ptr_info.child).bitSize(pt),
21 };21 };
22 const bit_offset = if (host_bits != 0) bit_offset: {22 const bit_offset = if (host_bits != 0) bit_offset: {
23 const child_bits = Type.fromInterned(ptr_info.child).bitSize(zcu);23 const child_bits = Type.fromInterned(ptr_info.child).bitSize(pt);
24 const bit_offset = ptr_info.packed_offset.bit_offset + switch (ptr_info.flags.vector_index) {24 const bit_offset = ptr_info.packed_offset.bit_offset + switch (ptr_info.flags.vector_index) {
25 .none => 0,25 .none => 0,
26 .runtime => return .runtime_load,26 .runtime => return .runtime_load,
27 else => |idx| switch (zcu.getTarget().cpu.arch.endian()) {27 else => |idx| switch (pt.zcu.getTarget().cpu.arch.endian()) {
28 .little => child_bits * @intFromEnum(idx),28 .little => child_bits * @intFromEnum(idx),
29 .big => host_bits - child_bits * (@intFromEnum(idx) + 1), // element order reversed on big endian29 .big => host_bits - child_bits * (@intFromEnum(idx) + 1), // element order reversed on big endian
30 },30 },
...@@ -60,28 +60,29 @@ pub fn storeComptimePtr(...@@ -60,28 +60,29 @@ pub fn storeComptimePtr(
60 ptr: Value,60 ptr: Value,
61 store_val: Value,61 store_val: Value,
62) !ComptimeStoreResult {62) !ComptimeStoreResult {
63 const zcu = sema.mod;63 const pt = sema.pt;
64 const zcu = pt.zcu;
64 const ptr_info = ptr.typeOf(zcu).ptrInfo(zcu);65 const ptr_info = ptr.typeOf(zcu).ptrInfo(zcu);
65 assert(store_val.typeOf(zcu).toIntern() == ptr_info.child);66 assert(store_val.typeOf(zcu).toIntern() == ptr_info.child);
66 // TODO: host size for vectors is terrible67 // TODO: host size for vectors is terrible
67 const host_bits = switch (ptr_info.flags.vector_index) {68 const host_bits = switch (ptr_info.flags.vector_index) {
68 .none => ptr_info.packed_offset.host_size * 8,69 .none => ptr_info.packed_offset.host_size * 8,
69 else => ptr_info.packed_offset.host_size * Type.fromInterned(ptr_info.child).bitSize(zcu),70 else => ptr_info.packed_offset.host_size * Type.fromInterned(ptr_info.child).bitSize(pt),
70 };71 };
71 const bit_offset = ptr_info.packed_offset.bit_offset + switch (ptr_info.flags.vector_index) {72 const bit_offset = ptr_info.packed_offset.bit_offset + switch (ptr_info.flags.vector_index) {
72 .none => 0,73 .none => 0,
73 .runtime => return .runtime_store,74 .runtime => return .runtime_store,
74 else => |idx| switch (zcu.getTarget().cpu.arch.endian()) {75 else => |idx| switch (zcu.getTarget().cpu.arch.endian()) {
75 .little => Type.fromInterned(ptr_info.child).bitSize(zcu) * @intFromEnum(idx),76 .little => Type.fromInterned(ptr_info.child).bitSize(pt) * @intFromEnum(idx),
76 .big => host_bits - Type.fromInterned(ptr_info.child).bitSize(zcu) * (@intFromEnum(idx) + 1), // element order reversed on big endian77 .big => host_bits - Type.fromInterned(ptr_info.child).bitSize(pt) * (@intFromEnum(idx) + 1), // element order reversed on big endian
77 },78 },
78 };79 };
79 const pseudo_store_ty = if (host_bits > 0) t: {80 const pseudo_store_ty = if (host_bits > 0) t: {
80 const need_bits = Type.fromInterned(ptr_info.child).bitSize(zcu);81 const need_bits = Type.fromInterned(ptr_info.child).bitSize(pt);
81 if (need_bits + bit_offset > host_bits) {82 if (need_bits + bit_offset > host_bits) {
82 return .exceeds_host_size;83 return .exceeds_host_size;
83 }84 }
84 break :t try zcu.intType(.unsigned, @intCast(host_bits));85 break :t try sema.pt.intType(.unsigned, @intCast(host_bits));
85 } else Type.fromInterned(ptr_info.child);86 } else Type.fromInterned(ptr_info.child);
8687
87 const strat = try prepareComptimePtrStore(sema, block, src, ptr, pseudo_store_ty, 0);88 const strat = try prepareComptimePtrStore(sema, block, src, ptr, pseudo_store_ty, 0);
...@@ -103,7 +104,7 @@ pub fn storeComptimePtr(...@@ -103,7 +104,7 @@ pub fn storeComptimePtr(
103 .needed_well_defined => |ty| return .{ .needed_well_defined = ty },104 .needed_well_defined => |ty| return .{ .needed_well_defined = ty },
104 .out_of_bounds => |ty| return .{ .out_of_bounds = ty },105 .out_of_bounds => |ty| return .{ .out_of_bounds = ty },
105 };106 };
106 const expected = try expected_mv.intern(zcu, sema.arena);107 const expected = try expected_mv.intern(pt, sema.arena);
107 if (store_val.toIntern() != expected.toIntern()) {108 if (store_val.toIntern() != expected.toIntern()) {
108 return .{ .comptime_field_mismatch = expected };109 return .{ .comptime_field_mismatch = expected };
109 }110 }
...@@ -126,14 +127,14 @@ pub fn storeComptimePtr(...@@ -126,14 +127,14 @@ pub fn storeComptimePtr(
126 switch (strat) {127 switch (strat) {
127 .direct => |direct| {128 .direct => |direct| {
128 const want_ty = direct.val.typeOf(zcu);129 const want_ty = direct.val.typeOf(zcu);
129 const coerced_store_val = try zcu.getCoerced(store_val, want_ty);130 const coerced_store_val = try pt.getCoerced(store_val, want_ty);
130 direct.val.* = .{ .interned = coerced_store_val.toIntern() };131 direct.val.* = .{ .interned = coerced_store_val.toIntern() };
131 return .success;132 return .success;
132 },133 },
133 .index => |index| {134 .index => |index| {
134 const want_ty = index.val.typeOf(zcu).childType(zcu);135 const want_ty = index.val.typeOf(zcu).childType(zcu);
135 const coerced_store_val = try zcu.getCoerced(store_val, want_ty);136 const coerced_store_val = try pt.getCoerced(store_val, want_ty);
136 try index.val.setElem(zcu, sema.arena, @intCast(index.elem_index), .{ .interned = coerced_store_val.toIntern() });137 try index.val.setElem(pt, sema.arena, @intCast(index.elem_index), .{ .interned = coerced_store_val.toIntern() });
137 return .success;138 return .success;
138 },139 },
139 .flat_index => |flat| {140 .flat_index => |flat| {
...@@ -149,7 +150,7 @@ pub fn storeComptimePtr(...@@ -149,7 +150,7 @@ pub fn storeComptimePtr(
149 // Better would be to gather all the store targets into an array.150 // Better would be to gather all the store targets into an array.
150 var index: u64 = flat.flat_elem_index + idx;151 var index: u64 = flat.flat_elem_index + idx;
151 const val_ptr, const final_idx = (try recursiveIndex(sema, flat.val, &index)).?;152 const val_ptr, const final_idx = (try recursiveIndex(sema, flat.val, &index)).?;
152 try val_ptr.setElem(zcu, sema.arena, @intCast(final_idx), .{ .interned = elem });153 try val_ptr.setElem(pt, sema.arena, @intCast(final_idx), .{ .interned = elem });
153 }154 }
154 return .success;155 return .success;
155 },156 },
...@@ -165,9 +166,9 @@ pub fn storeComptimePtr(...@@ -165,9 +166,9 @@ pub fn storeComptimePtr(
165 .direct => |direct| .{ direct.val, 0 },166 .direct => |direct| .{ direct.val, 0 },
166 .index => |index| .{167 .index => |index| .{
167 index.val,168 index.val,
168 index.elem_index * index.val.typeOf(zcu).childType(zcu).abiSize(zcu),169 index.elem_index * index.val.typeOf(zcu).childType(zcu).abiSize(pt),
169 },170 },
170 .flat_index => |flat| .{ flat.val, flat.flat_elem_index * flat.val.typeOf(zcu).arrayBase(zcu)[0].abiSize(zcu) },171 .flat_index => |flat| .{ flat.val, flat.flat_elem_index * flat.val.typeOf(zcu).arrayBase(zcu)[0].abiSize(pt) },
171 .reinterpret => |reinterpret| .{ reinterpret.val, reinterpret.byte_offset },172 .reinterpret => |reinterpret| .{ reinterpret.val, reinterpret.byte_offset },
172 else => unreachable,173 else => unreachable,
173 };174 };
...@@ -181,7 +182,7 @@ pub fn storeComptimePtr(...@@ -181,7 +182,7 @@ pub fn storeComptimePtr(
181 }182 }
182183
183 const new_val = try sema.bitCastSpliceVal(184 const new_val = try sema.bitCastSpliceVal(
184 try val_ptr.intern(zcu, sema.arena),185 try val_ptr.intern(pt, sema.arena),
185 store_val,186 store_val,
186 byte_offset,187 byte_offset,
187 host_bits,188 host_bits,
...@@ -205,7 +206,8 @@ fn loadComptimePtrInner(...@@ -205,7 +206,8 @@ fn loadComptimePtrInner(
205 /// before `load_ty`. Otherwise, it is ignored and may be `undefined`.206 /// before `load_ty`. Otherwise, it is ignored and may be `undefined`.
206 array_offset: u64,207 array_offset: u64,
207) !ComptimeLoadResult {208) !ComptimeLoadResult {
208 const zcu = sema.mod;209 const pt = sema.pt;
210 const zcu = pt.zcu;
209 const ip = &zcu.intern_pool;211 const ip = &zcu.intern_pool;
210212
211 const ptr = switch (ip.indexToKey(ptr_val.toIntern())) {213 const ptr = switch (ip.indexToKey(ptr_val.toIntern())) {
...@@ -263,7 +265,7 @@ fn loadComptimePtrInner(...@@ -263,7 +265,7 @@ fn loadComptimePtrInner(
263 const load_one_ty, const load_count = load_ty.arrayBase(zcu);265 const load_one_ty, const load_count = load_ty.arrayBase(zcu);
264 const count = if (load_one_ty.toIntern() == base_ty.toIntern()) load_count else 1;266 const count = if (load_one_ty.toIntern() == base_ty.toIntern()) load_count else 1;
265267
266 const want_ty = try zcu.arrayType(.{268 const want_ty = try sema.pt.arrayType(.{
267 .len = count,269 .len = count,
268 .child = base_ty.toIntern(),270 .child = base_ty.toIntern(),
269 });271 });
...@@ -285,7 +287,7 @@ fn loadComptimePtrInner(...@@ -285,7 +287,7 @@ fn loadComptimePtrInner(
285287
286 const agg_ty = agg_val.typeOf(zcu);288 const agg_ty = agg_val.typeOf(zcu);
287 switch (agg_ty.zigTypeTag(zcu)) {289 switch (agg_ty.zigTypeTag(zcu)) {
288 .Struct, .Pointer => break :val try agg_val.getElem(zcu, @intCast(base_index.index)),290 .Struct, .Pointer => break :val try agg_val.getElem(sema.pt, @intCast(base_index.index)),
289 .Union => {291 .Union => {
290 const tag_val: Value, const payload_mv: MutableValue = switch (agg_val) {292 const tag_val: Value, const payload_mv: MutableValue = switch (agg_val) {
291 .un => |un| .{ Value.fromInterned(un.tag), un.payload.* },293 .un => |un| .{ Value.fromInterned(un.tag), un.payload.* },
...@@ -427,7 +429,7 @@ fn loadComptimePtrInner(...@@ -427,7 +429,7 @@ fn loadComptimePtrInner(
427 const next_elem_off = elem_size * (elem_idx + 1);429 const next_elem_off = elem_size * (elem_idx + 1);
428 if (cur_offset + need_bytes <= next_elem_off) {430 if (cur_offset + need_bytes <= next_elem_off) {
429 // We can look at a single array element.431 // We can look at a single array element.
430 cur_val = try cur_val.getElem(zcu, @intCast(elem_idx));432 cur_val = try cur_val.getElem(sema.pt, @intCast(elem_idx));
431 cur_offset -= elem_idx * elem_size;433 cur_offset -= elem_idx * elem_size;
432 } else {434 } else {
433 break;435 break;
...@@ -437,10 +439,10 @@ fn loadComptimePtrInner(...@@ -437,10 +439,10 @@ fn loadComptimePtrInner(
437 .auto => unreachable, // ill-defined layout439 .auto => unreachable, // ill-defined layout
438 .@"packed" => break, // let the bitcast logic handle this440 .@"packed" => break, // let the bitcast logic handle this
439 .@"extern" => for (0..cur_ty.structFieldCount(zcu)) |field_idx| {441 .@"extern" => for (0..cur_ty.structFieldCount(zcu)) |field_idx| {
440 const start_off = cur_ty.structFieldOffset(field_idx, zcu);442 const start_off = cur_ty.structFieldOffset(field_idx, pt);
441 const end_off = start_off + try sema.typeAbiSize(cur_ty.structFieldType(field_idx, zcu));443 const end_off = start_off + try sema.typeAbiSize(cur_ty.structFieldType(field_idx, zcu));
442 if (cur_offset >= start_off and cur_offset + need_bytes <= end_off) {444 if (cur_offset >= start_off and cur_offset + need_bytes <= end_off) {
443 cur_val = try cur_val.getElem(zcu, field_idx);445 cur_val = try cur_val.getElem(sema.pt, field_idx);
444 cur_offset -= start_off;446 cur_offset -= start_off;
445 break;447 break;
446 }448 }
...@@ -482,7 +484,7 @@ fn loadComptimePtrInner(...@@ -482,7 +484,7 @@ fn loadComptimePtrInner(
482 }484 }
483485
484 const result_val = try sema.bitCastVal(486 const result_val = try sema.bitCastVal(
485 try cur_val.intern(zcu, sema.arena),487 try cur_val.intern(sema.pt, sema.arena),
486 load_ty,488 load_ty,
487 cur_offset,489 cur_offset,
488 host_bits,490 host_bits,
...@@ -564,7 +566,8 @@ fn prepareComptimePtrStore(...@@ -564,7 +566,8 @@ fn prepareComptimePtrStore(
564 /// before `store_ty`. Otherwise, it is ignored and may be `undefined`.566 /// before `store_ty`. Otherwise, it is ignored and may be `undefined`.
565 array_offset: u64,567 array_offset: u64,
566) !ComptimeStoreStrategy {568) !ComptimeStoreStrategy {
567 const zcu = sema.mod;569 const pt = sema.pt;
570 const zcu = pt.zcu;
568 const ip = &zcu.intern_pool;571 const ip = &zcu.intern_pool;
569572
570 const ptr = switch (ip.indexToKey(ptr_val.toIntern())) {573 const ptr = switch (ip.indexToKey(ptr_val.toIntern())) {
...@@ -587,14 +590,14 @@ fn prepareComptimePtrStore(...@@ -587,14 +590,14 @@ fn prepareComptimePtrStore(
587 const eu_val_ptr, const alloc = switch (try prepareComptimePtrStore(sema, block, src, base_ptr, base_ty, undefined)) {590 const eu_val_ptr, const alloc = switch (try prepareComptimePtrStore(sema, block, src, base_ptr, base_ty, undefined)) {
588 .direct => |direct| .{ direct.val, direct.alloc },591 .direct => |direct| .{ direct.val, direct.alloc },
589 .index => |index| .{592 .index => |index| .{
590 try index.val.elem(zcu, sema.arena, @intCast(index.elem_index)),593 try index.val.elem(pt, sema.arena, @intCast(index.elem_index)),
591 index.alloc,594 index.alloc,
592 },595 },
593 .flat_index => unreachable, // base_ty is not an array596 .flat_index => unreachable, // base_ty is not an array
594 .reinterpret => unreachable, // base_ty has ill-defined layout597 .reinterpret => unreachable, // base_ty has ill-defined layout
595 else => |err| return err,598 else => |err| return err,
596 };599 };
597 try eu_val_ptr.unintern(zcu, sema.arena, false, false);600 try eu_val_ptr.unintern(pt, sema.arena, false, false);
598 switch (eu_val_ptr.*) {601 switch (eu_val_ptr.*) {
599 .interned => |ip_index| switch (ip.indexToKey(ip_index)) {602 .interned => |ip_index| switch (ip.indexToKey(ip_index)) {
600 .undef => return .undef,603 .undef => return .undef,
...@@ -614,14 +617,14 @@ fn prepareComptimePtrStore(...@@ -614,14 +617,14 @@ fn prepareComptimePtrStore(
614 const opt_val_ptr, const alloc = switch (try prepareComptimePtrStore(sema, block, src, base_ptr, base_ty, undefined)) {617 const opt_val_ptr, const alloc = switch (try prepareComptimePtrStore(sema, block, src, base_ptr, base_ty, undefined)) {
615 .direct => |direct| .{ direct.val, direct.alloc },618 .direct => |direct| .{ direct.val, direct.alloc },
616 .index => |index| .{619 .index => |index| .{
617 try index.val.elem(zcu, sema.arena, @intCast(index.elem_index)),620 try index.val.elem(pt, sema.arena, @intCast(index.elem_index)),
618 index.alloc,621 index.alloc,
619 },622 },
620 .flat_index => unreachable, // base_ty is not an array623 .flat_index => unreachable, // base_ty is not an array
621 .reinterpret => unreachable, // base_ty has ill-defined layout624 .reinterpret => unreachable, // base_ty has ill-defined layout
622 else => |err| return err,625 else => |err| return err,
623 };626 };
624 try opt_val_ptr.unintern(zcu, sema.arena, false, false);627 try opt_val_ptr.unintern(pt, sema.arena, false, false);
625 switch (opt_val_ptr.*) {628 switch (opt_val_ptr.*) {
626 .interned => |ip_index| switch (ip.indexToKey(ip_index)) {629 .interned => |ip_index| switch (ip.indexToKey(ip_index)) {
627 .undef => return .undef,630 .undef => return .undef,
...@@ -648,7 +651,7 @@ fn prepareComptimePtrStore(...@@ -648,7 +651,7 @@ fn prepareComptimePtrStore(
648 const store_one_ty, const store_count = store_ty.arrayBase(zcu);651 const store_one_ty, const store_count = store_ty.arrayBase(zcu);
649 const count = if (store_one_ty.toIntern() == base_ty.toIntern()) store_count else 1;652 const count = if (store_one_ty.toIntern() == base_ty.toIntern()) store_count else 1;
650653
651 const want_ty = try zcu.arrayType(.{654 const want_ty = try pt.arrayType(.{
652 .len = count,655 .len = count,
653 .child = base_ty.toIntern(),656 .child = base_ty.toIntern(),
654 });657 });
...@@ -668,7 +671,7 @@ fn prepareComptimePtrStore(...@@ -668,7 +671,7 @@ fn prepareComptimePtrStore(
668 const agg_val, const alloc = switch (try prepareComptimePtrStore(sema, block, src, base_ptr, base_ty, undefined)) {671 const agg_val, const alloc = switch (try prepareComptimePtrStore(sema, block, src, base_ptr, base_ty, undefined)) {
669 .direct => |direct| .{ direct.val, direct.alloc },672 .direct => |direct| .{ direct.val, direct.alloc },
670 .index => |index| .{673 .index => |index| .{
671 try index.val.elem(zcu, sema.arena, @intCast(index.elem_index)),674 try index.val.elem(pt, sema.arena, @intCast(index.elem_index)),
672 index.alloc,675 index.alloc,
673 },676 },
674 .flat_index => unreachable, // base_ty is not an array677 .flat_index => unreachable, // base_ty is not an array
...@@ -679,14 +682,14 @@ fn prepareComptimePtrStore(...@@ -679,14 +682,14 @@ fn prepareComptimePtrStore(
679 const agg_ty = agg_val.typeOf(zcu);682 const agg_ty = agg_val.typeOf(zcu);
680 switch (agg_ty.zigTypeTag(zcu)) {683 switch (agg_ty.zigTypeTag(zcu)) {
681 .Struct, .Pointer => break :strat .{ .direct = .{684 .Struct, .Pointer => break :strat .{ .direct = .{
682 .val = try agg_val.elem(zcu, sema.arena, @intCast(base_index.index)),685 .val = try agg_val.elem(pt, sema.arena, @intCast(base_index.index)),
683 .alloc = alloc,686 .alloc = alloc,
684 } },687 } },
685 .Union => {688 .Union => {
686 if (agg_val.* == .interned and Value.fromInterned(agg_val.interned).isUndef(zcu)) {689 if (agg_val.* == .interned and Value.fromInterned(agg_val.interned).isUndef(zcu)) {
687 return .undef;690 return .undef;
688 }691 }
689 try agg_val.unintern(zcu, sema.arena, false, false);692 try agg_val.unintern(pt, sema.arena, false, false);
690 const un = agg_val.un;693 const un = agg_val.un;
691 const tag_ty = agg_ty.unionTagTypeHypothetical(zcu);694 const tag_ty = agg_ty.unionTagTypeHypothetical(zcu);
692 if (tag_ty.enumTagFieldIndex(Value.fromInterned(un.tag), zcu).? != base_index.index) {695 if (tag_ty.enumTagFieldIndex(Value.fromInterned(un.tag), zcu).? != base_index.index) {
...@@ -847,7 +850,7 @@ fn prepareComptimePtrStore(...@@ -847,7 +850,7 @@ fn prepareComptimePtrStore(
847 const next_elem_off = elem_size * (elem_idx + 1);850 const next_elem_off = elem_size * (elem_idx + 1);
848 if (cur_offset + need_bytes <= next_elem_off) {851 if (cur_offset + need_bytes <= next_elem_off) {
849 // We can look at a single array element.852 // We can look at a single array element.
850 cur_val = try cur_val.elem(zcu, sema.arena, @intCast(elem_idx));853 cur_val = try cur_val.elem(pt, sema.arena, @intCast(elem_idx));
851 cur_offset -= elem_idx * elem_size;854 cur_offset -= elem_idx * elem_size;
852 } else {855 } else {
853 break;856 break;
...@@ -857,10 +860,10 @@ fn prepareComptimePtrStore(...@@ -857,10 +860,10 @@ fn prepareComptimePtrStore(
857 .auto => unreachable, // ill-defined layout860 .auto => unreachable, // ill-defined layout
858 .@"packed" => break, // let the bitcast logic handle this861 .@"packed" => break, // let the bitcast logic handle this
859 .@"extern" => for (0..cur_ty.structFieldCount(zcu)) |field_idx| {862 .@"extern" => for (0..cur_ty.structFieldCount(zcu)) |field_idx| {
860 const start_off = cur_ty.structFieldOffset(field_idx, zcu);863 const start_off = cur_ty.structFieldOffset(field_idx, pt);
861 const end_off = start_off + try sema.typeAbiSize(cur_ty.structFieldType(field_idx, zcu));864 const end_off = start_off + try sema.typeAbiSize(cur_ty.structFieldType(field_idx, zcu));
862 if (cur_offset >= start_off and cur_offset + need_bytes <= end_off) {865 if (cur_offset >= start_off and cur_offset + need_bytes <= end_off) {
863 cur_val = try cur_val.elem(zcu, sema.arena, field_idx);866 cur_val = try cur_val.elem(pt, sema.arena, field_idx);
864 cur_offset -= start_off;867 cur_offset -= start_off;
865 break;868 break;
866 }869 }
...@@ -874,7 +877,7 @@ fn prepareComptimePtrStore(...@@ -874,7 +877,7 @@ fn prepareComptimePtrStore(
874 // Otherwise, we might traverse into a union field which doesn't allow pointers.877 // Otherwise, we might traverse into a union field which doesn't allow pointers.
875 // Figure out a solution!878 // Figure out a solution!
876 if (true) break;879 if (true) break;
877 try cur_val.unintern(zcu, sema.arena, false, false);880 try cur_val.unintern(pt, sema.arena, false, false);
878 const payload = switch (cur_val.*) {881 const payload = switch (cur_val.*) {
879 .un => |un| un.payload,882 .un => |un| un.payload,
880 else => unreachable,883 else => unreachable,
...@@ -918,7 +921,7 @@ fn flattenArray(...@@ -918,7 +921,7 @@ fn flattenArray(
918) Allocator.Error!void {921) Allocator.Error!void {
919 if (next_idx.* == out.len) return;922 if (next_idx.* == out.len) return;
920923
921 const zcu = sema.mod;924 const zcu = sema.pt.zcu;
922925
923 const ty = val.typeOf(zcu);926 const ty = val.typeOf(zcu);
924 const base_elem_count = ty.arrayBase(zcu)[1];927 const base_elem_count = ty.arrayBase(zcu)[1];
...@@ -928,7 +931,7 @@ fn flattenArray(...@@ -928,7 +931,7 @@ fn flattenArray(
928 }931 }
929932
930 if (ty.zigTypeTag(zcu) != .Array) {933 if (ty.zigTypeTag(zcu) != .Array) {
931 out[@intCast(next_idx.*)] = (try val.intern(zcu, sema.arena)).toIntern();934 out[@intCast(next_idx.*)] = (try val.intern(sema.pt, sema.arena)).toIntern();
932 next_idx.* += 1;935 next_idx.* += 1;
933 return;936 return;
934 }937 }
...@@ -942,7 +945,7 @@ fn flattenArray(...@@ -942,7 +945,7 @@ fn flattenArray(
942 skip.* -= arr_base_elem_count;945 skip.* -= arr_base_elem_count;
943 continue;946 continue;
944 }947 }
945 try flattenArray(sema, try val.getElem(zcu, elem_idx), skip, next_idx, out);948 try flattenArray(sema, try val.getElem(sema.pt, elem_idx), skip, next_idx, out);
946 }949 }
947 if (ty.sentinel(zcu)) |s| {950 if (ty.sentinel(zcu)) |s| {
948 try flattenArray(sema, .{ .interned = s.toIntern() }, skip, next_idx, out);951 try flattenArray(sema, .{ .interned = s.toIntern() }, skip, next_idx, out);
...@@ -957,13 +960,13 @@ fn unflattenArray(...@@ -957,13 +960,13 @@ fn unflattenArray(
957 elems: []const InternPool.Index,960 elems: []const InternPool.Index,
958 next_idx: *u64,961 next_idx: *u64,
959) Allocator.Error!Value {962) Allocator.Error!Value {
960 const zcu = sema.mod;963 const zcu = sema.pt.zcu;
961 const arena = sema.arena;964 const arena = sema.arena;
962965
963 if (ty.zigTypeTag(zcu) != .Array) {966 if (ty.zigTypeTag(zcu) != .Array) {
964 const val = Value.fromInterned(elems[@intCast(next_idx.*)]);967 const val = Value.fromInterned(elems[@intCast(next_idx.*)]);
965 next_idx.* += 1;968 next_idx.* += 1;
966 return zcu.getCoerced(val, ty);969 return sema.pt.getCoerced(val, ty);
967 }970 }
968971
969 const elem_ty = ty.childType(zcu);972 const elem_ty = ty.childType(zcu);
...@@ -975,7 +978,7 @@ fn unflattenArray(...@@ -975,7 +978,7 @@ fn unflattenArray(
975 // TODO: validate sentinel978 // TODO: validate sentinel
976 _ = try unflattenArray(sema, elem_ty, elems, next_idx);979 _ = try unflattenArray(sema, elem_ty, elems, next_idx);
977 }980 }
978 return Value.fromInterned(try zcu.intern(.{ .aggregate = .{981 return Value.fromInterned(try sema.pt.intern(.{ .aggregate = .{
979 .ty = ty.toIntern(),982 .ty = ty.toIntern(),
980 .storage = .{ .elems = buf },983 .storage = .{ .elems = buf },
981 } }));984 } }));
...@@ -990,25 +993,25 @@ fn recursiveIndex(...@@ -990,25 +993,25 @@ fn recursiveIndex(
990 mv: *MutableValue,993 mv: *MutableValue,
991 index: *u64,994 index: *u64,
992) !?struct { *MutableValue, u64 } {995) !?struct { *MutableValue, u64 } {
993 const zcu = sema.mod;996 const pt = sema.pt;
994997
995 const ty = mv.typeOf(zcu);998 const ty = mv.typeOf(pt.zcu);
996 assert(ty.zigTypeTag(zcu) == .Array);999 assert(ty.zigTypeTag(pt.zcu) == .Array);
9971000
998 const ty_base_elems = ty.arrayBase(zcu)[1];1001 const ty_base_elems = ty.arrayBase(pt.zcu)[1];
999 if (index.* >= ty_base_elems) {1002 if (index.* >= ty_base_elems) {
1000 index.* -= ty_base_elems;1003 index.* -= ty_base_elems;
1001 return null;1004 return null;
1002 }1005 }
10031006
1004 const elem_ty = ty.childType(zcu);1007 const elem_ty = ty.childType(pt.zcu);
1005 if (elem_ty.zigTypeTag(zcu) != .Array) {1008 if (elem_ty.zigTypeTag(pt.zcu) != .Array) {
1006 assert(index.* < ty.arrayLenIncludingSentinel(zcu)); // should be handled by initial check1009 assert(index.* < ty.arrayLenIncludingSentinel(pt.zcu)); // should be handled by initial check
1007 return .{ mv, index.* };1010 return .{ mv, index.* };
1008 }1011 }
10091012
1010 for (0..@intCast(ty.arrayLenIncludingSentinel(zcu))) |elem_index| {1013 for (0..@intCast(ty.arrayLenIncludingSentinel(pt.zcu))) |elem_index| {
1011 if (try recursiveIndex(sema, try mv.elem(zcu, sema.arena, elem_index), index)) |result| {1014 if (try recursiveIndex(sema, try mv.elem(pt, sema.arena, elem_index), index)) |result| {
1012 return result;1015 return result;
1013 }1016 }
1014 }1017 }
src/Type.zig+377-362
...@@ -136,16 +136,16 @@ pub fn format(ty: Type, comptime unused_fmt_string: []const u8, options: std.fmt...@@ -136,16 +136,16 @@ pub fn format(ty: Type, comptime unused_fmt_string: []const u8, options: std.fmt
136136
137pub const Formatter = std.fmt.Formatter(format2);137pub const Formatter = std.fmt.Formatter(format2);
138138
139pub fn fmt(ty: Type, module: *Module) Formatter {139pub fn fmt(ty: Type, pt: Zcu.PerThread) Formatter {
140 return .{ .data = .{140 return .{ .data = .{
141 .ty = ty,141 .ty = ty,
142 .module = module,142 .pt = pt,
143 } };143 } };
144}144}
145145
146const FormatContext = struct {146const FormatContext = struct {
147 ty: Type,147 ty: Type,
148 module: *Module,148 pt: Zcu.PerThread,
149};149};
150150
151fn format2(151fn format2(
...@@ -156,7 +156,7 @@ fn format2(...@@ -156,7 +156,7 @@ fn format2(
156) !void {156) !void {
157 comptime assert(unused_format_string.len == 0);157 comptime assert(unused_format_string.len == 0);
158 _ = options;158 _ = options;
159 return print(ctx.ty, writer, ctx.module);159 return print(ctx.ty, writer, ctx.pt);
160}160}
161161
162pub fn fmtDebug(ty: Type) std.fmt.Formatter(dump) {162pub fn fmtDebug(ty: Type) std.fmt.Formatter(dump) {
...@@ -178,7 +178,8 @@ pub fn dump(...@@ -178,7 +178,8 @@ pub fn dump(
178178
179/// Prints a name suitable for `@typeName`.179/// Prints a name suitable for `@typeName`.
180/// TODO: take an `opt_sema` to pass to `fmtValue` when printing sentinels.180/// TODO: take an `opt_sema` to pass to `fmtValue` when printing sentinels.
181pub fn print(ty: Type, writer: anytype, mod: *Module) @TypeOf(writer).Error!void {181pub fn print(ty: Type, writer: anytype, pt: Zcu.PerThread) @TypeOf(writer).Error!void {
182 const mod = pt.zcu;
182 const ip = &mod.intern_pool;183 const ip = &mod.intern_pool;
183 switch (ip.indexToKey(ty.toIntern())) {184 switch (ip.indexToKey(ty.toIntern())) {
184 .int_type => |int_type| {185 .int_type => |int_type| {
...@@ -193,8 +194,8 @@ pub fn print(ty: Type, writer: anytype, mod: *Module) @TypeOf(writer).Error!void...@@ -193,8 +194,8 @@ pub fn print(ty: Type, writer: anytype, mod: *Module) @TypeOf(writer).Error!void
193194
194 if (info.sentinel != .none) switch (info.flags.size) {195 if (info.sentinel != .none) switch (info.flags.size) {
195 .One, .C => unreachable,196 .One, .C => unreachable,
196 .Many => try writer.print("[*:{}]", .{Value.fromInterned(info.sentinel).fmtValue(mod, null)}),197 .Many => try writer.print("[*:{}]", .{Value.fromInterned(info.sentinel).fmtValue(pt, null)}),
197 .Slice => try writer.print("[:{}]", .{Value.fromInterned(info.sentinel).fmtValue(mod, null)}),198 .Slice => try writer.print("[:{}]", .{Value.fromInterned(info.sentinel).fmtValue(pt, null)}),
198 } else switch (info.flags.size) {199 } else switch (info.flags.size) {
199 .One => try writer.writeAll("*"),200 .One => try writer.writeAll("*"),
200 .Many => try writer.writeAll("[*]"),201 .Many => try writer.writeAll("[*]"),
...@@ -208,7 +209,7 @@ pub fn print(ty: Type, writer: anytype, mod: *Module) @TypeOf(writer).Error!void...@@ -208,7 +209,7 @@ pub fn print(ty: Type, writer: anytype, mod: *Module) @TypeOf(writer).Error!void
208 const alignment = if (info.flags.alignment != .none)209 const alignment = if (info.flags.alignment != .none)
209 info.flags.alignment210 info.flags.alignment
210 else211 else
211 Type.fromInterned(info.child).abiAlignment(mod);212 Type.fromInterned(info.child).abiAlignment(pt);
212 try writer.print("align({d}", .{alignment.toByteUnits() orelse 0});213 try writer.print("align({d}", .{alignment.toByteUnits() orelse 0});
213214
214 if (info.packed_offset.bit_offset != 0 or info.packed_offset.host_size != 0) {215 if (info.packed_offset.bit_offset != 0 or info.packed_offset.host_size != 0) {
...@@ -230,39 +231,39 @@ pub fn print(ty: Type, writer: anytype, mod: *Module) @TypeOf(writer).Error!void...@@ -230,39 +231,39 @@ pub fn print(ty: Type, writer: anytype, mod: *Module) @TypeOf(writer).Error!void
230 if (info.flags.is_volatile) try writer.writeAll("volatile ");231 if (info.flags.is_volatile) try writer.writeAll("volatile ");
231 if (info.flags.is_allowzero and info.flags.size != .C) try writer.writeAll("allowzero ");232 if (info.flags.is_allowzero and info.flags.size != .C) try writer.writeAll("allowzero ");
232233
233 try print(Type.fromInterned(info.child), writer, mod);234 try print(Type.fromInterned(info.child), writer, pt);
234 return;235 return;
235 },236 },
236 .array_type => |array_type| {237 .array_type => |array_type| {
237 if (array_type.sentinel == .none) {238 if (array_type.sentinel == .none) {
238 try writer.print("[{d}]", .{array_type.len});239 try writer.print("[{d}]", .{array_type.len});
239 try print(Type.fromInterned(array_type.child), writer, mod);240 try print(Type.fromInterned(array_type.child), writer, pt);
240 } else {241 } else {
241 try writer.print("[{d}:{}]", .{242 try writer.print("[{d}:{}]", .{
242 array_type.len,243 array_type.len,
243 Value.fromInterned(array_type.sentinel).fmtValue(mod, null),244 Value.fromInterned(array_type.sentinel).fmtValue(pt, null),
244 });245 });
245 try print(Type.fromInterned(array_type.child), writer, mod);246 try print(Type.fromInterned(array_type.child), writer, pt);
246 }247 }
247 return;248 return;
248 },249 },
249 .vector_type => |vector_type| {250 .vector_type => |vector_type| {
250 try writer.print("@Vector({d}, ", .{vector_type.len});251 try writer.print("@Vector({d}, ", .{vector_type.len});
251 try print(Type.fromInterned(vector_type.child), writer, mod);252 try print(Type.fromInterned(vector_type.child), writer, pt);
252 try writer.writeAll(")");253 try writer.writeAll(")");
253 return;254 return;
254 },255 },
255 .opt_type => |child| {256 .opt_type => |child| {
256 try writer.writeByte('?');257 try writer.writeByte('?');
257 return print(Type.fromInterned(child), writer, mod);258 return print(Type.fromInterned(child), writer, pt);
258 },259 },
259 .error_union_type => |error_union_type| {260 .error_union_type => |error_union_type| {
260 try print(Type.fromInterned(error_union_type.error_set_type), writer, mod);261 try print(Type.fromInterned(error_union_type.error_set_type), writer, pt);
261 try writer.writeByte('!');262 try writer.writeByte('!');
262 if (error_union_type.payload_type == .generic_poison_type) {263 if (error_union_type.payload_type == .generic_poison_type) {
263 try writer.writeAll("anytype");264 try writer.writeAll("anytype");
264 } else {265 } else {
265 try print(Type.fromInterned(error_union_type.payload_type), writer, mod);266 try print(Type.fromInterned(error_union_type.payload_type), writer, pt);
266 }267 }
267 return;268 return;
268 },269 },
...@@ -355,10 +356,10 @@ pub fn print(ty: Type, writer: anytype, mod: *Module) @TypeOf(writer).Error!void...@@ -355,10 +356,10 @@ pub fn print(ty: Type, writer: anytype, mod: *Module) @TypeOf(writer).Error!void
355 try writer.print("{}: ", .{anon_struct.names.get(ip)[i].fmt(&mod.intern_pool)});356 try writer.print("{}: ", .{anon_struct.names.get(ip)[i].fmt(&mod.intern_pool)});
356 }357 }
357358
358 try print(Type.fromInterned(field_ty), writer, mod);359 try print(Type.fromInterned(field_ty), writer, pt);
359360
360 if (val != .none) {361 if (val != .none) {
361 try writer.print(" = {}", .{Value.fromInterned(val).fmtValue(mod, null)});362 try writer.print(" = {}", .{Value.fromInterned(val).fmtValue(pt, null)});
362 }363 }
363 }364 }
364 try writer.writeAll("}");365 try writer.writeAll("}");
...@@ -395,7 +396,7 @@ pub fn print(ty: Type, writer: anytype, mod: *Module) @TypeOf(writer).Error!void...@@ -395,7 +396,7 @@ pub fn print(ty: Type, writer: anytype, mod: *Module) @TypeOf(writer).Error!void
395 if (param_ty == .generic_poison_type) {396 if (param_ty == .generic_poison_type) {
396 try writer.writeAll("anytype");397 try writer.writeAll("anytype");
397 } else {398 } else {
398 try print(Type.fromInterned(param_ty), writer, mod);399 try print(Type.fromInterned(param_ty), writer, pt);
399 }400 }
400 }401 }
401 if (fn_info.is_var_args) {402 if (fn_info.is_var_args) {
...@@ -413,13 +414,13 @@ pub fn print(ty: Type, writer: anytype, mod: *Module) @TypeOf(writer).Error!void...@@ -413,13 +414,13 @@ pub fn print(ty: Type, writer: anytype, mod: *Module) @TypeOf(writer).Error!void
413 if (fn_info.return_type == .generic_poison_type) {414 if (fn_info.return_type == .generic_poison_type) {
414 try writer.writeAll("anytype");415 try writer.writeAll("anytype");
415 } else {416 } else {
416 try print(Type.fromInterned(fn_info.return_type), writer, mod);417 try print(Type.fromInterned(fn_info.return_type), writer, pt);
417 }418 }
418 },419 },
419 .anyframe_type => |child| {420 .anyframe_type => |child| {
420 if (child == .none) return writer.writeAll("anyframe");421 if (child == .none) return writer.writeAll("anyframe");
421 try writer.writeAll("anyframe->");422 try writer.writeAll("anyframe->");
422 return print(Type.fromInterned(child), writer, mod);423 return print(Type.fromInterned(child), writer, pt);
423 },424 },
424425
425 // values, not types426 // values, not types
...@@ -475,10 +476,11 @@ const RuntimeBitsError = SemaError || error{NeedLazy};...@@ -475,10 +476,11 @@ const RuntimeBitsError = SemaError || error{NeedLazy};
475/// may return false positives.476/// may return false positives.
476pub fn hasRuntimeBitsAdvanced(477pub fn hasRuntimeBitsAdvanced(
477 ty: Type,478 ty: Type,
478 mod: *Module,479 pt: Zcu.PerThread,
479 ignore_comptime_only: bool,480 ignore_comptime_only: bool,
480 strat: ResolveStratLazy,481 strat: ResolveStratLazy,
481) RuntimeBitsError!bool {482) RuntimeBitsError!bool {
483 const mod = pt.zcu;
482 const ip = &mod.intern_pool;484 const ip = &mod.intern_pool;
483 return switch (ty.toIntern()) {485 return switch (ty.toIntern()) {
484 // False because it is a comptime-only type.486 // False because it is a comptime-only type.
...@@ -490,16 +492,16 @@ pub fn hasRuntimeBitsAdvanced(...@@ -490,16 +492,16 @@ pub fn hasRuntimeBitsAdvanced(
490 // to comptime-only types do not, with the exception of function pointers.492 // to comptime-only types do not, with the exception of function pointers.
491 if (ignore_comptime_only) return true;493 if (ignore_comptime_only) return true;
492 return switch (strat) {494 return switch (strat) {
493 .sema => !try ty.comptimeOnlyAdvanced(mod, .sema),495 .sema => !try ty.comptimeOnlyAdvanced(pt, .sema),
494 .eager => !ty.comptimeOnly(mod),496 .eager => !ty.comptimeOnly(pt),
495 .lazy => error.NeedLazy,497 .lazy => error.NeedLazy,
496 };498 };
497 },499 },
498 .anyframe_type => true,500 .anyframe_type => true,
499 .array_type => |array_type| return array_type.lenIncludingSentinel() > 0 and501 .array_type => |array_type| return array_type.lenIncludingSentinel() > 0 and
500 try Type.fromInterned(array_type.child).hasRuntimeBitsAdvanced(mod, ignore_comptime_only, strat),502 try Type.fromInterned(array_type.child).hasRuntimeBitsAdvanced(pt, ignore_comptime_only, strat),
501 .vector_type => |vector_type| return vector_type.len > 0 and503 .vector_type => |vector_type| return vector_type.len > 0 and
502 try Type.fromInterned(vector_type.child).hasRuntimeBitsAdvanced(mod, ignore_comptime_only, strat),504 try Type.fromInterned(vector_type.child).hasRuntimeBitsAdvanced(pt, ignore_comptime_only, strat),
503 .opt_type => |child| {505 .opt_type => |child| {
504 const child_ty = Type.fromInterned(child);506 const child_ty = Type.fromInterned(child);
505 if (child_ty.isNoReturn(mod)) {507 if (child_ty.isNoReturn(mod)) {
...@@ -508,8 +510,8 @@ pub fn hasRuntimeBitsAdvanced(...@@ -508,8 +510,8 @@ pub fn hasRuntimeBitsAdvanced(
508 }510 }
509 if (ignore_comptime_only) return true;511 if (ignore_comptime_only) return true;
510 return switch (strat) {512 return switch (strat) {
511 .sema => !try child_ty.comptimeOnlyAdvanced(mod, .sema),513 .sema => !try child_ty.comptimeOnlyAdvanced(pt, .sema),
512 .eager => !child_ty.comptimeOnly(mod),514 .eager => !child_ty.comptimeOnly(pt),
513 .lazy => error.NeedLazy,515 .lazy => error.NeedLazy,
514 };516 };
515 },517 },
...@@ -580,14 +582,14 @@ pub fn hasRuntimeBitsAdvanced(...@@ -580,14 +582,14 @@ pub fn hasRuntimeBitsAdvanced(
580 return true;582 return true;
581 }583 }
582 switch (strat) {584 switch (strat) {
583 .sema => try ty.resolveFields(mod),585 .sema => try ty.resolveFields(pt),
584 .eager => assert(struct_type.haveFieldTypes(ip)),586 .eager => assert(struct_type.haveFieldTypes(ip)),
585 .lazy => if (!struct_type.haveFieldTypes(ip)) return error.NeedLazy,587 .lazy => if (!struct_type.haveFieldTypes(ip)) return error.NeedLazy,
586 }588 }
587 for (0..struct_type.field_types.len) |i| {589 for (0..struct_type.field_types.len) |i| {
588 if (struct_type.comptime_bits.getBit(ip, i)) continue;590 if (struct_type.comptime_bits.getBit(ip, i)) continue;
589 const field_ty = Type.fromInterned(struct_type.field_types.get(ip)[i]);591 const field_ty = Type.fromInterned(struct_type.field_types.get(ip)[i]);
590 if (try field_ty.hasRuntimeBitsAdvanced(mod, ignore_comptime_only, strat))592 if (try field_ty.hasRuntimeBitsAdvanced(pt, ignore_comptime_only, strat))
591 return true;593 return true;
592 } else {594 } else {
593 return false;595 return false;
...@@ -596,7 +598,7 @@ pub fn hasRuntimeBitsAdvanced(...@@ -596,7 +598,7 @@ pub fn hasRuntimeBitsAdvanced(
596 .anon_struct_type => |tuple| {598 .anon_struct_type => |tuple| {
597 for (tuple.types.get(ip), tuple.values.get(ip)) |field_ty, val| {599 for (tuple.types.get(ip), tuple.values.get(ip)) |field_ty, val| {
598 if (val != .none) continue; // comptime field600 if (val != .none) continue; // comptime field
599 if (try Type.fromInterned(field_ty).hasRuntimeBitsAdvanced(mod, ignore_comptime_only, strat)) return true;601 if (try Type.fromInterned(field_ty).hasRuntimeBitsAdvanced(pt, ignore_comptime_only, strat)) return true;
600 }602 }
601 return false;603 return false;
602 },604 },
...@@ -617,21 +619,21 @@ pub fn hasRuntimeBitsAdvanced(...@@ -617,21 +619,21 @@ pub fn hasRuntimeBitsAdvanced(
617 // tag_ty will be `none` if this union's tag type is not resolved yet,619 // tag_ty will be `none` if this union's tag type is not resolved yet,
618 // in which case we want control flow to continue down below.620 // in which case we want control flow to continue down below.
619 if (tag_ty != .none and621 if (tag_ty != .none and
620 try Type.fromInterned(tag_ty).hasRuntimeBitsAdvanced(mod, ignore_comptime_only, strat))622 try Type.fromInterned(tag_ty).hasRuntimeBitsAdvanced(pt, ignore_comptime_only, strat))
621 {623 {
622 return true;624 return true;
623 }625 }
624 },626 },
625 }627 }
626 switch (strat) {628 switch (strat) {
627 .sema => try ty.resolveFields(mod),629 .sema => try ty.resolveFields(pt),
628 .eager => assert(union_type.flagsPtr(ip).status.haveFieldTypes()),630 .eager => assert(union_type.flagsPtr(ip).status.haveFieldTypes()),
629 .lazy => if (!union_type.flagsPtr(ip).status.haveFieldTypes())631 .lazy => if (!union_type.flagsPtr(ip).status.haveFieldTypes())
630 return error.NeedLazy,632 return error.NeedLazy,
631 }633 }
632 for (0..union_type.field_types.len) |field_index| {634 for (0..union_type.field_types.len) |field_index| {
633 const field_ty = Type.fromInterned(union_type.field_types.get(ip)[field_index]);635 const field_ty = Type.fromInterned(union_type.field_types.get(ip)[field_index]);
634 if (try field_ty.hasRuntimeBitsAdvanced(mod, ignore_comptime_only, strat))636 if (try field_ty.hasRuntimeBitsAdvanced(pt, ignore_comptime_only, strat))
635 return true;637 return true;
636 } else {638 } else {
637 return false;639 return false;
...@@ -639,7 +641,7 @@ pub fn hasRuntimeBitsAdvanced(...@@ -639,7 +641,7 @@ pub fn hasRuntimeBitsAdvanced(
639 },641 },
640642
641 .opaque_type => true,643 .opaque_type => true,
642 .enum_type => Type.fromInterned(ip.loadEnumType(ty.toIntern()).tag_ty).hasRuntimeBitsAdvanced(mod, ignore_comptime_only, strat),644 .enum_type => Type.fromInterned(ip.loadEnumType(ty.toIntern()).tag_ty).hasRuntimeBitsAdvanced(pt, ignore_comptime_only, strat),
643645
644 // values, not types646 // values, not types
645 .undef,647 .undef,
...@@ -777,41 +779,41 @@ pub fn hasWellDefinedLayout(ty: Type, mod: *Module) bool {...@@ -777,41 +779,41 @@ pub fn hasWellDefinedLayout(ty: Type, mod: *Module) bool {
777 };779 };
778}780}
779781
780pub fn hasRuntimeBits(ty: Type, mod: *Module) bool {782pub fn hasRuntimeBits(ty: Type, pt: Zcu.PerThread) bool {
781 return hasRuntimeBitsAdvanced(ty, mod, false, .eager) catch unreachable;783 return hasRuntimeBitsAdvanced(ty, pt, false, .eager) catch unreachable;
782}784}
783785
784pub fn hasRuntimeBitsIgnoreComptime(ty: Type, mod: *Module) bool {786pub fn hasRuntimeBitsIgnoreComptime(ty: Type, pt: Zcu.PerThread) bool {
785 return hasRuntimeBitsAdvanced(ty, mod, true, .eager) catch unreachable;787 return hasRuntimeBitsAdvanced(ty, pt, true, .eager) catch unreachable;
786}788}
787789
788pub fn fnHasRuntimeBits(ty: Type, mod: *Module) bool {790pub fn fnHasRuntimeBits(ty: Type, pt: Zcu.PerThread) bool {
789 return ty.fnHasRuntimeBitsAdvanced(mod, .normal) catch unreachable;791 return ty.fnHasRuntimeBitsAdvanced(pt, .normal) catch unreachable;
790}792}
791793
792/// Determines whether a function type has runtime bits, i.e. whether a794/// Determines whether a function type has runtime bits, i.e. whether a
793/// function with this type can exist at runtime.795/// function with this type can exist at runtime.
794/// Asserts that `ty` is a function type.796/// Asserts that `ty` is a function type.
795pub fn fnHasRuntimeBitsAdvanced(ty: Type, mod: *Module, strat: ResolveStrat) SemaError!bool {797pub fn fnHasRuntimeBitsAdvanced(ty: Type, pt: Zcu.PerThread, strat: ResolveStrat) SemaError!bool {
796 const fn_info = mod.typeToFunc(ty).?;798 const fn_info = pt.zcu.typeToFunc(ty).?;
797 if (fn_info.is_generic) return false;799 if (fn_info.is_generic) return false;
798 if (fn_info.is_var_args) return true;800 if (fn_info.is_var_args) return true;
799 if (fn_info.cc == .Inline) return false;801 if (fn_info.cc == .Inline) return false;
800 return !try Type.fromInterned(fn_info.return_type).comptimeOnlyAdvanced(mod, strat);802 return !try Type.fromInterned(fn_info.return_type).comptimeOnlyAdvanced(pt, strat);
801}803}
802804
803pub fn isFnOrHasRuntimeBits(ty: Type, mod: *Module) bool {805pub fn isFnOrHasRuntimeBits(ty: Type, pt: Zcu.PerThread) bool {
804 switch (ty.zigTypeTag(mod)) {806 switch (ty.zigTypeTag(pt.zcu)) {
805 .Fn => return ty.fnHasRuntimeBits(mod),807 .Fn => return ty.fnHasRuntimeBits(pt),
806 else => return ty.hasRuntimeBits(mod),808 else => return ty.hasRuntimeBits(pt),
807 }809 }
808}810}
809811
810/// Same as `isFnOrHasRuntimeBits` but comptime-only types may return a false positive.812/// Same as `isFnOrHasRuntimeBits` but comptime-only types may return a false positive.
811pub fn isFnOrHasRuntimeBitsIgnoreComptime(ty: Type, mod: *Module) bool {813pub fn isFnOrHasRuntimeBitsIgnoreComptime(ty: Type, pt: Zcu.PerThread) bool {
812 return switch (ty.zigTypeTag(mod)) {814 return switch (ty.zigTypeTag(pt.zcu)) {
813 .Fn => true,815 .Fn => true,
814 else => return ty.hasRuntimeBitsIgnoreComptime(mod),816 else => return ty.hasRuntimeBitsIgnoreComptime(pt),
815 };817 };
816}818}
817819
...@@ -820,24 +822,24 @@ pub fn isNoReturn(ty: Type, mod: *Module) bool {...@@ -820,24 +822,24 @@ pub fn isNoReturn(ty: Type, mod: *Module) bool {
820}822}
821823
822/// Returns `none` if the pointer is naturally aligned and the element type is 0-bit.824/// Returns `none` if the pointer is naturally aligned and the element type is 0-bit.
823pub fn ptrAlignment(ty: Type, mod: *Module) Alignment {825pub fn ptrAlignment(ty: Type, pt: Zcu.PerThread) Alignment {
824 return ptrAlignmentAdvanced(ty, mod, .normal) catch unreachable;826 return ptrAlignmentAdvanced(ty, pt, .normal) catch unreachable;
825}827}
826828
827pub fn ptrAlignmentAdvanced(ty: Type, mod: *Module, strat: ResolveStrat) !Alignment {829pub fn ptrAlignmentAdvanced(ty: Type, pt: Zcu.PerThread, strat: ResolveStrat) !Alignment {
828 return switch (mod.intern_pool.indexToKey(ty.toIntern())) {830 return switch (pt.zcu.intern_pool.indexToKey(ty.toIntern())) {
829 .ptr_type => |ptr_type| {831 .ptr_type => |ptr_type| {
830 if (ptr_type.flags.alignment != .none)832 if (ptr_type.flags.alignment != .none)
831 return ptr_type.flags.alignment;833 return ptr_type.flags.alignment;
832834
833 if (strat == .sema) {835 if (strat == .sema) {
834 const res = try Type.fromInterned(ptr_type.child).abiAlignmentAdvanced(mod, .sema);836 const res = try Type.fromInterned(ptr_type.child).abiAlignmentAdvanced(pt, .sema);
835 return res.scalar;837 return res.scalar;
836 }838 }
837839
838 return (Type.fromInterned(ptr_type.child).abiAlignmentAdvanced(mod, .eager) catch unreachable).scalar;840 return (Type.fromInterned(ptr_type.child).abiAlignmentAdvanced(pt, .eager) catch unreachable).scalar;
839 },841 },
840 .opt_type => |child| Type.fromInterned(child).ptrAlignmentAdvanced(mod, strat),842 .opt_type => |child| Type.fromInterned(child).ptrAlignmentAdvanced(pt, strat),
841 else => unreachable,843 else => unreachable,
842 };844 };
843}845}
...@@ -851,16 +853,16 @@ pub fn ptrAddressSpace(ty: Type, mod: *const Module) std.builtin.AddressSpace {...@@ -851,16 +853,16 @@ pub fn ptrAddressSpace(ty: Type, mod: *const Module) std.builtin.AddressSpace {
851}853}
852854
853/// Never returns `none`. Asserts that all necessary type resolution is already done.855/// Never returns `none`. Asserts that all necessary type resolution is already done.
854pub fn abiAlignment(ty: Type, mod: *Module) Alignment {856pub fn abiAlignment(ty: Type, pt: Zcu.PerThread) Alignment {
855 return (ty.abiAlignmentAdvanced(mod, .eager) catch unreachable).scalar;857 return (ty.abiAlignmentAdvanced(pt, .eager) catch unreachable).scalar;
856}858}
857859
858/// May capture a reference to `ty`.860/// May capture a reference to `ty`.
859/// Returned value has type `comptime_int`.861/// Returned value has type `comptime_int`.
860pub fn lazyAbiAlignment(ty: Type, mod: *Module) !Value {862pub fn lazyAbiAlignment(ty: Type, pt: Zcu.PerThread) !Value {
861 switch (try ty.abiAlignmentAdvanced(mod, .lazy)) {863 switch (try ty.abiAlignmentAdvanced(pt, .lazy)) {
862 .val => |val| return val,864 .val => |val| return val,
863 .scalar => |x| return mod.intValue(Type.comptime_int, x.toByteUnits() orelse 0),865 .scalar => |x| return pt.intValue(Type.comptime_int, x.toByteUnits() orelse 0),
864 }866 }
865}867}
866868
...@@ -907,38 +909,39 @@ pub const ResolveStrat = enum {...@@ -907,38 +909,39 @@ pub const ResolveStrat = enum {
907/// necessary, possibly returning a CompileError.909/// necessary, possibly returning a CompileError.
908pub fn abiAlignmentAdvanced(910pub fn abiAlignmentAdvanced(
909 ty: Type,911 ty: Type,
910 mod: *Module,912 pt: Zcu.PerThread,
911 strat: ResolveStratLazy,913 strat: ResolveStratLazy,
912) SemaError!AbiAlignmentAdvanced {914) SemaError!AbiAlignmentAdvanced {
915 const mod = pt.zcu;
913 const target = mod.getTarget();916 const target = mod.getTarget();
914 const use_llvm = mod.comp.config.use_llvm;917 const use_llvm = mod.comp.config.use_llvm;
915 const ip = &mod.intern_pool;918 const ip = &mod.intern_pool;
916919
917 switch (ty.toIntern()) {920 switch (ty.toIntern()) {
918 .empty_struct_type => return AbiAlignmentAdvanced{ .scalar = .@"1" },921 .empty_struct_type => return .{ .scalar = .@"1" },
919 else => switch (ip.indexToKey(ty.toIntern())) {922 else => switch (ip.indexToKey(ty.toIntern())) {
920 .int_type => |int_type| {923 .int_type => |int_type| {
921 if (int_type.bits == 0) return AbiAlignmentAdvanced{ .scalar = .@"1" };924 if (int_type.bits == 0) return .{ .scalar = .@"1" };
922 return .{ .scalar = intAbiAlignment(int_type.bits, target, use_llvm) };925 return .{ .scalar = intAbiAlignment(int_type.bits, target, use_llvm) };
923 },926 },
924 .ptr_type, .anyframe_type => {927 .ptr_type, .anyframe_type => {
925 return .{ .scalar = ptrAbiAlignment(target) };928 return .{ .scalar = ptrAbiAlignment(target) };
926 },929 },
927 .array_type => |array_type| {930 .array_type => |array_type| {
928 return Type.fromInterned(array_type.child).abiAlignmentAdvanced(mod, strat);931 return Type.fromInterned(array_type.child).abiAlignmentAdvanced(pt, strat);
929 },932 },
930 .vector_type => |vector_type| {933 .vector_type => |vector_type| {
931 if (vector_type.len == 0) return .{ .scalar = .@"1" };934 if (vector_type.len == 0) return .{ .scalar = .@"1" };
932 switch (mod.comp.getZigBackend()) {935 switch (mod.comp.getZigBackend()) {
933 else => {936 else => {
934 const elem_bits: u32 = @intCast(try Type.fromInterned(vector_type.child).bitSizeAdvanced(mod, .sema));937 const elem_bits: u32 = @intCast(try Type.fromInterned(vector_type.child).bitSizeAdvanced(pt, .sema));
935 if (elem_bits == 0) return .{ .scalar = .@"1" };938 if (elem_bits == 0) return .{ .scalar = .@"1" };
936 const bytes = ((elem_bits * vector_type.len) + 7) / 8;939 const bytes = ((elem_bits * vector_type.len) + 7) / 8;
937 const alignment = std.math.ceilPowerOfTwoAssert(u32, bytes);940 const alignment = std.math.ceilPowerOfTwoAssert(u32, bytes);
938 return .{ .scalar = Alignment.fromByteUnits(alignment) };941 return .{ .scalar = Alignment.fromByteUnits(alignment) };
939 },942 },
940 .stage2_c => {943 .stage2_c => {
941 return Type.fromInterned(vector_type.child).abiAlignmentAdvanced(mod, strat);944 return Type.fromInterned(vector_type.child).abiAlignmentAdvanced(pt, strat);
942 },945 },
943 .stage2_x86_64 => {946 .stage2_x86_64 => {
944 if (vector_type.child == .bool_type) {947 if (vector_type.child == .bool_type) {
...@@ -949,7 +952,7 @@ pub fn abiAlignmentAdvanced(...@@ -949,7 +952,7 @@ pub fn abiAlignmentAdvanced(
949 const alignment = std.math.ceilPowerOfTwoAssert(u32, bytes);952 const alignment = std.math.ceilPowerOfTwoAssert(u32, bytes);
950 return .{ .scalar = Alignment.fromByteUnits(alignment) };953 return .{ .scalar = Alignment.fromByteUnits(alignment) };
951 }954 }
952 const elem_bytes: u32 = @intCast((try Type.fromInterned(vector_type.child).abiSizeAdvanced(mod, strat)).scalar);955 const elem_bytes: u32 = @intCast((try Type.fromInterned(vector_type.child).abiSizeAdvanced(pt, strat)).scalar);
953 if (elem_bytes == 0) return .{ .scalar = .@"1" };956 if (elem_bytes == 0) return .{ .scalar = .@"1" };
954 const bytes = elem_bytes * vector_type.len;957 const bytes = elem_bytes * vector_type.len;
955 if (bytes > 32 and std.Target.x86.featureSetHas(target.cpu.features, .avx512f)) return .{ .scalar = .@"64" };958 if (bytes > 32 and std.Target.x86.featureSetHas(target.cpu.features, .avx512f)) return .{ .scalar = .@"64" };
...@@ -959,12 +962,12 @@ pub fn abiAlignmentAdvanced(...@@ -959,12 +962,12 @@ pub fn abiAlignmentAdvanced(
959 }962 }
960 },963 },
961964
962 .opt_type => return abiAlignmentAdvancedOptional(ty, mod, strat),965 .opt_type => return ty.abiAlignmentAdvancedOptional(pt, strat),
963 .error_union_type => |info| return abiAlignmentAdvancedErrorUnion(ty, mod, strat, Type.fromInterned(info.payload_type)),966 .error_union_type => |info| return ty.abiAlignmentAdvancedErrorUnion(pt, strat, Type.fromInterned(info.payload_type)),
964967
965 .error_set_type, .inferred_error_set_type => {968 .error_set_type, .inferred_error_set_type => {
966 const bits = mod.errorSetBits();969 const bits = mod.errorSetBits();
967 if (bits == 0) return AbiAlignmentAdvanced{ .scalar = .@"1" };970 if (bits == 0) return .{ .scalar = .@"1" };
968 return .{ .scalar = intAbiAlignment(bits, target, use_llvm) };971 return .{ .scalar = intAbiAlignment(bits, target, use_llvm) };
969 },972 },
970973
...@@ -1012,10 +1015,7 @@ pub fn abiAlignmentAdvanced(...@@ -1012,10 +1015,7 @@ pub fn abiAlignmentAdvanced(
1012 },1015 },
1013 .f80 => switch (target.c_type_bit_size(.longdouble)) {1016 .f80 => switch (target.c_type_bit_size(.longdouble)) {
1014 80 => return .{ .scalar = cTypeAlign(target, .longdouble) },1017 80 => return .{ .scalar = cTypeAlign(target, .longdouble) },
1015 else => {1018 else => return .{ .scalar = Type.u80.abiAlignment(pt) },
1016 const u80_ty: Type = .{ .ip_index = .u80_type };
1017 return .{ .scalar = abiAlignment(u80_ty, mod) };
1018 },
1019 },1019 },
1020 .f128 => switch (target.c_type_bit_size(.longdouble)) {1020 .f128 => switch (target.c_type_bit_size(.longdouble)) {
1021 128 => return .{ .scalar = cTypeAlign(target, .longdouble) },1021 128 => return .{ .scalar = cTypeAlign(target, .longdouble) },
...@@ -1024,7 +1024,7 @@ pub fn abiAlignmentAdvanced(...@@ -1024,7 +1024,7 @@ pub fn abiAlignmentAdvanced(
10241024
1025 .anyerror, .adhoc_inferred_error_set => {1025 .anyerror, .adhoc_inferred_error_set => {
1026 const bits = mod.errorSetBits();1026 const bits = mod.errorSetBits();
1027 if (bits == 0) return AbiAlignmentAdvanced{ .scalar = .@"1" };1027 if (bits == 0) return .{ .scalar = .@"1" };
1028 return .{ .scalar = intAbiAlignment(bits, target, use_llvm) };1028 return .{ .scalar = intAbiAlignment(bits, target, use_llvm) };
1029 },1029 },
10301030
...@@ -1044,22 +1044,22 @@ pub fn abiAlignmentAdvanced(...@@ -1044,22 +1044,22 @@ pub fn abiAlignmentAdvanced(
1044 const struct_type = ip.loadStructType(ty.toIntern());1044 const struct_type = ip.loadStructType(ty.toIntern());
1045 if (struct_type.layout == .@"packed") {1045 if (struct_type.layout == .@"packed") {
1046 switch (strat) {1046 switch (strat) {
1047 .sema => try ty.resolveLayout(mod),1047 .sema => try ty.resolveLayout(pt),
1048 .lazy => if (struct_type.backingIntType(ip).* == .none) return .{1048 .lazy => if (struct_type.backingIntType(ip).* == .none) return .{
1049 .val = Value.fromInterned((try mod.intern(.{ .int = .{1049 .val = Value.fromInterned(try pt.intern(.{ .int = .{
1050 .ty = .comptime_int_type,1050 .ty = .comptime_int_type,
1051 .storage = .{ .lazy_align = ty.toIntern() },1051 .storage = .{ .lazy_align = ty.toIntern() },
1052 } }))),1052 } })),
1053 },1053 },
1054 .eager => {},1054 .eager => {},
1055 }1055 }
1056 return .{ .scalar = Type.fromInterned(struct_type.backingIntType(ip).*).abiAlignment(mod) };1056 return .{ .scalar = Type.fromInterned(struct_type.backingIntType(ip).*).abiAlignment(pt) };
1057 }1057 }
10581058
1059 if (struct_type.flagsPtr(ip).alignment == .none) switch (strat) {1059 if (struct_type.flagsPtr(ip).alignment == .none) switch (strat) {
1060 .eager => unreachable, // struct alignment not resolved1060 .eager => unreachable, // struct alignment not resolved
1061 .sema => try ty.resolveStructAlignment(mod),1061 .sema => try ty.resolveStructAlignment(pt),
1062 .lazy => return .{ .val = Value.fromInterned(try mod.intern(.{ .int = .{1062 .lazy => return .{ .val = Value.fromInterned(try pt.intern(.{ .int = .{
1063 .ty = .comptime_int_type,1063 .ty = .comptime_int_type,
1064 .storage = .{ .lazy_align = ty.toIntern() },1064 .storage = .{ .lazy_align = ty.toIntern() },
1065 } })) },1065 } })) },
...@@ -1071,15 +1071,15 @@ pub fn abiAlignmentAdvanced(...@@ -1071,15 +1071,15 @@ pub fn abiAlignmentAdvanced(
1071 var big_align: Alignment = .@"1";1071 var big_align: Alignment = .@"1";
1072 for (tuple.types.get(ip), tuple.values.get(ip)) |field_ty, val| {1072 for (tuple.types.get(ip), tuple.values.get(ip)) |field_ty, val| {
1073 if (val != .none) continue; // comptime field1073 if (val != .none) continue; // comptime field
1074 switch (try Type.fromInterned(field_ty).abiAlignmentAdvanced(mod, strat)) {1074 switch (try Type.fromInterned(field_ty).abiAlignmentAdvanced(pt, strat)) {
1075 .scalar => |field_align| big_align = big_align.max(field_align),1075 .scalar => |field_align| big_align = big_align.max(field_align),
1076 .val => switch (strat) {1076 .val => switch (strat) {
1077 .eager => unreachable, // field type alignment not resolved1077 .eager => unreachable, // field type alignment not resolved
1078 .sema => unreachable, // passed to abiAlignmentAdvanced above1078 .sema => unreachable, // passed to abiAlignmentAdvanced above
1079 .lazy => return .{ .val = Value.fromInterned((try mod.intern(.{ .int = .{1079 .lazy => return .{ .val = Value.fromInterned(try pt.intern(.{ .int = .{
1080 .ty = .comptime_int_type,1080 .ty = .comptime_int_type,
1081 .storage = .{ .lazy_align = ty.toIntern() },1081 .storage = .{ .lazy_align = ty.toIntern() },
1082 } }))) },1082 } })) },
1083 },1083 },
1084 }1084 }
1085 }1085 }
...@@ -1090,18 +1090,18 @@ pub fn abiAlignmentAdvanced(...@@ -1090,18 +1090,18 @@ pub fn abiAlignmentAdvanced(
10901090
1091 if (union_type.flagsPtr(ip).alignment == .none) switch (strat) {1091 if (union_type.flagsPtr(ip).alignment == .none) switch (strat) {
1092 .eager => unreachable, // union layout not resolved1092 .eager => unreachable, // union layout not resolved
1093 .sema => try ty.resolveUnionAlignment(mod),1093 .sema => try ty.resolveUnionAlignment(pt),
1094 .lazy => return .{ .val = Value.fromInterned((try mod.intern(.{ .int = .{1094 .lazy => return .{ .val = Value.fromInterned(try pt.intern(.{ .int = .{
1095 .ty = .comptime_int_type,1095 .ty = .comptime_int_type,
1096 .storage = .{ .lazy_align = ty.toIntern() },1096 .storage = .{ .lazy_align = ty.toIntern() },
1097 } }))) },1097 } })) },
1098 };1098 };
10991099
1100 return .{ .scalar = union_type.flagsPtr(ip).alignment };1100 return .{ .scalar = union_type.flagsPtr(ip).alignment };
1101 },1101 },
1102 .opaque_type => return .{ .scalar = .@"1" },1102 .opaque_type => return .{ .scalar = .@"1" },
1103 .enum_type => return .{1103 .enum_type => return .{
1104 .scalar = Type.fromInterned(ip.loadEnumType(ty.toIntern()).tag_ty).abiAlignment(mod),1104 .scalar = Type.fromInterned(ip.loadEnumType(ty.toIntern()).tag_ty).abiAlignment(pt),
1105 },1105 },
11061106
1107 // values, not types1107 // values, not types
...@@ -1131,91 +1131,92 @@ pub fn abiAlignmentAdvanced(...@@ -1131,91 +1131,92 @@ pub fn abiAlignmentAdvanced(
11311131
1132fn abiAlignmentAdvancedErrorUnion(1132fn abiAlignmentAdvancedErrorUnion(
1133 ty: Type,1133 ty: Type,
1134 mod: *Module,1134 pt: Zcu.PerThread,
1135 strat: ResolveStratLazy,1135 strat: ResolveStratLazy,
1136 payload_ty: Type,1136 payload_ty: Type,
1137) SemaError!AbiAlignmentAdvanced {1137) SemaError!AbiAlignmentAdvanced {
1138 // This code needs to be kept in sync with the equivalent switch prong1138 // This code needs to be kept in sync with the equivalent switch prong
1139 // in abiSizeAdvanced.1139 // in abiSizeAdvanced.
1140 const code_align = abiAlignment(Type.anyerror, mod);1140 const code_align = Type.anyerror.abiAlignment(pt);
1141 switch (strat) {1141 switch (strat) {
1142 .eager, .sema => {1142 .eager, .sema => {
1143 if (!(payload_ty.hasRuntimeBitsAdvanced(mod, false, strat) catch |err| switch (err) {1143 if (!(payload_ty.hasRuntimeBitsAdvanced(pt, false, strat) catch |err| switch (err) {
1144 error.NeedLazy => return .{ .val = Value.fromInterned((try mod.intern(.{ .int = .{1144 error.NeedLazy => return .{ .val = Value.fromInterned(try pt.intern(.{ .int = .{
1145 .ty = .comptime_int_type,1145 .ty = .comptime_int_type,
1146 .storage = .{ .lazy_align = ty.toIntern() },1146 .storage = .{ .lazy_align = ty.toIntern() },
1147 } }))) },1147 } })) },
1148 else => |e| return e,1148 else => |e| return e,
1149 })) {1149 })) {
1150 return .{ .scalar = code_align };1150 return .{ .scalar = code_align };
1151 }1151 }
1152 return .{ .scalar = code_align.max(1152 return .{ .scalar = code_align.max(
1153 (try payload_ty.abiAlignmentAdvanced(mod, strat)).scalar,1153 (try payload_ty.abiAlignmentAdvanced(pt, strat)).scalar,
1154 ) };1154 ) };
1155 },1155 },
1156 .lazy => {1156 .lazy => {
1157 switch (try payload_ty.abiAlignmentAdvanced(mod, strat)) {1157 switch (try payload_ty.abiAlignmentAdvanced(pt, strat)) {
1158 .scalar => |payload_align| return .{ .scalar = code_align.max(payload_align) },1158 .scalar => |payload_align| return .{ .scalar = code_align.max(payload_align) },
1159 .val => {},1159 .val => {},
1160 }1160 }
1161 return .{ .val = Value.fromInterned((try mod.intern(.{ .int = .{1161 return .{ .val = Value.fromInterned(try pt.intern(.{ .int = .{
1162 .ty = .comptime_int_type,1162 .ty = .comptime_int_type,
1163 .storage = .{ .lazy_align = ty.toIntern() },1163 .storage = .{ .lazy_align = ty.toIntern() },
1164 } }))) };1164 } })) };
1165 },1165 },
1166 }1166 }
1167}1167}
11681168
1169fn abiAlignmentAdvancedOptional(1169fn abiAlignmentAdvancedOptional(
1170 ty: Type,1170 ty: Type,
1171 mod: *Module,1171 pt: Zcu.PerThread,
1172 strat: ResolveStratLazy,1172 strat: ResolveStratLazy,
1173) SemaError!AbiAlignmentAdvanced {1173) SemaError!AbiAlignmentAdvanced {
1174 const mod = pt.zcu;
1174 const target = mod.getTarget();1175 const target = mod.getTarget();
1175 const child_type = ty.optionalChild(mod);1176 const child_type = ty.optionalChild(mod);
11761177
1177 switch (child_type.zigTypeTag(mod)) {1178 switch (child_type.zigTypeTag(mod)) {
1178 .Pointer => return .{ .scalar = ptrAbiAlignment(target) },1179 .Pointer => return .{ .scalar = ptrAbiAlignment(target) },
1179 .ErrorSet => return abiAlignmentAdvanced(Type.anyerror, mod, strat),1180 .ErrorSet => return Type.anyerror.abiAlignmentAdvanced(pt, strat),
1180 .NoReturn => return .{ .scalar = .@"1" },1181 .NoReturn => return .{ .scalar = .@"1" },
1181 else => {},1182 else => {},
1182 }1183 }
11831184
1184 switch (strat) {1185 switch (strat) {
1185 .eager, .sema => {1186 .eager, .sema => {
1186 if (!(child_type.hasRuntimeBitsAdvanced(mod, false, strat) catch |err| switch (err) {1187 if (!(child_type.hasRuntimeBitsAdvanced(pt, false, strat) catch |err| switch (err) {
1187 error.NeedLazy => return .{ .val = Value.fromInterned((try mod.intern(.{ .int = .{1188 error.NeedLazy => return .{ .val = Value.fromInterned(try pt.intern(.{ .int = .{
1188 .ty = .comptime_int_type,1189 .ty = .comptime_int_type,
1189 .storage = .{ .lazy_align = ty.toIntern() },1190 .storage = .{ .lazy_align = ty.toIntern() },
1190 } }))) },1191 } })) },
1191 else => |e| return e,1192 else => |e| return e,
1192 })) {1193 })) {
1193 return .{ .scalar = .@"1" };1194 return .{ .scalar = .@"1" };
1194 }1195 }
1195 return child_type.abiAlignmentAdvanced(mod, strat);1196 return child_type.abiAlignmentAdvanced(pt, strat);
1196 },1197 },
1197 .lazy => switch (try child_type.abiAlignmentAdvanced(mod, strat)) {1198 .lazy => switch (try child_type.abiAlignmentAdvanced(pt, strat)) {
1198 .scalar => |x| return .{ .scalar = x.max(.@"1") },1199 .scalar => |x| return .{ .scalar = x.max(.@"1") },
1199 .val => return .{ .val = Value.fromInterned((try mod.intern(.{ .int = .{1200 .val => return .{ .val = Value.fromInterned(try pt.intern(.{ .int = .{
1200 .ty = .comptime_int_type,1201 .ty = .comptime_int_type,
1201 .storage = .{ .lazy_align = ty.toIntern() },1202 .storage = .{ .lazy_align = ty.toIntern() },
1202 } }))) },1203 } })) },
1203 },1204 },
1204 }1205 }
1205}1206}
12061207
1207/// May capture a reference to `ty`.1208/// May capture a reference to `ty`.
1208pub fn lazyAbiSize(ty: Type, mod: *Module) !Value {1209pub fn lazyAbiSize(ty: Type, pt: Zcu.PerThread) !Value {
1209 switch (try ty.abiSizeAdvanced(mod, .lazy)) {1210 switch (try ty.abiSizeAdvanced(pt, .lazy)) {
1210 .val => |val| return val,1211 .val => |val| return val,
1211 .scalar => |x| return mod.intValue(Type.comptime_int, x),1212 .scalar => |x| return pt.intValue(Type.comptime_int, x),
1212 }1213 }
1213}1214}
12141215
1215/// Asserts the type has the ABI size already resolved.1216/// Asserts the type has the ABI size already resolved.
1216/// Types that return false for hasRuntimeBits() return 0.1217/// Types that return false for hasRuntimeBits() return 0.
1217pub fn abiSize(ty: Type, mod: *Module) u64 {1218pub fn abiSize(ty: Type, pt: Zcu.PerThread) u64 {
1218 return (abiSizeAdvanced(ty, mod, .eager) catch unreachable).scalar;1219 return (abiSizeAdvanced(ty, pt, .eager) catch unreachable).scalar;
1219}1220}
12201221
1221const AbiSizeAdvanced = union(enum) {1222const AbiSizeAdvanced = union(enum) {
...@@ -1231,38 +1232,39 @@ const AbiSizeAdvanced = union(enum) {...@@ -1231,38 +1232,39 @@ const AbiSizeAdvanced = union(enum) {
1231/// necessary, possibly returning a CompileError.1232/// necessary, possibly returning a CompileError.
1232pub fn abiSizeAdvanced(1233pub fn abiSizeAdvanced(
1233 ty: Type,1234 ty: Type,
1234 mod: *Module,1235 pt: Zcu.PerThread,
1235 strat: ResolveStratLazy,1236 strat: ResolveStratLazy,
1236) SemaError!AbiSizeAdvanced {1237) SemaError!AbiSizeAdvanced {
1238 const mod = pt.zcu;
1237 const target = mod.getTarget();1239 const target = mod.getTarget();
1238 const use_llvm = mod.comp.config.use_llvm;1240 const use_llvm = mod.comp.config.use_llvm;
1239 const ip = &mod.intern_pool;1241 const ip = &mod.intern_pool;
12401242
1241 switch (ty.toIntern()) {1243 switch (ty.toIntern()) {
1242 .empty_struct_type => return AbiSizeAdvanced{ .scalar = 0 },1244 .empty_struct_type => return .{ .scalar = 0 },
12431245
1244 else => switch (ip.indexToKey(ty.toIntern())) {1246 else => switch (ip.indexToKey(ty.toIntern())) {
1245 .int_type => |int_type| {1247 .int_type => |int_type| {
1246 if (int_type.bits == 0) return AbiSizeAdvanced{ .scalar = 0 };1248 if (int_type.bits == 0) return .{ .scalar = 0 };
1247 return AbiSizeAdvanced{ .scalar = intAbiSize(int_type.bits, target, use_llvm) };1249 return .{ .scalar = intAbiSize(int_type.bits, target, use_llvm) };
1248 },1250 },
1249 .ptr_type => |ptr_type| switch (ptr_type.flags.size) {1251 .ptr_type => |ptr_type| switch (ptr_type.flags.size) {
1250 .Slice => return .{ .scalar = @divExact(target.ptrBitWidth(), 8) * 2 },1252 .Slice => return .{ .scalar = @divExact(target.ptrBitWidth(), 8) * 2 },
1251 else => return .{ .scalar = @divExact(target.ptrBitWidth(), 8) },1253 else => return .{ .scalar = @divExact(target.ptrBitWidth(), 8) },
1252 },1254 },
1253 .anyframe_type => return AbiSizeAdvanced{ .scalar = @divExact(target.ptrBitWidth(), 8) },1255 .anyframe_type => return .{ .scalar = @divExact(target.ptrBitWidth(), 8) },
12541256
1255 .array_type => |array_type| {1257 .array_type => |array_type| {
1256 const len = array_type.lenIncludingSentinel();1258 const len = array_type.lenIncludingSentinel();
1257 if (len == 0) return .{ .scalar = 0 };1259 if (len == 0) return .{ .scalar = 0 };
1258 switch (try Type.fromInterned(array_type.child).abiSizeAdvanced(mod, strat)) {1260 switch (try Type.fromInterned(array_type.child).abiSizeAdvanced(pt, strat)) {
1259 .scalar => |elem_size| return .{ .scalar = len * elem_size },1261 .scalar => |elem_size| return .{ .scalar = len * elem_size },
1260 .val => switch (strat) {1262 .val => switch (strat) {
1261 .sema, .eager => unreachable,1263 .sema, .eager => unreachable,
1262 .lazy => return .{ .val = Value.fromInterned((try mod.intern(.{ .int = .{1264 .lazy => return .{ .val = Value.fromInterned(try pt.intern(.{ .int = .{
1263 .ty = .comptime_int_type,1265 .ty = .comptime_int_type,
1264 .storage = .{ .lazy_size = ty.toIntern() },1266 .storage = .{ .lazy_size = ty.toIntern() },
1265 } }))) },1267 } })) },
1266 },1268 },
1267 }1269 }
1268 },1270 },
...@@ -1270,71 +1272,71 @@ pub fn abiSizeAdvanced(...@@ -1270,71 +1272,71 @@ pub fn abiSizeAdvanced(
1270 const sub_strat: ResolveStrat = switch (strat) {1272 const sub_strat: ResolveStrat = switch (strat) {
1271 .sema => .sema,1273 .sema => .sema,
1272 .eager => .normal,1274 .eager => .normal,
1273 .lazy => return .{ .val = Value.fromInterned((try mod.intern(.{ .int = .{1275 .lazy => return .{ .val = Value.fromInterned(try pt.intern(.{ .int = .{
1274 .ty = .comptime_int_type,1276 .ty = .comptime_int_type,
1275 .storage = .{ .lazy_size = ty.toIntern() },1277 .storage = .{ .lazy_size = ty.toIntern() },
1276 } }))) },1278 } })) },
1277 };1279 };
1278 const alignment = switch (try ty.abiAlignmentAdvanced(mod, strat)) {1280 const alignment = switch (try ty.abiAlignmentAdvanced(pt, strat)) {
1279 .scalar => |x| x,1281 .scalar => |x| x,
1280 .val => return .{ .val = Value.fromInterned((try mod.intern(.{ .int = .{1282 .val => return .{ .val = Value.fromInterned(try pt.intern(.{ .int = .{
1281 .ty = .comptime_int_type,1283 .ty = .comptime_int_type,
1282 .storage = .{ .lazy_size = ty.toIntern() },1284 .storage = .{ .lazy_size = ty.toIntern() },
1283 } }))) },1285 } })) },
1284 };1286 };
1285 const total_bytes = switch (mod.comp.getZigBackend()) {1287 const total_bytes = switch (mod.comp.getZigBackend()) {
1286 else => total_bytes: {1288 else => total_bytes: {
1287 const elem_bits = try Type.fromInterned(vector_type.child).bitSizeAdvanced(mod, sub_strat);1289 const elem_bits = try Type.fromInterned(vector_type.child).bitSizeAdvanced(pt, sub_strat);
1288 const total_bits = elem_bits * vector_type.len;1290 const total_bits = elem_bits * vector_type.len;
1289 break :total_bytes (total_bits + 7) / 8;1291 break :total_bytes (total_bits + 7) / 8;
1290 },1292 },
1291 .stage2_c => total_bytes: {1293 .stage2_c => total_bytes: {
1292 const elem_bytes: u32 = @intCast((try Type.fromInterned(vector_type.child).abiSizeAdvanced(mod, strat)).scalar);1294 const elem_bytes: u32 = @intCast((try Type.fromInterned(vector_type.child).abiSizeAdvanced(pt, strat)).scalar);
1293 break :total_bytes elem_bytes * vector_type.len;1295 break :total_bytes elem_bytes * vector_type.len;
1294 },1296 },
1295 .stage2_x86_64 => total_bytes: {1297 .stage2_x86_64 => total_bytes: {
1296 if (vector_type.child == .bool_type) break :total_bytes std.math.divCeil(u32, vector_type.len, 8) catch unreachable;1298 if (vector_type.child == .bool_type) break :total_bytes std.math.divCeil(u32, vector_type.len, 8) catch unreachable;
1297 const elem_bytes: u32 = @intCast((try Type.fromInterned(vector_type.child).abiSizeAdvanced(mod, strat)).scalar);1299 const elem_bytes: u32 = @intCast((try Type.fromInterned(vector_type.child).abiSizeAdvanced(pt, strat)).scalar);
1298 break :total_bytes elem_bytes * vector_type.len;1300 break :total_bytes elem_bytes * vector_type.len;
1299 },1301 },
1300 };1302 };
1301 return AbiSizeAdvanced{ .scalar = alignment.forward(total_bytes) };1303 return .{ .scalar = alignment.forward(total_bytes) };
1302 },1304 },
13031305
1304 .opt_type => return ty.abiSizeAdvancedOptional(mod, strat),1306 .opt_type => return ty.abiSizeAdvancedOptional(pt, strat),
13051307
1306 .error_set_type, .inferred_error_set_type => {1308 .error_set_type, .inferred_error_set_type => {
1307 const bits = mod.errorSetBits();1309 const bits = mod.errorSetBits();
1308 if (bits == 0) return AbiSizeAdvanced{ .scalar = 0 };1310 if (bits == 0) return .{ .scalar = 0 };
1309 return AbiSizeAdvanced{ .scalar = intAbiSize(bits, target, use_llvm) };1311 return .{ .scalar = intAbiSize(bits, target, use_llvm) };
1310 },1312 },
13111313
1312 .error_union_type => |error_union_type| {1314 .error_union_type => |error_union_type| {
1313 const payload_ty = Type.fromInterned(error_union_type.payload_type);1315 const payload_ty = Type.fromInterned(error_union_type.payload_type);
1314 // This code needs to be kept in sync with the equivalent switch prong1316 // This code needs to be kept in sync with the equivalent switch prong
1315 // in abiAlignmentAdvanced.1317 // in abiAlignmentAdvanced.
1316 const code_size = abiSize(Type.anyerror, mod);1318 const code_size = Type.anyerror.abiSize(pt);
1317 if (!(payload_ty.hasRuntimeBitsAdvanced(mod, false, strat) catch |err| switch (err) {1319 if (!(payload_ty.hasRuntimeBitsAdvanced(pt, false, strat) catch |err| switch (err) {
1318 error.NeedLazy => return .{ .val = Value.fromInterned((try mod.intern(.{ .int = .{1320 error.NeedLazy => return .{ .val = Value.fromInterned(try pt.intern(.{ .int = .{
1319 .ty = .comptime_int_type,1321 .ty = .comptime_int_type,
1320 .storage = .{ .lazy_size = ty.toIntern() },1322 .storage = .{ .lazy_size = ty.toIntern() },
1321 } }))) },1323 } })) },
1322 else => |e| return e,1324 else => |e| return e,
1323 })) {1325 })) {
1324 // Same as anyerror.1326 // Same as anyerror.
1325 return AbiSizeAdvanced{ .scalar = code_size };1327 return .{ .scalar = code_size };
1326 }1328 }
1327 const code_align = abiAlignment(Type.anyerror, mod);1329 const code_align = Type.anyerror.abiAlignment(pt);
1328 const payload_align = abiAlignment(payload_ty, mod);1330 const payload_align = payload_ty.abiAlignment(pt);
1329 const payload_size = switch (try payload_ty.abiSizeAdvanced(mod, strat)) {1331 const payload_size = switch (try payload_ty.abiSizeAdvanced(pt, strat)) {
1330 .scalar => |elem_size| elem_size,1332 .scalar => |elem_size| elem_size,
1331 .val => switch (strat) {1333 .val => switch (strat) {
1332 .sema => unreachable,1334 .sema => unreachable,
1333 .eager => unreachable,1335 .eager => unreachable,
1334 .lazy => return .{ .val = Value.fromInterned((try mod.intern(.{ .int = .{1336 .lazy => return .{ .val = Value.fromInterned(try pt.intern(.{ .int = .{
1335 .ty = .comptime_int_type,1337 .ty = .comptime_int_type,
1336 .storage = .{ .lazy_size = ty.toIntern() },1338 .storage = .{ .lazy_size = ty.toIntern() },
1337 } }))) },1339 } })) },
1338 },1340 },
1339 };1341 };
13401342
...@@ -1350,7 +1352,7 @@ pub fn abiSizeAdvanced(...@@ -1350,7 +1352,7 @@ pub fn abiSizeAdvanced(
1350 size += code_size;1352 size += code_size;
1351 size = payload_align.forward(size);1353 size = payload_align.forward(size);
1352 }1354 }
1353 return AbiSizeAdvanced{ .scalar = size };1355 return .{ .scalar = size };
1354 },1356 },
1355 .func_type => unreachable, // represents machine code; not a pointer1357 .func_type => unreachable, // represents machine code; not a pointer
1356 .simple_type => |t| switch (t) {1358 .simple_type => |t| switch (t) {
...@@ -1362,34 +1364,31 @@ pub fn abiSizeAdvanced(...@@ -1362,34 +1364,31 @@ pub fn abiSizeAdvanced(
1362 .float_mode,1364 .float_mode,
1363 .reduce_op,1365 .reduce_op,
1364 .call_modifier,1366 .call_modifier,
1365 => return AbiSizeAdvanced{ .scalar = 1 },1367 => return .{ .scalar = 1 },
13661368
1367 .f16 => return AbiSizeAdvanced{ .scalar = 2 },1369 .f16 => return .{ .scalar = 2 },
1368 .f32 => return AbiSizeAdvanced{ .scalar = 4 },1370 .f32 => return .{ .scalar = 4 },
1369 .f64 => return AbiSizeAdvanced{ .scalar = 8 },1371 .f64 => return .{ .scalar = 8 },
1370 .f128 => return AbiSizeAdvanced{ .scalar = 16 },1372 .f128 => return .{ .scalar = 16 },
1371 .f80 => switch (target.c_type_bit_size(.longdouble)) {1373 .f80 => switch (target.c_type_bit_size(.longdouble)) {
1372 80 => return AbiSizeAdvanced{ .scalar = target.c_type_byte_size(.longdouble) },1374 80 => return .{ .scalar = target.c_type_byte_size(.longdouble) },
1373 else => {1375 else => return .{ .scalar = Type.u80.abiSize(pt) },
1374 const u80_ty: Type = .{ .ip_index = .u80_type };
1375 return AbiSizeAdvanced{ .scalar = abiSize(u80_ty, mod) };
1376 },
1377 },1376 },
13781377
1379 .usize,1378 .usize,
1380 .isize,1379 .isize,
1381 => return AbiSizeAdvanced{ .scalar = @divExact(target.ptrBitWidth(), 8) },1380 => return .{ .scalar = @divExact(target.ptrBitWidth(), 8) },
13821381
1383 .c_char => return AbiSizeAdvanced{ .scalar = target.c_type_byte_size(.char) },1382 .c_char => return .{ .scalar = target.c_type_byte_size(.char) },
1384 .c_short => return AbiSizeAdvanced{ .scalar = target.c_type_byte_size(.short) },1383 .c_short => return .{ .scalar = target.c_type_byte_size(.short) },
1385 .c_ushort => return AbiSizeAdvanced{ .scalar = target.c_type_byte_size(.ushort) },1384 .c_ushort => return .{ .scalar = target.c_type_byte_size(.ushort) },
1386 .c_int => return AbiSizeAdvanced{ .scalar = target.c_type_byte_size(.int) },1385 .c_int => return .{ .scalar = target.c_type_byte_size(.int) },
1387 .c_uint => return AbiSizeAdvanced{ .scalar = target.c_type_byte_size(.uint) },1386 .c_uint => return .{ .scalar = target.c_type_byte_size(.uint) },
1388 .c_long => return AbiSizeAdvanced{ .scalar = target.c_type_byte_size(.long) },1387 .c_long => return .{ .scalar = target.c_type_byte_size(.long) },
1389 .c_ulong => return AbiSizeAdvanced{ .scalar = target.c_type_byte_size(.ulong) },1388 .c_ulong => return .{ .scalar = target.c_type_byte_size(.ulong) },
1390 .c_longlong => return AbiSizeAdvanced{ .scalar = target.c_type_byte_size(.longlong) },1389 .c_longlong => return .{ .scalar = target.c_type_byte_size(.longlong) },
1391 .c_ulonglong => return AbiSizeAdvanced{ .scalar = target.c_type_byte_size(.ulonglong) },1390 .c_ulonglong => return .{ .scalar = target.c_type_byte_size(.ulonglong) },
1392 .c_longdouble => return AbiSizeAdvanced{ .scalar = target.c_type_byte_size(.longdouble) },1391 .c_longdouble => return .{ .scalar = target.c_type_byte_size(.longdouble) },
13931392
1394 .anyopaque,1393 .anyopaque,
1395 .void,1394 .void,
...@@ -1399,12 +1398,12 @@ pub fn abiSizeAdvanced(...@@ -1399,12 +1398,12 @@ pub fn abiSizeAdvanced(
1399 .null,1398 .null,
1400 .undefined,1399 .undefined,
1401 .enum_literal,1400 .enum_literal,
1402 => return AbiSizeAdvanced{ .scalar = 0 },1401 => return .{ .scalar = 0 },
14031402
1404 .anyerror, .adhoc_inferred_error_set => {1403 .anyerror, .adhoc_inferred_error_set => {
1405 const bits = mod.errorSetBits();1404 const bits = mod.errorSetBits();
1406 if (bits == 0) return AbiSizeAdvanced{ .scalar = 0 };1405 if (bits == 0) return .{ .scalar = 0 };
1407 return AbiSizeAdvanced{ .scalar = intAbiSize(bits, target, use_llvm) };1406 return .{ .scalar = intAbiSize(bits, target, use_llvm) };
1408 },1407 },
14091408
1410 .prefetch_options => unreachable, // missing call to resolveTypeFields1409 .prefetch_options => unreachable, // missing call to resolveTypeFields
...@@ -1418,22 +1417,22 @@ pub fn abiSizeAdvanced(...@@ -1418,22 +1417,22 @@ pub fn abiSizeAdvanced(
1418 .struct_type => {1417 .struct_type => {
1419 const struct_type = ip.loadStructType(ty.toIntern());1418 const struct_type = ip.loadStructType(ty.toIntern());
1420 switch (strat) {1419 switch (strat) {
1421 .sema => try ty.resolveLayout(mod),1420 .sema => try ty.resolveLayout(pt),
1422 .lazy => switch (struct_type.layout) {1421 .lazy => switch (struct_type.layout) {
1423 .@"packed" => {1422 .@"packed" => {
1424 if (struct_type.backingIntType(ip).* == .none) return .{1423 if (struct_type.backingIntType(ip).* == .none) return .{
1425 .val = Value.fromInterned((try mod.intern(.{ .int = .{1424 .val = Value.fromInterned(try pt.intern(.{ .int = .{
1426 .ty = .comptime_int_type,1425 .ty = .comptime_int_type,
1427 .storage = .{ .lazy_size = ty.toIntern() },1426 .storage = .{ .lazy_size = ty.toIntern() },
1428 } }))),1427 } })),
1429 };1428 };
1430 },1429 },
1431 .auto, .@"extern" => {1430 .auto, .@"extern" => {
1432 if (!struct_type.haveLayout(ip)) return .{1431 if (!struct_type.haveLayout(ip)) return .{
1433 .val = Value.fromInterned((try mod.intern(.{ .int = .{1432 .val = Value.fromInterned(try pt.intern(.{ .int = .{
1434 .ty = .comptime_int_type,1433 .ty = .comptime_int_type,
1435 .storage = .{ .lazy_size = ty.toIntern() },1434 .storage = .{ .lazy_size = ty.toIntern() },
1436 } }))),1435 } })),
1437 };1436 };
1438 },1437 },
1439 },1438 },
...@@ -1441,7 +1440,7 @@ pub fn abiSizeAdvanced(...@@ -1441,7 +1440,7 @@ pub fn abiSizeAdvanced(
1441 }1440 }
1442 switch (struct_type.layout) {1441 switch (struct_type.layout) {
1443 .@"packed" => return .{1442 .@"packed" => return .{
1444 .scalar = Type.fromInterned(struct_type.backingIntType(ip).*).abiSize(mod),1443 .scalar = Type.fromInterned(struct_type.backingIntType(ip).*).abiSize(pt),
1445 },1444 },
1446 .auto, .@"extern" => {1445 .auto, .@"extern" => {
1447 assert(struct_type.haveLayout(ip));1446 assert(struct_type.haveLayout(ip));
...@@ -1451,25 +1450,25 @@ pub fn abiSizeAdvanced(...@@ -1451,25 +1450,25 @@ pub fn abiSizeAdvanced(
1451 },1450 },
1452 .anon_struct_type => |tuple| {1451 .anon_struct_type => |tuple| {
1453 switch (strat) {1452 switch (strat) {
1454 .sema => try ty.resolveLayout(mod),1453 .sema => try ty.resolveLayout(pt),
1455 .lazy, .eager => {},1454 .lazy, .eager => {},
1456 }1455 }
1457 const field_count = tuple.types.len;1456 const field_count = tuple.types.len;
1458 if (field_count == 0) {1457 if (field_count == 0) {
1459 return AbiSizeAdvanced{ .scalar = 0 };1458 return .{ .scalar = 0 };
1460 }1459 }
1461 return AbiSizeAdvanced{ .scalar = ty.structFieldOffset(field_count, mod) };1460 return .{ .scalar = ty.structFieldOffset(field_count, pt) };
1462 },1461 },
14631462
1464 .union_type => {1463 .union_type => {
1465 const union_type = ip.loadUnionType(ty.toIntern());1464 const union_type = ip.loadUnionType(ty.toIntern());
1466 switch (strat) {1465 switch (strat) {
1467 .sema => try ty.resolveLayout(mod),1466 .sema => try ty.resolveLayout(pt),
1468 .lazy => if (!union_type.flagsPtr(ip).status.haveLayout()) return .{1467 .lazy => if (!union_type.flagsPtr(ip).status.haveLayout()) return .{
1469 .val = Value.fromInterned((try mod.intern(.{ .int = .{1468 .val = Value.fromInterned(try pt.intern(.{ .int = .{
1470 .ty = .comptime_int_type,1469 .ty = .comptime_int_type,
1471 .storage = .{ .lazy_size = ty.toIntern() },1470 .storage = .{ .lazy_size = ty.toIntern() },
1472 } }))),1471 } })),
1473 },1472 },
1474 .eager => {},1473 .eager => {},
1475 }1474 }
...@@ -1478,7 +1477,7 @@ pub fn abiSizeAdvanced(...@@ -1478,7 +1477,7 @@ pub fn abiSizeAdvanced(
1478 return .{ .scalar = union_type.size(ip).* };1477 return .{ .scalar = union_type.size(ip).* };
1479 },1478 },
1480 .opaque_type => unreachable, // no size available1479 .opaque_type => unreachable, // no size available
1481 .enum_type => return .{ .scalar = Type.fromInterned(ip.loadEnumType(ty.toIntern()).tag_ty).abiSize(mod) },1480 .enum_type => return .{ .scalar = Type.fromInterned(ip.loadEnumType(ty.toIntern()).tag_ty).abiSize(pt) },
14821481
1483 // values, not types1482 // values, not types
1484 .undef,1483 .undef,
...@@ -1507,36 +1506,37 @@ pub fn abiSizeAdvanced(...@@ -1507,36 +1506,37 @@ pub fn abiSizeAdvanced(
15071506
1508fn abiSizeAdvancedOptional(1507fn abiSizeAdvancedOptional(
1509 ty: Type,1508 ty: Type,
1510 mod: *Module,1509 pt: Zcu.PerThread,
1511 strat: ResolveStratLazy,1510 strat: ResolveStratLazy,
1512) SemaError!AbiSizeAdvanced {1511) SemaError!AbiSizeAdvanced {
1512 const mod = pt.zcu;
1513 const child_ty = ty.optionalChild(mod);1513 const child_ty = ty.optionalChild(mod);
15141514
1515 if (child_ty.isNoReturn(mod)) {1515 if (child_ty.isNoReturn(mod)) {
1516 return AbiSizeAdvanced{ .scalar = 0 };1516 return .{ .scalar = 0 };
1517 }1517 }
15181518
1519 if (!(child_ty.hasRuntimeBitsAdvanced(mod, false, strat) catch |err| switch (err) {1519 if (!(child_ty.hasRuntimeBitsAdvanced(pt, false, strat) catch |err| switch (err) {
1520 error.NeedLazy => return .{ .val = Value.fromInterned((try mod.intern(.{ .int = .{1520 error.NeedLazy => return .{ .val = Value.fromInterned(try pt.intern(.{ .int = .{
1521 .ty = .comptime_int_type,1521 .ty = .comptime_int_type,
1522 .storage = .{ .lazy_size = ty.toIntern() },1522 .storage = .{ .lazy_size = ty.toIntern() },
1523 } }))) },1523 } })) },
1524 else => |e| return e,1524 else => |e| return e,
1525 })) return AbiSizeAdvanced{ .scalar = 1 };1525 })) return .{ .scalar = 1 };
15261526
1527 if (ty.optionalReprIsPayload(mod)) {1527 if (ty.optionalReprIsPayload(mod)) {
1528 return abiSizeAdvanced(child_ty, mod, strat);1528 return child_ty.abiSizeAdvanced(pt, strat);
1529 }1529 }
15301530
1531 const payload_size = switch (try child_ty.abiSizeAdvanced(mod, strat)) {1531 const payload_size = switch (try child_ty.abiSizeAdvanced(pt, strat)) {
1532 .scalar => |elem_size| elem_size,1532 .scalar => |elem_size| elem_size,
1533 .val => switch (strat) {1533 .val => switch (strat) {
1534 .sema => unreachable,1534 .sema => unreachable,
1535 .eager => unreachable,1535 .eager => unreachable,
1536 .lazy => return .{ .val = Value.fromInterned((try mod.intern(.{ .int = .{1536 .lazy => return .{ .val = Value.fromInterned(try pt.intern(.{ .int = .{
1537 .ty = .comptime_int_type,1537 .ty = .comptime_int_type,
1538 .storage = .{ .lazy_size = ty.toIntern() },1538 .storage = .{ .lazy_size = ty.toIntern() },
1539 } }))) },1539 } })) },
1540 },1540 },
1541 };1541 };
15421542
...@@ -1544,8 +1544,8 @@ fn abiSizeAdvancedOptional(...@@ -1544,8 +1544,8 @@ fn abiSizeAdvancedOptional(
1544 // field and a boolean as the second. Since the child type's abi alignment is1544 // field and a boolean as the second. Since the child type's abi alignment is
1545 // guaranteed to be >= that of bool's (1 byte) the added size is exactly equal1545 // guaranteed to be >= that of bool's (1 byte) the added size is exactly equal
1546 // to the child type's ABI alignment.1546 // to the child type's ABI alignment.
1547 return AbiSizeAdvanced{1547 return .{
1548 .scalar = (child_ty.abiAlignment(mod).toByteUnits() orelse 0) + payload_size,1548 .scalar = (child_ty.abiAlignment(pt).toByteUnits() orelse 0) + payload_size,
1549 };1549 };
1550}1550}
15511551
...@@ -1675,15 +1675,16 @@ pub fn maxIntAlignment(target: std.Target, use_llvm: bool) u16 {...@@ -1675,15 +1675,16 @@ pub fn maxIntAlignment(target: std.Target, use_llvm: bool) u16 {
1675 };1675 };
1676}1676}
16771677
1678pub fn bitSize(ty: Type, mod: *Module) u64 {1678pub fn bitSize(ty: Type, pt: Zcu.PerThread) u64 {
1679 return bitSizeAdvanced(ty, mod, .normal) catch unreachable;1679 return bitSizeAdvanced(ty, pt, .normal) catch unreachable;
1680}1680}
16811681
1682pub fn bitSizeAdvanced(1682pub fn bitSizeAdvanced(
1683 ty: Type,1683 ty: Type,
1684 mod: *Module,1684 pt: Zcu.PerThread,
1685 strat: ResolveStrat,1685 strat: ResolveStrat,
1686) SemaError!u64 {1686) SemaError!u64 {
1687 const mod = pt.zcu;
1687 const target = mod.getTarget();1688 const target = mod.getTarget();
1688 const ip = &mod.intern_pool;1689 const ip = &mod.intern_pool;
16891690
...@@ -1702,22 +1703,22 @@ pub fn bitSizeAdvanced(...@@ -1702,22 +1703,22 @@ pub fn bitSizeAdvanced(
1702 if (len == 0) return 0;1703 if (len == 0) return 0;
1703 const elem_ty = Type.fromInterned(array_type.child);1704 const elem_ty = Type.fromInterned(array_type.child);
1704 const elem_size = @max(1705 const elem_size = @max(
1705 (try elem_ty.abiAlignmentAdvanced(mod, strat_lazy)).scalar.toByteUnits() orelse 0,1706 (try elem_ty.abiAlignmentAdvanced(pt, strat_lazy)).scalar.toByteUnits() orelse 0,
1706 (try elem_ty.abiSizeAdvanced(mod, strat_lazy)).scalar,1707 (try elem_ty.abiSizeAdvanced(pt, strat_lazy)).scalar,
1707 );1708 );
1708 if (elem_size == 0) return 0;1709 if (elem_size == 0) return 0;
1709 const elem_bit_size = try bitSizeAdvanced(elem_ty, mod, strat);1710 const elem_bit_size = try elem_ty.bitSizeAdvanced(pt, strat);
1710 return (len - 1) * 8 * elem_size + elem_bit_size;1711 return (len - 1) * 8 * elem_size + elem_bit_size;
1711 },1712 },
1712 .vector_type => |vector_type| {1713 .vector_type => |vector_type| {
1713 const child_ty = Type.fromInterned(vector_type.child);1714 const child_ty = Type.fromInterned(vector_type.child);
1714 const elem_bit_size = try bitSizeAdvanced(child_ty, mod, strat);1715 const elem_bit_size = try child_ty.bitSizeAdvanced(pt, strat);
1715 return elem_bit_size * vector_type.len;1716 return elem_bit_size * vector_type.len;
1716 },1717 },
1717 .opt_type => {1718 .opt_type => {
1718 // Optionals and error unions are not packed so their bitsize1719 // Optionals and error unions are not packed so their bitsize
1719 // includes padding bits.1720 // includes padding bits.
1720 return (try abiSizeAdvanced(ty, mod, strat_lazy)).scalar * 8;1721 return (try ty.abiSizeAdvanced(pt, strat_lazy)).scalar * 8;
1721 },1722 },
17221723
1723 .error_set_type, .inferred_error_set_type => return mod.errorSetBits(),1724 .error_set_type, .inferred_error_set_type => return mod.errorSetBits(),
...@@ -1725,7 +1726,7 @@ pub fn bitSizeAdvanced(...@@ -1725,7 +1726,7 @@ pub fn bitSizeAdvanced(
1725 .error_union_type => {1726 .error_union_type => {
1726 // Optionals and error unions are not packed so their bitsize1727 // Optionals and error unions are not packed so their bitsize
1727 // includes padding bits.1728 // includes padding bits.
1728 return (try abiSizeAdvanced(ty, mod, strat_lazy)).scalar * 8;1729 return (try ty.abiSizeAdvanced(pt, strat_lazy)).scalar * 8;
1729 },1730 },
1730 .func_type => unreachable, // represents machine code; not a pointer1731 .func_type => unreachable, // represents machine code; not a pointer
1731 .simple_type => |t| switch (t) {1732 .simple_type => |t| switch (t) {
...@@ -1783,42 +1784,42 @@ pub fn bitSizeAdvanced(...@@ -1783,42 +1784,42 @@ pub fn bitSizeAdvanced(
1783 const struct_type = ip.loadStructType(ty.toIntern());1784 const struct_type = ip.loadStructType(ty.toIntern());
1784 const is_packed = struct_type.layout == .@"packed";1785 const is_packed = struct_type.layout == .@"packed";
1785 if (strat == .sema) {1786 if (strat == .sema) {
1786 try ty.resolveFields(mod);1787 try ty.resolveFields(pt);
1787 if (is_packed) try ty.resolveLayout(mod);1788 if (is_packed) try ty.resolveLayout(pt);
1788 }1789 }
1789 if (is_packed) {1790 if (is_packed) {
1790 return try Type.fromInterned(struct_type.backingIntType(ip).*).bitSizeAdvanced(mod, strat);1791 return try Type.fromInterned(struct_type.backingIntType(ip).*).bitSizeAdvanced(pt, strat);
1791 }1792 }
1792 return (try ty.abiSizeAdvanced(mod, strat_lazy)).scalar * 8;1793 return (try ty.abiSizeAdvanced(pt, strat_lazy)).scalar * 8;
1793 },1794 },
17941795
1795 .anon_struct_type => {1796 .anon_struct_type => {
1796 if (strat == .sema) try ty.resolveFields(mod);1797 if (strat == .sema) try ty.resolveFields(pt);
1797 return (try ty.abiSizeAdvanced(mod, strat_lazy)).scalar * 8;1798 return (try ty.abiSizeAdvanced(pt, strat_lazy)).scalar * 8;
1798 },1799 },
17991800
1800 .union_type => {1801 .union_type => {
1801 const union_type = ip.loadUnionType(ty.toIntern());1802 const union_type = ip.loadUnionType(ty.toIntern());
1802 const is_packed = ty.containerLayout(mod) == .@"packed";1803 const is_packed = ty.containerLayout(mod) == .@"packed";
1803 if (strat == .sema) {1804 if (strat == .sema) {
1804 try ty.resolveFields(mod);1805 try ty.resolveFields(pt);
1805 if (is_packed) try ty.resolveLayout(mod);1806 if (is_packed) try ty.resolveLayout(pt);
1806 }1807 }
1807 if (!is_packed) {1808 if (!is_packed) {
1808 return (try ty.abiSizeAdvanced(mod, strat_lazy)).scalar * 8;1809 return (try ty.abiSizeAdvanced(pt, strat_lazy)).scalar * 8;
1809 }1810 }
1810 assert(union_type.flagsPtr(ip).status.haveFieldTypes());1811 assert(union_type.flagsPtr(ip).status.haveFieldTypes());
18111812
1812 var size: u64 = 0;1813 var size: u64 = 0;
1813 for (0..union_type.field_types.len) |field_index| {1814 for (0..union_type.field_types.len) |field_index| {
1814 const field_ty = union_type.field_types.get(ip)[field_index];1815 const field_ty = union_type.field_types.get(ip)[field_index];
1815 size = @max(size, try bitSizeAdvanced(Type.fromInterned(field_ty), mod, strat));1816 size = @max(size, try Type.fromInterned(field_ty).bitSizeAdvanced(pt, strat));
1816 }1817 }
18171818
1818 return size;1819 return size;
1819 },1820 },
1820 .opaque_type => unreachable,1821 .opaque_type => unreachable,
1821 .enum_type => return bitSizeAdvanced(Type.fromInterned(ip.loadEnumType(ty.toIntern()).tag_ty), mod, strat),1822 .enum_type => return Type.fromInterned(ip.loadEnumType(ty.toIntern()).tag_ty).bitSizeAdvanced(pt, strat),
18221823
1823 // values, not types1824 // values, not types
1824 .undef,1825 .undef,
...@@ -1870,7 +1871,7 @@ pub fn isSinglePointer(ty: Type, mod: *const Module) bool {...@@ -1870,7 +1871,7 @@ pub fn isSinglePointer(ty: Type, mod: *const Module) bool {
18701871
1871/// Asserts `ty` is a pointer.1872/// Asserts `ty` is a pointer.
1872pub fn ptrSize(ty: Type, mod: *const Module) std.builtin.Type.Pointer.Size {1873pub fn ptrSize(ty: Type, mod: *const Module) std.builtin.Type.Pointer.Size {
1873 return ptrSizeOrNull(ty, mod).?;1874 return ty.ptrSizeOrNull(mod).?;
1874}1875}
18751876
1876/// Returns `null` if `ty` is not a pointer.1877/// Returns `null` if `ty` is not a pointer.
...@@ -2105,29 +2106,28 @@ pub fn unionTagFieldIndex(ty: Type, enum_tag: Value, mod: *Module) ?u32 {...@@ -2105,29 +2106,28 @@ pub fn unionTagFieldIndex(ty: Type, enum_tag: Value, mod: *Module) ?u32 {
2105 return mod.unionTagFieldIndex(union_obj, enum_tag);2106 return mod.unionTagFieldIndex(union_obj, enum_tag);
2106}2107}
21072108
2108pub fn unionHasAllZeroBitFieldTypes(ty: Type, mod: *Module) bool {2109pub fn unionHasAllZeroBitFieldTypes(ty: Type, pt: Zcu.PerThread) bool {
2109 const ip = &mod.intern_pool;2110 const ip = &pt.zcu.intern_pool;
2110 const union_obj = mod.typeToUnion(ty).?;2111 const union_obj = pt.zcu.typeToUnion(ty).?;
2111 for (union_obj.field_types.get(ip)) |field_ty| {2112 for (union_obj.field_types.get(ip)) |field_ty| {
2112 if (Type.fromInterned(field_ty).hasRuntimeBits(mod)) return false;2113 if (Type.fromInterned(field_ty).hasRuntimeBits(pt)) return false;
2113 }2114 }
2114 return true;2115 return true;
2115}2116}
21162117
2117/// Returns the type used for backing storage of this union during comptime operations.2118/// Returns the type used for backing storage of this union during comptime operations.
2118/// Asserts the type is either an extern or packed union.2119/// Asserts the type is either an extern or packed union.
2119pub fn unionBackingType(ty: Type, mod: *Module) !Type {2120pub fn unionBackingType(ty: Type, pt: Zcu.PerThread) !Type {
2120 return switch (ty.containerLayout(mod)) {2121 return switch (ty.containerLayout(pt.zcu)) {
2121 .@"extern" => try mod.arrayType(.{ .len = ty.abiSize(mod), .child = .u8_type }),2122 .@"extern" => try pt.arrayType(.{ .len = ty.abiSize(pt), .child = .u8_type }),
2122 .@"packed" => try mod.intType(.unsigned, @intCast(ty.bitSize(mod))),2123 .@"packed" => try pt.intType(.unsigned, @intCast(ty.bitSize(pt))),
2123 .auto => unreachable,2124 .auto => unreachable,
2124 };2125 };
2125}2126}
21262127
2127pub fn unionGetLayout(ty: Type, mod: *Module) Module.UnionLayout {2128pub fn unionGetLayout(ty: Type, pt: Zcu.PerThread) Module.UnionLayout {
2128 const ip = &mod.intern_pool;2129 const union_obj = pt.zcu.intern_pool.loadUnionType(ty.toIntern());
2129 const union_obj = ip.loadUnionType(ty.toIntern());2130 return pt.getUnionLayout(union_obj);
2130 return mod.getUnionLayout(union_obj);
2131}2131}
21322132
2133pub fn containerLayout(ty: Type, mod: *Module) std.builtin.Type.ContainerLayout {2133pub fn containerLayout(ty: Type, mod: *Module) std.builtin.Type.ContainerLayout {
...@@ -2509,7 +2509,8 @@ pub fn isNumeric(ty: Type, mod: *const Module) bool {...@@ -2509,7 +2509,8 @@ pub fn isNumeric(ty: Type, mod: *const Module) bool {
25092509
2510/// During semantic analysis, instead call `Sema.typeHasOnePossibleValue` which2510/// During semantic analysis, instead call `Sema.typeHasOnePossibleValue` which
2511/// resolves field types rather than asserting they are already resolved.2511/// resolves field types rather than asserting they are already resolved.
2512pub fn onePossibleValue(starting_type: Type, mod: *Module) !?Value {2512pub fn onePossibleValue(starting_type: Type, pt: Zcu.PerThread) !?Value {
2513 const mod = pt.zcu;
2513 var ty = starting_type;2514 var ty = starting_type;
2514 const ip = &mod.intern_pool;2515 const ip = &mod.intern_pool;
2515 while (true) switch (ty.toIntern()) {2516 while (true) switch (ty.toIntern()) {
...@@ -2518,7 +2519,7 @@ pub fn onePossibleValue(starting_type: Type, mod: *Module) !?Value {...@@ -2518,7 +2519,7 @@ pub fn onePossibleValue(starting_type: Type, mod: *Module) !?Value {
2518 else => switch (ip.indexToKey(ty.toIntern())) {2519 else => switch (ip.indexToKey(ty.toIntern())) {
2519 .int_type => |int_type| {2520 .int_type => |int_type| {
2520 if (int_type.bits == 0) {2521 if (int_type.bits == 0) {
2521 return try mod.intValue(ty, 0);2522 return try pt.intValue(ty, 0);
2522 } else {2523 } else {
2523 return null;2524 return null;
2524 }2525 }
...@@ -2534,21 +2535,21 @@ pub fn onePossibleValue(starting_type: Type, mod: *Module) !?Value {...@@ -2534,21 +2535,21 @@ pub fn onePossibleValue(starting_type: Type, mod: *Module) !?Value {
25342535
2535 inline .array_type, .vector_type => |seq_type, seq_tag| {2536 inline .array_type, .vector_type => |seq_type, seq_tag| {
2536 const has_sentinel = seq_tag == .array_type and seq_type.sentinel != .none;2537 const has_sentinel = seq_tag == .array_type and seq_type.sentinel != .none;
2537 if (seq_type.len + @intFromBool(has_sentinel) == 0) return Value.fromInterned((try mod.intern(.{ .aggregate = .{2538 if (seq_type.len + @intFromBool(has_sentinel) == 0) return Value.fromInterned(try pt.intern(.{ .aggregate = .{
2538 .ty = ty.toIntern(),2539 .ty = ty.toIntern(),
2539 .storage = .{ .elems = &.{} },2540 .storage = .{ .elems = &.{} },
2540 } })));2541 } }));
2541 if (try Type.fromInterned(seq_type.child).onePossibleValue(mod)) |opv| {2542 if (try Type.fromInterned(seq_type.child).onePossibleValue(pt)) |opv| {
2542 return Value.fromInterned((try mod.intern(.{ .aggregate = .{2543 return Value.fromInterned(try pt.intern(.{ .aggregate = .{
2543 .ty = ty.toIntern(),2544 .ty = ty.toIntern(),
2544 .storage = .{ .repeated_elem = opv.toIntern() },2545 .storage = .{ .repeated_elem = opv.toIntern() },
2545 } })));2546 } }));
2546 }2547 }
2547 return null;2548 return null;
2548 },2549 },
2549 .opt_type => |child| {2550 .opt_type => |child| {
2550 if (child == .noreturn_type) {2551 if (child == .noreturn_type) {
2551 return try mod.nullValue(ty);2552 return try pt.nullValue(ty);
2552 } else {2553 } else {
2553 return null;2554 return null;
2554 }2555 }
...@@ -2615,17 +2616,17 @@ pub fn onePossibleValue(starting_type: Type, mod: *Module) !?Value {...@@ -2615,17 +2616,17 @@ pub fn onePossibleValue(starting_type: Type, mod: *Module) !?Value {
2615 continue;2616 continue;
2616 }2617 }
2617 const field_ty = Type.fromInterned(struct_type.field_types.get(ip)[i]);2618 const field_ty = Type.fromInterned(struct_type.field_types.get(ip)[i]);
2618 if (try field_ty.onePossibleValue(mod)) |field_opv| {2619 if (try field_ty.onePossibleValue(pt)) |field_opv| {
2619 field_val.* = field_opv.toIntern();2620 field_val.* = field_opv.toIntern();
2620 } else return null;2621 } else return null;
2621 }2622 }
26222623
2623 // In this case the struct has no runtime-known fields and2624 // In this case the struct has no runtime-known fields and
2624 // therefore has one possible value.2625 // therefore has one possible value.
2625 return Value.fromInterned((try mod.intern(.{ .aggregate = .{2626 return Value.fromInterned(try pt.intern(.{ .aggregate = .{
2626 .ty = ty.toIntern(),2627 .ty = ty.toIntern(),
2627 .storage = .{ .elems = field_vals },2628 .storage = .{ .elems = field_vals },
2628 } })));2629 } }));
2629 },2630 },
26302631
2631 .anon_struct_type => |tuple| {2632 .anon_struct_type => |tuple| {
...@@ -2637,24 +2638,24 @@ pub fn onePossibleValue(starting_type: Type, mod: *Module) !?Value {...@@ -2637,24 +2638,24 @@ pub fn onePossibleValue(starting_type: Type, mod: *Module) !?Value {
2637 // TODO: write something like getCoercedInts to avoid needing to dupe2638 // TODO: write something like getCoercedInts to avoid needing to dupe
2638 const duped_values = try mod.gpa.dupe(InternPool.Index, tuple.values.get(ip));2639 const duped_values = try mod.gpa.dupe(InternPool.Index, tuple.values.get(ip));
2639 defer mod.gpa.free(duped_values);2640 defer mod.gpa.free(duped_values);
2640 return Value.fromInterned((try mod.intern(.{ .aggregate = .{2641 return Value.fromInterned(try pt.intern(.{ .aggregate = .{
2641 .ty = ty.toIntern(),2642 .ty = ty.toIntern(),
2642 .storage = .{ .elems = duped_values },2643 .storage = .{ .elems = duped_values },
2643 } })));2644 } }));
2644 },2645 },
26452646
2646 .union_type => {2647 .union_type => {
2647 const union_obj = ip.loadUnionType(ty.toIntern());2648 const union_obj = ip.loadUnionType(ty.toIntern());
2648 const tag_val = (try Type.fromInterned(union_obj.enum_tag_ty).onePossibleValue(mod)) orelse2649 const tag_val = (try Type.fromInterned(union_obj.enum_tag_ty).onePossibleValue(pt)) orelse
2649 return null;2650 return null;
2650 if (union_obj.field_types.len == 0) {2651 if (union_obj.field_types.len == 0) {
2651 const only = try mod.intern(.{ .empty_enum_value = ty.toIntern() });2652 const only = try pt.intern(.{ .empty_enum_value = ty.toIntern() });
2652 return Value.fromInterned(only);2653 return Value.fromInterned(only);
2653 }2654 }
2654 const only_field_ty = union_obj.field_types.get(ip)[0];2655 const only_field_ty = union_obj.field_types.get(ip)[0];
2655 const val_val = (try Type.fromInterned(only_field_ty).onePossibleValue(mod)) orelse2656 const val_val = (try Type.fromInterned(only_field_ty).onePossibleValue(pt)) orelse
2656 return null;2657 return null;
2657 const only = try mod.intern(.{ .un = .{2658 const only = try pt.intern(.{ .un = .{
2658 .ty = ty.toIntern(),2659 .ty = ty.toIntern(),
2659 .tag = tag_val.toIntern(),2660 .tag = tag_val.toIntern(),
2660 .val = val_val.toIntern(),2661 .val = val_val.toIntern(),
...@@ -2668,8 +2669,8 @@ pub fn onePossibleValue(starting_type: Type, mod: *Module) !?Value {...@@ -2668,8 +2669,8 @@ pub fn onePossibleValue(starting_type: Type, mod: *Module) !?Value {
2668 .nonexhaustive => {2669 .nonexhaustive => {
2669 if (enum_type.tag_ty == .comptime_int_type) return null;2670 if (enum_type.tag_ty == .comptime_int_type) return null;
26702671
2671 if (try Type.fromInterned(enum_type.tag_ty).onePossibleValue(mod)) |int_opv| {2672 if (try Type.fromInterned(enum_type.tag_ty).onePossibleValue(pt)) |int_opv| {
2672 const only = try mod.intern(.{ .enum_tag = .{2673 const only = try pt.intern(.{ .enum_tag = .{
2673 .ty = ty.toIntern(),2674 .ty = ty.toIntern(),
2674 .int = int_opv.toIntern(),2675 .int = int_opv.toIntern(),
2675 } });2676 } });
...@@ -2679,18 +2680,18 @@ pub fn onePossibleValue(starting_type: Type, mod: *Module) !?Value {...@@ -2679,18 +2680,18 @@ pub fn onePossibleValue(starting_type: Type, mod: *Module) !?Value {
2679 return null;2680 return null;
2680 },2681 },
2681 .auto, .explicit => {2682 .auto, .explicit => {
2682 if (Type.fromInterned(enum_type.tag_ty).hasRuntimeBits(mod)) return null;2683 if (Type.fromInterned(enum_type.tag_ty).hasRuntimeBits(pt)) return null;
26832684
2684 switch (enum_type.names.len) {2685 switch (enum_type.names.len) {
2685 0 => {2686 0 => {
2686 const only = try mod.intern(.{ .empty_enum_value = ty.toIntern() });2687 const only = try pt.intern(.{ .empty_enum_value = ty.toIntern() });
2687 return Value.fromInterned(only);2688 return Value.fromInterned(only);
2688 },2689 },
2689 1 => {2690 1 => {
2690 if (enum_type.values.len == 0) {2691 if (enum_type.values.len == 0) {
2691 const only = try mod.intern(.{ .enum_tag = .{2692 const only = try pt.intern(.{ .enum_tag = .{
2692 .ty = ty.toIntern(),2693 .ty = ty.toIntern(),
2693 .int = try mod.intern(.{ .int = .{2694 .int = try pt.intern(.{ .int = .{
2694 .ty = enum_type.tag_ty,2695 .ty = enum_type.tag_ty,
2695 .storage = .{ .u64 = 0 },2696 .storage = .{ .u64 = 0 },
2696 } }),2697 } }),
...@@ -2733,13 +2734,14 @@ pub fn onePossibleValue(starting_type: Type, mod: *Module) !?Value {...@@ -2733,13 +2734,14 @@ pub fn onePossibleValue(starting_type: Type, mod: *Module) !?Value {
27332734
2734/// During semantic analysis, instead call `Sema.typeRequiresComptime` which2735/// During semantic analysis, instead call `Sema.typeRequiresComptime` which
2735/// resolves field types rather than asserting they are already resolved.2736/// resolves field types rather than asserting they are already resolved.
2736pub fn comptimeOnly(ty: Type, mod: *Module) bool {2737pub fn comptimeOnly(ty: Type, pt: Zcu.PerThread) bool {
2737 return ty.comptimeOnlyAdvanced(mod, .normal) catch unreachable;2738 return ty.comptimeOnlyAdvanced(pt, .normal) catch unreachable;
2738}2739}
27392740
2740/// `generic_poison` will return false.2741/// `generic_poison` will return false.
2741/// May return false negatives when structs and unions are having their field types resolved.2742/// May return false negatives when structs and unions are having their field types resolved.
2742pub fn comptimeOnlyAdvanced(ty: Type, mod: *Module, strat: ResolveStrat) SemaError!bool {2743pub fn comptimeOnlyAdvanced(ty: Type, pt: Zcu.PerThread, strat: ResolveStrat) SemaError!bool {
2744 const mod = pt.zcu;
2743 const ip = &mod.intern_pool;2745 const ip = &mod.intern_pool;
2744 return switch (ty.toIntern()) {2746 return switch (ty.toIntern()) {
2745 .empty_struct_type => false,2747 .empty_struct_type => false,
...@@ -2749,19 +2751,19 @@ pub fn comptimeOnlyAdvanced(ty: Type, mod: *Module, strat: ResolveStrat) SemaErr...@@ -2749,19 +2751,19 @@ pub fn comptimeOnlyAdvanced(ty: Type, mod: *Module, strat: ResolveStrat) SemaErr
2749 .ptr_type => |ptr_type| {2751 .ptr_type => |ptr_type| {
2750 const child_ty = Type.fromInterned(ptr_type.child);2752 const child_ty = Type.fromInterned(ptr_type.child);
2751 switch (child_ty.zigTypeTag(mod)) {2753 switch (child_ty.zigTypeTag(mod)) {
2752 .Fn => return !try child_ty.fnHasRuntimeBitsAdvanced(mod, strat),2754 .Fn => return !try child_ty.fnHasRuntimeBitsAdvanced(pt, strat),
2753 .Opaque => return false,2755 .Opaque => return false,
2754 else => return child_ty.comptimeOnlyAdvanced(mod, strat),2756 else => return child_ty.comptimeOnlyAdvanced(pt, strat),
2755 }2757 }
2756 },2758 },
2757 .anyframe_type => |child| {2759 .anyframe_type => |child| {
2758 if (child == .none) return false;2760 if (child == .none) return false;
2759 return Type.fromInterned(child).comptimeOnlyAdvanced(mod, strat);2761 return Type.fromInterned(child).comptimeOnlyAdvanced(pt, strat);
2760 },2762 },
2761 .array_type => |array_type| return Type.fromInterned(array_type.child).comptimeOnlyAdvanced(mod, strat),2763 .array_type => |array_type| return Type.fromInterned(array_type.child).comptimeOnlyAdvanced(pt, strat),
2762 .vector_type => |vector_type| return Type.fromInterned(vector_type.child).comptimeOnlyAdvanced(mod, strat),2764 .vector_type => |vector_type| return Type.fromInterned(vector_type.child).comptimeOnlyAdvanced(pt, strat),
2763 .opt_type => |child| return Type.fromInterned(child).comptimeOnlyAdvanced(mod, strat),2765 .opt_type => |child| return Type.fromInterned(child).comptimeOnlyAdvanced(pt, strat),
2764 .error_union_type => |error_union_type| return Type.fromInterned(error_union_type.payload_type).comptimeOnlyAdvanced(mod, strat),2766 .error_union_type => |error_union_type| return Type.fromInterned(error_union_type.payload_type).comptimeOnlyAdvanced(pt, strat),
27652767
2766 .error_set_type,2768 .error_set_type,
2767 .inferred_error_set_type,2769 .inferred_error_set_type,
...@@ -2836,13 +2838,13 @@ pub fn comptimeOnlyAdvanced(ty: Type, mod: *Module, strat: ResolveStrat) SemaErr...@@ -2836,13 +2838,13 @@ pub fn comptimeOnlyAdvanced(ty: Type, mod: *Module, strat: ResolveStrat) SemaErr
2836 struct_type.flagsPtr(ip).requires_comptime = .wip;2838 struct_type.flagsPtr(ip).requires_comptime = .wip;
2837 errdefer struct_type.flagsPtr(ip).requires_comptime = .unknown;2839 errdefer struct_type.flagsPtr(ip).requires_comptime = .unknown;
28382840
2839 try ty.resolveFields(mod);2841 try ty.resolveFields(pt);
28402842
2841 for (0..struct_type.field_types.len) |i_usize| {2843 for (0..struct_type.field_types.len) |i_usize| {
2842 const i: u32 = @intCast(i_usize);2844 const i: u32 = @intCast(i_usize);
2843 if (struct_type.fieldIsComptime(ip, i)) continue;2845 if (struct_type.fieldIsComptime(ip, i)) continue;
2844 const field_ty = struct_type.field_types.get(ip)[i];2846 const field_ty = struct_type.field_types.get(ip)[i];
2845 if (try Type.fromInterned(field_ty).comptimeOnlyAdvanced(mod, strat)) {2847 if (try Type.fromInterned(field_ty).comptimeOnlyAdvanced(pt, strat)) {
2846 // Note that this does not cause the layout to2848 // Note that this does not cause the layout to
2847 // be considered resolved. Comptime-only types2849 // be considered resolved. Comptime-only types
2848 // still maintain a layout of their2850 // still maintain a layout of their
...@@ -2861,7 +2863,7 @@ pub fn comptimeOnlyAdvanced(ty: Type, mod: *Module, strat: ResolveStrat) SemaErr...@@ -2861,7 +2863,7 @@ pub fn comptimeOnlyAdvanced(ty: Type, mod: *Module, strat: ResolveStrat) SemaErr
2861 .anon_struct_type => |tuple| {2863 .anon_struct_type => |tuple| {
2862 for (tuple.types.get(ip), tuple.values.get(ip)) |field_ty, val| {2864 for (tuple.types.get(ip), tuple.values.get(ip)) |field_ty, val| {
2863 const have_comptime_val = val != .none;2865 const have_comptime_val = val != .none;
2864 if (!have_comptime_val and try Type.fromInterned(field_ty).comptimeOnlyAdvanced(mod, strat)) return true;2866 if (!have_comptime_val and try Type.fromInterned(field_ty).comptimeOnlyAdvanced(pt, strat)) return true;
2865 }2867 }
2866 return false;2868 return false;
2867 },2869 },
...@@ -2880,11 +2882,11 @@ pub fn comptimeOnlyAdvanced(ty: Type, mod: *Module, strat: ResolveStrat) SemaErr...@@ -2880,11 +2882,11 @@ pub fn comptimeOnlyAdvanced(ty: Type, mod: *Module, strat: ResolveStrat) SemaErr
2880 union_type.flagsPtr(ip).requires_comptime = .wip;2882 union_type.flagsPtr(ip).requires_comptime = .wip;
2881 errdefer union_type.flagsPtr(ip).requires_comptime = .unknown;2883 errdefer union_type.flagsPtr(ip).requires_comptime = .unknown;
28822884
2883 try ty.resolveFields(mod);2885 try ty.resolveFields(pt);
28842886
2885 for (0..union_type.field_types.len) |field_idx| {2887 for (0..union_type.field_types.len) |field_idx| {
2886 const field_ty = union_type.field_types.get(ip)[field_idx];2888 const field_ty = union_type.field_types.get(ip)[field_idx];
2887 if (try Type.fromInterned(field_ty).comptimeOnlyAdvanced(mod, strat)) {2889 if (try Type.fromInterned(field_ty).comptimeOnlyAdvanced(pt, strat)) {
2888 union_type.flagsPtr(ip).requires_comptime = .yes;2890 union_type.flagsPtr(ip).requires_comptime = .yes;
2889 return true;2891 return true;
2890 }2892 }
...@@ -2898,7 +2900,7 @@ pub fn comptimeOnlyAdvanced(ty: Type, mod: *Module, strat: ResolveStrat) SemaErr...@@ -2898,7 +2900,7 @@ pub fn comptimeOnlyAdvanced(ty: Type, mod: *Module, strat: ResolveStrat) SemaErr
28982900
2899 .opaque_type => false,2901 .opaque_type => false,
29002902
2901 .enum_type => return Type.fromInterned(ip.loadEnumType(ty.toIntern()).tag_ty).comptimeOnlyAdvanced(mod, strat),2903 .enum_type => return Type.fromInterned(ip.loadEnumType(ty.toIntern()).tag_ty).comptimeOnlyAdvanced(pt, strat),
29022904
2903 // values, not types2905 // values, not types
2904 .undef,2906 .undef,
...@@ -2930,10 +2932,10 @@ pub fn isVector(ty: Type, mod: *const Module) bool {...@@ -2930,10 +2932,10 @@ pub fn isVector(ty: Type, mod: *const Module) bool {
2930}2932}
29312933
2932/// Returns 0 if not a vector, otherwise returns @bitSizeOf(Element) * vector_len.2934/// Returns 0 if not a vector, otherwise returns @bitSizeOf(Element) * vector_len.
2933pub fn totalVectorBits(ty: Type, zcu: *Zcu) u64 {2935pub fn totalVectorBits(ty: Type, pt: Zcu.PerThread) u64 {
2934 if (!ty.isVector(zcu)) return 0;2936 if (!ty.isVector(pt.zcu)) return 0;
2935 const v = zcu.intern_pool.indexToKey(ty.toIntern()).vector_type;2937 const v = pt.zcu.intern_pool.indexToKey(ty.toIntern()).vector_type;
2936 return v.len * Type.fromInterned(v.child).bitSize(zcu);2938 return v.len * Type.fromInterned(v.child).bitSize(pt);
2937}2939}
29382940
2939pub fn isArrayOrVector(ty: Type, mod: *const Module) bool {2941pub fn isArrayOrVector(ty: Type, mod: *const Module) bool {
...@@ -3013,23 +3015,25 @@ pub fn getNamespace(ty: Type, zcu: *Zcu) ?InternPool.OptionalNamespaceIndex {...@@ -3013,23 +3015,25 @@ pub fn getNamespace(ty: Type, zcu: *Zcu) ?InternPool.OptionalNamespaceIndex {
3013}3015}
30143016
3015// Works for vectors and vectors of integers.3017// Works for vectors and vectors of integers.
3016pub fn minInt(ty: Type, mod: *Module, dest_ty: Type) !Value {3018pub fn minInt(ty: Type, pt: Zcu.PerThread, dest_ty: Type) !Value {
3017 const scalar = try minIntScalar(ty.scalarType(mod), mod, dest_ty.scalarType(mod));3019 const mod = pt.zcu;
3018 return if (ty.zigTypeTag(mod) == .Vector) Value.fromInterned((try mod.intern(.{ .aggregate = .{3020 const scalar = try minIntScalar(ty.scalarType(mod), pt, dest_ty.scalarType(mod));
3021 return if (ty.zigTypeTag(mod) == .Vector) Value.fromInterned(try pt.intern(.{ .aggregate = .{
3019 .ty = dest_ty.toIntern(),3022 .ty = dest_ty.toIntern(),
3020 .storage = .{ .repeated_elem = scalar.toIntern() },3023 .storage = .{ .repeated_elem = scalar.toIntern() },
3021 } }))) else scalar;3024 } })) else scalar;
3022}3025}
30233026
3024/// Asserts that the type is an integer.3027/// Asserts that the type is an integer.
3025pub fn minIntScalar(ty: Type, mod: *Module, dest_ty: Type) !Value {3028pub fn minIntScalar(ty: Type, pt: Zcu.PerThread, dest_ty: Type) !Value {
3029 const mod = pt.zcu;
3026 const info = ty.intInfo(mod);3030 const info = ty.intInfo(mod);
3027 if (info.signedness == .unsigned) return mod.intValue(dest_ty, 0);3031 if (info.signedness == .unsigned) return pt.intValue(dest_ty, 0);
3028 if (info.bits == 0) return mod.intValue(dest_ty, -1);3032 if (info.bits == 0) return pt.intValue(dest_ty, -1);
30293033
3030 if (std.math.cast(u6, info.bits - 1)) |shift| {3034 if (std.math.cast(u6, info.bits - 1)) |shift| {
3031 const n = @as(i64, std.math.minInt(i64)) >> (63 - shift);3035 const n = @as(i64, std.math.minInt(i64)) >> (63 - shift);
3032 return mod.intValue(dest_ty, n);3036 return pt.intValue(dest_ty, n);
3033 }3037 }
30343038
3035 var res = try std.math.big.int.Managed.init(mod.gpa);3039 var res = try std.math.big.int.Managed.init(mod.gpa);
...@@ -3037,31 +3041,32 @@ pub fn minIntScalar(ty: Type, mod: *Module, dest_ty: Type) !Value {...@@ -3037,31 +3041,32 @@ pub fn minIntScalar(ty: Type, mod: *Module, dest_ty: Type) !Value {
30373041
3038 try res.setTwosCompIntLimit(.min, info.signedness, info.bits);3042 try res.setTwosCompIntLimit(.min, info.signedness, info.bits);
30393043
3040 return mod.intValue_big(dest_ty, res.toConst());3044 return pt.intValue_big(dest_ty, res.toConst());
3041}3045}
30423046
3043// Works for vectors and vectors of integers.3047// Works for vectors and vectors of integers.
3044/// The returned Value will have type dest_ty.3048/// The returned Value will have type dest_ty.
3045pub fn maxInt(ty: Type, mod: *Module, dest_ty: Type) !Value {3049pub fn maxInt(ty: Type, pt: Zcu.PerThread, dest_ty: Type) !Value {
3046 const scalar = try maxIntScalar(ty.scalarType(mod), mod, dest_ty.scalarType(mod));3050 const mod = pt.zcu;
3047 return if (ty.zigTypeTag(mod) == .Vector) Value.fromInterned((try mod.intern(.{ .aggregate = .{3051 const scalar = try maxIntScalar(ty.scalarType(mod), pt, dest_ty.scalarType(mod));
3052 return if (ty.zigTypeTag(mod) == .Vector) Value.fromInterned(try pt.intern(.{ .aggregate = .{
3048 .ty = dest_ty.toIntern(),3053 .ty = dest_ty.toIntern(),
3049 .storage = .{ .repeated_elem = scalar.toIntern() },3054 .storage = .{ .repeated_elem = scalar.toIntern() },
3050 } }))) else scalar;3055 } })) else scalar;
3051}3056}
30523057
3053/// The returned Value will have type dest_ty.3058/// The returned Value will have type dest_ty.
3054pub fn maxIntScalar(ty: Type, mod: *Module, dest_ty: Type) !Value {3059pub fn maxIntScalar(ty: Type, pt: Zcu.PerThread, dest_ty: Type) !Value {
3055 const info = ty.intInfo(mod);3060 const info = ty.intInfo(pt.zcu);
30563061
3057 switch (info.bits) {3062 switch (info.bits) {
3058 0 => return switch (info.signedness) {3063 0 => return switch (info.signedness) {
3059 .signed => try mod.intValue(dest_ty, -1),3064 .signed => try pt.intValue(dest_ty, -1),
3060 .unsigned => try mod.intValue(dest_ty, 0),3065 .unsigned => try pt.intValue(dest_ty, 0),
3061 },3066 },
3062 1 => return switch (info.signedness) {3067 1 => return switch (info.signedness) {
3063 .signed => try mod.intValue(dest_ty, 0),3068 .signed => try pt.intValue(dest_ty, 0),
3064 .unsigned => try mod.intValue(dest_ty, 1),3069 .unsigned => try pt.intValue(dest_ty, 1),
3065 },3070 },
3066 else => {},3071 else => {},
3067 }3072 }
...@@ -3069,20 +3074,20 @@ pub fn maxIntScalar(ty: Type, mod: *Module, dest_ty: Type) !Value {...@@ -3069,20 +3074,20 @@ pub fn maxIntScalar(ty: Type, mod: *Module, dest_ty: Type) !Value {
3069 if (std.math.cast(u6, info.bits - 1)) |shift| switch (info.signedness) {3074 if (std.math.cast(u6, info.bits - 1)) |shift| switch (info.signedness) {
3070 .signed => {3075 .signed => {
3071 const n = @as(i64, std.math.maxInt(i64)) >> (63 - shift);3076 const n = @as(i64, std.math.maxInt(i64)) >> (63 - shift);
3072 return mod.intValue(dest_ty, n);3077 return pt.intValue(dest_ty, n);
3073 },3078 },
3074 .unsigned => {3079 .unsigned => {
3075 const n = @as(u64, std.math.maxInt(u64)) >> (63 - shift);3080 const n = @as(u64, std.math.maxInt(u64)) >> (63 - shift);
3076 return mod.intValue(dest_ty, n);3081 return pt.intValue(dest_ty, n);
3077 },3082 },
3078 };3083 };
30793084
3080 var res = try std.math.big.int.Managed.init(mod.gpa);3085 var res = try std.math.big.int.Managed.init(pt.zcu.gpa);
3081 defer res.deinit();3086 defer res.deinit();
30823087
3083 try res.setTwosCompIntLimit(.max, info.signedness, info.bits);3088 try res.setTwosCompIntLimit(.max, info.signedness, info.bits);
30843089
3085 return mod.intValue_big(dest_ty, res.toConst());3090 return pt.intValue_big(dest_ty, res.toConst());
3086}3091}
30873092
3088/// Asserts the type is an enum or a union.3093/// Asserts the type is an enum or a union.
...@@ -3188,26 +3193,26 @@ pub fn structFieldType(ty: Type, index: usize, mod: *Module) Type {...@@ -3188,26 +3193,26 @@ pub fn structFieldType(ty: Type, index: usize, mod: *Module) Type {
3188 };3193 };
3189}3194}
31903195
3191pub fn structFieldAlign(ty: Type, index: usize, zcu: *Zcu) Alignment {3196pub fn structFieldAlign(ty: Type, index: usize, pt: Zcu.PerThread) Alignment {
3192 return ty.structFieldAlignAdvanced(index, zcu, .normal) catch unreachable;3197 return ty.structFieldAlignAdvanced(index, pt, .normal) catch unreachable;
3193}3198}
31943199
3195pub fn structFieldAlignAdvanced(ty: Type, index: usize, zcu: *Zcu, strat: ResolveStrat) !Alignment {3200pub fn structFieldAlignAdvanced(ty: Type, index: usize, pt: Zcu.PerThread, strat: ResolveStrat) !Alignment {
3196 const ip = &zcu.intern_pool;3201 const ip = &pt.zcu.intern_pool;
3197 switch (ip.indexToKey(ty.toIntern())) {3202 switch (ip.indexToKey(ty.toIntern())) {
3198 .struct_type => {3203 .struct_type => {
3199 const struct_type = ip.loadStructType(ty.toIntern());3204 const struct_type = ip.loadStructType(ty.toIntern());
3200 assert(struct_type.layout != .@"packed");3205 assert(struct_type.layout != .@"packed");
3201 const explicit_align = struct_type.fieldAlign(ip, index);3206 const explicit_align = struct_type.fieldAlign(ip, index);
3202 const field_ty = Type.fromInterned(struct_type.field_types.get(ip)[index]);3207 const field_ty = Type.fromInterned(struct_type.field_types.get(ip)[index]);
3203 return zcu.structFieldAlignmentAdvanced(explicit_align, field_ty, struct_type.layout, strat);3208 return pt.structFieldAlignmentAdvanced(explicit_align, field_ty, struct_type.layout, strat);
3204 },3209 },
3205 .anon_struct_type => |anon_struct| {3210 .anon_struct_type => |anon_struct| {
3206 return (try Type.fromInterned(anon_struct.types.get(ip)[index]).abiAlignmentAdvanced(zcu, strat.toLazy())).scalar;3211 return (try Type.fromInterned(anon_struct.types.get(ip)[index]).abiAlignmentAdvanced(pt, strat.toLazy())).scalar;
3207 },3212 },
3208 .union_type => {3213 .union_type => {
3209 const union_obj = ip.loadUnionType(ty.toIntern());3214 const union_obj = ip.loadUnionType(ty.toIntern());
3210 return zcu.unionFieldNormalAlignmentAdvanced(union_obj, @intCast(index), strat);3215 return pt.unionFieldNormalAlignmentAdvanced(union_obj, @intCast(index), strat);
3211 },3216 },
3212 else => unreachable,3217 else => unreachable,
3213 }3218 }
...@@ -3233,7 +3238,8 @@ pub fn structFieldDefaultValue(ty: Type, index: usize, mod: *Module) Value {...@@ -3233,7 +3238,8 @@ pub fn structFieldDefaultValue(ty: Type, index: usize, mod: *Module) Value {
3233 }3238 }
3234}3239}
32353240
3236pub fn structFieldValueComptime(ty: Type, mod: *Module, index: usize) !?Value {3241pub fn structFieldValueComptime(ty: Type, pt: Zcu.PerThread, index: usize) !?Value {
3242 const mod = pt.zcu;
3237 const ip = &mod.intern_pool;3243 const ip = &mod.intern_pool;
3238 switch (ip.indexToKey(ty.toIntern())) {3244 switch (ip.indexToKey(ty.toIntern())) {
3239 .struct_type => {3245 .struct_type => {
...@@ -3242,13 +3248,13 @@ pub fn structFieldValueComptime(ty: Type, mod: *Module, index: usize) !?Value {...@@ -3242,13 +3248,13 @@ pub fn structFieldValueComptime(ty: Type, mod: *Module, index: usize) !?Value {
3242 assert(struct_type.haveFieldInits(ip));3248 assert(struct_type.haveFieldInits(ip));
3243 return Value.fromInterned(struct_type.field_inits.get(ip)[index]);3249 return Value.fromInterned(struct_type.field_inits.get(ip)[index]);
3244 } else {3250 } else {
3245 return Type.fromInterned(struct_type.field_types.get(ip)[index]).onePossibleValue(mod);3251 return Type.fromInterned(struct_type.field_types.get(ip)[index]).onePossibleValue(pt);
3246 }3252 }
3247 },3253 },
3248 .anon_struct_type => |tuple| {3254 .anon_struct_type => |tuple| {
3249 const val = tuple.values.get(ip)[index];3255 const val = tuple.values.get(ip)[index];
3250 if (val == .none) {3256 if (val == .none) {
3251 return Type.fromInterned(tuple.types.get(ip)[index]).onePossibleValue(mod);3257 return Type.fromInterned(tuple.types.get(ip)[index]).onePossibleValue(pt);
3252 } else {3258 } else {
3253 return Value.fromInterned(val);3259 return Value.fromInterned(val);
3254 }3260 }
...@@ -3272,7 +3278,8 @@ pub const FieldOffset = struct {...@@ -3272,7 +3278,8 @@ pub const FieldOffset = struct {
3272};3278};
32733279
3274/// Supports structs and unions.3280/// Supports structs and unions.
3275pub fn structFieldOffset(ty: Type, index: usize, mod: *Module) u64 {3281pub fn structFieldOffset(ty: Type, index: usize, pt: Zcu.PerThread) u64 {
3282 const mod = pt.zcu;
3276 const ip = &mod.intern_pool;3283 const ip = &mod.intern_pool;
3277 switch (ip.indexToKey(ty.toIntern())) {3284 switch (ip.indexToKey(ty.toIntern())) {
3278 .struct_type => {3285 .struct_type => {
...@@ -3287,17 +3294,17 @@ pub fn structFieldOffset(ty: Type, index: usize, mod: *Module) u64 {...@@ -3287,17 +3294,17 @@ pub fn structFieldOffset(ty: Type, index: usize, mod: *Module) u64 {
3287 var big_align: Alignment = .none;3294 var big_align: Alignment = .none;
32883295
3289 for (tuple.types.get(ip), tuple.values.get(ip), 0..) |field_ty, field_val, i| {3296 for (tuple.types.get(ip), tuple.values.get(ip), 0..) |field_ty, field_val, i| {
3290 if (field_val != .none or !Type.fromInterned(field_ty).hasRuntimeBits(mod)) {3297 if (field_val != .none or !Type.fromInterned(field_ty).hasRuntimeBits(pt)) {
3291 // comptime field3298 // comptime field
3292 if (i == index) return offset;3299 if (i == index) return offset;
3293 continue;3300 continue;
3294 }3301 }
32953302
3296 const field_align = Type.fromInterned(field_ty).abiAlignment(mod);3303 const field_align = Type.fromInterned(field_ty).abiAlignment(pt);
3297 big_align = big_align.max(field_align);3304 big_align = big_align.max(field_align);
3298 offset = field_align.forward(offset);3305 offset = field_align.forward(offset);
3299 if (i == index) return offset;3306 if (i == index) return offset;
3300 offset += Type.fromInterned(field_ty).abiSize(mod);3307 offset += Type.fromInterned(field_ty).abiSize(pt);
3301 }3308 }
3302 offset = big_align.max(.@"1").forward(offset);3309 offset = big_align.max(.@"1").forward(offset);
3303 return offset;3310 return offset;
...@@ -3307,7 +3314,7 @@ pub fn structFieldOffset(ty: Type, index: usize, mod: *Module) u64 {...@@ -3307,7 +3314,7 @@ pub fn structFieldOffset(ty: Type, index: usize, mod: *Module) u64 {
3307 const union_type = ip.loadUnionType(ty.toIntern());3314 const union_type = ip.loadUnionType(ty.toIntern());
3308 if (!union_type.hasTag(ip))3315 if (!union_type.hasTag(ip))
3309 return 0;3316 return 0;
3310 const layout = mod.getUnionLayout(union_type);3317 const layout = pt.getUnionLayout(union_type);
3311 if (layout.tag_align.compare(.gte, layout.payload_align)) {3318 if (layout.tag_align.compare(.gte, layout.payload_align)) {
3312 // {Tag, Payload}3319 // {Tag, Payload}
3313 return layout.payload_align.forward(layout.tag_size);3320 return layout.payload_align.forward(layout.tag_size);
...@@ -3421,12 +3428,13 @@ pub fn optEuBaseType(ty: Type, mod: *Module) Type {...@@ -3421,12 +3428,13 @@ pub fn optEuBaseType(ty: Type, mod: *Module) Type {
3421 };3428 };
3422}3429}
34233430
3424pub fn toUnsigned(ty: Type, mod: *Module) !Type {3431pub fn toUnsigned(ty: Type, pt: Zcu.PerThread) !Type {
3432 const mod = pt.zcu;
3425 return switch (ty.zigTypeTag(mod)) {3433 return switch (ty.zigTypeTag(mod)) {
3426 .Int => mod.intType(.unsigned, ty.intInfo(mod).bits),3434 .Int => pt.intType(.unsigned, ty.intInfo(mod).bits),
3427 .Vector => try mod.vectorType(.{3435 .Vector => try pt.vectorType(.{
3428 .len = ty.vectorLen(mod),3436 .len = ty.vectorLen(mod),
3429 .child = (try ty.childType(mod).toUnsigned(mod)).toIntern(),3437 .child = (try ty.childType(mod).toUnsigned(pt)).toIntern(),
3430 }),3438 }),
3431 else => unreachable,3439 else => unreachable,
3432 };3440 };
...@@ -3492,7 +3500,7 @@ pub fn arrayBase(ty: Type, zcu: *const Zcu) struct { Type, u64 } {...@@ -3492,7 +3500,7 @@ pub fn arrayBase(ty: Type, zcu: *const Zcu) struct { Type, u64 } {
3492 return .{ cur_ty, cur_len };3500 return .{ cur_ty, cur_len };
3493}3501}
34943502
3495pub fn packedStructFieldPtrInfo(struct_ty: Type, parent_ptr_ty: Type, field_idx: u32, zcu: *Zcu) union(enum) {3503pub fn packedStructFieldPtrInfo(struct_ty: Type, parent_ptr_ty: Type, field_idx: u32, pt: Zcu.PerThread) union(enum) {
3496 /// The result is a bit-pointer with the same value and a new packed offset.3504 /// The result is a bit-pointer with the same value and a new packed offset.
3497 bit_ptr: InternPool.Key.PtrType.PackedOffset,3505 bit_ptr: InternPool.Key.PtrType.PackedOffset,
3498 /// The result is a standard pointer.3506 /// The result is a standard pointer.
...@@ -3505,6 +3513,7 @@ pub fn packedStructFieldPtrInfo(struct_ty: Type, parent_ptr_ty: Type, field_idx:...@@ -3505,6 +3513,7 @@ pub fn packedStructFieldPtrInfo(struct_ty: Type, parent_ptr_ty: Type, field_idx:
3505} {3513} {
3506 comptime assert(Type.packed_struct_layout_version == 2);3514 comptime assert(Type.packed_struct_layout_version == 2);
35073515
3516 const zcu = pt.zcu;
3508 const parent_ptr_info = parent_ptr_ty.ptrInfo(zcu);3517 const parent_ptr_info = parent_ptr_ty.ptrInfo(zcu);
3509 const field_ty = struct_ty.structFieldType(field_idx, zcu);3518 const field_ty = struct_ty.structFieldType(field_idx, zcu);
35103519
...@@ -3515,7 +3524,7 @@ pub fn packedStructFieldPtrInfo(struct_ty: Type, parent_ptr_ty: Type, field_idx:...@@ -3515,7 +3524,7 @@ pub fn packedStructFieldPtrInfo(struct_ty: Type, parent_ptr_ty: Type, field_idx:
3515 if (i == field_idx) {3524 if (i == field_idx) {
3516 bit_offset = running_bits;3525 bit_offset = running_bits;
3517 }3526 }
3518 running_bits += @intCast(f_ty.bitSize(zcu));3527 running_bits += @intCast(f_ty.bitSize(pt));
3519 }3528 }
35203529
3521 const res_host_size: u16, const res_bit_offset: u16 = if (parent_ptr_info.packed_offset.host_size != 0)3530 const res_host_size: u16, const res_bit_offset: u16 = if (parent_ptr_info.packed_offset.host_size != 0)
...@@ -3532,9 +3541,9 @@ pub fn packedStructFieldPtrInfo(struct_ty: Type, parent_ptr_ty: Type, field_idx:...@@ -3532,9 +3541,9 @@ pub fn packedStructFieldPtrInfo(struct_ty: Type, parent_ptr_ty: Type, field_idx:
3532 // targets before adding the necessary complications to this code. This will not3541 // targets before adding the necessary complications to this code. This will not
3533 // cause miscompilations; it only means the field pointer uses bit masking when it3542 // cause miscompilations; it only means the field pointer uses bit masking when it
3534 // might not be strictly necessary.3543 // might not be strictly necessary.
3535 if (res_bit_offset % 8 == 0 and field_ty.bitSize(zcu) == field_ty.abiSize(zcu) * 8 and zcu.getTarget().cpu.arch.endian() == .little) {3544 if (res_bit_offset % 8 == 0 and field_ty.bitSize(pt) == field_ty.abiSize(pt) * 8 and zcu.getTarget().cpu.arch.endian() == .little) {
3536 const byte_offset = res_bit_offset / 8;3545 const byte_offset = res_bit_offset / 8;
3537 const new_align = Alignment.fromLog2Units(@ctz(byte_offset | parent_ptr_ty.ptrAlignment(zcu).toByteUnits().?));3546 const new_align = Alignment.fromLog2Units(@ctz(byte_offset | parent_ptr_ty.ptrAlignment(pt).toByteUnits().?));
3538 return .{ .byte_ptr = .{3547 return .{ .byte_ptr = .{
3539 .offset = byte_offset,3548 .offset = byte_offset,
3540 .alignment = new_align,3549 .alignment = new_align,
...@@ -3547,34 +3556,35 @@ pub fn packedStructFieldPtrInfo(struct_ty: Type, parent_ptr_ty: Type, field_idx:...@@ -3547,34 +3556,35 @@ pub fn packedStructFieldPtrInfo(struct_ty: Type, parent_ptr_ty: Type, field_idx:
3547 } };3556 } };
3548}3557}
35493558
3550pub fn resolveLayout(ty: Type, zcu: *Zcu) SemaError!void {3559pub fn resolveLayout(ty: Type, pt: Zcu.PerThread) SemaError!void {
3560 const zcu = pt.zcu;
3551 const ip = &zcu.intern_pool;3561 const ip = &zcu.intern_pool;
3552 switch (ip.indexToKey(ty.toIntern())) {3562 switch (ip.indexToKey(ty.toIntern())) {
3553 .simple_type => |simple_type| return resolveSimpleType(simple_type, zcu),3563 .simple_type => |simple_type| return resolveSimpleType(simple_type, pt),
3554 else => {},3564 else => {},
3555 }3565 }
3556 switch (ty.zigTypeTag(zcu)) {3566 switch (ty.zigTypeTag(zcu)) {
3557 .Struct => switch (ip.indexToKey(ty.toIntern())) {3567 .Struct => switch (ip.indexToKey(ty.toIntern())) {
3558 .anon_struct_type => |anon_struct_type| for (0..anon_struct_type.types.len) |i| {3568 .anon_struct_type => |anon_struct_type| for (0..anon_struct_type.types.len) |i| {
3559 const field_ty = Type.fromInterned(anon_struct_type.types.get(ip)[i]);3569 const field_ty = Type.fromInterned(anon_struct_type.types.get(ip)[i]);
3560 try field_ty.resolveLayout(zcu);3570 try field_ty.resolveLayout(pt);
3561 },3571 },
3562 .struct_type => return ty.resolveStructInner(zcu, .layout),3572 .struct_type => return ty.resolveStructInner(pt, .layout),
3563 else => unreachable,3573 else => unreachable,
3564 },3574 },
3565 .Union => return ty.resolveUnionInner(zcu, .layout),3575 .Union => return ty.resolveUnionInner(pt, .layout),
3566 .Array => {3576 .Array => {
3567 if (ty.arrayLenIncludingSentinel(zcu) == 0) return;3577 if (ty.arrayLenIncludingSentinel(zcu) == 0) return;
3568 const elem_ty = ty.childType(zcu);3578 const elem_ty = ty.childType(zcu);
3569 return elem_ty.resolveLayout(zcu);3579 return elem_ty.resolveLayout(pt);
3570 },3580 },
3571 .Optional => {3581 .Optional => {
3572 const payload_ty = ty.optionalChild(zcu);3582 const payload_ty = ty.optionalChild(zcu);
3573 return payload_ty.resolveLayout(zcu);3583 return payload_ty.resolveLayout(pt);
3574 },3584 },
3575 .ErrorUnion => {3585 .ErrorUnion => {
3576 const payload_ty = ty.errorUnionPayload(zcu);3586 const payload_ty = ty.errorUnionPayload(zcu);
3577 return payload_ty.resolveLayout(zcu);3587 return payload_ty.resolveLayout(pt);
3578 },3588 },
3579 .Fn => {3589 .Fn => {
3580 const info = zcu.typeToFunc(ty).?;3590 const info = zcu.typeToFunc(ty).?;
...@@ -3585,16 +3595,16 @@ pub fn resolveLayout(ty: Type, zcu: *Zcu) SemaError!void {...@@ -3585,16 +3595,16 @@ pub fn resolveLayout(ty: Type, zcu: *Zcu) SemaError!void {
3585 }3595 }
3586 for (0..info.param_types.len) |i| {3596 for (0..info.param_types.len) |i| {
3587 const param_ty = info.param_types.get(ip)[i];3597 const param_ty = info.param_types.get(ip)[i];
3588 try Type.fromInterned(param_ty).resolveLayout(zcu);3598 try Type.fromInterned(param_ty).resolveLayout(pt);
3589 }3599 }
3590 try Type.fromInterned(info.return_type).resolveLayout(zcu);3600 try Type.fromInterned(info.return_type).resolveLayout(pt);
3591 },3601 },
3592 else => {},3602 else => {},
3593 }3603 }
3594}3604}
35953605
3596pub fn resolveFields(ty: Type, zcu: *Zcu) SemaError!void {3606pub fn resolveFields(ty: Type, pt: Zcu.PerThread) SemaError!void {
3597 const ip = &zcu.intern_pool;3607 const ip = &pt.zcu.intern_pool;
3598 const ty_ip = ty.toIntern();3608 const ty_ip = ty.toIntern();
35993609
3600 switch (ty_ip) {3610 switch (ty_ip) {
...@@ -3676,26 +3686,27 @@ pub fn resolveFields(ty: Type, zcu: *Zcu) SemaError!void {...@@ -3676,26 +3686,27 @@ pub fn resolveFields(ty: Type, zcu: *Zcu) SemaError!void {
3676 .empty_struct => unreachable,3686 .empty_struct => unreachable,
3677 .generic_poison => unreachable,3687 .generic_poison => unreachable,
36783688
3679 else => switch (ip.items.items(.tag)[@intFromEnum(ty_ip)]) {3689 else => switch (ty_ip.unwrap(ip).getTag(ip)) {
3680 .type_struct,3690 .type_struct,
3681 .type_struct_packed,3691 .type_struct_packed,
3682 .type_struct_packed_inits,3692 .type_struct_packed_inits,
3683 => return ty.resolveStructInner(zcu, .fields),3693 => return ty.resolveStructInner(pt, .fields),
36843694
3685 .type_union => return ty.resolveUnionInner(zcu, .fields),3695 .type_union => return ty.resolveUnionInner(pt, .fields),
36863696
3687 .simple_type => return resolveSimpleType(ip.indexToKey(ty_ip).simple_type, zcu),3697 .simple_type => return resolveSimpleType(ip.indexToKey(ty_ip).simple_type, pt),
36883698
3689 else => {},3699 else => {},
3690 },3700 },
3691 }3701 }
3692}3702}
36933703
3694pub fn resolveFully(ty: Type, zcu: *Zcu) SemaError!void {3704pub fn resolveFully(ty: Type, pt: Zcu.PerThread) SemaError!void {
3705 const zcu = pt.zcu;
3695 const ip = &zcu.intern_pool;3706 const ip = &zcu.intern_pool;
36963707
3697 switch (ip.indexToKey(ty.toIntern())) {3708 switch (ip.indexToKey(ty.toIntern())) {
3698 .simple_type => |simple_type| return resolveSimpleType(simple_type, zcu),3709 .simple_type => |simple_type| return resolveSimpleType(simple_type, pt),
3699 else => {},3710 else => {},
3700 }3711 }
37013712
...@@ -3719,52 +3730,53 @@ pub fn resolveFully(ty: Type, zcu: *Zcu) SemaError!void {...@@ -3719,52 +3730,53 @@ pub fn resolveFully(ty: Type, zcu: *Zcu) SemaError!void {
3719 .EnumLiteral,3730 .EnumLiteral,
3720 => {},3731 => {},
37213732
3722 .Pointer => return ty.childType(zcu).resolveFully(zcu),3733 .Pointer => return ty.childType(zcu).resolveFully(pt),
3723 .Array => return ty.childType(zcu).resolveFully(zcu),3734 .Array => return ty.childType(zcu).resolveFully(pt),
3724 .Optional => return ty.optionalChild(zcu).resolveFully(zcu),3735 .Optional => return ty.optionalChild(zcu).resolveFully(pt),
3725 .ErrorUnion => return ty.errorUnionPayload(zcu).resolveFully(zcu),3736 .ErrorUnion => return ty.errorUnionPayload(zcu).resolveFully(pt),
3726 .Fn => {3737 .Fn => {
3727 const info = zcu.typeToFunc(ty).?;3738 const info = zcu.typeToFunc(ty).?;
3728 if (info.is_generic) return;3739 if (info.is_generic) return;
3729 for (0..info.param_types.len) |i| {3740 for (0..info.param_types.len) |i| {
3730 const param_ty = info.param_types.get(ip)[i];3741 const param_ty = info.param_types.get(ip)[i];
3731 try Type.fromInterned(param_ty).resolveFully(zcu);3742 try Type.fromInterned(param_ty).resolveFully(pt);
3732 }3743 }
3733 try Type.fromInterned(info.return_type).resolveFully(zcu);3744 try Type.fromInterned(info.return_type).resolveFully(pt);
3734 },3745 },
37353746
3736 .Struct => switch (ip.indexToKey(ty.toIntern())) {3747 .Struct => switch (ip.indexToKey(ty.toIntern())) {
3737 .anon_struct_type => |anon_struct_type| for (0..anon_struct_type.types.len) |i| {3748 .anon_struct_type => |anon_struct_type| for (0..anon_struct_type.types.len) |i| {
3738 const field_ty = Type.fromInterned(anon_struct_type.types.get(ip)[i]);3749 const field_ty = Type.fromInterned(anon_struct_type.types.get(ip)[i]);
3739 try field_ty.resolveFully(zcu);3750 try field_ty.resolveFully(pt);
3740 },3751 },
3741 .struct_type => return ty.resolveStructInner(zcu, .full),3752 .struct_type => return ty.resolveStructInner(pt, .full),
3742 else => unreachable,3753 else => unreachable,
3743 },3754 },
3744 .Union => return ty.resolveUnionInner(zcu, .full),3755 .Union => return ty.resolveUnionInner(pt, .full),
3745 }3756 }
3746}3757}
37473758
3748pub fn resolveStructFieldInits(ty: Type, zcu: *Zcu) SemaError!void {3759pub fn resolveStructFieldInits(ty: Type, pt: Zcu.PerThread) SemaError!void {
3749 // TODO: stop calling this for tuples!3760 // TODO: stop calling this for tuples!
3750 _ = zcu.typeToStruct(ty) orelse return;3761 _ = pt.zcu.typeToStruct(ty) orelse return;
3751 return ty.resolveStructInner(zcu, .inits);3762 return ty.resolveStructInner(pt, .inits);
3752}3763}
37533764
3754pub fn resolveStructAlignment(ty: Type, zcu: *Zcu) SemaError!void {3765pub fn resolveStructAlignment(ty: Type, pt: Zcu.PerThread) SemaError!void {
3755 return ty.resolveStructInner(zcu, .alignment);3766 return ty.resolveStructInner(pt, .alignment);
3756}3767}
37573768
3758pub fn resolveUnionAlignment(ty: Type, zcu: *Zcu) SemaError!void {3769pub fn resolveUnionAlignment(ty: Type, pt: Zcu.PerThread) SemaError!void {
3759 return ty.resolveUnionInner(zcu, .alignment);3770 return ty.resolveUnionInner(pt, .alignment);
3760}3771}
37613772
3762/// `ty` must be a struct.3773/// `ty` must be a struct.
3763fn resolveStructInner(3774fn resolveStructInner(
3764 ty: Type,3775 ty: Type,
3765 zcu: *Zcu,3776 pt: Zcu.PerThread,
3766 resolution: enum { fields, inits, alignment, layout, full },3777 resolution: enum { fields, inits, alignment, layout, full },
3767) SemaError!void {3778) SemaError!void {
3779 const zcu = pt.zcu;
3768 const gpa = zcu.gpa;3780 const gpa = zcu.gpa;
37693781
3770 const struct_obj = zcu.typeToStruct(ty).?;3782 const struct_obj = zcu.typeToStruct(ty).?;
...@@ -3777,7 +3789,7 @@ fn resolveStructInner(...@@ -3777,7 +3789,7 @@ fn resolveStructInner(
3777 defer comptime_err_ret_trace.deinit();3789 defer comptime_err_ret_trace.deinit();
37783790
3779 var sema: Sema = .{3791 var sema: Sema = .{
3780 .mod = zcu,3792 .pt = pt,
3781 .gpa = gpa,3793 .gpa = gpa,
3782 .arena = analysis_arena.allocator(),3794 .arena = analysis_arena.allocator(),
3783 .code = undefined, // This ZIR will not be used.3795 .code = undefined, // This ZIR will not be used.
...@@ -3804,9 +3816,10 @@ fn resolveStructInner(...@@ -3804,9 +3816,10 @@ fn resolveStructInner(
3804/// `ty` must be a union.3816/// `ty` must be a union.
3805fn resolveUnionInner(3817fn resolveUnionInner(
3806 ty: Type,3818 ty: Type,
3807 zcu: *Zcu,3819 pt: Zcu.PerThread,
3808 resolution: enum { fields, alignment, layout, full },3820 resolution: enum { fields, alignment, layout, full },
3809) SemaError!void {3821) SemaError!void {
3822 const zcu = pt.zcu;
3810 const gpa = zcu.gpa;3823 const gpa = zcu.gpa;
38113824
3812 const union_obj = zcu.typeToUnion(ty).?;3825 const union_obj = zcu.typeToUnion(ty).?;
...@@ -3819,7 +3832,7 @@ fn resolveUnionInner(...@@ -3819,7 +3832,7 @@ fn resolveUnionInner(
3819 defer comptime_err_ret_trace.deinit();3832 defer comptime_err_ret_trace.deinit();
38203833
3821 var sema: Sema = .{3834 var sema: Sema = .{
3822 .mod = zcu,3835 .pt = pt,
3823 .gpa = gpa,3836 .gpa = gpa,
3824 .arena = analysis_arena.allocator(),3837 .arena = analysis_arena.allocator(),
3825 .code = undefined, // This ZIR will not be used.3838 .code = undefined, // This ZIR will not be used.
...@@ -3845,7 +3858,7 @@ fn resolveUnionInner(...@@ -3845,7 +3858,7 @@ fn resolveUnionInner(
3845/// Fully resolves a simple type. This is usually a nop, but for builtin types with3858/// Fully resolves a simple type. This is usually a nop, but for builtin types with
3846/// special InternPool indices (such as std.builtin.Type) it will analyze and fully3859/// special InternPool indices (such as std.builtin.Type) it will analyze and fully
3847/// resolve the type.3860/// resolve the type.
3848fn resolveSimpleType(simple_type: InternPool.SimpleType, zcu: *Zcu) Allocator.Error!void {3861fn resolveSimpleType(simple_type: InternPool.SimpleType, pt: Zcu.PerThread) Allocator.Error!void {
3849 const builtin_type_name: []const u8 = switch (simple_type) {3862 const builtin_type_name: []const u8 = switch (simple_type) {
3850 .atomic_order => "AtomicOrder",3863 .atomic_order => "AtomicOrder",
3851 .atomic_rmw_op => "AtomicRmwOp",3864 .atomic_rmw_op => "AtomicRmwOp",
...@@ -3861,7 +3874,7 @@ fn resolveSimpleType(simple_type: InternPool.SimpleType, zcu: *Zcu) Allocator.Er...@@ -3861,7 +3874,7 @@ fn resolveSimpleType(simple_type: InternPool.SimpleType, zcu: *Zcu) Allocator.Er
3861 else => return,3874 else => return,
3862 };3875 };
3863 // This will fully resolve the type.3876 // This will fully resolve the type.
3864 _ = try zcu.getBuiltinType(builtin_type_name);3877 _ = try pt.getBuiltinType(builtin_type_name);
3865}3878}
38663879
3867/// Returns the type of a pointer to an element.3880/// Returns the type of a pointer to an element.
...@@ -3874,7 +3887,8 @@ fn resolveSimpleType(simple_type: InternPool.SimpleType, zcu: *Zcu) Allocator.Er...@@ -3874,7 +3887,8 @@ fn resolveSimpleType(simple_type: InternPool.SimpleType, zcu: *Zcu) Allocator.Er
3874/// Handles const-ness and address spaces in particular.3887/// Handles const-ness and address spaces in particular.
3875/// This code is duplicated in `Sema.analyzePtrArithmetic`.3888/// This code is duplicated in `Sema.analyzePtrArithmetic`.
3876/// May perform type resolution and return a transitive `error.AnalysisFail`.3889/// May perform type resolution and return a transitive `error.AnalysisFail`.
3877pub fn elemPtrType(ptr_ty: Type, offset: ?usize, zcu: *Zcu) !Type {3890pub fn elemPtrType(ptr_ty: Type, offset: ?usize, pt: Zcu.PerThread) !Type {
3891 const zcu = pt.zcu;
3878 const ptr_info = ptr_ty.ptrInfo(zcu);3892 const ptr_info = ptr_ty.ptrInfo(zcu);
3879 const elem_ty = ptr_ty.elemType2(zcu);3893 const elem_ty = ptr_ty.elemType2(zcu);
3880 const is_allowzero = ptr_info.flags.is_allowzero and (offset orelse 0) == 0;3894 const is_allowzero = ptr_info.flags.is_allowzero and (offset orelse 0) == 0;
...@@ -3887,14 +3901,14 @@ pub fn elemPtrType(ptr_ty: Type, offset: ?usize, zcu: *Zcu) !Type {...@@ -3887,14 +3901,14 @@ pub fn elemPtrType(ptr_ty: Type, offset: ?usize, zcu: *Zcu) !Type {
3887 alignment: Alignment = .none,3901 alignment: Alignment = .none,
3888 vector_index: VI = .none,3902 vector_index: VI = .none,
3889 } = if (parent_ty.isVector(zcu) and ptr_info.flags.size == .One) blk: {3903 } = if (parent_ty.isVector(zcu) and ptr_info.flags.size == .One) blk: {
3890 const elem_bits = elem_ty.bitSize(zcu);3904 const elem_bits = elem_ty.bitSize(pt);
3891 if (elem_bits == 0) break :blk .{};3905 if (elem_bits == 0) break :blk .{};
3892 const is_packed = elem_bits < 8 or !std.math.isPowerOfTwo(elem_bits);3906 const is_packed = elem_bits < 8 or !std.math.isPowerOfTwo(elem_bits);
3893 if (!is_packed) break :blk .{};3907 if (!is_packed) break :blk .{};
38943908
3895 break :blk .{3909 break :blk .{
3896 .host_size = @intCast(parent_ty.arrayLen(zcu)),3910 .host_size = @intCast(parent_ty.arrayLen(zcu)),
3897 .alignment = parent_ty.abiAlignment(zcu),3911 .alignment = parent_ty.abiAlignment(pt),
3898 .vector_index = if (offset) |some| @enumFromInt(some) else .runtime,3912 .vector_index = if (offset) |some| @enumFromInt(some) else .runtime,
3899 };3913 };
3900 } else .{};3914 } else .{};
...@@ -3908,7 +3922,7 @@ pub fn elemPtrType(ptr_ty: Type, offset: ?usize, zcu: *Zcu) !Type {...@@ -3908,7 +3922,7 @@ pub fn elemPtrType(ptr_ty: Type, offset: ?usize, zcu: *Zcu) !Type {
3908 }3922 }
3909 // If the addend is not a comptime-known value we can still count on3923 // If the addend is not a comptime-known value we can still count on
3910 // it being a multiple of the type size.3924 // it being a multiple of the type size.
3911 const elem_size = (try elem_ty.abiSizeAdvanced(zcu, .sema)).scalar;3925 const elem_size = (try elem_ty.abiSizeAdvanced(pt, .sema)).scalar;
3912 const addend = if (offset) |off| elem_size * off else elem_size;3926 const addend = if (offset) |off| elem_size * off else elem_size;
39133927
3914 // The resulting pointer is aligned to the lcd between the offset (an3928 // The resulting pointer is aligned to the lcd between the offset (an
...@@ -3921,7 +3935,7 @@ pub fn elemPtrType(ptr_ty: Type, offset: ?usize, zcu: *Zcu) !Type {...@@ -3921,7 +3935,7 @@ pub fn elemPtrType(ptr_ty: Type, offset: ?usize, zcu: *Zcu) !Type {
3921 assert(new_align != .none);3935 assert(new_align != .none);
3922 break :a new_align;3936 break :a new_align;
3923 };3937 };
3924 return zcu.ptrTypeSema(.{3938 return pt.ptrTypeSema(.{
3925 .child = elem_ty.toIntern(),3939 .child = elem_ty.toIntern(),
3926 .flags = .{3940 .flags = .{
3927 .alignment = alignment,3941 .alignment = alignment,
...@@ -3944,6 +3958,7 @@ pub const @"u16": Type = .{ .ip_index = .u16_type };...@@ -3944,6 +3958,7 @@ pub const @"u16": Type = .{ .ip_index = .u16_type };
3944pub const @"u29": Type = .{ .ip_index = .u29_type };3958pub const @"u29": Type = .{ .ip_index = .u29_type };
3945pub const @"u32": Type = .{ .ip_index = .u32_type };3959pub const @"u32": Type = .{ .ip_index = .u32_type };
3946pub const @"u64": Type = .{ .ip_index = .u64_type };3960pub const @"u64": Type = .{ .ip_index = .u64_type };
3961pub const @"u80": Type = .{ .ip_index = .u80_type };
3947pub const @"u128": Type = .{ .ip_index = .u128_type };3962pub const @"u128": Type = .{ .ip_index = .u128_type };
39483963
3949pub const @"i8": Type = .{ .ip_index = .i8_type };3964pub const @"i8": Type = .{ .ip_index = .i8_type };
src/Value.zig+1174-1093
...@@ -40,10 +40,10 @@ pub fn fmtDebug(val: Value) std.fmt.Formatter(dump) {...@@ -40,10 +40,10 @@ pub fn fmtDebug(val: Value) std.fmt.Formatter(dump) {
40 return .{ .data = val };40 return .{ .data = val };
41}41}
4242
43pub fn fmtValue(val: Value, mod: *Module, opt_sema: ?*Sema) std.fmt.Formatter(print_value.format) {43pub fn fmtValue(val: Value, pt: Zcu.PerThread, opt_sema: ?*Sema) std.fmt.Formatter(print_value.format) {
44 return .{ .data = .{44 return .{ .data = .{
45 .val = val,45 .val = val,
46 .mod = mod,46 .pt = pt,
47 .opt_sema = opt_sema,47 .opt_sema = opt_sema,
48 .depth = 3,48 .depth = 3,
49 } };49 } };
...@@ -55,34 +55,37 @@ pub fn fmtValueFull(ctx: print_value.FormatContext) std.fmt.Formatter(print_valu...@@ -55,34 +55,37 @@ pub fn fmtValueFull(ctx: print_value.FormatContext) std.fmt.Formatter(print_valu
5555
56/// Converts `val` to a null-terminated string stored in the InternPool.56/// Converts `val` to a null-terminated string stored in the InternPool.
57/// Asserts `val` is an array of `u8`57/// Asserts `val` is an array of `u8`
58pub fn toIpString(val: Value, ty: Type, mod: *Module) !InternPool.NullTerminatedString {58pub fn toIpString(val: Value, ty: Type, pt: Zcu.PerThread) !InternPool.NullTerminatedString {
59 const mod = pt.zcu;
59 assert(ty.zigTypeTag(mod) == .Array);60 assert(ty.zigTypeTag(mod) == .Array);
60 assert(ty.childType(mod).toIntern() == .u8_type);61 assert(ty.childType(mod).toIntern() == .u8_type);
61 const ip = &mod.intern_pool;62 const ip = &mod.intern_pool;
62 switch (mod.intern_pool.indexToKey(val.toIntern()).aggregate.storage) {63 switch (mod.intern_pool.indexToKey(val.toIntern()).aggregate.storage) {
63 .bytes => |bytes| return bytes.toNullTerminatedString(ty.arrayLen(mod), ip),64 .bytes => |bytes| return bytes.toNullTerminatedString(ty.arrayLen(mod), ip),
64 .elems => return arrayToIpString(val, ty.arrayLen(mod), mod),65 .elems => return arrayToIpString(val, ty.arrayLen(mod), pt),
65 .repeated_elem => |elem| {66 .repeated_elem => |elem| {
66 const byte: u8 = @intCast(Value.fromInterned(elem).toUnsignedInt(mod));67 const byte: u8 = @intCast(Value.fromInterned(elem).toUnsignedInt(pt));
67 const len: usize = @intCast(ty.arrayLen(mod));68 const len: u32 = @intCast(ty.arrayLen(mod));
68 try ip.string_bytes.appendNTimes(mod.gpa, byte, len);69 const strings = ip.getLocal(pt.tid).getMutableStrings(mod.gpa);
69 return ip.getOrPutTrailingString(mod.gpa, len, .no_embedded_nulls);70 try strings.appendNTimes(.{byte}, len);
71 return ip.getOrPutTrailingString(mod.gpa, pt.tid, len, .no_embedded_nulls);
70 },72 },
71 }73 }
72}74}
7375
74/// Asserts that the value is representable as an array of bytes.76/// Asserts that the value is representable as an array of bytes.
75/// Copies the value into a freshly allocated slice of memory, which is owned by the caller.77/// Copies the value into a freshly allocated slice of memory, which is owned by the caller.
76pub fn toAllocatedBytes(val: Value, ty: Type, allocator: Allocator, mod: *Module) ![]u8 {78pub fn toAllocatedBytes(val: Value, ty: Type, allocator: Allocator, pt: Zcu.PerThread) ![]u8 {
79 const mod = pt.zcu;
77 const ip = &mod.intern_pool;80 const ip = &mod.intern_pool;
78 return switch (ip.indexToKey(val.toIntern())) {81 return switch (ip.indexToKey(val.toIntern())) {
79 .enum_literal => |enum_literal| allocator.dupe(u8, enum_literal.toSlice(ip)),82 .enum_literal => |enum_literal| allocator.dupe(u8, enum_literal.toSlice(ip)),
80 .slice => |slice| try arrayToAllocatedBytes(val, Value.fromInterned(slice.len).toUnsignedInt(mod), allocator, mod),83 .slice => |slice| try arrayToAllocatedBytes(val, Value.fromInterned(slice.len).toUnsignedInt(pt), allocator, pt),
81 .aggregate => |aggregate| switch (aggregate.storage) {84 .aggregate => |aggregate| switch (aggregate.storage) {
82 .bytes => |bytes| try allocator.dupe(u8, bytes.toSlice(ty.arrayLenIncludingSentinel(mod), ip)),85 .bytes => |bytes| try allocator.dupe(u8, bytes.toSlice(ty.arrayLenIncludingSentinel(mod), ip)),
83 .elems => try arrayToAllocatedBytes(val, ty.arrayLen(mod), allocator, mod),86 .elems => try arrayToAllocatedBytes(val, ty.arrayLen(mod), allocator, pt),
84 .repeated_elem => |elem| {87 .repeated_elem => |elem| {
85 const byte: u8 = @intCast(Value.fromInterned(elem).toUnsignedInt(mod));88 const byte: u8 = @intCast(Value.fromInterned(elem).toUnsignedInt(pt));
86 const result = try allocator.alloc(u8, @intCast(ty.arrayLen(mod)));89 const result = try allocator.alloc(u8, @intCast(ty.arrayLen(mod)));
87 @memset(result, byte);90 @memset(result, byte);
88 return result;91 return result;
...@@ -92,30 +95,32 @@ pub fn toAllocatedBytes(val: Value, ty: Type, allocator: Allocator, mod: *Module...@@ -92,30 +95,32 @@ pub fn toAllocatedBytes(val: Value, ty: Type, allocator: Allocator, mod: *Module
92 };95 };
93}96}
9497
95fn arrayToAllocatedBytes(val: Value, len: u64, allocator: Allocator, mod: *Module) ![]u8 {98fn arrayToAllocatedBytes(val: Value, len: u64, allocator: Allocator, pt: Zcu.PerThread) ![]u8 {
96 const result = try allocator.alloc(u8, @intCast(len));99 const result = try allocator.alloc(u8, @intCast(len));
97 for (result, 0..) |*elem, i| {100 for (result, 0..) |*elem, i| {
98 const elem_val = try val.elemValue(mod, i);101 const elem_val = try val.elemValue(pt, i);
99 elem.* = @intCast(elem_val.toUnsignedInt(mod));102 elem.* = @intCast(elem_val.toUnsignedInt(pt));
100 }103 }
101 return result;104 return result;
102}105}
103106
104fn arrayToIpString(val: Value, len_u64: u64, mod: *Module) !InternPool.NullTerminatedString {107fn arrayToIpString(val: Value, len_u64: u64, pt: Zcu.PerThread) !InternPool.NullTerminatedString {
108 const mod = pt.zcu;
105 const gpa = mod.gpa;109 const gpa = mod.gpa;
106 const ip = &mod.intern_pool;110 const ip = &mod.intern_pool;
107 const len: usize = @intCast(len_u64);111 const len: u32 = @intCast(len_u64);
108 try ip.string_bytes.ensureUnusedCapacity(gpa, len);112 const strings = ip.getLocal(pt.tid).getMutableStrings(gpa);
113 try strings.ensureUnusedCapacity(len);
109 for (0..len) |i| {114 for (0..len) |i| {
110 // I don't think elemValue has the possibility to affect ip.string_bytes. Let's115 // I don't think elemValue has the possibility to affect ip.string_bytes. Let's
111 // assert just to be sure.116 // assert just to be sure.
112 const prev = ip.string_bytes.items.len;117 const prev_len = strings.mutate.len;
113 const elem_val = try val.elemValue(mod, i);118 const elem_val = try val.elemValue(pt, i);
114 assert(ip.string_bytes.items.len == prev);119 assert(strings.mutate.len == prev_len);
115 const byte: u8 = @intCast(elem_val.toUnsignedInt(mod));120 const byte: u8 = @intCast(elem_val.toUnsignedInt(pt));
116 ip.string_bytes.appendAssumeCapacity(byte);121 strings.appendAssumeCapacity(.{byte});
117 }122 }
118 return ip.getOrPutTrailingString(gpa, len, .no_embedded_nulls);123 return ip.getOrPutTrailingString(gpa, pt.tid, len, .no_embedded_nulls);
119}124}
120125
121pub fn fromInterned(i: InternPool.Index) Value {126pub fn fromInterned(i: InternPool.Index) Value {
...@@ -133,14 +138,14 @@ pub fn toType(self: Value) Type {...@@ -133,14 +138,14 @@ pub fn toType(self: Value) Type {
133 return Type.fromInterned(self.toIntern());138 return Type.fromInterned(self.toIntern());
134}139}
135140
136pub fn intFromEnum(val: Value, ty: Type, mod: *Module) Allocator.Error!Value {141pub fn intFromEnum(val: Value, ty: Type, pt: Zcu.PerThread) Allocator.Error!Value {
137 const ip = &mod.intern_pool;142 const ip = &pt.zcu.intern_pool;
138 const enum_ty = ip.typeOf(val.toIntern());143 const enum_ty = ip.typeOf(val.toIntern());
139 return switch (ip.indexToKey(enum_ty)) {144 return switch (ip.indexToKey(enum_ty)) {
140 // Assume it is already an integer and return it directly.145 // Assume it is already an integer and return it directly.
141 .simple_type, .int_type => val,146 .simple_type, .int_type => val,
142 .enum_literal => |enum_literal| {147 .enum_literal => |enum_literal| {
143 const field_index = ty.enumFieldIndex(enum_literal, mod).?;148 const field_index = ty.enumFieldIndex(enum_literal, pt.zcu).?;
144 switch (ip.indexToKey(ty.toIntern())) {149 switch (ip.indexToKey(ty.toIntern())) {
145 // Assume it is already an integer and return it directly.150 // Assume it is already an integer and return it directly.
146 .simple_type, .int_type => return val,151 .simple_type, .int_type => return val,
...@@ -150,13 +155,13 @@ pub fn intFromEnum(val: Value, ty: Type, mod: *Module) Allocator.Error!Value {...@@ -150,13 +155,13 @@ pub fn intFromEnum(val: Value, ty: Type, mod: *Module) Allocator.Error!Value {
150 return Value.fromInterned(enum_type.values.get(ip)[field_index]);155 return Value.fromInterned(enum_type.values.get(ip)[field_index]);
151 } else {156 } else {
152 // Field index and integer values are the same.157 // Field index and integer values are the same.
153 return mod.intValue(Type.fromInterned(enum_type.tag_ty), field_index);158 return pt.intValue(Type.fromInterned(enum_type.tag_ty), field_index);
154 }159 }
155 },160 },
156 else => unreachable,161 else => unreachable,
157 }162 }
158 },163 },
159 .enum_type => try mod.getCoerced(val, Type.fromInterned(ip.loadEnumType(enum_ty).tag_ty)),164 .enum_type => try pt.getCoerced(val, Type.fromInterned(ip.loadEnumType(enum_ty).tag_ty)),
160 else => unreachable,165 else => unreachable,
161 };166 };
162}167}
...@@ -164,38 +169,38 @@ pub fn intFromEnum(val: Value, ty: Type, mod: *Module) Allocator.Error!Value {...@@ -164,38 +169,38 @@ pub fn intFromEnum(val: Value, ty: Type, mod: *Module) Allocator.Error!Value {
164pub const ResolveStrat = Type.ResolveStrat;169pub const ResolveStrat = Type.ResolveStrat;
165170
166/// Asserts the value is an integer.171/// Asserts the value is an integer.
167pub fn toBigInt(val: Value, space: *BigIntSpace, mod: *Module) BigIntConst {172pub fn toBigInt(val: Value, space: *BigIntSpace, pt: Zcu.PerThread) BigIntConst {
168 return val.toBigIntAdvanced(space, mod, .normal) catch unreachable;173 return val.toBigIntAdvanced(space, pt, .normal) catch unreachable;
169}174}
170175
171/// Asserts the value is an integer.176/// Asserts the value is an integer.
172pub fn toBigIntAdvanced(177pub fn toBigIntAdvanced(
173 val: Value,178 val: Value,
174 space: *BigIntSpace,179 space: *BigIntSpace,
175 mod: *Module,180 pt: Zcu.PerThread,
176 strat: ResolveStrat,181 strat: ResolveStrat,
177) Module.CompileError!BigIntConst {182) Module.CompileError!BigIntConst {
178 return switch (val.toIntern()) {183 return switch (val.toIntern()) {
179 .bool_false => BigIntMutable.init(&space.limbs, 0).toConst(),184 .bool_false => BigIntMutable.init(&space.limbs, 0).toConst(),
180 .bool_true => BigIntMutable.init(&space.limbs, 1).toConst(),185 .bool_true => BigIntMutable.init(&space.limbs, 1).toConst(),
181 .null_value => BigIntMutable.init(&space.limbs, 0).toConst(),186 .null_value => BigIntMutable.init(&space.limbs, 0).toConst(),
182 else => switch (mod.intern_pool.indexToKey(val.toIntern())) {187 else => switch (pt.zcu.intern_pool.indexToKey(val.toIntern())) {
183 .int => |int| switch (int.storage) {188 .int => |int| switch (int.storage) {
184 .u64, .i64, .big_int => int.storage.toBigInt(space),189 .u64, .i64, .big_int => int.storage.toBigInt(space),
185 .lazy_align, .lazy_size => |ty| {190 .lazy_align, .lazy_size => |ty| {
186 if (strat == .sema) try Type.fromInterned(ty).resolveLayout(mod);191 if (strat == .sema) try Type.fromInterned(ty).resolveLayout(pt);
187 const x = switch (int.storage) {192 const x = switch (int.storage) {
188 else => unreachable,193 else => unreachable,
189 .lazy_align => Type.fromInterned(ty).abiAlignment(mod).toByteUnits() orelse 0,194 .lazy_align => Type.fromInterned(ty).abiAlignment(pt).toByteUnits() orelse 0,
190 .lazy_size => Type.fromInterned(ty).abiSize(mod),195 .lazy_size => Type.fromInterned(ty).abiSize(pt),
191 };196 };
192 return BigIntMutable.init(&space.limbs, x).toConst();197 return BigIntMutable.init(&space.limbs, x).toConst();
193 },198 },
194 },199 },
195 .enum_tag => |enum_tag| Value.fromInterned(enum_tag.int).toBigIntAdvanced(space, mod, strat),200 .enum_tag => |enum_tag| Value.fromInterned(enum_tag.int).toBigIntAdvanced(space, pt, strat),
196 .opt, .ptr => BigIntMutable.init(201 .opt, .ptr => BigIntMutable.init(
197 &space.limbs,202 &space.limbs,
198 (try val.getUnsignedIntAdvanced(mod, strat)).?,203 (try val.getUnsignedIntAdvanced(pt, strat)).?,
199 ).toConst(),204 ).toConst(),
200 else => unreachable,205 else => unreachable,
201 },206 },
...@@ -229,13 +234,14 @@ pub fn getVariable(val: Value, mod: *Module) ?InternPool.Key.Variable {...@@ -229,13 +234,14 @@ pub fn getVariable(val: Value, mod: *Module) ?InternPool.Key.Variable {
229234
230/// If the value fits in a u64, return it, otherwise null.235/// If the value fits in a u64, return it, otherwise null.
231/// Asserts not undefined.236/// Asserts not undefined.
232pub fn getUnsignedInt(val: Value, mod: *Module) ?u64 {237pub fn getUnsignedInt(val: Value, pt: Zcu.PerThread) ?u64 {
233 return getUnsignedIntAdvanced(val, mod, .normal) catch unreachable;238 return getUnsignedIntAdvanced(val, pt, .normal) catch unreachable;
234}239}
235240
236/// If the value fits in a u64, return it, otherwise null.241/// If the value fits in a u64, return it, otherwise null.
237/// Asserts not undefined.242/// Asserts not undefined.
238pub fn getUnsignedIntAdvanced(val: Value, mod: *Module, strat: ResolveStrat) !?u64 {243pub fn getUnsignedIntAdvanced(val: Value, pt: Zcu.PerThread, strat: ResolveStrat) !?u64 {
244 const mod = pt.zcu;
239 return switch (val.toIntern()) {245 return switch (val.toIntern()) {
240 .undef => unreachable,246 .undef => unreachable,
241 .bool_false => 0,247 .bool_false => 0,
...@@ -246,22 +252,22 @@ pub fn getUnsignedIntAdvanced(val: Value, mod: *Module, strat: ResolveStrat) !?u...@@ -246,22 +252,22 @@ pub fn getUnsignedIntAdvanced(val: Value, mod: *Module, strat: ResolveStrat) !?u
246 .big_int => |big_int| big_int.to(u64) catch null,252 .big_int => |big_int| big_int.to(u64) catch null,
247 .u64 => |x| x,253 .u64 => |x| x,
248 .i64 => |x| std.math.cast(u64, x),254 .i64 => |x| std.math.cast(u64, x),
249 .lazy_align => |ty| (try Type.fromInterned(ty).abiAlignmentAdvanced(mod, strat.toLazy())).scalar.toByteUnits() orelse 0,255 .lazy_align => |ty| (try Type.fromInterned(ty).abiAlignmentAdvanced(pt, strat.toLazy())).scalar.toByteUnits() orelse 0,
250 .lazy_size => |ty| (try Type.fromInterned(ty).abiSizeAdvanced(mod, strat.toLazy())).scalar,256 .lazy_size => |ty| (try Type.fromInterned(ty).abiSizeAdvanced(pt, strat.toLazy())).scalar,
251 },257 },
252 .ptr => |ptr| switch (ptr.base_addr) {258 .ptr => |ptr| switch (ptr.base_addr) {
253 .int => ptr.byte_offset,259 .int => ptr.byte_offset,
254 .field => |field| {260 .field => |field| {
255 const base_addr = (try Value.fromInterned(field.base).getUnsignedIntAdvanced(mod, strat)) orelse return null;261 const base_addr = (try Value.fromInterned(field.base).getUnsignedIntAdvanced(pt, strat)) orelse return null;
256 const struct_ty = Value.fromInterned(field.base).typeOf(mod).childType(mod);262 const struct_ty = Value.fromInterned(field.base).typeOf(mod).childType(mod);
257 if (strat == .sema) try struct_ty.resolveLayout(mod);263 if (strat == .sema) try struct_ty.resolveLayout(pt);
258 return base_addr + struct_ty.structFieldOffset(@intCast(field.index), mod) + ptr.byte_offset;264 return base_addr + struct_ty.structFieldOffset(@intCast(field.index), pt) + ptr.byte_offset;
259 },265 },
260 else => null,266 else => null,
261 },267 },
262 .opt => |opt| switch (opt.val) {268 .opt => |opt| switch (opt.val) {
263 .none => 0,269 .none => 0,
264 else => |payload| Value.fromInterned(payload).getUnsignedIntAdvanced(mod, strat),270 else => |payload| Value.fromInterned(payload).getUnsignedIntAdvanced(pt, strat),
265 },271 },
266 else => null,272 else => null,
267 },273 },
...@@ -269,27 +275,27 @@ pub fn getUnsignedIntAdvanced(val: Value, mod: *Module, strat: ResolveStrat) !?u...@@ -269,27 +275,27 @@ pub fn getUnsignedIntAdvanced(val: Value, mod: *Module, strat: ResolveStrat) !?u
269}275}
270276
271/// Asserts the value is an integer and it fits in a u64277/// Asserts the value is an integer and it fits in a u64
272pub fn toUnsignedInt(val: Value, zcu: *Zcu) u64 {278pub fn toUnsignedInt(val: Value, pt: Zcu.PerThread) u64 {
273 return getUnsignedInt(val, zcu).?;279 return getUnsignedInt(val, pt).?;
274}280}
275281
276/// Asserts the value is an integer and it fits in a u64282/// Asserts the value is an integer and it fits in a u64
277pub fn toUnsignedIntSema(val: Value, zcu: *Zcu) !u64 {283pub fn toUnsignedIntSema(val: Value, pt: Zcu.PerThread) !u64 {
278 return (try getUnsignedIntAdvanced(val, zcu, .sema)).?;284 return (try getUnsignedIntAdvanced(val, pt, .sema)).?;
279}285}
280286
281/// Asserts the value is an integer and it fits in a i64287/// Asserts the value is an integer and it fits in a i64
282pub fn toSignedInt(val: Value, mod: *Module) i64 {288pub fn toSignedInt(val: Value, pt: Zcu.PerThread) i64 {
283 return switch (val.toIntern()) {289 return switch (val.toIntern()) {
284 .bool_false => 0,290 .bool_false => 0,
285 .bool_true => 1,291 .bool_true => 1,
286 else => switch (mod.intern_pool.indexToKey(val.toIntern())) {292 else => switch (pt.zcu.intern_pool.indexToKey(val.toIntern())) {
287 .int => |int| switch (int.storage) {293 .int => |int| switch (int.storage) {
288 .big_int => |big_int| big_int.to(i64) catch unreachable,294 .big_int => |big_int| big_int.to(i64) catch unreachable,
289 .i64 => |x| x,295 .i64 => |x| x,
290 .u64 => |x| @intCast(x),296 .u64 => |x| @intCast(x),
291 .lazy_align => |ty| @intCast(Type.fromInterned(ty).abiAlignment(mod).toByteUnits() orelse 0),297 .lazy_align => |ty| @intCast(Type.fromInterned(ty).abiAlignment(pt).toByteUnits() orelse 0),
292 .lazy_size => |ty| @intCast(Type.fromInterned(ty).abiSize(mod)),298 .lazy_size => |ty| @intCast(Type.fromInterned(ty).abiSize(pt)),
293 },299 },
294 else => unreachable,300 else => unreachable,
295 },301 },
...@@ -321,16 +327,17 @@ fn ptrHasIntAddr(val: Value, mod: *Module) bool {...@@ -321,16 +327,17 @@ fn ptrHasIntAddr(val: Value, mod: *Module) bool {
321///327///
322/// Asserts that buffer.len >= ty.abiSize(). The buffer is allowed to extend past328/// Asserts that buffer.len >= ty.abiSize(). The buffer is allowed to extend past
323/// the end of the value in memory.329/// the end of the value in memory.
324pub fn writeToMemory(val: Value, ty: Type, mod: *Module, buffer: []u8) error{330pub fn writeToMemory(val: Value, ty: Type, pt: Zcu.PerThread, buffer: []u8) error{
325 ReinterpretDeclRef,331 ReinterpretDeclRef,
326 IllDefinedMemoryLayout,332 IllDefinedMemoryLayout,
327 Unimplemented,333 Unimplemented,
328 OutOfMemory,334 OutOfMemory,
329}!void {335}!void {
336 const mod = pt.zcu;
330 const target = mod.getTarget();337 const target = mod.getTarget();
331 const endian = target.cpu.arch.endian();338 const endian = target.cpu.arch.endian();
332 if (val.isUndef(mod)) {339 if (val.isUndef(mod)) {
333 const size: usize = @intCast(ty.abiSize(mod));340 const size: usize = @intCast(ty.abiSize(pt));
334 @memset(buffer[0..size], 0xaa);341 @memset(buffer[0..size], 0xaa);
335 return;342 return;
336 }343 }
...@@ -346,41 +353,41 @@ pub fn writeToMemory(val: Value, ty: Type, mod: *Module, buffer: []u8) error{...@@ -346,41 +353,41 @@ pub fn writeToMemory(val: Value, ty: Type, mod: *Module, buffer: []u8) error{
346 const byte_count: u16 = @intCast((@as(u17, bits) + 7) / 8);353 const byte_count: u16 = @intCast((@as(u17, bits) + 7) / 8);
347354
348 var bigint_buffer: BigIntSpace = undefined;355 var bigint_buffer: BigIntSpace = undefined;
349 const bigint = val.toBigInt(&bigint_buffer, mod);356 const bigint = val.toBigInt(&bigint_buffer, pt);
350 bigint.writeTwosComplement(buffer[0..byte_count], endian);357 bigint.writeTwosComplement(buffer[0..byte_count], endian);
351 },358 },
352 .Float => switch (ty.floatBits(target)) {359 .Float => switch (ty.floatBits(target)) {
353 16 => std.mem.writeInt(u16, buffer[0..2], @bitCast(val.toFloat(f16, mod)), endian),360 16 => std.mem.writeInt(u16, buffer[0..2], @bitCast(val.toFloat(f16, pt)), endian),
354 32 => std.mem.writeInt(u32, buffer[0..4], @bitCast(val.toFloat(f32, mod)), endian),361 32 => std.mem.writeInt(u32, buffer[0..4], @bitCast(val.toFloat(f32, pt)), endian),
355 64 => std.mem.writeInt(u64, buffer[0..8], @bitCast(val.toFloat(f64, mod)), endian),362 64 => std.mem.writeInt(u64, buffer[0..8], @bitCast(val.toFloat(f64, pt)), endian),
356 80 => std.mem.writeInt(u80, buffer[0..10], @bitCast(val.toFloat(f80, mod)), endian),363 80 => std.mem.writeInt(u80, buffer[0..10], @bitCast(val.toFloat(f80, pt)), endian),
357 128 => std.mem.writeInt(u128, buffer[0..16], @bitCast(val.toFloat(f128, mod)), endian),364 128 => std.mem.writeInt(u128, buffer[0..16], @bitCast(val.toFloat(f128, pt)), endian),
358 else => unreachable,365 else => unreachable,
359 },366 },
360 .Array => {367 .Array => {
361 const len = ty.arrayLen(mod);368 const len = ty.arrayLen(mod);
362 const elem_ty = ty.childType(mod);369 const elem_ty = ty.childType(mod);
363 const elem_size: usize = @intCast(elem_ty.abiSize(mod));370 const elem_size: usize = @intCast(elem_ty.abiSize(pt));
364 var elem_i: usize = 0;371 var elem_i: usize = 0;
365 var buf_off: usize = 0;372 var buf_off: usize = 0;
366 while (elem_i < len) : (elem_i += 1) {373 while (elem_i < len) : (elem_i += 1) {
367 const elem_val = try val.elemValue(mod, elem_i);374 const elem_val = try val.elemValue(pt, elem_i);
368 try elem_val.writeToMemory(elem_ty, mod, buffer[buf_off..]);375 try elem_val.writeToMemory(elem_ty, pt, buffer[buf_off..]);
369 buf_off += elem_size;376 buf_off += elem_size;
370 }377 }
371 },378 },
372 .Vector => {379 .Vector => {
373 // We use byte_count instead of abi_size here, so that any padding bytes380 // We use byte_count instead of abi_size here, so that any padding bytes
374 // follow the data bytes, on both big- and little-endian systems.381 // follow the data bytes, on both big- and little-endian systems.
375 const byte_count = (@as(usize, @intCast(ty.bitSize(mod))) + 7) / 8;382 const byte_count = (@as(usize, @intCast(ty.bitSize(pt))) + 7) / 8;
376 return writeToPackedMemory(val, ty, mod, buffer[0..byte_count], 0);383 return writeToPackedMemory(val, ty, pt, buffer[0..byte_count], 0);
377 },384 },
378 .Struct => {385 .Struct => {
379 const struct_type = mod.typeToStruct(ty) orelse return error.IllDefinedMemoryLayout;386 const struct_type = mod.typeToStruct(ty) orelse return error.IllDefinedMemoryLayout;
380 switch (struct_type.layout) {387 switch (struct_type.layout) {
381 .auto => return error.IllDefinedMemoryLayout,388 .auto => return error.IllDefinedMemoryLayout,
382 .@"extern" => for (0..struct_type.field_types.len) |field_index| {389 .@"extern" => for (0..struct_type.field_types.len) |field_index| {
383 const off: usize = @intCast(ty.structFieldOffset(field_index, mod));390 const off: usize = @intCast(ty.structFieldOffset(field_index, pt));
384 const field_val = Value.fromInterned(switch (ip.indexToKey(val.toIntern()).aggregate.storage) {391 const field_val = Value.fromInterned(switch (ip.indexToKey(val.toIntern()).aggregate.storage) {
385 .bytes => |bytes| {392 .bytes => |bytes| {
386 buffer[off] = bytes.at(field_index, ip);393 buffer[off] = bytes.at(field_index, ip);
...@@ -390,11 +397,11 @@ pub fn writeToMemory(val: Value, ty: Type, mod: *Module, buffer: []u8) error{...@@ -390,11 +397,11 @@ pub fn writeToMemory(val: Value, ty: Type, mod: *Module, buffer: []u8) error{
390 .repeated_elem => |elem| elem,397 .repeated_elem => |elem| elem,
391 });398 });
392 const field_ty = Type.fromInterned(struct_type.field_types.get(ip)[field_index]);399 const field_ty = Type.fromInterned(struct_type.field_types.get(ip)[field_index]);
393 try writeToMemory(field_val, field_ty, mod, buffer[off..]);400 try writeToMemory(field_val, field_ty, pt, buffer[off..]);
394 },401 },
395 .@"packed" => {402 .@"packed" => {
396 const byte_count = (@as(usize, @intCast(ty.bitSize(mod))) + 7) / 8;403 const byte_count = (@as(usize, @intCast(ty.bitSize(pt))) + 7) / 8;
397 return writeToPackedMemory(val, ty, mod, buffer[0..byte_count], 0);404 return writeToPackedMemory(val, ty, pt, buffer[0..byte_count], 0);
398 },405 },
399 }406 }
400 },407 },
...@@ -421,34 +428,34 @@ pub fn writeToMemory(val: Value, ty: Type, mod: *Module, buffer: []u8) error{...@@ -421,34 +428,34 @@ pub fn writeToMemory(val: Value, ty: Type, mod: *Module, buffer: []u8) error{
421 const union_obj = mod.typeToUnion(ty).?;428 const union_obj = mod.typeToUnion(ty).?;
422 const field_index = mod.unionTagFieldIndex(union_obj, union_tag).?;429 const field_index = mod.unionTagFieldIndex(union_obj, union_tag).?;
423 const field_type = Type.fromInterned(union_obj.field_types.get(&mod.intern_pool)[field_index]);430 const field_type = Type.fromInterned(union_obj.field_types.get(&mod.intern_pool)[field_index]);
424 const field_val = try val.fieldValue(mod, field_index);431 const field_val = try val.fieldValue(pt, field_index);
425 const byte_count: usize = @intCast(field_type.abiSize(mod));432 const byte_count: usize = @intCast(field_type.abiSize(pt));
426 return writeToMemory(field_val, field_type, mod, buffer[0..byte_count]);433 return writeToMemory(field_val, field_type, pt, buffer[0..byte_count]);
427 } else {434 } else {
428 const backing_ty = try ty.unionBackingType(mod);435 const backing_ty = try ty.unionBackingType(pt);
429 const byte_count: usize = @intCast(backing_ty.abiSize(mod));436 const byte_count: usize = @intCast(backing_ty.abiSize(pt));
430 return writeToMemory(val.unionValue(mod), backing_ty, mod, buffer[0..byte_count]);437 return writeToMemory(val.unionValue(mod), backing_ty, pt, buffer[0..byte_count]);
431 }438 }
432 },439 },
433 .@"packed" => {440 .@"packed" => {
434 const backing_ty = try ty.unionBackingType(mod);441 const backing_ty = try ty.unionBackingType(pt);
435 const byte_count: usize = @intCast(backing_ty.abiSize(mod));442 const byte_count: usize = @intCast(backing_ty.abiSize(pt));
436 return writeToPackedMemory(val, ty, mod, buffer[0..byte_count], 0);443 return writeToPackedMemory(val, ty, pt, buffer[0..byte_count], 0);
437 },444 },
438 },445 },
439 .Pointer => {446 .Pointer => {
440 if (ty.isSlice(mod)) return error.IllDefinedMemoryLayout;447 if (ty.isSlice(mod)) return error.IllDefinedMemoryLayout;
441 if (!val.ptrHasIntAddr(mod)) return error.ReinterpretDeclRef;448 if (!val.ptrHasIntAddr(mod)) return error.ReinterpretDeclRef;
442 return val.writeToMemory(Type.usize, mod, buffer);449 return val.writeToMemory(Type.usize, pt, buffer);
443 },450 },
444 .Optional => {451 .Optional => {
445 if (!ty.isPtrLikeOptional(mod)) return error.IllDefinedMemoryLayout;452 if (!ty.isPtrLikeOptional(mod)) return error.IllDefinedMemoryLayout;
446 const child = ty.optionalChild(mod);453 const child = ty.optionalChild(mod);
447 const opt_val = val.optionalValue(mod);454 const opt_val = val.optionalValue(mod);
448 if (opt_val) |some| {455 if (opt_val) |some| {
449 return some.writeToMemory(child, mod, buffer);456 return some.writeToMemory(child, pt, buffer);
450 } else {457 } else {
451 return writeToMemory(try mod.intValue(Type.usize, 0), Type.usize, mod, buffer);458 return writeToMemory(try pt.intValue(Type.usize, 0), Type.usize, pt, buffer);
452 }459 }
453 },460 },
454 else => return error.Unimplemented,461 else => return error.Unimplemented,
...@@ -462,15 +469,16 @@ pub fn writeToMemory(val: Value, ty: Type, mod: *Module, buffer: []u8) error{...@@ -462,15 +469,16 @@ pub fn writeToMemory(val: Value, ty: Type, mod: *Module, buffer: []u8) error{
462pub fn writeToPackedMemory(469pub fn writeToPackedMemory(
463 val: Value,470 val: Value,
464 ty: Type,471 ty: Type,
465 mod: *Module,472 pt: Zcu.PerThread,
466 buffer: []u8,473 buffer: []u8,
467 bit_offset: usize,474 bit_offset: usize,
468) error{ ReinterpretDeclRef, OutOfMemory }!void {475) error{ ReinterpretDeclRef, OutOfMemory }!void {
476 const mod = pt.zcu;
469 const ip = &mod.intern_pool;477 const ip = &mod.intern_pool;
470 const target = mod.getTarget();478 const target = mod.getTarget();
471 const endian = target.cpu.arch.endian();479 const endian = target.cpu.arch.endian();
472 if (val.isUndef(mod)) {480 if (val.isUndef(mod)) {
473 const bit_size: usize = @intCast(ty.bitSize(mod));481 const bit_size: usize = @intCast(ty.bitSize(pt));
474 if (bit_size != 0) {482 if (bit_size != 0) {
475 std.mem.writeVarPackedInt(buffer, bit_offset, bit_size, @as(u1, 0), endian);483 std.mem.writeVarPackedInt(buffer, bit_offset, bit_size, @as(u1, 0), endian);
476 }484 }
...@@ -494,30 +502,30 @@ pub fn writeToPackedMemory(...@@ -494,30 +502,30 @@ pub fn writeToPackedMemory(
494 const bits = ty.intInfo(mod).bits;502 const bits = ty.intInfo(mod).bits;
495 if (bits == 0) return;503 if (bits == 0) return;
496504
497 switch (ip.indexToKey((try val.intFromEnum(ty, mod)).toIntern()).int.storage) {505 switch (ip.indexToKey((try val.intFromEnum(ty, pt)).toIntern()).int.storage) {
498 inline .u64, .i64 => |int| std.mem.writeVarPackedInt(buffer, bit_offset, bits, int, endian),506 inline .u64, .i64 => |int| std.mem.writeVarPackedInt(buffer, bit_offset, bits, int, endian),
499 .big_int => |bigint| bigint.writePackedTwosComplement(buffer, bit_offset, bits, endian),507 .big_int => |bigint| bigint.writePackedTwosComplement(buffer, bit_offset, bits, endian),
500 .lazy_align => |lazy_align| {508 .lazy_align => |lazy_align| {
501 const num = Type.fromInterned(lazy_align).abiAlignment(mod).toByteUnits() orelse 0;509 const num = Type.fromInterned(lazy_align).abiAlignment(pt).toByteUnits() orelse 0;
502 std.mem.writeVarPackedInt(buffer, bit_offset, bits, num, endian);510 std.mem.writeVarPackedInt(buffer, bit_offset, bits, num, endian);
503 },511 },
504 .lazy_size => |lazy_size| {512 .lazy_size => |lazy_size| {
505 const num = Type.fromInterned(lazy_size).abiSize(mod);513 const num = Type.fromInterned(lazy_size).abiSize(pt);
506 std.mem.writeVarPackedInt(buffer, bit_offset, bits, num, endian);514 std.mem.writeVarPackedInt(buffer, bit_offset, bits, num, endian);
507 },515 },
508 }516 }
509 },517 },
510 .Float => switch (ty.floatBits(target)) {518 .Float => switch (ty.floatBits(target)) {
511 16 => std.mem.writePackedInt(u16, buffer, bit_offset, @bitCast(val.toFloat(f16, mod)), endian),519 16 => std.mem.writePackedInt(u16, buffer, bit_offset, @bitCast(val.toFloat(f16, pt)), endian),
512 32 => std.mem.writePackedInt(u32, buffer, bit_offset, @bitCast(val.toFloat(f32, mod)), endian),520 32 => std.mem.writePackedInt(u32, buffer, bit_offset, @bitCast(val.toFloat(f32, pt)), endian),
513 64 => std.mem.writePackedInt(u64, buffer, bit_offset, @bitCast(val.toFloat(f64, mod)), endian),521 64 => std.mem.writePackedInt(u64, buffer, bit_offset, @bitCast(val.toFloat(f64, pt)), endian),
514 80 => std.mem.writePackedInt(u80, buffer, bit_offset, @bitCast(val.toFloat(f80, mod)), endian),522 80 => std.mem.writePackedInt(u80, buffer, bit_offset, @bitCast(val.toFloat(f80, pt)), endian),
515 128 => std.mem.writePackedInt(u128, buffer, bit_offset, @bitCast(val.toFloat(f128, mod)), endian),523 128 => std.mem.writePackedInt(u128, buffer, bit_offset, @bitCast(val.toFloat(f128, pt)), endian),
516 else => unreachable,524 else => unreachable,
517 },525 },
518 .Vector => {526 .Vector => {
519 const elem_ty = ty.childType(mod);527 const elem_ty = ty.childType(mod);
520 const elem_bit_size: u16 = @intCast(elem_ty.bitSize(mod));528 const elem_bit_size: u16 = @intCast(elem_ty.bitSize(pt));
521 const len: usize = @intCast(ty.arrayLen(mod));529 const len: usize = @intCast(ty.arrayLen(mod));
522530
523 var bits: u16 = 0;531 var bits: u16 = 0;
...@@ -525,8 +533,8 @@ pub fn writeToPackedMemory(...@@ -525,8 +533,8 @@ pub fn writeToPackedMemory(
525 while (elem_i < len) : (elem_i += 1) {533 while (elem_i < len) : (elem_i += 1) {
526 // On big-endian systems, LLVM reverses the element order of vectors by default534 // On big-endian systems, LLVM reverses the element order of vectors by default
527 const tgt_elem_i = if (endian == .big) len - elem_i - 1 else elem_i;535 const tgt_elem_i = if (endian == .big) len - elem_i - 1 else elem_i;
528 const elem_val = try val.elemValue(mod, tgt_elem_i);536 const elem_val = try val.elemValue(pt, tgt_elem_i);
529 try elem_val.writeToPackedMemory(elem_ty, mod, buffer, bit_offset + bits);537 try elem_val.writeToPackedMemory(elem_ty, pt, buffer, bit_offset + bits);
530 bits += elem_bit_size;538 bits += elem_bit_size;
531 }539 }
532 },540 },
...@@ -543,8 +551,8 @@ pub fn writeToPackedMemory(...@@ -543,8 +551,8 @@ pub fn writeToPackedMemory(
543 .repeated_elem => |elem| elem,551 .repeated_elem => |elem| elem,
544 });552 });
545 const field_ty = Type.fromInterned(struct_type.field_types.get(ip)[i]);553 const field_ty = Type.fromInterned(struct_type.field_types.get(ip)[i]);
546 const field_bits: u16 = @intCast(field_ty.bitSize(mod));554 const field_bits: u16 = @intCast(field_ty.bitSize(pt));
547 try field_val.writeToPackedMemory(field_ty, mod, buffer, bit_offset + bits);555 try field_val.writeToPackedMemory(field_ty, pt, buffer, bit_offset + bits);
548 bits += field_bits;556 bits += field_bits;
549 }557 }
550 },558 },
...@@ -556,11 +564,11 @@ pub fn writeToPackedMemory(...@@ -556,11 +564,11 @@ pub fn writeToPackedMemory(
556 if (val.unionTag(mod)) |union_tag| {564 if (val.unionTag(mod)) |union_tag| {
557 const field_index = mod.unionTagFieldIndex(union_obj, union_tag).?;565 const field_index = mod.unionTagFieldIndex(union_obj, union_tag).?;
558 const field_type = Type.fromInterned(union_obj.field_types.get(ip)[field_index]);566 const field_type = Type.fromInterned(union_obj.field_types.get(ip)[field_index]);
559 const field_val = try val.fieldValue(mod, field_index);567 const field_val = try val.fieldValue(pt, field_index);
560 return field_val.writeToPackedMemory(field_type, mod, buffer, bit_offset);568 return field_val.writeToPackedMemory(field_type, pt, buffer, bit_offset);
561 } else {569 } else {
562 const backing_ty = try ty.unionBackingType(mod);570 const backing_ty = try ty.unionBackingType(pt);
563 return val.unionValue(mod).writeToPackedMemory(backing_ty, mod, buffer, bit_offset);571 return val.unionValue(mod).writeToPackedMemory(backing_ty, pt, buffer, bit_offset);
564 }572 }
565 },573 },
566 }574 }
...@@ -568,16 +576,16 @@ pub fn writeToPackedMemory(...@@ -568,16 +576,16 @@ pub fn writeToPackedMemory(
568 .Pointer => {576 .Pointer => {
569 assert(!ty.isSlice(mod)); // No well defined layout.577 assert(!ty.isSlice(mod)); // No well defined layout.
570 if (!val.ptrHasIntAddr(mod)) return error.ReinterpretDeclRef;578 if (!val.ptrHasIntAddr(mod)) return error.ReinterpretDeclRef;
571 return val.writeToPackedMemory(Type.usize, mod, buffer, bit_offset);579 return val.writeToPackedMemory(Type.usize, pt, buffer, bit_offset);
572 },580 },
573 .Optional => {581 .Optional => {
574 assert(ty.isPtrLikeOptional(mod));582 assert(ty.isPtrLikeOptional(mod));
575 const child = ty.optionalChild(mod);583 const child = ty.optionalChild(mod);
576 const opt_val = val.optionalValue(mod);584 const opt_val = val.optionalValue(mod);
577 if (opt_val) |some| {585 if (opt_val) |some| {
578 return some.writeToPackedMemory(child, mod, buffer, bit_offset);586 return some.writeToPackedMemory(child, pt, buffer, bit_offset);
579 } else {587 } else {
580 return writeToPackedMemory(try mod.intValue(Type.usize, 0), Type.usize, mod, buffer, bit_offset);588 return writeToPackedMemory(try pt.intValue(Type.usize, 0), Type.usize, pt, buffer, bit_offset);
581 }589 }
582 },590 },
583 else => @panic("TODO implement writeToPackedMemory for more types"),591 else => @panic("TODO implement writeToPackedMemory for more types"),
...@@ -590,7 +598,7 @@ pub fn writeToPackedMemory(...@@ -590,7 +598,7 @@ pub fn writeToPackedMemory(
590/// the end of the value in memory.598/// the end of the value in memory.
591pub fn readFromMemory(599pub fn readFromMemory(
592 ty: Type,600 ty: Type,
593 mod: *Module,601 pt: Zcu.PerThread,
594 buffer: []const u8,602 buffer: []const u8,
595 arena: Allocator,603 arena: Allocator,
596) error{604) error{
...@@ -598,6 +606,7 @@ pub fn readFromMemory(...@@ -598,6 +606,7 @@ pub fn readFromMemory(
598 Unimplemented,606 Unimplemented,
599 OutOfMemory,607 OutOfMemory,
600}!Value {608}!Value {
609 const mod = pt.zcu;
601 const ip = &mod.intern_pool;610 const ip = &mod.intern_pool;
602 const target = mod.getTarget();611 const target = mod.getTarget();
603 const endian = target.cpu.arch.endian();612 const endian = target.cpu.arch.endian();
...@@ -642,7 +651,7 @@ pub fn readFromMemory(...@@ -642,7 +651,7 @@ pub fn readFromMemory(
642 return mod.getCoerced(try mod.intValue_big(int_ty, bigint.toConst()), ty);651 return mod.getCoerced(try mod.intValue_big(int_ty, bigint.toConst()), ty);
643 }652 }
644 },653 },
645 .Float => return Value.fromInterned((try mod.intern(.{ .float = .{654 .Float => return Value.fromInterned(try pt.intern(.{ .float = .{
646 .ty = ty.toIntern(),655 .ty = ty.toIntern(),
647 .storage = switch (ty.floatBits(target)) {656 .storage = switch (ty.floatBits(target)) {
648 16 => .{ .f16 = @bitCast(std.mem.readInt(u16, buffer[0..2], endian)) },657 16 => .{ .f16 = @bitCast(std.mem.readInt(u16, buffer[0..2], endian)) },
...@@ -652,25 +661,25 @@ pub fn readFromMemory(...@@ -652,25 +661,25 @@ pub fn readFromMemory(
652 128 => .{ .f128 = @bitCast(std.mem.readInt(u128, buffer[0..16], endian)) },661 128 => .{ .f128 = @bitCast(std.mem.readInt(u128, buffer[0..16], endian)) },
653 else => unreachable,662 else => unreachable,
654 },663 },
655 } }))),664 } })),
656 .Array => {665 .Array => {
657 const elem_ty = ty.childType(mod);666 const elem_ty = ty.childType(mod);
658 const elem_size = elem_ty.abiSize(mod);667 const elem_size = elem_ty.abiSize(pt);
659 const elems = try arena.alloc(InternPool.Index, @intCast(ty.arrayLen(mod)));668 const elems = try arena.alloc(InternPool.Index, @intCast(ty.arrayLen(mod)));
660 var offset: usize = 0;669 var offset: usize = 0;
661 for (elems) |*elem| {670 for (elems) |*elem| {
662 elem.* = (try readFromMemory(elem_ty, mod, buffer[offset..], arena)).toIntern();671 elem.* = (try readFromMemory(elem_ty, mod, buffer[offset..], arena)).toIntern();
663 offset += @intCast(elem_size);672 offset += @intCast(elem_size);
664 }673 }
665 return Value.fromInterned((try mod.intern(.{ .aggregate = .{674 return Value.fromInterned(try pt.intern(.{ .aggregate = .{
666 .ty = ty.toIntern(),675 .ty = ty.toIntern(),
667 .storage = .{ .elems = elems },676 .storage = .{ .elems = elems },
668 } })));677 } }));
669 },678 },
670 .Vector => {679 .Vector => {
671 // We use byte_count instead of abi_size here, so that any padding bytes680 // We use byte_count instead of abi_size here, so that any padding bytes
672 // follow the data bytes, on both big- and little-endian systems.681 // follow the data bytes, on both big- and little-endian systems.
673 const byte_count = (@as(usize, @intCast(ty.bitSize(mod))) + 7) / 8;682 const byte_count = (@as(usize, @intCast(ty.bitSize(pt))) + 7) / 8;
674 return readFromPackedMemory(ty, mod, buffer[0..byte_count], 0, arena);683 return readFromPackedMemory(ty, mod, buffer[0..byte_count], 0, arena);
675 },684 },
676 .Struct => {685 .Struct => {
...@@ -683,16 +692,16 @@ pub fn readFromMemory(...@@ -683,16 +692,16 @@ pub fn readFromMemory(
683 for (field_vals, 0..) |*field_val, i| {692 for (field_vals, 0..) |*field_val, i| {
684 const field_ty = Type.fromInterned(field_types.get(ip)[i]);693 const field_ty = Type.fromInterned(field_types.get(ip)[i]);
685 const off: usize = @intCast(ty.structFieldOffset(i, mod));694 const off: usize = @intCast(ty.structFieldOffset(i, mod));
686 const sz: usize = @intCast(field_ty.abiSize(mod));695 const sz: usize = @intCast(field_ty.abiSize(pt));
687 field_val.* = (try readFromMemory(field_ty, mod, buffer[off..(off + sz)], arena)).toIntern();696 field_val.* = (try readFromMemory(field_ty, mod, buffer[off..(off + sz)], arena)).toIntern();
688 }697 }
689 return Value.fromInterned((try mod.intern(.{ .aggregate = .{698 return Value.fromInterned(try pt.intern(.{ .aggregate = .{
690 .ty = ty.toIntern(),699 .ty = ty.toIntern(),
691 .storage = .{ .elems = field_vals },700 .storage = .{ .elems = field_vals },
692 } })));701 } }));
693 },702 },
694 .@"packed" => {703 .@"packed" => {
695 const byte_count = (@as(usize, @intCast(ty.bitSize(mod))) + 7) / 8;704 const byte_count = (@as(usize, @intCast(ty.bitSize(pt))) + 7) / 8;
696 return readFromPackedMemory(ty, mod, buffer[0..byte_count], 0, arena);705 return readFromPackedMemory(ty, mod, buffer[0..byte_count], 0, arena);
697 },706 },
698 }707 }
...@@ -704,49 +713,49 @@ pub fn readFromMemory(...@@ -704,49 +713,49 @@ pub fn readFromMemory(
704 const index = (int << @as(u6, @intCast(64 - bits))) >> @as(u6, @intCast(64 - bits));713 const index = (int << @as(u6, @intCast(64 - bits))) >> @as(u6, @intCast(64 - bits));
705 const name = mod.global_error_set.keys()[@intCast(index)];714 const name = mod.global_error_set.keys()[@intCast(index)];
706715
707 return Value.fromInterned((try mod.intern(.{ .err = .{716 return Value.fromInterned(try pt.intern(.{ .err = .{
708 .ty = ty.toIntern(),717 .ty = ty.toIntern(),
709 .name = name,718 .name = name,
710 } })));719 } }));
711 },720 },
712 .Union => switch (ty.containerLayout(mod)) {721 .Union => switch (ty.containerLayout(mod)) {
713 .auto => return error.IllDefinedMemoryLayout,722 .auto => return error.IllDefinedMemoryLayout,
714 .@"extern" => {723 .@"extern" => {
715 const union_size = ty.abiSize(mod);724 const union_size = ty.abiSize(pt);
716 const array_ty = try mod.arrayType(.{ .len = union_size, .child = .u8_type });725 const array_ty = try mod.arrayType(.{ .len = union_size, .child = .u8_type });
717 const val = (try readFromMemory(array_ty, mod, buffer, arena)).toIntern();726 const val = (try readFromMemory(array_ty, mod, buffer, arena)).toIntern();
718 return Value.fromInterned((try mod.intern(.{ .un = .{727 return Value.fromInterned(try pt.intern(.{ .un = .{
719 .ty = ty.toIntern(),728 .ty = ty.toIntern(),
720 .tag = .none,729 .tag = .none,
721 .val = val,730 .val = val,
722 } })));731 } }));
723 },732 },
724 .@"packed" => {733 .@"packed" => {
725 const byte_count = (@as(usize, @intCast(ty.bitSize(mod))) + 7) / 8;734 const byte_count = (@as(usize, @intCast(ty.bitSize(pt))) + 7) / 8;
726 return readFromPackedMemory(ty, mod, buffer[0..byte_count], 0, arena);735 return readFromPackedMemory(ty, mod, buffer[0..byte_count], 0, arena);
727 },736 },
728 },737 },
729 .Pointer => {738 .Pointer => {
730 assert(!ty.isSlice(mod)); // No well defined layout.739 assert(!ty.isSlice(mod)); // No well defined layout.
731 const int_val = try readFromMemory(Type.usize, mod, buffer, arena);740 const int_val = try readFromMemory(Type.usize, mod, buffer, arena);
732 return Value.fromInterned((try mod.intern(.{ .ptr = .{741 return Value.fromInterned(try pt.intern(.{ .ptr = .{
733 .ty = ty.toIntern(),742 .ty = ty.toIntern(),
734 .base_addr = .int,743 .base_addr = .int,
735 .byte_offset = int_val.toUnsignedInt(mod),744 .byte_offset = int_val.toUnsignedInt(pt),
736 } })));745 } }));
737 },746 },
738 .Optional => {747 .Optional => {
739 assert(ty.isPtrLikeOptional(mod));748 assert(ty.isPtrLikeOptional(mod));
740 const child_ty = ty.optionalChild(mod);749 const child_ty = ty.optionalChild(mod);
741 const child_val = try readFromMemory(child_ty, mod, buffer, arena);750 const child_val = try readFromMemory(child_ty, mod, buffer, arena);
742 return Value.fromInterned((try mod.intern(.{ .opt = .{751 return Value.fromInterned(try pt.intern(.{ .opt = .{
743 .ty = ty.toIntern(),752 .ty = ty.toIntern(),
744 .val = switch (child_val.orderAgainstZero(mod)) {753 .val = switch (child_val.orderAgainstZero(pt)) {
745 .lt => unreachable,754 .lt => unreachable,
746 .eq => .none,755 .eq => .none,
747 .gt => child_val.toIntern(),756 .gt => child_val.toIntern(),
748 },757 },
749 } })));758 } }));
750 },759 },
751 else => return error.Unimplemented,760 else => return error.Unimplemented,
752 }761 }
...@@ -758,7 +767,7 @@ pub fn readFromMemory(...@@ -758,7 +767,7 @@ pub fn readFromMemory(
758/// big-endian packed memory layouts start at the end of the buffer.767/// big-endian packed memory layouts start at the end of the buffer.
759pub fn readFromPackedMemory(768pub fn readFromPackedMemory(
760 ty: Type,769 ty: Type,
761 mod: *Module,770 pt: Zcu.PerThread,
762 buffer: []const u8,771 buffer: []const u8,
763 bit_offset: usize,772 bit_offset: usize,
764 arena: Allocator,773 arena: Allocator,
...@@ -766,6 +775,7 @@ pub fn readFromPackedMemory(...@@ -766,6 +775,7 @@ pub fn readFromPackedMemory(
766 IllDefinedMemoryLayout,775 IllDefinedMemoryLayout,
767 OutOfMemory,776 OutOfMemory,
768}!Value {777}!Value {
778 const mod = pt.zcu;
769 const ip = &mod.intern_pool;779 const ip = &mod.intern_pool;
770 const target = mod.getTarget();780 const target = mod.getTarget();
771 const endian = target.cpu.arch.endian();781 const endian = target.cpu.arch.endian();
...@@ -783,35 +793,35 @@ pub fn readFromPackedMemory(...@@ -783,35 +793,35 @@ pub fn readFromPackedMemory(
783 }793 }
784 },794 },
785 .Int => {795 .Int => {
786 if (buffer.len == 0) return mod.intValue(ty, 0);796 if (buffer.len == 0) return pt.intValue(ty, 0);
787 const int_info = ty.intInfo(mod);797 const int_info = ty.intInfo(mod);
788 const bits = int_info.bits;798 const bits = int_info.bits;
789 if (bits == 0) return mod.intValue(ty, 0);799 if (bits == 0) return pt.intValue(ty, 0);
790800
791 // Fast path for integers <= u64801 // Fast path for integers <= u64
792 if (bits <= 64) switch (int_info.signedness) {802 if (bits <= 64) switch (int_info.signedness) {
793 // Use different backing types for unsigned vs signed to avoid the need to go via803 // Use different backing types for unsigned vs signed to avoid the need to go via
794 // a larger type like `i128`.804 // a larger type like `i128`.
795 .unsigned => return mod.intValue(ty, std.mem.readVarPackedInt(u64, buffer, bit_offset, bits, endian, .unsigned)),805 .unsigned => return pt.intValue(ty, std.mem.readVarPackedInt(u64, buffer, bit_offset, bits, endian, .unsigned)),
796 .signed => return mod.intValue(ty, std.mem.readVarPackedInt(i64, buffer, bit_offset, bits, endian, .signed)),806 .signed => return pt.intValue(ty, std.mem.readVarPackedInt(i64, buffer, bit_offset, bits, endian, .signed)),
797 };807 };
798808
799 // Slow path, we have to construct a big-int809 // Slow path, we have to construct a big-int
800 const abi_size: usize = @intCast(ty.abiSize(mod));810 const abi_size: usize = @intCast(ty.abiSize(pt));
801 const Limb = std.math.big.Limb;811 const Limb = std.math.big.Limb;
802 const limb_count = (abi_size + @sizeOf(Limb) - 1) / @sizeOf(Limb);812 const limb_count = (abi_size + @sizeOf(Limb) - 1) / @sizeOf(Limb);
803 const limbs_buffer = try arena.alloc(Limb, limb_count);813 const limbs_buffer = try arena.alloc(Limb, limb_count);
804814
805 var bigint = BigIntMutable.init(limbs_buffer, 0);815 var bigint = BigIntMutable.init(limbs_buffer, 0);
806 bigint.readPackedTwosComplement(buffer, bit_offset, bits, endian, int_info.signedness);816 bigint.readPackedTwosComplement(buffer, bit_offset, bits, endian, int_info.signedness);
807 return mod.intValue_big(ty, bigint.toConst());817 return pt.intValue_big(ty, bigint.toConst());
808 },818 },
809 .Enum => {819 .Enum => {
810 const int_ty = ty.intTagType(mod);820 const int_ty = ty.intTagType(mod);
811 const int_val = try Value.readFromPackedMemory(int_ty, mod, buffer, bit_offset, arena);821 const int_val = try Value.readFromPackedMemory(int_ty, pt, buffer, bit_offset, arena);
812 return mod.getCoerced(int_val, ty);822 return pt.getCoerced(int_val, ty);
813 },823 },
814 .Float => return Value.fromInterned((try mod.intern(.{ .float = .{824 .Float => return Value.fromInterned(try pt.intern(.{ .float = .{
815 .ty = ty.toIntern(),825 .ty = ty.toIntern(),
816 .storage = switch (ty.floatBits(target)) {826 .storage = switch (ty.floatBits(target)) {
817 16 => .{ .f16 = @bitCast(std.mem.readPackedInt(u16, buffer, bit_offset, endian)) },827 16 => .{ .f16 = @bitCast(std.mem.readPackedInt(u16, buffer, bit_offset, endian)) },
...@@ -821,23 +831,23 @@ pub fn readFromPackedMemory(...@@ -821,23 +831,23 @@ pub fn readFromPackedMemory(
821 128 => .{ .f128 = @bitCast(std.mem.readPackedInt(u128, buffer, bit_offset, endian)) },831 128 => .{ .f128 = @bitCast(std.mem.readPackedInt(u128, buffer, bit_offset, endian)) },
822 else => unreachable,832 else => unreachable,
823 },833 },
824 } }))),834 } })),
825 .Vector => {835 .Vector => {
826 const elem_ty = ty.childType(mod);836 const elem_ty = ty.childType(mod);
827 const elems = try arena.alloc(InternPool.Index, @intCast(ty.arrayLen(mod)));837 const elems = try arena.alloc(InternPool.Index, @intCast(ty.arrayLen(mod)));
828838
829 var bits: u16 = 0;839 var bits: u16 = 0;
830 const elem_bit_size: u16 = @intCast(elem_ty.bitSize(mod));840 const elem_bit_size: u16 = @intCast(elem_ty.bitSize(pt));
831 for (elems, 0..) |_, i| {841 for (elems, 0..) |_, i| {
832 // On big-endian systems, LLVM reverses the element order of vectors by default842 // On big-endian systems, LLVM reverses the element order of vectors by default
833 const tgt_elem_i = if (endian == .big) elems.len - i - 1 else i;843 const tgt_elem_i = if (endian == .big) elems.len - i - 1 else i;
834 elems[tgt_elem_i] = (try readFromPackedMemory(elem_ty, mod, buffer, bit_offset + bits, arena)).toIntern();844 elems[tgt_elem_i] = (try readFromPackedMemory(elem_ty, pt, buffer, bit_offset + bits, arena)).toIntern();
835 bits += elem_bit_size;845 bits += elem_bit_size;
836 }846 }
837 return Value.fromInterned((try mod.intern(.{ .aggregate = .{847 return Value.fromInterned(try pt.intern(.{ .aggregate = .{
838 .ty = ty.toIntern(),848 .ty = ty.toIntern(),
839 .storage = .{ .elems = elems },849 .storage = .{ .elems = elems },
840 } })));850 } }));
841 },851 },
842 .Struct => {852 .Struct => {
843 // Sema is supposed to have emitted a compile error already for Auto layout structs,853 // Sema is supposed to have emitted a compile error already for Auto layout structs,
...@@ -847,43 +857,43 @@ pub fn readFromPackedMemory(...@@ -847,43 +857,43 @@ pub fn readFromPackedMemory(
847 const field_vals = try arena.alloc(InternPool.Index, struct_type.field_types.len);857 const field_vals = try arena.alloc(InternPool.Index, struct_type.field_types.len);
848 for (field_vals, 0..) |*field_val, i| {858 for (field_vals, 0..) |*field_val, i| {
849 const field_ty = Type.fromInterned(struct_type.field_types.get(ip)[i]);859 const field_ty = Type.fromInterned(struct_type.field_types.get(ip)[i]);
850 const field_bits: u16 = @intCast(field_ty.bitSize(mod));860 const field_bits: u16 = @intCast(field_ty.bitSize(pt));
851 field_val.* = (try readFromPackedMemory(field_ty, mod, buffer, bit_offset + bits, arena)).toIntern();861 field_val.* = (try readFromPackedMemory(field_ty, pt, buffer, bit_offset + bits, arena)).toIntern();
852 bits += field_bits;862 bits += field_bits;
853 }863 }
854 return Value.fromInterned((try mod.intern(.{ .aggregate = .{864 return Value.fromInterned(try pt.intern(.{ .aggregate = .{
855 .ty = ty.toIntern(),865 .ty = ty.toIntern(),
856 .storage = .{ .elems = field_vals },866 .storage = .{ .elems = field_vals },
857 } })));867 } }));
858 },868 },
859 .Union => switch (ty.containerLayout(mod)) {869 .Union => switch (ty.containerLayout(mod)) {
860 .auto, .@"extern" => unreachable, // Handled by non-packed readFromMemory870 .auto, .@"extern" => unreachable, // Handled by non-packed readFromMemory
861 .@"packed" => {871 .@"packed" => {
862 const backing_ty = try ty.unionBackingType(mod);872 const backing_ty = try ty.unionBackingType(pt);
863 const val = (try readFromPackedMemory(backing_ty, mod, buffer, bit_offset, arena)).toIntern();873 const val = (try readFromPackedMemory(backing_ty, pt, buffer, bit_offset, arena)).toIntern();
864 return Value.fromInterned((try mod.intern(.{ .un = .{874 return Value.fromInterned(try pt.intern(.{ .un = .{
865 .ty = ty.toIntern(),875 .ty = ty.toIntern(),
866 .tag = .none,876 .tag = .none,
867 .val = val,877 .val = val,
868 } })));878 } }));
869 },879 },
870 },880 },
871 .Pointer => {881 .Pointer => {
872 assert(!ty.isSlice(mod)); // No well defined layout.882 assert(!ty.isSlice(mod)); // No well defined layout.
873 const int_val = try readFromPackedMemory(Type.usize, mod, buffer, bit_offset, arena);883 const int_val = try readFromPackedMemory(Type.usize, pt, buffer, bit_offset, arena);
874 return Value.fromInterned(try mod.intern(.{ .ptr = .{884 return Value.fromInterned(try pt.intern(.{ .ptr = .{
875 .ty = ty.toIntern(),885 .ty = ty.toIntern(),
876 .base_addr = .int,886 .base_addr = .int,
877 .byte_offset = int_val.toUnsignedInt(mod),887 .byte_offset = int_val.toUnsignedInt(pt),
878 } }));888 } }));
879 },889 },
880 .Optional => {890 .Optional => {
881 assert(ty.isPtrLikeOptional(mod));891 assert(ty.isPtrLikeOptional(mod));
882 const child_ty = ty.optionalChild(mod);892 const child_ty = ty.optionalChild(mod);
883 const child_val = try readFromPackedMemory(child_ty, mod, buffer, bit_offset, arena);893 const child_val = try readFromPackedMemory(child_ty, pt, buffer, bit_offset, arena);
884 return Value.fromInterned(try mod.intern(.{ .opt = .{894 return Value.fromInterned(try pt.intern(.{ .opt = .{
885 .ty = ty.toIntern(),895 .ty = ty.toIntern(),
886 .val = switch (child_val.orderAgainstZero(mod)) {896 .val = switch (child_val.orderAgainstZero(pt)) {
887 .lt => unreachable,897 .lt => unreachable,
888 .eq => .none,898 .eq => .none,
889 .gt => child_val.toIntern(),899 .gt => child_val.toIntern(),
...@@ -895,8 +905,8 @@ pub fn readFromPackedMemory(...@@ -895,8 +905,8 @@ pub fn readFromPackedMemory(
895}905}
896906
897/// Asserts that the value is a float or an integer.907/// Asserts that the value is a float or an integer.
898pub fn toFloat(val: Value, comptime T: type, mod: *Module) T {908pub fn toFloat(val: Value, comptime T: type, pt: Zcu.PerThread) T {
899 return switch (mod.intern_pool.indexToKey(val.toIntern())) {909 return switch (pt.zcu.intern_pool.indexToKey(val.toIntern())) {
900 .int => |int| switch (int.storage) {910 .int => |int| switch (int.storage) {
901 .big_int => |big_int| @floatCast(bigIntToFloat(big_int.limbs, big_int.positive)),911 .big_int => |big_int| @floatCast(bigIntToFloat(big_int.limbs, big_int.positive)),
902 inline .u64, .i64 => |x| {912 inline .u64, .i64 => |x| {
...@@ -905,8 +915,8 @@ pub fn toFloat(val: Value, comptime T: type, mod: *Module) T {...@@ -905,8 +915,8 @@ pub fn toFloat(val: Value, comptime T: type, mod: *Module) T {
905 }915 }
906 return @floatFromInt(x);916 return @floatFromInt(x);
907 },917 },
908 .lazy_align => |ty| @floatFromInt(Type.fromInterned(ty).abiAlignment(mod).toByteUnits() orelse 0),918 .lazy_align => |ty| @floatFromInt(Type.fromInterned(ty).abiAlignment(pt).toByteUnits() orelse 0),
909 .lazy_size => |ty| @floatFromInt(Type.fromInterned(ty).abiSize(mod)),919 .lazy_size => |ty| @floatFromInt(Type.fromInterned(ty).abiSize(pt)),
910 },920 },
911 .float => |float| switch (float.storage) {921 .float => |float| switch (float.storage) {
912 inline else => |x| @floatCast(x),922 inline else => |x| @floatCast(x),
...@@ -934,29 +944,30 @@ fn bigIntToFloat(limbs: []const std.math.big.Limb, positive: bool) f128 {...@@ -934,29 +944,30 @@ fn bigIntToFloat(limbs: []const std.math.big.Limb, positive: bool) f128 {
934 }944 }
935}945}
936946
937pub fn clz(val: Value, ty: Type, mod: *Module) u64 {947pub fn clz(val: Value, ty: Type, pt: Zcu.PerThread) u64 {
938 var bigint_buf: BigIntSpace = undefined;948 var bigint_buf: BigIntSpace = undefined;
939 const bigint = val.toBigInt(&bigint_buf, mod);949 const bigint = val.toBigInt(&bigint_buf, pt);
940 return bigint.clz(ty.intInfo(mod).bits);950 return bigint.clz(ty.intInfo(pt.zcu).bits);
941}951}
942952
943pub fn ctz(val: Value, ty: Type, mod: *Module) u64 {953pub fn ctz(val: Value, ty: Type, pt: Zcu.PerThread) u64 {
944 var bigint_buf: BigIntSpace = undefined;954 var bigint_buf: BigIntSpace = undefined;
945 const bigint = val.toBigInt(&bigint_buf, mod);955 const bigint = val.toBigInt(&bigint_buf, pt);
946 return bigint.ctz(ty.intInfo(mod).bits);956 return bigint.ctz(ty.intInfo(pt.zcu).bits);
947}957}
948958
949pub fn popCount(val: Value, ty: Type, mod: *Module) u64 {959pub fn popCount(val: Value, ty: Type, pt: Zcu.PerThread) u64 {
950 var bigint_buf: BigIntSpace = undefined;960 var bigint_buf: BigIntSpace = undefined;
951 const bigint = val.toBigInt(&bigint_buf, mod);961 const bigint = val.toBigInt(&bigint_buf, pt);
952 return @intCast(bigint.popCount(ty.intInfo(mod).bits));962 return @intCast(bigint.popCount(ty.intInfo(pt.zcu).bits));
953}963}
954964
955pub fn bitReverse(val: Value, ty: Type, mod: *Module, arena: Allocator) !Value {965pub fn bitReverse(val: Value, ty: Type, pt: Zcu.PerThread, arena: Allocator) !Value {
966 const mod = pt.zcu;
956 const info = ty.intInfo(mod);967 const info = ty.intInfo(mod);
957968
958 var buffer: Value.BigIntSpace = undefined;969 var buffer: Value.BigIntSpace = undefined;
959 const operand_bigint = val.toBigInt(&buffer, mod);970 const operand_bigint = val.toBigInt(&buffer, pt);
960971
961 const limbs = try arena.alloc(972 const limbs = try arena.alloc(
962 std.math.big.Limb,973 std.math.big.Limb,
...@@ -965,17 +976,18 @@ pub fn bitReverse(val: Value, ty: Type, mod: *Module, arena: Allocator) !Value {...@@ -965,17 +976,18 @@ pub fn bitReverse(val: Value, ty: Type, mod: *Module, arena: Allocator) !Value {
965 var result_bigint = BigIntMutable{ .limbs = limbs, .positive = undefined, .len = undefined };976 var result_bigint = BigIntMutable{ .limbs = limbs, .positive = undefined, .len = undefined };
966 result_bigint.bitReverse(operand_bigint, info.signedness, info.bits);977 result_bigint.bitReverse(operand_bigint, info.signedness, info.bits);
967978
968 return mod.intValue_big(ty, result_bigint.toConst());979 return pt.intValue_big(ty, result_bigint.toConst());
969}980}
970981
971pub fn byteSwap(val: Value, ty: Type, mod: *Module, arena: Allocator) !Value {982pub fn byteSwap(val: Value, ty: Type, pt: Zcu.PerThread, arena: Allocator) !Value {
983 const mod = pt.zcu;
972 const info = ty.intInfo(mod);984 const info = ty.intInfo(mod);
973985
974 // Bit count must be evenly divisible by 8986 // Bit count must be evenly divisible by 8
975 assert(info.bits % 8 == 0);987 assert(info.bits % 8 == 0);
976988
977 var buffer: Value.BigIntSpace = undefined;989 var buffer: Value.BigIntSpace = undefined;
978 const operand_bigint = val.toBigInt(&buffer, mod);990 const operand_bigint = val.toBigInt(&buffer, pt);
979991
980 const limbs = try arena.alloc(992 const limbs = try arena.alloc(
981 std.math.big.Limb,993 std.math.big.Limb,
...@@ -984,33 +996,33 @@ pub fn byteSwap(val: Value, ty: Type, mod: *Module, arena: Allocator) !Value {...@@ -984,33 +996,33 @@ pub fn byteSwap(val: Value, ty: Type, mod: *Module, arena: Allocator) !Value {
984 var result_bigint = BigIntMutable{ .limbs = limbs, .positive = undefined, .len = undefined };996 var result_bigint = BigIntMutable{ .limbs = limbs, .positive = undefined, .len = undefined };
985 result_bigint.byteSwap(operand_bigint, info.signedness, info.bits / 8);997 result_bigint.byteSwap(operand_bigint, info.signedness, info.bits / 8);
986998
987 return mod.intValue_big(ty, result_bigint.toConst());999 return pt.intValue_big(ty, result_bigint.toConst());
988}1000}
9891001
990/// Asserts the value is an integer and not undefined.1002/// Asserts the value is an integer and not undefined.
991/// Returns the number of bits the value requires to represent stored in twos complement form.1003/// Returns the number of bits the value requires to represent stored in twos complement form.
992pub fn intBitCountTwosComp(self: Value, mod: *Module) usize {1004pub fn intBitCountTwosComp(self: Value, pt: Zcu.PerThread) usize {
993 var buffer: BigIntSpace = undefined;1005 var buffer: BigIntSpace = undefined;
994 const big_int = self.toBigInt(&buffer, mod);1006 const big_int = self.toBigInt(&buffer, pt);
995 return big_int.bitCountTwosComp();1007 return big_int.bitCountTwosComp();
996}1008}
9971009
998/// Converts an integer or a float to a float. May result in a loss of information.1010/// Converts an integer or a float to a float. May result in a loss of information.
999/// Caller can find out by equality checking the result against the operand.1011/// Caller can find out by equality checking the result against the operand.
1000pub fn floatCast(val: Value, dest_ty: Type, zcu: *Zcu) !Value {1012pub fn floatCast(val: Value, dest_ty: Type, pt: Zcu.PerThread) !Value {
1001 const target = zcu.getTarget();1013 const target = pt.zcu.getTarget();
1002 if (val.isUndef(zcu)) return zcu.undefValue(dest_ty);1014 if (val.isUndef(pt.zcu)) return pt.undefValue(dest_ty);
1003 return Value.fromInterned((try zcu.intern(.{ .float = .{1015 return Value.fromInterned(try pt.intern(.{ .float = .{
1004 .ty = dest_ty.toIntern(),1016 .ty = dest_ty.toIntern(),
1005 .storage = switch (dest_ty.floatBits(target)) {1017 .storage = switch (dest_ty.floatBits(target)) {
1006 16 => .{ .f16 = val.toFloat(f16, zcu) },1018 16 => .{ .f16 = val.toFloat(f16, pt) },
1007 32 => .{ .f32 = val.toFloat(f32, zcu) },1019 32 => .{ .f32 = val.toFloat(f32, pt) },
1008 64 => .{ .f64 = val.toFloat(f64, zcu) },1020 64 => .{ .f64 = val.toFloat(f64, pt) },
1009 80 => .{ .f80 = val.toFloat(f80, zcu) },1021 80 => .{ .f80 = val.toFloat(f80, pt) },
1010 128 => .{ .f128 = val.toFloat(f128, zcu) },1022 128 => .{ .f128 = val.toFloat(f128, pt) },
1011 else => unreachable,1023 else => unreachable,
1012 },1024 },
1013 } })));1025 } }));
1014}1026}
10151027
1016/// Asserts the value is a float1028/// Asserts the value is a float
...@@ -1023,19 +1035,19 @@ pub fn floatHasFraction(self: Value, mod: *const Module) bool {...@@ -1023,19 +1035,19 @@ pub fn floatHasFraction(self: Value, mod: *const Module) bool {
1023 };1035 };
1024}1036}
10251037
1026pub fn orderAgainstZero(lhs: Value, mod: *Module) std.math.Order {1038pub fn orderAgainstZero(lhs: Value, pt: Zcu.PerThread) std.math.Order {
1027 return orderAgainstZeroAdvanced(lhs, mod, .normal) catch unreachable;1039 return orderAgainstZeroAdvanced(lhs, pt, .normal) catch unreachable;
1028}1040}
10291041
1030pub fn orderAgainstZeroAdvanced(1042pub fn orderAgainstZeroAdvanced(
1031 lhs: Value,1043 lhs: Value,
1032 mod: *Module,1044 pt: Zcu.PerThread,
1033 strat: ResolveStrat,1045 strat: ResolveStrat,
1034) Module.CompileError!std.math.Order {1046) Module.CompileError!std.math.Order {
1035 return switch (lhs.toIntern()) {1047 return switch (lhs.toIntern()) {
1036 .bool_false => .eq,1048 .bool_false => .eq,
1037 .bool_true => .gt,1049 .bool_true => .gt,
1038 else => switch (mod.intern_pool.indexToKey(lhs.toIntern())) {1050 else => switch (pt.zcu.intern_pool.indexToKey(lhs.toIntern())) {
1039 .ptr => |ptr| if (ptr.byte_offset > 0) .gt else switch (ptr.base_addr) {1051 .ptr => |ptr| if (ptr.byte_offset > 0) .gt else switch (ptr.base_addr) {
1040 .decl, .comptime_alloc, .comptime_field => .gt,1052 .decl, .comptime_alloc, .comptime_field => .gt,
1041 .int => .eq,1053 .int => .eq,
...@@ -1046,7 +1058,7 @@ pub fn orderAgainstZeroAdvanced(...@@ -1046,7 +1058,7 @@ pub fn orderAgainstZeroAdvanced(
1046 inline .u64, .i64 => |x| std.math.order(x, 0),1058 inline .u64, .i64 => |x| std.math.order(x, 0),
1047 .lazy_align => .gt, // alignment is never 01059 .lazy_align => .gt, // alignment is never 0
1048 .lazy_size => |ty| return if (Type.fromInterned(ty).hasRuntimeBitsAdvanced(1060 .lazy_size => |ty| return if (Type.fromInterned(ty).hasRuntimeBitsAdvanced(
1049 mod,1061 pt,
1050 false,1062 false,
1051 strat.toLazy(),1063 strat.toLazy(),
1052 ) catch |err| switch (err) {1064 ) catch |err| switch (err) {
...@@ -1054,7 +1066,7 @@ pub fn orderAgainstZeroAdvanced(...@@ -1054,7 +1066,7 @@ pub fn orderAgainstZeroAdvanced(
1054 else => |e| return e,1066 else => |e| return e,
1055 }) .gt else .eq,1067 }) .gt else .eq,
1056 },1068 },
1057 .enum_tag => |enum_tag| Value.fromInterned(enum_tag.int).orderAgainstZeroAdvanced(mod, strat),1069 .enum_tag => |enum_tag| Value.fromInterned(enum_tag.int).orderAgainstZeroAdvanced(pt, strat),
1058 .float => |float| switch (float.storage) {1070 .float => |float| switch (float.storage) {
1059 inline else => |x| std.math.order(x, 0),1071 inline else => |x| std.math.order(x, 0),
1060 },1072 },
...@@ -1064,14 +1076,14 @@ pub fn orderAgainstZeroAdvanced(...@@ -1064,14 +1076,14 @@ pub fn orderAgainstZeroAdvanced(
1064}1076}
10651077
1066/// Asserts the value is comparable.1078/// Asserts the value is comparable.
1067pub fn order(lhs: Value, rhs: Value, mod: *Module) std.math.Order {1079pub fn order(lhs: Value, rhs: Value, pt: Zcu.PerThread) std.math.Order {
1068 return orderAdvanced(lhs, rhs, mod, .normal) catch unreachable;1080 return orderAdvanced(lhs, rhs, pt, .normal) catch unreachable;
1069}1081}
10701082
1071/// Asserts the value is comparable.1083/// Asserts the value is comparable.
1072pub fn orderAdvanced(lhs: Value, rhs: Value, mod: *Module, strat: ResolveStrat) !std.math.Order {1084pub fn orderAdvanced(lhs: Value, rhs: Value, pt: Zcu.PerThread, strat: ResolveStrat) !std.math.Order {
1073 const lhs_against_zero = try lhs.orderAgainstZeroAdvanced(mod, strat);1085 const lhs_against_zero = try lhs.orderAgainstZeroAdvanced(pt, strat);
1074 const rhs_against_zero = try rhs.orderAgainstZeroAdvanced(mod, strat);1086 const rhs_against_zero = try rhs.orderAgainstZeroAdvanced(pt, strat);
1075 switch (lhs_against_zero) {1087 switch (lhs_against_zero) {
1076 .lt => if (rhs_against_zero != .lt) return .lt,1088 .lt => if (rhs_against_zero != .lt) return .lt,
1077 .eq => return rhs_against_zero.invert(),1089 .eq => return rhs_against_zero.invert(),
...@@ -1083,34 +1095,34 @@ pub fn orderAdvanced(lhs: Value, rhs: Value, mod: *Module, strat: ResolveStrat)...@@ -1083,34 +1095,34 @@ pub fn orderAdvanced(lhs: Value, rhs: Value, mod: *Module, strat: ResolveStrat)
1083 .gt => {},1095 .gt => {},
1084 }1096 }
10851097
1086 if (lhs.isFloat(mod) or rhs.isFloat(mod)) {1098 if (lhs.isFloat(pt.zcu) or rhs.isFloat(pt.zcu)) {
1087 const lhs_f128 = lhs.toFloat(f128, mod);1099 const lhs_f128 = lhs.toFloat(f128, pt);
1088 const rhs_f128 = rhs.toFloat(f128, mod);1100 const rhs_f128 = rhs.toFloat(f128, pt);
1089 return std.math.order(lhs_f128, rhs_f128);1101 return std.math.order(lhs_f128, rhs_f128);
1090 }1102 }
10911103
1092 var lhs_bigint_space: BigIntSpace = undefined;1104 var lhs_bigint_space: BigIntSpace = undefined;
1093 var rhs_bigint_space: BigIntSpace = undefined;1105 var rhs_bigint_space: BigIntSpace = undefined;
1094 const lhs_bigint = try lhs.toBigIntAdvanced(&lhs_bigint_space, mod, strat);1106 const lhs_bigint = try lhs.toBigIntAdvanced(&lhs_bigint_space, pt, strat);
1095 const rhs_bigint = try rhs.toBigIntAdvanced(&rhs_bigint_space, mod, strat);1107 const rhs_bigint = try rhs.toBigIntAdvanced(&rhs_bigint_space, pt, strat);
1096 return lhs_bigint.order(rhs_bigint);1108 return lhs_bigint.order(rhs_bigint);
1097}1109}
10981110
1099/// Asserts the value is comparable. Does not take a type parameter because it supports1111/// Asserts the value is comparable. Does not take a type parameter because it supports
1100/// comparisons between heterogeneous types.1112/// comparisons between heterogeneous types.
1101pub fn compareHetero(lhs: Value, op: std.math.CompareOperator, rhs: Value, mod: *Module) bool {1113pub fn compareHetero(lhs: Value, op: std.math.CompareOperator, rhs: Value, pt: Zcu.PerThread) bool {
1102 return compareHeteroAdvanced(lhs, op, rhs, mod, .normal) catch unreachable;1114 return compareHeteroAdvanced(lhs, op, rhs, pt, .normal) catch unreachable;
1103}1115}
11041116
1105pub fn compareHeteroAdvanced(1117pub fn compareHeteroAdvanced(
1106 lhs: Value,1118 lhs: Value,
1107 op: std.math.CompareOperator,1119 op: std.math.CompareOperator,
1108 rhs: Value,1120 rhs: Value,
1109 mod: *Module,1121 pt: Zcu.PerThread,
1110 strat: ResolveStrat,1122 strat: ResolveStrat,
1111) !bool {1123) !bool {
1112 if (lhs.pointerDecl(mod)) |lhs_decl| {1124 if (lhs.pointerDecl(pt.zcu)) |lhs_decl| {
1113 if (rhs.pointerDecl(mod)) |rhs_decl| {1125 if (rhs.pointerDecl(pt.zcu)) |rhs_decl| {
1114 switch (op) {1126 switch (op) {
1115 .eq => return lhs_decl == rhs_decl,1127 .eq => return lhs_decl == rhs_decl,
1116 .neq => return lhs_decl != rhs_decl,1128 .neq => return lhs_decl != rhs_decl,
...@@ -1123,31 +1135,32 @@ pub fn compareHeteroAdvanced(...@@ -1123,31 +1135,32 @@ pub fn compareHeteroAdvanced(
1123 else => {},1135 else => {},
1124 }1136 }
1125 }1137 }
1126 } else if (rhs.pointerDecl(mod)) |_| {1138 } else if (rhs.pointerDecl(pt.zcu)) |_| {
1127 switch (op) {1139 switch (op) {
1128 .eq => return false,1140 .eq => return false,
1129 .neq => return true,1141 .neq => return true,
1130 else => {},1142 else => {},
1131 }1143 }
1132 }1144 }
1133 return (try orderAdvanced(lhs, rhs, mod, strat)).compare(op);1145 return (try orderAdvanced(lhs, rhs, pt, strat)).compare(op);
1134}1146}
11351147
1136/// Asserts the values are comparable. Both operands have type `ty`.1148/// Asserts the values are comparable. Both operands have type `ty`.
1137/// For vectors, returns true if comparison is true for ALL elements.1149/// For vectors, returns true if comparison is true for ALL elements.
1138pub fn compareAll(lhs: Value, op: std.math.CompareOperator, rhs: Value, ty: Type, mod: *Module) !bool {1150pub fn compareAll(lhs: Value, op: std.math.CompareOperator, rhs: Value, ty: Type, pt: Zcu.PerThread) !bool {
1151 const mod = pt.zcu;
1139 if (ty.zigTypeTag(mod) == .Vector) {1152 if (ty.zigTypeTag(mod) == .Vector) {
1140 const scalar_ty = ty.scalarType(mod);1153 const scalar_ty = ty.scalarType(mod);
1141 for (0..ty.vectorLen(mod)) |i| {1154 for (0..ty.vectorLen(mod)) |i| {
1142 const lhs_elem = try lhs.elemValue(mod, i);1155 const lhs_elem = try lhs.elemValue(pt, i);
1143 const rhs_elem = try rhs.elemValue(mod, i);1156 const rhs_elem = try rhs.elemValue(pt, i);
1144 if (!compareScalar(lhs_elem, op, rhs_elem, scalar_ty, mod)) {1157 if (!compareScalar(lhs_elem, op, rhs_elem, scalar_ty, pt)) {
1145 return false;1158 return false;
1146 }1159 }
1147 }1160 }
1148 return true;1161 return true;
1149 }1162 }
1150 return compareScalar(lhs, op, rhs, ty, mod);1163 return compareScalar(lhs, op, rhs, ty, pt);
1151}1164}
11521165
1153/// Asserts the values are comparable. Both operands have type `ty`.1166/// Asserts the values are comparable. Both operands have type `ty`.
...@@ -1156,12 +1169,12 @@ pub fn compareScalar(...@@ -1156,12 +1169,12 @@ pub fn compareScalar(
1156 op: std.math.CompareOperator,1169 op: std.math.CompareOperator,
1157 rhs: Value,1170 rhs: Value,
1158 ty: Type,1171 ty: Type,
1159 mod: *Module,1172 pt: Zcu.PerThread,
1160) bool {1173) bool {
1161 return switch (op) {1174 return switch (op) {
1162 .eq => lhs.eql(rhs, ty, mod),1175 .eq => lhs.eql(rhs, ty, pt.zcu),
1163 .neq => !lhs.eql(rhs, ty, mod),1176 .neq => !lhs.eql(rhs, ty, pt.zcu),
1164 else => compareHetero(lhs, op, rhs, mod),1177 else => compareHetero(lhs, op, rhs, pt),
1165 };1178 };
1166}1179}
11671180
...@@ -1170,24 +1183,25 @@ pub fn compareScalar(...@@ -1170,24 +1183,25 @@ pub fn compareScalar(
1170/// Returns `false` if the value or any vector element is undefined.1183/// Returns `false` if the value or any vector element is undefined.
1171///1184///
1172/// Note that `!compareAllWithZero(.eq, ...) != compareAllWithZero(.neq, ...)`1185/// Note that `!compareAllWithZero(.eq, ...) != compareAllWithZero(.neq, ...)`
1173pub fn compareAllWithZero(lhs: Value, op: std.math.CompareOperator, mod: *Module) bool {1186pub fn compareAllWithZero(lhs: Value, op: std.math.CompareOperator, pt: Zcu.PerThread) bool {
1174 return compareAllWithZeroAdvancedExtra(lhs, op, mod, .normal) catch unreachable;1187 return compareAllWithZeroAdvancedExtra(lhs, op, pt, .normal) catch unreachable;
1175}1188}
11761189
1177pub fn compareAllWithZeroSema(1190pub fn compareAllWithZeroSema(
1178 lhs: Value,1191 lhs: Value,
1179 op: std.math.CompareOperator,1192 op: std.math.CompareOperator,
1180 zcu: *Zcu,1193 pt: Zcu.PerThread,
1181) Module.CompileError!bool {1194) Module.CompileError!bool {
1182 return compareAllWithZeroAdvancedExtra(lhs, op, zcu, .sema);1195 return compareAllWithZeroAdvancedExtra(lhs, op, pt, .sema);
1183}1196}
11841197
1185pub fn compareAllWithZeroAdvancedExtra(1198pub fn compareAllWithZeroAdvancedExtra(
1186 lhs: Value,1199 lhs: Value,
1187 op: std.math.CompareOperator,1200 op: std.math.CompareOperator,
1188 mod: *Module,1201 pt: Zcu.PerThread,
1189 strat: ResolveStrat,1202 strat: ResolveStrat,
1190) Module.CompileError!bool {1203) Module.CompileError!bool {
1204 const mod = pt.zcu;
1191 if (lhs.isInf(mod)) {1205 if (lhs.isInf(mod)) {
1192 switch (op) {1206 switch (op) {
1193 .neq => return true,1207 .neq => return true,
...@@ -1206,14 +1220,14 @@ pub fn compareAllWithZeroAdvancedExtra(...@@ -1206,14 +1220,14 @@ pub fn compareAllWithZeroAdvancedExtra(
1206 if (!std.math.order(byte, 0).compare(op)) break false;1220 if (!std.math.order(byte, 0).compare(op)) break false;
1207 } else true,1221 } else true,
1208 .elems => |elems| for (elems) |elem| {1222 .elems => |elems| for (elems) |elem| {
1209 if (!try Value.fromInterned(elem).compareAllWithZeroAdvancedExtra(op, mod, strat)) break false;1223 if (!try Value.fromInterned(elem).compareAllWithZeroAdvancedExtra(op, pt, strat)) break false;
1210 } else true,1224 } else true,
1211 .repeated_elem => |elem| Value.fromInterned(elem).compareAllWithZeroAdvancedExtra(op, mod, strat),1225 .repeated_elem => |elem| Value.fromInterned(elem).compareAllWithZeroAdvancedExtra(op, pt, strat),
1212 },1226 },
1213 .undef => return false,1227 .undef => return false,
1214 else => {},1228 else => {},
1215 }1229 }
1216 return (try orderAgainstZeroAdvanced(lhs, mod, strat)).compare(op);1230 return (try orderAgainstZeroAdvanced(lhs, pt, strat)).compare(op);
1217}1231}
12181232
1219pub fn eql(a: Value, b: Value, ty: Type, mod: *Module) bool {1233pub fn eql(a: Value, b: Value, ty: Type, mod: *Module) bool {
...@@ -1275,21 +1289,22 @@ pub fn slicePtr(val: Value, mod: *Module) Value {...@@ -1275,21 +1289,22 @@ pub fn slicePtr(val: Value, mod: *Module) Value {
12751289
1276/// Gets the `len` field of a slice value as a `u64`.1290/// Gets the `len` field of a slice value as a `u64`.
1277/// Resolves the length using `Sema` if necessary.1291/// Resolves the length using `Sema` if necessary.
1278pub fn sliceLen(val: Value, zcu: *Zcu) !u64 {1292pub fn sliceLen(val: Value, pt: Zcu.PerThread) !u64 {
1279 return Value.fromInterned(zcu.intern_pool.sliceLen(val.toIntern())).toUnsignedIntSema(zcu);1293 return Value.fromInterned(pt.zcu.intern_pool.sliceLen(val.toIntern())).toUnsignedIntSema(pt);
1280}1294}
12811295
1282/// Asserts the value is an aggregate, and returns the element value at the given index.1296/// Asserts the value is an aggregate, and returns the element value at the given index.
1283pub fn elemValue(val: Value, zcu: *Zcu, index: usize) Allocator.Error!Value {1297pub fn elemValue(val: Value, pt: Zcu.PerThread, index: usize) Allocator.Error!Value {
1298 const zcu = pt.zcu;
1284 const ip = &zcu.intern_pool;1299 const ip = &zcu.intern_pool;
1285 switch (zcu.intern_pool.indexToKey(val.toIntern())) {1300 switch (zcu.intern_pool.indexToKey(val.toIntern())) {
1286 .undef => |ty| {1301 .undef => |ty| {
1287 return Value.fromInterned(try zcu.intern(.{ .undef = Type.fromInterned(ty).childType(zcu).toIntern() }));1302 return Value.fromInterned(try pt.intern(.{ .undef = Type.fromInterned(ty).childType(zcu).toIntern() }));
1288 },1303 },
1289 .aggregate => |aggregate| {1304 .aggregate => |aggregate| {
1290 const len = ip.aggregateTypeLen(aggregate.ty);1305 const len = ip.aggregateTypeLen(aggregate.ty);
1291 if (index < len) return Value.fromInterned(switch (aggregate.storage) {1306 if (index < len) return Value.fromInterned(switch (aggregate.storage) {
1292 .bytes => |bytes| try zcu.intern(.{ .int = .{1307 .bytes => |bytes| try pt.intern(.{ .int = .{
1293 .ty = .u8_type,1308 .ty = .u8_type,
1294 .storage = .{ .u64 = bytes.at(index, ip) },1309 .storage = .{ .u64 = bytes.at(index, ip) },
1295 } }),1310 } }),
...@@ -1330,17 +1345,17 @@ pub fn sliceArray(...@@ -1330,17 +1345,17 @@ pub fn sliceArray(
1330 start: usize,1345 start: usize,
1331 end: usize,1346 end: usize,
1332) error{OutOfMemory}!Value {1347) error{OutOfMemory}!Value {
1333 const mod = sema.mod;1348 const pt = sema.pt;
1334 const ip = &mod.intern_pool;1349 const ip = &pt.zcu.intern_pool;
1335 return Value.fromInterned(try mod.intern(.{1350 return Value.fromInterned(try pt.intern(.{
1336 .aggregate = .{1351 .aggregate = .{
1337 .ty = switch (mod.intern_pool.indexToKey(mod.intern_pool.typeOf(val.toIntern()))) {1352 .ty = switch (pt.zcu.intern_pool.indexToKey(pt.zcu.intern_pool.typeOf(val.toIntern()))) {
1338 .array_type => |array_type| try mod.arrayType(.{1353 .array_type => |array_type| try pt.arrayType(.{
1339 .len = @intCast(end - start),1354 .len = @intCast(end - start),
1340 .child = array_type.child,1355 .child = array_type.child,
1341 .sentinel = if (end == array_type.len) array_type.sentinel else .none,1356 .sentinel = if (end == array_type.len) array_type.sentinel else .none,
1342 }),1357 }),
1343 .vector_type => |vector_type| try mod.vectorType(.{1358 .vector_type => |vector_type| try pt.vectorType(.{
1344 .len = @intCast(end - start),1359 .len = @intCast(end - start),
1345 .child = vector_type.child,1360 .child = vector_type.child,
1346 }),1361 }),
...@@ -1363,13 +1378,14 @@ pub fn sliceArray(...@@ -1363,13 +1378,14 @@ pub fn sliceArray(
1363 }));1378 }));
1364}1379}
13651380
1366pub fn fieldValue(val: Value, mod: *Module, index: usize) !Value {1381pub fn fieldValue(val: Value, pt: Zcu.PerThread, index: usize) !Value {
1382 const mod = pt.zcu;
1367 return switch (mod.intern_pool.indexToKey(val.toIntern())) {1383 return switch (mod.intern_pool.indexToKey(val.toIntern())) {
1368 .undef => |ty| Value.fromInterned((try mod.intern(.{1384 .undef => |ty| Value.fromInterned(try pt.intern(.{
1369 .undef = Type.fromInterned(ty).structFieldType(index, mod).toIntern(),1385 .undef = Type.fromInterned(ty).structFieldType(index, mod).toIntern(),
1370 }))),1386 })),
1371 .aggregate => |aggregate| Value.fromInterned(switch (aggregate.storage) {1387 .aggregate => |aggregate| Value.fromInterned(switch (aggregate.storage) {
1372 .bytes => |bytes| try mod.intern(.{ .int = .{1388 .bytes => |bytes| try pt.intern(.{ .int = .{
1373 .ty = .u8_type,1389 .ty = .u8_type,
1374 .storage = .{ .u64 = bytes.at(index, &mod.intern_pool) },1390 .storage = .{ .u64 = bytes.at(index, &mod.intern_pool) },
1375 } }),1391 } }),
...@@ -1483,40 +1499,49 @@ pub fn floatFromInt(val: Value, arena: Allocator, int_ty: Type, float_ty: Type,...@@ -1483,40 +1499,49 @@ pub fn floatFromInt(val: Value, arena: Allocator, int_ty: Type, float_ty: Type,
1483 };1499 };
1484}1500}
14851501
1486pub fn floatFromIntAdvanced(val: Value, arena: Allocator, int_ty: Type, float_ty: Type, mod: *Module, strat: ResolveStrat) !Value {1502pub fn floatFromIntAdvanced(
1503 val: Value,
1504 arena: Allocator,
1505 int_ty: Type,
1506 float_ty: Type,
1507 pt: Zcu.PerThread,
1508 strat: ResolveStrat,
1509) !Value {
1510 const mod = pt.zcu;
1487 if (int_ty.zigTypeTag(mod) == .Vector) {1511 if (int_ty.zigTypeTag(mod) == .Vector) {
1488 const result_data = try arena.alloc(InternPool.Index, int_ty.vectorLen(mod));1512 const result_data = try arena.alloc(InternPool.Index, int_ty.vectorLen(mod));
1489 const scalar_ty = float_ty.scalarType(mod);1513 const scalar_ty = float_ty.scalarType(mod);
1490 for (result_data, 0..) |*scalar, i| {1514 for (result_data, 0..) |*scalar, i| {
1491 const elem_val = try val.elemValue(mod, i);1515 const elem_val = try val.elemValue(pt, i);
1492 scalar.* = (try floatFromIntScalar(elem_val, scalar_ty, mod, strat)).toIntern();1516 scalar.* = (try floatFromIntScalar(elem_val, scalar_ty, pt, strat)).toIntern();
1493 }1517 }
1494 return Value.fromInterned((try mod.intern(.{ .aggregate = .{1518 return Value.fromInterned(try pt.intern(.{ .aggregate = .{
1495 .ty = float_ty.toIntern(),1519 .ty = float_ty.toIntern(),
1496 .storage = .{ .elems = result_data },1520 .storage = .{ .elems = result_data },
1497 } })));1521 } }));
1498 }1522 }
1499 return floatFromIntScalar(val, float_ty, mod, strat);1523 return floatFromIntScalar(val, float_ty, pt, strat);
1500}1524}
15011525
1502pub fn floatFromIntScalar(val: Value, float_ty: Type, mod: *Module, strat: ResolveStrat) !Value {1526pub fn floatFromIntScalar(val: Value, float_ty: Type, pt: Zcu.PerThread, strat: ResolveStrat) !Value {
1527 const mod = pt.zcu;
1503 return switch (mod.intern_pool.indexToKey(val.toIntern())) {1528 return switch (mod.intern_pool.indexToKey(val.toIntern())) {
1504 .undef => try mod.undefValue(float_ty),1529 .undef => try pt.undefValue(float_ty),
1505 .int => |int| switch (int.storage) {1530 .int => |int| switch (int.storage) {
1506 .big_int => |big_int| {1531 .big_int => |big_int| {
1507 const float = bigIntToFloat(big_int.limbs, big_int.positive);1532 const float = bigIntToFloat(big_int.limbs, big_int.positive);
1508 return mod.floatValue(float_ty, float);1533 return pt.floatValue(float_ty, float);
1509 },1534 },
1510 inline .u64, .i64 => |x| floatFromIntInner(x, float_ty, mod),1535 inline .u64, .i64 => |x| floatFromIntInner(x, float_ty, pt),
1511 .lazy_align => |ty| return floatFromIntInner((try Type.fromInterned(ty).abiAlignmentAdvanced(mod, strat.toLazy())).scalar.toByteUnits() orelse 0, float_ty, mod),1536 .lazy_align => |ty| return floatFromIntInner((try Type.fromInterned(ty).abiAlignmentAdvanced(pt, strat.toLazy())).scalar.toByteUnits() orelse 0, float_ty, pt),
1512 .lazy_size => |ty| return floatFromIntInner((try Type.fromInterned(ty).abiSizeAdvanced(mod, strat.toLazy())).scalar, float_ty, mod),1537 .lazy_size => |ty| return floatFromIntInner((try Type.fromInterned(ty).abiSizeAdvanced(pt, strat.toLazy())).scalar, float_ty, pt),
1513 },1538 },
1514 else => unreachable,1539 else => unreachable,
1515 };1540 };
1516}1541}
15171542
1518fn floatFromIntInner(x: anytype, dest_ty: Type, mod: *Module) !Value {1543fn floatFromIntInner(x: anytype, dest_ty: Type, pt: Zcu.PerThread) !Value {
1519 const target = mod.getTarget();1544 const target = pt.zcu.getTarget();
1520 const storage: InternPool.Key.Float.Storage = switch (dest_ty.floatBits(target)) {1545 const storage: InternPool.Key.Float.Storage = switch (dest_ty.floatBits(target)) {
1521 16 => .{ .f16 = @floatFromInt(x) },1546 16 => .{ .f16 = @floatFromInt(x) },
1522 32 => .{ .f32 = @floatFromInt(x) },1547 32 => .{ .f32 = @floatFromInt(x) },
...@@ -1525,10 +1550,10 @@ fn floatFromIntInner(x: anytype, dest_ty: Type, mod: *Module) !Value {...@@ -1525,10 +1550,10 @@ fn floatFromIntInner(x: anytype, dest_ty: Type, mod: *Module) !Value {
1525 128 => .{ .f128 = @floatFromInt(x) },1550 128 => .{ .f128 = @floatFromInt(x) },
1526 else => unreachable,1551 else => unreachable,
1527 };1552 };
1528 return Value.fromInterned((try mod.intern(.{ .float = .{1553 return Value.fromInterned(try pt.intern(.{ .float = .{
1529 .ty = dest_ty.toIntern(),1554 .ty = dest_ty.toIntern(),
1530 .storage = storage,1555 .storage = storage,
1531 } })));1556 } }));
1532}1557}
15331558
1534fn calcLimbLenFloat(scalar: anytype) usize {1559fn calcLimbLenFloat(scalar: anytype) usize {
...@@ -1551,22 +1576,22 @@ pub fn intAddSat(...@@ -1551,22 +1576,22 @@ pub fn intAddSat(
1551 rhs: Value,1576 rhs: Value,
1552 ty: Type,1577 ty: Type,
1553 arena: Allocator,1578 arena: Allocator,
1554 mod: *Module,1579 pt: Zcu.PerThread,
1555) !Value {1580) !Value {
1556 if (ty.zigTypeTag(mod) == .Vector) {1581 if (ty.zigTypeTag(pt.zcu) == .Vector) {
1557 const result_data = try arena.alloc(InternPool.Index, ty.vectorLen(mod));1582 const result_data = try arena.alloc(InternPool.Index, ty.vectorLen(pt.zcu));
1558 const scalar_ty = ty.scalarType(mod);1583 const scalar_ty = ty.scalarType(pt.zcu);
1559 for (result_data, 0..) |*scalar, i| {1584 for (result_data, 0..) |*scalar, i| {
1560 const lhs_elem = try lhs.elemValue(mod, i);1585 const lhs_elem = try lhs.elemValue(pt, i);
1561 const rhs_elem = try rhs.elemValue(mod, i);1586 const rhs_elem = try rhs.elemValue(pt, i);
1562 scalar.* = (try intAddSatScalar(lhs_elem, rhs_elem, scalar_ty, arena, mod)).toIntern();1587 scalar.* = (try intAddSatScalar(lhs_elem, rhs_elem, scalar_ty, arena, pt)).toIntern();
1563 }1588 }
1564 return Value.fromInterned((try mod.intern(.{ .aggregate = .{1589 return Value.fromInterned(try pt.intern(.{ .aggregate = .{
1565 .ty = ty.toIntern(),1590 .ty = ty.toIntern(),
1566 .storage = .{ .elems = result_data },1591 .storage = .{ .elems = result_data },
1567 } })));1592 } }));
1568 }1593 }
1569 return intAddSatScalar(lhs, rhs, ty, arena, mod);1594 return intAddSatScalar(lhs, rhs, ty, arena, pt);
1570}1595}
15711596
1572/// Supports integers only; asserts neither operand is undefined.1597/// Supports integers only; asserts neither operand is undefined.
...@@ -1575,24 +1600,24 @@ pub fn intAddSatScalar(...@@ -1575,24 +1600,24 @@ pub fn intAddSatScalar(
1575 rhs: Value,1600 rhs: Value,
1576 ty: Type,1601 ty: Type,
1577 arena: Allocator,1602 arena: Allocator,
1578 mod: *Module,1603 pt: Zcu.PerThread,
1579) !Value {1604) !Value {
1580 assert(!lhs.isUndef(mod));1605 assert(!lhs.isUndef(pt.zcu));
1581 assert(!rhs.isUndef(mod));1606 assert(!rhs.isUndef(pt.zcu));
15821607
1583 const info = ty.intInfo(mod);1608 const info = ty.intInfo(pt.zcu);
15841609
1585 var lhs_space: Value.BigIntSpace = undefined;1610 var lhs_space: Value.BigIntSpace = undefined;
1586 var rhs_space: Value.BigIntSpace = undefined;1611 var rhs_space: Value.BigIntSpace = undefined;
1587 const lhs_bigint = lhs.toBigInt(&lhs_space, mod);1612 const lhs_bigint = lhs.toBigInt(&lhs_space, pt);
1588 const rhs_bigint = rhs.toBigInt(&rhs_space, mod);1613 const rhs_bigint = rhs.toBigInt(&rhs_space, pt);
1589 const limbs = try arena.alloc(1614 const limbs = try arena.alloc(
1590 std.math.big.Limb,1615 std.math.big.Limb,
1591 std.math.big.int.calcTwosCompLimbCount(info.bits),1616 std.math.big.int.calcTwosCompLimbCount(info.bits),
1592 );1617 );
1593 var result_bigint = BigIntMutable{ .limbs = limbs, .positive = undefined, .len = undefined };1618 var result_bigint = BigIntMutable{ .limbs = limbs, .positive = undefined, .len = undefined };
1594 result_bigint.addSat(lhs_bigint, rhs_bigint, info.signedness, info.bits);1619 result_bigint.addSat(lhs_bigint, rhs_bigint, info.signedness, info.bits);
1595 return mod.intValue_big(ty, result_bigint.toConst());1620 return pt.intValue_big(ty, result_bigint.toConst());
1596}1621}
15971622
1598/// Supports (vectors of) integers only; asserts neither operand is undefined.1623/// Supports (vectors of) integers only; asserts neither operand is undefined.
...@@ -1601,22 +1626,22 @@ pub fn intSubSat(...@@ -1601,22 +1626,22 @@ pub fn intSubSat(
1601 rhs: Value,1626 rhs: Value,
1602 ty: Type,1627 ty: Type,
1603 arena: Allocator,1628 arena: Allocator,
1604 mod: *Module,1629 pt: Zcu.PerThread,
1605) !Value {1630) !Value {
1606 if (ty.zigTypeTag(mod) == .Vector) {1631 if (ty.zigTypeTag(pt.zcu) == .Vector) {
1607 const result_data = try arena.alloc(InternPool.Index, ty.vectorLen(mod));1632 const result_data = try arena.alloc(InternPool.Index, ty.vectorLen(pt.zcu));
1608 const scalar_ty = ty.scalarType(mod);1633 const scalar_ty = ty.scalarType(pt.zcu);
1609 for (result_data, 0..) |*scalar, i| {1634 for (result_data, 0..) |*scalar, i| {
1610 const lhs_elem = try lhs.elemValue(mod, i);1635 const lhs_elem = try lhs.elemValue(pt, i);
1611 const rhs_elem = try rhs.elemValue(mod, i);1636 const rhs_elem = try rhs.elemValue(pt, i);
1612 scalar.* = (try intSubSatScalar(lhs_elem, rhs_elem, scalar_ty, arena, mod)).toIntern();1637 scalar.* = (try intSubSatScalar(lhs_elem, rhs_elem, scalar_ty, arena, pt)).toIntern();
1613 }1638 }
1614 return Value.fromInterned((try mod.intern(.{ .aggregate = .{1639 return Value.fromInterned(try pt.intern(.{ .aggregate = .{
1615 .ty = ty.toIntern(),1640 .ty = ty.toIntern(),
1616 .storage = .{ .elems = result_data },1641 .storage = .{ .elems = result_data },
1617 } })));1642 } }));
1618 }1643 }
1619 return intSubSatScalar(lhs, rhs, ty, arena, mod);1644 return intSubSatScalar(lhs, rhs, ty, arena, pt);
1620}1645}
16211646
1622/// Supports integers only; asserts neither operand is undefined.1647/// Supports integers only; asserts neither operand is undefined.
...@@ -1625,24 +1650,24 @@ pub fn intSubSatScalar(...@@ -1625,24 +1650,24 @@ pub fn intSubSatScalar(
1625 rhs: Value,1650 rhs: Value,
1626 ty: Type,1651 ty: Type,
1627 arena: Allocator,1652 arena: Allocator,
1628 mod: *Module,1653 pt: Zcu.PerThread,
1629) !Value {1654) !Value {
1630 assert(!lhs.isUndef(mod));1655 assert(!lhs.isUndef(pt.zcu));
1631 assert(!rhs.isUndef(mod));1656 assert(!rhs.isUndef(pt.zcu));
16321657
1633 const info = ty.intInfo(mod);1658 const info = ty.intInfo(pt.zcu);
16341659
1635 var lhs_space: Value.BigIntSpace = undefined;1660 var lhs_space: Value.BigIntSpace = undefined;
1636 var rhs_space: Value.BigIntSpace = undefined;1661 var rhs_space: Value.BigIntSpace = undefined;
1637 const lhs_bigint = lhs.toBigInt(&lhs_space, mod);1662 const lhs_bigint = lhs.toBigInt(&lhs_space, pt);
1638 const rhs_bigint = rhs.toBigInt(&rhs_space, mod);1663 const rhs_bigint = rhs.toBigInt(&rhs_space, pt);
1639 const limbs = try arena.alloc(1664 const limbs = try arena.alloc(
1640 std.math.big.Limb,1665 std.math.big.Limb,
1641 std.math.big.int.calcTwosCompLimbCount(info.bits),1666 std.math.big.int.calcTwosCompLimbCount(info.bits),
1642 );1667 );
1643 var result_bigint = BigIntMutable{ .limbs = limbs, .positive = undefined, .len = undefined };1668 var result_bigint = BigIntMutable{ .limbs = limbs, .positive = undefined, .len = undefined };
1644 result_bigint.subSat(lhs_bigint, rhs_bigint, info.signedness, info.bits);1669 result_bigint.subSat(lhs_bigint, rhs_bigint, info.signedness, info.bits);
1645 return mod.intValue_big(ty, result_bigint.toConst());1670 return pt.intValue_big(ty, result_bigint.toConst());
1646}1671}
16471672
1648pub fn intMulWithOverflow(1673pub fn intMulWithOverflow(
...@@ -1650,32 +1675,33 @@ pub fn intMulWithOverflow(...@@ -1650,32 +1675,33 @@ pub fn intMulWithOverflow(
1650 rhs: Value,1675 rhs: Value,
1651 ty: Type,1676 ty: Type,
1652 arena: Allocator,1677 arena: Allocator,
1653 mod: *Module,1678 pt: Zcu.PerThread,
1654) !OverflowArithmeticResult {1679) !OverflowArithmeticResult {
1680 const mod = pt.zcu;
1655 if (ty.zigTypeTag(mod) == .Vector) {1681 if (ty.zigTypeTag(mod) == .Vector) {
1656 const vec_len = ty.vectorLen(mod);1682 const vec_len = ty.vectorLen(mod);
1657 const overflowed_data = try arena.alloc(InternPool.Index, vec_len);1683 const overflowed_data = try arena.alloc(InternPool.Index, vec_len);
1658 const result_data = try arena.alloc(InternPool.Index, vec_len);1684 const result_data = try arena.alloc(InternPool.Index, vec_len);
1659 const scalar_ty = ty.scalarType(mod);1685 const scalar_ty = ty.scalarType(mod);
1660 for (overflowed_data, result_data, 0..) |*of, *scalar, i| {1686 for (overflowed_data, result_data, 0..) |*of, *scalar, i| {
1661 const lhs_elem = try lhs.elemValue(mod, i);1687 const lhs_elem = try lhs.elemValue(pt, i);
1662 const rhs_elem = try rhs.elemValue(mod, i);1688 const rhs_elem = try rhs.elemValue(pt, i);
1663 const of_math_result = try intMulWithOverflowScalar(lhs_elem, rhs_elem, scalar_ty, arena, mod);1689 const of_math_result = try intMulWithOverflowScalar(lhs_elem, rhs_elem, scalar_ty, arena, pt);
1664 of.* = of_math_result.overflow_bit.toIntern();1690 of.* = of_math_result.overflow_bit.toIntern();
1665 scalar.* = of_math_result.wrapped_result.toIntern();1691 scalar.* = of_math_result.wrapped_result.toIntern();
1666 }1692 }
1667 return OverflowArithmeticResult{1693 return OverflowArithmeticResult{
1668 .overflow_bit = Value.fromInterned((try mod.intern(.{ .aggregate = .{1694 .overflow_bit = Value.fromInterned(try pt.intern(.{ .aggregate = .{
1669 .ty = (try mod.vectorType(.{ .len = vec_len, .child = .u1_type })).toIntern(),1695 .ty = (try pt.vectorType(.{ .len = vec_len, .child = .u1_type })).toIntern(),
1670 .storage = .{ .elems = overflowed_data },1696 .storage = .{ .elems = overflowed_data },
1671 } }))),1697 } })),
1672 .wrapped_result = Value.fromInterned((try mod.intern(.{ .aggregate = .{1698 .wrapped_result = Value.fromInterned(try pt.intern(.{ .aggregate = .{
1673 .ty = ty.toIntern(),1699 .ty = ty.toIntern(),
1674 .storage = .{ .elems = result_data },1700 .storage = .{ .elems = result_data },
1675 } }))),1701 } })),
1676 };1702 };
1677 }1703 }
1678 return intMulWithOverflowScalar(lhs, rhs, ty, arena, mod);1704 return intMulWithOverflowScalar(lhs, rhs, ty, arena, pt);
1679}1705}
16801706
1681pub fn intMulWithOverflowScalar(1707pub fn intMulWithOverflowScalar(
...@@ -1683,21 +1709,22 @@ pub fn intMulWithOverflowScalar(...@@ -1683,21 +1709,22 @@ pub fn intMulWithOverflowScalar(
1683 rhs: Value,1709 rhs: Value,
1684 ty: Type,1710 ty: Type,
1685 arena: Allocator,1711 arena: Allocator,
1686 mod: *Module,1712 pt: Zcu.PerThread,
1687) !OverflowArithmeticResult {1713) !OverflowArithmeticResult {
1714 const mod = pt.zcu;
1688 const info = ty.intInfo(mod);1715 const info = ty.intInfo(mod);
16891716
1690 if (lhs.isUndef(mod) or rhs.isUndef(mod)) {1717 if (lhs.isUndef(mod) or rhs.isUndef(mod)) {
1691 return .{1718 return .{
1692 .overflow_bit = try mod.undefValue(Type.u1),1719 .overflow_bit = try pt.undefValue(Type.u1),
1693 .wrapped_result = try mod.undefValue(ty),1720 .wrapped_result = try pt.undefValue(ty),
1694 };1721 };
1695 }1722 }
16961723
1697 var lhs_space: Value.BigIntSpace = undefined;1724 var lhs_space: Value.BigIntSpace = undefined;
1698 var rhs_space: Value.BigIntSpace = undefined;1725 var rhs_space: Value.BigIntSpace = undefined;
1699 const lhs_bigint = lhs.toBigInt(&lhs_space, mod);1726 const lhs_bigint = lhs.toBigInt(&lhs_space, pt);
1700 const rhs_bigint = rhs.toBigInt(&rhs_space, mod);1727 const rhs_bigint = rhs.toBigInt(&rhs_space, pt);
1701 const limbs = try arena.alloc(1728 const limbs = try arena.alloc(
1702 std.math.big.Limb,1729 std.math.big.Limb,
1703 lhs_bigint.limbs.len + rhs_bigint.limbs.len,1730 lhs_bigint.limbs.len + rhs_bigint.limbs.len,
...@@ -1715,8 +1742,8 @@ pub fn intMulWithOverflowScalar(...@@ -1715,8 +1742,8 @@ pub fn intMulWithOverflowScalar(
1715 }1742 }
17161743
1717 return OverflowArithmeticResult{1744 return OverflowArithmeticResult{
1718 .overflow_bit = try mod.intValue(Type.u1, @intFromBool(overflowed)),1745 .overflow_bit = try pt.intValue(Type.u1, @intFromBool(overflowed)),
1719 .wrapped_result = try mod.intValue_big(ty, result_bigint.toConst()),1746 .wrapped_result = try pt.intValue_big(ty, result_bigint.toConst()),
1720 };1747 };
1721}1748}
17221749
...@@ -1726,22 +1753,23 @@ pub fn numberMulWrap(...@@ -1726,22 +1753,23 @@ pub fn numberMulWrap(
1726 rhs: Value,1753 rhs: Value,
1727 ty: Type,1754 ty: Type,
1728 arena: Allocator,1755 arena: Allocator,
1729 mod: *Module,1756 pt: Zcu.PerThread,
1730) !Value {1757) !Value {
1758 const mod = pt.zcu;
1731 if (ty.zigTypeTag(mod) == .Vector) {1759 if (ty.zigTypeTag(mod) == .Vector) {
1732 const result_data = try arena.alloc(InternPool.Index, ty.vectorLen(mod));1760 const result_data = try arena.alloc(InternPool.Index, ty.vectorLen(mod));
1733 const scalar_ty = ty.scalarType(mod);1761 const scalar_ty = ty.scalarType(mod);
1734 for (result_data, 0..) |*scalar, i| {1762 for (result_data, 0..) |*scalar, i| {
1735 const lhs_elem = try lhs.elemValue(mod, i);1763 const lhs_elem = try lhs.elemValue(pt, i);
1736 const rhs_elem = try rhs.elemValue(mod, i);1764 const rhs_elem = try rhs.elemValue(pt, i);
1737 scalar.* = (try numberMulWrapScalar(lhs_elem, rhs_elem, scalar_ty, arena, mod)).toIntern();1765 scalar.* = (try numberMulWrapScalar(lhs_elem, rhs_elem, scalar_ty, arena, pt)).toIntern();
1738 }1766 }
1739 return Value.fromInterned((try mod.intern(.{ .aggregate = .{1767 return Value.fromInterned(try pt.intern(.{ .aggregate = .{
1740 .ty = ty.toIntern(),1768 .ty = ty.toIntern(),
1741 .storage = .{ .elems = result_data },1769 .storage = .{ .elems = result_data },
1742 } })));1770 } }));
1743 }1771 }
1744 return numberMulWrapScalar(lhs, rhs, ty, arena, mod);1772 return numberMulWrapScalar(lhs, rhs, ty, arena, pt);
1745}1773}
17461774
1747/// Supports both floats and ints; handles undefined.1775/// Supports both floats and ints; handles undefined.
...@@ -1750,19 +1778,20 @@ pub fn numberMulWrapScalar(...@@ -1750,19 +1778,20 @@ pub fn numberMulWrapScalar(
1750 rhs: Value,1778 rhs: Value,
1751 ty: Type,1779 ty: Type,
1752 arena: Allocator,1780 arena: Allocator,
1753 mod: *Module,1781 pt: Zcu.PerThread,
1754) !Value {1782) !Value {
1783 const mod = pt.zcu;
1755 if (lhs.isUndef(mod) or rhs.isUndef(mod)) return Value.undef;1784 if (lhs.isUndef(mod) or rhs.isUndef(mod)) return Value.undef;
17561785
1757 if (ty.zigTypeTag(mod) == .ComptimeInt) {1786 if (ty.zigTypeTag(mod) == .ComptimeInt) {
1758 return intMul(lhs, rhs, ty, undefined, arena, mod);1787 return intMul(lhs, rhs, ty, undefined, arena, pt);
1759 }1788 }
17601789
1761 if (ty.isAnyFloat()) {1790 if (ty.isAnyFloat()) {
1762 return floatMul(lhs, rhs, ty, arena, mod);1791 return floatMul(lhs, rhs, ty, arena, pt);
1763 }1792 }
17641793
1765 const overflow_result = try intMulWithOverflow(lhs, rhs, ty, arena, mod);1794 const overflow_result = try intMulWithOverflow(lhs, rhs, ty, arena, pt);
1766 return overflow_result.wrapped_result;1795 return overflow_result.wrapped_result;
1767}1796}
17681797
...@@ -1772,22 +1801,22 @@ pub fn intMulSat(...@@ -1772,22 +1801,22 @@ pub fn intMulSat(
1772 rhs: Value,1801 rhs: Value,
1773 ty: Type,1802 ty: Type,
1774 arena: Allocator,1803 arena: Allocator,
1775 mod: *Module,1804 pt: Zcu.PerThread,
1776) !Value {1805) !Value {
1777 if (ty.zigTypeTag(mod) == .Vector) {1806 if (ty.zigTypeTag(pt.zcu) == .Vector) {
1778 const result_data = try arena.alloc(InternPool.Index, ty.vectorLen(mod));1807 const result_data = try arena.alloc(InternPool.Index, ty.vectorLen(pt.zcu));
1779 const scalar_ty = ty.scalarType(mod);1808 const scalar_ty = ty.scalarType(pt.zcu);
1780 for (result_data, 0..) |*scalar, i| {1809 for (result_data, 0..) |*scalar, i| {
1781 const lhs_elem = try lhs.elemValue(mod, i);1810 const lhs_elem = try lhs.elemValue(pt, i);
1782 const rhs_elem = try rhs.elemValue(mod, i);1811 const rhs_elem = try rhs.elemValue(pt, i);
1783 scalar.* = (try intMulSatScalar(lhs_elem, rhs_elem, scalar_ty, arena, mod)).toIntern();1812 scalar.* = (try intMulSatScalar(lhs_elem, rhs_elem, scalar_ty, arena, pt)).toIntern();
1784 }1813 }
1785 return Value.fromInterned((try mod.intern(.{ .aggregate = .{1814 return Value.fromInterned(try pt.intern(.{ .aggregate = .{
1786 .ty = ty.toIntern(),1815 .ty = ty.toIntern(),
1787 .storage = .{ .elems = result_data },1816 .storage = .{ .elems = result_data },
1788 } })));1817 } }));
1789 }1818 }
1790 return intMulSatScalar(lhs, rhs, ty, arena, mod);1819 return intMulSatScalar(lhs, rhs, ty, arena, pt);
1791}1820}
17921821
1793/// Supports (vectors of) integers only; asserts neither operand is undefined.1822/// Supports (vectors of) integers only; asserts neither operand is undefined.
...@@ -1796,17 +1825,17 @@ pub fn intMulSatScalar(...@@ -1796,17 +1825,17 @@ pub fn intMulSatScalar(
1796 rhs: Value,1825 rhs: Value,
1797 ty: Type,1826 ty: Type,
1798 arena: Allocator,1827 arena: Allocator,
1799 mod: *Module,1828 pt: Zcu.PerThread,
1800) !Value {1829) !Value {
1801 assert(!lhs.isUndef(mod));1830 assert(!lhs.isUndef(pt.zcu));
1802 assert(!rhs.isUndef(mod));1831 assert(!rhs.isUndef(pt.zcu));
18031832
1804 const info = ty.intInfo(mod);1833 const info = ty.intInfo(pt.zcu);
18051834
1806 var lhs_space: Value.BigIntSpace = undefined;1835 var lhs_space: Value.BigIntSpace = undefined;
1807 var rhs_space: Value.BigIntSpace = undefined;1836 var rhs_space: Value.BigIntSpace = undefined;
1808 const lhs_bigint = lhs.toBigInt(&lhs_space, mod);1837 const lhs_bigint = lhs.toBigInt(&lhs_space, pt);
1809 const rhs_bigint = rhs.toBigInt(&rhs_space, mod);1838 const rhs_bigint = rhs.toBigInt(&rhs_space, pt);
1810 const limbs = try arena.alloc(1839 const limbs = try arena.alloc(
1811 std.math.big.Limb,1840 std.math.big.Limb,
1812 @max(1841 @max(
...@@ -1822,53 +1851,55 @@ pub fn intMulSatScalar(...@@ -1822,53 +1851,55 @@ pub fn intMulSatScalar(
1822 );1851 );
1823 result_bigint.mul(lhs_bigint, rhs_bigint, limbs_buffer, arena);1852 result_bigint.mul(lhs_bigint, rhs_bigint, limbs_buffer, arena);
1824 result_bigint.saturate(result_bigint.toConst(), info.signedness, info.bits);1853 result_bigint.saturate(result_bigint.toConst(), info.signedness, info.bits);
1825 return mod.intValue_big(ty, result_bigint.toConst());1854 return pt.intValue_big(ty, result_bigint.toConst());
1826}1855}
18271856
1828/// Supports both floats and ints; handles undefined.1857/// Supports both floats and ints; handles undefined.
1829pub fn numberMax(lhs: Value, rhs: Value, mod: *Module) Value {1858pub fn numberMax(lhs: Value, rhs: Value, pt: Zcu.PerThread) Value {
1830 if (lhs.isUndef(mod) or rhs.isUndef(mod)) return undef;1859 if (lhs.isUndef(pt.zcu) or rhs.isUndef(pt.zcu)) return undef;
1831 if (lhs.isNan(mod)) return rhs;1860 if (lhs.isNan(pt.zcu)) return rhs;
1832 if (rhs.isNan(mod)) return lhs;1861 if (rhs.isNan(pt.zcu)) return lhs;
18331862
1834 return switch (order(lhs, rhs, mod)) {1863 return switch (order(lhs, rhs, pt)) {
1835 .lt => rhs,1864 .lt => rhs,
1836 .gt, .eq => lhs,1865 .gt, .eq => lhs,
1837 };1866 };
1838}1867}
18391868
1840/// Supports both floats and ints; handles undefined.1869/// Supports both floats and ints; handles undefined.
1841pub fn numberMin(lhs: Value, rhs: Value, mod: *Module) Value {1870pub fn numberMin(lhs: Value, rhs: Value, pt: Zcu.PerThread) Value {
1842 if (lhs.isUndef(mod) or rhs.isUndef(mod)) return undef;1871 if (lhs.isUndef(pt.zcu) or rhs.isUndef(pt.zcu)) return undef;
1843 if (lhs.isNan(mod)) return rhs;1872 if (lhs.isNan(pt.zcu)) return rhs;
1844 if (rhs.isNan(mod)) return lhs;1873 if (rhs.isNan(pt.zcu)) return lhs;
18451874
1846 return switch (order(lhs, rhs, mod)) {1875 return switch (order(lhs, rhs, pt)) {
1847 .lt => lhs,1876 .lt => lhs,
1848 .gt, .eq => rhs,1877 .gt, .eq => rhs,
1849 };1878 };
1850}1879}
18511880
1852/// operands must be (vectors of) integers; handles undefined scalars.1881/// operands must be (vectors of) integers; handles undefined scalars.
1853pub fn bitwiseNot(val: Value, ty: Type, arena: Allocator, mod: *Module) !Value {1882pub fn bitwiseNot(val: Value, ty: Type, arena: Allocator, pt: Zcu.PerThread) !Value {
1883 const mod = pt.zcu;
1854 if (ty.zigTypeTag(mod) == .Vector) {1884 if (ty.zigTypeTag(mod) == .Vector) {
1855 const result_data = try arena.alloc(InternPool.Index, ty.vectorLen(mod));1885 const result_data = try arena.alloc(InternPool.Index, ty.vectorLen(mod));
1856 const scalar_ty = ty.scalarType(mod);1886 const scalar_ty = ty.scalarType(mod);
1857 for (result_data, 0..) |*scalar, i| {1887 for (result_data, 0..) |*scalar, i| {
1858 const elem_val = try val.elemValue(mod, i);1888 const elem_val = try val.elemValue(pt, i);
1859 scalar.* = (try bitwiseNotScalar(elem_val, scalar_ty, arena, mod)).toIntern();1889 scalar.* = (try bitwiseNotScalar(elem_val, scalar_ty, arena, pt)).toIntern();
1860 }1890 }
1861 return Value.fromInterned((try mod.intern(.{ .aggregate = .{1891 return Value.fromInterned(try pt.intern(.{ .aggregate = .{
1862 .ty = ty.toIntern(),1892 .ty = ty.toIntern(),
1863 .storage = .{ .elems = result_data },1893 .storage = .{ .elems = result_data },
1864 } })));1894 } }));
1865 }1895 }
1866 return bitwiseNotScalar(val, ty, arena, mod);1896 return bitwiseNotScalar(val, ty, arena, pt);
1867}1897}
18681898
1869/// operands must be integers; handles undefined.1899/// operands must be integers; handles undefined.
1870pub fn bitwiseNotScalar(val: Value, ty: Type, arena: Allocator, mod: *Module) !Value {1900pub fn bitwiseNotScalar(val: Value, ty: Type, arena: Allocator, pt: Zcu.PerThread) !Value {
1871 if (val.isUndef(mod)) return Value.fromInterned((try mod.intern(.{ .undef = ty.toIntern() })));1901 const mod = pt.zcu;
1902 if (val.isUndef(mod)) return Value.fromInterned(try pt.intern(.{ .undef = ty.toIntern() }));
1872 if (ty.toIntern() == .bool_type) return makeBool(!val.toBool());1903 if (ty.toIntern() == .bool_type) return makeBool(!val.toBool());
18731904
1874 const info = ty.intInfo(mod);1905 const info = ty.intInfo(mod);
...@@ -1880,7 +1911,7 @@ pub fn bitwiseNotScalar(val: Value, ty: Type, arena: Allocator, mod: *Module) !V...@@ -1880,7 +1911,7 @@ pub fn bitwiseNotScalar(val: Value, ty: Type, arena: Allocator, mod: *Module) !V
1880 // TODO is this a performance issue? maybe we should try the operation without1911 // TODO is this a performance issue? maybe we should try the operation without
1881 // resorting to BigInt first.1912 // resorting to BigInt first.
1882 var val_space: Value.BigIntSpace = undefined;1913 var val_space: Value.BigIntSpace = undefined;
1883 const val_bigint = val.toBigInt(&val_space, mod);1914 const val_bigint = val.toBigInt(&val_space, pt);
1884 const limbs = try arena.alloc(1915 const limbs = try arena.alloc(
1885 std.math.big.Limb,1916 std.math.big.Limb,
1886 std.math.big.int.calcTwosCompLimbCount(info.bits),1917 std.math.big.int.calcTwosCompLimbCount(info.bits),
...@@ -1888,29 +1919,31 @@ pub fn bitwiseNotScalar(val: Value, ty: Type, arena: Allocator, mod: *Module) !V...@@ -1888,29 +1919,31 @@ pub fn bitwiseNotScalar(val: Value, ty: Type, arena: Allocator, mod: *Module) !V
18881919
1889 var result_bigint = BigIntMutable{ .limbs = limbs, .positive = undefined, .len = undefined };1920 var result_bigint = BigIntMutable{ .limbs = limbs, .positive = undefined, .len = undefined };
1890 result_bigint.bitNotWrap(val_bigint, info.signedness, info.bits);1921 result_bigint.bitNotWrap(val_bigint, info.signedness, info.bits);
1891 return mod.intValue_big(ty, result_bigint.toConst());1922 return pt.intValue_big(ty, result_bigint.toConst());
1892}1923}
18931924
1894/// operands must be (vectors of) integers; handles undefined scalars.1925/// operands must be (vectors of) integers; handles undefined scalars.
1895pub fn bitwiseAnd(lhs: Value, rhs: Value, ty: Type, allocator: Allocator, mod: *Module) !Value {1926pub fn bitwiseAnd(lhs: Value, rhs: Value, ty: Type, allocator: Allocator, pt: Zcu.PerThread) !Value {
1927 const mod = pt.zcu;
1896 if (ty.zigTypeTag(mod) == .Vector) {1928 if (ty.zigTypeTag(mod) == .Vector) {
1897 const result_data = try allocator.alloc(InternPool.Index, ty.vectorLen(mod));1929 const result_data = try allocator.alloc(InternPool.Index, ty.vectorLen(mod));
1898 const scalar_ty = ty.scalarType(mod);1930 const scalar_ty = ty.scalarType(mod);
1899 for (result_data, 0..) |*scalar, i| {1931 for (result_data, 0..) |*scalar, i| {
1900 const lhs_elem = try lhs.elemValue(mod, i);1932 const lhs_elem = try lhs.elemValue(pt, i);
1901 const rhs_elem = try rhs.elemValue(mod, i);1933 const rhs_elem = try rhs.elemValue(pt, i);
1902 scalar.* = (try bitwiseAndScalar(lhs_elem, rhs_elem, scalar_ty, allocator, mod)).toIntern();1934 scalar.* = (try bitwiseAndScalar(lhs_elem, rhs_elem, scalar_ty, allocator, pt)).toIntern();
1903 }1935 }
1904 return Value.fromInterned((try mod.intern(.{ .aggregate = .{1936 return Value.fromInterned(try pt.intern(.{ .aggregate = .{
1905 .ty = ty.toIntern(),1937 .ty = ty.toIntern(),
1906 .storage = .{ .elems = result_data },1938 .storage = .{ .elems = result_data },
1907 } })));1939 } }));
1908 }1940 }
1909 return bitwiseAndScalar(lhs, rhs, ty, allocator, mod);1941 return bitwiseAndScalar(lhs, rhs, ty, allocator, pt);
1910}1942}
19111943
1912/// operands must be integers; handles undefined.1944/// operands must be integers; handles undefined.
1913pub fn bitwiseAndScalar(orig_lhs: Value, orig_rhs: Value, ty: Type, arena: Allocator, zcu: *Zcu) !Value {1945pub fn bitwiseAndScalar(orig_lhs: Value, orig_rhs: Value, ty: Type, arena: Allocator, pt: Zcu.PerThread) !Value {
1946 const zcu = pt.zcu;
1914 // If one operand is defined, we turn the other into `0xAA` so the bitwise AND can1947 // If one operand is defined, we turn the other into `0xAA` so the bitwise AND can
1915 // still zero out some bits.1948 // still zero out some bits.
1916 // TODO: ideally we'd still like tracking for the undef bits. Related: #19634.1949 // TODO: ideally we'd still like tracking for the undef bits. Related: #19634.
...@@ -1919,9 +1952,9 @@ pub fn bitwiseAndScalar(orig_lhs: Value, orig_rhs: Value, ty: Type, arena: Alloc...@@ -1919,9 +1952,9 @@ pub fn bitwiseAndScalar(orig_lhs: Value, orig_rhs: Value, ty: Type, arena: Alloc
1919 const rhs_undef = orig_rhs.isUndef(zcu);1952 const rhs_undef = orig_rhs.isUndef(zcu);
1920 break :make_defined switch ((@as(u2, @intFromBool(lhs_undef)) << 1) | @intFromBool(rhs_undef)) {1953 break :make_defined switch ((@as(u2, @intFromBool(lhs_undef)) << 1) | @intFromBool(rhs_undef)) {
1921 0b00 => .{ orig_lhs, orig_rhs },1954 0b00 => .{ orig_lhs, orig_rhs },
1922 0b01 => .{ orig_lhs, try intValueAa(ty, arena, zcu) },1955 0b01 => .{ orig_lhs, try intValueAa(ty, arena, pt) },
1923 0b10 => .{ try intValueAa(ty, arena, zcu), orig_rhs },1956 0b10 => .{ try intValueAa(ty, arena, pt), orig_rhs },
1924 0b11 => return zcu.undefValue(ty),1957 0b11 => return pt.undefValue(ty),
1925 };1958 };
1926 };1959 };
19271960
...@@ -1931,8 +1964,8 @@ pub fn bitwiseAndScalar(orig_lhs: Value, orig_rhs: Value, ty: Type, arena: Alloc...@@ -1931,8 +1964,8 @@ pub fn bitwiseAndScalar(orig_lhs: Value, orig_rhs: Value, ty: Type, arena: Alloc
1931 // resorting to BigInt first.1964 // resorting to BigInt first.
1932 var lhs_space: Value.BigIntSpace = undefined;1965 var lhs_space: Value.BigIntSpace = undefined;
1933 var rhs_space: Value.BigIntSpace = undefined;1966 var rhs_space: Value.BigIntSpace = undefined;
1934 const lhs_bigint = lhs.toBigInt(&lhs_space, zcu);1967 const lhs_bigint = lhs.toBigInt(&lhs_space, pt);
1935 const rhs_bigint = rhs.toBigInt(&rhs_space, zcu);1968 const rhs_bigint = rhs.toBigInt(&rhs_space, pt);
1936 const limbs = try arena.alloc(1969 const limbs = try arena.alloc(
1937 std.math.big.Limb,1970 std.math.big.Limb,
1938 // + 1 for negatives1971 // + 1 for negatives
...@@ -1940,12 +1973,13 @@ pub fn bitwiseAndScalar(orig_lhs: Value, orig_rhs: Value, ty: Type, arena: Alloc...@@ -1940,12 +1973,13 @@ pub fn bitwiseAndScalar(orig_lhs: Value, orig_rhs: Value, ty: Type, arena: Alloc
1940 );1973 );
1941 var result_bigint = BigIntMutable{ .limbs = limbs, .positive = undefined, .len = undefined };1974 var result_bigint = BigIntMutable{ .limbs = limbs, .positive = undefined, .len = undefined };
1942 result_bigint.bitAnd(lhs_bigint, rhs_bigint);1975 result_bigint.bitAnd(lhs_bigint, rhs_bigint);
1943 return zcu.intValue_big(ty, result_bigint.toConst());1976 return pt.intValue_big(ty, result_bigint.toConst());
1944}1977}
19451978
1946/// Given an integer or boolean type, creates an value of that with the bit pattern 0xAA.1979/// Given an integer or boolean type, creates an value of that with the bit pattern 0xAA.
1947/// This is used to convert undef values into 0xAA when performing e.g. bitwise operations.1980/// This is used to convert undef values into 0xAA when performing e.g. bitwise operations.
1948fn intValueAa(ty: Type, arena: Allocator, zcu: *Zcu) !Value {1981fn intValueAa(ty: Type, arena: Allocator, pt: Zcu.PerThread) !Value {
1982 const zcu = pt.zcu;
1949 if (ty.toIntern() == .bool_type) return Value.true;1983 if (ty.toIntern() == .bool_type) return Value.true;
1950 const info = ty.intInfo(zcu);1984 const info = ty.intInfo(zcu);
19511985
...@@ -1958,68 +1992,71 @@ fn intValueAa(ty: Type, arena: Allocator, zcu: *Zcu) !Value {...@@ -1958,68 +1992,71 @@ fn intValueAa(ty: Type, arena: Allocator, zcu: *Zcu) !Value {
1958 );1992 );
1959 var result_bigint = BigIntMutable{ .limbs = limbs, .positive = undefined, .len = undefined };1993 var result_bigint = BigIntMutable{ .limbs = limbs, .positive = undefined, .len = undefined };
1960 result_bigint.readTwosComplement(buf, info.bits, zcu.getTarget().cpu.arch.endian(), info.signedness);1994 result_bigint.readTwosComplement(buf, info.bits, zcu.getTarget().cpu.arch.endian(), info.signedness);
1961 return zcu.intValue_big(ty, result_bigint.toConst());1995 return pt.intValue_big(ty, result_bigint.toConst());
1962}1996}
19631997
1964/// operands must be (vectors of) integers; handles undefined scalars.1998/// operands must be (vectors of) integers; handles undefined scalars.
1965pub fn bitwiseNand(lhs: Value, rhs: Value, ty: Type, arena: Allocator, mod: *Module) !Value {1999pub fn bitwiseNand(lhs: Value, rhs: Value, ty: Type, arena: Allocator, pt: Zcu.PerThread) !Value {
2000 const mod = pt.zcu;
1966 if (ty.zigTypeTag(mod) == .Vector) {2001 if (ty.zigTypeTag(mod) == .Vector) {
1967 const result_data = try arena.alloc(InternPool.Index, ty.vectorLen(mod));2002 const result_data = try arena.alloc(InternPool.Index, ty.vectorLen(mod));
1968 const scalar_ty = ty.scalarType(mod);2003 const scalar_ty = ty.scalarType(mod);
1969 for (result_data, 0..) |*scalar, i| {2004 for (result_data, 0..) |*scalar, i| {
1970 const lhs_elem = try lhs.elemValue(mod, i);2005 const lhs_elem = try lhs.elemValue(pt, i);
1971 const rhs_elem = try rhs.elemValue(mod, i);2006 const rhs_elem = try rhs.elemValue(pt, i);
1972 scalar.* = (try bitwiseNandScalar(lhs_elem, rhs_elem, scalar_ty, arena, mod)).toIntern();2007 scalar.* = (try bitwiseNandScalar(lhs_elem, rhs_elem, scalar_ty, arena, pt)).toIntern();
1973 }2008 }
1974 return Value.fromInterned((try mod.intern(.{ .aggregate = .{2009 return Value.fromInterned(try pt.intern(.{ .aggregate = .{
1975 .ty = ty.toIntern(),2010 .ty = ty.toIntern(),
1976 .storage = .{ .elems = result_data },2011 .storage = .{ .elems = result_data },
1977 } })));2012 } }));
1978 }2013 }
1979 return bitwiseNandScalar(lhs, rhs, ty, arena, mod);2014 return bitwiseNandScalar(lhs, rhs, ty, arena, pt);
1980}2015}
19812016
1982/// operands must be integers; handles undefined.2017/// operands must be integers; handles undefined.
1983pub fn bitwiseNandScalar(lhs: Value, rhs: Value, ty: Type, arena: Allocator, mod: *Module) !Value {2018pub fn bitwiseNandScalar(lhs: Value, rhs: Value, ty: Type, arena: Allocator, pt: Zcu.PerThread) !Value {
1984 if (lhs.isUndef(mod) or rhs.isUndef(mod)) return Value.fromInterned((try mod.intern(.{ .undef = ty.toIntern() })));2019 const mod = pt.zcu;
2020 if (lhs.isUndef(mod) or rhs.isUndef(mod)) return Value.fromInterned(try pt.intern(.{ .undef = ty.toIntern() }));
1985 if (ty.toIntern() == .bool_type) return makeBool(!(lhs.toBool() and rhs.toBool()));2021 if (ty.toIntern() == .bool_type) return makeBool(!(lhs.toBool() and rhs.toBool()));
19862022
1987 const anded = try bitwiseAnd(lhs, rhs, ty, arena, mod);2023 const anded = try bitwiseAnd(lhs, rhs, ty, arena, pt);
1988 const all_ones = if (ty.isSignedInt(mod)) try mod.intValue(ty, -1) else try ty.maxIntScalar(mod, ty);2024 const all_ones = if (ty.isSignedInt(mod)) try pt.intValue(ty, -1) else try ty.maxIntScalar(pt, ty);
1989 return bitwiseXor(anded, all_ones, ty, arena, mod);2025 return bitwiseXor(anded, all_ones, ty, arena, pt);
1990}2026}
19912027
1992/// operands must be (vectors of) integers; handles undefined scalars.2028/// operands must be (vectors of) integers; handles undefined scalars.
1993pub fn bitwiseOr(lhs: Value, rhs: Value, ty: Type, allocator: Allocator, mod: *Module) !Value {2029pub fn bitwiseOr(lhs: Value, rhs: Value, ty: Type, allocator: Allocator, pt: Zcu.PerThread) !Value {
2030 const mod = pt.zcu;
1994 if (ty.zigTypeTag(mod) == .Vector) {2031 if (ty.zigTypeTag(mod) == .Vector) {
1995 const result_data = try allocator.alloc(InternPool.Index, ty.vectorLen(mod));2032 const result_data = try allocator.alloc(InternPool.Index, ty.vectorLen(mod));
1996 const scalar_ty = ty.scalarType(mod);2033 const scalar_ty = ty.scalarType(mod);
1997 for (result_data, 0..) |*scalar, i| {2034 for (result_data, 0..) |*scalar, i| {
1998 const lhs_elem = try lhs.elemValue(mod, i);2035 const lhs_elem = try lhs.elemValue(pt, i);
1999 const rhs_elem = try rhs.elemValue(mod, i);2036 const rhs_elem = try rhs.elemValue(pt, i);
2000 scalar.* = (try bitwiseOrScalar(lhs_elem, rhs_elem, scalar_ty, allocator, mod)).toIntern();2037 scalar.* = (try bitwiseOrScalar(lhs_elem, rhs_elem, scalar_ty, allocator, pt)).toIntern();
2001 }2038 }
2002 return Value.fromInterned((try mod.intern(.{ .aggregate = .{2039 return Value.fromInterned(try pt.intern(.{ .aggregate = .{
2003 .ty = ty.toIntern(),2040 .ty = ty.toIntern(),
2004 .storage = .{ .elems = result_data },2041 .storage = .{ .elems = result_data },
2005 } })));2042 } }));
2006 }2043 }
2007 return bitwiseOrScalar(lhs, rhs, ty, allocator, mod);2044 return bitwiseOrScalar(lhs, rhs, ty, allocator, pt);
2008}2045}
20092046
2010/// operands must be integers; handles undefined.2047/// operands must be integers; handles undefined.
2011pub fn bitwiseOrScalar(orig_lhs: Value, orig_rhs: Value, ty: Type, arena: Allocator, zcu: *Zcu) !Value {2048pub fn bitwiseOrScalar(orig_lhs: Value, orig_rhs: Value, ty: Type, arena: Allocator, pt: Zcu.PerThread) !Value {
2012 // If one operand is defined, we turn the other into `0xAA` so the bitwise AND can2049 // If one operand is defined, we turn the other into `0xAA` so the bitwise AND can
2013 // still zero out some bits.2050 // still zero out some bits.
2014 // TODO: ideally we'd still like tracking for the undef bits. Related: #19634.2051 // TODO: ideally we'd still like tracking for the undef bits. Related: #19634.
2015 const lhs: Value, const rhs: Value = make_defined: {2052 const lhs: Value, const rhs: Value = make_defined: {
2016 const lhs_undef = orig_lhs.isUndef(zcu);2053 const lhs_undef = orig_lhs.isUndef(pt.zcu);
2017 const rhs_undef = orig_rhs.isUndef(zcu);2054 const rhs_undef = orig_rhs.isUndef(pt.zcu);
2018 break :make_defined switch ((@as(u2, @intFromBool(lhs_undef)) << 1) | @intFromBool(rhs_undef)) {2055 break :make_defined switch ((@as(u2, @intFromBool(lhs_undef)) << 1) | @intFromBool(rhs_undef)) {
2019 0b00 => .{ orig_lhs, orig_rhs },2056 0b00 => .{ orig_lhs, orig_rhs },
2020 0b01 => .{ orig_lhs, try intValueAa(ty, arena, zcu) },2057 0b01 => .{ orig_lhs, try intValueAa(ty, arena, pt) },
2021 0b10 => .{ try intValueAa(ty, arena, zcu), orig_rhs },2058 0b10 => .{ try intValueAa(ty, arena, pt), orig_rhs },
2022 0b11 => return zcu.undefValue(ty),2059 0b11 => return pt.undefValue(ty),
2023 };2060 };
2024 };2061 };
20252062
...@@ -2029,46 +2066,48 @@ pub fn bitwiseOrScalar(orig_lhs: Value, orig_rhs: Value, ty: Type, arena: Alloca...@@ -2029,46 +2066,48 @@ pub fn bitwiseOrScalar(orig_lhs: Value, orig_rhs: Value, ty: Type, arena: Alloca
2029 // resorting to BigInt first.2066 // resorting to BigInt first.
2030 var lhs_space: Value.BigIntSpace = undefined;2067 var lhs_space: Value.BigIntSpace = undefined;
2031 var rhs_space: Value.BigIntSpace = undefined;2068 var rhs_space: Value.BigIntSpace = undefined;
2032 const lhs_bigint = lhs.toBigInt(&lhs_space, zcu);2069 const lhs_bigint = lhs.toBigInt(&lhs_space, pt);
2033 const rhs_bigint = rhs.toBigInt(&rhs_space, zcu);2070 const rhs_bigint = rhs.toBigInt(&rhs_space, pt);
2034 const limbs = try arena.alloc(2071 const limbs = try arena.alloc(
2035 std.math.big.Limb,2072 std.math.big.Limb,
2036 @max(lhs_bigint.limbs.len, rhs_bigint.limbs.len),2073 @max(lhs_bigint.limbs.len, rhs_bigint.limbs.len),
2037 );2074 );
2038 var result_bigint = BigIntMutable{ .limbs = limbs, .positive = undefined, .len = undefined };2075 var result_bigint = BigIntMutable{ .limbs = limbs, .positive = undefined, .len = undefined };
2039 result_bigint.bitOr(lhs_bigint, rhs_bigint);2076 result_bigint.bitOr(lhs_bigint, rhs_bigint);
2040 return zcu.intValue_big(ty, result_bigint.toConst());2077 return pt.intValue_big(ty, result_bigint.toConst());
2041}2078}
20422079
2043/// operands must be (vectors of) integers; handles undefined scalars.2080/// operands must be (vectors of) integers; handles undefined scalars.
2044pub fn bitwiseXor(lhs: Value, rhs: Value, ty: Type, allocator: Allocator, mod: *Module) !Value {2081pub fn bitwiseXor(lhs: Value, rhs: Value, ty: Type, allocator: Allocator, pt: Zcu.PerThread) !Value {
2082 const mod = pt.zcu;
2045 if (ty.zigTypeTag(mod) == .Vector) {2083 if (ty.zigTypeTag(mod) == .Vector) {
2046 const result_data = try allocator.alloc(InternPool.Index, ty.vectorLen(mod));2084 const result_data = try allocator.alloc(InternPool.Index, ty.vectorLen(mod));
2047 const scalar_ty = ty.scalarType(mod);2085 const scalar_ty = ty.scalarType(mod);
2048 for (result_data, 0..) |*scalar, i| {2086 for (result_data, 0..) |*scalar, i| {
2049 const lhs_elem = try lhs.elemValue(mod, i);2087 const lhs_elem = try lhs.elemValue(pt, i);
2050 const rhs_elem = try rhs.elemValue(mod, i);2088 const rhs_elem = try rhs.elemValue(pt, i);
2051 scalar.* = (try bitwiseXorScalar(lhs_elem, rhs_elem, scalar_ty, allocator, mod)).toIntern();2089 scalar.* = (try bitwiseXorScalar(lhs_elem, rhs_elem, scalar_ty, allocator, pt)).toIntern();
2052 }2090 }
2053 return Value.fromInterned((try mod.intern(.{ .aggregate = .{2091 return Value.fromInterned(try pt.intern(.{ .aggregate = .{
2054 .ty = ty.toIntern(),2092 .ty = ty.toIntern(),
2055 .storage = .{ .elems = result_data },2093 .storage = .{ .elems = result_data },
2056 } })));2094 } }));
2057 }2095 }
2058 return bitwiseXorScalar(lhs, rhs, ty, allocator, mod);2096 return bitwiseXorScalar(lhs, rhs, ty, allocator, pt);
2059}2097}
20602098
2061/// operands must be integers; handles undefined.2099/// operands must be integers; handles undefined.
2062pub fn bitwiseXorScalar(lhs: Value, rhs: Value, ty: Type, arena: Allocator, mod: *Module) !Value {2100pub fn bitwiseXorScalar(lhs: Value, rhs: Value, ty: Type, arena: Allocator, pt: Zcu.PerThread) !Value {
2063 if (lhs.isUndef(mod) or rhs.isUndef(mod)) return Value.fromInterned((try mod.intern(.{ .undef = ty.toIntern() })));2101 const mod = pt.zcu;
2102 if (lhs.isUndef(mod) or rhs.isUndef(mod)) return Value.fromInterned(try pt.intern(.{ .undef = ty.toIntern() }));
2064 if (ty.toIntern() == .bool_type) return makeBool(lhs.toBool() != rhs.toBool());2103 if (ty.toIntern() == .bool_type) return makeBool(lhs.toBool() != rhs.toBool());
20652104
2066 // TODO is this a performance issue? maybe we should try the operation without2105 // TODO is this a performance issue? maybe we should try the operation without
2067 // resorting to BigInt first.2106 // resorting to BigInt first.
2068 var lhs_space: Value.BigIntSpace = undefined;2107 var lhs_space: Value.BigIntSpace = undefined;
2069 var rhs_space: Value.BigIntSpace = undefined;2108 var rhs_space: Value.BigIntSpace = undefined;
2070 const lhs_bigint = lhs.toBigInt(&lhs_space, mod);2109 const lhs_bigint = lhs.toBigInt(&lhs_space, pt);
2071 const rhs_bigint = rhs.toBigInt(&rhs_space, mod);2110 const rhs_bigint = rhs.toBigInt(&rhs_space, pt);
2072 const limbs = try arena.alloc(2111 const limbs = try arena.alloc(
2073 std.math.big.Limb,2112 std.math.big.Limb,
2074 // + 1 for negatives2113 // + 1 for negatives
...@@ -2076,22 +2115,22 @@ pub fn bitwiseXorScalar(lhs: Value, rhs: Value, ty: Type, arena: Allocator, mod:...@@ -2076,22 +2115,22 @@ pub fn bitwiseXorScalar(lhs: Value, rhs: Value, ty: Type, arena: Allocator, mod:
2076 );2115 );
2077 var result_bigint = BigIntMutable{ .limbs = limbs, .positive = undefined, .len = undefined };2116 var result_bigint = BigIntMutable{ .limbs = limbs, .positive = undefined, .len = undefined };
2078 result_bigint.bitXor(lhs_bigint, rhs_bigint);2117 result_bigint.bitXor(lhs_bigint, rhs_bigint);
2079 return mod.intValue_big(ty, result_bigint.toConst());2118 return pt.intValue_big(ty, result_bigint.toConst());
2080}2119}
20812120
2082/// If the value overflowed the type, returns a comptime_int (or vector thereof) instead, setting2121/// If the value overflowed the type, returns a comptime_int (or vector thereof) instead, setting
2083/// overflow_idx to the vector index the overflow was at (or 0 for a scalar).2122/// overflow_idx to the vector index the overflow was at (or 0 for a scalar).
2084pub fn intDiv(lhs: Value, rhs: Value, ty: Type, overflow_idx: *?usize, allocator: Allocator, mod: *Module) !Value {2123pub fn intDiv(lhs: Value, rhs: Value, ty: Type, overflow_idx: *?usize, allocator: Allocator, pt: Zcu.PerThread) !Value {
2085 var overflow: usize = undefined;2124 var overflow: usize = undefined;
2086 return intDivInner(lhs, rhs, ty, &overflow, allocator, mod) catch |err| switch (err) {2125 return intDivInner(lhs, rhs, ty, &overflow, allocator, pt) catch |err| switch (err) {
2087 error.Overflow => {2126 error.Overflow => {
2088 const is_vec = ty.isVector(mod);2127 const is_vec = ty.isVector(pt.zcu);
2089 overflow_idx.* = if (is_vec) overflow else 0;2128 overflow_idx.* = if (is_vec) overflow else 0;
2090 const safe_ty = if (is_vec) try mod.vectorType(.{2129 const safe_ty = if (is_vec) try pt.vectorType(.{
2091 .len = ty.vectorLen(mod),2130 .len = ty.vectorLen(pt.zcu),
2092 .child = .comptime_int_type,2131 .child = .comptime_int_type,
2093 }) else Type.comptime_int;2132 }) else Type.comptime_int;
2094 return intDivInner(lhs, rhs, safe_ty, undefined, allocator, mod) catch |err1| switch (err1) {2133 return intDivInner(lhs, rhs, safe_ty, undefined, allocator, pt) catch |err1| switch (err1) {
2095 error.Overflow => unreachable,2134 error.Overflow => unreachable,
2096 else => |e| return e,2135 else => |e| return e,
2097 };2136 };
...@@ -2100,14 +2139,14 @@ pub fn intDiv(lhs: Value, rhs: Value, ty: Type, overflow_idx: *?usize, allocator...@@ -2100,14 +2139,14 @@ pub fn intDiv(lhs: Value, rhs: Value, ty: Type, overflow_idx: *?usize, allocator
2100 };2139 };
2101}2140}
21022141
2103fn intDivInner(lhs: Value, rhs: Value, ty: Type, overflow_idx: *usize, allocator: Allocator, mod: *Module) !Value {2142fn intDivInner(lhs: Value, rhs: Value, ty: Type, overflow_idx: *usize, allocator: Allocator, pt: Zcu.PerThread) !Value {
2104 if (ty.zigTypeTag(mod) == .Vector) {2143 if (ty.zigTypeTag(pt.zcu) == .Vector) {
2105 const result_data = try allocator.alloc(InternPool.Index, ty.vectorLen(mod));2144 const result_data = try allocator.alloc(InternPool.Index, ty.vectorLen(pt.zcu));
2106 const scalar_ty = ty.scalarType(mod);2145 const scalar_ty = ty.scalarType(pt.zcu);
2107 for (result_data, 0..) |*scalar, i| {2146 for (result_data, 0..) |*scalar, i| {
2108 const lhs_elem = try lhs.elemValue(mod, i);2147 const lhs_elem = try lhs.elemValue(pt, i);
2109 const rhs_elem = try rhs.elemValue(mod, i);2148 const rhs_elem = try rhs.elemValue(pt, i);
2110 const val = intDivScalar(lhs_elem, rhs_elem, scalar_ty, allocator, mod) catch |err| switch (err) {2149 const val = intDivScalar(lhs_elem, rhs_elem, scalar_ty, allocator, pt) catch |err| switch (err) {
2111 error.Overflow => {2150 error.Overflow => {
2112 overflow_idx.* = i;2151 overflow_idx.* = i;
2113 return error.Overflow;2152 return error.Overflow;
...@@ -2116,21 +2155,21 @@ fn intDivInner(lhs: Value, rhs: Value, ty: Type, overflow_idx: *usize, allocator...@@ -2116,21 +2155,21 @@ fn intDivInner(lhs: Value, rhs: Value, ty: Type, overflow_idx: *usize, allocator
2116 };2155 };
2117 scalar.* = val.toIntern();2156 scalar.* = val.toIntern();
2118 }2157 }
2119 return Value.fromInterned((try mod.intern(.{ .aggregate = .{2158 return Value.fromInterned(try pt.intern(.{ .aggregate = .{
2120 .ty = ty.toIntern(),2159 .ty = ty.toIntern(),
2121 .storage = .{ .elems = result_data },2160 .storage = .{ .elems = result_data },
2122 } })));2161 } }));
2123 }2162 }
2124 return intDivScalar(lhs, rhs, ty, allocator, mod);2163 return intDivScalar(lhs, rhs, ty, allocator, pt);
2125}2164}
21262165
2127pub fn intDivScalar(lhs: Value, rhs: Value, ty: Type, allocator: Allocator, mod: *Module) !Value {2166pub fn intDivScalar(lhs: Value, rhs: Value, ty: Type, allocator: Allocator, pt: Zcu.PerThread) !Value {
2128 // TODO is this a performance issue? maybe we should try the operation without2167 // TODO is this a performance issue? maybe we should try the operation without
2129 // resorting to BigInt first.2168 // resorting to BigInt first.
2130 var lhs_space: Value.BigIntSpace = undefined;2169 var lhs_space: Value.BigIntSpace = undefined;
2131 var rhs_space: Value.BigIntSpace = undefined;2170 var rhs_space: Value.BigIntSpace = undefined;
2132 const lhs_bigint = lhs.toBigInt(&lhs_space, mod);2171 const lhs_bigint = lhs.toBigInt(&lhs_space, pt);
2133 const rhs_bigint = rhs.toBigInt(&rhs_space, mod);2172 const rhs_bigint = rhs.toBigInt(&rhs_space, pt);
2134 const limbs_q = try allocator.alloc(2173 const limbs_q = try allocator.alloc(
2135 std.math.big.Limb,2174 std.math.big.Limb,
2136 lhs_bigint.limbs.len,2175 lhs_bigint.limbs.len,
...@@ -2147,38 +2186,38 @@ pub fn intDivScalar(lhs: Value, rhs: Value, ty: Type, allocator: Allocator, mod:...@@ -2147,38 +2186,38 @@ pub fn intDivScalar(lhs: Value, rhs: Value, ty: Type, allocator: Allocator, mod:
2147 var result_r = BigIntMutable{ .limbs = limbs_r, .positive = undefined, .len = undefined };2186 var result_r = BigIntMutable{ .limbs = limbs_r, .positive = undefined, .len = undefined };
2148 result_q.divTrunc(&result_r, lhs_bigint, rhs_bigint, limbs_buffer);2187 result_q.divTrunc(&result_r, lhs_bigint, rhs_bigint, limbs_buffer);
2149 if (ty.toIntern() != .comptime_int_type) {2188 if (ty.toIntern() != .comptime_int_type) {
2150 const info = ty.intInfo(mod);2189 const info = ty.intInfo(pt.zcu);
2151 if (!result_q.toConst().fitsInTwosComp(info.signedness, info.bits)) {2190 if (!result_q.toConst().fitsInTwosComp(info.signedness, info.bits)) {
2152 return error.Overflow;2191 return error.Overflow;
2153 }2192 }
2154 }2193 }
2155 return mod.intValue_big(ty, result_q.toConst());2194 return pt.intValue_big(ty, result_q.toConst());
2156}2195}
21572196
2158pub fn intDivFloor(lhs: Value, rhs: Value, ty: Type, allocator: Allocator, mod: *Module) !Value {2197pub fn intDivFloor(lhs: Value, rhs: Value, ty: Type, allocator: Allocator, pt: Zcu.PerThread) !Value {
2159 if (ty.zigTypeTag(mod) == .Vector) {2198 if (ty.zigTypeTag(pt.zcu) == .Vector) {
2160 const result_data = try allocator.alloc(InternPool.Index, ty.vectorLen(mod));2199 const result_data = try allocator.alloc(InternPool.Index, ty.vectorLen(pt.zcu));
2161 const scalar_ty = ty.scalarType(mod);2200 const scalar_ty = ty.scalarType(pt.zcu);
2162 for (result_data, 0..) |*scalar, i| {2201 for (result_data, 0..) |*scalar, i| {
2163 const lhs_elem = try lhs.elemValue(mod, i);2202 const lhs_elem = try lhs.elemValue(pt, i);
2164 const rhs_elem = try rhs.elemValue(mod, i);2203 const rhs_elem = try rhs.elemValue(pt, i);
2165 scalar.* = (try intDivFloorScalar(lhs_elem, rhs_elem, scalar_ty, allocator, mod)).toIntern();2204 scalar.* = (try intDivFloorScalar(lhs_elem, rhs_elem, scalar_ty, allocator, pt)).toIntern();
2166 }2205 }
2167 return Value.fromInterned((try mod.intern(.{ .aggregate = .{2206 return Value.fromInterned(try pt.intern(.{ .aggregate = .{
2168 .ty = ty.toIntern(),2207 .ty = ty.toIntern(),
2169 .storage = .{ .elems = result_data },2208 .storage = .{ .elems = result_data },
2170 } })));2209 } }));
2171 }2210 }
2172 return intDivFloorScalar(lhs, rhs, ty, allocator, mod);2211 return intDivFloorScalar(lhs, rhs, ty, allocator, pt);
2173}2212}
21742213
2175pub fn intDivFloorScalar(lhs: Value, rhs: Value, ty: Type, allocator: Allocator, mod: *Module) !Value {2214pub fn intDivFloorScalar(lhs: Value, rhs: Value, ty: Type, allocator: Allocator, pt: Zcu.PerThread) !Value {
2176 // TODO is this a performance issue? maybe we should try the operation without2215 // TODO is this a performance issue? maybe we should try the operation without
2177 // resorting to BigInt first.2216 // resorting to BigInt first.
2178 var lhs_space: Value.BigIntSpace = undefined;2217 var lhs_space: Value.BigIntSpace = undefined;
2179 var rhs_space: Value.BigIntSpace = undefined;2218 var rhs_space: Value.BigIntSpace = undefined;
2180 const lhs_bigint = lhs.toBigInt(&lhs_space, mod);2219 const lhs_bigint = lhs.toBigInt(&lhs_space, pt);
2181 const rhs_bigint = rhs.toBigInt(&rhs_space, mod);2220 const rhs_bigint = rhs.toBigInt(&rhs_space, pt);
2182 const limbs_q = try allocator.alloc(2221 const limbs_q = try allocator.alloc(
2183 std.math.big.Limb,2222 std.math.big.Limb,
2184 lhs_bigint.limbs.len,2223 lhs_bigint.limbs.len,
...@@ -2194,33 +2233,33 @@ pub fn intDivFloorScalar(lhs: Value, rhs: Value, ty: Type, allocator: Allocator,...@@ -2194,33 +2233,33 @@ pub fn intDivFloorScalar(lhs: Value, rhs: Value, ty: Type, allocator: Allocator,
2194 var result_q = BigIntMutable{ .limbs = limbs_q, .positive = undefined, .len = undefined };2233 var result_q = BigIntMutable{ .limbs = limbs_q, .positive = undefined, .len = undefined };
2195 var result_r = BigIntMutable{ .limbs = limbs_r, .positive = undefined, .len = undefined };2234 var result_r = BigIntMutable{ .limbs = limbs_r, .positive = undefined, .len = undefined };
2196 result_q.divFloor(&result_r, lhs_bigint, rhs_bigint, limbs_buffer);2235 result_q.divFloor(&result_r, lhs_bigint, rhs_bigint, limbs_buffer);
2197 return mod.intValue_big(ty, result_q.toConst());2236 return pt.intValue_big(ty, result_q.toConst());
2198}2237}
21992238
2200pub fn intMod(lhs: Value, rhs: Value, ty: Type, allocator: Allocator, mod: *Module) !Value {2239pub fn intMod(lhs: Value, rhs: Value, ty: Type, allocator: Allocator, pt: Zcu.PerThread) !Value {
2201 if (ty.zigTypeTag(mod) == .Vector) {2240 if (ty.zigTypeTag(pt.zcu) == .Vector) {
2202 const result_data = try allocator.alloc(InternPool.Index, ty.vectorLen(mod));2241 const result_data = try allocator.alloc(InternPool.Index, ty.vectorLen(pt.zcu));
2203 const scalar_ty = ty.scalarType(mod);2242 const scalar_ty = ty.scalarType(pt.zcu);
2204 for (result_data, 0..) |*scalar, i| {2243 for (result_data, 0..) |*scalar, i| {
2205 const lhs_elem = try lhs.elemValue(mod, i);2244 const lhs_elem = try lhs.elemValue(pt, i);
2206 const rhs_elem = try rhs.elemValue(mod, i);2245 const rhs_elem = try rhs.elemValue(pt, i);
2207 scalar.* = (try intModScalar(lhs_elem, rhs_elem, scalar_ty, allocator, mod)).toIntern();2246 scalar.* = (try intModScalar(lhs_elem, rhs_elem, scalar_ty, allocator, pt)).toIntern();
2208 }2247 }
2209 return Value.fromInterned((try mod.intern(.{ .aggregate = .{2248 return Value.fromInterned(try pt.intern(.{ .aggregate = .{
2210 .ty = ty.toIntern(),2249 .ty = ty.toIntern(),
2211 .storage = .{ .elems = result_data },2250 .storage = .{ .elems = result_data },
2212 } })));2251 } }));
2213 }2252 }
2214 return intModScalar(lhs, rhs, ty, allocator, mod);2253 return intModScalar(lhs, rhs, ty, allocator, pt);
2215}2254}
22162255
2217pub fn intModScalar(lhs: Value, rhs: Value, ty: Type, allocator: Allocator, mod: *Module) !Value {2256pub fn intModScalar(lhs: Value, rhs: Value, ty: Type, allocator: Allocator, pt: Zcu.PerThread) !Value {
2218 // TODO is this a performance issue? maybe we should try the operation without2257 // TODO is this a performance issue? maybe we should try the operation without
2219 // resorting to BigInt first.2258 // resorting to BigInt first.
2220 var lhs_space: Value.BigIntSpace = undefined;2259 var lhs_space: Value.BigIntSpace = undefined;
2221 var rhs_space: Value.BigIntSpace = undefined;2260 var rhs_space: Value.BigIntSpace = undefined;
2222 const lhs_bigint = lhs.toBigInt(&lhs_space, mod);2261 const lhs_bigint = lhs.toBigInt(&lhs_space, pt);
2223 const rhs_bigint = rhs.toBigInt(&rhs_space, mod);2262 const rhs_bigint = rhs.toBigInt(&rhs_space, pt);
2224 const limbs_q = try allocator.alloc(2263 const limbs_q = try allocator.alloc(
2225 std.math.big.Limb,2264 std.math.big.Limb,
2226 lhs_bigint.limbs.len,2265 lhs_bigint.limbs.len,
...@@ -2236,7 +2275,7 @@ pub fn intModScalar(lhs: Value, rhs: Value, ty: Type, allocator: Allocator, mod:...@@ -2236,7 +2275,7 @@ pub fn intModScalar(lhs: Value, rhs: Value, ty: Type, allocator: Allocator, mod:
2236 var result_q = BigIntMutable{ .limbs = limbs_q, .positive = undefined, .len = undefined };2275 var result_q = BigIntMutable{ .limbs = limbs_q, .positive = undefined, .len = undefined };
2237 var result_r = BigIntMutable{ .limbs = limbs_r, .positive = undefined, .len = undefined };2276 var result_r = BigIntMutable{ .limbs = limbs_r, .positive = undefined, .len = undefined };
2238 result_q.divFloor(&result_r, lhs_bigint, rhs_bigint, limbs_buffer);2277 result_q.divFloor(&result_r, lhs_bigint, rhs_bigint, limbs_buffer);
2239 return mod.intValue_big(ty, result_r.toConst());2278 return pt.intValue_big(ty, result_r.toConst());
2240}2279}
22412280
2242/// Returns true if the value is a floating point type and is NaN. Returns false otherwise.2281/// Returns true if the value is a floating point type and is NaN. Returns false otherwise.
...@@ -2268,85 +2307,86 @@ pub fn isNegativeInf(val: Value, mod: *const Module) bool {...@@ -2268,85 +2307,86 @@ pub fn isNegativeInf(val: Value, mod: *const Module) bool {
2268 };2307 };
2269}2308}
22702309
2271pub fn floatRem(lhs: Value, rhs: Value, float_type: Type, arena: Allocator, mod: *Module) !Value {2310pub fn floatRem(lhs: Value, rhs: Value, float_type: Type, arena: Allocator, pt: Zcu.PerThread) !Value {
2272 if (float_type.zigTypeTag(mod) == .Vector) {2311 if (float_type.zigTypeTag(pt.zcu) == .Vector) {
2273 const result_data = try arena.alloc(InternPool.Index, float_type.vectorLen(mod));2312 const result_data = try arena.alloc(InternPool.Index, float_type.vectorLen(pt.zcu));
2274 const scalar_ty = float_type.scalarType(mod);2313 const scalar_ty = float_type.scalarType(pt.zcu);
2275 for (result_data, 0..) |*scalar, i| {2314 for (result_data, 0..) |*scalar, i| {
2276 const lhs_elem = try lhs.elemValue(mod, i);2315 const lhs_elem = try lhs.elemValue(pt, i);
2277 const rhs_elem = try rhs.elemValue(mod, i);2316 const rhs_elem = try rhs.elemValue(pt, i);
2278 scalar.* = (try floatRemScalar(lhs_elem, rhs_elem, scalar_ty, mod)).toIntern();2317 scalar.* = (try floatRemScalar(lhs_elem, rhs_elem, scalar_ty, pt)).toIntern();
2279 }2318 }
2280 return Value.fromInterned((try mod.intern(.{ .aggregate = .{2319 return Value.fromInterned(try pt.intern(.{ .aggregate = .{
2281 .ty = float_type.toIntern(),2320 .ty = float_type.toIntern(),
2282 .storage = .{ .elems = result_data },2321 .storage = .{ .elems = result_data },
2283 } })));2322 } }));
2284 }2323 }
2285 return floatRemScalar(lhs, rhs, float_type, mod);2324 return floatRemScalar(lhs, rhs, float_type, pt);
2286}2325}
22872326
2288pub fn floatRemScalar(lhs: Value, rhs: Value, float_type: Type, mod: *Module) !Value {2327pub fn floatRemScalar(lhs: Value, rhs: Value, float_type: Type, pt: Zcu.PerThread) !Value {
2289 const target = mod.getTarget();2328 const target = pt.zcu.getTarget();
2290 const storage: InternPool.Key.Float.Storage = switch (float_type.floatBits(target)) {2329 const storage: InternPool.Key.Float.Storage = switch (float_type.floatBits(target)) {
2291 16 => .{ .f16 = @rem(lhs.toFloat(f16, mod), rhs.toFloat(f16, mod)) },2330 16 => .{ .f16 = @rem(lhs.toFloat(f16, pt), rhs.toFloat(f16, pt)) },
2292 32 => .{ .f32 = @rem(lhs.toFloat(f32, mod), rhs.toFloat(f32, mod)) },2331 32 => .{ .f32 = @rem(lhs.toFloat(f32, pt), rhs.toFloat(f32, pt)) },
2293 64 => .{ .f64 = @rem(lhs.toFloat(f64, mod), rhs.toFloat(f64, mod)) },2332 64 => .{ .f64 = @rem(lhs.toFloat(f64, pt), rhs.toFloat(f64, pt)) },
2294 80 => .{ .f80 = @rem(lhs.toFloat(f80, mod), rhs.toFloat(f80, mod)) },2333 80 => .{ .f80 = @rem(lhs.toFloat(f80, pt), rhs.toFloat(f80, pt)) },
2295 128 => .{ .f128 = @rem(lhs.toFloat(f128, mod), rhs.toFloat(f128, mod)) },2334 128 => .{ .f128 = @rem(lhs.toFloat(f128, pt), rhs.toFloat(f128, pt)) },
2296 else => unreachable,2335 else => unreachable,
2297 };2336 };
2298 return Value.fromInterned((try mod.intern(.{ .float = .{2337 return Value.fromInterned(try pt.intern(.{ .float = .{
2299 .ty = float_type.toIntern(),2338 .ty = float_type.toIntern(),
2300 .storage = storage,2339 .storage = storage,
2301 } })));2340 } }));
2302}2341}
23032342
2304pub fn floatMod(lhs: Value, rhs: Value, float_type: Type, arena: Allocator, mod: *Module) !Value {2343pub fn floatMod(lhs: Value, rhs: Value, float_type: Type, arena: Allocator, pt: Zcu.PerThread) !Value {
2305 if (float_type.zigTypeTag(mod) == .Vector) {2344 if (float_type.zigTypeTag(pt.zcu) == .Vector) {
2306 const result_data = try arena.alloc(InternPool.Index, float_type.vectorLen(mod));2345 const result_data = try arena.alloc(InternPool.Index, float_type.vectorLen(pt.zcu));
2307 const scalar_ty = float_type.scalarType(mod);2346 const scalar_ty = float_type.scalarType(pt.zcu);
2308 for (result_data, 0..) |*scalar, i| {2347 for (result_data, 0..) |*scalar, i| {
2309 const lhs_elem = try lhs.elemValue(mod, i);2348 const lhs_elem = try lhs.elemValue(pt, i);
2310 const rhs_elem = try rhs.elemValue(mod, i);2349 const rhs_elem = try rhs.elemValue(pt, i);
2311 scalar.* = (try floatModScalar(lhs_elem, rhs_elem, scalar_ty, mod)).toIntern();2350 scalar.* = (try floatModScalar(lhs_elem, rhs_elem, scalar_ty, pt)).toIntern();
2312 }2351 }
2313 return Value.fromInterned((try mod.intern(.{ .aggregate = .{2352 return Value.fromInterned(try pt.intern(.{ .aggregate = .{
2314 .ty = float_type.toIntern(),2353 .ty = float_type.toIntern(),
2315 .storage = .{ .elems = result_data },2354 .storage = .{ .elems = result_data },
2316 } })));2355 } }));
2317 }2356 }
2318 return floatModScalar(lhs, rhs, float_type, mod);2357 return floatModScalar(lhs, rhs, float_type, pt);
2319}2358}
23202359
2321pub fn floatModScalar(lhs: Value, rhs: Value, float_type: Type, mod: *Module) !Value {2360pub fn floatModScalar(lhs: Value, rhs: Value, float_type: Type, pt: Zcu.PerThread) !Value {
2322 const target = mod.getTarget();2361 const target = pt.zcu.getTarget();
2323 const storage: InternPool.Key.Float.Storage = switch (float_type.floatBits(target)) {2362 const storage: InternPool.Key.Float.Storage = switch (float_type.floatBits(target)) {
2324 16 => .{ .f16 = @mod(lhs.toFloat(f16, mod), rhs.toFloat(f16, mod)) },2363 16 => .{ .f16 = @mod(lhs.toFloat(f16, pt), rhs.toFloat(f16, pt)) },
2325 32 => .{ .f32 = @mod(lhs.toFloat(f32, mod), rhs.toFloat(f32, mod)) },2364 32 => .{ .f32 = @mod(lhs.toFloat(f32, pt), rhs.toFloat(f32, pt)) },
2326 64 => .{ .f64 = @mod(lhs.toFloat(f64, mod), rhs.toFloat(f64, mod)) },2365 64 => .{ .f64 = @mod(lhs.toFloat(f64, pt), rhs.toFloat(f64, pt)) },
2327 80 => .{ .f80 = @mod(lhs.toFloat(f80, mod), rhs.toFloat(f80, mod)) },2366 80 => .{ .f80 = @mod(lhs.toFloat(f80, pt), rhs.toFloat(f80, pt)) },
2328 128 => .{ .f128 = @mod(lhs.toFloat(f128, mod), rhs.toFloat(f128, mod)) },2367 128 => .{ .f128 = @mod(lhs.toFloat(f128, pt), rhs.toFloat(f128, pt)) },
2329 else => unreachable,2368 else => unreachable,
2330 };2369 };
2331 return Value.fromInterned((try mod.intern(.{ .float = .{2370 return Value.fromInterned(try pt.intern(.{ .float = .{
2332 .ty = float_type.toIntern(),2371 .ty = float_type.toIntern(),
2333 .storage = storage,2372 .storage = storage,
2334 } })));2373 } }));
2335}2374}
23362375
2337/// If the value overflowed the type, returns a comptime_int (or vector thereof) instead, setting2376/// If the value overflowed the type, returns a comptime_int (or vector thereof) instead, setting
2338/// overflow_idx to the vector index the overflow was at (or 0 for a scalar).2377/// overflow_idx to the vector index the overflow was at (or 0 for a scalar).
2339pub fn intMul(lhs: Value, rhs: Value, ty: Type, overflow_idx: *?usize, allocator: Allocator, mod: *Module) !Value {2378pub fn intMul(lhs: Value, rhs: Value, ty: Type, overflow_idx: *?usize, allocator: Allocator, pt: Zcu.PerThread) !Value {
2379 const mod = pt.zcu;
2340 var overflow: usize = undefined;2380 var overflow: usize = undefined;
2341 return intMulInner(lhs, rhs, ty, &overflow, allocator, mod) catch |err| switch (err) {2381 return intMulInner(lhs, rhs, ty, &overflow, allocator, pt) catch |err| switch (err) {
2342 error.Overflow => {2382 error.Overflow => {
2343 const is_vec = ty.isVector(mod);2383 const is_vec = ty.isVector(mod);
2344 overflow_idx.* = if (is_vec) overflow else 0;2384 overflow_idx.* = if (is_vec) overflow else 0;
2345 const safe_ty = if (is_vec) try mod.vectorType(.{2385 const safe_ty = if (is_vec) try pt.vectorType(.{
2346 .len = ty.vectorLen(mod),2386 .len = ty.vectorLen(mod),
2347 .child = .comptime_int_type,2387 .child = .comptime_int_type,
2348 }) else Type.comptime_int;2388 }) else Type.comptime_int;
2349 return intMulInner(lhs, rhs, safe_ty, undefined, allocator, mod) catch |err1| switch (err1) {2389 return intMulInner(lhs, rhs, safe_ty, undefined, allocator, pt) catch |err1| switch (err1) {
2350 error.Overflow => unreachable,2390 error.Overflow => unreachable,
2351 else => |e| return e,2391 else => |e| return e,
2352 };2392 };
...@@ -2355,14 +2395,15 @@ pub fn intMul(lhs: Value, rhs: Value, ty: Type, overflow_idx: *?usize, allocator...@@ -2355,14 +2395,15 @@ pub fn intMul(lhs: Value, rhs: Value, ty: Type, overflow_idx: *?usize, allocator
2355 };2395 };
2356}2396}
23572397
2358fn intMulInner(lhs: Value, rhs: Value, ty: Type, overflow_idx: *usize, allocator: Allocator, mod: *Module) !Value {2398fn intMulInner(lhs: Value, rhs: Value, ty: Type, overflow_idx: *usize, allocator: Allocator, pt: Zcu.PerThread) !Value {
2399 const mod = pt.zcu;
2359 if (ty.zigTypeTag(mod) == .Vector) {2400 if (ty.zigTypeTag(mod) == .Vector) {
2360 const result_data = try allocator.alloc(InternPool.Index, ty.vectorLen(mod));2401 const result_data = try allocator.alloc(InternPool.Index, ty.vectorLen(mod));
2361 const scalar_ty = ty.scalarType(mod);2402 const scalar_ty = ty.scalarType(mod);
2362 for (result_data, 0..) |*scalar, i| {2403 for (result_data, 0..) |*scalar, i| {
2363 const lhs_elem = try lhs.elemValue(mod, i);2404 const lhs_elem = try lhs.elemValue(pt, i);
2364 const rhs_elem = try rhs.elemValue(mod, i);2405 const rhs_elem = try rhs.elemValue(pt, i);
2365 const val = intMulScalar(lhs_elem, rhs_elem, scalar_ty, allocator, mod) catch |err| switch (err) {2406 const val = intMulScalar(lhs_elem, rhs_elem, scalar_ty, allocator, pt) catch |err| switch (err) {
2366 error.Overflow => {2407 error.Overflow => {
2367 overflow_idx.* = i;2408 overflow_idx.* = i;
2368 return error.Overflow;2409 return error.Overflow;
...@@ -2371,26 +2412,26 @@ fn intMulInner(lhs: Value, rhs: Value, ty: Type, overflow_idx: *usize, allocator...@@ -2371,26 +2412,26 @@ fn intMulInner(lhs: Value, rhs: Value, ty: Type, overflow_idx: *usize, allocator
2371 };2412 };
2372 scalar.* = val.toIntern();2413 scalar.* = val.toIntern();
2373 }2414 }
2374 return Value.fromInterned((try mod.intern(.{ .aggregate = .{2415 return Value.fromInterned(try pt.intern(.{ .aggregate = .{
2375 .ty = ty.toIntern(),2416 .ty = ty.toIntern(),
2376 .storage = .{ .elems = result_data },2417 .storage = .{ .elems = result_data },
2377 } })));2418 } }));
2378 }2419 }
2379 return intMulScalar(lhs, rhs, ty, allocator, mod);2420 return intMulScalar(lhs, rhs, ty, allocator, pt);
2380}2421}
23812422
2382pub fn intMulScalar(lhs: Value, rhs: Value, ty: Type, allocator: Allocator, mod: *Module) !Value {2423pub fn intMulScalar(lhs: Value, rhs: Value, ty: Type, allocator: Allocator, pt: Zcu.PerThread) !Value {
2383 if (ty.toIntern() != .comptime_int_type) {2424 if (ty.toIntern() != .comptime_int_type) {
2384 const res = try intMulWithOverflowScalar(lhs, rhs, ty, allocator, mod);2425 const res = try intMulWithOverflowScalar(lhs, rhs, ty, allocator, pt);
2385 if (res.overflow_bit.compareAllWithZero(.neq, mod)) return error.Overflow;2426 if (res.overflow_bit.compareAllWithZero(.neq, pt)) return error.Overflow;
2386 return res.wrapped_result;2427 return res.wrapped_result;
2387 }2428 }
2388 // TODO is this a performance issue? maybe we should try the operation without2429 // TODO is this a performance issue? maybe we should try the operation without
2389 // resorting to BigInt first.2430 // resorting to BigInt first.
2390 var lhs_space: Value.BigIntSpace = undefined;2431 var lhs_space: Value.BigIntSpace = undefined;
2391 var rhs_space: Value.BigIntSpace = undefined;2432 var rhs_space: Value.BigIntSpace = undefined;
2392 const lhs_bigint = lhs.toBigInt(&lhs_space, mod);2433 const lhs_bigint = lhs.toBigInt(&lhs_space, pt);
2393 const rhs_bigint = rhs.toBigInt(&rhs_space, mod);2434 const rhs_bigint = rhs.toBigInt(&rhs_space, pt);
2394 const limbs = try allocator.alloc(2435 const limbs = try allocator.alloc(
2395 std.math.big.Limb,2436 std.math.big.Limb,
2396 lhs_bigint.limbs.len + rhs_bigint.limbs.len,2437 lhs_bigint.limbs.len + rhs_bigint.limbs.len,
...@@ -2402,23 +2443,24 @@ pub fn intMulScalar(lhs: Value, rhs: Value, ty: Type, allocator: Allocator, mod:...@@ -2402,23 +2443,24 @@ pub fn intMulScalar(lhs: Value, rhs: Value, ty: Type, allocator: Allocator, mod:
2402 );2443 );
2403 defer allocator.free(limbs_buffer);2444 defer allocator.free(limbs_buffer);
2404 result_bigint.mul(lhs_bigint, rhs_bigint, limbs_buffer, allocator);2445 result_bigint.mul(lhs_bigint, rhs_bigint, limbs_buffer, allocator);
2405 return mod.intValue_big(ty, result_bigint.toConst());2446 return pt.intValue_big(ty, result_bigint.toConst());
2406}2447}
24072448
2408pub fn intTrunc(val: Value, ty: Type, allocator: Allocator, signedness: std.builtin.Signedness, bits: u16, mod: *Module) !Value {2449pub fn intTrunc(val: Value, ty: Type, allocator: Allocator, signedness: std.builtin.Signedness, bits: u16, pt: Zcu.PerThread) !Value {
2450 const mod = pt.zcu;
2409 if (ty.zigTypeTag(mod) == .Vector) {2451 if (ty.zigTypeTag(mod) == .Vector) {
2410 const result_data = try allocator.alloc(InternPool.Index, ty.vectorLen(mod));2452 const result_data = try allocator.alloc(InternPool.Index, ty.vectorLen(mod));
2411 const scalar_ty = ty.scalarType(mod);2453 const scalar_ty = ty.scalarType(mod);
2412 for (result_data, 0..) |*scalar, i| {2454 for (result_data, 0..) |*scalar, i| {
2413 const elem_val = try val.elemValue(mod, i);2455 const elem_val = try val.elemValue(pt, i);
2414 scalar.* = (try intTruncScalar(elem_val, scalar_ty, allocator, signedness, bits, mod)).toIntern();2456 scalar.* = (try intTruncScalar(elem_val, scalar_ty, allocator, signedness, bits, pt)).toIntern();
2415 }2457 }
2416 return Value.fromInterned((try mod.intern(.{ .aggregate = .{2458 return Value.fromInterned(try pt.intern(.{ .aggregate = .{
2417 .ty = ty.toIntern(),2459 .ty = ty.toIntern(),
2418 .storage = .{ .elems = result_data },2460 .storage = .{ .elems = result_data },
2419 } })));2461 } }));
2420 }2462 }
2421 return intTruncScalar(val, ty, allocator, signedness, bits, mod);2463 return intTruncScalar(val, ty, allocator, signedness, bits, pt);
2422}2464}
24232465
2424/// This variant may vectorize on `bits`. Asserts that `bits` is a (vector of) `u16`.2466/// This variant may vectorize on `bits`. Asserts that `bits` is a (vector of) `u16`.
...@@ -2428,22 +2470,22 @@ pub fn intTruncBitsAsValue(...@@ -2428,22 +2470,22 @@ pub fn intTruncBitsAsValue(
2428 allocator: Allocator,2470 allocator: Allocator,
2429 signedness: std.builtin.Signedness,2471 signedness: std.builtin.Signedness,
2430 bits: Value,2472 bits: Value,
2431 mod: *Module,2473 pt: Zcu.PerThread,
2432) !Value {2474) !Value {
2433 if (ty.zigTypeTag(mod) == .Vector) {2475 if (ty.zigTypeTag(pt.zcu) == .Vector) {
2434 const result_data = try allocator.alloc(InternPool.Index, ty.vectorLen(mod));2476 const result_data = try allocator.alloc(InternPool.Index, ty.vectorLen(pt.zcu));
2435 const scalar_ty = ty.scalarType(mod);2477 const scalar_ty = ty.scalarType(pt.zcu);
2436 for (result_data, 0..) |*scalar, i| {2478 for (result_data, 0..) |*scalar, i| {
2437 const elem_val = try val.elemValue(mod, i);2479 const elem_val = try val.elemValue(pt, i);
2438 const bits_elem = try bits.elemValue(mod, i);2480 const bits_elem = try bits.elemValue(pt, i);
2439 scalar.* = (try intTruncScalar(elem_val, scalar_ty, allocator, signedness, @intCast(bits_elem.toUnsignedInt(mod)), mod)).toIntern();2481 scalar.* = (try intTruncScalar(elem_val, scalar_ty, allocator, signedness, @intCast(bits_elem.toUnsignedInt(pt)), pt)).toIntern();
2440 }2482 }
2441 return Value.fromInterned((try mod.intern(.{ .aggregate = .{2483 return Value.fromInterned(try pt.intern(.{ .aggregate = .{
2442 .ty = ty.toIntern(),2484 .ty = ty.toIntern(),
2443 .storage = .{ .elems = result_data },2485 .storage = .{ .elems = result_data },
2444 } })));2486 } }));
2445 }2487 }
2446 return intTruncScalar(val, ty, allocator, signedness, @intCast(bits.toUnsignedInt(mod)), mod);2488 return intTruncScalar(val, ty, allocator, signedness, @intCast(bits.toUnsignedInt(pt)), pt);
2447}2489}
24482490
2449pub fn intTruncScalar(2491pub fn intTruncScalar(
...@@ -2452,14 +2494,15 @@ pub fn intTruncScalar(...@@ -2452,14 +2494,15 @@ pub fn intTruncScalar(
2452 allocator: Allocator,2494 allocator: Allocator,
2453 signedness: std.builtin.Signedness,2495 signedness: std.builtin.Signedness,
2454 bits: u16,2496 bits: u16,
2455 zcu: *Zcu,2497 pt: Zcu.PerThread,
2456) !Value {2498) !Value {
2457 if (bits == 0) return zcu.intValue(ty, 0);2499 const zcu = pt.zcu;
2500 if (bits == 0) return pt.intValue(ty, 0);
24582501
2459 if (val.isUndef(zcu)) return zcu.undefValue(ty);2502 if (val.isUndef(zcu)) return pt.undefValue(ty);
24602503
2461 var val_space: Value.BigIntSpace = undefined;2504 var val_space: Value.BigIntSpace = undefined;
2462 const val_bigint = val.toBigInt(&val_space, zcu);2505 const val_bigint = val.toBigInt(&val_space, pt);
24632506
2464 const limbs = try allocator.alloc(2507 const limbs = try allocator.alloc(
2465 std.math.big.Limb,2508 std.math.big.Limb,
...@@ -2468,32 +2511,33 @@ pub fn intTruncScalar(...@@ -2468,32 +2511,33 @@ pub fn intTruncScalar(
2468 var result_bigint = BigIntMutable{ .limbs = limbs, .positive = undefined, .len = undefined };2511 var result_bigint = BigIntMutable{ .limbs = limbs, .positive = undefined, .len = undefined };
24692512
2470 result_bigint.truncate(val_bigint, signedness, bits);2513 result_bigint.truncate(val_bigint, signedness, bits);
2471 return zcu.intValue_big(ty, result_bigint.toConst());2514 return pt.intValue_big(ty, result_bigint.toConst());
2472}2515}
24732516
2474pub fn shl(lhs: Value, rhs: Value, ty: Type, allocator: Allocator, mod: *Module) !Value {2517pub fn shl(lhs: Value, rhs: Value, ty: Type, allocator: Allocator, pt: Zcu.PerThread) !Value {
2518 const mod = pt.zcu;
2475 if (ty.zigTypeTag(mod) == .Vector) {2519 if (ty.zigTypeTag(mod) == .Vector) {
2476 const result_data = try allocator.alloc(InternPool.Index, ty.vectorLen(mod));2520 const result_data = try allocator.alloc(InternPool.Index, ty.vectorLen(mod));
2477 const scalar_ty = ty.scalarType(mod);2521 const scalar_ty = ty.scalarType(mod);
2478 for (result_data, 0..) |*scalar, i| {2522 for (result_data, 0..) |*scalar, i| {
2479 const lhs_elem = try lhs.elemValue(mod, i);2523 const lhs_elem = try lhs.elemValue(pt, i);
2480 const rhs_elem = try rhs.elemValue(mod, i);2524 const rhs_elem = try rhs.elemValue(pt, i);
2481 scalar.* = (try shlScalar(lhs_elem, rhs_elem, scalar_ty, allocator, mod)).toIntern();2525 scalar.* = (try shlScalar(lhs_elem, rhs_elem, scalar_ty, allocator, pt)).toIntern();
2482 }2526 }
2483 return Value.fromInterned((try mod.intern(.{ .aggregate = .{2527 return Value.fromInterned(try pt.intern(.{ .aggregate = .{
2484 .ty = ty.toIntern(),2528 .ty = ty.toIntern(),
2485 .storage = .{ .elems = result_data },2529 .storage = .{ .elems = result_data },
2486 } })));2530 } }));
2487 }2531 }
2488 return shlScalar(lhs, rhs, ty, allocator, mod);2532 return shlScalar(lhs, rhs, ty, allocator, pt);
2489}2533}
24902534
2491pub fn shlScalar(lhs: Value, rhs: Value, ty: Type, allocator: Allocator, mod: *Module) !Value {2535pub fn shlScalar(lhs: Value, rhs: Value, ty: Type, allocator: Allocator, pt: Zcu.PerThread) !Value {
2492 // TODO is this a performance issue? maybe we should try the operation without2536 // TODO is this a performance issue? maybe we should try the operation without
2493 // resorting to BigInt first.2537 // resorting to BigInt first.
2494 var lhs_space: Value.BigIntSpace = undefined;2538 var lhs_space: Value.BigIntSpace = undefined;
2495 const lhs_bigint = lhs.toBigInt(&lhs_space, mod);2539 const lhs_bigint = lhs.toBigInt(&lhs_space, pt);
2496 const shift: usize = @intCast(rhs.toUnsignedInt(mod));2540 const shift: usize = @intCast(rhs.toUnsignedInt(pt));
2497 const limbs = try allocator.alloc(2541 const limbs = try allocator.alloc(
2498 std.math.big.Limb,2542 std.math.big.Limb,
2499 lhs_bigint.limbs.len + (shift / (@sizeOf(std.math.big.Limb) * 8)) + 1,2543 lhs_bigint.limbs.len + (shift / (@sizeOf(std.math.big.Limb) * 8)) + 1,
...@@ -2505,11 +2549,11 @@ pub fn shlScalar(lhs: Value, rhs: Value, ty: Type, allocator: Allocator, mod: *M...@@ -2505,11 +2549,11 @@ pub fn shlScalar(lhs: Value, rhs: Value, ty: Type, allocator: Allocator, mod: *M
2505 };2549 };
2506 result_bigint.shiftLeft(lhs_bigint, shift);2550 result_bigint.shiftLeft(lhs_bigint, shift);
2507 if (ty.toIntern() != .comptime_int_type) {2551 if (ty.toIntern() != .comptime_int_type) {
2508 const int_info = ty.intInfo(mod);2552 const int_info = ty.intInfo(pt.zcu);
2509 result_bigint.truncate(result_bigint.toConst(), int_info.signedness, int_info.bits);2553 result_bigint.truncate(result_bigint.toConst(), int_info.signedness, int_info.bits);
2510 }2554 }
25112555
2512 return mod.intValue_big(ty, result_bigint.toConst());2556 return pt.intValue_big(ty, result_bigint.toConst());
2513}2557}
25142558
2515pub fn shlWithOverflow(2559pub fn shlWithOverflow(
...@@ -2517,32 +2561,32 @@ pub fn shlWithOverflow(...@@ -2517,32 +2561,32 @@ pub fn shlWithOverflow(
2517 rhs: Value,2561 rhs: Value,
2518 ty: Type,2562 ty: Type,
2519 allocator: Allocator,2563 allocator: Allocator,
2520 mod: *Module,2564 pt: Zcu.PerThread,
2521) !OverflowArithmeticResult {2565) !OverflowArithmeticResult {
2522 if (ty.zigTypeTag(mod) == .Vector) {2566 if (ty.zigTypeTag(pt.zcu) == .Vector) {
2523 const vec_len = ty.vectorLen(mod);2567 const vec_len = ty.vectorLen(pt.zcu);
2524 const overflowed_data = try allocator.alloc(InternPool.Index, vec_len);2568 const overflowed_data = try allocator.alloc(InternPool.Index, vec_len);
2525 const result_data = try allocator.alloc(InternPool.Index, vec_len);2569 const result_data = try allocator.alloc(InternPool.Index, vec_len);
2526 const scalar_ty = ty.scalarType(mod);2570 const scalar_ty = ty.scalarType(pt.zcu);
2527 for (overflowed_data, result_data, 0..) |*of, *scalar, i| {2571 for (overflowed_data, result_data, 0..) |*of, *scalar, i| {
2528 const lhs_elem = try lhs.elemValue(mod, i);2572 const lhs_elem = try lhs.elemValue(pt, i);
2529 const rhs_elem = try rhs.elemValue(mod, i);2573 const rhs_elem = try rhs.elemValue(pt, i);
2530 const of_math_result = try shlWithOverflowScalar(lhs_elem, rhs_elem, scalar_ty, allocator, mod);2574 const of_math_result = try shlWithOverflowScalar(lhs_elem, rhs_elem, scalar_ty, allocator, pt);
2531 of.* = of_math_result.overflow_bit.toIntern();2575 of.* = of_math_result.overflow_bit.toIntern();
2532 scalar.* = of_math_result.wrapped_result.toIntern();2576 scalar.* = of_math_result.wrapped_result.toIntern();
2533 }2577 }
2534 return OverflowArithmeticResult{2578 return OverflowArithmeticResult{
2535 .overflow_bit = Value.fromInterned((try mod.intern(.{ .aggregate = .{2579 .overflow_bit = Value.fromInterned(try pt.intern(.{ .aggregate = .{
2536 .ty = (try mod.vectorType(.{ .len = vec_len, .child = .u1_type })).toIntern(),2580 .ty = (try pt.vectorType(.{ .len = vec_len, .child = .u1_type })).toIntern(),
2537 .storage = .{ .elems = overflowed_data },2581 .storage = .{ .elems = overflowed_data },
2538 } }))),2582 } })),
2539 .wrapped_result = Value.fromInterned((try mod.intern(.{ .aggregate = .{2583 .wrapped_result = Value.fromInterned(try pt.intern(.{ .aggregate = .{
2540 .ty = ty.toIntern(),2584 .ty = ty.toIntern(),
2541 .storage = .{ .elems = result_data },2585 .storage = .{ .elems = result_data },
2542 } }))),2586 } })),
2543 };2587 };
2544 }2588 }
2545 return shlWithOverflowScalar(lhs, rhs, ty, allocator, mod);2589 return shlWithOverflowScalar(lhs, rhs, ty, allocator, pt);
2546}2590}
25472591
2548pub fn shlWithOverflowScalar(2592pub fn shlWithOverflowScalar(
...@@ -2550,12 +2594,12 @@ pub fn shlWithOverflowScalar(...@@ -2550,12 +2594,12 @@ pub fn shlWithOverflowScalar(
2550 rhs: Value,2594 rhs: Value,
2551 ty: Type,2595 ty: Type,
2552 allocator: Allocator,2596 allocator: Allocator,
2553 mod: *Module,2597 pt: Zcu.PerThread,
2554) !OverflowArithmeticResult {2598) !OverflowArithmeticResult {
2555 const info = ty.intInfo(mod);2599 const info = ty.intInfo(pt.zcu);
2556 var lhs_space: Value.BigIntSpace = undefined;2600 var lhs_space: Value.BigIntSpace = undefined;
2557 const lhs_bigint = lhs.toBigInt(&lhs_space, mod);2601 const lhs_bigint = lhs.toBigInt(&lhs_space, pt);
2558 const shift: usize = @intCast(rhs.toUnsignedInt(mod));2602 const shift: usize = @intCast(rhs.toUnsignedInt(pt));
2559 const limbs = try allocator.alloc(2603 const limbs = try allocator.alloc(
2560 std.math.big.Limb,2604 std.math.big.Limb,
2561 lhs_bigint.limbs.len + (shift / (@sizeOf(std.math.big.Limb) * 8)) + 1,2605 lhs_bigint.limbs.len + (shift / (@sizeOf(std.math.big.Limb) * 8)) + 1,
...@@ -2571,8 +2615,8 @@ pub fn shlWithOverflowScalar(...@@ -2571,8 +2615,8 @@ pub fn shlWithOverflowScalar(
2571 result_bigint.truncate(result_bigint.toConst(), info.signedness, info.bits);2615 result_bigint.truncate(result_bigint.toConst(), info.signedness, info.bits);
2572 }2616 }
2573 return OverflowArithmeticResult{2617 return OverflowArithmeticResult{
2574 .overflow_bit = try mod.intValue(Type.u1, @intFromBool(overflowed)),2618 .overflow_bit = try pt.intValue(Type.u1, @intFromBool(overflowed)),
2575 .wrapped_result = try mod.intValue_big(ty, result_bigint.toConst()),2619 .wrapped_result = try pt.intValue_big(ty, result_bigint.toConst()),
2576 };2620 };
2577}2621}
25782622
...@@ -2581,22 +2625,22 @@ pub fn shlSat(...@@ -2581,22 +2625,22 @@ pub fn shlSat(
2581 rhs: Value,2625 rhs: Value,
2582 ty: Type,2626 ty: Type,
2583 arena: Allocator,2627 arena: Allocator,
2584 mod: *Module,2628 pt: Zcu.PerThread,
2585) !Value {2629) !Value {
2586 if (ty.zigTypeTag(mod) == .Vector) {2630 if (ty.zigTypeTag(pt.zcu) == .Vector) {
2587 const result_data = try arena.alloc(InternPool.Index, ty.vectorLen(mod));2631 const result_data = try arena.alloc(InternPool.Index, ty.vectorLen(pt.zcu));
2588 const scalar_ty = ty.scalarType(mod);2632 const scalar_ty = ty.scalarType(pt.zcu);
2589 for (result_data, 0..) |*scalar, i| {2633 for (result_data, 0..) |*scalar, i| {
2590 const lhs_elem = try lhs.elemValue(mod, i);2634 const lhs_elem = try lhs.elemValue(pt, i);
2591 const rhs_elem = try rhs.elemValue(mod, i);2635 const rhs_elem = try rhs.elemValue(pt, i);
2592 scalar.* = (try shlSatScalar(lhs_elem, rhs_elem, scalar_ty, arena, mod)).toIntern();2636 scalar.* = (try shlSatScalar(lhs_elem, rhs_elem, scalar_ty, arena, pt)).toIntern();
2593 }2637 }
2594 return Value.fromInterned((try mod.intern(.{ .aggregate = .{2638 return Value.fromInterned(try pt.intern(.{ .aggregate = .{
2595 .ty = ty.toIntern(),2639 .ty = ty.toIntern(),
2596 .storage = .{ .elems = result_data },2640 .storage = .{ .elems = result_data },
2597 } })));2641 } }));
2598 }2642 }
2599 return shlSatScalar(lhs, rhs, ty, arena, mod);2643 return shlSatScalar(lhs, rhs, ty, arena, pt);
2600}2644}
26012645
2602pub fn shlSatScalar(2646pub fn shlSatScalar(
...@@ -2604,15 +2648,15 @@ pub fn shlSatScalar(...@@ -2604,15 +2648,15 @@ pub fn shlSatScalar(
2604 rhs: Value,2648 rhs: Value,
2605 ty: Type,2649 ty: Type,
2606 arena: Allocator,2650 arena: Allocator,
2607 mod: *Module,2651 pt: Zcu.PerThread,
2608) !Value {2652) !Value {
2609 // TODO is this a performance issue? maybe we should try the operation without2653 // TODO is this a performance issue? maybe we should try the operation without
2610 // resorting to BigInt first.2654 // resorting to BigInt first.
2611 const info = ty.intInfo(mod);2655 const info = ty.intInfo(pt.zcu);
26122656
2613 var lhs_space: Value.BigIntSpace = undefined;2657 var lhs_space: Value.BigIntSpace = undefined;
2614 const lhs_bigint = lhs.toBigInt(&lhs_space, mod);2658 const lhs_bigint = lhs.toBigInt(&lhs_space, pt);
2615 const shift: usize = @intCast(rhs.toUnsignedInt(mod));2659 const shift: usize = @intCast(rhs.toUnsignedInt(pt));
2616 const limbs = try arena.alloc(2660 const limbs = try arena.alloc(
2617 std.math.big.Limb,2661 std.math.big.Limb,
2618 std.math.big.int.calcTwosCompLimbCount(info.bits) + 1,2662 std.math.big.int.calcTwosCompLimbCount(info.bits) + 1,
...@@ -2623,7 +2667,7 @@ pub fn shlSatScalar(...@@ -2623,7 +2667,7 @@ pub fn shlSatScalar(
2623 .len = undefined,2667 .len = undefined,
2624 };2668 };
2625 result_bigint.shiftLeftSat(lhs_bigint, shift, info.signedness, info.bits);2669 result_bigint.shiftLeftSat(lhs_bigint, shift, info.signedness, info.bits);
2626 return mod.intValue_big(ty, result_bigint.toConst());2670 return pt.intValue_big(ty, result_bigint.toConst());
2627}2671}
26282672
2629pub fn shlTrunc(2673pub fn shlTrunc(
...@@ -2631,22 +2675,22 @@ pub fn shlTrunc(...@@ -2631,22 +2675,22 @@ pub fn shlTrunc(
2631 rhs: Value,2675 rhs: Value,
2632 ty: Type,2676 ty: Type,
2633 arena: Allocator,2677 arena: Allocator,
2634 mod: *Module,2678 pt: Zcu.PerThread,
2635) !Value {2679) !Value {
2636 if (ty.zigTypeTag(mod) == .Vector) {2680 if (ty.zigTypeTag(pt.zcu) == .Vector) {
2637 const result_data = try arena.alloc(InternPool.Index, ty.vectorLen(mod));2681 const result_data = try arena.alloc(InternPool.Index, ty.vectorLen(pt.zcu));
2638 const scalar_ty = ty.scalarType(mod);2682 const scalar_ty = ty.scalarType(pt.zcu);
2639 for (result_data, 0..) |*scalar, i| {2683 for (result_data, 0..) |*scalar, i| {
2640 const lhs_elem = try lhs.elemValue(mod, i);2684 const lhs_elem = try lhs.elemValue(pt, i);
2641 const rhs_elem = try rhs.elemValue(mod, i);2685 const rhs_elem = try rhs.elemValue(pt, i);
2642 scalar.* = (try shlTruncScalar(lhs_elem, rhs_elem, scalar_ty, arena, mod)).toIntern();2686 scalar.* = (try shlTruncScalar(lhs_elem, rhs_elem, scalar_ty, arena, pt)).toIntern();
2643 }2687 }
2644 return Value.fromInterned((try mod.intern(.{ .aggregate = .{2688 return Value.fromInterned(try pt.intern(.{ .aggregate = .{
2645 .ty = ty.toIntern(),2689 .ty = ty.toIntern(),
2646 .storage = .{ .elems = result_data },2690 .storage = .{ .elems = result_data },
2647 } })));2691 } }));
2648 }2692 }
2649 return shlTruncScalar(lhs, rhs, ty, arena, mod);2693 return shlTruncScalar(lhs, rhs, ty, arena, pt);
2650}2694}
26512695
2652pub fn shlTruncScalar(2696pub fn shlTruncScalar(
...@@ -2654,46 +2698,46 @@ pub fn shlTruncScalar(...@@ -2654,46 +2698,46 @@ pub fn shlTruncScalar(
2654 rhs: Value,2698 rhs: Value,
2655 ty: Type,2699 ty: Type,
2656 arena: Allocator,2700 arena: Allocator,
2657 mod: *Module,2701 pt: Zcu.PerThread,
2658) !Value {2702) !Value {
2659 const shifted = try lhs.shl(rhs, ty, arena, mod);2703 const shifted = try lhs.shl(rhs, ty, arena, pt);
2660 const int_info = ty.intInfo(mod);2704 const int_info = ty.intInfo(pt.zcu);
2661 const truncated = try shifted.intTrunc(ty, arena, int_info.signedness, int_info.bits, mod);2705 const truncated = try shifted.intTrunc(ty, arena, int_info.signedness, int_info.bits, pt);
2662 return truncated;2706 return truncated;
2663}2707}
26642708
2665pub fn shr(lhs: Value, rhs: Value, ty: Type, allocator: Allocator, mod: *Module) !Value {2709pub fn shr(lhs: Value, rhs: Value, ty: Type, allocator: Allocator, pt: Zcu.PerThread) !Value {
2666 if (ty.zigTypeTag(mod) == .Vector) {2710 if (ty.zigTypeTag(pt.zcu) == .Vector) {
2667 const result_data = try allocator.alloc(InternPool.Index, ty.vectorLen(mod));2711 const result_data = try allocator.alloc(InternPool.Index, ty.vectorLen(pt.zcu));
2668 const scalar_ty = ty.scalarType(mod);2712 const scalar_ty = ty.scalarType(pt.zcu);
2669 for (result_data, 0..) |*scalar, i| {2713 for (result_data, 0..) |*scalar, i| {
2670 const lhs_elem = try lhs.elemValue(mod, i);2714 const lhs_elem = try lhs.elemValue(pt, i);
2671 const rhs_elem = try rhs.elemValue(mod, i);2715 const rhs_elem = try rhs.elemValue(pt, i);
2672 scalar.* = (try shrScalar(lhs_elem, rhs_elem, scalar_ty, allocator, mod)).toIntern();2716 scalar.* = (try shrScalar(lhs_elem, rhs_elem, scalar_ty, allocator, pt)).toIntern();
2673 }2717 }
2674 return Value.fromInterned((try mod.intern(.{ .aggregate = .{2718 return Value.fromInterned(try pt.intern(.{ .aggregate = .{
2675 .ty = ty.toIntern(),2719 .ty = ty.toIntern(),
2676 .storage = .{ .elems = result_data },2720 .storage = .{ .elems = result_data },
2677 } })));2721 } }));
2678 }2722 }
2679 return shrScalar(lhs, rhs, ty, allocator, mod);2723 return shrScalar(lhs, rhs, ty, allocator, pt);
2680}2724}
26812725
2682pub fn shrScalar(lhs: Value, rhs: Value, ty: Type, allocator: Allocator, mod: *Module) !Value {2726pub fn shrScalar(lhs: Value, rhs: Value, ty: Type, allocator: Allocator, pt: Zcu.PerThread) !Value {
2683 // TODO is this a performance issue? maybe we should try the operation without2727 // TODO is this a performance issue? maybe we should try the operation without
2684 // resorting to BigInt first.2728 // resorting to BigInt first.
2685 var lhs_space: Value.BigIntSpace = undefined;2729 var lhs_space: Value.BigIntSpace = undefined;
2686 const lhs_bigint = lhs.toBigInt(&lhs_space, mod);2730 const lhs_bigint = lhs.toBigInt(&lhs_space, pt);
2687 const shift: usize = @intCast(rhs.toUnsignedInt(mod));2731 const shift: usize = @intCast(rhs.toUnsignedInt(pt));
26882732
2689 const result_limbs = lhs_bigint.limbs.len -| (shift / (@sizeOf(std.math.big.Limb) * 8));2733 const result_limbs = lhs_bigint.limbs.len -| (shift / (@sizeOf(std.math.big.Limb) * 8));
2690 if (result_limbs == 0) {2734 if (result_limbs == 0) {
2691 // The shift is enough to remove all the bits from the number, which means the2735 // The shift is enough to remove all the bits from the number, which means the
2692 // result is 0 or -1 depending on the sign.2736 // result is 0 or -1 depending on the sign.
2693 if (lhs_bigint.positive) {2737 if (lhs_bigint.positive) {
2694 return mod.intValue(ty, 0);2738 return pt.intValue(ty, 0);
2695 } else {2739 } else {
2696 return mod.intValue(ty, -1);2740 return pt.intValue(ty, -1);
2697 }2741 }
2698 }2742 }
26992743
...@@ -2707,48 +2751,45 @@ pub fn shrScalar(lhs: Value, rhs: Value, ty: Type, allocator: Allocator, mod: *M...@@ -2707,48 +2751,45 @@ pub fn shrScalar(lhs: Value, rhs: Value, ty: Type, allocator: Allocator, mod: *M
2707 .len = undefined,2751 .len = undefined,
2708 };2752 };
2709 result_bigint.shiftRight(lhs_bigint, shift);2753 result_bigint.shiftRight(lhs_bigint, shift);
2710 return mod.intValue_big(ty, result_bigint.toConst());2754 return pt.intValue_big(ty, result_bigint.toConst());
2711}2755}
27122756
2713pub fn floatNeg(2757pub fn floatNeg(
2714 val: Value,2758 val: Value,
2715 float_type: Type,2759 float_type: Type,
2716 arena: Allocator,2760 arena: Allocator,
2717 mod: *Module,2761 pt: Zcu.PerThread,
2718) !Value {2762) !Value {
2763 const mod = pt.zcu;
2719 if (float_type.zigTypeTag(mod) == .Vector) {2764 if (float_type.zigTypeTag(mod) == .Vector) {
2720 const result_data = try arena.alloc(InternPool.Index, float_type.vectorLen(mod));2765 const result_data = try arena.alloc(InternPool.Index, float_type.vectorLen(mod));
2721 const scalar_ty = float_type.scalarType(mod);2766 const scalar_ty = float_type.scalarType(mod);
2722 for (result_data, 0..) |*scalar, i| {2767 for (result_data, 0..) |*scalar, i| {
2723 const elem_val = try val.elemValue(mod, i);2768 const elem_val = try val.elemValue(pt, i);
2724 scalar.* = (try floatNegScalar(elem_val, scalar_ty, mod)).toIntern();2769 scalar.* = (try floatNegScalar(elem_val, scalar_ty, pt)).toIntern();
2725 }2770 }
2726 return Value.fromInterned((try mod.intern(.{ .aggregate = .{2771 return Value.fromInterned(try pt.intern(.{ .aggregate = .{
2727 .ty = float_type.toIntern(),2772 .ty = float_type.toIntern(),
2728 .storage = .{ .elems = result_data },2773 .storage = .{ .elems = result_data },
2729 } })));2774 } }));
2730 }2775 }
2731 return floatNegScalar(val, float_type, mod);2776 return floatNegScalar(val, float_type, pt);
2732}2777}
27332778
2734pub fn floatNegScalar(2779pub fn floatNegScalar(val: Value, float_type: Type, pt: Zcu.PerThread) !Value {
2735 val: Value,2780 const target = pt.zcu.getTarget();
2736 float_type: Type,
2737 mod: *Module,
2738) !Value {
2739 const target = mod.getTarget();
2740 const storage: InternPool.Key.Float.Storage = switch (float_type.floatBits(target)) {2781 const storage: InternPool.Key.Float.Storage = switch (float_type.floatBits(target)) {
2741 16 => .{ .f16 = -val.toFloat(f16, mod) },2782 16 => .{ .f16 = -val.toFloat(f16, pt) },
2742 32 => .{ .f32 = -val.toFloat(f32, mod) },2783 32 => .{ .f32 = -val.toFloat(f32, pt) },
2743 64 => .{ .f64 = -val.toFloat(f64, mod) },2784 64 => .{ .f64 = -val.toFloat(f64, pt) },
2744 80 => .{ .f80 = -val.toFloat(f80, mod) },2785 80 => .{ .f80 = -val.toFloat(f80, pt) },
2745 128 => .{ .f128 = -val.toFloat(f128, mod) },2786 128 => .{ .f128 = -val.toFloat(f128, pt) },
2746 else => unreachable,2787 else => unreachable,
2747 };2788 };
2748 return Value.fromInterned((try mod.intern(.{ .float = .{2789 return Value.fromInterned(try pt.intern(.{ .float = .{
2749 .ty = float_type.toIntern(),2790 .ty = float_type.toIntern(),
2750 .storage = storage,2791 .storage = storage,
2751 } })));2792 } }));
2752}2793}
27532794
2754pub fn floatAdd(2795pub fn floatAdd(
...@@ -2756,43 +2797,45 @@ pub fn floatAdd(...@@ -2756,43 +2797,45 @@ pub fn floatAdd(
2756 rhs: Value,2797 rhs: Value,
2757 float_type: Type,2798 float_type: Type,
2758 arena: Allocator,2799 arena: Allocator,
2759 mod: *Module,2800 pt: Zcu.PerThread,
2760) !Value {2801) !Value {
2802 const mod = pt.zcu;
2761 if (float_type.zigTypeTag(mod) == .Vector) {2803 if (float_type.zigTypeTag(mod) == .Vector) {
2762 const result_data = try arena.alloc(InternPool.Index, float_type.vectorLen(mod));2804 const result_data = try arena.alloc(InternPool.Index, float_type.vectorLen(mod));
2763 const scalar_ty = float_type.scalarType(mod);2805 const scalar_ty = float_type.scalarType(mod);
2764 for (result_data, 0..) |*scalar, i| {2806 for (result_data, 0..) |*scalar, i| {
2765 const lhs_elem = try lhs.elemValue(mod, i);2807 const lhs_elem = try lhs.elemValue(pt, i);
2766 const rhs_elem = try rhs.elemValue(mod, i);2808 const rhs_elem = try rhs.elemValue(pt, i);
2767 scalar.* = (try floatAddScalar(lhs_elem, rhs_elem, scalar_ty, mod)).toIntern();2809 scalar.* = (try floatAddScalar(lhs_elem, rhs_elem, scalar_ty, pt)).toIntern();
2768 }2810 }
2769 return Value.fromInterned((try mod.intern(.{ .aggregate = .{2811 return Value.fromInterned(try pt.intern(.{ .aggregate = .{
2770 .ty = float_type.toIntern(),2812 .ty = float_type.toIntern(),
2771 .storage = .{ .elems = result_data },2813 .storage = .{ .elems = result_data },
2772 } })));2814 } }));
2773 }2815 }
2774 return floatAddScalar(lhs, rhs, float_type, mod);2816 return floatAddScalar(lhs, rhs, float_type, pt);
2775}2817}
27762818
2777pub fn floatAddScalar(2819pub fn floatAddScalar(
2778 lhs: Value,2820 lhs: Value,
2779 rhs: Value,2821 rhs: Value,
2780 float_type: Type,2822 float_type: Type,
2781 mod: *Module,2823 pt: Zcu.PerThread,
2782) !Value {2824) !Value {
2825 const mod = pt.zcu;
2783 const target = mod.getTarget();2826 const target = mod.getTarget();
2784 const storage: InternPool.Key.Float.Storage = switch (float_type.floatBits(target)) {2827 const storage: InternPool.Key.Float.Storage = switch (float_type.floatBits(target)) {
2785 16 => .{ .f16 = lhs.toFloat(f16, mod) + rhs.toFloat(f16, mod) },2828 16 => .{ .f16 = lhs.toFloat(f16, pt) + rhs.toFloat(f16, pt) },
2786 32 => .{ .f32 = lhs.toFloat(f32, mod) + rhs.toFloat(f32, mod) },2829 32 => .{ .f32 = lhs.toFloat(f32, pt) + rhs.toFloat(f32, pt) },
2787 64 => .{ .f64 = lhs.toFloat(f64, mod) + rhs.toFloat(f64, mod) },2830 64 => .{ .f64 = lhs.toFloat(f64, pt) + rhs.toFloat(f64, pt) },
2788 80 => .{ .f80 = lhs.toFloat(f80, mod) + rhs.toFloat(f80, mod) },2831 80 => .{ .f80 = lhs.toFloat(f80, pt) + rhs.toFloat(f80, pt) },
2789 128 => .{ .f128 = lhs.toFloat(f128, mod) + rhs.toFloat(f128, mod) },2832 128 => .{ .f128 = lhs.toFloat(f128, pt) + rhs.toFloat(f128, pt) },
2790 else => unreachable,2833 else => unreachable,
2791 };2834 };
2792 return Value.fromInterned((try mod.intern(.{ .float = .{2835 return Value.fromInterned(try pt.intern(.{ .float = .{
2793 .ty = float_type.toIntern(),2836 .ty = float_type.toIntern(),
2794 .storage = storage,2837 .storage = storage,
2795 } })));2838 } }));
2796}2839}
27972840
2798pub fn floatSub(2841pub fn floatSub(
...@@ -2800,43 +2843,45 @@ pub fn floatSub(...@@ -2800,43 +2843,45 @@ pub fn floatSub(
2800 rhs: Value,2843 rhs: Value,
2801 float_type: Type,2844 float_type: Type,
2802 arena: Allocator,2845 arena: Allocator,
2803 mod: *Module,2846 pt: Zcu.PerThread,
2804) !Value {2847) !Value {
2848 const mod = pt.zcu;
2805 if (float_type.zigTypeTag(mod) == .Vector) {2849 if (float_type.zigTypeTag(mod) == .Vector) {
2806 const result_data = try arena.alloc(InternPool.Index, float_type.vectorLen(mod));2850 const result_data = try arena.alloc(InternPool.Index, float_type.vectorLen(mod));
2807 const scalar_ty = float_type.scalarType(mod);2851 const scalar_ty = float_type.scalarType(mod);
2808 for (result_data, 0..) |*scalar, i| {2852 for (result_data, 0..) |*scalar, i| {
2809 const lhs_elem = try lhs.elemValue(mod, i);2853 const lhs_elem = try lhs.elemValue(pt, i);
2810 const rhs_elem = try rhs.elemValue(mod, i);2854 const rhs_elem = try rhs.elemValue(pt, i);
2811 scalar.* = (try floatSubScalar(lhs_elem, rhs_elem, scalar_ty, mod)).toIntern();2855 scalar.* = (try floatSubScalar(lhs_elem, rhs_elem, scalar_ty, pt)).toIntern();
2812 }2856 }
2813 return Value.fromInterned((try mod.intern(.{ .aggregate = .{2857 return Value.fromInterned(try pt.intern(.{ .aggregate = .{
2814 .ty = float_type.toIntern(),2858 .ty = float_type.toIntern(),
2815 .storage = .{ .elems = result_data },2859 .storage = .{ .elems = result_data },
2816 } })));2860 } }));
2817 }2861 }
2818 return floatSubScalar(lhs, rhs, float_type, mod);2862 return floatSubScalar(lhs, rhs, float_type, pt);
2819}2863}
28202864
2821pub fn floatSubScalar(2865pub fn floatSubScalar(
2822 lhs: Value,2866 lhs: Value,
2823 rhs: Value,2867 rhs: Value,
2824 float_type: Type,2868 float_type: Type,
2825 mod: *Module,2869 pt: Zcu.PerThread,
2826) !Value {2870) !Value {
2871 const mod = pt.zcu;
2827 const target = mod.getTarget();2872 const target = mod.getTarget();
2828 const storage: InternPool.Key.Float.Storage = switch (float_type.floatBits(target)) {2873 const storage: InternPool.Key.Float.Storage = switch (float_type.floatBits(target)) {
2829 16 => .{ .f16 = lhs.toFloat(f16, mod) - rhs.toFloat(f16, mod) },2874 16 => .{ .f16 = lhs.toFloat(f16, pt) - rhs.toFloat(f16, pt) },
2830 32 => .{ .f32 = lhs.toFloat(f32, mod) - rhs.toFloat(f32, mod) },2875 32 => .{ .f32 = lhs.toFloat(f32, pt) - rhs.toFloat(f32, pt) },
2831 64 => .{ .f64 = lhs.toFloat(f64, mod) - rhs.toFloat(f64, mod) },2876 64 => .{ .f64 = lhs.toFloat(f64, pt) - rhs.toFloat(f64, pt) },
2832 80 => .{ .f80 = lhs.toFloat(f80, mod) - rhs.toFloat(f80, mod) },2877 80 => .{ .f80 = lhs.toFloat(f80, pt) - rhs.toFloat(f80, pt) },
2833 128 => .{ .f128 = lhs.toFloat(f128, mod) - rhs.toFloat(f128, mod) },2878 128 => .{ .f128 = lhs.toFloat(f128, pt) - rhs.toFloat(f128, pt) },
2834 else => unreachable,2879 else => unreachable,
2835 };2880 };
2836 return Value.fromInterned((try mod.intern(.{ .float = .{2881 return Value.fromInterned(try pt.intern(.{ .float = .{
2837 .ty = float_type.toIntern(),2882 .ty = float_type.toIntern(),
2838 .storage = storage,2883 .storage = storage,
2839 } })));2884 } }));
2840}2885}
28412886
2842pub fn floatDiv(2887pub fn floatDiv(
...@@ -2844,43 +2889,43 @@ pub fn floatDiv(...@@ -2844,43 +2889,43 @@ pub fn floatDiv(
2844 rhs: Value,2889 rhs: Value,
2845 float_type: Type,2890 float_type: Type,
2846 arena: Allocator,2891 arena: Allocator,
2847 mod: *Module,2892 pt: Zcu.PerThread,
2848) !Value {2893) !Value {
2849 if (float_type.zigTypeTag(mod) == .Vector) {2894 if (float_type.zigTypeTag(pt.zcu) == .Vector) {
2850 const result_data = try arena.alloc(InternPool.Index, float_type.vectorLen(mod));2895 const result_data = try arena.alloc(InternPool.Index, float_type.vectorLen(pt.zcu));
2851 const scalar_ty = float_type.scalarType(mod);2896 const scalar_ty = float_type.scalarType(pt.zcu);
2852 for (result_data, 0..) |*scalar, i| {2897 for (result_data, 0..) |*scalar, i| {
2853 const lhs_elem = try lhs.elemValue(mod, i);2898 const lhs_elem = try lhs.elemValue(pt, i);
2854 const rhs_elem = try rhs.elemValue(mod, i);2899 const rhs_elem = try rhs.elemValue(pt, i);
2855 scalar.* = (try floatDivScalar(lhs_elem, rhs_elem, scalar_ty, mod)).toIntern();2900 scalar.* = (try floatDivScalar(lhs_elem, rhs_elem, scalar_ty, pt)).toIntern();
2856 }2901 }
2857 return Value.fromInterned((try mod.intern(.{ .aggregate = .{2902 return Value.fromInterned(try pt.intern(.{ .aggregate = .{
2858 .ty = float_type.toIntern(),2903 .ty = float_type.toIntern(),
2859 .storage = .{ .elems = result_data },2904 .storage = .{ .elems = result_data },
2860 } })));2905 } }));
2861 }2906 }
2862 return floatDivScalar(lhs, rhs, float_type, mod);2907 return floatDivScalar(lhs, rhs, float_type, pt);
2863}2908}
28642909
2865pub fn floatDivScalar(2910pub fn floatDivScalar(
2866 lhs: Value,2911 lhs: Value,
2867 rhs: Value,2912 rhs: Value,
2868 float_type: Type,2913 float_type: Type,
2869 mod: *Module,2914 pt: Zcu.PerThread,
2870) !Value {2915) !Value {
2871 const target = mod.getTarget();2916 const target = pt.zcu.getTarget();
2872 const storage: InternPool.Key.Float.Storage = switch (float_type.floatBits(target)) {2917 const storage: InternPool.Key.Float.Storage = switch (float_type.floatBits(target)) {
2873 16 => .{ .f16 = lhs.toFloat(f16, mod) / rhs.toFloat(f16, mod) },2918 16 => .{ .f16 = lhs.toFloat(f16, pt) / rhs.toFloat(f16, pt) },
2874 32 => .{ .f32 = lhs.toFloat(f32, mod) / rhs.toFloat(f32, mod) },2919 32 => .{ .f32 = lhs.toFloat(f32, pt) / rhs.toFloat(f32, pt) },
2875 64 => .{ .f64 = lhs.toFloat(f64, mod) / rhs.toFloat(f64, mod) },2920 64 => .{ .f64 = lhs.toFloat(f64, pt) / rhs.toFloat(f64, pt) },
2876 80 => .{ .f80 = lhs.toFloat(f80, mod) / rhs.toFloat(f80, mod) },2921 80 => .{ .f80 = lhs.toFloat(f80, pt) / rhs.toFloat(f80, pt) },
2877 128 => .{ .f128 = lhs.toFloat(f128, mod) / rhs.toFloat(f128, mod) },2922 128 => .{ .f128 = lhs.toFloat(f128, pt) / rhs.toFloat(f128, pt) },
2878 else => unreachable,2923 else => unreachable,
2879 };2924 };
2880 return Value.fromInterned((try mod.intern(.{ .float = .{2925 return Value.fromInterned(try pt.intern(.{ .float = .{
2881 .ty = float_type.toIntern(),2926 .ty = float_type.toIntern(),
2882 .storage = storage,2927 .storage = storage,
2883 } })));2928 } }));
2884}2929}
28852930
2886pub fn floatDivFloor(2931pub fn floatDivFloor(
...@@ -2888,43 +2933,43 @@ pub fn floatDivFloor(...@@ -2888,43 +2933,43 @@ pub fn floatDivFloor(
2888 rhs: Value,2933 rhs: Value,
2889 float_type: Type,2934 float_type: Type,
2890 arena: Allocator,2935 arena: Allocator,
2891 mod: *Module,2936 pt: Zcu.PerThread,
2892) !Value {2937) !Value {
2893 if (float_type.zigTypeTag(mod) == .Vector) {2938 if (float_type.zigTypeTag(pt.zcu) == .Vector) {
2894 const result_data = try arena.alloc(InternPool.Index, float_type.vectorLen(mod));2939 const result_data = try arena.alloc(InternPool.Index, float_type.vectorLen(pt.zcu));
2895 const scalar_ty = float_type.scalarType(mod);2940 const scalar_ty = float_type.scalarType(pt.zcu);
2896 for (result_data, 0..) |*scalar, i| {2941 for (result_data, 0..) |*scalar, i| {
2897 const lhs_elem = try lhs.elemValue(mod, i);2942 const lhs_elem = try lhs.elemValue(pt, i);
2898 const rhs_elem = try rhs.elemValue(mod, i);2943 const rhs_elem = try rhs.elemValue(pt, i);
2899 scalar.* = (try floatDivFloorScalar(lhs_elem, rhs_elem, scalar_ty, mod)).toIntern();2944 scalar.* = (try floatDivFloorScalar(lhs_elem, rhs_elem, scalar_ty, pt)).toIntern();
2900 }2945 }
2901 return Value.fromInterned((try mod.intern(.{ .aggregate = .{2946 return Value.fromInterned(try pt.intern(.{ .aggregate = .{
2902 .ty = float_type.toIntern(),2947 .ty = float_type.toIntern(),
2903 .storage = .{ .elems = result_data },2948 .storage = .{ .elems = result_data },
2904 } })));2949 } }));
2905 }2950 }
2906 return floatDivFloorScalar(lhs, rhs, float_type, mod);2951 return floatDivFloorScalar(lhs, rhs, float_type, pt);
2907}2952}
29082953
2909pub fn floatDivFloorScalar(2954pub fn floatDivFloorScalar(
2910 lhs: Value,2955 lhs: Value,
2911 rhs: Value,2956 rhs: Value,
2912 float_type: Type,2957 float_type: Type,
2913 mod: *Module,2958 pt: Zcu.PerThread,
2914) !Value {2959) !Value {
2915 const target = mod.getTarget();2960 const target = pt.zcu.getTarget();
2916 const storage: InternPool.Key.Float.Storage = switch (float_type.floatBits(target)) {2961 const storage: InternPool.Key.Float.Storage = switch (float_type.floatBits(target)) {
2917 16 => .{ .f16 = @divFloor(lhs.toFloat(f16, mod), rhs.toFloat(f16, mod)) },2962 16 => .{ .f16 = @divFloor(lhs.toFloat(f16, pt), rhs.toFloat(f16, pt)) },
2918 32 => .{ .f32 = @divFloor(lhs.toFloat(f32, mod), rhs.toFloat(f32, mod)) },2963 32 => .{ .f32 = @divFloor(lhs.toFloat(f32, pt), rhs.toFloat(f32, pt)) },
2919 64 => .{ .f64 = @divFloor(lhs.toFloat(f64, mod), rhs.toFloat(f64, mod)) },2964 64 => .{ .f64 = @divFloor(lhs.toFloat(f64, pt), rhs.toFloat(f64, pt)) },
2920 80 => .{ .f80 = @divFloor(lhs.toFloat(f80, mod), rhs.toFloat(f80, mod)) },2965 80 => .{ .f80 = @divFloor(lhs.toFloat(f80, pt), rhs.toFloat(f80, pt)) },
2921 128 => .{ .f128 = @divFloor(lhs.toFloat(f128, mod), rhs.toFloat(f128, mod)) },2966 128 => .{ .f128 = @divFloor(lhs.toFloat(f128, pt), rhs.toFloat(f128, pt)) },
2922 else => unreachable,2967 else => unreachable,
2923 };2968 };
2924 return Value.fromInterned((try mod.intern(.{ .float = .{2969 return Value.fromInterned(try pt.intern(.{ .float = .{
2925 .ty = float_type.toIntern(),2970 .ty = float_type.toIntern(),
2926 .storage = storage,2971 .storage = storage,
2927 } })));2972 } }));
2928}2973}
29292974
2930pub fn floatDivTrunc(2975pub fn floatDivTrunc(
...@@ -2932,43 +2977,43 @@ pub fn floatDivTrunc(...@@ -2932,43 +2977,43 @@ pub fn floatDivTrunc(
2932 rhs: Value,2977 rhs: Value,
2933 float_type: Type,2978 float_type: Type,
2934 arena: Allocator,2979 arena: Allocator,
2935 mod: *Module,2980 pt: Zcu.PerThread,
2936) !Value {2981) !Value {
2937 if (float_type.zigTypeTag(mod) == .Vector) {2982 if (float_type.zigTypeTag(pt.zcu) == .Vector) {
2938 const result_data = try arena.alloc(InternPool.Index, float_type.vectorLen(mod));2983 const result_data = try arena.alloc(InternPool.Index, float_type.vectorLen(pt.zcu));
2939 const scalar_ty = float_type.scalarType(mod);2984 const scalar_ty = float_type.scalarType(pt.zcu);
2940 for (result_data, 0..) |*scalar, i| {2985 for (result_data, 0..) |*scalar, i| {
2941 const lhs_elem = try lhs.elemValue(mod, i);2986 const lhs_elem = try lhs.elemValue(pt, i);
2942 const rhs_elem = try rhs.elemValue(mod, i);2987 const rhs_elem = try rhs.elemValue(pt, i);
2943 scalar.* = (try floatDivTruncScalar(lhs_elem, rhs_elem, scalar_ty, mod)).toIntern();2988 scalar.* = (try floatDivTruncScalar(lhs_elem, rhs_elem, scalar_ty, pt)).toIntern();
2944 }2989 }
2945 return Value.fromInterned((try mod.intern(.{ .aggregate = .{2990 return Value.fromInterned(try pt.intern(.{ .aggregate = .{
2946 .ty = float_type.toIntern(),2991 .ty = float_type.toIntern(),
2947 .storage = .{ .elems = result_data },2992 .storage = .{ .elems = result_data },
2948 } })));2993 } }));
2949 }2994 }
2950 return floatDivTruncScalar(lhs, rhs, float_type, mod);2995 return floatDivTruncScalar(lhs, rhs, float_type, pt);
2951}2996}
29522997
2953pub fn floatDivTruncScalar(2998pub fn floatDivTruncScalar(
2954 lhs: Value,2999 lhs: Value,
2955 rhs: Value,3000 rhs: Value,
2956 float_type: Type,3001 float_type: Type,
2957 mod: *Module,3002 pt: Zcu.PerThread,
2958) !Value {3003) !Value {
2959 const target = mod.getTarget();3004 const target = pt.zcu.getTarget();
2960 const storage: InternPool.Key.Float.Storage = switch (float_type.floatBits(target)) {3005 const storage: InternPool.Key.Float.Storage = switch (float_type.floatBits(target)) {
2961 16 => .{ .f16 = @divTrunc(lhs.toFloat(f16, mod), rhs.toFloat(f16, mod)) },3006 16 => .{ .f16 = @divTrunc(lhs.toFloat(f16, pt), rhs.toFloat(f16, pt)) },
2962 32 => .{ .f32 = @divTrunc(lhs.toFloat(f32, mod), rhs.toFloat(f32, mod)) },3007 32 => .{ .f32 = @divTrunc(lhs.toFloat(f32, pt), rhs.toFloat(f32, pt)) },
2963 64 => .{ .f64 = @divTrunc(lhs.toFloat(f64, mod), rhs.toFloat(f64, mod)) },3008 64 => .{ .f64 = @divTrunc(lhs.toFloat(f64, pt), rhs.toFloat(f64, pt)) },
2964 80 => .{ .f80 = @divTrunc(lhs.toFloat(f80, mod), rhs.toFloat(f80, mod)) },3009 80 => .{ .f80 = @divTrunc(lhs.toFloat(f80, pt), rhs.toFloat(f80, pt)) },
2965 128 => .{ .f128 = @divTrunc(lhs.toFloat(f128, mod), rhs.toFloat(f128, mod)) },3010 128 => .{ .f128 = @divTrunc(lhs.toFloat(f128, pt), rhs.toFloat(f128, pt)) },
2966 else => unreachable,3011 else => unreachable,
2967 };3012 };
2968 return Value.fromInterned((try mod.intern(.{ .float = .{3013 return Value.fromInterned(try pt.intern(.{ .float = .{
2969 .ty = float_type.toIntern(),3014 .ty = float_type.toIntern(),
2970 .storage = storage,3015 .storage = storage,
2971 } })));3016 } }));
2972}3017}
29733018
2974pub fn floatMul(3019pub fn floatMul(
...@@ -2976,510 +3021,539 @@ pub fn floatMul(...@@ -2976,510 +3021,539 @@ pub fn floatMul(
2976 rhs: Value,3021 rhs: Value,
2977 float_type: Type,3022 float_type: Type,
2978 arena: Allocator,3023 arena: Allocator,
2979 mod: *Module,3024 pt: Zcu.PerThread,
2980) !Value {3025) !Value {
3026 const mod = pt.zcu;
2981 if (float_type.zigTypeTag(mod) == .Vector) {3027 if (float_type.zigTypeTag(mod) == .Vector) {
2982 const result_data = try arena.alloc(InternPool.Index, float_type.vectorLen(mod));3028 const result_data = try arena.alloc(InternPool.Index, float_type.vectorLen(mod));
2983 const scalar_ty = float_type.scalarType(mod);3029 const scalar_ty = float_type.scalarType(mod);
2984 for (result_data, 0..) |*scalar, i| {3030 for (result_data, 0..) |*scalar, i| {
2985 const lhs_elem = try lhs.elemValue(mod, i);3031 const lhs_elem = try lhs.elemValue(pt, i);
2986 const rhs_elem = try rhs.elemValue(mod, i);3032 const rhs_elem = try rhs.elemValue(pt, i);
2987 scalar.* = (try floatMulScalar(lhs_elem, rhs_elem, scalar_ty, mod)).toIntern();3033 scalar.* = (try floatMulScalar(lhs_elem, rhs_elem, scalar_ty, pt)).toIntern();
2988 }3034 }
2989 return Value.fromInterned((try mod.intern(.{ .aggregate = .{3035 return Value.fromInterned(try pt.intern(.{ .aggregate = .{
2990 .ty = float_type.toIntern(),3036 .ty = float_type.toIntern(),
2991 .storage = .{ .elems = result_data },3037 .storage = .{ .elems = result_data },
2992 } })));3038 } }));
2993 }3039 }
2994 return floatMulScalar(lhs, rhs, float_type, mod);3040 return floatMulScalar(lhs, rhs, float_type, pt);
2995}3041}
29963042
2997pub fn floatMulScalar(3043pub fn floatMulScalar(
2998 lhs: Value,3044 lhs: Value,
2999 rhs: Value,3045 rhs: Value,
3000 float_type: Type,3046 float_type: Type,
3001 mod: *Module,3047 pt: Zcu.PerThread,
3002) !Value {3048) !Value {
3049 const mod = pt.zcu;
3003 const target = mod.getTarget();3050 const target = mod.getTarget();
3004 const storage: InternPool.Key.Float.Storage = switch (float_type.floatBits(target)) {3051 const storage: InternPool.Key.Float.Storage = switch (float_type.floatBits(target)) {
3005 16 => .{ .f16 = lhs.toFloat(f16, mod) * rhs.toFloat(f16, mod) },3052 16 => .{ .f16 = lhs.toFloat(f16, pt) * rhs.toFloat(f16, pt) },
3006 32 => .{ .f32 = lhs.toFloat(f32, mod) * rhs.toFloat(f32, mod) },3053 32 => .{ .f32 = lhs.toFloat(f32, pt) * rhs.toFloat(f32, pt) },
3007 64 => .{ .f64 = lhs.toFloat(f64, mod) * rhs.toFloat(f64, mod) },3054 64 => .{ .f64 = lhs.toFloat(f64, pt) * rhs.toFloat(f64, pt) },
3008 80 => .{ .f80 = lhs.toFloat(f80, mod) * rhs.toFloat(f80, mod) },3055 80 => .{ .f80 = lhs.toFloat(f80, pt) * rhs.toFloat(f80, pt) },
3009 128 => .{ .f128 = lhs.toFloat(f128, mod) * rhs.toFloat(f128, mod) },3056 128 => .{ .f128 = lhs.toFloat(f128, pt) * rhs.toFloat(f128, pt) },
3010 else => unreachable,3057 else => unreachable,
3011 };3058 };
3012 return Value.fromInterned((try mod.intern(.{ .float = .{3059 return Value.fromInterned(try pt.intern(.{ .float = .{
3013 .ty = float_type.toIntern(),3060 .ty = float_type.toIntern(),
3014 .storage = storage,3061 .storage = storage,
3015 } })));3062 } }));
3016}3063}
30173064
3018pub fn sqrt(val: Value, float_type: Type, arena: Allocator, mod: *Module) !Value {3065pub fn sqrt(val: Value, float_type: Type, arena: Allocator, pt: Zcu.PerThread) !Value {
3019 if (float_type.zigTypeTag(mod) == .Vector) {3066 if (float_type.zigTypeTag(pt.zcu) == .Vector) {
3020 const result_data = try arena.alloc(InternPool.Index, float_type.vectorLen(mod));3067 const result_data = try arena.alloc(InternPool.Index, float_type.vectorLen(pt.zcu));
3021 const scalar_ty = float_type.scalarType(mod);3068 const scalar_ty = float_type.scalarType(pt.zcu);
3022 for (result_data, 0..) |*scalar, i| {3069 for (result_data, 0..) |*scalar, i| {
3023 const elem_val = try val.elemValue(mod, i);3070 const elem_val = try val.elemValue(pt, i);
3024 scalar.* = (try sqrtScalar(elem_val, scalar_ty, mod)).toIntern();3071 scalar.* = (try sqrtScalar(elem_val, scalar_ty, pt)).toIntern();
3025 }3072 }
3026 return Value.fromInterned((try mod.intern(.{ .aggregate = .{3073 return Value.fromInterned(try pt.intern(.{ .aggregate = .{
3027 .ty = float_type.toIntern(),3074 .ty = float_type.toIntern(),
3028 .storage = .{ .elems = result_data },3075 .storage = .{ .elems = result_data },
3029 } })));3076 } }));
3030 }3077 }
3031 return sqrtScalar(val, float_type, mod);3078 return sqrtScalar(val, float_type, pt);
3032}3079}
30333080
3034pub fn sqrtScalar(val: Value, float_type: Type, mod: *Module) Allocator.Error!Value {3081pub fn sqrtScalar(val: Value, float_type: Type, pt: Zcu.PerThread) Allocator.Error!Value {
3082 const mod = pt.zcu;
3035 const target = mod.getTarget();3083 const target = mod.getTarget();
3036 const storage: InternPool.Key.Float.Storage = switch (float_type.floatBits(target)) {3084 const storage: InternPool.Key.Float.Storage = switch (float_type.floatBits(target)) {
3037 16 => .{ .f16 = @sqrt(val.toFloat(f16, mod)) },3085 16 => .{ .f16 = @sqrt(val.toFloat(f16, pt)) },
3038 32 => .{ .f32 = @sqrt(val.toFloat(f32, mod)) },3086 32 => .{ .f32 = @sqrt(val.toFloat(f32, pt)) },
3039 64 => .{ .f64 = @sqrt(val.toFloat(f64, mod)) },3087 64 => .{ .f64 = @sqrt(val.toFloat(f64, pt)) },
3040 80 => .{ .f80 = @sqrt(val.toFloat(f80, mod)) },3088 80 => .{ .f80 = @sqrt(val.toFloat(f80, pt)) },
3041 128 => .{ .f128 = @sqrt(val.toFloat(f128, mod)) },3089 128 => .{ .f128 = @sqrt(val.toFloat(f128, pt)) },
3042 else => unreachable,3090 else => unreachable,
3043 };3091 };
3044 return Value.fromInterned((try mod.intern(.{ .float = .{3092 return Value.fromInterned(try pt.intern(.{ .float = .{
3045 .ty = float_type.toIntern(),3093 .ty = float_type.toIntern(),
3046 .storage = storage,3094 .storage = storage,
3047 } })));3095 } }));
3048}3096}
30493097
3050pub fn sin(val: Value, float_type: Type, arena: Allocator, mod: *Module) !Value {3098pub fn sin(val: Value, float_type: Type, arena: Allocator, pt: Zcu.PerThread) !Value {
3099 const mod = pt.zcu;
3051 if (float_type.zigTypeTag(mod) == .Vector) {3100 if (float_type.zigTypeTag(mod) == .Vector) {
3052 const result_data = try arena.alloc(InternPool.Index, float_type.vectorLen(mod));3101 const result_data = try arena.alloc(InternPool.Index, float_type.vectorLen(mod));
3053 const scalar_ty = float_type.scalarType(mod);3102 const scalar_ty = float_type.scalarType(mod);
3054 for (result_data, 0..) |*scalar, i| {3103 for (result_data, 0..) |*scalar, i| {
3055 const elem_val = try val.elemValue(mod, i);3104 const elem_val = try val.elemValue(pt, i);
3056 scalar.* = (try sinScalar(elem_val, scalar_ty, mod)).toIntern();3105 scalar.* = (try sinScalar(elem_val, scalar_ty, pt)).toIntern();
3057 }3106 }
3058 return Value.fromInterned((try mod.intern(.{ .aggregate = .{3107 return Value.fromInterned(try pt.intern(.{ .aggregate = .{
3059 .ty = float_type.toIntern(),3108 .ty = float_type.toIntern(),
3060 .storage = .{ .elems = result_data },3109 .storage = .{ .elems = result_data },
3061 } })));3110 } }));
3062 }3111 }
3063 return sinScalar(val, float_type, mod);3112 return sinScalar(val, float_type, pt);
3064}3113}
30653114
3066pub fn sinScalar(val: Value, float_type: Type, mod: *Module) Allocator.Error!Value {3115pub fn sinScalar(val: Value, float_type: Type, pt: Zcu.PerThread) Allocator.Error!Value {
3116 const mod = pt.zcu;
3067 const target = mod.getTarget();3117 const target = mod.getTarget();
3068 const storage: InternPool.Key.Float.Storage = switch (float_type.floatBits(target)) {3118 const storage: InternPool.Key.Float.Storage = switch (float_type.floatBits(target)) {
3069 16 => .{ .f16 = @sin(val.toFloat(f16, mod)) },3119 16 => .{ .f16 = @sin(val.toFloat(f16, pt)) },
3070 32 => .{ .f32 = @sin(val.toFloat(f32, mod)) },3120 32 => .{ .f32 = @sin(val.toFloat(f32, pt)) },
3071 64 => .{ .f64 = @sin(val.toFloat(f64, mod)) },3121 64 => .{ .f64 = @sin(val.toFloat(f64, pt)) },
3072 80 => .{ .f80 = @sin(val.toFloat(f80, mod)) },3122 80 => .{ .f80 = @sin(val.toFloat(f80, pt)) },
3073 128 => .{ .f128 = @sin(val.toFloat(f128, mod)) },3123 128 => .{ .f128 = @sin(val.toFloat(f128, pt)) },
3074 else => unreachable,3124 else => unreachable,
3075 };3125 };
3076 return Value.fromInterned((try mod.intern(.{ .float = .{3126 return Value.fromInterned(try pt.intern(.{ .float = .{
3077 .ty = float_type.toIntern(),3127 .ty = float_type.toIntern(),
3078 .storage = storage,3128 .storage = storage,
3079 } })));3129 } }));
3080}3130}
30813131
3082pub fn cos(val: Value, float_type: Type, arena: Allocator, mod: *Module) !Value {3132pub fn cos(val: Value, float_type: Type, arena: Allocator, pt: Zcu.PerThread) !Value {
3133 const mod = pt.zcu;
3083 if (float_type.zigTypeTag(mod) == .Vector) {3134 if (float_type.zigTypeTag(mod) == .Vector) {
3084 const result_data = try arena.alloc(InternPool.Index, float_type.vectorLen(mod));3135 const result_data = try arena.alloc(InternPool.Index, float_type.vectorLen(mod));
3085 const scalar_ty = float_type.scalarType(mod);3136 const scalar_ty = float_type.scalarType(mod);
3086 for (result_data, 0..) |*scalar, i| {3137 for (result_data, 0..) |*scalar, i| {
3087 const elem_val = try val.elemValue(mod, i);3138 const elem_val = try val.elemValue(pt, i);
3088 scalar.* = (try cosScalar(elem_val, scalar_ty, mod)).toIntern();3139 scalar.* = (try cosScalar(elem_val, scalar_ty, pt)).toIntern();
3089 }3140 }
3090 return Value.fromInterned((try mod.intern(.{ .aggregate = .{3141 return Value.fromInterned(try pt.intern(.{ .aggregate = .{
3091 .ty = float_type.toIntern(),3142 .ty = float_type.toIntern(),
3092 .storage = .{ .elems = result_data },3143 .storage = .{ .elems = result_data },
3093 } })));3144 } }));
3094 }3145 }
3095 return cosScalar(val, float_type, mod);3146 return cosScalar(val, float_type, pt);
3096}3147}
30973148
3098pub fn cosScalar(val: Value, float_type: Type, mod: *Module) Allocator.Error!Value {3149pub fn cosScalar(val: Value, float_type: Type, pt: Zcu.PerThread) Allocator.Error!Value {
3150 const mod = pt.zcu;
3099 const target = mod.getTarget();3151 const target = mod.getTarget();
3100 const storage: InternPool.Key.Float.Storage = switch (float_type.floatBits(target)) {3152 const storage: InternPool.Key.Float.Storage = switch (float_type.floatBits(target)) {
3101 16 => .{ .f16 = @cos(val.toFloat(f16, mod)) },3153 16 => .{ .f16 = @cos(val.toFloat(f16, pt)) },
3102 32 => .{ .f32 = @cos(val.toFloat(f32, mod)) },3154 32 => .{ .f32 = @cos(val.toFloat(f32, pt)) },
3103 64 => .{ .f64 = @cos(val.toFloat(f64, mod)) },3155 64 => .{ .f64 = @cos(val.toFloat(f64, pt)) },
3104 80 => .{ .f80 = @cos(val.toFloat(f80, mod)) },3156 80 => .{ .f80 = @cos(val.toFloat(f80, pt)) },
3105 128 => .{ .f128 = @cos(val.toFloat(f128, mod)) },3157 128 => .{ .f128 = @cos(val.toFloat(f128, pt)) },
3106 else => unreachable,3158 else => unreachable,
3107 };3159 };
3108 return Value.fromInterned((try mod.intern(.{ .float = .{3160 return Value.fromInterned(try pt.intern(.{ .float = .{
3109 .ty = float_type.toIntern(),3161 .ty = float_type.toIntern(),
3110 .storage = storage,3162 .storage = storage,
3111 } })));3163 } }));
3112}3164}
31133165
3114pub fn tan(val: Value, float_type: Type, arena: Allocator, mod: *Module) !Value {3166pub fn tan(val: Value, float_type: Type, arena: Allocator, pt: Zcu.PerThread) !Value {
3167 const mod = pt.zcu;
3115 if (float_type.zigTypeTag(mod) == .Vector) {3168 if (float_type.zigTypeTag(mod) == .Vector) {
3116 const result_data = try arena.alloc(InternPool.Index, float_type.vectorLen(mod));3169 const result_data = try arena.alloc(InternPool.Index, float_type.vectorLen(mod));
3117 const scalar_ty = float_type.scalarType(mod);3170 const scalar_ty = float_type.scalarType(mod);
3118 for (result_data, 0..) |*scalar, i| {3171 for (result_data, 0..) |*scalar, i| {
3119 const elem_val = try val.elemValue(mod, i);3172 const elem_val = try val.elemValue(pt, i);
3120 scalar.* = (try tanScalar(elem_val, scalar_ty, mod)).toIntern();3173 scalar.* = (try tanScalar(elem_val, scalar_ty, pt)).toIntern();
3121 }3174 }
3122 return Value.fromInterned((try mod.intern(.{ .aggregate = .{3175 return Value.fromInterned(try pt.intern(.{ .aggregate = .{
3123 .ty = float_type.toIntern(),3176 .ty = float_type.toIntern(),
3124 .storage = .{ .elems = result_data },3177 .storage = .{ .elems = result_data },
3125 } })));3178 } }));
3126 }3179 }
3127 return tanScalar(val, float_type, mod);3180 return tanScalar(val, float_type, pt);
3128}3181}
31293182
3130pub fn tanScalar(val: Value, float_type: Type, mod: *Module) Allocator.Error!Value {3183pub fn tanScalar(val: Value, float_type: Type, pt: Zcu.PerThread) Allocator.Error!Value {
3184 const mod = pt.zcu;
3131 const target = mod.getTarget();3185 const target = mod.getTarget();
3132 const storage: InternPool.Key.Float.Storage = switch (float_type.floatBits(target)) {3186 const storage: InternPool.Key.Float.Storage = switch (float_type.floatBits(target)) {
3133 16 => .{ .f16 = @tan(val.toFloat(f16, mod)) },3187 16 => .{ .f16 = @tan(val.toFloat(f16, pt)) },
3134 32 => .{ .f32 = @tan(val.toFloat(f32, mod)) },3188 32 => .{ .f32 = @tan(val.toFloat(f32, pt)) },
3135 64 => .{ .f64 = @tan(val.toFloat(f64, mod)) },3189 64 => .{ .f64 = @tan(val.toFloat(f64, pt)) },
3136 80 => .{ .f80 = @tan(val.toFloat(f80, mod)) },3190 80 => .{ .f80 = @tan(val.toFloat(f80, pt)) },
3137 128 => .{ .f128 = @tan(val.toFloat(f128, mod)) },3191 128 => .{ .f128 = @tan(val.toFloat(f128, pt)) },
3138 else => unreachable,3192 else => unreachable,
3139 };3193 };
3140 return Value.fromInterned((try mod.intern(.{ .float = .{3194 return Value.fromInterned(try pt.intern(.{ .float = .{
3141 .ty = float_type.toIntern(),3195 .ty = float_type.toIntern(),
3142 .storage = storage,3196 .storage = storage,
3143 } })));3197 } }));
3144}3198}
31453199
3146pub fn exp(val: Value, float_type: Type, arena: Allocator, mod: *Module) !Value {3200pub fn exp(val: Value, float_type: Type, arena: Allocator, pt: Zcu.PerThread) !Value {
3201 const mod = pt.zcu;
3147 if (float_type.zigTypeTag(mod) == .Vector) {3202 if (float_type.zigTypeTag(mod) == .Vector) {
3148 const result_data = try arena.alloc(InternPool.Index, float_type.vectorLen(mod));3203 const result_data = try arena.alloc(InternPool.Index, float_type.vectorLen(mod));
3149 const scalar_ty = float_type.scalarType(mod);3204 const scalar_ty = float_type.scalarType(mod);
3150 for (result_data, 0..) |*scalar, i| {3205 for (result_data, 0..) |*scalar, i| {
3151 const elem_val = try val.elemValue(mod, i);3206 const elem_val = try val.elemValue(pt, i);
3152 scalar.* = (try expScalar(elem_val, scalar_ty, mod)).toIntern();3207 scalar.* = (try expScalar(elem_val, scalar_ty, pt)).toIntern();
3153 }3208 }
3154 return Value.fromInterned((try mod.intern(.{ .aggregate = .{3209 return Value.fromInterned(try pt.intern(.{ .aggregate = .{
3155 .ty = float_type.toIntern(),3210 .ty = float_type.toIntern(),
3156 .storage = .{ .elems = result_data },3211 .storage = .{ .elems = result_data },
3157 } })));3212 } }));
3158 }3213 }
3159 return expScalar(val, float_type, mod);3214 return expScalar(val, float_type, pt);
3160}3215}
31613216
3162pub fn expScalar(val: Value, float_type: Type, mod: *Module) Allocator.Error!Value {3217pub fn expScalar(val: Value, float_type: Type, pt: Zcu.PerThread) Allocator.Error!Value {
3218 const mod = pt.zcu;
3163 const target = mod.getTarget();3219 const target = mod.getTarget();
3164 const storage: InternPool.Key.Float.Storage = switch (float_type.floatBits(target)) {3220 const storage: InternPool.Key.Float.Storage = switch (float_type.floatBits(target)) {
3165 16 => .{ .f16 = @exp(val.toFloat(f16, mod)) },3221 16 => .{ .f16 = @exp(val.toFloat(f16, pt)) },
3166 32 => .{ .f32 = @exp(val.toFloat(f32, mod)) },3222 32 => .{ .f32 = @exp(val.toFloat(f32, pt)) },
3167 64 => .{ .f64 = @exp(val.toFloat(f64, mod)) },3223 64 => .{ .f64 = @exp(val.toFloat(f64, pt)) },
3168 80 => .{ .f80 = @exp(val.toFloat(f80, mod)) },3224 80 => .{ .f80 = @exp(val.toFloat(f80, pt)) },
3169 128 => .{ .f128 = @exp(val.toFloat(f128, mod)) },3225 128 => .{ .f128 = @exp(val.toFloat(f128, pt)) },
3170 else => unreachable,3226 else => unreachable,
3171 };3227 };
3172 return Value.fromInterned((try mod.intern(.{ .float = .{3228 return Value.fromInterned(try pt.intern(.{ .float = .{
3173 .ty = float_type.toIntern(),3229 .ty = float_type.toIntern(),
3174 .storage = storage,3230 .storage = storage,
3175 } })));3231 } }));
3176}3232}
31773233
3178pub fn exp2(val: Value, float_type: Type, arena: Allocator, mod: *Module) !Value {3234pub fn exp2(val: Value, float_type: Type, arena: Allocator, pt: Zcu.PerThread) !Value {
3235 const mod = pt.zcu;
3179 if (float_type.zigTypeTag(mod) == .Vector) {3236 if (float_type.zigTypeTag(mod) == .Vector) {
3180 const result_data = try arena.alloc(InternPool.Index, float_type.vectorLen(mod));3237 const result_data = try arena.alloc(InternPool.Index, float_type.vectorLen(mod));
3181 const scalar_ty = float_type.scalarType(mod);3238 const scalar_ty = float_type.scalarType(mod);
3182 for (result_data, 0..) |*scalar, i| {3239 for (result_data, 0..) |*scalar, i| {
3183 const elem_val = try val.elemValue(mod, i);3240 const elem_val = try val.elemValue(pt, i);
3184 scalar.* = (try exp2Scalar(elem_val, scalar_ty, mod)).toIntern();3241 scalar.* = (try exp2Scalar(elem_val, scalar_ty, pt)).toIntern();
3185 }3242 }
3186 return Value.fromInterned((try mod.intern(.{ .aggregate = .{3243 return Value.fromInterned(try pt.intern(.{ .aggregate = .{
3187 .ty = float_type.toIntern(),3244 .ty = float_type.toIntern(),
3188 .storage = .{ .elems = result_data },3245 .storage = .{ .elems = result_data },
3189 } })));3246 } }));
3190 }3247 }
3191 return exp2Scalar(val, float_type, mod);3248 return exp2Scalar(val, float_type, pt);
3192}3249}
31933250
3194pub fn exp2Scalar(val: Value, float_type: Type, mod: *Module) Allocator.Error!Value {3251pub fn exp2Scalar(val: Value, float_type: Type, pt: Zcu.PerThread) Allocator.Error!Value {
3252 const mod = pt.zcu;
3195 const target = mod.getTarget();3253 const target = mod.getTarget();
3196 const storage: InternPool.Key.Float.Storage = switch (float_type.floatBits(target)) {3254 const storage: InternPool.Key.Float.Storage = switch (float_type.floatBits(target)) {
3197 16 => .{ .f16 = @exp2(val.toFloat(f16, mod)) },3255 16 => .{ .f16 = @exp2(val.toFloat(f16, pt)) },
3198 32 => .{ .f32 = @exp2(val.toFloat(f32, mod)) },3256 32 => .{ .f32 = @exp2(val.toFloat(f32, pt)) },
3199 64 => .{ .f64 = @exp2(val.toFloat(f64, mod)) },3257 64 => .{ .f64 = @exp2(val.toFloat(f64, pt)) },
3200 80 => .{ .f80 = @exp2(val.toFloat(f80, mod)) },3258 80 => .{ .f80 = @exp2(val.toFloat(f80, pt)) },
3201 128 => .{ .f128 = @exp2(val.toFloat(f128, mod)) },3259 128 => .{ .f128 = @exp2(val.toFloat(f128, pt)) },
3202 else => unreachable,3260 else => unreachable,
3203 };3261 };
3204 return Value.fromInterned((try mod.intern(.{ .float = .{3262 return Value.fromInterned(try pt.intern(.{ .float = .{
3205 .ty = float_type.toIntern(),3263 .ty = float_type.toIntern(),
3206 .storage = storage,3264 .storage = storage,
3207 } })));3265 } }));
3208}3266}
32093267
3210pub fn log(val: Value, float_type: Type, arena: Allocator, mod: *Module) !Value {3268pub fn log(val: Value, float_type: Type, arena: Allocator, pt: Zcu.PerThread) !Value {
3269 const mod = pt.zcu;
3211 if (float_type.zigTypeTag(mod) == .Vector) {3270 if (float_type.zigTypeTag(mod) == .Vector) {
3212 const result_data = try arena.alloc(InternPool.Index, float_type.vectorLen(mod));3271 const result_data = try arena.alloc(InternPool.Index, float_type.vectorLen(mod));
3213 const scalar_ty = float_type.scalarType(mod);3272 const scalar_ty = float_type.scalarType(mod);
3214 for (result_data, 0..) |*scalar, i| {3273 for (result_data, 0..) |*scalar, i| {
3215 const elem_val = try val.elemValue(mod, i);3274 const elem_val = try val.elemValue(pt, i);
3216 scalar.* = (try logScalar(elem_val, scalar_ty, mod)).toIntern();3275 scalar.* = (try logScalar(elem_val, scalar_ty, pt)).toIntern();
3217 }3276 }
3218 return Value.fromInterned((try mod.intern(.{ .aggregate = .{3277 return Value.fromInterned(try pt.intern(.{ .aggregate = .{
3219 .ty = float_type.toIntern(),3278 .ty = float_type.toIntern(),
3220 .storage = .{ .elems = result_data },3279 .storage = .{ .elems = result_data },
3221 } })));3280 } }));
3222 }3281 }
3223 return logScalar(val, float_type, mod);3282 return logScalar(val, float_type, pt);
3224}3283}
32253284
3226pub fn logScalar(val: Value, float_type: Type, mod: *Module) Allocator.Error!Value {3285pub fn logScalar(val: Value, float_type: Type, pt: Zcu.PerThread) Allocator.Error!Value {
3286 const mod = pt.zcu;
3227 const target = mod.getTarget();3287 const target = mod.getTarget();
3228 const storage: InternPool.Key.Float.Storage = switch (float_type.floatBits(target)) {3288 const storage: InternPool.Key.Float.Storage = switch (float_type.floatBits(target)) {
3229 16 => .{ .f16 = @log(val.toFloat(f16, mod)) },3289 16 => .{ .f16 = @log(val.toFloat(f16, pt)) },
3230 32 => .{ .f32 = @log(val.toFloat(f32, mod)) },3290 32 => .{ .f32 = @log(val.toFloat(f32, pt)) },
3231 64 => .{ .f64 = @log(val.toFloat(f64, mod)) },3291 64 => .{ .f64 = @log(val.toFloat(f64, pt)) },
3232 80 => .{ .f80 = @log(val.toFloat(f80, mod)) },3292 80 => .{ .f80 = @log(val.toFloat(f80, pt)) },
3233 128 => .{ .f128 = @log(val.toFloat(f128, mod)) },3293 128 => .{ .f128 = @log(val.toFloat(f128, pt)) },
3234 else => unreachable,3294 else => unreachable,
3235 };3295 };
3236 return Value.fromInterned((try mod.intern(.{ .float = .{3296 return Value.fromInterned(try pt.intern(.{ .float = .{
3237 .ty = float_type.toIntern(),3297 .ty = float_type.toIntern(),
3238 .storage = storage,3298 .storage = storage,
3239 } })));3299 } }));
3240}3300}
32413301
3242pub fn log2(val: Value, float_type: Type, arena: Allocator, mod: *Module) !Value {3302pub fn log2(val: Value, float_type: Type, arena: Allocator, pt: Zcu.PerThread) !Value {
3303 const mod = pt.zcu;
3243 if (float_type.zigTypeTag(mod) == .Vector) {3304 if (float_type.zigTypeTag(mod) == .Vector) {
3244 const result_data = try arena.alloc(InternPool.Index, float_type.vectorLen(mod));3305 const result_data = try arena.alloc(InternPool.Index, float_type.vectorLen(mod));
3245 const scalar_ty = float_type.scalarType(mod);3306 const scalar_ty = float_type.scalarType(mod);
3246 for (result_data, 0..) |*scalar, i| {3307 for (result_data, 0..) |*scalar, i| {
3247 const elem_val = try val.elemValue(mod, i);3308 const elem_val = try val.elemValue(pt, i);
3248 scalar.* = (try log2Scalar(elem_val, scalar_ty, mod)).toIntern();3309 scalar.* = (try log2Scalar(elem_val, scalar_ty, pt)).toIntern();
3249 }3310 }
3250 return Value.fromInterned((try mod.intern(.{ .aggregate = .{3311 return Value.fromInterned(try pt.intern(.{ .aggregate = .{
3251 .ty = float_type.toIntern(),3312 .ty = float_type.toIntern(),
3252 .storage = .{ .elems = result_data },3313 .storage = .{ .elems = result_data },
3253 } })));3314 } }));
3254 }3315 }
3255 return log2Scalar(val, float_type, mod);3316 return log2Scalar(val, float_type, pt);
3256}3317}
32573318
3258pub fn log2Scalar(val: Value, float_type: Type, mod: *Module) Allocator.Error!Value {3319pub fn log2Scalar(val: Value, float_type: Type, pt: Zcu.PerThread) Allocator.Error!Value {
3320 const mod = pt.zcu;
3259 const target = mod.getTarget();3321 const target = mod.getTarget();
3260 const storage: InternPool.Key.Float.Storage = switch (float_type.floatBits(target)) {3322 const storage: InternPool.Key.Float.Storage = switch (float_type.floatBits(target)) {
3261 16 => .{ .f16 = @log2(val.toFloat(f16, mod)) },3323 16 => .{ .f16 = @log2(val.toFloat(f16, pt)) },
3262 32 => .{ .f32 = @log2(val.toFloat(f32, mod)) },3324 32 => .{ .f32 = @log2(val.toFloat(f32, pt)) },
3263 64 => .{ .f64 = @log2(val.toFloat(f64, mod)) },3325 64 => .{ .f64 = @log2(val.toFloat(f64, pt)) },
3264 80 => .{ .f80 = @log2(val.toFloat(f80, mod)) },3326 80 => .{ .f80 = @log2(val.toFloat(f80, pt)) },
3265 128 => .{ .f128 = @log2(val.toFloat(f128, mod)) },3327 128 => .{ .f128 = @log2(val.toFloat(f128, pt)) },
3266 else => unreachable,3328 else => unreachable,
3267 };3329 };
3268 return Value.fromInterned((try mod.intern(.{ .float = .{3330 return Value.fromInterned(try pt.intern(.{ .float = .{
3269 .ty = float_type.toIntern(),3331 .ty = float_type.toIntern(),
3270 .storage = storage,3332 .storage = storage,
3271 } })));3333 } }));
3272}3334}
32733335
3274pub fn log10(val: Value, float_type: Type, arena: Allocator, mod: *Module) !Value {3336pub fn log10(val: Value, float_type: Type, arena: Allocator, pt: Zcu.PerThread) !Value {
3337 const mod = pt.zcu;
3275 if (float_type.zigTypeTag(mod) == .Vector) {3338 if (float_type.zigTypeTag(mod) == .Vector) {
3276 const result_data = try arena.alloc(InternPool.Index, float_type.vectorLen(mod));3339 const result_data = try arena.alloc(InternPool.Index, float_type.vectorLen(mod));
3277 const scalar_ty = float_type.scalarType(mod);3340 const scalar_ty = float_type.scalarType(mod);
3278 for (result_data, 0..) |*scalar, i| {3341 for (result_data, 0..) |*scalar, i| {
3279 const elem_val = try val.elemValue(mod, i);3342 const elem_val = try val.elemValue(pt, i);
3280 scalar.* = (try log10Scalar(elem_val, scalar_ty, mod)).toIntern();3343 scalar.* = (try log10Scalar(elem_val, scalar_ty, pt)).toIntern();
3281 }3344 }
3282 return Value.fromInterned((try mod.intern(.{ .aggregate = .{3345 return Value.fromInterned(try pt.intern(.{ .aggregate = .{
3283 .ty = float_type.toIntern(),3346 .ty = float_type.toIntern(),
3284 .storage = .{ .elems = result_data },3347 .storage = .{ .elems = result_data },
3285 } })));3348 } }));
3286 }3349 }
3287 return log10Scalar(val, float_type, mod);3350 return log10Scalar(val, float_type, pt);
3288}3351}
32893352
3290pub fn log10Scalar(val: Value, float_type: Type, mod: *Module) Allocator.Error!Value {3353pub fn log10Scalar(val: Value, float_type: Type, pt: Zcu.PerThread) Allocator.Error!Value {
3354 const mod = pt.zcu;
3291 const target = mod.getTarget();3355 const target = mod.getTarget();
3292 const storage: InternPool.Key.Float.Storage = switch (float_type.floatBits(target)) {3356 const storage: InternPool.Key.Float.Storage = switch (float_type.floatBits(target)) {
3293 16 => .{ .f16 = @log10(val.toFloat(f16, mod)) },3357 16 => .{ .f16 = @log10(val.toFloat(f16, pt)) },
3294 32 => .{ .f32 = @log10(val.toFloat(f32, mod)) },3358 32 => .{ .f32 = @log10(val.toFloat(f32, pt)) },
3295 64 => .{ .f64 = @log10(val.toFloat(f64, mod)) },3359 64 => .{ .f64 = @log10(val.toFloat(f64, pt)) },
3296 80 => .{ .f80 = @log10(val.toFloat(f80, mod)) },3360 80 => .{ .f80 = @log10(val.toFloat(f80, pt)) },
3297 128 => .{ .f128 = @log10(val.toFloat(f128, mod)) },3361 128 => .{ .f128 = @log10(val.toFloat(f128, pt)) },
3298 else => unreachable,3362 else => unreachable,
3299 };3363 };
3300 return Value.fromInterned((try mod.intern(.{ .float = .{3364 return Value.fromInterned(try pt.intern(.{ .float = .{
3301 .ty = float_type.toIntern(),3365 .ty = float_type.toIntern(),
3302 .storage = storage,3366 .storage = storage,
3303 } })));3367 } }));
3304}3368}
33053369
3306pub fn abs(val: Value, ty: Type, arena: Allocator, mod: *Module) !Value {3370pub fn abs(val: Value, ty: Type, arena: Allocator, pt: Zcu.PerThread) !Value {
3371 const mod = pt.zcu;
3307 if (ty.zigTypeTag(mod) == .Vector) {3372 if (ty.zigTypeTag(mod) == .Vector) {
3308 const result_data = try arena.alloc(InternPool.Index, ty.vectorLen(mod));3373 const result_data = try arena.alloc(InternPool.Index, ty.vectorLen(mod));
3309 const scalar_ty = ty.scalarType(mod);3374 const scalar_ty = ty.scalarType(mod);
3310 for (result_data, 0..) |*scalar, i| {3375 for (result_data, 0..) |*scalar, i| {
3311 const elem_val = try val.elemValue(mod, i);3376 const elem_val = try val.elemValue(pt, i);
3312 scalar.* = (try absScalar(elem_val, scalar_ty, mod, arena)).toIntern();3377 scalar.* = (try absScalar(elem_val, scalar_ty, pt, arena)).toIntern();
3313 }3378 }
3314 return Value.fromInterned((try mod.intern(.{ .aggregate = .{3379 return Value.fromInterned(try pt.intern(.{ .aggregate = .{
3315 .ty = ty.toIntern(),3380 .ty = ty.toIntern(),
3316 .storage = .{ .elems = result_data },3381 .storage = .{ .elems = result_data },
3317 } })));3382 } }));
3318 }3383 }
3319 return absScalar(val, ty, mod, arena);3384 return absScalar(val, ty, pt, arena);
3320}3385}
33213386
3322pub fn absScalar(val: Value, ty: Type, mod: *Module, arena: Allocator) Allocator.Error!Value {3387pub fn absScalar(val: Value, ty: Type, pt: Zcu.PerThread, arena: Allocator) Allocator.Error!Value {
3388 const mod = pt.zcu;
3323 switch (ty.zigTypeTag(mod)) {3389 switch (ty.zigTypeTag(mod)) {
3324 .Int => {3390 .Int => {
3325 var buffer: Value.BigIntSpace = undefined;3391 var buffer: Value.BigIntSpace = undefined;
3326 var operand_bigint = try val.toBigInt(&buffer, mod).toManaged(arena);3392 var operand_bigint = try val.toBigInt(&buffer, pt).toManaged(arena);
3327 operand_bigint.abs();3393 operand_bigint.abs();
33283394
3329 return mod.intValue_big(try ty.toUnsigned(mod), operand_bigint.toConst());3395 return pt.intValue_big(try ty.toUnsigned(pt), operand_bigint.toConst());
3330 },3396 },
3331 .ComptimeInt => {3397 .ComptimeInt => {
3332 var buffer: Value.BigIntSpace = undefined;3398 var buffer: Value.BigIntSpace = undefined;
3333 var operand_bigint = try val.toBigInt(&buffer, mod).toManaged(arena);3399 var operand_bigint = try val.toBigInt(&buffer, pt).toManaged(arena);
3334 operand_bigint.abs();3400 operand_bigint.abs();
33353401
3336 return mod.intValue_big(ty, operand_bigint.toConst());3402 return pt.intValue_big(ty, operand_bigint.toConst());
3337 },3403 },
3338 .ComptimeFloat, .Float => {3404 .ComptimeFloat, .Float => {
3339 const target = mod.getTarget();3405 const target = mod.getTarget();
3340 const storage: InternPool.Key.Float.Storage = switch (ty.floatBits(target)) {3406 const storage: InternPool.Key.Float.Storage = switch (ty.floatBits(target)) {
3341 16 => .{ .f16 = @abs(val.toFloat(f16, mod)) },3407 16 => .{ .f16 = @abs(val.toFloat(f16, pt)) },
3342 32 => .{ .f32 = @abs(val.toFloat(f32, mod)) },3408 32 => .{ .f32 = @abs(val.toFloat(f32, pt)) },
3343 64 => .{ .f64 = @abs(val.toFloat(f64, mod)) },3409 64 => .{ .f64 = @abs(val.toFloat(f64, pt)) },
3344 80 => .{ .f80 = @abs(val.toFloat(f80, mod)) },3410 80 => .{ .f80 = @abs(val.toFloat(f80, pt)) },
3345 128 => .{ .f128 = @abs(val.toFloat(f128, mod)) },3411 128 => .{ .f128 = @abs(val.toFloat(f128, pt)) },
3346 else => unreachable,3412 else => unreachable,
3347 };3413 };
3348 return Value.fromInterned((try mod.intern(.{ .float = .{3414 return Value.fromInterned(try pt.intern(.{ .float = .{
3349 .ty = ty.toIntern(),3415 .ty = ty.toIntern(),
3350 .storage = storage,3416 .storage = storage,
3351 } })));3417 } }));
3352 },3418 },
3353 else => unreachable,3419 else => unreachable,
3354 }3420 }
3355}3421}
33563422
3357pub fn floor(val: Value, float_type: Type, arena: Allocator, mod: *Module) !Value {3423pub fn floor(val: Value, float_type: Type, arena: Allocator, pt: Zcu.PerThread) !Value {
3424 const mod = pt.zcu;
3358 if (float_type.zigTypeTag(mod) == .Vector) {3425 if (float_type.zigTypeTag(mod) == .Vector) {
3359 const result_data = try arena.alloc(InternPool.Index, float_type.vectorLen(mod));3426 const result_data = try arena.alloc(InternPool.Index, float_type.vectorLen(mod));
3360 const scalar_ty = float_type.scalarType(mod);3427 const scalar_ty = float_type.scalarType(mod);
3361 for (result_data, 0..) |*scalar, i| {3428 for (result_data, 0..) |*scalar, i| {
3362 const elem_val = try val.elemValue(mod, i);3429 const elem_val = try val.elemValue(pt, i);
3363 scalar.* = (try floorScalar(elem_val, scalar_ty, mod)).toIntern();3430 scalar.* = (try floorScalar(elem_val, scalar_ty, pt)).toIntern();
3364 }3431 }
3365 return Value.fromInterned((try mod.intern(.{ .aggregate = .{3432 return Value.fromInterned(try pt.intern(.{ .aggregate = .{
3366 .ty = float_type.toIntern(),3433 .ty = float_type.toIntern(),
3367 .storage = .{ .elems = result_data },3434 .storage = .{ .elems = result_data },
3368 } })));3435 } }));
3369 }3436 }
3370 return floorScalar(val, float_type, mod);3437 return floorScalar(val, float_type, pt);
3371}3438}
33723439
3373pub fn floorScalar(val: Value, float_type: Type, mod: *Module) Allocator.Error!Value {3440pub fn floorScalar(val: Value, float_type: Type, pt: Zcu.PerThread) Allocator.Error!Value {
3441 const mod = pt.zcu;
3374 const target = mod.getTarget();3442 const target = mod.getTarget();
3375 const storage: InternPool.Key.Float.Storage = switch (float_type.floatBits(target)) {3443 const storage: InternPool.Key.Float.Storage = switch (float_type.floatBits(target)) {
3376 16 => .{ .f16 = @floor(val.toFloat(f16, mod)) },3444 16 => .{ .f16 = @floor(val.toFloat(f16, pt)) },
3377 32 => .{ .f32 = @floor(val.toFloat(f32, mod)) },3445 32 => .{ .f32 = @floor(val.toFloat(f32, pt)) },
3378 64 => .{ .f64 = @floor(val.toFloat(f64, mod)) },3446 64 => .{ .f64 = @floor(val.toFloat(f64, pt)) },
3379 80 => .{ .f80 = @floor(val.toFloat(f80, mod)) },3447 80 => .{ .f80 = @floor(val.toFloat(f80, pt)) },
3380 128 => .{ .f128 = @floor(val.toFloat(f128, mod)) },3448 128 => .{ .f128 = @floor(val.toFloat(f128, pt)) },
3381 else => unreachable,3449 else => unreachable,
3382 };3450 };
3383 return Value.fromInterned((try mod.intern(.{ .float = .{3451 return Value.fromInterned(try pt.intern(.{ .float = .{
3384 .ty = float_type.toIntern(),3452 .ty = float_type.toIntern(),
3385 .storage = storage,3453 .storage = storage,
3386 } })));3454 } }));
3387}3455}
33883456
3389pub fn ceil(val: Value, float_type: Type, arena: Allocator, mod: *Module) !Value {3457pub fn ceil(val: Value, float_type: Type, arena: Allocator, pt: Zcu.PerThread) !Value {
3458 const mod = pt.zcu;
3390 if (float_type.zigTypeTag(mod) == .Vector) {3459 if (float_type.zigTypeTag(mod) == .Vector) {
3391 const result_data = try arena.alloc(InternPool.Index, float_type.vectorLen(mod));3460 const result_data = try arena.alloc(InternPool.Index, float_type.vectorLen(mod));
3392 const scalar_ty = float_type.scalarType(mod);3461 const scalar_ty = float_type.scalarType(mod);
3393 for (result_data, 0..) |*scalar, i| {3462 for (result_data, 0..) |*scalar, i| {
3394 const elem_val = try val.elemValue(mod, i);3463 const elem_val = try val.elemValue(pt, i);
3395 scalar.* = (try ceilScalar(elem_val, scalar_ty, mod)).toIntern();3464 scalar.* = (try ceilScalar(elem_val, scalar_ty, pt)).toIntern();
3396 }3465 }
3397 return Value.fromInterned((try mod.intern(.{ .aggregate = .{3466 return Value.fromInterned(try pt.intern(.{ .aggregate = .{
3398 .ty = float_type.toIntern(),3467 .ty = float_type.toIntern(),
3399 .storage = .{ .elems = result_data },3468 .storage = .{ .elems = result_data },
3400 } })));3469 } }));
3401 }3470 }
3402 return ceilScalar(val, float_type, mod);3471 return ceilScalar(val, float_type, pt);
3403}3472}
34043473
3405pub fn ceilScalar(val: Value, float_type: Type, mod: *Module) Allocator.Error!Value {3474pub fn ceilScalar(val: Value, float_type: Type, pt: Zcu.PerThread) Allocator.Error!Value {
3475 const mod = pt.zcu;
3406 const target = mod.getTarget();3476 const target = mod.getTarget();
3407 const storage: InternPool.Key.Float.Storage = switch (float_type.floatBits(target)) {3477 const storage: InternPool.Key.Float.Storage = switch (float_type.floatBits(target)) {
3408 16 => .{ .f16 = @ceil(val.toFloat(f16, mod)) },3478 16 => .{ .f16 = @ceil(val.toFloat(f16, pt)) },
3409 32 => .{ .f32 = @ceil(val.toFloat(f32, mod)) },3479 32 => .{ .f32 = @ceil(val.toFloat(f32, pt)) },
3410 64 => .{ .f64 = @ceil(val.toFloat(f64, mod)) },3480 64 => .{ .f64 = @ceil(val.toFloat(f64, pt)) },
3411 80 => .{ .f80 = @ceil(val.toFloat(f80, mod)) },3481 80 => .{ .f80 = @ceil(val.toFloat(f80, pt)) },
3412 128 => .{ .f128 = @ceil(val.toFloat(f128, mod)) },3482 128 => .{ .f128 = @ceil(val.toFloat(f128, pt)) },
3413 else => unreachable,3483 else => unreachable,
3414 };3484 };
3415 return Value.fromInterned((try mod.intern(.{ .float = .{3485 return Value.fromInterned(try pt.intern(.{ .float = .{
3416 .ty = float_type.toIntern(),3486 .ty = float_type.toIntern(),
3417 .storage = storage,3487 .storage = storage,
3418 } })));3488 } }));
3419}3489}
34203490
3421pub fn round(val: Value, float_type: Type, arena: Allocator, mod: *Module) !Value {3491pub fn round(val: Value, float_type: Type, arena: Allocator, pt: Zcu.PerThread) !Value {
3492 const mod = pt.zcu;
3422 if (float_type.zigTypeTag(mod) == .Vector) {3493 if (float_type.zigTypeTag(mod) == .Vector) {
3423 const result_data = try arena.alloc(InternPool.Index, float_type.vectorLen(mod));3494 const result_data = try arena.alloc(InternPool.Index, float_type.vectorLen(mod));
3424 const scalar_ty = float_type.scalarType(mod);3495 const scalar_ty = float_type.scalarType(mod);
3425 for (result_data, 0..) |*scalar, i| {3496 for (result_data, 0..) |*scalar, i| {
3426 const elem_val = try val.elemValue(mod, i);3497 const elem_val = try val.elemValue(pt, i);
3427 scalar.* = (try roundScalar(elem_val, scalar_ty, mod)).toIntern();3498 scalar.* = (try roundScalar(elem_val, scalar_ty, pt)).toIntern();
3428 }3499 }
3429 return Value.fromInterned((try mod.intern(.{ .aggregate = .{3500 return Value.fromInterned(try pt.intern(.{ .aggregate = .{
3430 .ty = float_type.toIntern(),3501 .ty = float_type.toIntern(),
3431 .storage = .{ .elems = result_data },3502 .storage = .{ .elems = result_data },
3432 } })));3503 } }));
3433 }3504 }
3434 return roundScalar(val, float_type, mod);3505 return roundScalar(val, float_type, pt);
3435}3506}
34363507
3437pub fn roundScalar(val: Value, float_type: Type, mod: *Module) Allocator.Error!Value {3508pub fn roundScalar(val: Value, float_type: Type, pt: Zcu.PerThread) Allocator.Error!Value {
3509 const mod = pt.zcu;
3438 const target = mod.getTarget();3510 const target = mod.getTarget();
3439 const storage: InternPool.Key.Float.Storage = switch (float_type.floatBits(target)) {3511 const storage: InternPool.Key.Float.Storage = switch (float_type.floatBits(target)) {
3440 16 => .{ .f16 = @round(val.toFloat(f16, mod)) },3512 16 => .{ .f16 = @round(val.toFloat(f16, pt)) },
3441 32 => .{ .f32 = @round(val.toFloat(f32, mod)) },3513 32 => .{ .f32 = @round(val.toFloat(f32, pt)) },
3442 64 => .{ .f64 = @round(val.toFloat(f64, mod)) },3514 64 => .{ .f64 = @round(val.toFloat(f64, pt)) },
3443 80 => .{ .f80 = @round(val.toFloat(f80, mod)) },3515 80 => .{ .f80 = @round(val.toFloat(f80, pt)) },
3444 128 => .{ .f128 = @round(val.toFloat(f128, mod)) },3516 128 => .{ .f128 = @round(val.toFloat(f128, pt)) },
3445 else => unreachable,3517 else => unreachable,
3446 };3518 };
3447 return Value.fromInterned((try mod.intern(.{ .float = .{3519 return Value.fromInterned(try pt.intern(.{ .float = .{
3448 .ty = float_type.toIntern(),3520 .ty = float_type.toIntern(),
3449 .storage = storage,3521 .storage = storage,
3450 } })));3522 } }));
3451}3523}
34523524
3453pub fn trunc(val: Value, float_type: Type, arena: Allocator, mod: *Module) !Value {3525pub fn trunc(val: Value, float_type: Type, arena: Allocator, pt: Zcu.PerThread) !Value {
3526 const mod = pt.zcu;
3454 if (float_type.zigTypeTag(mod) == .Vector) {3527 if (float_type.zigTypeTag(mod) == .Vector) {
3455 const result_data = try arena.alloc(InternPool.Index, float_type.vectorLen(mod));3528 const result_data = try arena.alloc(InternPool.Index, float_type.vectorLen(mod));
3456 const scalar_ty = float_type.scalarType(mod);3529 const scalar_ty = float_type.scalarType(mod);
3457 for (result_data, 0..) |*scalar, i| {3530 for (result_data, 0..) |*scalar, i| {
3458 const elem_val = try val.elemValue(mod, i);3531 const elem_val = try val.elemValue(pt, i);
3459 scalar.* = (try truncScalar(elem_val, scalar_ty, mod)).toIntern();3532 scalar.* = (try truncScalar(elem_val, scalar_ty, pt)).toIntern();
3460 }3533 }
3461 return Value.fromInterned((try mod.intern(.{ .aggregate = .{3534 return Value.fromInterned(try pt.intern(.{ .aggregate = .{
3462 .ty = float_type.toIntern(),3535 .ty = float_type.toIntern(),
3463 .storage = .{ .elems = result_data },3536 .storage = .{ .elems = result_data },
3464 } })));3537 } }));
3465 }3538 }
3466 return truncScalar(val, float_type, mod);3539 return truncScalar(val, float_type, pt);
3467}3540}
34683541
3469pub fn truncScalar(val: Value, float_type: Type, mod: *Module) Allocator.Error!Value {3542pub fn truncScalar(val: Value, float_type: Type, pt: Zcu.PerThread) Allocator.Error!Value {
3543 const mod = pt.zcu;
3470 const target = mod.getTarget();3544 const target = mod.getTarget();
3471 const storage: InternPool.Key.Float.Storage = switch (float_type.floatBits(target)) {3545 const storage: InternPool.Key.Float.Storage = switch (float_type.floatBits(target)) {
3472 16 => .{ .f16 = @trunc(val.toFloat(f16, mod)) },3546 16 => .{ .f16 = @trunc(val.toFloat(f16, pt)) },
3473 32 => .{ .f32 = @trunc(val.toFloat(f32, mod)) },3547 32 => .{ .f32 = @trunc(val.toFloat(f32, pt)) },
3474 64 => .{ .f64 = @trunc(val.toFloat(f64, mod)) },3548 64 => .{ .f64 = @trunc(val.toFloat(f64, pt)) },
3475 80 => .{ .f80 = @trunc(val.toFloat(f80, mod)) },3549 80 => .{ .f80 = @trunc(val.toFloat(f80, pt)) },
3476 128 => .{ .f128 = @trunc(val.toFloat(f128, mod)) },3550 128 => .{ .f128 = @trunc(val.toFloat(f128, pt)) },
3477 else => unreachable,3551 else => unreachable,
3478 };3552 };
3479 return Value.fromInterned((try mod.intern(.{ .float = .{3553 return Value.fromInterned(try pt.intern(.{ .float = .{
3480 .ty = float_type.toIntern(),3554 .ty = float_type.toIntern(),
3481 .storage = storage,3555 .storage = storage,
3482 } })));3556 } }));
3483}3557}
34843558
3485pub fn mulAdd(3559pub fn mulAdd(
...@@ -3488,23 +3562,24 @@ pub fn mulAdd(...@@ -3488,23 +3562,24 @@ pub fn mulAdd(
3488 mulend2: Value,3562 mulend2: Value,
3489 addend: Value,3563 addend: Value,
3490 arena: Allocator,3564 arena: Allocator,
3491 mod: *Module,3565 pt: Zcu.PerThread,
3492) !Value {3566) !Value {
3567 const mod = pt.zcu;
3493 if (float_type.zigTypeTag(mod) == .Vector) {3568 if (float_type.zigTypeTag(mod) == .Vector) {
3494 const result_data = try arena.alloc(InternPool.Index, float_type.vectorLen(mod));3569 const result_data = try arena.alloc(InternPool.Index, float_type.vectorLen(mod));
3495 const scalar_ty = float_type.scalarType(mod);3570 const scalar_ty = float_type.scalarType(mod);
3496 for (result_data, 0..) |*scalar, i| {3571 for (result_data, 0..) |*scalar, i| {
3497 const mulend1_elem = try mulend1.elemValue(mod, i);3572 const mulend1_elem = try mulend1.elemValue(pt, i);
3498 const mulend2_elem = try mulend2.elemValue(mod, i);3573 const mulend2_elem = try mulend2.elemValue(pt, i);
3499 const addend_elem = try addend.elemValue(mod, i);3574 const addend_elem = try addend.elemValue(pt, i);
3500 scalar.* = (try mulAddScalar(scalar_ty, mulend1_elem, mulend2_elem, addend_elem, mod)).toIntern();3575 scalar.* = (try mulAddScalar(scalar_ty, mulend1_elem, mulend2_elem, addend_elem, pt)).toIntern();
3501 }3576 }
3502 return Value.fromInterned((try mod.intern(.{ .aggregate = .{3577 return Value.fromInterned(try pt.intern(.{ .aggregate = .{
3503 .ty = float_type.toIntern(),3578 .ty = float_type.toIntern(),
3504 .storage = .{ .elems = result_data },3579 .storage = .{ .elems = result_data },
3505 } })));3580 } }));
3506 }3581 }
3507 return mulAddScalar(float_type, mulend1, mulend2, addend, mod);3582 return mulAddScalar(float_type, mulend1, mulend2, addend, pt);
3508}3583}
35093584
3510pub fn mulAddScalar(3585pub fn mulAddScalar(
...@@ -3512,32 +3587,33 @@ pub fn mulAddScalar(...@@ -3512,32 +3587,33 @@ pub fn mulAddScalar(
3512 mulend1: Value,3587 mulend1: Value,
3513 mulend2: Value,3588 mulend2: Value,
3514 addend: Value,3589 addend: Value,
3515 mod: *Module,3590 pt: Zcu.PerThread,
3516) Allocator.Error!Value {3591) Allocator.Error!Value {
3592 const mod = pt.zcu;
3517 const target = mod.getTarget();3593 const target = mod.getTarget();
3518 const storage: InternPool.Key.Float.Storage = switch (float_type.floatBits(target)) {3594 const storage: InternPool.Key.Float.Storage = switch (float_type.floatBits(target)) {
3519 16 => .{ .f16 = @mulAdd(f16, mulend1.toFloat(f16, mod), mulend2.toFloat(f16, mod), addend.toFloat(f16, mod)) },3595 16 => .{ .f16 = @mulAdd(f16, mulend1.toFloat(f16, pt), mulend2.toFloat(f16, pt), addend.toFloat(f16, pt)) },
3520 32 => .{ .f32 = @mulAdd(f32, mulend1.toFloat(f32, mod), mulend2.toFloat(f32, mod), addend.toFloat(f32, mod)) },3596 32 => .{ .f32 = @mulAdd(f32, mulend1.toFloat(f32, pt), mulend2.toFloat(f32, pt), addend.toFloat(f32, pt)) },
3521 64 => .{ .f64 = @mulAdd(f64, mulend1.toFloat(f64, mod), mulend2.toFloat(f64, mod), addend.toFloat(f64, mod)) },3597 64 => .{ .f64 = @mulAdd(f64, mulend1.toFloat(f64, pt), mulend2.toFloat(f64, pt), addend.toFloat(f64, pt)) },
3522 80 => .{ .f80 = @mulAdd(f80, mulend1.toFloat(f80, mod), mulend2.toFloat(f80, mod), addend.toFloat(f80, mod)) },3598 80 => .{ .f80 = @mulAdd(f80, mulend1.toFloat(f80, pt), mulend2.toFloat(f80, pt), addend.toFloat(f80, pt)) },
3523 128 => .{ .f128 = @mulAdd(f128, mulend1.toFloat(f128, mod), mulend2.toFloat(f128, mod), addend.toFloat(f128, mod)) },3599 128 => .{ .f128 = @mulAdd(f128, mulend1.toFloat(f128, pt), mulend2.toFloat(f128, pt), addend.toFloat(f128, pt)) },
3524 else => unreachable,3600 else => unreachable,
3525 };3601 };
3526 return Value.fromInterned((try mod.intern(.{ .float = .{3602 return Value.fromInterned(try pt.intern(.{ .float = .{
3527 .ty = float_type.toIntern(),3603 .ty = float_type.toIntern(),
3528 .storage = storage,3604 .storage = storage,
3529 } })));3605 } }));
3530}3606}
35313607
3532/// If the value is represented in-memory as a series of bytes that all3608/// If the value is represented in-memory as a series of bytes that all
3533/// have the same value, return that byte value, otherwise null.3609/// have the same value, return that byte value, otherwise null.
3534pub fn hasRepeatedByteRepr(val: Value, ty: Type, mod: *Module) !?u8 {3610pub fn hasRepeatedByteRepr(val: Value, ty: Type, pt: Zcu.PerThread) !?u8 {
3535 const abi_size = std.math.cast(usize, ty.abiSize(mod)) orelse return null;3611 const abi_size = std.math.cast(usize, ty.abiSize(pt)) orelse return null;
3536 assert(abi_size >= 1);3612 assert(abi_size >= 1);
3537 const byte_buffer = try mod.gpa.alloc(u8, abi_size);3613 const byte_buffer = try pt.zcu.gpa.alloc(u8, abi_size);
3538 defer mod.gpa.free(byte_buffer);3614 defer pt.zcu.gpa.free(byte_buffer);
35393615
3540 writeToMemory(val, ty, mod, byte_buffer) catch |err| switch (err) {3616 writeToMemory(val, ty, pt, byte_buffer) catch |err| switch (err) {
3541 error.OutOfMemory => return error.OutOfMemory,3617 error.OutOfMemory => return error.OutOfMemory,
3542 error.ReinterpretDeclRef => return null,3618 error.ReinterpretDeclRef => return null,
3543 // TODO: The writeToMemory function was originally created for the purpose3619 // TODO: The writeToMemory function was originally created for the purpose
...@@ -3567,13 +3643,13 @@ pub fn typeOf(val: Value, zcu: *const Zcu) Type {...@@ -3567,13 +3643,13 @@ pub fn typeOf(val: Value, zcu: *const Zcu) Type {
3567/// If `val` is not undef, the bounds are both `val`.3643/// If `val` is not undef, the bounds are both `val`.
3568/// If `val` is undef and has a fixed-width type, the bounds are the bounds of the type.3644/// If `val` is undef and has a fixed-width type, the bounds are the bounds of the type.
3569/// If `val` is undef and is a `comptime_int`, returns null.3645/// If `val` is undef and is a `comptime_int`, returns null.
3570pub fn intValueBounds(val: Value, mod: *Module) !?[2]Value {3646pub fn intValueBounds(val: Value, pt: Zcu.PerThread) !?[2]Value {
3571 if (!val.isUndef(mod)) return .{ val, val };3647 if (!val.isUndef(pt.zcu)) return .{ val, val };
3572 const ty = mod.intern_pool.typeOf(val.toIntern());3648 const ty = pt.zcu.intern_pool.typeOf(val.toIntern());
3573 if (ty == .comptime_int_type) return null;3649 if (ty == .comptime_int_type) return null;
3574 return .{3650 return .{
3575 try Type.fromInterned(ty).minInt(mod, Type.fromInterned(ty)),3651 try Type.fromInterned(ty).minInt(pt, Type.fromInterned(ty)),
3576 try Type.fromInterned(ty).maxInt(mod, Type.fromInterned(ty)),3652 try Type.fromInterned(ty).maxInt(pt, Type.fromInterned(ty)),
3577 };3653 };
3578}3654}
35793655
...@@ -3604,14 +3680,15 @@ pub const RuntimeIndex = InternPool.RuntimeIndex;...@@ -3604,14 +3680,15 @@ pub const RuntimeIndex = InternPool.RuntimeIndex;
3604/// `parent_ptr` must be a single-pointer to some optional.3680/// `parent_ptr` must be a single-pointer to some optional.
3605/// Returns a pointer to the payload of the optional.3681/// Returns a pointer to the payload of the optional.
3606/// May perform type resolution.3682/// May perform type resolution.
3607pub fn ptrOptPayload(parent_ptr: Value, zcu: *Zcu) !Value {3683pub fn ptrOptPayload(parent_ptr: Value, pt: Zcu.PerThread) !Value {
3684 const zcu = pt.zcu;
3608 const parent_ptr_ty = parent_ptr.typeOf(zcu);3685 const parent_ptr_ty = parent_ptr.typeOf(zcu);
3609 const opt_ty = parent_ptr_ty.childType(zcu);3686 const opt_ty = parent_ptr_ty.childType(zcu);
36103687
3611 assert(parent_ptr_ty.ptrSize(zcu) == .One);3688 assert(parent_ptr_ty.ptrSize(zcu) == .One);
3612 assert(opt_ty.zigTypeTag(zcu) == .Optional);3689 assert(opt_ty.zigTypeTag(zcu) == .Optional);
36133690
3614 const result_ty = try zcu.ptrTypeSema(info: {3691 const result_ty = try pt.ptrTypeSema(info: {
3615 var new = parent_ptr_ty.ptrInfo(zcu);3692 var new = parent_ptr_ty.ptrInfo(zcu);
3616 // We can correctly preserve alignment `.none`, since an optional has the same3693 // We can correctly preserve alignment `.none`, since an optional has the same
3617 // natural alignment as its child type.3694 // natural alignment as its child type.
...@@ -3619,15 +3696,15 @@ pub fn ptrOptPayload(parent_ptr: Value, zcu: *Zcu) !Value {...@@ -3619,15 +3696,15 @@ pub fn ptrOptPayload(parent_ptr: Value, zcu: *Zcu) !Value {
3619 break :info new;3696 break :info new;
3620 });3697 });
36213698
3622 if (parent_ptr.isUndef(zcu)) return zcu.undefValue(result_ty);3699 if (parent_ptr.isUndef(zcu)) return pt.undefValue(result_ty);
36233700
3624 if (opt_ty.isPtrLikeOptional(zcu)) {3701 if (opt_ty.isPtrLikeOptional(zcu)) {
3625 // Just reinterpret the pointer, since the layout is well-defined3702 // Just reinterpret the pointer, since the layout is well-defined
3626 return zcu.getCoerced(parent_ptr, result_ty);3703 return pt.getCoerced(parent_ptr, result_ty);
3627 }3704 }
36283705
3629 const base_ptr = try parent_ptr.canonicalizeBasePtr(.One, opt_ty, zcu);3706 const base_ptr = try parent_ptr.canonicalizeBasePtr(.One, opt_ty, pt);
3630 return Value.fromInterned(try zcu.intern(.{ .ptr = .{3707 return Value.fromInterned(try pt.intern(.{ .ptr = .{
3631 .ty = result_ty.toIntern(),3708 .ty = result_ty.toIntern(),
3632 .base_addr = .{ .opt_payload = base_ptr.toIntern() },3709 .base_addr = .{ .opt_payload = base_ptr.toIntern() },
3633 .byte_offset = 0,3710 .byte_offset = 0,
...@@ -3637,14 +3714,15 @@ pub fn ptrOptPayload(parent_ptr: Value, zcu: *Zcu) !Value {...@@ -3637,14 +3714,15 @@ pub fn ptrOptPayload(parent_ptr: Value, zcu: *Zcu) !Value {
3637/// `parent_ptr` must be a single-pointer to some error union.3714/// `parent_ptr` must be a single-pointer to some error union.
3638/// Returns a pointer to the payload of the error union.3715/// Returns a pointer to the payload of the error union.
3639/// May perform type resolution.3716/// May perform type resolution.
3640pub fn ptrEuPayload(parent_ptr: Value, zcu: *Zcu) !Value {3717pub fn ptrEuPayload(parent_ptr: Value, pt: Zcu.PerThread) !Value {
3718 const zcu = pt.zcu;
3641 const parent_ptr_ty = parent_ptr.typeOf(zcu);3719 const parent_ptr_ty = parent_ptr.typeOf(zcu);
3642 const eu_ty = parent_ptr_ty.childType(zcu);3720 const eu_ty = parent_ptr_ty.childType(zcu);
36433721
3644 assert(parent_ptr_ty.ptrSize(zcu) == .One);3722 assert(parent_ptr_ty.ptrSize(zcu) == .One);
3645 assert(eu_ty.zigTypeTag(zcu) == .ErrorUnion);3723 assert(eu_ty.zigTypeTag(zcu) == .ErrorUnion);
36463724
3647 const result_ty = try zcu.ptrTypeSema(info: {3725 const result_ty = try pt.ptrTypeSema(info: {
3648 var new = parent_ptr_ty.ptrInfo(zcu);3726 var new = parent_ptr_ty.ptrInfo(zcu);
3649 // We can correctly preserve alignment `.none`, since an error union has a3727 // We can correctly preserve alignment `.none`, since an error union has a
3650 // natural alignment greater than or equal to that of its payload type.3728 // natural alignment greater than or equal to that of its payload type.
...@@ -3652,10 +3730,10 @@ pub fn ptrEuPayload(parent_ptr: Value, zcu: *Zcu) !Value {...@@ -3652,10 +3730,10 @@ pub fn ptrEuPayload(parent_ptr: Value, zcu: *Zcu) !Value {
3652 break :info new;3730 break :info new;
3653 });3731 });
36543732
3655 if (parent_ptr.isUndef(zcu)) return zcu.undefValue(result_ty);3733 if (parent_ptr.isUndef(zcu)) return pt.undefValue(result_ty);
36563734
3657 const base_ptr = try parent_ptr.canonicalizeBasePtr(.One, eu_ty, zcu);3735 const base_ptr = try parent_ptr.canonicalizeBasePtr(.One, eu_ty, pt);
3658 return Value.fromInterned(try zcu.intern(.{ .ptr = .{3736 return Value.fromInterned(try pt.intern(.{ .ptr = .{
3659 .ty = result_ty.toIntern(),3737 .ty = result_ty.toIntern(),
3660 .base_addr = .{ .eu_payload = base_ptr.toIntern() },3738 .base_addr = .{ .eu_payload = base_ptr.toIntern() },
3661 .byte_offset = 0,3739 .byte_offset = 0,
...@@ -3666,7 +3744,8 @@ pub fn ptrEuPayload(parent_ptr: Value, zcu: *Zcu) !Value {...@@ -3666,7 +3744,8 @@ pub fn ptrEuPayload(parent_ptr: Value, zcu: *Zcu) !Value {
3666/// Returns a pointer to the aggregate field at the specified index.3744/// Returns a pointer to the aggregate field at the specified index.
3667/// For slices, uses `slice_ptr_index` and `slice_len_index`.3745/// For slices, uses `slice_ptr_index` and `slice_len_index`.
3668/// May perform type resolution.3746/// May perform type resolution.
3669pub fn ptrField(parent_ptr: Value, field_idx: u32, zcu: *Zcu) !Value {3747pub fn ptrField(parent_ptr: Value, field_idx: u32, pt: Zcu.PerThread) !Value {
3748 const zcu = pt.zcu;
3670 const parent_ptr_ty = parent_ptr.typeOf(zcu);3749 const parent_ptr_ty = parent_ptr.typeOf(zcu);
3671 const aggregate_ty = parent_ptr_ty.childType(zcu);3750 const aggregate_ty = parent_ptr_ty.childType(zcu);
36723751
...@@ -3679,39 +3758,39 @@ pub fn ptrField(parent_ptr: Value, field_idx: u32, zcu: *Zcu) !Value {...@@ -3679,39 +3758,39 @@ pub fn ptrField(parent_ptr: Value, field_idx: u32, zcu: *Zcu) !Value {
3679 .Struct => field: {3758 .Struct => field: {
3680 const field_ty = aggregate_ty.structFieldType(field_idx, zcu);3759 const field_ty = aggregate_ty.structFieldType(field_idx, zcu);
3681 switch (aggregate_ty.containerLayout(zcu)) {3760 switch (aggregate_ty.containerLayout(zcu)) {
3682 .auto => break :field .{ field_ty, try aggregate_ty.structFieldAlignAdvanced(@intCast(field_idx), zcu, .sema) },3761 .auto => break :field .{ field_ty, try aggregate_ty.structFieldAlignAdvanced(@intCast(field_idx), pt, .sema) },
3683 .@"extern" => {3762 .@"extern" => {
3684 // Well-defined layout, so just offset the pointer appropriately.3763 // Well-defined layout, so just offset the pointer appropriately.
3685 const byte_off = aggregate_ty.structFieldOffset(field_idx, zcu);3764 const byte_off = aggregate_ty.structFieldOffset(field_idx, pt);
3686 const field_align = a: {3765 const field_align = a: {
3687 const parent_align = if (parent_ptr_info.flags.alignment == .none) pa: {3766 const parent_align = if (parent_ptr_info.flags.alignment == .none) pa: {
3688 break :pa (try aggregate_ty.abiAlignmentAdvanced(zcu, .sema)).scalar;3767 break :pa (try aggregate_ty.abiAlignmentAdvanced(pt, .sema)).scalar;
3689 } else parent_ptr_info.flags.alignment;3768 } else parent_ptr_info.flags.alignment;
3690 break :a InternPool.Alignment.fromLog2Units(@min(parent_align.toLog2Units(), @ctz(byte_off)));3769 break :a InternPool.Alignment.fromLog2Units(@min(parent_align.toLog2Units(), @ctz(byte_off)));
3691 };3770 };
3692 const result_ty = try zcu.ptrTypeSema(info: {3771 const result_ty = try pt.ptrTypeSema(info: {
3693 var new = parent_ptr_info;3772 var new = parent_ptr_info;
3694 new.child = field_ty.toIntern();3773 new.child = field_ty.toIntern();
3695 new.flags.alignment = field_align;3774 new.flags.alignment = field_align;
3696 break :info new;3775 break :info new;
3697 });3776 });
3698 return parent_ptr.getOffsetPtr(byte_off, result_ty, zcu);3777 return parent_ptr.getOffsetPtr(byte_off, result_ty, pt);
3699 },3778 },
3700 .@"packed" => switch (aggregate_ty.packedStructFieldPtrInfo(parent_ptr_ty, field_idx, zcu)) {3779 .@"packed" => switch (aggregate_ty.packedStructFieldPtrInfo(parent_ptr_ty, field_idx, pt)) {
3701 .bit_ptr => |packed_offset| {3780 .bit_ptr => |packed_offset| {
3702 const result_ty = try zcu.ptrType(info: {3781 const result_ty = try pt.ptrType(info: {
3703 var new = parent_ptr_info;3782 var new = parent_ptr_info;
3704 new.packed_offset = packed_offset;3783 new.packed_offset = packed_offset;
3705 new.child = field_ty.toIntern();3784 new.child = field_ty.toIntern();
3706 if (new.flags.alignment == .none) {3785 if (new.flags.alignment == .none) {
3707 new.flags.alignment = (try aggregate_ty.abiAlignmentAdvanced(zcu, .sema)).scalar;3786 new.flags.alignment = (try aggregate_ty.abiAlignmentAdvanced(pt, .sema)).scalar;
3708 }3787 }
3709 break :info new;3788 break :info new;
3710 });3789 });
3711 return zcu.getCoerced(parent_ptr, result_ty);3790 return pt.getCoerced(parent_ptr, result_ty);
3712 },3791 },
3713 .byte_ptr => |ptr_info| {3792 .byte_ptr => |ptr_info| {
3714 const result_ty = try zcu.ptrTypeSema(info: {3793 const result_ty = try pt.ptrTypeSema(info: {
3715 var new = parent_ptr_info;3794 var new = parent_ptr_info;
3716 new.child = field_ty.toIntern();3795 new.child = field_ty.toIntern();
3717 new.packed_offset = .{3796 new.packed_offset = .{
...@@ -3721,7 +3800,7 @@ pub fn ptrField(parent_ptr: Value, field_idx: u32, zcu: *Zcu) !Value {...@@ -3721,7 +3800,7 @@ pub fn ptrField(parent_ptr: Value, field_idx: u32, zcu: *Zcu) !Value {
3721 new.flags.alignment = ptr_info.alignment;3800 new.flags.alignment = ptr_info.alignment;
3722 break :info new;3801 break :info new;
3723 });3802 });
3724 return parent_ptr.getOffsetPtr(ptr_info.offset, result_ty, zcu);3803 return parent_ptr.getOffsetPtr(ptr_info.offset, result_ty, pt);
3725 },3804 },
3726 },3805 },
3727 }3806 }
...@@ -3730,46 +3809,46 @@ pub fn ptrField(parent_ptr: Value, field_idx: u32, zcu: *Zcu) !Value {...@@ -3730,46 +3809,46 @@ pub fn ptrField(parent_ptr: Value, field_idx: u32, zcu: *Zcu) !Value {
3730 const union_obj = zcu.typeToUnion(aggregate_ty).?;3809 const union_obj = zcu.typeToUnion(aggregate_ty).?;
3731 const field_ty = Type.fromInterned(union_obj.field_types.get(&zcu.intern_pool)[field_idx]);3810 const field_ty = Type.fromInterned(union_obj.field_types.get(&zcu.intern_pool)[field_idx]);
3732 switch (aggregate_ty.containerLayout(zcu)) {3811 switch (aggregate_ty.containerLayout(zcu)) {
3733 .auto => break :field .{ field_ty, try aggregate_ty.structFieldAlignAdvanced(@intCast(field_idx), zcu, .sema) },3812 .auto => break :field .{ field_ty, try aggregate_ty.structFieldAlignAdvanced(@intCast(field_idx), pt, .sema) },
3734 .@"extern" => {3813 .@"extern" => {
3735 // Point to the same address.3814 // Point to the same address.
3736 const result_ty = try zcu.ptrTypeSema(info: {3815 const result_ty = try pt.ptrTypeSema(info: {
3737 var new = parent_ptr_info;3816 var new = parent_ptr_info;
3738 new.child = field_ty.toIntern();3817 new.child = field_ty.toIntern();
3739 break :info new;3818 break :info new;
3740 });3819 });
3741 return zcu.getCoerced(parent_ptr, result_ty);3820 return pt.getCoerced(parent_ptr, result_ty);
3742 },3821 },
3743 .@"packed" => {3822 .@"packed" => {
3744 // If the field has an ABI size matching its bit size, then we can continue to use a3823 // If the field has an ABI size matching its bit size, then we can continue to use a
3745 // non-bit pointer if the parent pointer is also a non-bit pointer.3824 // non-bit pointer if the parent pointer is also a non-bit pointer.
3746 if (parent_ptr_info.packed_offset.host_size == 0 and (try field_ty.abiSizeAdvanced(zcu, .sema)).scalar * 8 == try field_ty.bitSizeAdvanced(zcu, .sema)) {3825 if (parent_ptr_info.packed_offset.host_size == 0 and (try field_ty.abiSizeAdvanced(pt, .sema)).scalar * 8 == try field_ty.bitSizeAdvanced(pt, .sema)) {
3747 // We must offset the pointer on big-endian targets, since the bits of packed memory don't align nicely.3826 // We must offset the pointer on big-endian targets, since the bits of packed memory don't align nicely.
3748 const byte_offset = switch (zcu.getTarget().cpu.arch.endian()) {3827 const byte_offset = switch (zcu.getTarget().cpu.arch.endian()) {
3749 .little => 0,3828 .little => 0,
3750 .big => (try aggregate_ty.abiSizeAdvanced(zcu, .sema)).scalar - (try field_ty.abiSizeAdvanced(zcu, .sema)).scalar,3829 .big => (try aggregate_ty.abiSizeAdvanced(pt, .sema)).scalar - (try field_ty.abiSizeAdvanced(pt, .sema)).scalar,
3751 };3830 };
3752 const result_ty = try zcu.ptrTypeSema(info: {3831 const result_ty = try pt.ptrTypeSema(info: {
3753 var new = parent_ptr_info;3832 var new = parent_ptr_info;
3754 new.child = field_ty.toIntern();3833 new.child = field_ty.toIntern();
3755 new.flags.alignment = InternPool.Alignment.fromLog2Units(3834 new.flags.alignment = InternPool.Alignment.fromLog2Units(
3756 @ctz(byte_offset | (try parent_ptr_ty.ptrAlignmentAdvanced(zcu, .sema)).toByteUnits().?),3835 @ctz(byte_offset | (try parent_ptr_ty.ptrAlignmentAdvanced(pt, .sema)).toByteUnits().?),
3757 );3836 );
3758 break :info new;3837 break :info new;
3759 });3838 });
3760 return parent_ptr.getOffsetPtr(byte_offset, result_ty, zcu);3839 return parent_ptr.getOffsetPtr(byte_offset, result_ty, pt);
3761 } else {3840 } else {
3762 // The result must be a bit-pointer if it is not already.3841 // The result must be a bit-pointer if it is not already.
3763 const result_ty = try zcu.ptrTypeSema(info: {3842 const result_ty = try pt.ptrTypeSema(info: {
3764 var new = parent_ptr_info;3843 var new = parent_ptr_info;
3765 new.child = field_ty.toIntern();3844 new.child = field_ty.toIntern();
3766 if (new.packed_offset.host_size == 0) {3845 if (new.packed_offset.host_size == 0) {
3767 new.packed_offset.host_size = @intCast(((try aggregate_ty.bitSizeAdvanced(zcu, .sema)) + 7) / 8);3846 new.packed_offset.host_size = @intCast(((try aggregate_ty.bitSizeAdvanced(pt, .sema)) + 7) / 8);
3768 assert(new.packed_offset.bit_offset == 0);3847 assert(new.packed_offset.bit_offset == 0);
3769 }3848 }
3770 break :info new;3849 break :info new;
3771 });3850 });
3772 return zcu.getCoerced(parent_ptr, result_ty);3851 return pt.getCoerced(parent_ptr, result_ty);
3773 }3852 }
3774 },3853 },
3775 }3854 }
...@@ -3777,8 +3856,8 @@ pub fn ptrField(parent_ptr: Value, field_idx: u32, zcu: *Zcu) !Value {...@@ -3777,8 +3856,8 @@ pub fn ptrField(parent_ptr: Value, field_idx: u32, zcu: *Zcu) !Value {
3777 .Pointer => field_ty: {3856 .Pointer => field_ty: {
3778 assert(aggregate_ty.isSlice(zcu));3857 assert(aggregate_ty.isSlice(zcu));
3779 break :field_ty switch (field_idx) {3858 break :field_ty switch (field_idx) {
3780 Value.slice_ptr_index => .{ aggregate_ty.slicePtrFieldType(zcu), Type.usize.abiAlignment(zcu) },3859 Value.slice_ptr_index => .{ aggregate_ty.slicePtrFieldType(zcu), Type.usize.abiAlignment(pt) },
3781 Value.slice_len_index => .{ Type.usize, Type.usize.abiAlignment(zcu) },3860 Value.slice_len_index => .{ Type.usize, Type.usize.abiAlignment(pt) },
3782 else => unreachable,3861 else => unreachable,
3783 };3862 };
3784 },3863 },
...@@ -3786,24 +3865,24 @@ pub fn ptrField(parent_ptr: Value, field_idx: u32, zcu: *Zcu) !Value {...@@ -3786,24 +3865,24 @@ pub fn ptrField(parent_ptr: Value, field_idx: u32, zcu: *Zcu) !Value {
3786 };3865 };
37873866
3788 const new_align: InternPool.Alignment = if (parent_ptr_info.flags.alignment != .none) a: {3867 const new_align: InternPool.Alignment = if (parent_ptr_info.flags.alignment != .none) a: {
3789 const ty_align = (try field_ty.abiAlignmentAdvanced(zcu, .sema)).scalar;3868 const ty_align = (try field_ty.abiAlignmentAdvanced(pt, .sema)).scalar;
3790 const true_field_align = if (field_align == .none) ty_align else field_align;3869 const true_field_align = if (field_align == .none) ty_align else field_align;
3791 const new_align = true_field_align.min(parent_ptr_info.flags.alignment);3870 const new_align = true_field_align.min(parent_ptr_info.flags.alignment);
3792 if (new_align == ty_align) break :a .none;3871 if (new_align == ty_align) break :a .none;
3793 break :a new_align;3872 break :a new_align;
3794 } else field_align;3873 } else field_align;
37953874
3796 const result_ty = try zcu.ptrTypeSema(info: {3875 const result_ty = try pt.ptrTypeSema(info: {
3797 var new = parent_ptr_info;3876 var new = parent_ptr_info;
3798 new.child = field_ty.toIntern();3877 new.child = field_ty.toIntern();
3799 new.flags.alignment = new_align;3878 new.flags.alignment = new_align;
3800 break :info new;3879 break :info new;
3801 });3880 });
38023881
3803 if (parent_ptr.isUndef(zcu)) return zcu.undefValue(result_ty);3882 if (parent_ptr.isUndef(zcu)) return pt.undefValue(result_ty);
38043883
3805 const base_ptr = try parent_ptr.canonicalizeBasePtr(.One, aggregate_ty, zcu);3884 const base_ptr = try parent_ptr.canonicalizeBasePtr(.One, aggregate_ty, pt);
3806 return Value.fromInterned(try zcu.intern(.{ .ptr = .{3885 return Value.fromInterned(try pt.intern(.{ .ptr = .{
3807 .ty = result_ty.toIntern(),3886 .ty = result_ty.toIntern(),
3808 .base_addr = .{ .field = .{3887 .base_addr = .{ .field = .{
3809 .base = base_ptr.toIntern(),3888 .base = base_ptr.toIntern(),
...@@ -3816,7 +3895,8 @@ pub fn ptrField(parent_ptr: Value, field_idx: u32, zcu: *Zcu) !Value {...@@ -3816,7 +3895,8 @@ pub fn ptrField(parent_ptr: Value, field_idx: u32, zcu: *Zcu) !Value {
3816/// `orig_parent_ptr` must be either a single-pointer to an array or vector, or a many-pointer or C-pointer or slice.3895/// `orig_parent_ptr` must be either a single-pointer to an array or vector, or a many-pointer or C-pointer or slice.
3817/// Returns a pointer to the element at the specified index.3896/// Returns a pointer to the element at the specified index.
3818/// May perform type resolution.3897/// May perform type resolution.
3819pub fn ptrElem(orig_parent_ptr: Value, field_idx: u64, zcu: *Zcu) !Value {3898pub fn ptrElem(orig_parent_ptr: Value, field_idx: u64, pt: Zcu.PerThread) !Value {
3899 const zcu = pt.zcu;
3820 const parent_ptr = switch (orig_parent_ptr.typeOf(zcu).ptrSize(zcu)) {3900 const parent_ptr = switch (orig_parent_ptr.typeOf(zcu).ptrSize(zcu)) {
3821 .One, .Many, .C => orig_parent_ptr,3901 .One, .Many, .C => orig_parent_ptr,
3822 .Slice => orig_parent_ptr.slicePtr(zcu),3902 .Slice => orig_parent_ptr.slicePtr(zcu),
...@@ -3824,14 +3904,14 @@ pub fn ptrElem(orig_parent_ptr: Value, field_idx: u64, zcu: *Zcu) !Value {...@@ -3824,14 +3904,14 @@ pub fn ptrElem(orig_parent_ptr: Value, field_idx: u64, zcu: *Zcu) !Value {
38243904
3825 const parent_ptr_ty = parent_ptr.typeOf(zcu);3905 const parent_ptr_ty = parent_ptr.typeOf(zcu);
3826 const elem_ty = parent_ptr_ty.childType(zcu);3906 const elem_ty = parent_ptr_ty.childType(zcu);
3827 const result_ty = try parent_ptr_ty.elemPtrType(@intCast(field_idx), zcu);3907 const result_ty = try parent_ptr_ty.elemPtrType(@intCast(field_idx), pt);
38283908
3829 if (parent_ptr.isUndef(zcu)) return zcu.undefValue(result_ty);3909 if (parent_ptr.isUndef(zcu)) return pt.undefValue(result_ty);
38303910
3831 if (result_ty.ptrInfo(zcu).packed_offset.host_size != 0) {3911 if (result_ty.ptrInfo(zcu).packed_offset.host_size != 0) {
3832 // Since we have a bit-pointer, the pointer address should be unchanged.3912 // Since we have a bit-pointer, the pointer address should be unchanged.
3833 assert(elem_ty.zigTypeTag(zcu) == .Vector);3913 assert(elem_ty.zigTypeTag(zcu) == .Vector);
3834 return zcu.getCoerced(parent_ptr, result_ty);3914 return pt.getCoerced(parent_ptr, result_ty);
3835 }3915 }
38363916
3837 const PtrStrat = union(enum) {3917 const PtrStrat = union(enum) {
...@@ -3841,31 +3921,31 @@ pub fn ptrElem(orig_parent_ptr: Value, field_idx: u64, zcu: *Zcu) !Value {...@@ -3841,31 +3921,31 @@ pub fn ptrElem(orig_parent_ptr: Value, field_idx: u64, zcu: *Zcu) !Value {
38413921
3842 const strat: PtrStrat = switch (parent_ptr_ty.ptrSize(zcu)) {3922 const strat: PtrStrat = switch (parent_ptr_ty.ptrSize(zcu)) {
3843 .One => switch (elem_ty.zigTypeTag(zcu)) {3923 .One => switch (elem_ty.zigTypeTag(zcu)) {
3844 .Vector => .{ .offset = field_idx * @divExact(try elem_ty.childType(zcu).bitSizeAdvanced(zcu, .sema), 8) },3924 .Vector => .{ .offset = field_idx * @divExact(try elem_ty.childType(zcu).bitSizeAdvanced(pt, .sema), 8) },
3845 .Array => strat: {3925 .Array => strat: {
3846 const arr_elem_ty = elem_ty.childType(zcu);3926 const arr_elem_ty = elem_ty.childType(zcu);
3847 if (try arr_elem_ty.comptimeOnlyAdvanced(zcu, .sema)) {3927 if (try arr_elem_ty.comptimeOnlyAdvanced(pt, .sema)) {
3848 break :strat .{ .elem_ptr = arr_elem_ty };3928 break :strat .{ .elem_ptr = arr_elem_ty };
3849 }3929 }
3850 break :strat .{ .offset = field_idx * (try arr_elem_ty.abiSizeAdvanced(zcu, .sema)).scalar };3930 break :strat .{ .offset = field_idx * (try arr_elem_ty.abiSizeAdvanced(pt, .sema)).scalar };
3851 },3931 },
3852 else => unreachable,3932 else => unreachable,
3853 },3933 },
38543934
3855 .Many, .C => if (try elem_ty.comptimeOnlyAdvanced(zcu, .sema))3935 .Many, .C => if (try elem_ty.comptimeOnlyAdvanced(pt, .sema))
3856 .{ .elem_ptr = elem_ty }3936 .{ .elem_ptr = elem_ty }
3857 else3937 else
3858 .{ .offset = field_idx * (try elem_ty.abiSizeAdvanced(zcu, .sema)).scalar },3938 .{ .offset = field_idx * (try elem_ty.abiSizeAdvanced(pt, .sema)).scalar },
38593939
3860 .Slice => unreachable,3940 .Slice => unreachable,
3861 };3941 };
38623942
3863 switch (strat) {3943 switch (strat) {
3864 .offset => |byte_offset| {3944 .offset => |byte_offset| {
3865 return parent_ptr.getOffsetPtr(byte_offset, result_ty, zcu);3945 return parent_ptr.getOffsetPtr(byte_offset, result_ty, pt);
3866 },3946 },
3867 .elem_ptr => |manyptr_elem_ty| if (field_idx == 0) {3947 .elem_ptr => |manyptr_elem_ty| if (field_idx == 0) {
3868 return zcu.getCoerced(parent_ptr, result_ty);3948 return pt.getCoerced(parent_ptr, result_ty);
3869 } else {3949 } else {
3870 const arr_base_ty, const arr_base_len = manyptr_elem_ty.arrayBase(zcu);3950 const arr_base_ty, const arr_base_len = manyptr_elem_ty.arrayBase(zcu);
3871 const base_idx = arr_base_len * field_idx;3951 const base_idx = arr_base_len * field_idx;
...@@ -3875,7 +3955,7 @@ pub fn ptrElem(orig_parent_ptr: Value, field_idx: u64, zcu: *Zcu) !Value {...@@ -3875,7 +3955,7 @@ pub fn ptrElem(orig_parent_ptr: Value, field_idx: u64, zcu: *Zcu) !Value {
3875 if (Value.fromInterned(arr_elem.base).typeOf(zcu).childType(zcu).toIntern() == arr_base_ty.toIntern()) {3955 if (Value.fromInterned(arr_elem.base).typeOf(zcu).childType(zcu).toIntern() == arr_base_ty.toIntern()) {
3876 // We already have a pointer to an element of an array of this type.3956 // We already have a pointer to an element of an array of this type.
3877 // Just modify the index.3957 // Just modify the index.
3878 return Value.fromInterned(try zcu.intern(.{ .ptr = ptr: {3958 return Value.fromInterned(try pt.intern(.{ .ptr = ptr: {
3879 var new = parent_info;3959 var new = parent_info;
3880 new.base_addr.arr_elem.index += base_idx;3960 new.base_addr.arr_elem.index += base_idx;
3881 new.ty = result_ty.toIntern();3961 new.ty = result_ty.toIntern();
...@@ -3885,8 +3965,8 @@ pub fn ptrElem(orig_parent_ptr: Value, field_idx: u64, zcu: *Zcu) !Value {...@@ -3885,8 +3965,8 @@ pub fn ptrElem(orig_parent_ptr: Value, field_idx: u64, zcu: *Zcu) !Value {
3885 },3965 },
3886 else => {},3966 else => {},
3887 }3967 }
3888 const base_ptr = try parent_ptr.canonicalizeBasePtr(.Many, arr_base_ty, zcu);3968 const base_ptr = try parent_ptr.canonicalizeBasePtr(.Many, arr_base_ty, pt);
3889 return Value.fromInterned(try zcu.intern(.{ .ptr = .{3969 return Value.fromInterned(try pt.intern(.{ .ptr = .{
3890 .ty = result_ty.toIntern(),3970 .ty = result_ty.toIntern(),
3891 .base_addr = .{ .arr_elem = .{3971 .base_addr = .{ .arr_elem = .{
3892 .base = base_ptr.toIntern(),3972 .base = base_ptr.toIntern(),
...@@ -3898,9 +3978,9 @@ pub fn ptrElem(orig_parent_ptr: Value, field_idx: u64, zcu: *Zcu) !Value {...@@ -3898,9 +3978,9 @@ pub fn ptrElem(orig_parent_ptr: Value, field_idx: u64, zcu: *Zcu) !Value {
3898 }3978 }
3899}3979}
39003980
3901fn canonicalizeBasePtr(base_ptr: Value, want_size: std.builtin.Type.Pointer.Size, want_child: Type, zcu: *Zcu) !Value {3981fn canonicalizeBasePtr(base_ptr: Value, want_size: std.builtin.Type.Pointer.Size, want_child: Type, pt: Zcu.PerThread) !Value {
3902 const ptr_ty = base_ptr.typeOf(zcu);3982 const ptr_ty = base_ptr.typeOf(pt.zcu);
3903 const ptr_info = ptr_ty.ptrInfo(zcu);3983 const ptr_info = ptr_ty.ptrInfo(pt.zcu);
39043984
3905 if (ptr_info.flags.size == want_size and3985 if (ptr_info.flags.size == want_size and
3906 ptr_info.child == want_child.toIntern() and3986 ptr_info.child == want_child.toIntern() and
...@@ -3914,7 +3994,7 @@ fn canonicalizeBasePtr(base_ptr: Value, want_size: std.builtin.Type.Pointer.Size...@@ -3914,7 +3994,7 @@ fn canonicalizeBasePtr(base_ptr: Value, want_size: std.builtin.Type.Pointer.Size
3914 return base_ptr;3994 return base_ptr;
3915 }3995 }
39163996
3917 const new_ty = try zcu.ptrType(.{3997 const new_ty = try pt.ptrType(.{
3918 .child = want_child.toIntern(),3998 .child = want_child.toIntern(),
3919 .sentinel = .none,3999 .sentinel = .none,
3920 .flags = .{4000 .flags = .{
...@@ -3926,15 +4006,15 @@ fn canonicalizeBasePtr(base_ptr: Value, want_size: std.builtin.Type.Pointer.Size...@@ -3926,15 +4006,15 @@ fn canonicalizeBasePtr(base_ptr: Value, want_size: std.builtin.Type.Pointer.Size
3926 .address_space = ptr_info.flags.address_space,4006 .address_space = ptr_info.flags.address_space,
3927 },4007 },
3928 });4008 });
3929 return zcu.getCoerced(base_ptr, new_ty);4009 return pt.getCoerced(base_ptr, new_ty);
3930}4010}
39314011
3932pub fn getOffsetPtr(ptr_val: Value, byte_off: u64, new_ty: Type, zcu: *Zcu) !Value {4012pub fn getOffsetPtr(ptr_val: Value, byte_off: u64, new_ty: Type, pt: Zcu.PerThread) !Value {
3933 if (ptr_val.isUndef(zcu)) return ptr_val;4013 if (ptr_val.isUndef(pt.zcu)) return ptr_val;
3934 var ptr = zcu.intern_pool.indexToKey(ptr_val.toIntern()).ptr;4014 var ptr = pt.zcu.intern_pool.indexToKey(ptr_val.toIntern()).ptr;
3935 ptr.ty = new_ty.toIntern();4015 ptr.ty = new_ty.toIntern();
3936 ptr.byte_offset += byte_off;4016 ptr.byte_offset += byte_off;
3937 return Value.fromInterned(try zcu.intern(.{ .ptr = ptr }));4017 return Value.fromInterned(try pt.intern(.{ .ptr = ptr }));
3938}4018}
39394019
3940pub const PointerDeriveStep = union(enum) {4020pub const PointerDeriveStep = union(enum) {
...@@ -3977,21 +4057,21 @@ pub const PointerDeriveStep = union(enum) {...@@ -3977,21 +4057,21 @@ pub const PointerDeriveStep = union(enum) {
3977 new_ptr_ty: Type,4057 new_ptr_ty: Type,
3978 },4058 },
39794059
3980 pub fn ptrType(step: PointerDeriveStep, zcu: *Zcu) !Type {4060 pub fn ptrType(step: PointerDeriveStep, pt: Zcu.PerThread) !Type {
3981 return switch (step) {4061 return switch (step) {
3982 .int => |int| int.ptr_ty,4062 .int => |int| int.ptr_ty,
3983 .decl_ptr => |decl| try zcu.declPtr(decl).declPtrType(zcu),4063 .decl_ptr => |decl| try pt.zcu.declPtr(decl).declPtrType(pt),
3984 .anon_decl_ptr => |ad| Type.fromInterned(ad.orig_ty),4064 .anon_decl_ptr => |ad| Type.fromInterned(ad.orig_ty),
3985 .comptime_alloc_ptr => |info| info.ptr_ty,4065 .comptime_alloc_ptr => |info| info.ptr_ty,
3986 .comptime_field_ptr => |val| try zcu.singleConstPtrType(val.typeOf(zcu)),4066 .comptime_field_ptr => |val| try pt.singleConstPtrType(val.typeOf(pt.zcu)),
3987 .offset_and_cast => |oac| oac.new_ptr_ty,4067 .offset_and_cast => |oac| oac.new_ptr_ty,
3988 inline .eu_payload_ptr, .opt_payload_ptr, .field_ptr, .elem_ptr => |x| x.result_ptr_ty,4068 inline .eu_payload_ptr, .opt_payload_ptr, .field_ptr, .elem_ptr => |x| x.result_ptr_ty,
3989 };4069 };
3990 }4070 }
3991};4071};
39924072
3993pub fn pointerDerivation(ptr_val: Value, arena: Allocator, zcu: *Zcu) Allocator.Error!PointerDeriveStep {4073pub fn pointerDerivation(ptr_val: Value, arena: Allocator, pt: Zcu.PerThread) Allocator.Error!PointerDeriveStep {
3994 return ptr_val.pointerDerivationAdvanced(arena, zcu, null) catch |err| switch (err) {4074 return ptr_val.pointerDerivationAdvanced(arena, pt, null) catch |err| switch (err) {
3995 error.OutOfMemory => |e| return e,4075 error.OutOfMemory => |e| return e,
3996 error.AnalysisFail => unreachable,4076 error.AnalysisFail => unreachable,
3997 };4077 };
...@@ -4001,7 +4081,8 @@ pub fn pointerDerivation(ptr_val: Value, arena: Allocator, zcu: *Zcu) Allocator....@@ -4001,7 +4081,8 @@ pub fn pointerDerivation(ptr_val: Value, arena: Allocator, zcu: *Zcu) Allocator.
4001/// only field and element pointers with no casts. This can be used by codegen backends4081/// only field and element pointers with no casts. This can be used by codegen backends
4002/// which prefer field/elem accesses when lowering constant pointer values.4082/// which prefer field/elem accesses when lowering constant pointer values.
4003/// It is also used by the Value printing logic for pointers.4083/// It is also used by the Value printing logic for pointers.
4004pub fn pointerDerivationAdvanced(ptr_val: Value, arena: Allocator, zcu: *Zcu, opt_sema: ?*Sema) !PointerDeriveStep {4084pub fn pointerDerivationAdvanced(ptr_val: Value, arena: Allocator, pt: Zcu.PerThread, opt_sema: ?*Sema) !PointerDeriveStep {
4085 const zcu = pt.zcu;
4005 const ptr = zcu.intern_pool.indexToKey(ptr_val.toIntern()).ptr;4086 const ptr = zcu.intern_pool.indexToKey(ptr_val.toIntern()).ptr;
4006 const base_derive: PointerDeriveStep = switch (ptr.base_addr) {4087 const base_derive: PointerDeriveStep = switch (ptr.base_addr) {
4007 .int => return .{ .int = .{4088 .int => return .{ .int = .{
...@@ -4012,7 +4093,7 @@ pub fn pointerDerivationAdvanced(ptr_val: Value, arena: Allocator, zcu: *Zcu, op...@@ -4012,7 +4093,7 @@ pub fn pointerDerivationAdvanced(ptr_val: Value, arena: Allocator, zcu: *Zcu, op
4012 .anon_decl => |ad| base: {4093 .anon_decl => |ad| base: {
4013 // A slight tweak: `orig_ty` here is sometimes not `const`, but it ought to be.4094 // A slight tweak: `orig_ty` here is sometimes not `const`, but it ought to be.
4014 // TODO: fix this in the sites interning anon decls!4095 // TODO: fix this in the sites interning anon decls!
4015 const const_ty = try zcu.ptrType(info: {4096 const const_ty = try pt.ptrType(info: {
4016 var info = Type.fromInterned(ad.orig_ty).ptrInfo(zcu);4097 var info = Type.fromInterned(ad.orig_ty).ptrInfo(zcu);
4017 info.flags.is_const = true;4098 info.flags.is_const = true;
4018 break :info info;4099 break :info info;
...@@ -4024,11 +4105,11 @@ pub fn pointerDerivationAdvanced(ptr_val: Value, arena: Allocator, zcu: *Zcu, op...@@ -4024,11 +4105,11 @@ pub fn pointerDerivationAdvanced(ptr_val: Value, arena: Allocator, zcu: *Zcu, op
4024 },4105 },
4025 .comptime_alloc => |idx| base: {4106 .comptime_alloc => |idx| base: {
4026 const alloc = opt_sema.?.getComptimeAlloc(idx);4107 const alloc = opt_sema.?.getComptimeAlloc(idx);
4027 const val = try alloc.val.intern(zcu, opt_sema.?.arena);4108 const val = try alloc.val.intern(pt, opt_sema.?.arena);
4028 const ty = val.typeOf(zcu);4109 const ty = val.typeOf(zcu);
4029 break :base .{ .comptime_alloc_ptr = .{4110 break :base .{ .comptime_alloc_ptr = .{
4030 .val = val,4111 .val = val,
4031 .ptr_ty = try zcu.ptrType(.{4112 .ptr_ty = try pt.ptrType(.{
4032 .child = ty.toIntern(),4113 .child = ty.toIntern(),
4033 .flags = .{4114 .flags = .{
4034 .alignment = alloc.alignment,4115 .alignment = alloc.alignment,
...@@ -4041,20 +4122,20 @@ pub fn pointerDerivationAdvanced(ptr_val: Value, arena: Allocator, zcu: *Zcu, op...@@ -4041,20 +4122,20 @@ pub fn pointerDerivationAdvanced(ptr_val: Value, arena: Allocator, zcu: *Zcu, op
4041 const base_ptr = Value.fromInterned(eu_ptr);4122 const base_ptr = Value.fromInterned(eu_ptr);
4042 const base_ptr_ty = base_ptr.typeOf(zcu);4123 const base_ptr_ty = base_ptr.typeOf(zcu);
4043 const parent_step = try arena.create(PointerDeriveStep);4124 const parent_step = try arena.create(PointerDeriveStep);
4044 parent_step.* = try pointerDerivationAdvanced(Value.fromInterned(eu_ptr), arena, zcu, opt_sema);4125 parent_step.* = try pointerDerivationAdvanced(Value.fromInterned(eu_ptr), arena, pt, opt_sema);
4045 break :base .{ .eu_payload_ptr = .{4126 break :base .{ .eu_payload_ptr = .{
4046 .parent = parent_step,4127 .parent = parent_step,
4047 .result_ptr_ty = try zcu.adjustPtrTypeChild(base_ptr_ty, base_ptr_ty.childType(zcu).errorUnionPayload(zcu)),4128 .result_ptr_ty = try pt.adjustPtrTypeChild(base_ptr_ty, base_ptr_ty.childType(zcu).errorUnionPayload(zcu)),
4048 } };4129 } };
4049 },4130 },
4050 .opt_payload => |opt_ptr| base: {4131 .opt_payload => |opt_ptr| base: {
4051 const base_ptr = Value.fromInterned(opt_ptr);4132 const base_ptr = Value.fromInterned(opt_ptr);
4052 const base_ptr_ty = base_ptr.typeOf(zcu);4133 const base_ptr_ty = base_ptr.typeOf(zcu);
4053 const parent_step = try arena.create(PointerDeriveStep);4134 const parent_step = try arena.create(PointerDeriveStep);
4054 parent_step.* = try pointerDerivationAdvanced(Value.fromInterned(opt_ptr), arena, zcu, opt_sema);4135 parent_step.* = try pointerDerivationAdvanced(Value.fromInterned(opt_ptr), arena, pt, opt_sema);
4055 break :base .{ .opt_payload_ptr = .{4136 break :base .{ .opt_payload_ptr = .{
4056 .parent = parent_step,4137 .parent = parent_step,
4057 .result_ptr_ty = try zcu.adjustPtrTypeChild(base_ptr_ty, base_ptr_ty.childType(zcu).optionalChild(zcu)),4138 .result_ptr_ty = try pt.adjustPtrTypeChild(base_ptr_ty, base_ptr_ty.childType(zcu).optionalChild(zcu)),
4058 } };4139 } };
4059 },4140 },
4060 .field => |field| base: {4141 .field => |field| base: {
...@@ -4062,22 +4143,22 @@ pub fn pointerDerivationAdvanced(ptr_val: Value, arena: Allocator, zcu: *Zcu, op...@@ -4062,22 +4143,22 @@ pub fn pointerDerivationAdvanced(ptr_val: Value, arena: Allocator, zcu: *Zcu, op
4062 const base_ptr_ty = base_ptr.typeOf(zcu);4143 const base_ptr_ty = base_ptr.typeOf(zcu);
4063 const agg_ty = base_ptr_ty.childType(zcu);4144 const agg_ty = base_ptr_ty.childType(zcu);
4064 const field_ty, const field_align = switch (agg_ty.zigTypeTag(zcu)) {4145 const field_ty, const field_align = switch (agg_ty.zigTypeTag(zcu)) {
4065 .Struct => .{ agg_ty.structFieldType(@intCast(field.index), zcu), try agg_ty.structFieldAlignAdvanced(@intCast(field.index), zcu, .sema) },4146 .Struct => .{ agg_ty.structFieldType(@intCast(field.index), zcu), try agg_ty.structFieldAlignAdvanced(@intCast(field.index), pt, .sema) },
4066 .Union => .{ agg_ty.unionFieldTypeByIndex(@intCast(field.index), zcu), try agg_ty.structFieldAlignAdvanced(@intCast(field.index), zcu, .sema) },4147 .Union => .{ agg_ty.unionFieldTypeByIndex(@intCast(field.index), zcu), try agg_ty.structFieldAlignAdvanced(@intCast(field.index), pt, .sema) },
4067 .Pointer => .{ switch (field.index) {4148 .Pointer => .{ switch (field.index) {
4068 Value.slice_ptr_index => agg_ty.slicePtrFieldType(zcu),4149 Value.slice_ptr_index => agg_ty.slicePtrFieldType(zcu),
4069 Value.slice_len_index => Type.usize,4150 Value.slice_len_index => Type.usize,
4070 else => unreachable,4151 else => unreachable,
4071 }, Type.usize.abiAlignment(zcu) },4152 }, Type.usize.abiAlignment(pt) },
4072 else => unreachable,4153 else => unreachable,
4073 };4154 };
4074 const base_align = base_ptr_ty.ptrAlignment(zcu);4155 const base_align = base_ptr_ty.ptrAlignment(pt);
4075 const result_align = field_align.minStrict(base_align);4156 const result_align = field_align.minStrict(base_align);
4076 const result_ty = try zcu.ptrType(.{4157 const result_ty = try pt.ptrType(.{
4077 .child = field_ty.toIntern(),4158 .child = field_ty.toIntern(),
4078 .flags = flags: {4159 .flags = flags: {
4079 var flags = base_ptr_ty.ptrInfo(zcu).flags;4160 var flags = base_ptr_ty.ptrInfo(zcu).flags;
4080 if (result_align == field_ty.abiAlignment(zcu)) {4161 if (result_align == field_ty.abiAlignment(pt)) {
4081 flags.alignment = .none;4162 flags.alignment = .none;
4082 } else {4163 } else {
4083 flags.alignment = result_align;4164 flags.alignment = result_align;
...@@ -4086,7 +4167,7 @@ pub fn pointerDerivationAdvanced(ptr_val: Value, arena: Allocator, zcu: *Zcu, op...@@ -4086,7 +4167,7 @@ pub fn pointerDerivationAdvanced(ptr_val: Value, arena: Allocator, zcu: *Zcu, op
4086 },4167 },
4087 });4168 });
4088 const parent_step = try arena.create(PointerDeriveStep);4169 const parent_step = try arena.create(PointerDeriveStep);
4089 parent_step.* = try pointerDerivationAdvanced(base_ptr, arena, zcu, opt_sema);4170 parent_step.* = try pointerDerivationAdvanced(base_ptr, arena, pt, opt_sema);
4090 break :base .{ .field_ptr = .{4171 break :base .{ .field_ptr = .{
4091 .parent = parent_step,4172 .parent = parent_step,
4092 .field_idx = @intCast(field.index),4173 .field_idx = @intCast(field.index),
...@@ -4095,9 +4176,9 @@ pub fn pointerDerivationAdvanced(ptr_val: Value, arena: Allocator, zcu: *Zcu, op...@@ -4095,9 +4176,9 @@ pub fn pointerDerivationAdvanced(ptr_val: Value, arena: Allocator, zcu: *Zcu, op
4095 },4176 },
4096 .arr_elem => |arr_elem| base: {4177 .arr_elem => |arr_elem| base: {
4097 const parent_step = try arena.create(PointerDeriveStep);4178 const parent_step = try arena.create(PointerDeriveStep);
4098 parent_step.* = try pointerDerivationAdvanced(Value.fromInterned(arr_elem.base), arena, zcu, opt_sema);4179 parent_step.* = try pointerDerivationAdvanced(Value.fromInterned(arr_elem.base), arena, pt, opt_sema);
4099 const parent_ptr_info = (try parent_step.ptrType(zcu)).ptrInfo(zcu);4180 const parent_ptr_info = (try parent_step.ptrType(pt)).ptrInfo(zcu);
4100 const result_ptr_ty = try zcu.ptrType(.{4181 const result_ptr_ty = try pt.ptrType(.{
4101 .child = parent_ptr_info.child,4182 .child = parent_ptr_info.child,
4102 .flags = flags: {4183 .flags = flags: {
4103 var flags = parent_ptr_info.flags;4184 var flags = parent_ptr_info.flags;
...@@ -4113,12 +4194,12 @@ pub fn pointerDerivationAdvanced(ptr_val: Value, arena: Allocator, zcu: *Zcu, op...@@ -4113,12 +4194,12 @@ pub fn pointerDerivationAdvanced(ptr_val: Value, arena: Allocator, zcu: *Zcu, op
4113 },4194 },
4114 };4195 };
41154196
4116 if (ptr.byte_offset == 0 and ptr.ty == (try base_derive.ptrType(zcu)).toIntern()) {4197 if (ptr.byte_offset == 0 and ptr.ty == (try base_derive.ptrType(pt)).toIntern()) {
4117 return base_derive;4198 return base_derive;
4118 }4199 }
41194200
4120 const need_child = Type.fromInterned(ptr.ty).childType(zcu);4201 const need_child = Type.fromInterned(ptr.ty).childType(zcu);
4121 if (need_child.comptimeOnly(zcu)) {4202 if (need_child.comptimeOnly(pt)) {
4122 // No refinement can happen - this pointer is presumably invalid.4203 // No refinement can happen - this pointer is presumably invalid.
4123 // Just offset it.4204 // Just offset it.
4124 const parent = try arena.create(PointerDeriveStep);4205 const parent = try arena.create(PointerDeriveStep);
...@@ -4129,7 +4210,7 @@ pub fn pointerDerivationAdvanced(ptr_val: Value, arena: Allocator, zcu: *Zcu, op...@@ -4129,7 +4210,7 @@ pub fn pointerDerivationAdvanced(ptr_val: Value, arena: Allocator, zcu: *Zcu, op
4129 .new_ptr_ty = Type.fromInterned(ptr.ty),4210 .new_ptr_ty = Type.fromInterned(ptr.ty),
4130 } };4211 } };
4131 }4212 }
4132 const need_bytes = need_child.abiSize(zcu);4213 const need_bytes = need_child.abiSize(pt);
41334214
4134 var cur_derive = base_derive;4215 var cur_derive = base_derive;
4135 var cur_offset = ptr.byte_offset;4216 var cur_offset = ptr.byte_offset;
...@@ -4137,7 +4218,7 @@ pub fn pointerDerivationAdvanced(ptr_val: Value, arena: Allocator, zcu: *Zcu, op...@@ -4137,7 +4218,7 @@ pub fn pointerDerivationAdvanced(ptr_val: Value, arena: Allocator, zcu: *Zcu, op
4137 // Refine through fields and array elements as much as possible.4218 // Refine through fields and array elements as much as possible.
41384219
4139 if (need_bytes > 0) while (true) {4220 if (need_bytes > 0) while (true) {
4140 const cur_ty = (try cur_derive.ptrType(zcu)).childType(zcu);4221 const cur_ty = (try cur_derive.ptrType(pt)).childType(zcu);
4141 if (cur_ty.toIntern() == need_child.toIntern() and cur_offset == 0) {4222 if (cur_ty.toIntern() == need_child.toIntern() and cur_offset == 0) {
4142 break;4223 break;
4143 }4224 }
...@@ -4168,7 +4249,7 @@ pub fn pointerDerivationAdvanced(ptr_val: Value, arena: Allocator, zcu: *Zcu, op...@@ -4168,7 +4249,7 @@ pub fn pointerDerivationAdvanced(ptr_val: Value, arena: Allocator, zcu: *Zcu, op
41684249
4169 .Array => {4250 .Array => {
4170 const elem_ty = cur_ty.childType(zcu);4251 const elem_ty = cur_ty.childType(zcu);
4171 const elem_size = elem_ty.abiSize(zcu);4252 const elem_size = elem_ty.abiSize(pt);
4172 const start_idx = cur_offset / elem_size;4253 const start_idx = cur_offset / elem_size;
4173 const end_idx = (cur_offset + need_bytes + elem_size - 1) / elem_size;4254 const end_idx = (cur_offset + need_bytes + elem_size - 1) / elem_size;
4174 if (end_idx == start_idx + 1) {4255 if (end_idx == start_idx + 1) {
...@@ -4177,7 +4258,7 @@ pub fn pointerDerivationAdvanced(ptr_val: Value, arena: Allocator, zcu: *Zcu, op...@@ -4177,7 +4258,7 @@ pub fn pointerDerivationAdvanced(ptr_val: Value, arena: Allocator, zcu: *Zcu, op
4177 cur_derive = .{ .elem_ptr = .{4258 cur_derive = .{ .elem_ptr = .{
4178 .parent = parent,4259 .parent = parent,
4179 .elem_idx = start_idx,4260 .elem_idx = start_idx,
4180 .result_ptr_ty = try zcu.adjustPtrTypeChild(try parent.ptrType(zcu), elem_ty),4261 .result_ptr_ty = try pt.adjustPtrTypeChild(try parent.ptrType(pt), elem_ty),
4181 } };4262 } };
4182 cur_offset -= start_idx * elem_size;4263 cur_offset -= start_idx * elem_size;
4183 } else {4264 } else {
...@@ -4188,7 +4269,7 @@ pub fn pointerDerivationAdvanced(ptr_val: Value, arena: Allocator, zcu: *Zcu, op...@@ -4188,7 +4269,7 @@ pub fn pointerDerivationAdvanced(ptr_val: Value, arena: Allocator, zcu: *Zcu, op
4188 cur_derive = .{ .elem_ptr = .{4269 cur_derive = .{ .elem_ptr = .{
4189 .parent = parent,4270 .parent = parent,
4190 .elem_idx = start_idx,4271 .elem_idx = start_idx,
4191 .result_ptr_ty = try zcu.adjustPtrTypeChild(try parent.ptrType(zcu), elem_ty),4272 .result_ptr_ty = try pt.adjustPtrTypeChild(try parent.ptrType(pt), elem_ty),
4192 } };4273 } };
4193 cur_offset -= start_idx * elem_size;4274 cur_offset -= start_idx * elem_size;
4194 }4275 }
...@@ -4199,19 +4280,19 @@ pub fn pointerDerivationAdvanced(ptr_val: Value, arena: Allocator, zcu: *Zcu, op...@@ -4199,19 +4280,19 @@ pub fn pointerDerivationAdvanced(ptr_val: Value, arena: Allocator, zcu: *Zcu, op
4199 .auto, .@"packed" => break,4280 .auto, .@"packed" => break,
4200 .@"extern" => for (0..cur_ty.structFieldCount(zcu)) |field_idx| {4281 .@"extern" => for (0..cur_ty.structFieldCount(zcu)) |field_idx| {
4201 const field_ty = cur_ty.structFieldType(field_idx, zcu);4282 const field_ty = cur_ty.structFieldType(field_idx, zcu);
4202 const start_off = cur_ty.structFieldOffset(field_idx, zcu);4283 const start_off = cur_ty.structFieldOffset(field_idx, pt);
4203 const end_off = start_off + field_ty.abiSize(zcu);4284 const end_off = start_off + field_ty.abiSize(pt);
4204 if (cur_offset >= start_off and cur_offset + need_bytes <= end_off) {4285 if (cur_offset >= start_off and cur_offset + need_bytes <= end_off) {
4205 const old_ptr_ty = try cur_derive.ptrType(zcu);4286 const old_ptr_ty = try cur_derive.ptrType(pt);
4206 const parent_align = old_ptr_ty.ptrAlignment(zcu);4287 const parent_align = old_ptr_ty.ptrAlignment(pt);
4207 const field_align = InternPool.Alignment.fromLog2Units(@min(parent_align.toLog2Units(), @ctz(start_off)));4288 const field_align = InternPool.Alignment.fromLog2Units(@min(parent_align.toLog2Units(), @ctz(start_off)));
4208 const parent = try arena.create(PointerDeriveStep);4289 const parent = try arena.create(PointerDeriveStep);
4209 parent.* = cur_derive;4290 parent.* = cur_derive;
4210 const new_ptr_ty = try zcu.ptrType(.{4291 const new_ptr_ty = try pt.ptrType(.{
4211 .child = field_ty.toIntern(),4292 .child = field_ty.toIntern(),
4212 .flags = flags: {4293 .flags = flags: {
4213 var flags = old_ptr_ty.ptrInfo(zcu).flags;4294 var flags = old_ptr_ty.ptrInfo(zcu).flags;
4214 if (field_align == field_ty.abiAlignment(zcu)) {4295 if (field_align == field_ty.abiAlignment(pt)) {
4215 flags.alignment = .none;4296 flags.alignment = .none;
4216 } else {4297 } else {
4217 flags.alignment = field_align;4298 flags.alignment = field_align;
...@@ -4232,7 +4313,7 @@ pub fn pointerDerivationAdvanced(ptr_val: Value, arena: Allocator, zcu: *Zcu, op...@@ -4232,7 +4313,7 @@ pub fn pointerDerivationAdvanced(ptr_val: Value, arena: Allocator, zcu: *Zcu, op
4232 }4313 }
4233 };4314 };
42344315
4235 if (cur_offset == 0 and (try cur_derive.ptrType(zcu)).toIntern() == ptr.ty) {4316 if (cur_offset == 0 and (try cur_derive.ptrType(pt)).toIntern() == ptr.ty) {
4236 return cur_derive;4317 return cur_derive;
4237 }4318 }
42384319
...@@ -4245,20 +4326,20 @@ pub fn pointerDerivationAdvanced(ptr_val: Value, arena: Allocator, zcu: *Zcu, op...@@ -4245,20 +4326,20 @@ pub fn pointerDerivationAdvanced(ptr_val: Value, arena: Allocator, zcu: *Zcu, op
4245 } };4326 } };
4246}4327}
42474328
4248pub fn resolveLazy(val: Value, arena: Allocator, zcu: *Zcu) Zcu.SemaError!Value {4329pub fn resolveLazy(val: Value, arena: Allocator, pt: Zcu.PerThread) Zcu.SemaError!Value {
4249 switch (zcu.intern_pool.indexToKey(val.toIntern())) {4330 switch (pt.zcu.intern_pool.indexToKey(val.toIntern())) {
4250 .int => |int| switch (int.storage) {4331 .int => |int| switch (int.storage) {
4251 .u64, .i64, .big_int => return val,4332 .u64, .i64, .big_int => return val,
4252 .lazy_align, .lazy_size => return zcu.intValue(4333 .lazy_align, .lazy_size => return pt.intValue(
4253 Type.fromInterned(int.ty),4334 Type.fromInterned(int.ty),
4254 (try val.getUnsignedIntAdvanced(zcu, .sema)).?,4335 (try val.getUnsignedIntAdvanced(pt, .sema)).?,
4255 ),4336 ),
4256 },4337 },
4257 .slice => |slice| {4338 .slice => |slice| {
4258 const ptr = try Value.fromInterned(slice.ptr).resolveLazy(arena, zcu);4339 const ptr = try Value.fromInterned(slice.ptr).resolveLazy(arena, pt);
4259 const len = try Value.fromInterned(slice.len).resolveLazy(arena, zcu);4340 const len = try Value.fromInterned(slice.len).resolveLazy(arena, pt);
4260 if (ptr.toIntern() == slice.ptr and len.toIntern() == slice.len) return val;4341 if (ptr.toIntern() == slice.ptr and len.toIntern() == slice.len) return val;
4261 return Value.fromInterned(try zcu.intern(.{ .slice = .{4342 return Value.fromInterned(try pt.intern(.{ .slice = .{
4262 .ty = slice.ty,4343 .ty = slice.ty,
4263 .ptr = ptr.toIntern(),4344 .ptr = ptr.toIntern(),
4264 .len = len.toIntern(),4345 .len = len.toIntern(),
...@@ -4268,22 +4349,22 @@ pub fn resolveLazy(val: Value, arena: Allocator, zcu: *Zcu) Zcu.SemaError!Value...@@ -4268,22 +4349,22 @@ pub fn resolveLazy(val: Value, arena: Allocator, zcu: *Zcu) Zcu.SemaError!Value
4268 switch (ptr.base_addr) {4349 switch (ptr.base_addr) {
4269 .decl, .comptime_alloc, .anon_decl, .int => return val,4350 .decl, .comptime_alloc, .anon_decl, .int => return val,
4270 .comptime_field => |field_val| {4351 .comptime_field => |field_val| {
4271 const resolved_field_val = (try Value.fromInterned(field_val).resolveLazy(arena, zcu)).toIntern();4352 const resolved_field_val = (try Value.fromInterned(field_val).resolveLazy(arena, pt)).toIntern();
4272 return if (resolved_field_val == field_val)4353 return if (resolved_field_val == field_val)
4273 val4354 val
4274 else4355 else
4275 Value.fromInterned((try zcu.intern(.{ .ptr = .{4356 Value.fromInterned(try pt.intern(.{ .ptr = .{
4276 .ty = ptr.ty,4357 .ty = ptr.ty,
4277 .base_addr = .{ .comptime_field = resolved_field_val },4358 .base_addr = .{ .comptime_field = resolved_field_val },
4278 .byte_offset = ptr.byte_offset,4359 .byte_offset = ptr.byte_offset,
4279 } })));4360 } }));
4280 },4361 },
4281 .eu_payload, .opt_payload => |base| {4362 .eu_payload, .opt_payload => |base| {
4282 const resolved_base = (try Value.fromInterned(base).resolveLazy(arena, zcu)).toIntern();4363 const resolved_base = (try Value.fromInterned(base).resolveLazy(arena, pt)).toIntern();
4283 return if (resolved_base == base)4364 return if (resolved_base == base)
4284 val4365 val
4285 else4366 else
4286 Value.fromInterned((try zcu.intern(.{ .ptr = .{4367 Value.fromInterned(try pt.intern(.{ .ptr = .{
4287 .ty = ptr.ty,4368 .ty = ptr.ty,
4288 .base_addr = switch (ptr.base_addr) {4369 .base_addr = switch (ptr.base_addr) {
4289 .eu_payload => .{ .eu_payload = resolved_base },4370 .eu_payload => .{ .eu_payload = resolved_base },
...@@ -4291,14 +4372,14 @@ pub fn resolveLazy(val: Value, arena: Allocator, zcu: *Zcu) Zcu.SemaError!Value...@@ -4291,14 +4372,14 @@ pub fn resolveLazy(val: Value, arena: Allocator, zcu: *Zcu) Zcu.SemaError!Value
4291 else => unreachable,4372 else => unreachable,
4292 },4373 },
4293 .byte_offset = ptr.byte_offset,4374 .byte_offset = ptr.byte_offset,
4294 } })));4375 } }));
4295 },4376 },
4296 .arr_elem, .field => |base_index| {4377 .arr_elem, .field => |base_index| {
4297 const resolved_base = (try Value.fromInterned(base_index.base).resolveLazy(arena, zcu)).toIntern();4378 const resolved_base = (try Value.fromInterned(base_index.base).resolveLazy(arena, pt)).toIntern();
4298 return if (resolved_base == base_index.base)4379 return if (resolved_base == base_index.base)
4299 val4380 val
4300 else4381 else
4301 Value.fromInterned((try zcu.intern(.{ .ptr = .{4382 Value.fromInterned(try pt.intern(.{ .ptr = .{
4302 .ty = ptr.ty,4383 .ty = ptr.ty,
4303 .base_addr = switch (ptr.base_addr) {4384 .base_addr = switch (ptr.base_addr) {
4304 .arr_elem => .{ .arr_elem = .{4385 .arr_elem => .{ .arr_elem = .{
...@@ -4312,7 +4393,7 @@ pub fn resolveLazy(val: Value, arena: Allocator, zcu: *Zcu) Zcu.SemaError!Value...@@ -4312,7 +4393,7 @@ pub fn resolveLazy(val: Value, arena: Allocator, zcu: *Zcu) Zcu.SemaError!Value
4312 else => unreachable,4393 else => unreachable,
4313 },4394 },
4314 .byte_offset = ptr.byte_offset,4395 .byte_offset = ptr.byte_offset,
4315 } })));4396 } }));
4316 },4397 },
4317 }4398 }
4318 },4399 },
...@@ -4321,40 +4402,40 @@ pub fn resolveLazy(val: Value, arena: Allocator, zcu: *Zcu) Zcu.SemaError!Value...@@ -4321,40 +4402,40 @@ pub fn resolveLazy(val: Value, arena: Allocator, zcu: *Zcu) Zcu.SemaError!Value
4321 .elems => |elems| {4402 .elems => |elems| {
4322 var resolved_elems: []InternPool.Index = &.{};4403 var resolved_elems: []InternPool.Index = &.{};
4323 for (elems, 0..) |elem, i| {4404 for (elems, 0..) |elem, i| {
4324 const resolved_elem = (try Value.fromInterned(elem).resolveLazy(arena, zcu)).toIntern();4405 const resolved_elem = (try Value.fromInterned(elem).resolveLazy(arena, pt)).toIntern();
4325 if (resolved_elems.len == 0 and resolved_elem != elem) {4406 if (resolved_elems.len == 0 and resolved_elem != elem) {
4326 resolved_elems = try arena.alloc(InternPool.Index, elems.len);4407 resolved_elems = try arena.alloc(InternPool.Index, elems.len);
4327 @memcpy(resolved_elems[0..i], elems[0..i]);4408 @memcpy(resolved_elems[0..i], elems[0..i]);
4328 }4409 }
4329 if (resolved_elems.len > 0) resolved_elems[i] = resolved_elem;4410 if (resolved_elems.len > 0) resolved_elems[i] = resolved_elem;
4330 }4411 }
4331 return if (resolved_elems.len == 0) val else Value.fromInterned((try zcu.intern(.{ .aggregate = .{4412 return if (resolved_elems.len == 0) val else Value.fromInterned(try pt.intern(.{ .aggregate = .{
4332 .ty = aggregate.ty,4413 .ty = aggregate.ty,
4333 .storage = .{ .elems = resolved_elems },4414 .storage = .{ .elems = resolved_elems },
4334 } })));4415 } }));
4335 },4416 },
4336 .repeated_elem => |elem| {4417 .repeated_elem => |elem| {
4337 const resolved_elem = (try Value.fromInterned(elem).resolveLazy(arena, zcu)).toIntern();4418 const resolved_elem = (try Value.fromInterned(elem).resolveLazy(arena, pt)).toIntern();
4338 return if (resolved_elem == elem) val else Value.fromInterned((try zcu.intern(.{ .aggregate = .{4419 return if (resolved_elem == elem) val else Value.fromInterned(try pt.intern(.{ .aggregate = .{
4339 .ty = aggregate.ty,4420 .ty = aggregate.ty,
4340 .storage = .{ .repeated_elem = resolved_elem },4421 .storage = .{ .repeated_elem = resolved_elem },
4341 } })));4422 } }));
4342 },4423 },
4343 },4424 },
4344 .un => |un| {4425 .un => |un| {
4345 const resolved_tag = if (un.tag == .none)4426 const resolved_tag = if (un.tag == .none)
4346 .none4427 .none
4347 else4428 else
4348 (try Value.fromInterned(un.tag).resolveLazy(arena, zcu)).toIntern();4429 (try Value.fromInterned(un.tag).resolveLazy(arena, pt)).toIntern();
4349 const resolved_val = (try Value.fromInterned(un.val).resolveLazy(arena, zcu)).toIntern();4430 const resolved_val = (try Value.fromInterned(un.val).resolveLazy(arena, pt)).toIntern();
4350 return if (resolved_tag == un.tag and resolved_val == un.val)4431 return if (resolved_tag == un.tag and resolved_val == un.val)
4351 val4432 val
4352 else4433 else
4353 Value.fromInterned((try zcu.intern(.{ .un = .{4434 Value.fromInterned(try pt.intern(.{ .un = .{
4354 .ty = un.ty,4435 .ty = un.ty,
4355 .tag = resolved_tag,4436 .tag = resolved_tag,
4356 .val = resolved_val,4437 .val = resolved_val,
4357 } })));4438 } }));
4358 },4439 },
4359 else => return val,4440 else => return val,
4360 }4441 }
src/Zcu.zig+129-2875
...@@ -6,7 +6,6 @@ const std = @import("std");...@@ -6,7 +6,6 @@ const std = @import("std");
6const builtin = @import("builtin");6const builtin = @import("builtin");
7const mem = std.mem;7const mem = std.mem;
8const Allocator = std.mem.Allocator;8const Allocator = std.mem.Allocator;
9const ArrayListUnmanaged = std.ArrayListUnmanaged;
10const assert = std.debug.assert;9const assert = std.debug.assert;
11const log = std.log.scoped(.module);10const log = std.log.scoped(.module);
12const BigIntConst = std.math.big.int.Const;11const BigIntConst = std.math.big.int.Const;
...@@ -65,8 +64,8 @@ root_mod: *Package.Module,...@@ -65,8 +64,8 @@ root_mod: *Package.Module,
65/// `root_mod` is the test runner, and `main_mod` is the user's source file which has the tests.64/// `root_mod` is the test runner, and `main_mod` is the user's source file which has the tests.
66main_mod: *Package.Module,65main_mod: *Package.Module,
67std_mod: *Package.Module,66std_mod: *Package.Module,
68sema_prog_node: std.Progress.Node = undefined,67sema_prog_node: std.Progress.Node = std.Progress.Node.none,
69codegen_prog_node: std.Progress.Node = undefined,68codegen_prog_node: std.Progress.Node = std.Progress.Node.none,
7069
71/// Used by AstGen worker to load and store ZIR cache.70/// Used by AstGen worker to load and store ZIR cache.
72global_zir_cache: Compilation.Directory,71global_zir_cache: Compilation.Directory,
...@@ -75,10 +74,10 @@ local_zir_cache: Compilation.Directory,...@@ -75,10 +74,10 @@ local_zir_cache: Compilation.Directory,
7574
76/// This is where all `Export` values are stored. Not all values here are necessarily valid exports;75/// This is where all `Export` values are stored. Not all values here are necessarily valid exports;
77/// to enumerate all exports, `single_exports` and `multi_exports` must be consulted.76/// to enumerate all exports, `single_exports` and `multi_exports` must be consulted.
78all_exports: ArrayListUnmanaged(Export) = .{},77all_exports: std.ArrayListUnmanaged(Export) = .{},
79/// This is a list of free indices in `all_exports`. These indices may be reused by exports from78/// This is a list of free indices in `all_exports`. These indices may be reused by exports from
80/// future semantic analysis.79/// future semantic analysis.
81free_exports: ArrayListUnmanaged(u32) = .{},80free_exports: std.ArrayListUnmanaged(u32) = .{},
82/// Maps from an `AnalUnit` which performs a single export, to the index into `all_exports` of81/// Maps from an `AnalUnit` which performs a single export, to the index into `all_exports` of
83/// the export it performs. Note that the key is not the `Decl` being exported, but the `AnalUnit`82/// the export it performs. Note that the key is not the `Decl` being exported, but the `AnalUnit`
84/// whose analysis triggered the export.83/// whose analysis triggered the export.
...@@ -179,7 +178,7 @@ stage1_flags: packed struct {...@@ -179,7 +178,7 @@ stage1_flags: packed struct {
179 reserved: u2 = 0,178 reserved: u2 = 0,
180} = .{},179} = .{},
181180
182compile_log_text: ArrayListUnmanaged(u8) = .{},181compile_log_text: std.ArrayListUnmanaged(u8) = .{},
183182
184emit_h: ?*GlobalEmitH,183emit_h: ?*GlobalEmitH,
185184
...@@ -203,6 +202,8 @@ panic_messages: [PanicId.len]Decl.OptionalIndex = .{.none} ** PanicId.len,...@@ -203,6 +202,8 @@ panic_messages: [PanicId.len]Decl.OptionalIndex = .{.none} ** PanicId.len,
203panic_func_index: InternPool.Index = .none,202panic_func_index: InternPool.Index = .none,
204null_stack_trace: InternPool.Index = .none,203null_stack_trace: InternPool.Index = .none,
205204
205pub const PerThread = @import("Zcu/PerThread.zig");
206
206pub const PanicId = enum {207pub const PanicId = enum {
207 unreach,208 unreach,
208 unwrap_null,209 unwrap_null,
...@@ -419,11 +420,11 @@ pub const Decl = struct {...@@ -419,11 +420,11 @@ pub const Decl = struct {
419 return zcu.namespacePtr(decl.src_namespace).renderFullyQualifiedDebugName(zcu, decl.name, writer);420 return zcu.namespacePtr(decl.src_namespace).renderFullyQualifiedDebugName(zcu, decl.name, writer);
420 }421 }
421422
422 pub fn fullyQualifiedName(decl: Decl, zcu: *Zcu) !InternPool.NullTerminatedString {423 pub fn fullyQualifiedName(decl: Decl, pt: Zcu.PerThread) !InternPool.NullTerminatedString {
423 return if (decl.name_fully_qualified)424 return if (decl.name_fully_qualified)
424 decl.name425 decl.name
425 else426 else
426 zcu.namespacePtr(decl.src_namespace).fullyQualifiedName(zcu, decl.name);427 pt.zcu.namespacePtr(decl.src_namespace).fullyQualifiedName(pt, decl.name);
427 }428 }
428429
429 pub fn typeOf(decl: Decl, zcu: *const Zcu) Type {430 pub fn typeOf(decl: Decl, zcu: *const Zcu) Type {
...@@ -519,24 +520,24 @@ pub const Decl = struct {...@@ -519,24 +520,24 @@ pub const Decl = struct {
519 return decl.getExternDecl(zcu) != .none;520 return decl.getExternDecl(zcu) != .none;
520 }521 }
521522
522 pub fn getAlignment(decl: Decl, zcu: *Zcu) Alignment {523 pub fn getAlignment(decl: Decl, pt: Zcu.PerThread) Alignment {
523 assert(decl.has_tv);524 assert(decl.has_tv);
524 if (decl.alignment != .none) return decl.alignment;525 if (decl.alignment != .none) return decl.alignment;
525 return decl.typeOf(zcu).abiAlignment(zcu);526 return decl.typeOf(pt.zcu).abiAlignment(pt);
526 }527 }
527528
528 pub fn declPtrType(decl: Decl, zcu: *Zcu) !Type {529 pub fn declPtrType(decl: Decl, pt: Zcu.PerThread) !Type {
529 assert(decl.has_tv);530 assert(decl.has_tv);
530 const decl_ty = decl.typeOf(zcu);531 const decl_ty = decl.typeOf(pt.zcu);
531 return zcu.ptrType(.{532 return pt.ptrType(.{
532 .child = decl_ty.toIntern(),533 .child = decl_ty.toIntern(),
533 .flags = .{534 .flags = .{
534 .alignment = if (decl.alignment == decl_ty.abiAlignment(zcu))535 .alignment = if (decl.alignment == decl_ty.abiAlignment(pt))
535 .none536 .none
536 else537 else
537 decl.alignment,538 decl.alignment,
538 .address_space = decl.@"addrspace",539 .address_space = decl.@"addrspace",
539 .is_const = decl.getOwnedVariable(zcu) == null,540 .is_const = decl.getOwnedVariable(pt.zcu) == null,
540 },541 },
541 });542 });
542 }543 }
...@@ -589,7 +590,7 @@ pub const Decl = struct {...@@ -589,7 +590,7 @@ pub const Decl = struct {
589590
590/// This state is attached to every Decl when Module emit_h is non-null.591/// This state is attached to every Decl when Module emit_h is non-null.
591pub const EmitH = struct {592pub const EmitH = struct {
592 fwd_decl: ArrayListUnmanaged(u8) = .{},593 fwd_decl: std.ArrayListUnmanaged(u8) = .{},
593};594};
594595
595pub const DeclAdapter = struct {596pub const DeclAdapter = struct {
...@@ -622,8 +623,8 @@ pub const Namespace = struct {...@@ -622,8 +623,8 @@ pub const Namespace = struct {
622 /// Value is whether the usingnamespace decl is marked `pub`.623 /// Value is whether the usingnamespace decl is marked `pub`.
623 usingnamespace_set: std.AutoHashMapUnmanaged(Decl.Index, bool) = .{},624 usingnamespace_set: std.AutoHashMapUnmanaged(Decl.Index, bool) = .{},
624625
625 const Index = InternPool.NamespaceIndex;626 pub const Index = InternPool.NamespaceIndex;
626 const OptionalIndex = InternPool.OptionalNamespaceIndex;627 pub const OptionalIndex = InternPool.OptionalNamespaceIndex;
627628
628 const DeclContext = struct {629 const DeclContext = struct {
629 zcu: *Zcu,630 zcu: *Zcu,
...@@ -687,42 +688,44 @@ pub const Namespace = struct {...@@ -687,42 +688,44 @@ pub const Namespace = struct {
687688
688 pub fn fullyQualifiedName(689 pub fn fullyQualifiedName(
689 ns: Namespace,690 ns: Namespace,
690 zcu: *Zcu,691 pt: Zcu.PerThread,
691 name: InternPool.NullTerminatedString,692 name: InternPool.NullTerminatedString,
692 ) !InternPool.NullTerminatedString {693 ) !InternPool.NullTerminatedString {
694 const zcu = pt.zcu;
693 const ip = &zcu.intern_pool;695 const ip = &zcu.intern_pool;
694 const count = count: {696
697 const gpa = zcu.gpa;
698 const strings = ip.getLocal(pt.tid).getMutableStrings(gpa);
699 // Protects reads of interned strings from being reallocated during the call to
700 // renderFullyQualifiedName.
701 const slice = try strings.addManyAsSlice(count: {
695 var count: usize = name.length(ip) + 1;702 var count: usize = name.length(ip) + 1;
696 var cur_ns = &ns;703 var cur_ns = &ns;
697 while (true) {704 while (true) {
698 const decl = zcu.declPtr(cur_ns.decl_index);705 const decl = zcu.declPtr(cur_ns.decl_index);
699 count += decl.name.length(ip) + 1;
700 cur_ns = zcu.namespacePtr(cur_ns.parent.unwrap() orelse {706 cur_ns = zcu.namespacePtr(cur_ns.parent.unwrap() orelse {
701 count += ns.fileScope(zcu).sub_file_path.len;707 count += ns.fileScope(zcu).fullyQualifiedNameLen();
702 break :count count;708 break :count count;
703 });709 });
710 count += decl.name.length(ip) + 1;
704 }711 }
705 };712 });
706713 var fbs = std.io.fixedBufferStream(slice[0]);
707 const gpa = zcu.gpa;714 ns.renderFullyQualifiedName(zcu, name, fbs.writer()) catch unreachable;
708 const start = ip.string_bytes.items.len;715 assert(fbs.pos == slice[0].len);
709 // Protects reads of interned strings from being reallocated during the call to
710 // renderFullyQualifiedName.
711 try ip.string_bytes.ensureUnusedCapacity(gpa, count);
712 ns.renderFullyQualifiedName(zcu, name, ip.string_bytes.writer(gpa)) catch unreachable;
713716
714 // Sanitize the name for nvptx which is more restrictive.717 // Sanitize the name for nvptx which is more restrictive.
715 // TODO This should be handled by the backend, not the frontend. Have a718 // TODO This should be handled by the backend, not the frontend. Have a
716 // look at how the C backend does it for inspiration.719 // look at how the C backend does it for inspiration.
717 const cpu_arch = zcu.root_mod.resolved_target.result.cpu.arch;720 const cpu_arch = zcu.root_mod.resolved_target.result.cpu.arch;
718 if (cpu_arch.isNvptx()) {721 if (cpu_arch.isNvptx()) {
719 for (ip.string_bytes.items[start..]) |*byte| switch (byte.*) {722 for (slice[0]) |*byte| switch (byte.*) {
720 '{', '}', '*', '[', ']', '(', ')', ',', ' ', '\'' => byte.* = '_',723 '{', '}', '*', '[', ']', '(', ')', ',', ' ', '\'' => byte.* = '_',
721 else => {},724 else => {},
722 };725 };
723 }726 }
724727
725 return ip.getOrPutTrailingString(gpa, ip.string_bytes.items.len - start, .no_embedded_nulls);728 return ip.getOrPutTrailingString(gpa, pt.tid, @intCast(slice[0].len), .no_embedded_nulls);
726 }729 }
727730
728 pub fn getType(ns: Namespace, zcu: *Zcu) Type {731 pub fn getType(ns: Namespace, zcu: *Zcu) Type {
...@@ -857,6 +860,11 @@ pub const File = struct {...@@ -857,6 +860,11 @@ pub const File = struct {
857 return &file.tree;860 return &file.tree;
858 }861 }
859862
863 pub fn fullyQualifiedNameLen(file: File) usize {
864 const ext = std.fs.path.extension(file.sub_file_path);
865 return file.sub_file_path.len - ext.len;
866 }
867
860 pub fn renderFullyQualifiedName(file: File, writer: anytype) !void {868 pub fn renderFullyQualifiedName(file: File, writer: anytype) !void {
861 // Convert all the slashes into dots and truncate the extension.869 // Convert all the slashes into dots and truncate the extension.
862 const ext = std.fs.path.extension(file.sub_file_path);870 const ext = std.fs.path.extension(file.sub_file_path);
...@@ -874,11 +882,15 @@ pub const File = struct {...@@ -874,11 +882,15 @@ pub const File = struct {
874 };882 };
875 }883 }
876884
877 pub fn fullyQualifiedName(file: File, mod: *Module) !InternPool.NullTerminatedString {885 pub fn fullyQualifiedName(file: File, pt: Zcu.PerThread) !InternPool.NullTerminatedString {
878 const ip = &mod.intern_pool;886 const gpa = pt.zcu.gpa;
879 const start = ip.string_bytes.items.len;887 const ip = &pt.zcu.intern_pool;
880 try file.renderFullyQualifiedName(ip.string_bytes.writer(mod.gpa));888 const strings = ip.getLocal(pt.tid).getMutableStrings(gpa);
881 return ip.getOrPutTrailingString(mod.gpa, ip.string_bytes.items.len - start, .no_embedded_nulls);889 const slice = try strings.addManyAsSlice(file.fullyQualifiedNameLen());
890 var fbs = std.io.fixedBufferStream(slice[0]);
891 file.renderFullyQualifiedName(fbs.writer()) catch unreachable;
892 assert(fbs.pos == slice[0].len);
893 return ip.getOrPutTrailingString(gpa, pt.tid, @intCast(slice[0].len), .no_embedded_nulls);
882 }894 }
883895
884 pub fn fullPath(file: File, ally: Allocator) ![]u8 {896 pub fn fullPath(file: File, ally: Allocator) ![]u8 {
...@@ -2391,9 +2403,9 @@ pub const CompileError = error{...@@ -2391,9 +2403,9 @@ pub const CompileError = error{
2391 ComptimeBreak,2403 ComptimeBreak,
2392};2404};
23932405
2394pub fn init(mod: *Module) !void {2406pub fn init(mod: *Module, thread_count: usize) !void {
2395 const gpa = mod.gpa;2407 const gpa = mod.gpa;
2396 try mod.intern_pool.init(gpa);2408 try mod.intern_pool.init(gpa, thread_count);
2397 try mod.global_error_set.put(gpa, .empty, {});2409 try mod.global_error_set.put(gpa, .empty, {});
2398}2410}
23992411
...@@ -2568,8 +2580,8 @@ pub fn declIsRoot(mod: *Module, decl_index: Decl.Index) bool {...@@ -2568,8 +2580,8 @@ pub fn declIsRoot(mod: *Module, decl_index: Decl.Index) bool {
2568}2580}
25692581
2570// TODO https://github.com/ziglang/zig/issues/86432582// TODO https://github.com/ziglang/zig/issues/8643
2571const data_has_safety_tag = @sizeOf(Zir.Inst.Data) != 8;2583pub const data_has_safety_tag = @sizeOf(Zir.Inst.Data) != 8;
2572const HackDataLayout = extern struct {2584pub const HackDataLayout = extern struct {
2573 data: [8]u8 align(@alignOf(Zir.Inst.Data)),2585 data: [8]u8 align(@alignOf(Zir.Inst.Data)),
2574 safety_tag: u8,2586 safety_tag: u8,
2575};2587};
...@@ -2579,291 +2591,11 @@ comptime {...@@ -2579,291 +2591,11 @@ comptime {
2579 }2591 }
2580}2592}
25812593
2582pub fn astGenFile(
2583 zcu: *Zcu,
2584 file: *File,
2585 /// This parameter is provided separately from `file` because it is not
2586 /// safe to access `import_table` without a lock, and this index is needed
2587 /// in the call to `updateZirRefs`.
2588 file_index: File.Index,
2589 path_digest: Cache.BinDigest,
2590 opt_root_decl: Zcu.Decl.OptionalIndex,
2591) !void {
2592 assert(!file.mod.isBuiltin());
2593
2594 const tracy = trace(@src());
2595 defer tracy.end();
2596
2597 const comp = zcu.comp;
2598 const gpa = zcu.gpa;
2599
2600 // In any case we need to examine the stat of the file to determine the course of action.
2601 var source_file = try file.mod.root.openFile(file.sub_file_path, .{});
2602 defer source_file.close();
2603
2604 const stat = try source_file.stat();
2605
2606 const want_local_cache = file.mod == zcu.main_mod;
2607 const hex_digest = Cache.binToHex(path_digest);
2608 const cache_directory = if (want_local_cache) zcu.local_zir_cache else zcu.global_zir_cache;
2609 const zir_dir = cache_directory.handle;
2610
2611 // Determine whether we need to reload the file from disk and redo parsing and AstGen.
2612 var lock: std.fs.File.Lock = switch (file.status) {
2613 .never_loaded, .retryable_failure => lock: {
2614 // First, load the cached ZIR code, if any.
2615 log.debug("AstGen checking cache: {s} (local={}, digest={s})", .{
2616 file.sub_file_path, want_local_cache, &hex_digest,
2617 });
2618
2619 break :lock .shared;
2620 },
2621 .parse_failure, .astgen_failure, .success_zir => lock: {
2622 const unchanged_metadata =
2623 stat.size == file.stat.size and
2624 stat.mtime == file.stat.mtime and
2625 stat.inode == file.stat.inode;
2626
2627 if (unchanged_metadata) {
2628 log.debug("unmodified metadata of file: {s}", .{file.sub_file_path});
2629 return;
2630 }
2631
2632 log.debug("metadata changed: {s}", .{file.sub_file_path});
2633
2634 break :lock .exclusive;
2635 },
2636 };
2637
2638 // We ask for a lock in order to coordinate with other zig processes.
2639 // If another process is already working on this file, we will get the cached
2640 // version. Likewise if we're working on AstGen and another process asks for
2641 // the cached file, they'll get it.
2642 const cache_file = while (true) {
2643 break zir_dir.createFile(&hex_digest, .{
2644 .read = true,
2645 .truncate = false,
2646 .lock = lock,
2647 }) catch |err| switch (err) {
2648 error.NotDir => unreachable, // no dir components
2649 error.InvalidUtf8 => unreachable, // it's a hex encoded name
2650 error.InvalidWtf8 => unreachable, // it's a hex encoded name
2651 error.BadPathName => unreachable, // it's a hex encoded name
2652 error.NameTooLong => unreachable, // it's a fixed size name
2653 error.PipeBusy => unreachable, // it's not a pipe
2654 error.WouldBlock => unreachable, // not asking for non-blocking I/O
2655 // There are no dir components, so you would think that this was
2656 // unreachable, however we have observed on macOS two processes racing
2657 // to do openat() with O_CREAT manifest in ENOENT.
2658 error.FileNotFound => continue,
2659
2660 else => |e| return e, // Retryable errors are handled at callsite.
2661 };
2662 };
2663 defer cache_file.close();
2664
2665 while (true) {
2666 update: {
2667 // First we read the header to determine the lengths of arrays.
2668 const header = cache_file.reader().readStruct(Zir.Header) catch |err| switch (err) {
2669 // This can happen if Zig bails out of this function between creating
2670 // the cached file and writing it.
2671 error.EndOfStream => break :update,
2672 else => |e| return e,
2673 };
2674 const unchanged_metadata =
2675 stat.size == header.stat_size and
2676 stat.mtime == header.stat_mtime and
2677 stat.inode == header.stat_inode;
2678
2679 if (!unchanged_metadata) {
2680 log.debug("AstGen cache stale: {s}", .{file.sub_file_path});
2681 break :update;
2682 }
2683 log.debug("AstGen cache hit: {s} instructions_len={d}", .{
2684 file.sub_file_path, header.instructions_len,
2685 });
2686
2687 file.zir = loadZirCacheBody(gpa, header, cache_file) catch |err| switch (err) {
2688 error.UnexpectedFileSize => {
2689 log.warn("unexpected EOF reading cached ZIR for {s}", .{file.sub_file_path});
2690 break :update;
2691 },
2692 else => |e| return e,
2693 };
2694 file.zir_loaded = true;
2695 file.stat = .{
2696 .size = header.stat_size,
2697 .inode = header.stat_inode,
2698 .mtime = header.stat_mtime,
2699 };
2700 file.status = .success_zir;
2701 log.debug("AstGen cached success: {s}", .{file.sub_file_path});
2702
2703 // TODO don't report compile errors until Sema @importFile
2704 if (file.zir.hasCompileErrors()) {
2705 {
2706 comp.mutex.lock();
2707 defer comp.mutex.unlock();
2708 try zcu.failed_files.putNoClobber(gpa, file, null);
2709 }
2710 file.status = .astgen_failure;
2711 return error.AnalysisFail;
2712 }
2713 return;
2714 }
2715
2716 // If we already have the exclusive lock then it is our job to update.
2717 if (builtin.os.tag == .wasi or lock == .exclusive) break;
2718 // Otherwise, unlock to give someone a chance to get the exclusive lock
2719 // and then upgrade to an exclusive lock.
2720 cache_file.unlock();
2721 lock = .exclusive;
2722 try cache_file.lock(lock);
2723 }
2724
2725 // The cache is definitely stale so delete the contents to avoid an underwrite later.
2726 cache_file.setEndPos(0) catch |err| switch (err) {
2727 error.FileTooBig => unreachable, // 0 is not too big
2728
2729 else => |e| return e,
2730 };
2731
2732 zcu.lockAndClearFileCompileError(file);
2733
2734 // If the previous ZIR does not have compile errors, keep it around
2735 // in case parsing or new ZIR fails. In case of successful ZIR update
2736 // at the end of this function we will free it.
2737 // We keep the previous ZIR loaded so that we can use it
2738 // for the update next time it does not have any compile errors. This avoids
2739 // needlessly tossing out semantic analysis work when an error is
2740 // temporarily introduced.
2741 if (file.zir_loaded and !file.zir.hasCompileErrors()) {
2742 assert(file.prev_zir == null);
2743 const prev_zir_ptr = try gpa.create(Zir);
2744 file.prev_zir = prev_zir_ptr;
2745 prev_zir_ptr.* = file.zir;
2746 file.zir = undefined;
2747 file.zir_loaded = false;
2748 }
2749 file.unload(gpa);
2750
2751 if (stat.size > std.math.maxInt(u32))
2752 return error.FileTooBig;
2753
2754 const source = try gpa.allocSentinel(u8, @as(usize, @intCast(stat.size)), 0);
2755 defer if (!file.source_loaded) gpa.free(source);
2756 const amt = try source_file.readAll(source);
2757 if (amt != stat.size)
2758 return error.UnexpectedEndOfFile;
2759
2760 file.stat = .{
2761 .size = stat.size,
2762 .inode = stat.inode,
2763 .mtime = stat.mtime,
2764 };
2765 file.source = source;
2766 file.source_loaded = true;
2767
2768 file.tree = try Ast.parse(gpa, source, .zig);
2769 file.tree_loaded = true;
2770
2771 // Any potential AST errors are converted to ZIR errors here.
2772 file.zir = try AstGen.generate(gpa, file.tree);
2773 file.zir_loaded = true;
2774 file.status = .success_zir;
2775 log.debug("AstGen fresh success: {s}", .{file.sub_file_path});
2776
2777 const safety_buffer = if (data_has_safety_tag)
2778 try gpa.alloc([8]u8, file.zir.instructions.len)
2779 else
2780 undefined;
2781 defer if (data_has_safety_tag) gpa.free(safety_buffer);
2782 const data_ptr = if (data_has_safety_tag)
2783 if (file.zir.instructions.len == 0)
2784 @as([*]const u8, undefined)
2785 else
2786 @as([*]const u8, @ptrCast(safety_buffer.ptr))
2787 else
2788 @as([*]const u8, @ptrCast(file.zir.instructions.items(.data).ptr));
2789 if (data_has_safety_tag) {
2790 // The `Data` union has a safety tag but in the file format we store it without.
2791 for (file.zir.instructions.items(.data), 0..) |*data, i| {
2792 const as_struct = @as(*const HackDataLayout, @ptrCast(data));
2793 safety_buffer[i] = as_struct.data;
2794 }
2795 }
2796
2797 const header: Zir.Header = .{
2798 .instructions_len = @as(u32, @intCast(file.zir.instructions.len)),
2799 .string_bytes_len = @as(u32, @intCast(file.zir.string_bytes.len)),
2800 .extra_len = @as(u32, @intCast(file.zir.extra.len)),
2801
2802 .stat_size = stat.size,
2803 .stat_inode = stat.inode,
2804 .stat_mtime = stat.mtime,
2805 };
2806 var iovecs = [_]std.posix.iovec_const{
2807 .{
2808 .base = @as([*]const u8, @ptrCast(&header)),
2809 .len = @sizeOf(Zir.Header),
2810 },
2811 .{
2812 .base = @as([*]const u8, @ptrCast(file.zir.instructions.items(.tag).ptr)),
2813 .len = file.zir.instructions.len,
2814 },
2815 .{
2816 .base = data_ptr,
2817 .len = file.zir.instructions.len * 8,
2818 },
2819 .{
2820 .base = file.zir.string_bytes.ptr,
2821 .len = file.zir.string_bytes.len,
2822 },
2823 .{
2824 .base = @as([*]const u8, @ptrCast(file.zir.extra.ptr)),
2825 .len = file.zir.extra.len * 4,
2826 },
2827 };
2828 cache_file.writevAll(&iovecs) catch |err| {
2829 log.warn("unable to write cached ZIR code for {}{s} to {}{s}: {s}", .{
2830 file.mod.root, file.sub_file_path, cache_directory, &hex_digest, @errorName(err),
2831 });
2832 };
2833
2834 if (file.zir.hasCompileErrors()) {
2835 {
2836 comp.mutex.lock();
2837 defer comp.mutex.unlock();
2838 try zcu.failed_files.putNoClobber(gpa, file, null);
2839 }
2840 file.status = .astgen_failure;
2841 return error.AnalysisFail;
2842 }
2843
2844 if (file.prev_zir) |prev_zir| {
2845 try updateZirRefs(zcu, file, file_index, prev_zir.*);
2846 // No need to keep previous ZIR.
2847 prev_zir.deinit(gpa);
2848 gpa.destroy(prev_zir);
2849 file.prev_zir = null;
2850 }
2851
2852 if (opt_root_decl.unwrap()) |root_decl| {
2853 // The root of this file must be re-analyzed, since the file has changed.
2854 comp.mutex.lock();
2855 defer comp.mutex.unlock();
2856
2857 log.debug("outdated root Decl: {}", .{root_decl});
2858 try zcu.outdated_file_root.put(gpa, root_decl, {});
2859 }
2860}
2861
2862pub fn loadZirCache(gpa: Allocator, cache_file: std.fs.File) !Zir {2594pub fn loadZirCache(gpa: Allocator, cache_file: std.fs.File) !Zir {
2863 return loadZirCacheBody(gpa, try cache_file.reader().readStruct(Zir.Header), cache_file);2595 return loadZirCacheBody(gpa, try cache_file.reader().readStruct(Zir.Header), cache_file);
2864}2596}
28652597
2866fn loadZirCacheBody(gpa: Allocator, header: Zir.Header, cache_file: std.fs.File) !Zir {2598pub fn loadZirCacheBody(gpa: Allocator, header: Zir.Header, cache_file: std.fs.File) !Zir {
2867 var instructions: std.MultiArrayList(Zir.Inst) = .{};2599 var instructions: std.MultiArrayList(Zir.Inst) = .{};
2868 errdefer instructions.deinit(gpa);2600 errdefer instructions.deinit(gpa);
28692601
...@@ -2929,127 +2661,6 @@ fn loadZirCacheBody(gpa: Allocator, header: Zir.Header, cache_file: std.fs.File)...@@ -2929,127 +2661,6 @@ fn loadZirCacheBody(gpa: Allocator, header: Zir.Header, cache_file: std.fs.File)
2929 return zir;2661 return zir;
2930}2662}
29312663
2932/// This is called from the AstGen thread pool, so must acquire
2933/// the Compilation mutex when acting on shared state.
2934fn updateZirRefs(zcu: *Module, file: *File, file_index: File.Index, old_zir: Zir) !void {
2935 const gpa = zcu.gpa;
2936 const new_zir = file.zir;
2937
2938 var inst_map: std.AutoHashMapUnmanaged(Zir.Inst.Index, Zir.Inst.Index) = .{};
2939 defer inst_map.deinit(gpa);
2940
2941 try mapOldZirToNew(gpa, old_zir, new_zir, &inst_map);
2942
2943 const old_tag = old_zir.instructions.items(.tag);
2944 const old_data = old_zir.instructions.items(.data);
2945
2946 // TODO: this should be done after all AstGen workers complete, to avoid
2947 // iterating over this full set for every updated file.
2948 for (zcu.intern_pool.tracked_insts.keys(), 0..) |*ti, idx_raw| {
2949 const ti_idx: InternPool.TrackedInst.Index = @enumFromInt(idx_raw);
2950 if (ti.file != file_index) continue;
2951 const old_inst = ti.inst;
2952 ti.inst = inst_map.get(ti.inst) orelse {
2953 // Tracking failed for this instruction. Invalidate associated `src_hash` deps.
2954 zcu.comp.mutex.lock();
2955 defer zcu.comp.mutex.unlock();
2956 log.debug("tracking failed for %{d}", .{old_inst});
2957 try zcu.markDependeeOutdated(.{ .src_hash = ti_idx });
2958 continue;
2959 };
2960
2961 if (old_zir.getAssociatedSrcHash(old_inst)) |old_hash| hash_changed: {
2962 if (new_zir.getAssociatedSrcHash(ti.inst)) |new_hash| {
2963 if (std.zig.srcHashEql(old_hash, new_hash)) {
2964 break :hash_changed;
2965 }
2966 log.debug("hash for (%{d} -> %{d}) changed: {} -> {}", .{
2967 old_inst,
2968 ti.inst,
2969 std.fmt.fmtSliceHexLower(&old_hash),
2970 std.fmt.fmtSliceHexLower(&new_hash),
2971 });
2972 }
2973 // The source hash associated with this instruction changed - invalidate relevant dependencies.
2974 zcu.comp.mutex.lock();
2975 defer zcu.comp.mutex.unlock();
2976 try zcu.markDependeeOutdated(.{ .src_hash = ti_idx });
2977 }
2978
2979 // If this is a `struct_decl` etc, we must invalidate any outdated namespace dependencies.
2980 const has_namespace = switch (old_tag[@intFromEnum(old_inst)]) {
2981 .extended => switch (old_data[@intFromEnum(old_inst)].extended.opcode) {
2982 .struct_decl, .union_decl, .opaque_decl, .enum_decl => true,
2983 else => false,
2984 },
2985 else => false,
2986 };
2987 if (!has_namespace) continue;
2988
2989 var old_names: std.AutoArrayHashMapUnmanaged(InternPool.NullTerminatedString, void) = .{};
2990 defer old_names.deinit(zcu.gpa);
2991 {
2992 var it = old_zir.declIterator(old_inst);
2993 while (it.next()) |decl_inst| {
2994 const decl_name = old_zir.getDeclaration(decl_inst)[0].name;
2995 switch (decl_name) {
2996 .@"comptime", .@"usingnamespace", .unnamed_test, .decltest => continue,
2997 _ => if (decl_name.isNamedTest(old_zir)) continue,
2998 }
2999 const name_zir = decl_name.toString(old_zir).?;
3000 const name_ip = try zcu.intern_pool.getOrPutString(
3001 zcu.gpa,
3002 old_zir.nullTerminatedString(name_zir),
3003 .no_embedded_nulls,
3004 );
3005 try old_names.put(zcu.gpa, name_ip, {});
3006 }
3007 }
3008 var any_change = false;
3009 {
3010 var it = new_zir.declIterator(ti.inst);
3011 while (it.next()) |decl_inst| {
3012 const decl_name = old_zir.getDeclaration(decl_inst)[0].name;
3013 switch (decl_name) {
3014 .@"comptime", .@"usingnamespace", .unnamed_test, .decltest => continue,
3015 _ => if (decl_name.isNamedTest(old_zir)) continue,
3016 }
3017 const name_zir = decl_name.toString(old_zir).?;
3018 const name_ip = try zcu.intern_pool.getOrPutString(
3019 zcu.gpa,
3020 old_zir.nullTerminatedString(name_zir),
3021 .no_embedded_nulls,
3022 );
3023 if (!old_names.swapRemove(name_ip)) continue;
3024 // Name added
3025 any_change = true;
3026 zcu.comp.mutex.lock();
3027 defer zcu.comp.mutex.unlock();
3028 try zcu.markDependeeOutdated(.{ .namespace_name = .{
3029 .namespace = ti_idx,
3030 .name = name_ip,
3031 } });
3032 }
3033 }
3034 // The only elements remaining in `old_names` now are any names which were removed.
3035 for (old_names.keys()) |name_ip| {
3036 any_change = true;
3037 zcu.comp.mutex.lock();
3038 defer zcu.comp.mutex.unlock();
3039 try zcu.markDependeeOutdated(.{ .namespace_name = .{
3040 .namespace = ti_idx,
3041 .name = name_ip,
3042 } });
3043 }
3044
3045 if (any_change) {
3046 zcu.comp.mutex.lock();
3047 defer zcu.comp.mutex.unlock();
3048 try zcu.markDependeeOutdated(.{ .namespace = ti_idx });
3049 }
3050 }
3051}
3052
3053pub fn markDependeeOutdated(zcu: *Zcu, dependee: InternPool.Dependee) !void {2664pub fn markDependeeOutdated(zcu: *Zcu, dependee: InternPool.Dependee) !void {
3054 log.debug("outdated dependee: {}", .{dependee});2665 log.debug("outdated dependee: {}", .{dependee});
3055 var it = zcu.intern_pool.dependencyIterator(dependee);2666 var it = zcu.intern_pool.dependencyIterator(dependee);
...@@ -3079,7 +2690,7 @@ pub fn markDependeeOutdated(zcu: *Zcu, dependee: InternPool.Dependee) !void {...@@ -3079,7 +2690,7 @@ pub fn markDependeeOutdated(zcu: *Zcu, dependee: InternPool.Dependee) !void {
3079 }2690 }
3080}2691}
30812692
3082fn markPoDependeeUpToDate(zcu: *Zcu, dependee: InternPool.Dependee) !void {2693pub fn markPoDependeeUpToDate(zcu: *Zcu, dependee: InternPool.Dependee) !void {
3083 var it = zcu.intern_pool.dependencyIterator(dependee);2694 var it = zcu.intern_pool.dependencyIterator(dependee);
3084 while (it.next()) |depender| {2695 while (it.next()) |depender| {
3085 if (zcu.outdated.getPtr(depender)) |po_dep_count| {2696 if (zcu.outdated.getPtr(depender)) |po_dep_count| {
...@@ -3279,7 +2890,7 @@ pub fn mapOldZirToNew(...@@ -3279,7 +2890,7 @@ pub fn mapOldZirToNew(
3279 old_inst: Zir.Inst.Index,2890 old_inst: Zir.Inst.Index,
3280 new_inst: Zir.Inst.Index,2891 new_inst: Zir.Inst.Index,
3281 };2892 };
3282 var match_stack: ArrayListUnmanaged(MatchedZirDecl) = .{};2893 var match_stack: std.ArrayListUnmanaged(MatchedZirDecl) = .{};
3283 defer match_stack.deinit(gpa);2894 defer match_stack.deinit(gpa);
32842895
3285 // Main struct inst is always matched2896 // Main struct inst is always matched
...@@ -3394,970 +3005,80 @@ pub fn mapOldZirToNew(...@@ -3394,970 +3005,80 @@ pub fn mapOldZirToNew(
3394 }3005 }
3395}3006}
33963007
3397/// Like `ensureDeclAnalyzed`, but the Decl is a file's root Decl.3008/// Ensure this function's body is or will be analyzed and emitted. This should
3398pub fn ensureFileAnalyzed(zcu: *Zcu, file_index: File.Index) SemaError!void {3009/// be called whenever a potential runtime call of a function is seen.
3399 if (zcu.fileRootDecl(file_index).unwrap()) |existing_root| {3010///
3400 return zcu.ensureDeclAnalyzed(existing_root);3011/// The caller is responsible for ensuring the function decl itself is already
3401 } else {3012/// analyzed, and for ensuring it can exist at runtime (see
3402 return zcu.semaFile(file_index);3013/// `sema.fnHasRuntimeBits`). This function does *not* guarantee that the body
3403 }3014/// will be analyzed when it returns: for that, see `ensureFuncBodyAnalyzed`.
3404}3015pub fn ensureFuncBodyAnalysisQueued(mod: *Module, func_index: InternPool.Index) !void {
3405
3406/// This ensures that the Decl will have an up-to-date Type and Value populated.
3407/// However the resolution status of the Type may not be fully resolved.
3408/// For example an inferred error set is not resolved until after `analyzeFnBody`.
3409/// is called.
3410pub fn ensureDeclAnalyzed(mod: *Module, decl_index: Decl.Index) SemaError!void {
3411 const tracy = trace(@src());
3412 defer tracy.end();
3413
3414 const ip = &mod.intern_pool;3016 const ip = &mod.intern_pool;
3415 const decl = mod.declPtr(decl_index);3017 const func = mod.funcInfo(func_index);
3416
3417 log.debug("ensureDeclAnalyzed '{d}' (name '{}')", .{
3418 @intFromEnum(decl_index),
3419 decl.name.fmt(ip),
3420 });
3421
3422 // Determine whether or not this Decl is outdated, i.e. requires re-analysis
3423 // even if `complete`. If a Decl is PO, we pessismistically assume that it
3424 // *does* require re-analysis, to ensure that the Decl is definitely
3425 // up-to-date when this function returns.
3426
3427 // If analysis occurs in a poor order, this could result in over-analysis.
3428 // We do our best to avoid this by the other dependency logic in this file
3429 // which tries to limit re-analysis to Decls whose previously listed
3430 // dependencies are all up-to-date.
3431
3432 const decl_as_depender = AnalUnit.wrap(.{ .decl = decl_index });
3433 const decl_was_outdated = mod.outdated.swapRemove(decl_as_depender) or
3434 mod.potentially_outdated.swapRemove(decl_as_depender);
3435
3436 if (decl_was_outdated) {
3437 _ = mod.outdated_ready.swapRemove(decl_as_depender);
3438 }
3439
3440 const was_outdated = mod.outdated_file_root.swapRemove(decl_index) or decl_was_outdated;
3441
3442 switch (decl.analysis) {
3443 .in_progress => unreachable,
3444
3445 .file_failure => return error.AnalysisFail,
3446
3447 .sema_failure,
3448 .dependency_failure,
3449 .codegen_failure,
3450 => if (!was_outdated) return error.AnalysisFail,
3451
3452 .complete => if (!was_outdated) return,
3453
3454 .unreferenced => {},
3455 }
3456
3457 if (was_outdated) {
3458 // The exports this Decl performs will be re-discovered, so we remove them here
3459 // prior to re-analysis.
3460 if (build_options.only_c) unreachable;
3461 mod.deleteUnitExports(decl_as_depender);
3462 mod.deleteUnitReferences(decl_as_depender);
3463 }
3464
3465 const sema_result: SemaDeclResult = blk: {
3466 if (decl.zir_decl_index == .none and !mod.declIsRoot(decl_index)) {
3467 // Anonymous decl. We don't semantically analyze these.
3468 break :blk .{
3469 .invalidate_decl_val = false,
3470 .invalidate_decl_ref = false,
3471 };
3472 }
3473
3474 if (mod.declIsRoot(decl_index)) {
3475 const changed = try mod.semaFileUpdate(decl.getFileScopeIndex(mod), decl_was_outdated);
3476 break :blk .{
3477 .invalidate_decl_val = changed,
3478 .invalidate_decl_ref = changed,
3479 };
3480 }
3481
3482 const decl_prog_node = mod.sema_prog_node.start((try decl.fullyQualifiedName(mod)).toSlice(ip), 0);
3483 defer decl_prog_node.end();
3484
3485 break :blk mod.semaDecl(decl_index) catch |err| switch (err) {
3486 error.AnalysisFail => {
3487 if (decl.analysis == .in_progress) {
3488 // If this decl caused the compile error, the analysis field would
3489 // be changed to indicate it was this Decl's fault. Because this
3490 // did not happen, we infer here that it was a dependency failure.
3491 decl.analysis = .dependency_failure;
3492 }
3493 return error.AnalysisFail;
3494 },
3495 error.GenericPoison => unreachable,
3496 else => |e| {
3497 decl.analysis = .sema_failure;
3498 try mod.failed_analysis.ensureUnusedCapacity(mod.gpa, 1);
3499 try mod.retryable_failures.append(mod.gpa, AnalUnit.wrap(.{ .decl = decl_index }));
3500 mod.failed_analysis.putAssumeCapacityNoClobber(AnalUnit.wrap(.{ .decl = decl_index }), try ErrorMsg.create(
3501 mod.gpa,
3502 decl.navSrcLoc(mod),
3503 "unable to analyze: {s}",
3504 .{@errorName(e)},
3505 ));
3506 return error.AnalysisFail;
3507 },
3508 };
3509 };
3510
3511 // TODO: we do not yet have separate dependencies for decl values vs types.
3512 if (decl_was_outdated) {
3513 if (sema_result.invalidate_decl_val or sema_result.invalidate_decl_ref) {
3514 log.debug("Decl tv invalidated ('{d}')", .{@intFromEnum(decl_index)});
3515 // This dependency was marked as PO, meaning dependees were waiting
3516 // on its analysis result, and it has turned out to be outdated.
3517 // Update dependees accordingly.
3518 try mod.markDependeeOutdated(.{ .decl_val = decl_index });
3519 } else {
3520 log.debug("Decl tv up-to-date ('{d}')", .{@intFromEnum(decl_index)});
3521 // This dependency was previously PO, but turned out to be up-to-date.
3522 // We do not need to queue successive analysis.
3523 try mod.markPoDependeeUpToDate(.{ .decl_val = decl_index });
3524 }
3525 }
3526}
3527
3528pub fn ensureFuncBodyAnalyzed(zcu: *Zcu, maybe_coerced_func_index: InternPool.Index) SemaError!void {
3529 const tracy = trace(@src());
3530 defer tracy.end();
3531
3532 const gpa = zcu.gpa;
3533 const ip = &zcu.intern_pool;
3534
3535 // We only care about the uncoerced function.
3536 // We need to do this for the "orphaned function" check below to be valid.
3537 const func_index = ip.unwrapCoercedFunc(maybe_coerced_func_index);
3538
3539 const func = zcu.funcInfo(maybe_coerced_func_index);
3540 const decl_index = func.owner_decl;3018 const decl_index = func.owner_decl;
3541 const decl = zcu.declPtr(decl_index);3019 const decl = mod.declPtr(decl_index);
3542
3543 log.debug("ensureFuncBodyAnalyzed '{d}' (instance of '{}')", .{
3544 @intFromEnum(func_index),
3545 decl.name.fmt(ip),
3546 });
3547
3548 // First, our owner decl must be up-to-date. This will always be the case
3549 // during the first update, but may not on successive updates if we happen
3550 // to get analyzed before our parent decl.
3551 try zcu.ensureDeclAnalyzed(decl_index);
3552
3553 // On an update, it's possible this function changed such that our owner
3554 // decl now refers to a different function, making this one orphaned. If
3555 // that's the case, we should remove this function from the binary.
3556 if (decl.val.ip_index != func_index) {
3557 try zcu.markDependeeOutdated(.{ .func_ies = func_index });
3558 ip.removeDependenciesForDepender(gpa, AnalUnit.wrap(.{ .func = func_index }));
3559 ip.remove(func_index);
3560 @panic("TODO: remove orphaned function from binary");
3561 }
3562
3563 // We'll want to remember what the IES used to be before the update for
3564 // dependency invalidation purposes.
3565 const old_resolved_ies = if (func.analysis(ip).inferred_error_set)
3566 func.resolvedErrorSet(ip).*
3567 else
3568 .none;
35693020
3570 switch (decl.analysis) {3021 switch (decl.analysis) {
3571 .unreferenced => unreachable,3022 .unreferenced => unreachable,
3572 .in_progress => unreachable,3023 .in_progress => unreachable,
35733024
3574 .codegen_failure => unreachable, // functions do not perform constant value generation
3575
3576 .file_failure,3025 .file_failure,
3577 .sema_failure,3026 .sema_failure,
3027 .codegen_failure,
3578 .dependency_failure,3028 .dependency_failure,
3579 => return error.AnalysisFail,3029 // Analysis of the function Decl itself failed, but we've already
3030 // emitted an error for that. The callee doesn't need the function to be
3031 // analyzed right now, so its analysis can safely continue.
3032 => return,
35803033
3581 .complete => {},3034 .complete => {},
3582 }3035 }
35833036
3584 const func_as_depender = AnalUnit.wrap(.{ .func = func_index });3037 assert(decl.has_tv);
3585 const was_outdated = zcu.outdated.swapRemove(func_as_depender) or
3586 zcu.potentially_outdated.swapRemove(func_as_depender);
35873038
3588 if (was_outdated) {3039 const func_as_depender = AnalUnit.wrap(.{ .func = func_index });
3589 if (build_options.only_c) unreachable;3040 const is_outdated = mod.outdated.contains(func_as_depender) or
3590 _ = zcu.outdated_ready.swapRemove(func_as_depender);3041 mod.potentially_outdated.contains(func_as_depender);
3591 zcu.deleteUnitExports(func_as_depender);
3592 zcu.deleteUnitReferences(func_as_depender);
3593 }
35943042
3595 switch (func.analysis(ip).state) {3043 switch (func.analysis(ip).state) {
3596 .success => if (!was_outdated) return,3044 .none => {},
3045 .queued => return,
3046 // As above, we don't need to forward errors here.
3597 .sema_failure,3047 .sema_failure,
3598 .dependency_failure,3048 .dependency_failure,
3599 .codegen_failure,3049 .codegen_failure,
3600 => if (!was_outdated) return error.AnalysisFail,3050 .success,
3601 .none, .queued => {},3051 => if (!is_outdated) return,
3602 .in_progress => unreachable,3052 .in_progress => return,
3603 .inline_only => unreachable, // don't queue work for this3053 .inline_only => unreachable, // don't queue work for this
3604 }3054 }
36053055
3606 log.debug("analyze and generate fn body '{d}'; reason='{s}'", .{3056 // Decl itself is safely analyzed, and body analysis is not yet queued
3607 @intFromEnum(func_index),
3608 if (was_outdated) "outdated" else "never analyzed",
3609 });
3610
3611 var tmp_arena = std.heap.ArenaAllocator.init(gpa);
3612 defer tmp_arena.deinit();
3613 const sema_arena = tmp_arena.allocator();
3614
3615 var air = zcu.analyzeFnBody(func_index, sema_arena) catch |err| switch (err) {
3616 error.AnalysisFail => {
3617 if (func.analysis(ip).state == .in_progress) {
3618 // If this decl caused the compile error, the analysis field would
3619 // be changed to indicate it was this Decl's fault. Because this
3620 // did not happen, we infer here that it was a dependency failure.
3621 func.analysis(ip).state = .dependency_failure;
3622 }
3623 return error.AnalysisFail;
3624 },
3625 error.OutOfMemory => return error.OutOfMemory,
3626 };
3627 errdefer air.deinit(gpa);
36283057
3629 const invalidate_ies_deps = i: {3058 try mod.comp.work_queue.writeItem(.{ .analyze_func = func_index });
3630 if (!was_outdated) break :i false;3059 if (mod.emit_h != null) {
3631 if (!func.analysis(ip).inferred_error_set) break :i true;3060 // TODO: we ideally only want to do this if the function's type changed
3632 const new_resolved_ies = func.resolvedErrorSet(ip).*;3061 // since the last update
3633 break :i new_resolved_ies != old_resolved_ies;3062 try mod.comp.work_queue.writeItem(.{ .emit_h_decl = decl_index });
3634 };
3635 if (invalidate_ies_deps) {
3636 log.debug("func IES invalidated ('{d}')", .{@intFromEnum(func_index)});
3637 try zcu.markDependeeOutdated(.{ .func_ies = func_index });
3638 } else if (was_outdated) {
3639 log.debug("func IES up-to-date ('{d}')", .{@intFromEnum(func_index)});
3640 try zcu.markPoDependeeUpToDate(.{ .func_ies = func_index });
3641 }3063 }
3064 func.analysis(ip).state = .queued;
3065}
36423066
3643 const comp = zcu.comp;3067pub const SemaDeclResult = packed struct {
36443068 /// Whether the value of a `decl_val` of this Decl changed.
3645 const dump_air = build_options.enable_debug_extensions and comp.verbose_air;3069 invalidate_decl_val: bool,
3646 const dump_llvm_ir = build_options.enable_debug_extensions and (comp.verbose_llvm_ir != null or comp.verbose_llvm_bc != null);3070 /// Whether the type of a `decl_ref` of this Decl changed.
36473071 invalidate_decl_ref: bool,
3648 if (comp.bin_file == null and zcu.llvm_object == null and !dump_air and !dump_llvm_ir) {3072};
3649 air.deinit(gpa);
3650 return;
3651 }
36523073
3653 try comp.work_queue.writeItem(.{ .codegen_func = .{3074pub const ImportFileResult = struct {
3654 .func = func_index,3075 file: *File,
3655 .air = air,3076 file_index: File.Index,
3656 } });3077 is_new: bool,
3657}3078 is_pkg: bool,
3079};
36583080
3659/// Takes ownership of `air`, even on error.3081pub fn importPkg(zcu: *Zcu, mod: *Package.Module) !ImportFileResult {
3660/// If any types referenced by `air` are unresolved, marks the codegen as failed.
3661pub fn linkerUpdateFunc(zcu: *Zcu, func_index: InternPool.Index, air: Air) Allocator.Error!void {
3662 const gpa = zcu.gpa;
3663 const ip = &zcu.intern_pool;
3664 const comp = zcu.comp;
3665
3666 defer {
3667 var air_mut = air;
3668 air_mut.deinit(gpa);
3669 }
3670
3671 const func = zcu.funcInfo(func_index);
3672 const decl_index = func.owner_decl;
3673 const decl = zcu.declPtr(decl_index);
3674
3675 var liveness = try Liveness.analyze(gpa, air, ip);
3676 defer liveness.deinit(gpa);
3677
3678 if (build_options.enable_debug_extensions and comp.verbose_air) {
3679 const fqn = try decl.fullyQualifiedName(zcu);
3680 std.debug.print("# Begin Function AIR: {}:\n", .{fqn.fmt(ip)});
3681 @import("print_air.zig").dump(zcu, air, liveness);
3682 std.debug.print("# End Function AIR: {}\n\n", .{fqn.fmt(ip)});
3683 }
3684
3685 if (std.debug.runtime_safety) {
3686 var verify: Liveness.Verify = .{
3687 .gpa = gpa,
3688 .air = air,
3689 .liveness = liveness,
3690 .intern_pool = ip,
3691 };
3692 defer verify.deinit();
3693
3694 verify.verify() catch |err| switch (err) {
3695 error.OutOfMemory => return error.OutOfMemory,
3696 else => {
3697 try zcu.failed_analysis.ensureUnusedCapacity(gpa, 1);
3698 zcu.failed_analysis.putAssumeCapacityNoClobber(
3699 AnalUnit.wrap(.{ .func = func_index }),
3700 try Module.ErrorMsg.create(
3701 gpa,
3702 decl.navSrcLoc(zcu),
3703 "invalid liveness: {s}",
3704 .{@errorName(err)},
3705 ),
3706 );
3707 func.analysis(ip).state = .codegen_failure;
3708 return;
3709 },
3710 };
3711 }
3712
3713 const codegen_prog_node = zcu.codegen_prog_node.start((try decl.fullyQualifiedName(zcu)).toSlice(ip), 0);
3714 defer codegen_prog_node.end();
3715
3716 if (!air.typesFullyResolved(zcu)) {
3717 // A type we depend on failed to resolve. This is a transitive failure.
3718 // Correcting this failure will involve changing a type this function
3719 // depends on, hence triggering re-analysis of this function, so this
3720 // interacts correctly with incremental compilation.
3721 func.analysis(ip).state = .codegen_failure;
3722 } else if (comp.bin_file) |lf| {
3723 lf.updateFunc(zcu, func_index, air, liveness) catch |err| switch (err) {
3724 error.OutOfMemory => return error.OutOfMemory,
3725 error.AnalysisFail => {
3726 func.analysis(ip).state = .codegen_failure;
3727 },
3728 else => {
3729 try zcu.failed_analysis.ensureUnusedCapacity(gpa, 1);
3730 zcu.failed_analysis.putAssumeCapacityNoClobber(AnalUnit.wrap(.{ .func = func_index }), try Module.ErrorMsg.create(
3731 gpa,
3732 decl.navSrcLoc(zcu),
3733 "unable to codegen: {s}",
3734 .{@errorName(err)},
3735 ));
3736 func.analysis(ip).state = .codegen_failure;
3737 try zcu.retryable_failures.append(zcu.gpa, AnalUnit.wrap(.{ .func = func_index }));
3738 },
3739 };
3740 } else if (zcu.llvm_object) |llvm_object| {
3741 if (build_options.only_c) unreachable;
3742 llvm_object.updateFunc(zcu, func_index, air, liveness) catch |err| switch (err) {
3743 error.OutOfMemory => return error.OutOfMemory,
3744 };
3745 }
3746}
3747
3748/// Ensure this function's body is or will be analyzed and emitted. This should
3749/// be called whenever a potential runtime call of a function is seen.
3750///
3751/// The caller is responsible for ensuring the function decl itself is already
3752/// analyzed, and for ensuring it can exist at runtime (see
3753/// `sema.fnHasRuntimeBits`). This function does *not* guarantee that the body
3754/// will be analyzed when it returns: for that, see `ensureFuncBodyAnalyzed`.
3755pub fn ensureFuncBodyAnalysisQueued(mod: *Module, func_index: InternPool.Index) !void {
3756 const ip = &mod.intern_pool;
3757 const func = mod.funcInfo(func_index);
3758 const decl_index = func.owner_decl;
3759 const decl = mod.declPtr(decl_index);
3760
3761 switch (decl.analysis) {
3762 .unreferenced => unreachable,
3763 .in_progress => unreachable,
3764
3765 .file_failure,
3766 .sema_failure,
3767 .codegen_failure,
3768 .dependency_failure,
3769 // Analysis of the function Decl itself failed, but we've already
3770 // emitted an error for that. The callee doesn't need the function to be
3771 // analyzed right now, so its analysis can safely continue.
3772 => return,
3773
3774 .complete => {},
3775 }
3776
3777 assert(decl.has_tv);
3778
3779 const func_as_depender = AnalUnit.wrap(.{ .func = func_index });
3780 const is_outdated = mod.outdated.contains(func_as_depender) or
3781 mod.potentially_outdated.contains(func_as_depender);
3782
3783 switch (func.analysis(ip).state) {
3784 .none => {},
3785 .queued => return,
3786 // As above, we don't need to forward errors here.
3787 .sema_failure,
3788 .dependency_failure,
3789 .codegen_failure,
3790 .success,
3791 => if (!is_outdated) return,
3792 .in_progress => return,
3793 .inline_only => unreachable, // don't queue work for this
3794 }
3795
3796 // Decl itself is safely analyzed, and body analysis is not yet queued
3797
3798 try mod.comp.work_queue.writeItem(.{ .analyze_func = func_index });
3799 if (mod.emit_h != null) {
3800 // TODO: we ideally only want to do this if the function's type changed
3801 // since the last update
3802 try mod.comp.work_queue.writeItem(.{ .emit_h_decl = decl_index });
3803 }
3804 func.analysis(ip).state = .queued;
3805}
3806
3807pub fn semaPkg(zcu: *Zcu, pkg: *Package.Module) !void {
3808 const import_file_result = try zcu.importPkg(pkg);
3809 const root_decl_index = zcu.fileRootDecl(import_file_result.file_index);
3810 if (root_decl_index == .none) {
3811 return zcu.semaFile(import_file_result.file_index);
3812 }
3813}
3814
3815fn getFileRootStruct(
3816 zcu: *Zcu,
3817 decl_index: Decl.Index,
3818 namespace_index: Namespace.Index,
3819 file_index: File.Index,
3820) Allocator.Error!InternPool.Index {
3821 const gpa = zcu.gpa;
3822 const ip = &zcu.intern_pool;
3823 const file = zcu.fileByIndex(file_index);
3824 const extended = file.zir.instructions.items(.data)[@intFromEnum(Zir.Inst.Index.main_struct_inst)].extended;
3825 assert(extended.opcode == .struct_decl);
3826 const small: Zir.Inst.StructDecl.Small = @bitCast(extended.small);
3827 assert(!small.has_captures_len);
3828 assert(!small.has_backing_int);
3829 assert(small.layout == .auto);
3830 var extra_index: usize = extended.operand + @typeInfo(Zir.Inst.StructDecl).Struct.fields.len;
3831 const fields_len = if (small.has_fields_len) blk: {
3832 const fields_len = file.zir.extra[extra_index];
3833 extra_index += 1;
3834 break :blk fields_len;
3835 } else 0;
3836 const decls_len = if (small.has_decls_len) blk: {
3837 const decls_len = file.zir.extra[extra_index];
3838 extra_index += 1;
3839 break :blk decls_len;
3840 } else 0;
3841 const decls = file.zir.bodySlice(extra_index, decls_len);
3842 extra_index += decls_len;
3843
3844 const tracked_inst = try ip.trackZir(gpa, file_index, .main_struct_inst);
3845 const wip_ty = switch (try ip.getStructType(gpa, .{
3846 .layout = .auto,
3847 .fields_len = fields_len,
3848 .known_non_opv = small.known_non_opv,
3849 .requires_comptime = if (small.known_comptime_only) .yes else .unknown,
3850 .is_tuple = small.is_tuple,
3851 .any_comptime_fields = small.any_comptime_fields,
3852 .any_default_inits = small.any_default_inits,
3853 .inits_resolved = false,
3854 .any_aligned_fields = small.any_aligned_fields,
3855 .has_namespace = true,
3856 .key = .{ .declared = .{
3857 .zir_index = tracked_inst,
3858 .captures = &.{},
3859 } },
3860 })) {
3861 .existing => unreachable, // we wouldn't be analysing the file root if this type existed
3862 .wip => |wip| wip,
3863 };
3864 errdefer wip_ty.cancel(ip);
3865
3866 if (zcu.comp.debug_incremental) {
3867 try ip.addDependency(
3868 gpa,
3869 AnalUnit.wrap(.{ .decl = decl_index }),
3870 .{ .src_hash = tracked_inst },
3871 );
3872 }
3873
3874 const decl = zcu.declPtr(decl_index);
3875 decl.val = Value.fromInterned(wip_ty.index);
3876 decl.has_tv = true;
3877 decl.owns_tv = true;
3878 decl.analysis = .complete;
3879
3880 try zcu.scanNamespace(namespace_index, decls, decl);
3881 try zcu.comp.work_queue.writeItem(.{ .resolve_type_fully = wip_ty.index });
3882 return wip_ty.finish(ip, decl_index, namespace_index.toOptional());
3883}
3884
3885/// Re-analyze the root Decl of a file on an incremental update.
3886/// If `type_outdated`, the struct type itself is considered outdated and is
3887/// reconstructed at a new InternPool index. Otherwise, the namespace is just
3888/// re-analyzed. Returns whether the decl's tyval was invalidated.
3889fn semaFileUpdate(zcu: *Zcu, file_index: File.Index, type_outdated: bool) SemaError!bool {
3890 const file = zcu.fileByIndex(file_index);
3891 const decl = zcu.declPtr(zcu.fileRootDecl(file_index).unwrap().?);
3892
3893 log.debug("semaFileUpdate mod={s} sub_file_path={s} type_outdated={}", .{
3894 file.mod.fully_qualified_name,
3895 file.sub_file_path,
3896 type_outdated,
3897 });
3898
3899 if (file.status != .success_zir) {
3900 if (decl.analysis == .file_failure) {
3901 return false;
3902 } else {
3903 decl.analysis = .file_failure;
3904 return true;
3905 }
3906 }
3907
3908 if (decl.analysis == .file_failure) {
3909 // No struct type currently exists. Create one!
3910 const root_decl = zcu.fileRootDecl(file_index);
3911 _ = try zcu.getFileRootStruct(root_decl.unwrap().?, decl.src_namespace, file_index);
3912 return true;
3913 }
3914
3915 assert(decl.has_tv);
3916 assert(decl.owns_tv);
3917
3918 if (type_outdated) {
3919 // Invalidate the existing type, reusing the decl and namespace.
3920 const file_root_decl = zcu.fileRootDecl(file_index).unwrap().?;
3921 zcu.intern_pool.removeDependenciesForDepender(zcu.gpa, AnalUnit.wrap(.{
3922 .decl = file_root_decl,
3923 }));
3924 zcu.intern_pool.remove(decl.val.toIntern());
3925 decl.val = undefined;
3926 _ = try zcu.getFileRootStruct(file_root_decl, decl.src_namespace, file_index);
3927 return true;
3928 }
3929
3930 // Only the struct's namespace is outdated.
3931 // Preserve the type - just scan the namespace again.
3932
3933 const extended = file.zir.instructions.items(.data)[@intFromEnum(Zir.Inst.Index.main_struct_inst)].extended;
3934 const small: Zir.Inst.StructDecl.Small = @bitCast(extended.small);
3935
3936 var extra_index: usize = extended.operand + @typeInfo(Zir.Inst.StructDecl).Struct.fields.len;
3937 extra_index += @intFromBool(small.has_fields_len);
3938 const decls_len = if (small.has_decls_len) blk: {
3939 const decls_len = file.zir.extra[extra_index];
3940 extra_index += 1;
3941 break :blk decls_len;
3942 } else 0;
3943 const decls = file.zir.bodySlice(extra_index, decls_len);
3944
3945 if (!type_outdated) {
3946 try zcu.scanNamespace(decl.src_namespace, decls, decl);
3947 }
3948
3949 return false;
3950}
3951
3952/// Regardless of the file status, will create a `Decl` if none exists so that we can track
3953/// dependencies and re-analyze when the file becomes outdated.
3954fn semaFile(zcu: *Zcu, file_index: File.Index) SemaError!void {
3955 const tracy = trace(@src());
3956 defer tracy.end();
3957
3958 const file = zcu.fileByIndex(file_index);
3959 assert(zcu.fileRootDecl(file_index) == .none);
3960
3961 const gpa = zcu.gpa;
3962 log.debug("semaFile zcu={s} sub_file_path={s}", .{
3963 file.mod.fully_qualified_name, file.sub_file_path,
3964 });
3965
3966 // Because these three things each reference each other, `undefined`
3967 // placeholders are used before being set after the struct type gains an
3968 // InternPool index.
3969 const new_namespace_index = try zcu.createNamespace(.{
3970 .parent = .none,
3971 .decl_index = undefined,
3972 .file_scope = file_index,
3973 });
3974 errdefer zcu.destroyNamespace(new_namespace_index);
3975
3976 const new_decl_index = try zcu.allocateNewDecl(new_namespace_index);
3977 const new_decl = zcu.declPtr(new_decl_index);
3978 errdefer @panic("TODO error handling");
3979
3980 zcu.setFileRootDecl(file_index, new_decl_index.toOptional());
3981 zcu.namespacePtr(new_namespace_index).decl_index = new_decl_index;
3982
3983 new_decl.name = try file.fullyQualifiedName(zcu);
3984 new_decl.name_fully_qualified = true;
3985 new_decl.is_pub = true;
3986 new_decl.is_exported = false;
3987 new_decl.alignment = .none;
3988 new_decl.@"linksection" = .none;
3989 new_decl.analysis = .in_progress;
3990
3991 if (file.status != .success_zir) {
3992 new_decl.analysis = .file_failure;
3993 return;
3994 }
3995 assert(file.zir_loaded);
3996
3997 const struct_ty = try zcu.getFileRootStruct(new_decl_index, new_namespace_index, file_index);
3998 errdefer zcu.intern_pool.remove(struct_ty);
3999
4000 switch (zcu.comp.cache_use) {
4001 .whole => |whole| if (whole.cache_manifest) |man| {
4002 const source = file.getSource(gpa) catch |err| {
4003 try reportRetryableFileError(zcu, file_index, "unable to load source: {s}", .{@errorName(err)});
4004 return error.AnalysisFail;
4005 };
4006
4007 const resolved_path = std.fs.path.resolve(gpa, &.{
4008 file.mod.root.root_dir.path orelse ".",
4009 file.mod.root.sub_path,
4010 file.sub_file_path,
4011 }) catch |err| {
4012 try reportRetryableFileError(zcu, file_index, "unable to resolve path: {s}", .{@errorName(err)});
4013 return error.AnalysisFail;
4014 };
4015 errdefer gpa.free(resolved_path);
4016
4017 whole.cache_manifest_mutex.lock();
4018 defer whole.cache_manifest_mutex.unlock();
4019 try man.addFilePostContents(resolved_path, source.bytes, source.stat);
4020 },
4021 .incremental => {},
4022 }
4023}
4024
4025const SemaDeclResult = packed struct {
4026 /// Whether the value of a `decl_val` of this Decl changed.
4027 invalidate_decl_val: bool,
4028 /// Whether the type of a `decl_ref` of this Decl changed.
4029 invalidate_decl_ref: bool,
4030};
4031
4032fn semaDecl(zcu: *Zcu, decl_index: Decl.Index) !SemaDeclResult {
4033 const tracy = trace(@src());
4034 defer tracy.end();
4035
4036 const decl = zcu.declPtr(decl_index);
4037 const ip = &zcu.intern_pool;
4038
4039 if (decl.getFileScope(zcu).status != .success_zir) {
4040 return error.AnalysisFail;
4041 }
4042
4043 assert(!zcu.declIsRoot(decl_index));
4044
4045 if (decl.zir_decl_index == .none and decl.owns_tv) {
4046 // We are re-analyzing an anonymous owner Decl (for a function or a namespace type).
4047 return zcu.semaAnonOwnerDecl(decl_index);
4048 }
4049
4050 log.debug("semaDecl '{d}'", .{@intFromEnum(decl_index)});
4051 log.debug("decl name '{}'", .{(try decl.fullyQualifiedName(zcu)).fmt(ip)});
4052 defer blk: {
4053 log.debug("finish decl name '{}'", .{(decl.fullyQualifiedName(zcu) catch break :blk).fmt(ip)});
4054 }
4055
4056 const old_has_tv = decl.has_tv;
4057 // The following values are ignored if `!old_has_tv`
4058 const old_ty = if (old_has_tv) decl.typeOf(zcu) else undefined;
4059 const old_val = decl.val;
4060 const old_align = decl.alignment;
4061 const old_linksection = decl.@"linksection";
4062 const old_addrspace = decl.@"addrspace";
4063 const old_is_inline = if (decl.getOwnedFunction(zcu)) |prev_func|
4064 prev_func.analysis(ip).state == .inline_only
4065 else
4066 false;
4067
4068 const decl_inst = decl.zir_decl_index.unwrap().?.resolve(ip);
4069
4070 const gpa = zcu.gpa;
4071 const zir = decl.getFileScope(zcu).zir;
4072
4073 const builtin_type_target_index: InternPool.Index = ip_index: {
4074 const std_mod = zcu.std_mod;
4075 if (decl.getFileScope(zcu).mod != std_mod) break :ip_index .none;
4076 // We're in the std module.
4077 const std_file_imported = try zcu.importPkg(std_mod);
4078 const std_file_root_decl_index = zcu.fileRootDecl(std_file_imported.file_index);
4079 const std_decl = zcu.declPtr(std_file_root_decl_index.unwrap().?);
4080 const std_namespace = std_decl.getInnerNamespace(zcu).?;
4081 const builtin_str = try ip.getOrPutString(gpa, "builtin", .no_embedded_nulls);
4082 const builtin_decl = zcu.declPtr(std_namespace.decls.getKeyAdapted(builtin_str, DeclAdapter{ .zcu = zcu }) orelse break :ip_index .none);
4083 const builtin_namespace = builtin_decl.getInnerNamespaceIndex(zcu).unwrap() orelse break :ip_index .none;
4084 if (decl.src_namespace != builtin_namespace) break :ip_index .none;
4085 // We're in builtin.zig. This could be a builtin we need to add to a specific InternPool index.
4086 for ([_][]const u8{
4087 "AtomicOrder",
4088 "AtomicRmwOp",
4089 "CallingConvention",
4090 "AddressSpace",
4091 "FloatMode",
4092 "ReduceOp",
4093 "CallModifier",
4094 "PrefetchOptions",
4095 "ExportOptions",
4096 "ExternOptions",
4097 "Type",
4098 }, [_]InternPool.Index{
4099 .atomic_order_type,
4100 .atomic_rmw_op_type,
4101 .calling_convention_type,
4102 .address_space_type,
4103 .float_mode_type,
4104 .reduce_op_type,
4105 .call_modifier_type,
4106 .prefetch_options_type,
4107 .export_options_type,
4108 .extern_options_type,
4109 .type_info_type,
4110 }) |type_name, type_ip| {
4111 if (decl.name.eqlSlice(type_name, ip)) break :ip_index type_ip;
4112 }
4113 break :ip_index .none;
4114 };
4115
4116 zcu.intern_pool.removeDependenciesForDepender(gpa, AnalUnit.wrap(.{ .decl = decl_index }));
4117
4118 decl.analysis = .in_progress;
4119
4120 var analysis_arena = std.heap.ArenaAllocator.init(gpa);
4121 defer analysis_arena.deinit();
4122
4123 var comptime_err_ret_trace = std.ArrayList(LazySrcLoc).init(gpa);
4124 defer comptime_err_ret_trace.deinit();
4125
4126 var sema: Sema = .{
4127 .mod = zcu,
4128 .gpa = gpa,
4129 .arena = analysis_arena.allocator(),
4130 .code = zir,
4131 .owner_decl = decl,
4132 .owner_decl_index = decl_index,
4133 .func_index = .none,
4134 .func_is_naked = false,
4135 .fn_ret_ty = Type.void,
4136 .fn_ret_ty_ies = null,
4137 .owner_func_index = .none,
4138 .comptime_err_ret_trace = &comptime_err_ret_trace,
4139 .builtin_type_target_index = builtin_type_target_index,
4140 };
4141 defer sema.deinit();
4142
4143 // Every Decl (other than file root Decls, which do not have a ZIR index) has a dependency on its own source.
4144 try sema.declareDependency(.{ .src_hash = try ip.trackZir(
4145 gpa,
4146 decl.getFileScopeIndex(zcu),
4147 decl_inst,
4148 ) });
4149
4150 var block_scope: Sema.Block = .{
4151 .parent = null,
4152 .sema = &sema,
4153 .namespace = decl.src_namespace,
4154 .instructions = .{},
4155 .inlining = null,
4156 .is_comptime = true,
4157 .src_base_inst = decl.zir_decl_index.unwrap().?,
4158 .type_name_ctx = decl.name,
4159 };
4160 defer block_scope.instructions.deinit(gpa);
4161
4162 const decl_bodies = decl.zirBodies(zcu);
4163
4164 const result_ref = try sema.resolveInlineBody(&block_scope, decl_bodies.value_body, decl_inst);
4165 // We'll do some other bits with the Sema. Clear the type target index just
4166 // in case they analyze any type.
4167 sema.builtin_type_target_index = .none;
4168 const align_src: LazySrcLoc = block_scope.src(.{ .node_offset_var_decl_align = 0 });
4169 const section_src: LazySrcLoc = block_scope.src(.{ .node_offset_var_decl_section = 0 });
4170 const address_space_src: LazySrcLoc = block_scope.src(.{ .node_offset_var_decl_addrspace = 0 });
4171 const ty_src: LazySrcLoc = block_scope.src(.{ .node_offset_var_decl_ty = 0 });
4172 const init_src: LazySrcLoc = block_scope.src(.{ .node_offset_var_decl_init = 0 });
4173 const decl_val = try sema.resolveFinalDeclValue(&block_scope, init_src, result_ref);
4174 const decl_ty = decl_val.typeOf(zcu);
4175
4176 // Note this resolves the type of the Decl, not the value; if this Decl
4177 // is a struct, for example, this resolves `type` (which needs no resolution),
4178 // not the struct itself.
4179 try decl_ty.resolveLayout(zcu);
4180
4181 if (decl.kind == .@"usingnamespace") {
4182 if (!decl_ty.eql(Type.type, zcu)) {
4183 return sema.fail(&block_scope, ty_src, "expected type, found {}", .{
4184 decl_ty.fmt(zcu),
4185 });
4186 }
4187 const ty = decl_val.toType();
4188 if (ty.getNamespace(zcu) == null) {
4189 return sema.fail(&block_scope, ty_src, "type {} has no namespace", .{ty.fmt(zcu)});
4190 }
4191
4192 decl.val = ty.toValue();
4193 decl.alignment = .none;
4194 decl.@"linksection" = .none;
4195 decl.has_tv = true;
4196 decl.owns_tv = false;
4197 decl.analysis = .complete;
4198
4199 // TODO: usingnamespace cannot currently participate in incremental compilation
4200 return .{
4201 .invalidate_decl_val = true,
4202 .invalidate_decl_ref = true,
4203 };
4204 }
4205
4206 var queue_linker_work = true;
4207 var is_func = false;
4208 var is_inline = false;
4209 switch (decl_val.toIntern()) {
4210 .generic_poison => unreachable,
4211 .unreachable_value => unreachable,
4212 else => switch (ip.indexToKey(decl_val.toIntern())) {
4213 .variable => |variable| {
4214 decl.owns_tv = variable.decl == decl_index;
4215 queue_linker_work = decl.owns_tv;
4216 },
4217
4218 .extern_func => |extern_func| {
4219 decl.owns_tv = extern_func.decl == decl_index;
4220 queue_linker_work = decl.owns_tv;
4221 is_func = decl.owns_tv;
4222 },
4223
4224 .func => |func| {
4225 decl.owns_tv = func.owner_decl == decl_index;
4226 queue_linker_work = false;
4227 is_inline = decl.owns_tv and decl_ty.fnCallingConvention(zcu) == .Inline;
4228 is_func = decl.owns_tv;
4229 },
4230
4231 else => {},
4232 },
4233 }
4234
4235 decl.val = decl_val;
4236 // Function linksection, align, and addrspace were already set by Sema
4237 if (!is_func) {
4238 decl.alignment = blk: {
4239 const align_body = decl_bodies.align_body orelse break :blk .none;
4240 const align_ref = try sema.resolveInlineBody(&block_scope, align_body, decl_inst);
4241 break :blk try sema.analyzeAsAlign(&block_scope, align_src, align_ref);
4242 };
4243 decl.@"linksection" = blk: {
4244 const linksection_body = decl_bodies.linksection_body orelse break :blk .none;
4245 const linksection_ref = try sema.resolveInlineBody(&block_scope, linksection_body, decl_inst);
4246 const bytes = try sema.toConstString(&block_scope, section_src, linksection_ref, .{
4247 .needed_comptime_reason = "linksection must be comptime-known",
4248 });
4249 if (mem.indexOfScalar(u8, bytes, 0) != null) {
4250 return sema.fail(&block_scope, section_src, "linksection cannot contain null bytes", .{});
4251 } else if (bytes.len == 0) {
4252 return sema.fail(&block_scope, section_src, "linksection cannot be empty", .{});
4253 }
4254 break :blk try ip.getOrPutStringOpt(gpa, bytes, .no_embedded_nulls);
4255 };
4256 decl.@"addrspace" = blk: {
4257 const addrspace_ctx: Sema.AddressSpaceContext = switch (ip.indexToKey(decl_val.toIntern())) {
4258 .variable => .variable,
4259 .extern_func, .func => .function,
4260 else => .constant,
4261 };
4262
4263 const target = sema.mod.getTarget();
4264
4265 const addrspace_body = decl_bodies.addrspace_body orelse break :blk switch (addrspace_ctx) {
4266 .function => target_util.defaultAddressSpace(target, .function),
4267 .variable => target_util.defaultAddressSpace(target, .global_mutable),
4268 .constant => target_util.defaultAddressSpace(target, .global_constant),
4269 else => unreachable,
4270 };
4271 const addrspace_ref = try sema.resolveInlineBody(&block_scope, addrspace_body, decl_inst);
4272 break :blk try sema.analyzeAsAddressSpace(&block_scope, address_space_src, addrspace_ref, addrspace_ctx);
4273 };
4274 }
4275 decl.has_tv = true;
4276 decl.analysis = .complete;
4277
4278 const result: SemaDeclResult = if (old_has_tv) .{
4279 .invalidate_decl_val = !decl_ty.eql(old_ty, zcu) or
4280 !decl.val.eql(old_val, decl_ty, zcu) or
4281 is_inline != old_is_inline,
4282 .invalidate_decl_ref = !decl_ty.eql(old_ty, zcu) or
4283 decl.alignment != old_align or
4284 decl.@"linksection" != old_linksection or
4285 decl.@"addrspace" != old_addrspace or
4286 is_inline != old_is_inline,
4287 } else .{
4288 .invalidate_decl_val = true,
4289 .invalidate_decl_ref = true,
4290 };
4291
4292 const has_runtime_bits = queue_linker_work and (is_func or try sema.typeHasRuntimeBits(decl_ty));
4293 if (has_runtime_bits) {
4294 // Needed for codegen_decl which will call updateDecl and then the
4295 // codegen backend wants full access to the Decl Type.
4296 try decl_ty.resolveFully(zcu);
4297
4298 try zcu.comp.work_queue.writeItem(.{ .codegen_decl = decl_index });
4299
4300 if (result.invalidate_decl_ref and zcu.emit_h != null) {
4301 try zcu.comp.work_queue.writeItem(.{ .emit_h_decl = decl_index });
4302 }
4303 }
4304
4305 if (decl.is_exported) {
4306 const export_src: LazySrcLoc = block_scope.src(.{ .token_offset = @intFromBool(decl.is_pub) });
4307 if (is_inline) return sema.fail(&block_scope, export_src, "export of inline function", .{});
4308 // The scope needs to have the decl in it.
4309 try sema.analyzeExport(&block_scope, export_src, .{ .name = decl.name }, decl_index);
4310 }
4311
4312 try sema.flushExports();
4313
4314 return result;
4315}
4316
4317fn semaAnonOwnerDecl(zcu: *Zcu, decl_index: Decl.Index) !SemaDeclResult {
4318 const decl = zcu.declPtr(decl_index);
4319
4320 assert(decl.has_tv);
4321 assert(decl.owns_tv);
4322
4323 log.debug("semaAnonOwnerDecl '{d}'", .{@intFromEnum(decl_index)});
4324
4325 switch (decl.typeOf(zcu).zigTypeTag(zcu)) {
4326 .Fn => @panic("TODO: update fn instance"),
4327 .Type => {},
4328 else => unreachable,
4329 }
4330
4331 // We are the owner Decl of a type, and we were marked as outdated. That means the *structure*
4332 // of this type changed; not just its namespace. Therefore, we need a new InternPool index.
4333 //
4334 // However, as soon as we make that, the context that created us will require re-analysis anyway
4335 // (as it depends on this Decl's value), meaning the `struct_decl` (or equivalent) instruction
4336 // will be analyzed again. Since Sema already needs to be able to reconstruct types like this,
4337 // why should we bother implementing it here too when the Sema logic will be hit right after?
4338 //
4339 // So instead, let's just mark this Decl as failed - so that any remaining Decls which genuinely
4340 // reference it (via `@This`) end up silently erroring too - and we'll let Sema make a new type
4341 // with a new Decl.
4342 //
4343 // Yes, this does mean that any type owner Decl has a constant value for its entire lifetime.
4344 zcu.intern_pool.removeDependenciesForDepender(zcu.gpa, AnalUnit.wrap(.{ .decl = decl_index }));
4345 zcu.intern_pool.remove(decl.val.toIntern());
4346 decl.analysis = .dependency_failure;
4347 return .{
4348 .invalidate_decl_val = true,
4349 .invalidate_decl_ref = true,
4350 };
4351}
4352
4353pub const ImportFileResult = struct {
4354 file: *File,
4355 file_index: File.Index,
4356 is_new: bool,
4357 is_pkg: bool,
4358};
4359
4360pub fn importPkg(zcu: *Zcu, mod: *Package.Module) !ImportFileResult {
4361 const gpa = zcu.gpa;3082 const gpa = zcu.gpa;
43623083
4363 // The resolved path is used as the key in the import table, to detect if3084 // The resolved path is used as the key in the import table, to detect if
...@@ -4533,78 +3254,6 @@ pub fn importFile(...@@ -4533,78 +3254,6 @@ pub fn importFile(
4533 };3254 };
4534}3255}
45353256
4536pub fn embedFile(
4537 mod: *Module,
4538 cur_file: *File,
4539 import_string: []const u8,
4540 src_loc: LazySrcLoc,
4541) !InternPool.Index {
4542 const gpa = mod.gpa;
4543
4544 if (cur_file.mod.deps.get(import_string)) |pkg| {
4545 const resolved_path = try std.fs.path.resolve(gpa, &.{
4546 pkg.root.root_dir.path orelse ".",
4547 pkg.root.sub_path,
4548 pkg.root_src_path,
4549 });
4550 var keep_resolved_path = false;
4551 defer if (!keep_resolved_path) gpa.free(resolved_path);
4552
4553 const gop = try mod.embed_table.getOrPut(gpa, resolved_path);
4554 errdefer {
4555 assert(std.mem.eql(u8, mod.embed_table.pop().key, resolved_path));
4556 keep_resolved_path = false;
4557 }
4558 if (gop.found_existing) return gop.value_ptr.*.val;
4559 keep_resolved_path = true;
4560
4561 const sub_file_path = try gpa.dupe(u8, pkg.root_src_path);
4562 errdefer gpa.free(sub_file_path);
4563
4564 return newEmbedFile(mod, pkg, sub_file_path, resolved_path, gop.value_ptr, src_loc);
4565 }
4566
4567 // The resolved path is used as the key in the table, to detect if a file
4568 // refers to the same as another, despite different relative paths.
4569 const resolved_path = try std.fs.path.resolve(gpa, &.{
4570 cur_file.mod.root.root_dir.path orelse ".",
4571 cur_file.mod.root.sub_path,
4572 cur_file.sub_file_path,
4573 "..",
4574 import_string,
4575 });
4576
4577 var keep_resolved_path = false;
4578 defer if (!keep_resolved_path) gpa.free(resolved_path);
4579
4580 const gop = try mod.embed_table.getOrPut(gpa, resolved_path);
4581 errdefer {
4582 assert(std.mem.eql(u8, mod.embed_table.pop().key, resolved_path));
4583 keep_resolved_path = false;
4584 }
4585 if (gop.found_existing) return gop.value_ptr.*.val;
4586 keep_resolved_path = true;
4587
4588 const resolved_root_path = try std.fs.path.resolve(gpa, &.{
4589 cur_file.mod.root.root_dir.path orelse ".",
4590 cur_file.mod.root.sub_path,
4591 });
4592 defer gpa.free(resolved_root_path);
4593
4594 const sub_file_path = p: {
4595 const relative = try std.fs.path.relative(gpa, resolved_root_path, resolved_path);
4596 errdefer gpa.free(relative);
4597
4598 if (!isUpDir(relative) and !std.fs.path.isAbsolute(relative)) {
4599 break :p relative;
4600 }
4601 return error.ImportOutsideModulePath;
4602 };
4603 defer gpa.free(sub_file_path);
4604
4605 return newEmbedFile(mod, cur_file.mod, sub_file_path, resolved_path, gop.value_ptr, src_loc);
4606}
4607
4608fn computePathDigest(zcu: *Zcu, mod: *Package.Module, sub_file_path: []const u8) Cache.BinDigest {3257fn computePathDigest(zcu: *Zcu, mod: *Package.Module, sub_file_path: []const u8) Cache.BinDigest {
4609 const want_local_cache = mod == zcu.main_mod;3258 const want_local_cache = mod == zcu.main_mod;
4610 var path_hash: Cache.HashHelper = .{};3259 var path_hash: Cache.HashHelper = .{};
...@@ -4620,349 +3269,6 @@ fn computePathDigest(zcu: *Zcu, mod: *Package.Module, sub_file_path: []const u8)...@@ -4620,349 +3269,6 @@ fn computePathDigest(zcu: *Zcu, mod: *Package.Module, sub_file_path: []const u8)
4620 return bin;3269 return bin;
4621}3270}
46223271
4623/// https://github.com/ziglang/zig/issues/14307
4624fn newEmbedFile(
4625 mod: *Module,
4626 pkg: *Package.Module,
4627 sub_file_path: []const u8,
4628 resolved_path: []const u8,
4629 result: **EmbedFile,
4630 src_loc: LazySrcLoc,
4631) !InternPool.Index {
4632 const gpa = mod.gpa;
4633 const ip = &mod.intern_pool;
4634
4635 const new_file = try gpa.create(EmbedFile);
4636 errdefer gpa.destroy(new_file);
4637
4638 var file = try pkg.root.openFile(sub_file_path, .{});
4639 defer file.close();
4640
4641 const actual_stat = try file.stat();
4642 const stat: Cache.File.Stat = .{
4643 .size = actual_stat.size,
4644 .inode = actual_stat.inode,
4645 .mtime = actual_stat.mtime,
4646 };
4647 const size = std.math.cast(usize, actual_stat.size) orelse return error.Overflow;
4648
4649 const bytes = try ip.string_bytes.addManyAsSlice(gpa, try std.math.add(usize, size, 1));
4650 const actual_read = try file.readAll(bytes[0..size]);
4651 if (actual_read != size) return error.UnexpectedEndOfFile;
4652 bytes[size] = 0;
4653
4654 const comp = mod.comp;
4655 switch (comp.cache_use) {
4656 .whole => |whole| if (whole.cache_manifest) |man| {
4657 const copied_resolved_path = try gpa.dupe(u8, resolved_path);
4658 errdefer gpa.free(copied_resolved_path);
4659 whole.cache_manifest_mutex.lock();
4660 defer whole.cache_manifest_mutex.unlock();
4661 try man.addFilePostContents(copied_resolved_path, bytes[0..size], stat);
4662 },
4663 .incremental => {},
4664 }
4665
4666 const array_ty = try ip.get(gpa, .{ .array_type = .{
4667 .len = size,
4668 .sentinel = .zero_u8,
4669 .child = .u8_type,
4670 } });
4671 const array_val = try ip.get(gpa, .{ .aggregate = .{
4672 .ty = array_ty,
4673 .storage = .{ .bytes = try ip.getOrPutTrailingString(gpa, bytes.len, .maybe_embedded_nulls) },
4674 } });
4675
4676 const ptr_ty = (try mod.ptrType(.{
4677 .child = array_ty,
4678 .flags = .{
4679 .alignment = .none,
4680 .is_const = true,
4681 .address_space = .generic,
4682 },
4683 })).toIntern();
4684 const ptr_val = try ip.get(gpa, .{ .ptr = .{
4685 .ty = ptr_ty,
4686 .base_addr = .{ .anon_decl = .{
4687 .val = array_val,
4688 .orig_ty = ptr_ty,
4689 } },
4690 .byte_offset = 0,
4691 } });
4692
4693 result.* = new_file;
4694 new_file.* = .{
4695 .sub_file_path = try ip.getOrPutString(gpa, sub_file_path, .no_embedded_nulls),
4696 .owner = pkg,
4697 .stat = stat,
4698 .val = ptr_val,
4699 .src_loc = src_loc,
4700 };
4701 return ptr_val;
4702}
4703
4704pub fn scanNamespace(
4705 zcu: *Zcu,
4706 namespace_index: Namespace.Index,
4707 decls: []const Zir.Inst.Index,
4708 parent_decl: *Decl,
4709) Allocator.Error!void {
4710 const tracy = trace(@src());
4711 defer tracy.end();
4712
4713 const gpa = zcu.gpa;
4714 const namespace = zcu.namespacePtr(namespace_index);
4715
4716 // For incremental updates, `scanDecl` wants to look up existing decls by their ZIR index rather
4717 // than their name. We'll build an efficient mapping now, then discard the current `decls`.
4718 var existing_by_inst: std.AutoHashMapUnmanaged(InternPool.TrackedInst.Index, Decl.Index) = .{};
4719 defer existing_by_inst.deinit(gpa);
4720
4721 try existing_by_inst.ensureTotalCapacity(gpa, @intCast(namespace.decls.count()));
4722
4723 for (namespace.decls.keys()) |decl_index| {
4724 const decl = zcu.declPtr(decl_index);
4725 existing_by_inst.putAssumeCapacityNoClobber(decl.zir_decl_index.unwrap().?, decl_index);
4726 }
4727
4728 var seen_decls: std.AutoHashMapUnmanaged(InternPool.NullTerminatedString, void) = .{};
4729 defer seen_decls.deinit(gpa);
4730
4731 try zcu.comp.work_queue.ensureUnusedCapacity(decls.len);
4732
4733 namespace.decls.clearRetainingCapacity();
4734 try namespace.decls.ensureTotalCapacity(gpa, decls.len);
4735
4736 namespace.usingnamespace_set.clearRetainingCapacity();
4737
4738 var scan_decl_iter: ScanDeclIter = .{
4739 .zcu = zcu,
4740 .namespace_index = namespace_index,
4741 .parent_decl = parent_decl,
4742 .seen_decls = &seen_decls,
4743 .existing_by_inst = &existing_by_inst,
4744 .pass = .named,
4745 };
4746 for (decls) |decl_inst| {
4747 try scanDecl(&scan_decl_iter, decl_inst);
4748 }
4749 scan_decl_iter.pass = .unnamed;
4750 for (decls) |decl_inst| {
4751 try scanDecl(&scan_decl_iter, decl_inst);
4752 }
4753
4754 if (seen_decls.count() != namespace.decls.count()) {
4755 // Do a pass over the namespace contents and remove any decls from the last update
4756 // which were removed in this one.
4757 var i: usize = 0;
4758 while (i < namespace.decls.count()) {
4759 const decl_index = namespace.decls.keys()[i];
4760 const decl = zcu.declPtr(decl_index);
4761 if (!seen_decls.contains(decl.name)) {
4762 // We must preserve namespace ordering for @typeInfo.
4763 namespace.decls.orderedRemoveAt(i);
4764 i -= 1;
4765 }
4766 }
4767 }
4768}
4769
4770const ScanDeclIter = struct {
4771 zcu: *Zcu,
4772 namespace_index: Namespace.Index,
4773 parent_decl: *Decl,
4774 seen_decls: *std.AutoHashMapUnmanaged(InternPool.NullTerminatedString, void),
4775 existing_by_inst: *const std.AutoHashMapUnmanaged(InternPool.TrackedInst.Index, Decl.Index),
4776 /// Decl scanning is run in two passes, so that we can detect when a generated
4777 /// name would clash with an explicit name and use a different one.
4778 pass: enum { named, unnamed },
4779 usingnamespace_index: usize = 0,
4780 comptime_index: usize = 0,
4781 unnamed_test_index: usize = 0,
4782
4783 fn avoidNameConflict(iter: *ScanDeclIter, comptime fmt: []const u8, args: anytype) !InternPool.NullTerminatedString {
4784 const zcu = iter.zcu;
4785 const gpa = zcu.gpa;
4786 const ip = &zcu.intern_pool;
4787 var name = try ip.getOrPutStringFmt(gpa, fmt, args, .no_embedded_nulls);
4788 var gop = try iter.seen_decls.getOrPut(gpa, name);
4789 var next_suffix: u32 = 0;
4790 while (gop.found_existing) {
4791 name = try ip.getOrPutStringFmt(gpa, "{}_{d}", .{ name.fmt(ip), next_suffix }, .no_embedded_nulls);
4792 gop = try iter.seen_decls.getOrPut(gpa, name);
4793 next_suffix += 1;
4794 }
4795 return name;
4796 }
4797};
4798
4799fn scanDecl(iter: *ScanDeclIter, decl_inst: Zir.Inst.Index) Allocator.Error!void {
4800 const tracy = trace(@src());
4801 defer tracy.end();
4802
4803 const zcu = iter.zcu;
4804 const namespace_index = iter.namespace_index;
4805 const namespace = zcu.namespacePtr(namespace_index);
4806 const gpa = zcu.gpa;
4807 const zir = namespace.fileScope(zcu).zir;
4808 const ip = &zcu.intern_pool;
4809
4810 const inst_data = zir.instructions.items(.data)[@intFromEnum(decl_inst)].declaration;
4811 const extra = zir.extraData(Zir.Inst.Declaration, inst_data.payload_index);
4812 const declaration = extra.data;
4813
4814 // Every Decl needs a name.
4815 const decl_name: InternPool.NullTerminatedString, const kind: Decl.Kind, const is_named_test: bool = switch (declaration.name) {
4816 .@"comptime" => info: {
4817 if (iter.pass != .unnamed) return;
4818 const i = iter.comptime_index;
4819 iter.comptime_index += 1;
4820 break :info .{
4821 try iter.avoidNameConflict("comptime_{d}", .{i}),
4822 .@"comptime",
4823 false,
4824 };
4825 },
4826 .@"usingnamespace" => info: {
4827 // TODO: this isn't right! These should be considered unnamed. Name conflicts can happen here.
4828 // The problem is, we need to preserve the decl ordering for `@typeInfo`.
4829 // I'm not bothering to fix this now, since some upcoming changes will change this code significantly anyway.
4830 if (iter.pass != .named) return;
4831 const i = iter.usingnamespace_index;
4832 iter.usingnamespace_index += 1;
4833 break :info .{
4834 try iter.avoidNameConflict("usingnamespace_{d}", .{i}),
4835 .@"usingnamespace",
4836 false,
4837 };
4838 },
4839 .unnamed_test => info: {
4840 if (iter.pass != .unnamed) return;
4841 const i = iter.unnamed_test_index;
4842 iter.unnamed_test_index += 1;
4843 break :info .{
4844 try iter.avoidNameConflict("test_{d}", .{i}),
4845 .@"test",
4846 false,
4847 };
4848 },
4849 .decltest => info: {
4850 // We consider these to be unnamed since the decl name can be adjusted to avoid conflicts if necessary.
4851 if (iter.pass != .unnamed) return;
4852 assert(declaration.flags.has_doc_comment);
4853 const name = zir.nullTerminatedString(@enumFromInt(zir.extra[extra.end]));
4854 break :info .{
4855 try iter.avoidNameConflict("decltest.{s}", .{name}),
4856 .@"test",
4857 true,
4858 };
4859 },
4860 _ => if (declaration.name.isNamedTest(zir)) info: {
4861 // We consider these to be unnamed since the decl name can be adjusted to avoid conflicts if necessary.
4862 if (iter.pass != .unnamed) return;
4863 break :info .{
4864 try iter.avoidNameConflict("test.{s}", .{zir.nullTerminatedString(declaration.name.toString(zir).?)}),
4865 .@"test",
4866 true,
4867 };
4868 } else info: {
4869 if (iter.pass != .named) return;
4870 const name = try ip.getOrPutString(
4871 gpa,
4872 zir.nullTerminatedString(declaration.name.toString(zir).?),
4873 .no_embedded_nulls,
4874 );
4875 try iter.seen_decls.putNoClobber(gpa, name, {});
4876 break :info .{
4877 name,
4878 .named,
4879 false,
4880 };
4881 },
4882 };
4883
4884 switch (kind) {
4885 .@"usingnamespace" => try namespace.usingnamespace_set.ensureUnusedCapacity(gpa, 1),
4886 .@"test" => try zcu.test_functions.ensureUnusedCapacity(gpa, 1),
4887 else => {},
4888 }
4889
4890 const parent_file_scope_index = iter.parent_decl.getFileScopeIndex(zcu);
4891 const tracked_inst = try ip.trackZir(gpa, parent_file_scope_index, decl_inst);
4892
4893 // We create a Decl for it regardless of analysis status.
4894
4895 const prev_exported, const decl_index = if (iter.existing_by_inst.get(tracked_inst)) |decl_index| decl_index: {
4896 // We need only update this existing Decl.
4897 const decl = zcu.declPtr(decl_index);
4898 const was_exported = decl.is_exported;
4899 assert(decl.kind == kind); // ZIR tracking should preserve this
4900 decl.name = decl_name;
4901 decl.is_pub = declaration.flags.is_pub;
4902 decl.is_exported = declaration.flags.is_export;
4903 break :decl_index .{ was_exported, decl_index };
4904 } else decl_index: {
4905 // Create and set up a new Decl.
4906 const new_decl_index = try zcu.allocateNewDecl(namespace_index);
4907 const new_decl = zcu.declPtr(new_decl_index);
4908 new_decl.kind = kind;
4909 new_decl.name = decl_name;
4910 new_decl.is_pub = declaration.flags.is_pub;
4911 new_decl.is_exported = declaration.flags.is_export;
4912 new_decl.zir_decl_index = tracked_inst.toOptional();
4913 break :decl_index .{ false, new_decl_index };
4914 };
4915
4916 const decl = zcu.declPtr(decl_index);
4917
4918 namespace.decls.putAssumeCapacityNoClobberContext(decl_index, {}, .{ .zcu = zcu });
4919
4920 const comp = zcu.comp;
4921 const decl_mod = namespace.fileScope(zcu).mod;
4922 const want_analysis = declaration.flags.is_export or switch (kind) {
4923 .anon => unreachable,
4924 .@"comptime" => true,
4925 .@"usingnamespace" => a: {
4926 namespace.usingnamespace_set.putAssumeCapacityNoClobber(decl_index, declaration.flags.is_pub);
4927 break :a true;
4928 },
4929 .named => false,
4930 .@"test" => a: {
4931 if (!comp.config.is_test) break :a false;
4932 if (decl_mod != zcu.main_mod) break :a false;
4933 if (is_named_test and comp.test_filters.len > 0) {
4934 const decl_fqn = try namespace.fullyQualifiedName(zcu, decl_name);
4935 const decl_fqn_slice = decl_fqn.toSlice(ip);
4936 for (comp.test_filters) |test_filter| {
4937 if (mem.indexOf(u8, decl_fqn_slice, test_filter)) |_| break;
4938 } else break :a false;
4939 }
4940 zcu.test_functions.putAssumeCapacity(decl_index, {}); // may clobber on incremental update
4941 break :a true;
4942 },
4943 };
4944
4945 if (want_analysis) {
4946 // We will not queue analysis if the decl has been analyzed on a previous update and
4947 // `is_export` is unchanged. In this case, the incremental update mechanism will handle
4948 // re-analysis for us if necessary.
4949 if (prev_exported != declaration.flags.is_export or decl.analysis == .unreferenced) {
4950 log.debug("scanDecl queue analyze_decl file='{s}' decl_name='{}' decl_index={d}", .{
4951 namespace.fileScope(zcu).sub_file_path, decl_name.fmt(ip), decl_index,
4952 });
4953 comp.work_queue.writeItemAssumeCapacity(.{ .analyze_decl = decl_index });
4954 }
4955 }
4956
4957 if (decl.getOwnedFunction(zcu) != null) {
4958 // TODO this logic is insufficient; namespaces we don't re-scan may still require
4959 // updated line numbers. Look into this!
4960 // TODO Look into detecting when this would be unnecessary by storing enough state
4961 // in `Decl` to notice that the line number did not change.
4962 comp.work_queue.writeItemAssumeCapacity(.{ .update_line_number = decl_index });
4963 }
4964}
4965
4966/// Cancel the creation of an anon decl and delete any references to it.3272/// Cancel the creation of an anon decl and delete any references to it.
4967/// If other decls depend on this decl, they must be aborted first.3273/// If other decls depend on this decl, they must be aborted first.
4968pub fn abortAnonDecl(mod: *Module, decl_index: Decl.Index) void {3274pub fn abortAnonDecl(mod: *Module, decl_index: Decl.Index) void {
...@@ -4970,13 +3276,6 @@ pub fn abortAnonDecl(mod: *Module, decl_index: Decl.Index) void {...@@ -4970,13 +3276,6 @@ pub fn abortAnonDecl(mod: *Module, decl_index: Decl.Index) void {
4970 mod.destroyDecl(decl_index);3276 mod.destroyDecl(decl_index);
4971}3277}
49723278
4973/// Finalize the creation of an anon decl.
4974pub fn finalizeAnonDecl(mod: *Module, decl_index: Decl.Index) Allocator.Error!void {
4975 if (mod.declPtr(decl_index).typeOf(mod).isFnOrHasRuntimeBits(mod)) {
4976 try mod.comp.work_queue.writeItem(.{ .codegen_decl = decl_index });
4977 }
4978}
4979
4980/// Delete all the Export objects that are caused by this `AnalUnit`. Re-analysis of3279/// Delete all the Export objects that are caused by this `AnalUnit`. Re-analysis of
4981/// this `AnalUnit` will cause them to be re-created (or not).3280/// this `AnalUnit` will cause them to be re-created (or not).
4982pub fn deleteUnitExports(zcu: *Zcu, anal_unit: AnalUnit) void {3281pub fn deleteUnitExports(zcu: *Zcu, anal_unit: AnalUnit) void {
...@@ -5019,7 +3318,7 @@ pub fn deleteUnitExports(zcu: *Zcu, anal_unit: AnalUnit) void {...@@ -5019,7 +3318,7 @@ pub fn deleteUnitExports(zcu: *Zcu, anal_unit: AnalUnit) void {
50193318
5020/// Delete all references in `reference_table` which are caused by this `AnalUnit`.3319/// Delete all references in `reference_table` which are caused by this `AnalUnit`.
5021/// Re-analysis of the `AnalUnit` will cause appropriate references to be recreated.3320/// Re-analysis of the `AnalUnit` will cause appropriate references to be recreated.
5022fn deleteUnitReferences(zcu: *Zcu, anal_unit: AnalUnit) void {3321pub fn deleteUnitReferences(zcu: *Zcu, anal_unit: AnalUnit) void {
5023 const gpa = zcu.gpa;3322 const gpa = zcu.gpa;
50243323
5025 const kv = zcu.reference_table.fetchSwapRemove(anal_unit) orelse return;3324 const kv = zcu.reference_table.fetchSwapRemove(anal_unit) orelse return;
...@@ -5031,276 +3330,31 @@ fn deleteUnitReferences(zcu: *Zcu, anal_unit: AnalUnit) void {...@@ -5031,276 +3330,31 @@ fn deleteUnitReferences(zcu: *Zcu, anal_unit: AnalUnit) void {
5031 // Just leak it for now, and let GC reclaim it later on.3330 // Just leak it for now, and let GC reclaim it later on.
5032 return;3331 return;
5033 };3332 };
5034 idx = zcu.all_references.items[idx].next;3333 idx = zcu.all_references.items[idx].next;
5035 }
5036}
5037
5038pub fn addUnitReference(zcu: *Zcu, src_unit: AnalUnit, referenced_unit: AnalUnit, ref_src: LazySrcLoc) Allocator.Error!void {
5039 const gpa = zcu.gpa;
5040
5041 try zcu.reference_table.ensureUnusedCapacity(gpa, 1);
5042
5043 const ref_idx = zcu.free_references.popOrNull() orelse idx: {
5044 _ = try zcu.all_references.addOne(gpa);
5045 break :idx zcu.all_references.items.len - 1;
5046 };
5047
5048 errdefer comptime unreachable;
5049
5050 const gop = zcu.reference_table.getOrPutAssumeCapacity(src_unit);
5051
5052 zcu.all_references.items[ref_idx] = .{
5053 .referenced = referenced_unit,
5054 .next = if (gop.found_existing) gop.value_ptr.* else std.math.maxInt(u32),
5055 .src = ref_src,
5056 };
5057
5058 gop.value_ptr.* = @intCast(ref_idx);
5059}
5060
5061pub fn analyzeFnBody(mod: *Module, func_index: InternPool.Index, arena: Allocator) SemaError!Air {
5062 const tracy = trace(@src());
5063 defer tracy.end();
5064
5065 const gpa = mod.gpa;
5066 const ip = &mod.intern_pool;
5067 const func = mod.funcInfo(func_index);
5068 const decl_index = func.owner_decl;
5069 const decl = mod.declPtr(decl_index);
5070
5071 log.debug("func name '{}'", .{(try decl.fullyQualifiedName(mod)).fmt(ip)});
5072 defer blk: {
5073 log.debug("finish func name '{}'", .{(decl.fullyQualifiedName(mod) catch break :blk).fmt(ip)});
5074 }
5075
5076 const decl_prog_node = mod.sema_prog_node.start((try decl.fullyQualifiedName(mod)).toSlice(ip), 0);
5077 defer decl_prog_node.end();
5078
5079 mod.intern_pool.removeDependenciesForDepender(gpa, AnalUnit.wrap(.{ .func = func_index }));
5080
5081 var comptime_err_ret_trace = std.ArrayList(LazySrcLoc).init(gpa);
5082 defer comptime_err_ret_trace.deinit();
5083
5084 // In the case of a generic function instance, this is the type of the
5085 // instance, which has comptime parameters elided. In other words, it is
5086 // the runtime-known parameters only, not to be confused with the
5087 // generic_owner function type, which potentially has more parameters,
5088 // including comptime parameters.
5089 const fn_ty = decl.typeOf(mod);
5090 const fn_ty_info = mod.typeToFunc(fn_ty).?;
5091
5092 var sema: Sema = .{
5093 .mod = mod,
5094 .gpa = gpa,
5095 .arena = arena,
5096 .code = decl.getFileScope(mod).zir,
5097 .owner_decl = decl,
5098 .owner_decl_index = decl_index,
5099 .func_index = func_index,
5100 .func_is_naked = fn_ty_info.cc == .Naked,
5101 .fn_ret_ty = Type.fromInterned(fn_ty_info.return_type),
5102 .fn_ret_ty_ies = null,
5103 .owner_func_index = func_index,
5104 .branch_quota = @max(func.branchQuota(ip).*, Sema.default_branch_quota),
5105 .comptime_err_ret_trace = &comptime_err_ret_trace,
5106 };
5107 defer sema.deinit();
5108
5109 // Every runtime function has a dependency on the source of the Decl it originates from.
5110 // It also depends on the value of its owner Decl.
5111 try sema.declareDependency(.{ .src_hash = decl.zir_decl_index.unwrap().? });
5112 try sema.declareDependency(.{ .decl_val = decl_index });
5113
5114 if (func.analysis(ip).inferred_error_set) {
5115 const ies = try arena.create(Sema.InferredErrorSet);
5116 ies.* = .{ .func = func_index };
5117 sema.fn_ret_ty_ies = ies;
5118 }
5119
5120 // reset in case calls to errorable functions are removed.
5121 func.analysis(ip).calls_or_awaits_errorable_fn = false;
5122
5123 // First few indexes of extra are reserved and set at the end.
5124 const reserved_count = @typeInfo(Air.ExtraIndex).Enum.fields.len;
5125 try sema.air_extra.ensureTotalCapacity(gpa, reserved_count);
5126 sema.air_extra.items.len += reserved_count;
5127
5128 var inner_block: Sema.Block = .{
5129 .parent = null,
5130 .sema = &sema,
5131 .namespace = decl.src_namespace,
5132 .instructions = .{},
5133 .inlining = null,
5134 .is_comptime = false,
5135 .src_base_inst = inst: {
5136 const owner_info = if (func.generic_owner == .none)
5137 func
5138 else
5139 mod.funcInfo(func.generic_owner);
5140 const orig_decl = mod.declPtr(owner_info.owner_decl);
5141 break :inst orig_decl.zir_decl_index.unwrap().?;
5142 },
5143 .type_name_ctx = decl.name,
5144 };
5145 defer inner_block.instructions.deinit(gpa);
5146
5147 const fn_info = sema.code.getFnInfo(func.zirBodyInst(ip).resolve(ip));
5148
5149 // Here we are performing "runtime semantic analysis" for a function body, which means
5150 // we must map the parameter ZIR instructions to `arg` AIR instructions.
5151 // AIR requires the `arg` parameters to be the first N instructions.
5152 // This could be a generic function instantiation, however, in which case we need to
5153 // map the comptime parameters to constant values and only emit arg AIR instructions
5154 // for the runtime ones.
5155 const runtime_params_len = fn_ty_info.param_types.len;
5156 try inner_block.instructions.ensureTotalCapacityPrecise(gpa, runtime_params_len);
5157 try sema.air_instructions.ensureUnusedCapacity(gpa, fn_info.total_params_len);
5158 try sema.inst_map.ensureSpaceForInstructions(gpa, fn_info.param_body);
5159
5160 // In the case of a generic function instance, pre-populate all the comptime args.
5161 if (func.comptime_args.len != 0) {
5162 for (
5163 fn_info.param_body[0..func.comptime_args.len],
5164 func.comptime_args.get(ip),
5165 ) |inst, comptime_arg| {
5166 if (comptime_arg == .none) continue;
5167 sema.inst_map.putAssumeCapacityNoClobber(inst, Air.internedToRef(comptime_arg));
5168 }
5169 }
5170
5171 const src_params_len = if (func.comptime_args.len != 0)
5172 func.comptime_args.len
5173 else
5174 runtime_params_len;
5175
5176 var runtime_param_index: usize = 0;
5177 for (fn_info.param_body[0..src_params_len], 0..) |inst, src_param_index| {
5178 const gop = sema.inst_map.getOrPutAssumeCapacity(inst);
5179 if (gop.found_existing) continue; // provided above by comptime arg
5180
5181 const param_ty = fn_ty_info.param_types.get(ip)[runtime_param_index];
5182 runtime_param_index += 1;
5183
5184 const opt_opv = sema.typeHasOnePossibleValue(Type.fromInterned(param_ty)) catch |err| switch (err) {
5185 error.GenericPoison => unreachable,
5186 error.ComptimeReturn => unreachable,
5187 error.ComptimeBreak => unreachable,
5188 else => |e| return e,
5189 };
5190 if (opt_opv) |opv| {
5191 gop.value_ptr.* = Air.internedToRef(opv.toIntern());
5192 continue;
5193 }
5194 const arg_index: Air.Inst.Index = @enumFromInt(sema.air_instructions.len);
5195 gop.value_ptr.* = arg_index.toRef();
5196 inner_block.instructions.appendAssumeCapacity(arg_index);
5197 sema.air_instructions.appendAssumeCapacity(.{
5198 .tag = .arg,
5199 .data = .{ .arg = .{
5200 .ty = Air.internedToRef(param_ty),
5201 .src_index = @intCast(src_param_index),
5202 } },
5203 });
5204 }
5205
5206 func.analysis(ip).state = .in_progress;
5207
5208 const last_arg_index = inner_block.instructions.items.len;
5209
5210 // Save the error trace as our first action in the function.
5211 // If this is unnecessary after all, Liveness will clean it up for us.
5212 const error_return_trace_index = try sema.analyzeSaveErrRetIndex(&inner_block);
5213 sema.error_return_trace_index_on_fn_entry = error_return_trace_index;
5214 inner_block.error_return_trace_index = error_return_trace_index;
5215
5216 sema.analyzeFnBody(&inner_block, fn_info.body) catch |err| switch (err) {
5217 // TODO make these unreachable instead of @panic
5218 error.GenericPoison => @panic("zig compiler bug: GenericPoison"),
5219 error.ComptimeReturn => @panic("zig compiler bug: ComptimeReturn"),
5220 else => |e| return e,
5221 };
5222
5223 for (sema.unresolved_inferred_allocs.keys()) |ptr_inst| {
5224 // The lack of a resolve_inferred_alloc means that this instruction
5225 // is unused so it just has to be a no-op.
5226 sema.air_instructions.set(@intFromEnum(ptr_inst), .{
5227 .tag = .alloc,
5228 .data = .{ .ty = Type.single_const_pointer_to_comptime_int },
5229 });
5230 }
5231
5232 // If we don't get an error return trace from a caller, create our own.
5233 if (func.analysis(ip).calls_or_awaits_errorable_fn and
5234 mod.comp.config.any_error_tracing and
5235 !sema.fn_ret_ty.isError(mod))
5236 {
5237 sema.setupErrorReturnTrace(&inner_block, last_arg_index) catch |err| switch (err) {
5238 // TODO make these unreachable instead of @panic
5239 error.GenericPoison => @panic("zig compiler bug: GenericPoison"),
5240 error.ComptimeReturn => @panic("zig compiler bug: ComptimeReturn"),
5241 error.ComptimeBreak => @panic("zig compiler bug: ComptimeBreak"),
5242 else => |e| return e,
5243 };
5244 }
5245
5246 // Copy the block into place and mark that as the main block.
5247 try sema.air_extra.ensureUnusedCapacity(gpa, @typeInfo(Air.Block).Struct.fields.len +
5248 inner_block.instructions.items.len);
5249 const main_block_index = sema.addExtraAssumeCapacity(Air.Block{
5250 .body_len = @intCast(inner_block.instructions.items.len),
5251 });
5252 sema.air_extra.appendSliceAssumeCapacity(@ptrCast(inner_block.instructions.items));
5253 sema.air_extra.items[@intFromEnum(Air.ExtraIndex.main_block)] = main_block_index;
5254
5255 // Resolving inferred error sets is done *before* setting the function
5256 // state to success, so that "unable to resolve inferred error set" errors
5257 // can be emitted here.
5258 if (sema.fn_ret_ty_ies) |ies| {
5259 sema.resolveInferredErrorSetPtr(&inner_block, .{
5260 .base_node_inst = inner_block.src_base_inst,
5261 .offset = LazySrcLoc.Offset.nodeOffset(0),
5262 }, ies) catch |err| switch (err) {
5263 error.GenericPoison => unreachable,
5264 error.ComptimeReturn => unreachable,
5265 error.ComptimeBreak => unreachable,
5266 error.AnalysisFail => {
5267 // In this case our function depends on a type that had a compile error.
5268 // We should not try to lower this function.
5269 decl.analysis = .dependency_failure;
5270 return error.AnalysisFail;
5271 },
5272 else => |e| return e,
5273 };
5274 assert(ies.resolved != .none);
5275 ip.funcIesResolved(func_index).* = ies.resolved;
5276 }3334 }
3335}
52773336
5278 func.analysis(ip).state = .success;3337pub fn addUnitReference(zcu: *Zcu, src_unit: AnalUnit, referenced_unit: AnalUnit, ref_src: LazySrcLoc) Allocator.Error!void {
52793338 const gpa = zcu.gpa;
5280 // Finally we must resolve the return type and parameter types so that backends3339
5281 // have full access to type information.3340 try zcu.reference_table.ensureUnusedCapacity(gpa, 1);
5282 // Crucially, this happens *after* we set the function state to success above,3341
5283 // so that dependencies on the function body will now be satisfied rather than3342 const ref_idx = zcu.free_references.popOrNull() orelse idx: {
5284 // result in circular dependency errors.3343 _ = try zcu.all_references.addOne(gpa);
5285 sema.resolveFnTypes(fn_ty) catch |err| switch (err) {3344 break :idx zcu.all_references.items.len - 1;
5286 error.GenericPoison => unreachable,
5287 error.ComptimeReturn => unreachable,
5288 error.ComptimeBreak => unreachable,
5289 error.AnalysisFail => {
5290 // In this case our function depends on a type that had a compile error.
5291 // We should not try to lower this function.
5292 decl.analysis = .dependency_failure;
5293 return error.AnalysisFail;
5294 },
5295 else => |e| return e,
5296 };3345 };
52973346
5298 try sema.flushExports();3347 errdefer comptime unreachable;
52993348
5300 return .{3349 const gop = zcu.reference_table.getOrPutAssumeCapacity(src_unit);
5301 .instructions = sema.air_instructions.toOwnedSlice(),3350
5302 .extra = try sema.air_extra.toOwnedSlice(gpa),3351 zcu.all_references.items[ref_idx] = .{
3352 .referenced = referenced_unit,
3353 .next = if (gop.found_existing) gop.value_ptr.* else std.math.maxInt(u32),
3354 .src = ref_src,
5303 };3355 };
3356
3357 gop.value_ptr.* = @intCast(ref_idx);
5304}3358}
53053359
5306pub fn createNamespace(mod: *Module, initialization: Namespace) !Namespace.Index {3360pub fn createNamespace(mod: *Module, initialization: Namespace) !Namespace.Index {
...@@ -5420,117 +3474,7 @@ fn lockAndClearFileCompileError(mod: *Module, file: *File) void {...@@ -5420,117 +3474,7 @@ fn lockAndClearFileCompileError(mod: *Module, file: *File) void {
5420 }3474 }
5421}3475}
54223476
5423/// Called from `Compilation.update`, after everything is done, just before3477pub fn handleUpdateExports(
5424/// reporting compile errors. In this function we emit exported symbol collision
5425/// errors and communicate exported symbols to the linker backend.
5426pub fn processExports(zcu: *Zcu) !void {
5427 const gpa = zcu.gpa;
5428
5429 // First, construct a mapping of every exported value and Decl to the indices of all its different exports.
5430 var decl_exports: std.AutoArrayHashMapUnmanaged(Decl.Index, ArrayListUnmanaged(u32)) = .{};
5431 var value_exports: std.AutoArrayHashMapUnmanaged(InternPool.Index, ArrayListUnmanaged(u32)) = .{};
5432 defer {
5433 for (decl_exports.values()) |*exports| {
5434 exports.deinit(gpa);
5435 }
5436 decl_exports.deinit(gpa);
5437 for (value_exports.values()) |*exports| {
5438 exports.deinit(gpa);
5439 }
5440 value_exports.deinit(gpa);
5441 }
5442
5443 // We note as a heuristic:
5444 // * It is rare to export a value.
5445 // * It is rare for one Decl to be exported multiple times.
5446 // So, this ensureTotalCapacity serves as a reasonable (albeit very approximate) optimization.
5447 try decl_exports.ensureTotalCapacity(gpa, zcu.single_exports.count() + zcu.multi_exports.count());
5448
5449 for (zcu.single_exports.values()) |export_idx| {
5450 const exp = zcu.all_exports.items[export_idx];
5451 const value_ptr, const found_existing = switch (exp.exported) {
5452 .decl_index => |i| gop: {
5453 const gop = try decl_exports.getOrPut(gpa, i);
5454 break :gop .{ gop.value_ptr, gop.found_existing };
5455 },
5456 .value => |i| gop: {
5457 const gop = try value_exports.getOrPut(gpa, i);
5458 break :gop .{ gop.value_ptr, gop.found_existing };
5459 },
5460 };
5461 if (!found_existing) value_ptr.* = .{};
5462 try value_ptr.append(gpa, export_idx);
5463 }
5464
5465 for (zcu.multi_exports.values()) |info| {
5466 for (zcu.all_exports.items[info.index..][0..info.len], info.index..) |exp, export_idx| {
5467 const value_ptr, const found_existing = switch (exp.exported) {
5468 .decl_index => |i| gop: {
5469 const gop = try decl_exports.getOrPut(gpa, i);
5470 break :gop .{ gop.value_ptr, gop.found_existing };
5471 },
5472 .value => |i| gop: {
5473 const gop = try value_exports.getOrPut(gpa, i);
5474 break :gop .{ gop.value_ptr, gop.found_existing };
5475 },
5476 };
5477 if (!found_existing) value_ptr.* = .{};
5478 try value_ptr.append(gpa, @intCast(export_idx));
5479 }
5480 }
5481
5482 // Map symbol names to `Export` for name collision detection.
5483 var symbol_exports: SymbolExports = .{};
5484 defer symbol_exports.deinit(gpa);
5485
5486 for (decl_exports.keys(), decl_exports.values()) |exported_decl, exports_list| {
5487 const exported: Exported = .{ .decl_index = exported_decl };
5488 try processExportsInner(zcu, &symbol_exports, exported, exports_list.items);
5489 }
5490
5491 for (value_exports.keys(), value_exports.values()) |exported_value, exports_list| {
5492 const exported: Exported = .{ .value = exported_value };
5493 try processExportsInner(zcu, &symbol_exports, exported, exports_list.items);
5494 }
5495}
5496
5497const SymbolExports = std.AutoArrayHashMapUnmanaged(InternPool.NullTerminatedString, u32);
5498
5499fn processExportsInner(
5500 zcu: *Zcu,
5501 symbol_exports: *SymbolExports,
5502 exported: Exported,
5503 export_indices: []const u32,
5504) error{OutOfMemory}!void {
5505 const gpa = zcu.gpa;
5506
5507 for (export_indices) |export_idx| {
5508 const new_export = &zcu.all_exports.items[export_idx];
5509 const gop = try symbol_exports.getOrPut(gpa, new_export.opts.name);
5510 if (gop.found_existing) {
5511 new_export.status = .failed_retryable;
5512 try zcu.failed_exports.ensureUnusedCapacity(gpa, 1);
5513 const msg = try ErrorMsg.create(gpa, new_export.src, "exported symbol collision: {}", .{
5514 new_export.opts.name.fmt(&zcu.intern_pool),
5515 });
5516 errdefer msg.destroy(gpa);
5517 const other_export = zcu.all_exports.items[gop.value_ptr.*];
5518 try zcu.errNote(other_export.src, msg, "other symbol here", .{});
5519 zcu.failed_exports.putAssumeCapacityNoClobber(export_idx, msg);
5520 new_export.status = .failed;
5521 } else {
5522 gop.value_ptr.* = export_idx;
5523 }
5524 }
5525 if (zcu.comp.bin_file) |lf| {
5526 try handleUpdateExports(zcu, export_indices, lf.updateExports(zcu, exported, export_indices));
5527 } else if (zcu.llvm_object) |llvm_object| {
5528 if (build_options.only_c) unreachable;
5529 try handleUpdateExports(zcu, export_indices, llvm_object.updateExports(zcu, exported, export_indices));
5530 }
5531}
5532
5533fn handleUpdateExports(
5534 zcu: *Zcu,3478 zcu: *Zcu,
5535 export_indices: []const u32,3479 export_indices: []const u32,
5536 result: link.File.UpdateExportsError!void,3480 result: link.File.UpdateExportsError!void,
...@@ -5551,180 +3495,7 @@ fn handleUpdateExports(...@@ -5551,180 +3495,7 @@ fn handleUpdateExports(
5551 };3495 };
5552}3496}
55533497
5554pub fn populateTestFunctions(3498pub fn reportRetryableFileError(
5555 zcu: *Zcu,
5556 main_progress_node: std.Progress.Node,
5557) !void {
5558 const gpa = zcu.gpa;
5559 const ip = &zcu.intern_pool;
5560 const builtin_mod = zcu.root_mod.getBuiltinDependency();
5561 const builtin_file_index = (zcu.importPkg(builtin_mod) catch unreachable).file_index;
5562 const root_decl_index = zcu.fileRootDecl(builtin_file_index);
5563 const root_decl = zcu.declPtr(root_decl_index.unwrap().?);
5564 const builtin_namespace = zcu.namespacePtr(root_decl.src_namespace);
5565 const test_functions_str = try ip.getOrPutString(gpa, "test_functions", .no_embedded_nulls);
5566 const decl_index = builtin_namespace.decls.getKeyAdapted(
5567 test_functions_str,
5568 DeclAdapter{ .zcu = zcu },
5569 ).?;
5570 {
5571 // We have to call `ensureDeclAnalyzed` here in case `builtin.test_functions`
5572 // was not referenced by start code.
5573 zcu.sema_prog_node = main_progress_node.start("Semantic Analysis", 0);
5574 defer {
5575 zcu.sema_prog_node.end();
5576 zcu.sema_prog_node = undefined;
5577 }
5578 try zcu.ensureDeclAnalyzed(decl_index);
5579 }
5580
5581 const decl = zcu.declPtr(decl_index);
5582 const test_fn_ty = decl.typeOf(zcu).slicePtrFieldType(zcu).childType(zcu);
5583
5584 const array_anon_decl: InternPool.Key.Ptr.BaseAddr.AnonDecl = array: {
5585 // Add zcu.test_functions to an array decl then make the test_functions
5586 // decl reference it as a slice.
5587 const test_fn_vals = try gpa.alloc(InternPool.Index, zcu.test_functions.count());
5588 defer gpa.free(test_fn_vals);
5589
5590 for (test_fn_vals, zcu.test_functions.keys()) |*test_fn_val, test_decl_index| {
5591 const test_decl = zcu.declPtr(test_decl_index);
5592 const test_decl_name = try test_decl.fullyQualifiedName(zcu);
5593 const test_decl_name_len = test_decl_name.length(ip);
5594 const test_name_anon_decl: InternPool.Key.Ptr.BaseAddr.AnonDecl = n: {
5595 const test_name_ty = try zcu.arrayType(.{
5596 .len = test_decl_name_len,
5597 .child = .u8_type,
5598 });
5599 const test_name_val = try zcu.intern(.{ .aggregate = .{
5600 .ty = test_name_ty.toIntern(),
5601 .storage = .{ .bytes = test_decl_name.toString() },
5602 } });
5603 break :n .{
5604 .orig_ty = (try zcu.singleConstPtrType(test_name_ty)).toIntern(),
5605 .val = test_name_val,
5606 };
5607 };
5608
5609 const test_fn_fields = .{
5610 // name
5611 try zcu.intern(.{ .slice = .{
5612 .ty = .slice_const_u8_type,
5613 .ptr = try zcu.intern(.{ .ptr = .{
5614 .ty = .manyptr_const_u8_type,
5615 .base_addr = .{ .anon_decl = test_name_anon_decl },
5616 .byte_offset = 0,
5617 } }),
5618 .len = try zcu.intern(.{ .int = .{
5619 .ty = .usize_type,
5620 .storage = .{ .u64 = test_decl_name_len },
5621 } }),
5622 } }),
5623 // func
5624 try zcu.intern(.{ .ptr = .{
5625 .ty = try zcu.intern(.{ .ptr_type = .{
5626 .child = test_decl.typeOf(zcu).toIntern(),
5627 .flags = .{
5628 .is_const = true,
5629 },
5630 } }),
5631 .base_addr = .{ .decl = test_decl_index },
5632 .byte_offset = 0,
5633 } }),
5634 };
5635 test_fn_val.* = try zcu.intern(.{ .aggregate = .{
5636 .ty = test_fn_ty.toIntern(),
5637 .storage = .{ .elems = &test_fn_fields },
5638 } });
5639 }
5640
5641 const array_ty = try zcu.arrayType(.{
5642 .len = test_fn_vals.len,
5643 .child = test_fn_ty.toIntern(),
5644 .sentinel = .none,
5645 });
5646 const array_val = try zcu.intern(.{ .aggregate = .{
5647 .ty = array_ty.toIntern(),
5648 .storage = .{ .elems = test_fn_vals },
5649 } });
5650 break :array .{
5651 .orig_ty = (try zcu.singleConstPtrType(array_ty)).toIntern(),
5652 .val = array_val,
5653 };
5654 };
5655
5656 {
5657 const new_ty = try zcu.ptrType(.{
5658 .child = test_fn_ty.toIntern(),
5659 .flags = .{
5660 .is_const = true,
5661 .size = .Slice,
5662 },
5663 });
5664 const new_val = decl.val;
5665 const new_init = try zcu.intern(.{ .slice = .{
5666 .ty = new_ty.toIntern(),
5667 .ptr = try zcu.intern(.{ .ptr = .{
5668 .ty = new_ty.slicePtrFieldType(zcu).toIntern(),
5669 .base_addr = .{ .anon_decl = array_anon_decl },
5670 .byte_offset = 0,
5671 } }),
5672 .len = (try zcu.intValue(Type.usize, zcu.test_functions.count())).toIntern(),
5673 } });
5674 ip.mutateVarInit(decl.val.toIntern(), new_init);
5675
5676 // Since we are replacing the Decl's value we must perform cleanup on the
5677 // previous value.
5678 decl.val = new_val;
5679 decl.has_tv = true;
5680 }
5681 {
5682 zcu.codegen_prog_node = main_progress_node.start("Code Generation", 0);
5683 defer {
5684 zcu.codegen_prog_node.end();
5685 zcu.codegen_prog_node = undefined;
5686 }
5687
5688 try zcu.linkerUpdateDecl(decl_index);
5689 }
5690}
5691
5692pub fn linkerUpdateDecl(zcu: *Zcu, decl_index: Decl.Index) !void {
5693 const comp = zcu.comp;
5694
5695 const decl = zcu.declPtr(decl_index);
5696
5697 const codegen_prog_node = zcu.codegen_prog_node.start((try decl.fullyQualifiedName(zcu)).toSlice(&zcu.intern_pool), 0);
5698 defer codegen_prog_node.end();
5699
5700 if (comp.bin_file) |lf| {
5701 lf.updateDecl(zcu, decl_index) catch |err| switch (err) {
5702 error.OutOfMemory => return error.OutOfMemory,
5703 error.AnalysisFail => {
5704 decl.analysis = .codegen_failure;
5705 },
5706 else => {
5707 const gpa = zcu.gpa;
5708 try zcu.failed_analysis.ensureUnusedCapacity(gpa, 1);
5709 zcu.failed_analysis.putAssumeCapacityNoClobber(AnalUnit.wrap(.{ .decl = decl_index }), try ErrorMsg.create(
5710 gpa,
5711 decl.navSrcLoc(zcu),
5712 "unable to codegen: {s}",
5713 .{@errorName(err)},
5714 ));
5715 decl.analysis = .codegen_failure;
5716 try zcu.retryable_failures.append(zcu.gpa, AnalUnit.wrap(.{ .decl = decl_index }));
5717 },
5718 };
5719 } else if (zcu.llvm_object) |llvm_object| {
5720 if (build_options.only_c) unreachable;
5721 llvm_object.updateDecl(zcu, decl_index) catch |err| switch (err) {
5722 error.OutOfMemory => return error.OutOfMemory,
5723 };
5724 }
5725}
5726
5727fn reportRetryableFileError(
5728 zcu: *Zcu,3499 zcu: *Zcu,
5729 file_index: File.Index,3500 file_index: File.Index,
5730 comptime format: []const u8,3501 comptime format: []const u8,
...@@ -5786,351 +3557,13 @@ pub const Feature = enum {...@@ -5786,351 +3557,13 @@ pub const Feature = enum {
5786 /// to generate better machine code in the backends. All backends should migrate to3557 /// to generate better machine code in the backends. All backends should migrate to
5787 /// enabling this feature.3558 /// enabling this feature.
5788 safety_checked_instructions,3559 safety_checked_instructions,
3560 /// If the backend supports running from another thread.
3561 separate_thread,
5789};3562};
57903563
5791pub fn backendSupportsFeature(zcu: Module, feature: Feature) bool {3564pub fn backendSupportsFeature(zcu: Module, comptime feature: Feature) bool {
5792 const cpu_arch = zcu.root_mod.resolved_target.result.cpu.arch;3565 const backend = target_util.zigBackend(zcu.root_mod.resolved_target.result, zcu.comp.config.use_llvm);
5793 const ofmt = zcu.root_mod.resolved_target.result.ofmt;3566 return target_util.backendSupportsFeature(backend, feature);
5794 const use_llvm = zcu.comp.config.use_llvm;
5795 return target_util.backendSupportsFeature(cpu_arch, ofmt, use_llvm, feature);
5796}
5797
5798/// Shortcut for calling `intern_pool.get`.
5799pub fn intern(mod: *Module, key: InternPool.Key) Allocator.Error!InternPool.Index {
5800 return mod.intern_pool.get(mod.gpa, key);
5801}
5802
5803/// Shortcut for calling `intern_pool.getCoerced`.
5804pub fn getCoerced(mod: *Module, val: Value, new_ty: Type) Allocator.Error!Value {
5805 return Value.fromInterned((try mod.intern_pool.getCoerced(mod.gpa, val.toIntern(), new_ty.toIntern())));
5806}
5807
5808pub fn intType(mod: *Module, signedness: std.builtin.Signedness, bits: u16) Allocator.Error!Type {
5809 return Type.fromInterned((try intern(mod, .{ .int_type = .{
5810 .signedness = signedness,
5811 .bits = bits,
5812 } })));
5813}
5814
5815pub fn errorIntType(mod: *Module) std.mem.Allocator.Error!Type {
5816 return mod.intType(.unsigned, mod.errorSetBits());
5817}
5818
5819pub fn arrayType(mod: *Module, info: InternPool.Key.ArrayType) Allocator.Error!Type {
5820 const i = try intern(mod, .{ .array_type = info });
5821 return Type.fromInterned(i);
5822}
5823
5824pub fn vectorType(mod: *Module, info: InternPool.Key.VectorType) Allocator.Error!Type {
5825 const i = try intern(mod, .{ .vector_type = info });
5826 return Type.fromInterned(i);
5827}
5828
5829pub fn optionalType(mod: *Module, child_type: InternPool.Index) Allocator.Error!Type {
5830 const i = try intern(mod, .{ .opt_type = child_type });
5831 return Type.fromInterned(i);
5832}
5833
5834pub fn ptrType(mod: *Module, info: InternPool.Key.PtrType) Allocator.Error!Type {
5835 var canon_info = info;
5836
5837 if (info.flags.size == .C) canon_info.flags.is_allowzero = true;
5838
5839 // Canonicalize non-zero alignment. If it matches the ABI alignment of the pointee
5840 // type, we change it to 0 here. If this causes an assertion trip because the
5841 // pointee type needs to be resolved more, that needs to be done before calling
5842 // this ptr() function.
5843 if (info.flags.alignment != .none and
5844 info.flags.alignment == Type.fromInterned(info.child).abiAlignment(mod))
5845 {
5846 canon_info.flags.alignment = .none;
5847 }
5848
5849 switch (info.flags.vector_index) {
5850 // Canonicalize host_size. If it matches the bit size of the pointee type,
5851 // we change it to 0 here. If this causes an assertion trip, the pointee type
5852 // needs to be resolved before calling this ptr() function.
5853 .none => if (info.packed_offset.host_size != 0) {
5854 const elem_bit_size = Type.fromInterned(info.child).bitSize(mod);
5855 assert(info.packed_offset.bit_offset + elem_bit_size <= info.packed_offset.host_size * 8);
5856 if (info.packed_offset.host_size * 8 == elem_bit_size) {
5857 canon_info.packed_offset.host_size = 0;
5858 }
5859 },
5860 .runtime => {},
5861 _ => assert(@intFromEnum(info.flags.vector_index) < info.packed_offset.host_size),
5862 }
5863
5864 return Type.fromInterned((try intern(mod, .{ .ptr_type = canon_info })));
5865}
5866
5867/// Like `ptrType`, but if `info` specifies an `alignment`, first ensures the pointer
5868/// child type's alignment is resolved so that an invalid alignment is not used.
5869/// In general, prefer this function during semantic analysis.
5870pub fn ptrTypeSema(zcu: *Zcu, info: InternPool.Key.PtrType) SemaError!Type {
5871 if (info.flags.alignment != .none) {
5872 _ = try Type.fromInterned(info.child).abiAlignmentAdvanced(zcu, .sema);
5873 }
5874 return zcu.ptrType(info);
5875}
5876
5877pub fn singleMutPtrType(mod: *Module, child_type: Type) Allocator.Error!Type {
5878 return ptrType(mod, .{ .child = child_type.toIntern() });
5879}
5880
5881pub fn singleConstPtrType(mod: *Module, child_type: Type) Allocator.Error!Type {
5882 return ptrType(mod, .{
5883 .child = child_type.toIntern(),
5884 .flags = .{
5885 .is_const = true,
5886 },
5887 });
5888}
5889
5890pub fn manyConstPtrType(mod: *Module, child_type: Type) Allocator.Error!Type {
5891 return ptrType(mod, .{
5892 .child = child_type.toIntern(),
5893 .flags = .{
5894 .size = .Many,
5895 .is_const = true,
5896 },
5897 });
5898}
5899
5900pub fn adjustPtrTypeChild(mod: *Module, ptr_ty: Type, new_child: Type) Allocator.Error!Type {
5901 var info = ptr_ty.ptrInfo(mod);
5902 info.child = new_child.toIntern();
5903 return mod.ptrType(info);
5904}
5905
5906pub fn funcType(mod: *Module, key: InternPool.GetFuncTypeKey) Allocator.Error!Type {
5907 return Type.fromInterned((try mod.intern_pool.getFuncType(mod.gpa, key)));
5908}
5909
5910/// Use this for `anyframe->T` only.
5911/// For `anyframe`, use the `InternPool.Index.anyframe` tag directly.
5912pub fn anyframeType(mod: *Module, payload_ty: Type) Allocator.Error!Type {
5913 return Type.fromInterned((try intern(mod, .{ .anyframe_type = payload_ty.toIntern() })));
5914}
5915
5916pub fn errorUnionType(mod: *Module, error_set_ty: Type, payload_ty: Type) Allocator.Error!Type {
5917 return Type.fromInterned((try intern(mod, .{ .error_union_type = .{
5918 .error_set_type = error_set_ty.toIntern(),
5919 .payload_type = payload_ty.toIntern(),
5920 } })));
5921}
5922
5923pub fn singleErrorSetType(mod: *Module, name: InternPool.NullTerminatedString) Allocator.Error!Type {
5924 const names: *const [1]InternPool.NullTerminatedString = &name;
5925 const new_ty = try mod.intern_pool.getErrorSetType(mod.gpa, names);
5926 return Type.fromInterned(new_ty);
5927}
5928
5929/// Sorts `names` in place.
5930pub fn errorSetFromUnsortedNames(
5931 mod: *Module,
5932 names: []InternPool.NullTerminatedString,
5933) Allocator.Error!Type {
5934 std.mem.sort(
5935 InternPool.NullTerminatedString,
5936 names,
5937 {},
5938 InternPool.NullTerminatedString.indexLessThan,
5939 );
5940 const new_ty = try mod.intern_pool.getErrorSetType(mod.gpa, names);
5941 return Type.fromInterned(new_ty);
5942}
5943
5944/// Supports only pointers, not pointer-like optionals.
5945pub fn ptrIntValue(mod: *Module, ty: Type, x: u64) Allocator.Error!Value {
5946 assert(ty.zigTypeTag(mod) == .Pointer and !ty.isSlice(mod));
5947 assert(x != 0 or ty.isAllowzeroPtr(mod));
5948 const i = try intern(mod, .{ .ptr = .{
5949 .ty = ty.toIntern(),
5950 .base_addr = .int,
5951 .byte_offset = x,
5952 } });
5953 return Value.fromInterned(i);
5954}
5955
5956/// Creates an enum tag value based on the integer tag value.
5957pub fn enumValue(mod: *Module, ty: Type, tag_int: InternPool.Index) Allocator.Error!Value {
5958 if (std.debug.runtime_safety) {
5959 const tag = ty.zigTypeTag(mod);
5960 assert(tag == .Enum);
5961 }
5962 const i = try intern(mod, .{ .enum_tag = .{
5963 .ty = ty.toIntern(),
5964 .int = tag_int,
5965 } });
5966 return Value.fromInterned(i);
5967}
5968
5969/// Creates an enum tag value based on the field index according to source code
5970/// declaration order.
5971pub fn enumValueFieldIndex(mod: *Module, ty: Type, field_index: u32) Allocator.Error!Value {
5972 const ip = &mod.intern_pool;
5973 const gpa = mod.gpa;
5974 const enum_type = ip.loadEnumType(ty.toIntern());
5975
5976 if (enum_type.values.len == 0) {
5977 // Auto-numbered fields.
5978 return Value.fromInterned((try ip.get(gpa, .{ .enum_tag = .{
5979 .ty = ty.toIntern(),
5980 .int = try ip.get(gpa, .{ .int = .{
5981 .ty = enum_type.tag_ty,
5982 .storage = .{ .u64 = field_index },
5983 } }),
5984 } })));
5985 }
5986
5987 return Value.fromInterned((try ip.get(gpa, .{ .enum_tag = .{
5988 .ty = ty.toIntern(),
5989 .int = enum_type.values.get(ip)[field_index],
5990 } })));
5991}
5992
5993pub fn undefValue(mod: *Module, ty: Type) Allocator.Error!Value {
5994 return Value.fromInterned((try mod.intern(.{ .undef = ty.toIntern() })));
5995}
5996
5997pub fn undefRef(mod: *Module, ty: Type) Allocator.Error!Air.Inst.Ref {
5998 return Air.internedToRef((try mod.undefValue(ty)).toIntern());
5999}
6000
6001pub fn intValue(mod: *Module, ty: Type, x: anytype) Allocator.Error!Value {
6002 if (std.math.cast(u64, x)) |casted| return intValue_u64(mod, ty, casted);
6003 if (std.math.cast(i64, x)) |casted| return intValue_i64(mod, ty, casted);
6004 var limbs_buffer: [4]usize = undefined;
6005 var big_int = BigIntMutable.init(&limbs_buffer, x);
6006 return intValue_big(mod, ty, big_int.toConst());
6007}
6008
6009pub fn intRef(mod: *Module, ty: Type, x: anytype) Allocator.Error!Air.Inst.Ref {
6010 return Air.internedToRef((try mod.intValue(ty, x)).toIntern());
6011}
6012
6013pub fn intValue_big(mod: *Module, ty: Type, x: BigIntConst) Allocator.Error!Value {
6014 const i = try intern(mod, .{ .int = .{
6015 .ty = ty.toIntern(),
6016 .storage = .{ .big_int = x },
6017 } });
6018 return Value.fromInterned(i);
6019}
6020
6021pub fn intValue_u64(mod: *Module, ty: Type, x: u64) Allocator.Error!Value {
6022 const i = try intern(mod, .{ .int = .{
6023 .ty = ty.toIntern(),
6024 .storage = .{ .u64 = x },
6025 } });
6026 return Value.fromInterned(i);
6027}
6028
6029pub fn intValue_i64(mod: *Module, ty: Type, x: i64) Allocator.Error!Value {
6030 const i = try intern(mod, .{ .int = .{
6031 .ty = ty.toIntern(),
6032 .storage = .{ .i64 = x },
6033 } });
6034 return Value.fromInterned(i);
6035}
6036
6037pub fn unionValue(mod: *Module, union_ty: Type, tag: Value, val: Value) Allocator.Error!Value {
6038 const i = try intern(mod, .{ .un = .{
6039 .ty = union_ty.toIntern(),
6040 .tag = tag.toIntern(),
6041 .val = val.toIntern(),
6042 } });
6043 return Value.fromInterned(i);
6044}
6045
6046/// This function casts the float representation down to the representation of the type, potentially
6047/// losing data if the representation wasn't correct.
6048pub fn floatValue(mod: *Module, ty: Type, x: anytype) Allocator.Error!Value {
6049 const storage: InternPool.Key.Float.Storage = switch (ty.floatBits(mod.getTarget())) {
6050 16 => .{ .f16 = @as(f16, @floatCast(x)) },
6051 32 => .{ .f32 = @as(f32, @floatCast(x)) },
6052 64 => .{ .f64 = @as(f64, @floatCast(x)) },
6053 80 => .{ .f80 = @as(f80, @floatCast(x)) },
6054 128 => .{ .f128 = @as(f128, @floatCast(x)) },
6055 else => unreachable,
6056 };
6057 const i = try intern(mod, .{ .float = .{
6058 .ty = ty.toIntern(),
6059 .storage = storage,
6060 } });
6061 return Value.fromInterned(i);
6062}
6063
6064pub fn nullValue(mod: *Module, opt_ty: Type) Allocator.Error!Value {
6065 const ip = &mod.intern_pool;
6066 assert(ip.isOptionalType(opt_ty.toIntern()));
6067 const result = try ip.get(mod.gpa, .{ .opt = .{
6068 .ty = opt_ty.toIntern(),
6069 .val = .none,
6070 } });
6071 return Value.fromInterned(result);
6072}
6073
6074pub fn smallestUnsignedInt(mod: *Module, max: u64) Allocator.Error!Type {
6075 return intType(mod, .unsigned, Type.smallestUnsignedBits(max));
6076}
6077
6078/// Returns the smallest possible integer type containing both `min` and
6079/// `max`. Asserts that neither value is undef.
6080/// TODO: if #3806 is implemented, this becomes trivial
6081pub fn intFittingRange(mod: *Module, min: Value, max: Value) !Type {
6082 assert(!min.isUndef(mod));
6083 assert(!max.isUndef(mod));
6084
6085 if (std.debug.runtime_safety) {
6086 assert(Value.order(min, max, mod).compare(.lte));
6087 }
6088
6089 const sign = min.orderAgainstZero(mod) == .lt;
6090
6091 const min_val_bits = intBitsForValue(mod, min, sign);
6092 const max_val_bits = intBitsForValue(mod, max, sign);
6093
6094 return mod.intType(
6095 if (sign) .signed else .unsigned,
6096 @max(min_val_bits, max_val_bits),
6097 );
6098}
6099
6100/// Given a value representing an integer, returns the number of bits necessary to represent
6101/// this value in an integer. If `sign` is true, returns the number of bits necessary in a
6102/// twos-complement integer; otherwise in an unsigned integer.
6103/// Asserts that `val` is not undef. If `val` is negative, asserts that `sign` is true.
6104pub fn intBitsForValue(mod: *Module, val: Value, sign: bool) u16 {
6105 assert(!val.isUndef(mod));
6106
6107 const key = mod.intern_pool.indexToKey(val.toIntern());
6108 switch (key.int.storage) {
6109 .i64 => |x| {
6110 if (std.math.cast(u64, x)) |casted| return Type.smallestUnsignedBits(casted) + @intFromBool(sign);
6111 assert(sign);
6112 // Protect against overflow in the following negation.
6113 if (x == std.math.minInt(i64)) return 64;
6114 return Type.smallestUnsignedBits(@as(u64, @intCast(-(x + 1)))) + 1;
6115 },
6116 .u64 => |x| {
6117 return Type.smallestUnsignedBits(x) + @intFromBool(sign);
6118 },
6119 .big_int => |big| {
6120 if (big.positive) return @as(u16, @intCast(big.bitCountAbs() + @intFromBool(sign)));
6121
6122 // Zero is still a possibility, in which case unsigned is fine
6123 if (big.eqlZero()) return 0;
6124
6125 return @as(u16, @intCast(big.bitCountTwosComp()));
6126 },
6127 .lazy_align => |lazy_ty| {
6128 return Type.smallestUnsignedBits(Type.fromInterned(lazy_ty).abiAlignment(mod).toByteUnits() orelse 0) + @intFromBool(sign);
6129 },
6130 .lazy_size => |lazy_ty| {
6131 return Type.smallestUnsignedBits(Type.fromInterned(lazy_ty).abiSize(mod)) + @intFromBool(sign);
6132 },
6133 }
6134}3567}
61353568
6136pub const AtomicPtrAlignmentError = error{3569pub const AtomicPtrAlignmentError = error{
...@@ -6371,101 +3804,6 @@ pub const UnionLayout = struct {...@@ -6371,101 +3804,6 @@ pub const UnionLayout = struct {
6371 padding: u32,3804 padding: u32,
6372};3805};
63733806
6374pub fn getUnionLayout(mod: *Module, loaded_union: InternPool.LoadedUnionType) UnionLayout {
6375 const ip = &mod.intern_pool;
6376 assert(loaded_union.haveLayout(ip));
6377 var most_aligned_field: u32 = undefined;
6378 var most_aligned_field_size: u64 = undefined;
6379 var biggest_field: u32 = undefined;
6380 var payload_size: u64 = 0;
6381 var payload_align: Alignment = .@"1";
6382 for (loaded_union.field_types.get(ip), 0..) |field_ty, field_index| {
6383 if (!Type.fromInterned(field_ty).hasRuntimeBitsIgnoreComptime(mod)) continue;
6384
6385 const explicit_align = loaded_union.fieldAlign(ip, field_index);
6386 const field_align = if (explicit_align != .none)
6387 explicit_align
6388 else
6389 Type.fromInterned(field_ty).abiAlignment(mod);
6390 const field_size = Type.fromInterned(field_ty).abiSize(mod);
6391 if (field_size > payload_size) {
6392 payload_size = field_size;
6393 biggest_field = @intCast(field_index);
6394 }
6395 if (field_align.compare(.gte, payload_align)) {
6396 payload_align = field_align;
6397 most_aligned_field = @intCast(field_index);
6398 most_aligned_field_size = field_size;
6399 }
6400 }
6401 const have_tag = loaded_union.flagsPtr(ip).runtime_tag.hasTag();
6402 if (!have_tag or !Type.fromInterned(loaded_union.enum_tag_ty).hasRuntimeBits(mod)) {
6403 return .{
6404 .abi_size = payload_align.forward(payload_size),
6405 .abi_align = payload_align,
6406 .most_aligned_field = most_aligned_field,
6407 .most_aligned_field_size = most_aligned_field_size,
6408 .biggest_field = biggest_field,
6409 .payload_size = payload_size,
6410 .payload_align = payload_align,
6411 .tag_align = .none,
6412 .tag_size = 0,
6413 .padding = 0,
6414 };
6415 }
6416
6417 const tag_size = Type.fromInterned(loaded_union.enum_tag_ty).abiSize(mod);
6418 const tag_align = Type.fromInterned(loaded_union.enum_tag_ty).abiAlignment(mod).max(.@"1");
6419 return .{
6420 .abi_size = loaded_union.size(ip).*,
6421 .abi_align = tag_align.max(payload_align),
6422 .most_aligned_field = most_aligned_field,
6423 .most_aligned_field_size = most_aligned_field_size,
6424 .biggest_field = biggest_field,
6425 .payload_size = payload_size,
6426 .payload_align = payload_align,
6427 .tag_align = tag_align,
6428 .tag_size = tag_size,
6429 .padding = loaded_union.padding(ip).*,
6430 };
6431}
6432
6433pub fn unionAbiSize(mod: *Module, loaded_union: InternPool.LoadedUnionType) u64 {
6434 return mod.getUnionLayout(loaded_union).abi_size;
6435}
6436
6437/// Returns 0 if the union is represented with 0 bits at runtime.
6438pub fn unionAbiAlignment(mod: *Module, loaded_union: InternPool.LoadedUnionType) Alignment {
6439 const ip = &mod.intern_pool;
6440 const have_tag = loaded_union.flagsPtr(ip).runtime_tag.hasTag();
6441 var max_align: Alignment = .none;
6442 if (have_tag) max_align = Type.fromInterned(loaded_union.enum_tag_ty).abiAlignment(mod);
6443 for (loaded_union.field_types.get(ip), 0..) |field_ty, field_index| {
6444 if (!Type.fromInterned(field_ty).hasRuntimeBits(mod)) continue;
6445
6446 const field_align = mod.unionFieldNormalAlignment(loaded_union, @intCast(field_index));
6447 max_align = max_align.max(field_align);
6448 }
6449 return max_align;
6450}
6451
6452/// Returns the field alignment of a non-packed union. Asserts the layout is not packed.
6453pub fn unionFieldNormalAlignment(zcu: *Zcu, loaded_union: InternPool.LoadedUnionType, field_index: u32) Alignment {
6454 return zcu.unionFieldNormalAlignmentAdvanced(loaded_union, field_index, .normal) catch unreachable;
6455}
6456
6457/// Returns the field alignment of a non-packed union. Asserts the layout is not packed.
6458/// If `strat` is `.sema`, may perform type resolution.
6459pub fn unionFieldNormalAlignmentAdvanced(zcu: *Zcu, loaded_union: InternPool.LoadedUnionType, field_index: u32, strat: Type.ResolveStrat) SemaError!Alignment {
6460 const ip = &zcu.intern_pool;
6461 assert(loaded_union.flagsPtr(ip).layout != .@"packed");
6462 const field_align = loaded_union.fieldAlign(ip, field_index);
6463 if (field_align != .none) return field_align;
6464 const field_ty = Type.fromInterned(loaded_union.field_types.get(ip)[field_index]);
6465 if (field_ty.isNoReturn(zcu)) return .none;
6466 return (try field_ty.abiAlignmentAdvanced(zcu, strat.toLazy())).scalar;
6467}
6468
6469/// Returns the index of the active field, given the current tag value3807/// Returns the index of the active field, given the current tag value
6470pub fn unionTagFieldIndex(mod: *Module, loaded_union: InternPool.LoadedUnionType, enum_tag: Value) ?u32 {3808pub fn unionTagFieldIndex(mod: *Module, loaded_union: InternPool.LoadedUnionType, enum_tag: Value) ?u32 {
6471 const ip = &mod.intern_pool;3809 const ip = &mod.intern_pool;
...@@ -6474,63 +3812,6 @@ pub fn unionTagFieldIndex(mod: *Module, loaded_union: InternPool.LoadedUnionType...@@ -6474,63 +3812,6 @@ pub fn unionTagFieldIndex(mod: *Module, loaded_union: InternPool.LoadedUnionType
6474 return loaded_union.loadTagType(ip).tagValueIndex(ip, enum_tag.toIntern());3812 return loaded_union.loadTagType(ip).tagValueIndex(ip, enum_tag.toIntern());
6475}3813}
64763814
6477/// Returns the field alignment of a non-packed struct. Asserts the layout is not packed.
6478pub fn structFieldAlignment(
6479 zcu: *Zcu,
6480 explicit_alignment: InternPool.Alignment,
6481 field_ty: Type,
6482 layout: std.builtin.Type.ContainerLayout,
6483) Alignment {
6484 return zcu.structFieldAlignmentAdvanced(explicit_alignment, field_ty, layout, .normal) catch unreachable;
6485}
6486
6487/// Returns the field alignment of a non-packed struct. Asserts the layout is not packed.
6488/// If `strat` is `.sema`, may perform type resolution.
6489pub fn structFieldAlignmentAdvanced(
6490 zcu: *Zcu,
6491 explicit_alignment: InternPool.Alignment,
6492 field_ty: Type,
6493 layout: std.builtin.Type.ContainerLayout,
6494 strat: Type.ResolveStrat,
6495) SemaError!Alignment {
6496 assert(layout != .@"packed");
6497 if (explicit_alignment != .none) return explicit_alignment;
6498 const ty_abi_align = (try field_ty.abiAlignmentAdvanced(zcu, strat.toLazy())).scalar;
6499 switch (layout) {
6500 .@"packed" => unreachable,
6501 .auto => if (zcu.getTarget().ofmt != .c) return ty_abi_align,
6502 .@"extern" => {},
6503 }
6504 // extern
6505 if (field_ty.isAbiInt(zcu) and field_ty.intInfo(zcu).bits >= 128) {
6506 return ty_abi_align.maxStrict(.@"16");
6507 }
6508 return ty_abi_align;
6509}
6510
6511/// https://github.com/ziglang/zig/issues/17178 explored storing these bit offsets
6512/// into the packed struct InternPool data rather than computing this on the
6513/// fly, however it was found to perform worse when measured on real world
6514/// projects.
6515pub fn structPackedFieldBitOffset(
6516 mod: *Module,
6517 struct_type: InternPool.LoadedStructType,
6518 field_index: u32,
6519) u16 {
6520 const ip = &mod.intern_pool;
6521 assert(struct_type.layout == .@"packed");
6522 assert(struct_type.haveLayout(ip));
6523 var bit_sum: u64 = 0;
6524 for (0..struct_type.field_types.len) |i| {
6525 if (i == field_index) {
6526 return @intCast(bit_sum);
6527 }
6528 const field_ty = Type.fromInterned(struct_type.field_types.get(ip)[i]);
6529 bit_sum += field_ty.bitSize(mod);
6530 }
6531 unreachable; // index out of bounds
6532}
6533
6534pub const ResolvedReference = struct {3815pub const ResolvedReference = struct {
6535 referencer: AnalUnit,3816 referencer: AnalUnit,
6536 src: LazySrcLoc,3817 src: LazySrcLoc,
...@@ -6564,33 +3845,6 @@ pub fn resolveReferences(zcu: *Zcu) !std.AutoHashMapUnmanaged(AnalUnit, Resolved...@@ -6564,33 +3845,6 @@ pub fn resolveReferences(zcu: *Zcu) !std.AutoHashMapUnmanaged(AnalUnit, Resolved
6564 return result;3845 return result;
6565}3846}
65663847
6567pub fn getBuiltin(zcu: *Zcu, name: []const u8) Allocator.Error!Air.Inst.Ref {
6568 const decl_index = try zcu.getBuiltinDecl(name);
6569 zcu.ensureDeclAnalyzed(decl_index) catch @panic("std.builtin is corrupt");
6570 return Air.internedToRef(zcu.declPtr(decl_index).val.toIntern());
6571}
6572
6573pub fn getBuiltinDecl(zcu: *Zcu, name: []const u8) Allocator.Error!InternPool.DeclIndex {
6574 const gpa = zcu.gpa;
6575 const ip = &zcu.intern_pool;
6576 const std_file_imported = zcu.importPkg(zcu.std_mod) catch @panic("failed to import lib/std.zig");
6577 const std_file_root_decl = zcu.fileRootDecl(std_file_imported.file_index).unwrap().?;
6578 const std_namespace = zcu.declPtr(std_file_root_decl).getOwnedInnerNamespace(zcu).?;
6579 const builtin_str = try ip.getOrPutString(gpa, "builtin", .no_embedded_nulls);
6580 const builtin_decl = std_namespace.decls.getKeyAdapted(builtin_str, Zcu.DeclAdapter{ .zcu = zcu }) orelse @panic("lib/std.zig is corrupt and missing 'builtin'");
6581 zcu.ensureDeclAnalyzed(builtin_decl) catch @panic("std.builtin is corrupt");
6582 const builtin_namespace = zcu.declPtr(builtin_decl).getInnerNamespace(zcu) orelse @panic("std.builtin is corrupt");
6583 const name_str = try ip.getOrPutString(gpa, name, .no_embedded_nulls);
6584 return builtin_namespace.decls.getKeyAdapted(name_str, Zcu.DeclAdapter{ .zcu = zcu }) orelse @panic("lib/std/builtin.zig is corrupt");
6585}
6586
6587pub fn getBuiltinType(zcu: *Zcu, name: []const u8) Allocator.Error!Type {
6588 const ty_inst = try zcu.getBuiltin(name);
6589 const ty = Type.fromInterned(ty_inst.toInterned() orelse @panic("std.builtin is corrupt"));
6590 ty.resolveFully(zcu) catch @panic("std.builtin is corrupt");
6591 return ty;
6592}
6593
6594pub fn fileByIndex(zcu: *const Zcu, i: File.Index) *File {3848pub fn fileByIndex(zcu: *const Zcu, i: File.Index) *File {
6595 return zcu.import_table.values()[@intFromEnum(i)];3849 return zcu.import_table.values()[@intFromEnum(i)];
6596}3850}
src/Zcu/PerThread.zig created+2825
...@@ -0,0 +1,2825 @@
1zcu: *Zcu,
2
3/// Dense, per-thread unique index.
4tid: Id,
5
6pub const Id = if (InternPool.single_threaded) enum { main } else enum(u8) { main, _ };
7
8pub fn astGenFile(
9 pt: Zcu.PerThread,
10 file: *Zcu.File,
11 /// This parameter is provided separately from `file` because it is not
12 /// safe to access `import_table` without a lock, and this index is needed
13 /// in the call to `updateZirRefs`.
14 file_index: Zcu.File.Index,
15 path_digest: Cache.BinDigest,
16 opt_root_decl: Zcu.Decl.OptionalIndex,
17) !void {
18 assert(!file.mod.isBuiltin());
19
20 const tracy = trace(@src());
21 defer tracy.end();
22
23 const zcu = pt.zcu;
24 const comp = zcu.comp;
25 const gpa = zcu.gpa;
26
27 // In any case we need to examine the stat of the file to determine the course of action.
28 var source_file = try file.mod.root.openFile(file.sub_file_path, .{});
29 defer source_file.close();
30
31 const stat = try source_file.stat();
32
33 const want_local_cache = file.mod == zcu.main_mod;
34 const hex_digest = Cache.binToHex(path_digest);
35 const cache_directory = if (want_local_cache) zcu.local_zir_cache else zcu.global_zir_cache;
36 const zir_dir = cache_directory.handle;
37
38 // Determine whether we need to reload the file from disk and redo parsing and AstGen.
39 var lock: std.fs.File.Lock = switch (file.status) {
40 .never_loaded, .retryable_failure => lock: {
41 // First, load the cached ZIR code, if any.
42 log.debug("AstGen checking cache: {s} (local={}, digest={s})", .{
43 file.sub_file_path, want_local_cache, &hex_digest,
44 });
45
46 break :lock .shared;
47 },
48 .parse_failure, .astgen_failure, .success_zir => lock: {
49 const unchanged_metadata =
50 stat.size == file.stat.size and
51 stat.mtime == file.stat.mtime and
52 stat.inode == file.stat.inode;
53
54 if (unchanged_metadata) {
55 log.debug("unmodified metadata of file: {s}", .{file.sub_file_path});
56 return;
57 }
58
59 log.debug("metadata changed: {s}", .{file.sub_file_path});
60
61 break :lock .exclusive;
62 },
63 };
64
65 // We ask for a lock in order to coordinate with other zig processes.
66 // If another process is already working on this file, we will get the cached
67 // version. Likewise if we're working on AstGen and another process asks for
68 // the cached file, they'll get it.
69 const cache_file = while (true) {
70 break zir_dir.createFile(&hex_digest, .{
71 .read = true,
72 .truncate = false,
73 .lock = lock,
74 }) catch |err| switch (err) {
75 error.NotDir => unreachable, // no dir components
76 error.InvalidUtf8 => unreachable, // it's a hex encoded name
77 error.InvalidWtf8 => unreachable, // it's a hex encoded name
78 error.BadPathName => unreachable, // it's a hex encoded name
79 error.NameTooLong => unreachable, // it's a fixed size name
80 error.PipeBusy => unreachable, // it's not a pipe
81 error.WouldBlock => unreachable, // not asking for non-blocking I/O
82 // There are no dir components, so you would think that this was
83 // unreachable, however we have observed on macOS two processes racing
84 // to do openat() with O_CREAT manifest in ENOENT.
85 error.FileNotFound => continue,
86
87 else => |e| return e, // Retryable errors are handled at callsite.
88 };
89 };
90 defer cache_file.close();
91
92 while (true) {
93 update: {
94 // First we read the header to determine the lengths of arrays.
95 const header = cache_file.reader().readStruct(Zir.Header) catch |err| switch (err) {
96 // This can happen if Zig bails out of this function between creating
97 // the cached file and writing it.
98 error.EndOfStream => break :update,
99 else => |e| return e,
100 };
101 const unchanged_metadata =
102 stat.size == header.stat_size and
103 stat.mtime == header.stat_mtime and
104 stat.inode == header.stat_inode;
105
106 if (!unchanged_metadata) {
107 log.debug("AstGen cache stale: {s}", .{file.sub_file_path});
108 break :update;
109 }
110 log.debug("AstGen cache hit: {s} instructions_len={d}", .{
111 file.sub_file_path, header.instructions_len,
112 });
113
114 file.zir = Zcu.loadZirCacheBody(gpa, header, cache_file) catch |err| switch (err) {
115 error.UnexpectedFileSize => {
116 log.warn("unexpected EOF reading cached ZIR for {s}", .{file.sub_file_path});
117 break :update;
118 },
119 else => |e| return e,
120 };
121 file.zir_loaded = true;
122 file.stat = .{
123 .size = header.stat_size,
124 .inode = header.stat_inode,
125 .mtime = header.stat_mtime,
126 };
127 file.status = .success_zir;
128 log.debug("AstGen cached success: {s}", .{file.sub_file_path});
129
130 // TODO don't report compile errors until Sema @importFile
131 if (file.zir.hasCompileErrors()) {
132 {
133 comp.mutex.lock();
134 defer comp.mutex.unlock();
135 try zcu.failed_files.putNoClobber(gpa, file, null);
136 }
137 file.status = .astgen_failure;
138 return error.AnalysisFail;
139 }
140 return;
141 }
142
143 // If we already have the exclusive lock then it is our job to update.
144 if (builtin.os.tag == .wasi or lock == .exclusive) break;
145 // Otherwise, unlock to give someone a chance to get the exclusive lock
146 // and then upgrade to an exclusive lock.
147 cache_file.unlock();
148 lock = .exclusive;
149 try cache_file.lock(lock);
150 }
151
152 // The cache is definitely stale so delete the contents to avoid an underwrite later.
153 cache_file.setEndPos(0) catch |err| switch (err) {
154 error.FileTooBig => unreachable, // 0 is not too big
155
156 else => |e| return e,
157 };
158
159 pt.lockAndClearFileCompileError(file);
160
161 // If the previous ZIR does not have compile errors, keep it around
162 // in case parsing or new ZIR fails. In case of successful ZIR update
163 // at the end of this function we will free it.
164 // We keep the previous ZIR loaded so that we can use it
165 // for the update next time it does not have any compile errors. This avoids
166 // needlessly tossing out semantic analysis work when an error is
167 // temporarily introduced.
168 if (file.zir_loaded and !file.zir.hasCompileErrors()) {
169 assert(file.prev_zir == null);
170 const prev_zir_ptr = try gpa.create(Zir);
171 file.prev_zir = prev_zir_ptr;
172 prev_zir_ptr.* = file.zir;
173 file.zir = undefined;
174 file.zir_loaded = false;
175 }
176 file.unload(gpa);
177
178 if (stat.size > std.math.maxInt(u32))
179 return error.FileTooBig;
180
181 const source = try gpa.allocSentinel(u8, @as(usize, @intCast(stat.size)), 0);
182 defer if (!file.source_loaded) gpa.free(source);
183 const amt = try source_file.readAll(source);
184 if (amt != stat.size)
185 return error.UnexpectedEndOfFile;
186
187 file.stat = .{
188 .size = stat.size,
189 .inode = stat.inode,
190 .mtime = stat.mtime,
191 };
192 file.source = source;
193 file.source_loaded = true;
194
195 file.tree = try Ast.parse(gpa, source, .zig);
196 file.tree_loaded = true;
197
198 // Any potential AST errors are converted to ZIR errors here.
199 file.zir = try AstGen.generate(gpa, file.tree);
200 file.zir_loaded = true;
201 file.status = .success_zir;
202 log.debug("AstGen fresh success: {s}", .{file.sub_file_path});
203
204 const safety_buffer = if (Zcu.data_has_safety_tag)
205 try gpa.alloc([8]u8, file.zir.instructions.len)
206 else
207 undefined;
208 defer if (Zcu.data_has_safety_tag) gpa.free(safety_buffer);
209 const data_ptr = if (Zcu.data_has_safety_tag)
210 if (file.zir.instructions.len == 0)
211 @as([*]const u8, undefined)
212 else
213 @as([*]const u8, @ptrCast(safety_buffer.ptr))
214 else
215 @as([*]const u8, @ptrCast(file.zir.instructions.items(.data).ptr));
216 if (Zcu.data_has_safety_tag) {
217 // The `Data` union has a safety tag but in the file format we store it without.
218 for (file.zir.instructions.items(.data), 0..) |*data, i| {
219 const as_struct: *const Zcu.HackDataLayout = @ptrCast(data);
220 safety_buffer[i] = as_struct.data;
221 }
222 }
223
224 const header: Zir.Header = .{
225 .instructions_len = @as(u32, @intCast(file.zir.instructions.len)),
226 .string_bytes_len = @as(u32, @intCast(file.zir.string_bytes.len)),
227 .extra_len = @as(u32, @intCast(file.zir.extra.len)),
228
229 .stat_size = stat.size,
230 .stat_inode = stat.inode,
231 .stat_mtime = stat.mtime,
232 };
233 var iovecs = [_]std.posix.iovec_const{
234 .{
235 .base = @as([*]const u8, @ptrCast(&header)),
236 .len = @sizeOf(Zir.Header),
237 },
238 .{
239 .base = @as([*]const u8, @ptrCast(file.zir.instructions.items(.tag).ptr)),
240 .len = file.zir.instructions.len,
241 },
242 .{
243 .base = data_ptr,
244 .len = file.zir.instructions.len * 8,
245 },
246 .{
247 .base = file.zir.string_bytes.ptr,
248 .len = file.zir.string_bytes.len,
249 },
250 .{
251 .base = @as([*]const u8, @ptrCast(file.zir.extra.ptr)),
252 .len = file.zir.extra.len * 4,
253 },
254 };
255 cache_file.writevAll(&iovecs) catch |err| {
256 log.warn("unable to write cached ZIR code for {}{s} to {}{s}: {s}", .{
257 file.mod.root, file.sub_file_path, cache_directory, &hex_digest, @errorName(err),
258 });
259 };
260
261 if (file.zir.hasCompileErrors()) {
262 {
263 comp.mutex.lock();
264 defer comp.mutex.unlock();
265 try zcu.failed_files.putNoClobber(gpa, file, null);
266 }
267 file.status = .astgen_failure;
268 return error.AnalysisFail;
269 }
270
271 if (file.prev_zir) |prev_zir| {
272 try pt.updateZirRefs(file, file_index, prev_zir.*);
273 // No need to keep previous ZIR.
274 prev_zir.deinit(gpa);
275 gpa.destroy(prev_zir);
276 file.prev_zir = null;
277 }
278
279 if (opt_root_decl.unwrap()) |root_decl| {
280 // The root of this file must be re-analyzed, since the file has changed.
281 comp.mutex.lock();
282 defer comp.mutex.unlock();
283
284 log.debug("outdated root Decl: {}", .{root_decl});
285 try zcu.outdated_file_root.put(gpa, root_decl, {});
286 }
287}
288
289/// This is called from the AstGen thread pool, so must acquire
290/// the Compilation mutex when acting on shared state.
291fn updateZirRefs(pt: Zcu.PerThread, file: *Zcu.File, file_index: Zcu.File.Index, old_zir: Zir) !void {
292 const zcu = pt.zcu;
293 const gpa = zcu.gpa;
294 const new_zir = file.zir;
295
296 var inst_map: std.AutoHashMapUnmanaged(Zir.Inst.Index, Zir.Inst.Index) = .{};
297 defer inst_map.deinit(gpa);
298
299 try Zcu.mapOldZirToNew(gpa, old_zir, new_zir, &inst_map);
300
301 const old_tag = old_zir.instructions.items(.tag);
302 const old_data = old_zir.instructions.items(.data);
303
304 // TODO: this should be done after all AstGen workers complete, to avoid
305 // iterating over this full set for every updated file.
306 for (zcu.intern_pool.tracked_insts.keys(), 0..) |*ti, idx_raw| {
307 const ti_idx: InternPool.TrackedInst.Index = @enumFromInt(idx_raw);
308 if (ti.file != file_index) continue;
309 const old_inst = ti.inst;
310 ti.inst = inst_map.get(ti.inst) orelse {
311 // Tracking failed for this instruction. Invalidate associated `src_hash` deps.
312 zcu.comp.mutex.lock();
313 defer zcu.comp.mutex.unlock();
314 log.debug("tracking failed for %{d}", .{old_inst});
315 try zcu.markDependeeOutdated(.{ .src_hash = ti_idx });
316 continue;
317 };
318
319 if (old_zir.getAssociatedSrcHash(old_inst)) |old_hash| hash_changed: {
320 if (new_zir.getAssociatedSrcHash(ti.inst)) |new_hash| {
321 if (std.zig.srcHashEql(old_hash, new_hash)) {
322 break :hash_changed;
323 }
324 log.debug("hash for (%{d} -> %{d}) changed: {} -> {}", .{
325 old_inst,
326 ti.inst,
327 std.fmt.fmtSliceHexLower(&old_hash),
328 std.fmt.fmtSliceHexLower(&new_hash),
329 });
330 }
331 // The source hash associated with this instruction changed - invalidate relevant dependencies.
332 zcu.comp.mutex.lock();
333 defer zcu.comp.mutex.unlock();
334 try zcu.markDependeeOutdated(.{ .src_hash = ti_idx });
335 }
336
337 // If this is a `struct_decl` etc, we must invalidate any outdated namespace dependencies.
338 const has_namespace = switch (old_tag[@intFromEnum(old_inst)]) {
339 .extended => switch (old_data[@intFromEnum(old_inst)].extended.opcode) {
340 .struct_decl, .union_decl, .opaque_decl, .enum_decl => true,
341 else => false,
342 },
343 else => false,
344 };
345 if (!has_namespace) continue;
346
347 var old_names: std.AutoArrayHashMapUnmanaged(InternPool.NullTerminatedString, void) = .{};
348 defer old_names.deinit(zcu.gpa);
349 {
350 var it = old_zir.declIterator(old_inst);
351 while (it.next()) |decl_inst| {
352 const decl_name = old_zir.getDeclaration(decl_inst)[0].name;
353 switch (decl_name) {
354 .@"comptime", .@"usingnamespace", .unnamed_test, .decltest => continue,
355 _ => if (decl_name.isNamedTest(old_zir)) continue,
356 }
357 const name_zir = decl_name.toString(old_zir).?;
358 const name_ip = try zcu.intern_pool.getOrPutString(
359 zcu.gpa,
360 pt.tid,
361 old_zir.nullTerminatedString(name_zir),
362 .no_embedded_nulls,
363 );
364 try old_names.put(zcu.gpa, name_ip, {});
365 }
366 }
367 var any_change = false;
368 {
369 var it = new_zir.declIterator(ti.inst);
370 while (it.next()) |decl_inst| {
371 const decl_name = old_zir.getDeclaration(decl_inst)[0].name;
372 switch (decl_name) {
373 .@"comptime", .@"usingnamespace", .unnamed_test, .decltest => continue,
374 _ => if (decl_name.isNamedTest(old_zir)) continue,
375 }
376 const name_zir = decl_name.toString(old_zir).?;
377 const name_ip = try zcu.intern_pool.getOrPutString(
378 zcu.gpa,
379 pt.tid,
380 old_zir.nullTerminatedString(name_zir),
381 .no_embedded_nulls,
382 );
383 if (!old_names.swapRemove(name_ip)) continue;
384 // Name added
385 any_change = true;
386 zcu.comp.mutex.lock();
387 defer zcu.comp.mutex.unlock();
388 try zcu.markDependeeOutdated(.{ .namespace_name = .{
389 .namespace = ti_idx,
390 .name = name_ip,
391 } });
392 }
393 }
394 // The only elements remaining in `old_names` now are any names which were removed.
395 for (old_names.keys()) |name_ip| {
396 any_change = true;
397 zcu.comp.mutex.lock();
398 defer zcu.comp.mutex.unlock();
399 try zcu.markDependeeOutdated(.{ .namespace_name = .{
400 .namespace = ti_idx,
401 .name = name_ip,
402 } });
403 }
404
405 if (any_change) {
406 zcu.comp.mutex.lock();
407 defer zcu.comp.mutex.unlock();
408 try zcu.markDependeeOutdated(.{ .namespace = ti_idx });
409 }
410 }
411}
412
413/// Like `ensureDeclAnalyzed`, but the Decl is a file's root Decl.
414pub fn ensureFileAnalyzed(pt: Zcu.PerThread, file_index: Zcu.File.Index) Zcu.SemaError!void {
415 if (pt.zcu.fileRootDecl(file_index).unwrap()) |existing_root| {
416 return pt.ensureDeclAnalyzed(existing_root);
417 } else {
418 return pt.semaFile(file_index);
419 }
420}
421
422/// This ensures that the Decl will have an up-to-date Type and Value populated.
423/// However the resolution status of the Type may not be fully resolved.
424/// For example an inferred error set is not resolved until after `analyzeFnBody`.
425/// is called.
426pub fn ensureDeclAnalyzed(pt: Zcu.PerThread, decl_index: Zcu.Decl.Index) Zcu.SemaError!void {
427 const tracy = trace(@src());
428 defer tracy.end();
429
430 const mod = pt.zcu;
431 const ip = &mod.intern_pool;
432 const decl = mod.declPtr(decl_index);
433
434 log.debug("ensureDeclAnalyzed '{d}' (name '{}')", .{
435 @intFromEnum(decl_index),
436 decl.name.fmt(ip),
437 });
438
439 // Determine whether or not this Decl is outdated, i.e. requires re-analysis
440 // even if `complete`. If a Decl is PO, we pessismistically assume that it
441 // *does* require re-analysis, to ensure that the Decl is definitely
442 // up-to-date when this function returns.
443
444 // If analysis occurs in a poor order, this could result in over-analysis.
445 // We do our best to avoid this by the other dependency logic in this file
446 // which tries to limit re-analysis to Decls whose previously listed
447 // dependencies are all up-to-date.
448
449 const decl_as_depender = InternPool.AnalUnit.wrap(.{ .decl = decl_index });
450 const decl_was_outdated = mod.outdated.swapRemove(decl_as_depender) or
451 mod.potentially_outdated.swapRemove(decl_as_depender);
452
453 if (decl_was_outdated) {
454 _ = mod.outdated_ready.swapRemove(decl_as_depender);
455 }
456
457 const was_outdated = mod.outdated_file_root.swapRemove(decl_index) or decl_was_outdated;
458
459 switch (decl.analysis) {
460 .in_progress => unreachable,
461
462 .file_failure => return error.AnalysisFail,
463
464 .sema_failure,
465 .dependency_failure,
466 .codegen_failure,
467 => if (!was_outdated) return error.AnalysisFail,
468
469 .complete => if (!was_outdated) return,
470
471 .unreferenced => {},
472 }
473
474 if (was_outdated) {
475 // The exports this Decl performs will be re-discovered, so we remove them here
476 // prior to re-analysis.
477 if (build_options.only_c) unreachable;
478 mod.deleteUnitExports(decl_as_depender);
479 mod.deleteUnitReferences(decl_as_depender);
480 }
481
482 const sema_result: Zcu.SemaDeclResult = blk: {
483 if (decl.zir_decl_index == .none and !mod.declIsRoot(decl_index)) {
484 // Anonymous decl. We don't semantically analyze these.
485 break :blk .{
486 .invalidate_decl_val = false,
487 .invalidate_decl_ref = false,
488 };
489 }
490
491 if (mod.declIsRoot(decl_index)) {
492 const changed = try pt.semaFileUpdate(decl.getFileScopeIndex(mod), decl_was_outdated);
493 break :blk .{
494 .invalidate_decl_val = changed,
495 .invalidate_decl_ref = changed,
496 };
497 }
498
499 const decl_prog_node = mod.sema_prog_node.start((try decl.fullyQualifiedName(pt)).toSlice(ip), 0);
500 defer decl_prog_node.end();
501
502 break :blk pt.semaDecl(decl_index) catch |err| switch (err) {
503 error.AnalysisFail => {
504 if (decl.analysis == .in_progress) {
505 // If this decl caused the compile error, the analysis field would
506 // be changed to indicate it was this Decl's fault. Because this
507 // did not happen, we infer here that it was a dependency failure.
508 decl.analysis = .dependency_failure;
509 }
510 return error.AnalysisFail;
511 },
512 error.GenericPoison => unreachable,
513 else => |e| {
514 decl.analysis = .sema_failure;
515 try mod.failed_analysis.ensureUnusedCapacity(mod.gpa, 1);
516 try mod.retryable_failures.append(mod.gpa, InternPool.AnalUnit.wrap(.{ .decl = decl_index }));
517 mod.failed_analysis.putAssumeCapacityNoClobber(InternPool.AnalUnit.wrap(.{ .decl = decl_index }), try Zcu.ErrorMsg.create(
518 mod.gpa,
519 decl.navSrcLoc(mod),
520 "unable to analyze: {s}",
521 .{@errorName(e)},
522 ));
523 return error.AnalysisFail;
524 },
525 };
526 };
527
528 // TODO: we do not yet have separate dependencies for decl values vs types.
529 if (decl_was_outdated) {
530 if (sema_result.invalidate_decl_val or sema_result.invalidate_decl_ref) {
531 log.debug("Decl tv invalidated ('{d}')", .{@intFromEnum(decl_index)});
532 // This dependency was marked as PO, meaning dependees were waiting
533 // on its analysis result, and it has turned out to be outdated.
534 // Update dependees accordingly.
535 try mod.markDependeeOutdated(.{ .decl_val = decl_index });
536 } else {
537 log.debug("Decl tv up-to-date ('{d}')", .{@intFromEnum(decl_index)});
538 // This dependency was previously PO, but turned out to be up-to-date.
539 // We do not need to queue successive analysis.
540 try mod.markPoDependeeUpToDate(.{ .decl_val = decl_index });
541 }
542 }
543}
544
545pub fn ensureFuncBodyAnalyzed(pt: Zcu.PerThread, maybe_coerced_func_index: InternPool.Index) Zcu.SemaError!void {
546 const tracy = trace(@src());
547 defer tracy.end();
548
549 const zcu = pt.zcu;
550 const gpa = zcu.gpa;
551 const ip = &zcu.intern_pool;
552
553 // We only care about the uncoerced function.
554 // We need to do this for the "orphaned function" check below to be valid.
555 const func_index = ip.unwrapCoercedFunc(maybe_coerced_func_index);
556
557 const func = zcu.funcInfo(maybe_coerced_func_index);
558 const decl_index = func.owner_decl;
559 const decl = zcu.declPtr(decl_index);
560
561 log.debug("ensureFuncBodyAnalyzed '{d}' (instance of '{}')", .{
562 @intFromEnum(func_index),
563 decl.name.fmt(ip),
564 });
565
566 // First, our owner decl must be up-to-date. This will always be the case
567 // during the first update, but may not on successive updates if we happen
568 // to get analyzed before our parent decl.
569 try pt.ensureDeclAnalyzed(decl_index);
570
571 // On an update, it's possible this function changed such that our owner
572 // decl now refers to a different function, making this one orphaned. If
573 // that's the case, we should remove this function from the binary.
574 if (decl.val.ip_index != func_index) {
575 try zcu.markDependeeOutdated(.{ .func_ies = func_index });
576 ip.removeDependenciesForDepender(gpa, InternPool.AnalUnit.wrap(.{ .func = func_index }));
577 ip.remove(pt.tid, func_index);
578 @panic("TODO: remove orphaned function from binary");
579 }
580
581 // We'll want to remember what the IES used to be before the update for
582 // dependency invalidation purposes.
583 const old_resolved_ies = if (func.analysis(ip).inferred_error_set)
584 func.resolvedErrorSet(ip).*
585 else
586 .none;
587
588 switch (decl.analysis) {
589 .unreferenced => unreachable,
590 .in_progress => unreachable,
591
592 .codegen_failure => unreachable, // functions do not perform constant value generation
593
594 .file_failure,
595 .sema_failure,
596 .dependency_failure,
597 => return error.AnalysisFail,
598
599 .complete => {},
600 }
601
602 const func_as_depender = InternPool.AnalUnit.wrap(.{ .func = func_index });
603 const was_outdated = zcu.outdated.swapRemove(func_as_depender) or
604 zcu.potentially_outdated.swapRemove(func_as_depender);
605
606 if (was_outdated) {
607 if (build_options.only_c) unreachable;
608 _ = zcu.outdated_ready.swapRemove(func_as_depender);
609 zcu.deleteUnitExports(func_as_depender);
610 zcu.deleteUnitReferences(func_as_depender);
611 }
612
613 switch (func.analysis(ip).state) {
614 .success => if (!was_outdated) return,
615 .sema_failure,
616 .dependency_failure,
617 .codegen_failure,
618 => if (!was_outdated) return error.AnalysisFail,
619 .none, .queued => {},
620 .in_progress => unreachable,
621 .inline_only => unreachable, // don't queue work for this
622 }
623
624 log.debug("analyze and generate fn body '{d}'; reason='{s}'", .{
625 @intFromEnum(func_index),
626 if (was_outdated) "outdated" else "never analyzed",
627 });
628
629 var tmp_arena = std.heap.ArenaAllocator.init(gpa);
630 defer tmp_arena.deinit();
631 const sema_arena = tmp_arena.allocator();
632
633 var air = pt.analyzeFnBody(func_index, sema_arena) catch |err| switch (err) {
634 error.AnalysisFail => {
635 if (func.analysis(ip).state == .in_progress) {
636 // If this decl caused the compile error, the analysis field would
637 // be changed to indicate it was this Decl's fault. Because this
638 // did not happen, we infer here that it was a dependency failure.
639 func.analysis(ip).state = .dependency_failure;
640 }
641 return error.AnalysisFail;
642 },
643 error.OutOfMemory => return error.OutOfMemory,
644 };
645 errdefer air.deinit(gpa);
646
647 const invalidate_ies_deps = i: {
648 if (!was_outdated) break :i false;
649 if (!func.analysis(ip).inferred_error_set) break :i true;
650 const new_resolved_ies = func.resolvedErrorSet(ip).*;
651 break :i new_resolved_ies != old_resolved_ies;
652 };
653 if (invalidate_ies_deps) {
654 log.debug("func IES invalidated ('{d}')", .{@intFromEnum(func_index)});
655 try zcu.markDependeeOutdated(.{ .func_ies = func_index });
656 } else if (was_outdated) {
657 log.debug("func IES up-to-date ('{d}')", .{@intFromEnum(func_index)});
658 try zcu.markPoDependeeUpToDate(.{ .func_ies = func_index });
659 }
660
661 const comp = zcu.comp;
662
663 const dump_air = build_options.enable_debug_extensions and comp.verbose_air;
664 const dump_llvm_ir = build_options.enable_debug_extensions and (comp.verbose_llvm_ir != null or comp.verbose_llvm_bc != null);
665
666 if (comp.bin_file == null and zcu.llvm_object == null and !dump_air and !dump_llvm_ir) {
667 air.deinit(gpa);
668 return;
669 }
670
671 try comp.work_queue.writeItem(.{ .codegen_func = .{
672 .func = func_index,
673 .air = air,
674 } });
675}
676
677/// Takes ownership of `air`, even on error.
678/// If any types referenced by `air` are unresolved, marks the codegen as failed.
679pub fn linkerUpdateFunc(pt: Zcu.PerThread, func_index: InternPool.Index, air: Air) Allocator.Error!void {
680 const zcu = pt.zcu;
681 const gpa = zcu.gpa;
682 const ip = &zcu.intern_pool;
683 const comp = zcu.comp;
684
685 defer {
686 var air_mut = air;
687 air_mut.deinit(gpa);
688 }
689
690 const func = zcu.funcInfo(func_index);
691 const decl_index = func.owner_decl;
692 const decl = zcu.declPtr(decl_index);
693
694 var liveness = try Liveness.analyze(gpa, air, ip);
695 defer liveness.deinit(gpa);
696
697 if (build_options.enable_debug_extensions and comp.verbose_air) {
698 const fqn = try decl.fullyQualifiedName(pt);
699 std.debug.print("# Begin Function AIR: {}:\n", .{fqn.fmt(ip)});
700 @import("../print_air.zig").dump(pt, air, liveness);
701 std.debug.print("# End Function AIR: {}\n\n", .{fqn.fmt(ip)});
702 }
703
704 if (std.debug.runtime_safety) {
705 var verify: Liveness.Verify = .{
706 .gpa = gpa,
707 .air = air,
708 .liveness = liveness,
709 .intern_pool = ip,
710 };
711 defer verify.deinit();
712
713 verify.verify() catch |err| switch (err) {
714 error.OutOfMemory => return error.OutOfMemory,
715 else => {
716 try zcu.failed_analysis.ensureUnusedCapacity(gpa, 1);
717 zcu.failed_analysis.putAssumeCapacityNoClobber(
718 InternPool.AnalUnit.wrap(.{ .func = func_index }),
719 try Zcu.ErrorMsg.create(
720 gpa,
721 decl.navSrcLoc(zcu),
722 "invalid liveness: {s}",
723 .{@errorName(err)},
724 ),
725 );
726 func.analysis(ip).state = .codegen_failure;
727 return;
728 },
729 };
730 }
731
732 const codegen_prog_node = zcu.codegen_prog_node.start((try decl.fullyQualifiedName(pt)).toSlice(ip), 0);
733 defer codegen_prog_node.end();
734
735 if (!air.typesFullyResolved(zcu)) {
736 // A type we depend on failed to resolve. This is a transitive failure.
737 // Correcting this failure will involve changing a type this function
738 // depends on, hence triggering re-analysis of this function, so this
739 // interacts correctly with incremental compilation.
740 func.analysis(ip).state = .codegen_failure;
741 } else if (comp.bin_file) |lf| {
742 lf.updateFunc(pt, func_index, air, liveness) catch |err| switch (err) {
743 error.OutOfMemory => return error.OutOfMemory,
744 error.AnalysisFail => {
745 func.analysis(ip).state = .codegen_failure;
746 },
747 else => {
748 try zcu.failed_analysis.ensureUnusedCapacity(gpa, 1);
749 zcu.failed_analysis.putAssumeCapacityNoClobber(InternPool.AnalUnit.wrap(.{ .func = func_index }), try Zcu.ErrorMsg.create(
750 gpa,
751 decl.navSrcLoc(zcu),
752 "unable to codegen: {s}",
753 .{@errorName(err)},
754 ));
755 func.analysis(ip).state = .codegen_failure;
756 try zcu.retryable_failures.append(zcu.gpa, InternPool.AnalUnit.wrap(.{ .func = func_index }));
757 },
758 };
759 } else if (zcu.llvm_object) |llvm_object| {
760 if (build_options.only_c) unreachable;
761 llvm_object.updateFunc(pt, func_index, air, liveness) catch |err| switch (err) {
762 error.OutOfMemory => return error.OutOfMemory,
763 };
764 }
765}
766
767/// https://github.com/ziglang/zig/issues/14307
768pub fn semaPkg(pt: Zcu.PerThread, pkg: *Module) !void {
769 const import_file_result = try pt.zcu.importPkg(pkg);
770 const root_decl_index = pt.zcu.fileRootDecl(import_file_result.file_index);
771 if (root_decl_index == .none) {
772 return pt.semaFile(import_file_result.file_index);
773 }
774}
775
776fn getFileRootStruct(
777 pt: Zcu.PerThread,
778 decl_index: Zcu.Decl.Index,
779 namespace_index: Zcu.Namespace.Index,
780 file_index: Zcu.File.Index,
781) Allocator.Error!InternPool.Index {
782 const zcu = pt.zcu;
783 const gpa = zcu.gpa;
784 const ip = &zcu.intern_pool;
785 const file = zcu.fileByIndex(file_index);
786 const extended = file.zir.instructions.items(.data)[@intFromEnum(Zir.Inst.Index.main_struct_inst)].extended;
787 assert(extended.opcode == .struct_decl);
788 const small: Zir.Inst.StructDecl.Small = @bitCast(extended.small);
789 assert(!small.has_captures_len);
790 assert(!small.has_backing_int);
791 assert(small.layout == .auto);
792 var extra_index: usize = extended.operand + @typeInfo(Zir.Inst.StructDecl).Struct.fields.len;
793 const fields_len = if (small.has_fields_len) blk: {
794 const fields_len = file.zir.extra[extra_index];
795 extra_index += 1;
796 break :blk fields_len;
797 } else 0;
798 const decls_len = if (small.has_decls_len) blk: {
799 const decls_len = file.zir.extra[extra_index];
800 extra_index += 1;
801 break :blk decls_len;
802 } else 0;
803 const decls = file.zir.bodySlice(extra_index, decls_len);
804 extra_index += decls_len;
805
806 const tracked_inst = try ip.trackZir(gpa, file_index, .main_struct_inst);
807 const wip_ty = switch (try ip.getStructType(gpa, pt.tid, .{
808 .layout = .auto,
809 .fields_len = fields_len,
810 .known_non_opv = small.known_non_opv,
811 .requires_comptime = if (small.known_comptime_only) .yes else .unknown,
812 .is_tuple = small.is_tuple,
813 .any_comptime_fields = small.any_comptime_fields,
814 .any_default_inits = small.any_default_inits,
815 .inits_resolved = false,
816 .any_aligned_fields = small.any_aligned_fields,
817 .has_namespace = true,
818 .key = .{ .declared = .{
819 .zir_index = tracked_inst,
820 .captures = &.{},
821 } },
822 })) {
823 .existing => unreachable, // we wouldn't be analysing the file root if this type existed
824 .wip => |wip| wip,
825 };
826 errdefer wip_ty.cancel(ip, pt.tid);
827
828 if (zcu.comp.debug_incremental) {
829 try ip.addDependency(
830 gpa,
831 InternPool.AnalUnit.wrap(.{ .decl = decl_index }),
832 .{ .src_hash = tracked_inst },
833 );
834 }
835
836 const decl = zcu.declPtr(decl_index);
837 decl.val = Value.fromInterned(wip_ty.index);
838 decl.has_tv = true;
839 decl.owns_tv = true;
840 decl.analysis = .complete;
841
842 try pt.scanNamespace(namespace_index, decls, decl);
843 try zcu.comp.work_queue.writeItem(.{ .resolve_type_fully = wip_ty.index });
844 return wip_ty.finish(ip, decl_index, namespace_index.toOptional());
845}
846
847/// Re-analyze the root Decl of a file on an incremental update.
848/// If `type_outdated`, the struct type itself is considered outdated and is
849/// reconstructed at a new InternPool index. Otherwise, the namespace is just
850/// re-analyzed. Returns whether the decl's tyval was invalidated.
851fn semaFileUpdate(pt: Zcu.PerThread, file_index: Zcu.File.Index, type_outdated: bool) Zcu.SemaError!bool {
852 const zcu = pt.zcu;
853 const ip = &zcu.intern_pool;
854 const file = zcu.fileByIndex(file_index);
855 const decl = zcu.declPtr(zcu.fileRootDecl(file_index).unwrap().?);
856
857 log.debug("semaFileUpdate mod={s} sub_file_path={s} type_outdated={}", .{
858 file.mod.fully_qualified_name,
859 file.sub_file_path,
860 type_outdated,
861 });
862
863 if (file.status != .success_zir) {
864 if (decl.analysis == .file_failure) {
865 return false;
866 } else {
867 decl.analysis = .file_failure;
868 return true;
869 }
870 }
871
872 if (decl.analysis == .file_failure) {
873 // No struct type currently exists. Create one!
874 const root_decl = zcu.fileRootDecl(file_index);
875 _ = try pt.getFileRootStruct(root_decl.unwrap().?, decl.src_namespace, file_index);
876 return true;
877 }
878
879 assert(decl.has_tv);
880 assert(decl.owns_tv);
881
882 if (type_outdated) {
883 // Invalidate the existing type, reusing the decl and namespace.
884 const file_root_decl = zcu.fileRootDecl(file_index).unwrap().?;
885 ip.removeDependenciesForDepender(zcu.gpa, InternPool.AnalUnit.wrap(.{
886 .decl = file_root_decl,
887 }));
888 ip.remove(pt.tid, decl.val.toIntern());
889 decl.val = undefined;
890 _ = try pt.getFileRootStruct(file_root_decl, decl.src_namespace, file_index);
891 return true;
892 }
893
894 // Only the struct's namespace is outdated.
895 // Preserve the type - just scan the namespace again.
896
897 const extended = file.zir.instructions.items(.data)[@intFromEnum(Zir.Inst.Index.main_struct_inst)].extended;
898 const small: Zir.Inst.StructDecl.Small = @bitCast(extended.small);
899
900 var extra_index: usize = extended.operand + @typeInfo(Zir.Inst.StructDecl).Struct.fields.len;
901 extra_index += @intFromBool(small.has_fields_len);
902 const decls_len = if (small.has_decls_len) blk: {
903 const decls_len = file.zir.extra[extra_index];
904 extra_index += 1;
905 break :blk decls_len;
906 } else 0;
907 const decls = file.zir.bodySlice(extra_index, decls_len);
908
909 if (!type_outdated) {
910 try pt.scanNamespace(decl.src_namespace, decls, decl);
911 }
912
913 return false;
914}
915
916/// Regardless of the file status, will create a `Decl` if none exists so that we can track
917/// dependencies and re-analyze when the file becomes outdated.
918fn semaFile(pt: Zcu.PerThread, file_index: Zcu.File.Index) Zcu.SemaError!void {
919 const tracy = trace(@src());
920 defer tracy.end();
921
922 const zcu = pt.zcu;
923 const gpa = zcu.gpa;
924 const file = zcu.fileByIndex(file_index);
925 assert(zcu.fileRootDecl(file_index) == .none);
926 log.debug("semaFile zcu={s} sub_file_path={s}", .{
927 file.mod.fully_qualified_name, file.sub_file_path,
928 });
929
930 // Because these three things each reference each other, `undefined`
931 // placeholders are used before being set after the struct type gains an
932 // InternPool index.
933 const new_namespace_index = try zcu.createNamespace(.{
934 .parent = .none,
935 .decl_index = undefined,
936 .file_scope = file_index,
937 });
938 errdefer zcu.destroyNamespace(new_namespace_index);
939
940 const new_decl_index = try zcu.allocateNewDecl(new_namespace_index);
941 const new_decl = zcu.declPtr(new_decl_index);
942 errdefer @panic("TODO error handling");
943
944 zcu.setFileRootDecl(file_index, new_decl_index.toOptional());
945 zcu.namespacePtr(new_namespace_index).decl_index = new_decl_index;
946
947 new_decl.name = try file.fullyQualifiedName(pt);
948 new_decl.name_fully_qualified = true;
949 new_decl.is_pub = true;
950 new_decl.is_exported = false;
951 new_decl.alignment = .none;
952 new_decl.@"linksection" = .none;
953 new_decl.analysis = .in_progress;
954
955 if (file.status != .success_zir) {
956 new_decl.analysis = .file_failure;
957 return;
958 }
959 assert(file.zir_loaded);
960
961 const struct_ty = try pt.getFileRootStruct(new_decl_index, new_namespace_index, file_index);
962 errdefer zcu.intern_pool.remove(pt.tid, struct_ty);
963
964 switch (zcu.comp.cache_use) {
965 .whole => |whole| if (whole.cache_manifest) |man| {
966 const source = file.getSource(gpa) catch |err| {
967 try Zcu.reportRetryableFileError(zcu, file_index, "unable to load source: {s}", .{@errorName(err)});
968 return error.AnalysisFail;
969 };
970
971 const resolved_path = std.fs.path.resolve(gpa, &.{
972 file.mod.root.root_dir.path orelse ".",
973 file.mod.root.sub_path,
974 file.sub_file_path,
975 }) catch |err| {
976 try Zcu.reportRetryableFileError(zcu, file_index, "unable to resolve path: {s}", .{@errorName(err)});
977 return error.AnalysisFail;
978 };
979 errdefer gpa.free(resolved_path);
980
981 whole.cache_manifest_mutex.lock();
982 defer whole.cache_manifest_mutex.unlock();
983 try man.addFilePostContents(resolved_path, source.bytes, source.stat);
984 },
985 .incremental => {},
986 }
987}
988
989fn semaDecl(pt: Zcu.PerThread, decl_index: Zcu.Decl.Index) !Zcu.SemaDeclResult {
990 const tracy = trace(@src());
991 defer tracy.end();
992
993 const zcu = pt.zcu;
994 const decl = zcu.declPtr(decl_index);
995 const ip = &zcu.intern_pool;
996
997 if (decl.getFileScope(zcu).status != .success_zir) {
998 return error.AnalysisFail;
999 }
1000
1001 assert(!zcu.declIsRoot(decl_index));
1002
1003 if (decl.zir_decl_index == .none and decl.owns_tv) {
1004 // We are re-analyzing an anonymous owner Decl (for a function or a namespace type).
1005 return pt.semaAnonOwnerDecl(decl_index);
1006 }
1007
1008 log.debug("semaDecl '{d}'", .{@intFromEnum(decl_index)});
1009 log.debug("decl name '{}'", .{(try decl.fullyQualifiedName(pt)).fmt(ip)});
1010 defer blk: {
1011 log.debug("finish decl name '{}'", .{(decl.fullyQualifiedName(pt) catch break :blk).fmt(ip)});
1012 }
1013
1014 const old_has_tv = decl.has_tv;
1015 // The following values are ignored if `!old_has_tv`
1016 const old_ty = if (old_has_tv) decl.typeOf(zcu) else undefined;
1017 const old_val = decl.val;
1018 const old_align = decl.alignment;
1019 const old_linksection = decl.@"linksection";
1020 const old_addrspace = decl.@"addrspace";
1021 const old_is_inline = if (decl.getOwnedFunction(zcu)) |prev_func|
1022 prev_func.analysis(ip).state == .inline_only
1023 else
1024 false;
1025
1026 const decl_inst = decl.zir_decl_index.unwrap().?.resolve(ip);
1027
1028 const gpa = zcu.gpa;
1029 const zir = decl.getFileScope(zcu).zir;
1030
1031 const builtin_type_target_index: InternPool.Index = ip_index: {
1032 const std_mod = zcu.std_mod;
1033 if (decl.getFileScope(zcu).mod != std_mod) break :ip_index .none;
1034 // We're in the std module.
1035 const std_file_imported = try zcu.importPkg(std_mod);
1036 const std_file_root_decl_index = zcu.fileRootDecl(std_file_imported.file_index);
1037 const std_decl = zcu.declPtr(std_file_root_decl_index.unwrap().?);
1038 const std_namespace = std_decl.getInnerNamespace(zcu).?;
1039 const builtin_str = try ip.getOrPutString(gpa, pt.tid, "builtin", .no_embedded_nulls);
1040 const builtin_decl = zcu.declPtr(std_namespace.decls.getKeyAdapted(builtin_str, Zcu.DeclAdapter{ .zcu = zcu }) orelse break :ip_index .none);
1041 const builtin_namespace = builtin_decl.getInnerNamespaceIndex(zcu).unwrap() orelse break :ip_index .none;
1042 if (decl.src_namespace != builtin_namespace) break :ip_index .none;
1043 // We're in builtin.zig. This could be a builtin we need to add to a specific InternPool index.
1044 for ([_][]const u8{
1045 "AtomicOrder",
1046 "AtomicRmwOp",
1047 "CallingConvention",
1048 "AddressSpace",
1049 "FloatMode",
1050 "ReduceOp",
1051 "CallModifier",
1052 "PrefetchOptions",
1053 "ExportOptions",
1054 "ExternOptions",
1055 "Type",
1056 }, [_]InternPool.Index{
1057 .atomic_order_type,
1058 .atomic_rmw_op_type,
1059 .calling_convention_type,
1060 .address_space_type,
1061 .float_mode_type,
1062 .reduce_op_type,
1063 .call_modifier_type,
1064 .prefetch_options_type,
1065 .export_options_type,
1066 .extern_options_type,
1067 .type_info_type,
1068 }) |type_name, type_ip| {
1069 if (decl.name.eqlSlice(type_name, ip)) break :ip_index type_ip;
1070 }
1071 break :ip_index .none;
1072 };
1073
1074 zcu.intern_pool.removeDependenciesForDepender(gpa, InternPool.AnalUnit.wrap(.{ .decl = decl_index }));
1075
1076 decl.analysis = .in_progress;
1077
1078 var analysis_arena = std.heap.ArenaAllocator.init(gpa);
1079 defer analysis_arena.deinit();
1080
1081 var comptime_err_ret_trace = std.ArrayList(Zcu.LazySrcLoc).init(gpa);
1082 defer comptime_err_ret_trace.deinit();
1083
1084 var sema: Sema = .{
1085 .pt = pt,
1086 .gpa = gpa,
1087 .arena = analysis_arena.allocator(),
1088 .code = zir,
1089 .owner_decl = decl,
1090 .owner_decl_index = decl_index,
1091 .func_index = .none,
1092 .func_is_naked = false,
1093 .fn_ret_ty = Type.void,
1094 .fn_ret_ty_ies = null,
1095 .owner_func_index = .none,
1096 .comptime_err_ret_trace = &comptime_err_ret_trace,
1097 .builtin_type_target_index = builtin_type_target_index,
1098 };
1099 defer sema.deinit();
1100
1101 // Every Decl (other than file root Decls, which do not have a ZIR index) has a dependency on its own source.
1102 try sema.declareDependency(.{ .src_hash = try ip.trackZir(
1103 gpa,
1104 decl.getFileScopeIndex(zcu),
1105 decl_inst,
1106 ) });
1107
1108 var block_scope: Sema.Block = .{
1109 .parent = null,
1110 .sema = &sema,
1111 .namespace = decl.src_namespace,
1112 .instructions = .{},
1113 .inlining = null,
1114 .is_comptime = true,
1115 .src_base_inst = decl.zir_decl_index.unwrap().?,
1116 .type_name_ctx = decl.name,
1117 };
1118 defer block_scope.instructions.deinit(gpa);
1119
1120 const decl_bodies = decl.zirBodies(zcu);
1121
1122 const result_ref = try sema.resolveInlineBody(&block_scope, decl_bodies.value_body, decl_inst);
1123 // We'll do some other bits with the Sema. Clear the type target index just
1124 // in case they analyze any type.
1125 sema.builtin_type_target_index = .none;
1126 const align_src = block_scope.src(.{ .node_offset_var_decl_align = 0 });
1127 const section_src = block_scope.src(.{ .node_offset_var_decl_section = 0 });
1128 const address_space_src = block_scope.src(.{ .node_offset_var_decl_addrspace = 0 });
1129 const ty_src = block_scope.src(.{ .node_offset_var_decl_ty = 0 });
1130 const init_src = block_scope.src(.{ .node_offset_var_decl_init = 0 });
1131 const decl_val = try sema.resolveFinalDeclValue(&block_scope, init_src, result_ref);
1132 const decl_ty = decl_val.typeOf(zcu);
1133
1134 // Note this resolves the type of the Decl, not the value; if this Decl
1135 // is a struct, for example, this resolves `type` (which needs no resolution),
1136 // not the struct itself.
1137 try decl_ty.resolveLayout(pt);
1138
1139 if (decl.kind == .@"usingnamespace") {
1140 if (!decl_ty.eql(Type.type, zcu)) {
1141 return sema.fail(&block_scope, ty_src, "expected type, found {}", .{decl_ty.fmt(pt)});
1142 }
1143 const ty = decl_val.toType();
1144 if (ty.getNamespace(zcu) == null) {
1145 return sema.fail(&block_scope, ty_src, "type {} has no namespace", .{ty.fmt(pt)});
1146 }
1147
1148 decl.val = ty.toValue();
1149 decl.alignment = .none;
1150 decl.@"linksection" = .none;
1151 decl.has_tv = true;
1152 decl.owns_tv = false;
1153 decl.analysis = .complete;
1154
1155 // TODO: usingnamespace cannot currently participate in incremental compilation
1156 return .{
1157 .invalidate_decl_val = true,
1158 .invalidate_decl_ref = true,
1159 };
1160 }
1161
1162 var queue_linker_work = true;
1163 var is_func = false;
1164 var is_inline = false;
1165 switch (decl_val.toIntern()) {
1166 .generic_poison => unreachable,
1167 .unreachable_value => unreachable,
1168 else => switch (ip.indexToKey(decl_val.toIntern())) {
1169 .variable => |variable| {
1170 decl.owns_tv = variable.decl == decl_index;
1171 queue_linker_work = decl.owns_tv;
1172 },
1173
1174 .extern_func => |extern_func| {
1175 decl.owns_tv = extern_func.decl == decl_index;
1176 queue_linker_work = decl.owns_tv;
1177 is_func = decl.owns_tv;
1178 },
1179
1180 .func => |func| {
1181 decl.owns_tv = func.owner_decl == decl_index;
1182 queue_linker_work = false;
1183 is_inline = decl.owns_tv and decl_ty.fnCallingConvention(zcu) == .Inline;
1184 is_func = decl.owns_tv;
1185 },
1186
1187 else => {},
1188 },
1189 }
1190
1191 decl.val = decl_val;
1192 // Function linksection, align, and addrspace were already set by Sema
1193 if (!is_func) {
1194 decl.alignment = blk: {
1195 const align_body = decl_bodies.align_body orelse break :blk .none;
1196 const align_ref = try sema.resolveInlineBody(&block_scope, align_body, decl_inst);
1197 break :blk try sema.analyzeAsAlign(&block_scope, align_src, align_ref);
1198 };
1199 decl.@"linksection" = blk: {
1200 const linksection_body = decl_bodies.linksection_body orelse break :blk .none;
1201 const linksection_ref = try sema.resolveInlineBody(&block_scope, linksection_body, decl_inst);
1202 const bytes = try sema.toConstString(&block_scope, section_src, linksection_ref, .{
1203 .needed_comptime_reason = "linksection must be comptime-known",
1204 });
1205 if (std.mem.indexOfScalar(u8, bytes, 0) != null) {
1206 return sema.fail(&block_scope, section_src, "linksection cannot contain null bytes", .{});
1207 } else if (bytes.len == 0) {
1208 return sema.fail(&block_scope, section_src, "linksection cannot be empty", .{});
1209 }
1210 break :blk try ip.getOrPutStringOpt(gpa, pt.tid, bytes, .no_embedded_nulls);
1211 };
1212 decl.@"addrspace" = blk: {
1213 const addrspace_ctx: Sema.AddressSpaceContext = switch (ip.indexToKey(decl_val.toIntern())) {
1214 .variable => .variable,
1215 .extern_func, .func => .function,
1216 else => .constant,
1217 };
1218
1219 const target = zcu.getTarget();
1220
1221 const addrspace_body = decl_bodies.addrspace_body orelse break :blk switch (addrspace_ctx) {
1222 .function => target_util.defaultAddressSpace(target, .function),
1223 .variable => target_util.defaultAddressSpace(target, .global_mutable),
1224 .constant => target_util.defaultAddressSpace(target, .global_constant),
1225 else => unreachable,
1226 };
1227 const addrspace_ref = try sema.resolveInlineBody(&block_scope, addrspace_body, decl_inst);
1228 break :blk try sema.analyzeAsAddressSpace(&block_scope, address_space_src, addrspace_ref, addrspace_ctx);
1229 };
1230 }
1231 decl.has_tv = true;
1232 decl.analysis = .complete;
1233
1234 const result: Zcu.SemaDeclResult = if (old_has_tv) .{
1235 .invalidate_decl_val = !decl_ty.eql(old_ty, zcu) or
1236 !decl.val.eql(old_val, decl_ty, zcu) or
1237 is_inline != old_is_inline,
1238 .invalidate_decl_ref = !decl_ty.eql(old_ty, zcu) or
1239 decl.alignment != old_align or
1240 decl.@"linksection" != old_linksection or
1241 decl.@"addrspace" != old_addrspace or
1242 is_inline != old_is_inline,
1243 } else .{
1244 .invalidate_decl_val = true,
1245 .invalidate_decl_ref = true,
1246 };
1247
1248 const has_runtime_bits = queue_linker_work and (is_func or try sema.typeHasRuntimeBits(decl_ty));
1249 if (has_runtime_bits) {
1250 // Needed for codegen_decl which will call updateDecl and then the
1251 // codegen backend wants full access to the Decl Type.
1252 try decl_ty.resolveFully(pt);
1253
1254 try zcu.comp.work_queue.writeItem(.{ .codegen_decl = decl_index });
1255
1256 if (result.invalidate_decl_ref and zcu.emit_h != null) {
1257 try zcu.comp.work_queue.writeItem(.{ .emit_h_decl = decl_index });
1258 }
1259 }
1260
1261 if (decl.is_exported) {
1262 const export_src = block_scope.src(.{ .token_offset = @intFromBool(decl.is_pub) });
1263 if (is_inline) return sema.fail(&block_scope, export_src, "export of inline function", .{});
1264 // The scope needs to have the decl in it.
1265 try sema.analyzeExport(&block_scope, export_src, .{ .name = decl.name }, decl_index);
1266 }
1267
1268 try sema.flushExports();
1269
1270 return result;
1271}
1272
1273pub fn semaAnonOwnerDecl(pt: Zcu.PerThread, decl_index: Zcu.Decl.Index) !Zcu.SemaDeclResult {
1274 const zcu = pt.zcu;
1275 const decl = zcu.declPtr(decl_index);
1276
1277 assert(decl.has_tv);
1278 assert(decl.owns_tv);
1279
1280 log.debug("semaAnonOwnerDecl '{d}'", .{@intFromEnum(decl_index)});
1281
1282 switch (decl.typeOf(zcu).zigTypeTag(zcu)) {
1283 .Fn => @panic("TODO: update fn instance"),
1284 .Type => {},
1285 else => unreachable,
1286 }
1287
1288 // We are the owner Decl of a type, and we were marked as outdated. That means the *structure*
1289 // of this type changed; not just its namespace. Therefore, we need a new InternPool index.
1290 //
1291 // However, as soon as we make that, the context that created us will require re-analysis anyway
1292 // (as it depends on this Decl's value), meaning the `struct_decl` (or equivalent) instruction
1293 // will be analyzed again. Since Sema already needs to be able to reconstruct types like this,
1294 // why should we bother implementing it here too when the Sema logic will be hit right after?
1295 //
1296 // So instead, let's just mark this Decl as failed - so that any remaining Decls which genuinely
1297 // reference it (via `@This`) end up silently erroring too - and we'll let Sema make a new type
1298 // with a new Decl.
1299 //
1300 // Yes, this does mean that any type owner Decl has a constant value for its entire lifetime.
1301 zcu.intern_pool.removeDependenciesForDepender(zcu.gpa, InternPool.AnalUnit.wrap(.{ .decl = decl_index }));
1302 zcu.intern_pool.remove(pt.tid, decl.val.toIntern());
1303 decl.analysis = .dependency_failure;
1304 return .{
1305 .invalidate_decl_val = true,
1306 .invalidate_decl_ref = true,
1307 };
1308}
1309
1310pub fn embedFile(
1311 pt: Zcu.PerThread,
1312 cur_file: *Zcu.File,
1313 import_string: []const u8,
1314 src_loc: Zcu.LazySrcLoc,
1315) !InternPool.Index {
1316 const mod = pt.zcu;
1317 const gpa = mod.gpa;
1318
1319 if (cur_file.mod.deps.get(import_string)) |pkg| {
1320 const resolved_path = try std.fs.path.resolve(gpa, &.{
1321 pkg.root.root_dir.path orelse ".",
1322 pkg.root.sub_path,
1323 pkg.root_src_path,
1324 });
1325 var keep_resolved_path = false;
1326 defer if (!keep_resolved_path) gpa.free(resolved_path);
1327
1328 const gop = try mod.embed_table.getOrPut(gpa, resolved_path);
1329 errdefer {
1330 assert(std.mem.eql(u8, mod.embed_table.pop().key, resolved_path));
1331 keep_resolved_path = false;
1332 }
1333 if (gop.found_existing) return gop.value_ptr.*.val;
1334 keep_resolved_path = true;
1335
1336 const sub_file_path = try gpa.dupe(u8, pkg.root_src_path);
1337 errdefer gpa.free(sub_file_path);
1338
1339 return pt.newEmbedFile(pkg, sub_file_path, resolved_path, gop.value_ptr, src_loc);
1340 }
1341
1342 // The resolved path is used as the key in the table, to detect if a file
1343 // refers to the same as another, despite different relative paths.
1344 const resolved_path = try std.fs.path.resolve(gpa, &.{
1345 cur_file.mod.root.root_dir.path orelse ".",
1346 cur_file.mod.root.sub_path,
1347 cur_file.sub_file_path,
1348 "..",
1349 import_string,
1350 });
1351
1352 var keep_resolved_path = false;
1353 defer if (!keep_resolved_path) gpa.free(resolved_path);
1354
1355 const gop = try mod.embed_table.getOrPut(gpa, resolved_path);
1356 errdefer {
1357 assert(std.mem.eql(u8, mod.embed_table.pop().key, resolved_path));
1358 keep_resolved_path = false;
1359 }
1360 if (gop.found_existing) return gop.value_ptr.*.val;
1361 keep_resolved_path = true;
1362
1363 const resolved_root_path = try std.fs.path.resolve(gpa, &.{
1364 cur_file.mod.root.root_dir.path orelse ".",
1365 cur_file.mod.root.sub_path,
1366 });
1367 defer gpa.free(resolved_root_path);
1368
1369 const sub_file_path = p: {
1370 const relative = try std.fs.path.relative(gpa, resolved_root_path, resolved_path);
1371 errdefer gpa.free(relative);
1372
1373 if (!isUpDir(relative) and !std.fs.path.isAbsolute(relative)) {
1374 break :p relative;
1375 }
1376 return error.ImportOutsideModulePath;
1377 };
1378 defer gpa.free(sub_file_path);
1379
1380 return pt.newEmbedFile(cur_file.mod, sub_file_path, resolved_path, gop.value_ptr, src_loc);
1381}
1382
1383/// Finalize the creation of an anon decl.
1384pub fn finalizeAnonDecl(pt: Zcu.PerThread, decl_index: Zcu.Decl.Index) Allocator.Error!void {
1385 if (pt.zcu.declPtr(decl_index).typeOf(pt.zcu).isFnOrHasRuntimeBits(pt)) {
1386 try pt.zcu.comp.work_queue.writeItem(.{ .codegen_decl = decl_index });
1387 }
1388}
1389
1390/// https://github.com/ziglang/zig/issues/14307
1391fn newEmbedFile(
1392 pt: Zcu.PerThread,
1393 pkg: *Module,
1394 sub_file_path: []const u8,
1395 resolved_path: []const u8,
1396 result: **Zcu.EmbedFile,
1397 src_loc: Zcu.LazySrcLoc,
1398) !InternPool.Index {
1399 const mod = pt.zcu;
1400 const gpa = mod.gpa;
1401 const ip = &mod.intern_pool;
1402
1403 const new_file = try gpa.create(Zcu.EmbedFile);
1404 errdefer gpa.destroy(new_file);
1405
1406 var file = try pkg.root.openFile(sub_file_path, .{});
1407 defer file.close();
1408
1409 const actual_stat = try file.stat();
1410 const stat: Cache.File.Stat = .{
1411 .size = actual_stat.size,
1412 .inode = actual_stat.inode,
1413 .mtime = actual_stat.mtime,
1414 };
1415 const size = std.math.cast(usize, actual_stat.size) orelse return error.Overflow;
1416
1417 const strings = ip.getLocal(pt.tid).getMutableStrings(gpa);
1418 const bytes = try strings.addManyAsSlice(try std.math.add(usize, size, 1));
1419 const actual_read = try file.readAll(bytes[0][0..size]);
1420 if (actual_read != size) return error.UnexpectedEndOfFile;
1421 bytes[0][size] = 0;
1422
1423 const comp = mod.comp;
1424 switch (comp.cache_use) {
1425 .whole => |whole| if (whole.cache_manifest) |man| {
1426 const copied_resolved_path = try gpa.dupe(u8, resolved_path);
1427 errdefer gpa.free(copied_resolved_path);
1428 whole.cache_manifest_mutex.lock();
1429 defer whole.cache_manifest_mutex.unlock();
1430 try man.addFilePostContents(copied_resolved_path, bytes[0][0..size], stat);
1431 },
1432 .incremental => {},
1433 }
1434
1435 const array_ty = try pt.intern(.{ .array_type = .{
1436 .len = size,
1437 .sentinel = .zero_u8,
1438 .child = .u8_type,
1439 } });
1440 const array_val = try pt.intern(.{ .aggregate = .{
1441 .ty = array_ty,
1442 .storage = .{ .bytes = try ip.getOrPutTrailingString(gpa, pt.tid, @intCast(bytes[0].len), .maybe_embedded_nulls) },
1443 } });
1444
1445 const ptr_ty = (try pt.ptrType(.{
1446 .child = array_ty,
1447 .flags = .{
1448 .alignment = .none,
1449 .is_const = true,
1450 .address_space = .generic,
1451 },
1452 })).toIntern();
1453 const ptr_val = try pt.intern(.{ .ptr = .{
1454 .ty = ptr_ty,
1455 .base_addr = .{ .anon_decl = .{
1456 .val = array_val,
1457 .orig_ty = ptr_ty,
1458 } },
1459 .byte_offset = 0,
1460 } });
1461
1462 result.* = new_file;
1463 new_file.* = .{
1464 .sub_file_path = try ip.getOrPutString(gpa, pt.tid, sub_file_path, .no_embedded_nulls),
1465 .owner = pkg,
1466 .stat = stat,
1467 .val = ptr_val,
1468 .src_loc = src_loc,
1469 };
1470 return ptr_val;
1471}
1472
1473pub fn scanNamespace(
1474 pt: Zcu.PerThread,
1475 namespace_index: Zcu.Namespace.Index,
1476 decls: []const Zir.Inst.Index,
1477 parent_decl: *Zcu.Decl,
1478) Allocator.Error!void {
1479 const tracy = trace(@src());
1480 defer tracy.end();
1481
1482 const zcu = pt.zcu;
1483 const gpa = zcu.gpa;
1484 const namespace = zcu.namespacePtr(namespace_index);
1485
1486 // For incremental updates, `scanDecl` wants to look up existing decls by their ZIR index rather
1487 // than their name. We'll build an efficient mapping now, then discard the current `decls`.
1488 var existing_by_inst: std.AutoHashMapUnmanaged(InternPool.TrackedInst.Index, Zcu.Decl.Index) = .{};
1489 defer existing_by_inst.deinit(gpa);
1490
1491 try existing_by_inst.ensureTotalCapacity(gpa, @intCast(namespace.decls.count()));
1492
1493 for (namespace.decls.keys()) |decl_index| {
1494 const decl = zcu.declPtr(decl_index);
1495 existing_by_inst.putAssumeCapacityNoClobber(decl.zir_decl_index.unwrap().?, decl_index);
1496 }
1497
1498 var seen_decls: std.AutoHashMapUnmanaged(InternPool.NullTerminatedString, void) = .{};
1499 defer seen_decls.deinit(gpa);
1500
1501 try zcu.comp.work_queue.ensureUnusedCapacity(decls.len);
1502
1503 namespace.decls.clearRetainingCapacity();
1504 try namespace.decls.ensureTotalCapacity(gpa, decls.len);
1505
1506 namespace.usingnamespace_set.clearRetainingCapacity();
1507
1508 var scan_decl_iter: ScanDeclIter = .{
1509 .pt = pt,
1510 .namespace_index = namespace_index,
1511 .parent_decl = parent_decl,
1512 .seen_decls = &seen_decls,
1513 .existing_by_inst = &existing_by_inst,
1514 .pass = .named,
1515 };
1516 for (decls) |decl_inst| {
1517 try scan_decl_iter.scanDecl(decl_inst);
1518 }
1519 scan_decl_iter.pass = .unnamed;
1520 for (decls) |decl_inst| {
1521 try scan_decl_iter.scanDecl(decl_inst);
1522 }
1523
1524 if (seen_decls.count() != namespace.decls.count()) {
1525 // Do a pass over the namespace contents and remove any decls from the last update
1526 // which were removed in this one.
1527 var i: usize = 0;
1528 while (i < namespace.decls.count()) {
1529 const decl_index = namespace.decls.keys()[i];
1530 const decl = zcu.declPtr(decl_index);
1531 if (!seen_decls.contains(decl.name)) {
1532 // We must preserve namespace ordering for @typeInfo.
1533 namespace.decls.orderedRemoveAt(i);
1534 i -= 1;
1535 }
1536 }
1537 }
1538}
1539
1540const ScanDeclIter = struct {
1541 pt: Zcu.PerThread,
1542 namespace_index: Zcu.Namespace.Index,
1543 parent_decl: *Zcu.Decl,
1544 seen_decls: *std.AutoHashMapUnmanaged(InternPool.NullTerminatedString, void),
1545 existing_by_inst: *const std.AutoHashMapUnmanaged(InternPool.TrackedInst.Index, Zcu.Decl.Index),
1546 /// Decl scanning is run in two passes, so that we can detect when a generated
1547 /// name would clash with an explicit name and use a different one.
1548 pass: enum { named, unnamed },
1549 usingnamespace_index: usize = 0,
1550 comptime_index: usize = 0,
1551 unnamed_test_index: usize = 0,
1552
1553 fn avoidNameConflict(iter: *ScanDeclIter, comptime fmt: []const u8, args: anytype) !InternPool.NullTerminatedString {
1554 const pt = iter.pt;
1555 const gpa = pt.zcu.gpa;
1556 const ip = &pt.zcu.intern_pool;
1557 var name = try ip.getOrPutStringFmt(gpa, pt.tid, fmt, args, .no_embedded_nulls);
1558 var gop = try iter.seen_decls.getOrPut(gpa, name);
1559 var next_suffix: u32 = 0;
1560 while (gop.found_existing) {
1561 name = try ip.getOrPutStringFmt(gpa, pt.tid, "{}_{d}", .{ name.fmt(ip), next_suffix }, .no_embedded_nulls);
1562 gop = try iter.seen_decls.getOrPut(gpa, name);
1563 next_suffix += 1;
1564 }
1565 return name;
1566 }
1567
1568 fn scanDecl(iter: *ScanDeclIter, decl_inst: Zir.Inst.Index) Allocator.Error!void {
1569 const tracy = trace(@src());
1570 defer tracy.end();
1571
1572 const pt = iter.pt;
1573 const zcu = pt.zcu;
1574 const namespace_index = iter.namespace_index;
1575 const namespace = zcu.namespacePtr(namespace_index);
1576 const gpa = zcu.gpa;
1577 const zir = namespace.fileScope(zcu).zir;
1578 const ip = &zcu.intern_pool;
1579
1580 const inst_data = zir.instructions.items(.data)[@intFromEnum(decl_inst)].declaration;
1581 const extra = zir.extraData(Zir.Inst.Declaration, inst_data.payload_index);
1582 const declaration = extra.data;
1583
1584 // Every Decl needs a name.
1585 const decl_name: InternPool.NullTerminatedString, const kind: Zcu.Decl.Kind, const is_named_test: bool = switch (declaration.name) {
1586 .@"comptime" => info: {
1587 if (iter.pass != .unnamed) return;
1588 const i = iter.comptime_index;
1589 iter.comptime_index += 1;
1590 break :info .{
1591 try iter.avoidNameConflict("comptime_{d}", .{i}),
1592 .@"comptime",
1593 false,
1594 };
1595 },
1596 .@"usingnamespace" => info: {
1597 // TODO: this isn't right! These should be considered unnamed. Name conflicts can happen here.
1598 // The problem is, we need to preserve the decl ordering for `@typeInfo`.
1599 // I'm not bothering to fix this now, since some upcoming changes will change this code significantly anyway.
1600 if (iter.pass != .named) return;
1601 const i = iter.usingnamespace_index;
1602 iter.usingnamespace_index += 1;
1603 break :info .{
1604 try iter.avoidNameConflict("usingnamespace_{d}", .{i}),
1605 .@"usingnamespace",
1606 false,
1607 };
1608 },
1609 .unnamed_test => info: {
1610 if (iter.pass != .unnamed) return;
1611 const i = iter.unnamed_test_index;
1612 iter.unnamed_test_index += 1;
1613 break :info .{
1614 try iter.avoidNameConflict("test_{d}", .{i}),
1615 .@"test",
1616 false,
1617 };
1618 },
1619 .decltest => info: {
1620 // We consider these to be unnamed since the decl name can be adjusted to avoid conflicts if necessary.
1621 if (iter.pass != .unnamed) return;
1622 assert(declaration.flags.has_doc_comment);
1623 const name = zir.nullTerminatedString(@enumFromInt(zir.extra[extra.end]));
1624 break :info .{
1625 try iter.avoidNameConflict("decltest.{s}", .{name}),
1626 .@"test",
1627 true,
1628 };
1629 },
1630 _ => if (declaration.name.isNamedTest(zir)) info: {
1631 // We consider these to be unnamed since the decl name can be adjusted to avoid conflicts if necessary.
1632 if (iter.pass != .unnamed) return;
1633 break :info .{
1634 try iter.avoidNameConflict("test.{s}", .{zir.nullTerminatedString(declaration.name.toString(zir).?)}),
1635 .@"test",
1636 true,
1637 };
1638 } else info: {
1639 if (iter.pass != .named) return;
1640 const name = try ip.getOrPutString(
1641 gpa,
1642 pt.tid,
1643 zir.nullTerminatedString(declaration.name.toString(zir).?),
1644 .no_embedded_nulls,
1645 );
1646 try iter.seen_decls.putNoClobber(gpa, name, {});
1647 break :info .{
1648 name,
1649 .named,
1650 false,
1651 };
1652 },
1653 };
1654
1655 switch (kind) {
1656 .@"usingnamespace" => try namespace.usingnamespace_set.ensureUnusedCapacity(gpa, 1),
1657 .@"test" => try zcu.test_functions.ensureUnusedCapacity(gpa, 1),
1658 else => {},
1659 }
1660
1661 const parent_file_scope_index = iter.parent_decl.getFileScopeIndex(zcu);
1662 const tracked_inst = try ip.trackZir(gpa, parent_file_scope_index, decl_inst);
1663
1664 // We create a Decl for it regardless of analysis status.
1665
1666 const prev_exported, const decl_index = if (iter.existing_by_inst.get(tracked_inst)) |decl_index| decl_index: {
1667 // We need only update this existing Decl.
1668 const decl = zcu.declPtr(decl_index);
1669 const was_exported = decl.is_exported;
1670 assert(decl.kind == kind); // ZIR tracking should preserve this
1671 decl.name = decl_name;
1672 decl.is_pub = declaration.flags.is_pub;
1673 decl.is_exported = declaration.flags.is_export;
1674 break :decl_index .{ was_exported, decl_index };
1675 } else decl_index: {
1676 // Create and set up a new Decl.
1677 const new_decl_index = try zcu.allocateNewDecl(namespace_index);
1678 const new_decl = zcu.declPtr(new_decl_index);
1679 new_decl.kind = kind;
1680 new_decl.name = decl_name;
1681 new_decl.is_pub = declaration.flags.is_pub;
1682 new_decl.is_exported = declaration.flags.is_export;
1683 new_decl.zir_decl_index = tracked_inst.toOptional();
1684 break :decl_index .{ false, new_decl_index };
1685 };
1686
1687 const decl = zcu.declPtr(decl_index);
1688
1689 namespace.decls.putAssumeCapacityNoClobberContext(decl_index, {}, .{ .zcu = zcu });
1690
1691 const comp = zcu.comp;
1692 const decl_mod = namespace.fileScope(zcu).mod;
1693 const want_analysis = declaration.flags.is_export or switch (kind) {
1694 .anon => unreachable,
1695 .@"comptime" => true,
1696 .@"usingnamespace" => a: {
1697 namespace.usingnamespace_set.putAssumeCapacityNoClobber(decl_index, declaration.flags.is_pub);
1698 break :a true;
1699 },
1700 .named => false,
1701 .@"test" => a: {
1702 if (!comp.config.is_test) break :a false;
1703 if (decl_mod != zcu.main_mod) break :a false;
1704 if (is_named_test and comp.test_filters.len > 0) {
1705 const decl_fqn = try namespace.fullyQualifiedName(pt, decl_name);
1706 const decl_fqn_slice = decl_fqn.toSlice(ip);
1707 for (comp.test_filters) |test_filter| {
1708 if (std.mem.indexOf(u8, decl_fqn_slice, test_filter)) |_| break;
1709 } else break :a false;
1710 }
1711 zcu.test_functions.putAssumeCapacity(decl_index, {}); // may clobber on incremental update
1712 break :a true;
1713 },
1714 };
1715
1716 if (want_analysis) {
1717 // We will not queue analysis if the decl has been analyzed on a previous update and
1718 // `is_export` is unchanged. In this case, the incremental update mechanism will handle
1719 // re-analysis for us if necessary.
1720 if (prev_exported != declaration.flags.is_export or decl.analysis == .unreferenced) {
1721 log.debug("scanDecl queue analyze_decl file='{s}' decl_name='{}' decl_index={d}", .{
1722 namespace.fileScope(zcu).sub_file_path, decl_name.fmt(ip), decl_index,
1723 });
1724 comp.work_queue.writeItemAssumeCapacity(.{ .analyze_decl = decl_index });
1725 }
1726 }
1727
1728 if (decl.getOwnedFunction(zcu) != null) {
1729 // TODO this logic is insufficient; namespaces we don't re-scan may still require
1730 // updated line numbers. Look into this!
1731 // TODO Look into detecting when this would be unnecessary by storing enough state
1732 // in `Decl` to notice that the line number did not change.
1733 comp.work_queue.writeItemAssumeCapacity(.{ .update_line_number = decl_index });
1734 }
1735 }
1736};
1737
1738pub fn analyzeFnBody(pt: Zcu.PerThread, func_index: InternPool.Index, arena: Allocator) Zcu.SemaError!Air {
1739 const tracy = trace(@src());
1740 defer tracy.end();
1741
1742 const mod = pt.zcu;
1743 const gpa = mod.gpa;
1744 const ip = &mod.intern_pool;
1745 const func = mod.funcInfo(func_index);
1746 const decl_index = func.owner_decl;
1747 const decl = mod.declPtr(decl_index);
1748
1749 log.debug("func name '{}'", .{(try decl.fullyQualifiedName(pt)).fmt(ip)});
1750 defer blk: {
1751 log.debug("finish func name '{}'", .{(decl.fullyQualifiedName(pt) catch break :blk).fmt(ip)});
1752 }
1753
1754 const decl_prog_node = mod.sema_prog_node.start((try decl.fullyQualifiedName(pt)).toSlice(ip), 0);
1755 defer decl_prog_node.end();
1756
1757 mod.intern_pool.removeDependenciesForDepender(gpa, InternPool.AnalUnit.wrap(.{ .func = func_index }));
1758
1759 var comptime_err_ret_trace = std.ArrayList(Zcu.LazySrcLoc).init(gpa);
1760 defer comptime_err_ret_trace.deinit();
1761
1762 // In the case of a generic function instance, this is the type of the
1763 // instance, which has comptime parameters elided. In other words, it is
1764 // the runtime-known parameters only, not to be confused with the
1765 // generic_owner function type, which potentially has more parameters,
1766 // including comptime parameters.
1767 const fn_ty = decl.typeOf(mod);
1768 const fn_ty_info = mod.typeToFunc(fn_ty).?;
1769
1770 var sema: Sema = .{
1771 .pt = pt,
1772 .gpa = gpa,
1773 .arena = arena,
1774 .code = decl.getFileScope(mod).zir,
1775 .owner_decl = decl,
1776 .owner_decl_index = decl_index,
1777 .func_index = func_index,
1778 .func_is_naked = fn_ty_info.cc == .Naked,
1779 .fn_ret_ty = Type.fromInterned(fn_ty_info.return_type),
1780 .fn_ret_ty_ies = null,
1781 .owner_func_index = func_index,
1782 .branch_quota = @max(func.branchQuota(ip).*, Sema.default_branch_quota),
1783 .comptime_err_ret_trace = &comptime_err_ret_trace,
1784 };
1785 defer sema.deinit();
1786
1787 // Every runtime function has a dependency on the source of the Decl it originates from.
1788 // It also depends on the value of its owner Decl.
1789 try sema.declareDependency(.{ .src_hash = decl.zir_decl_index.unwrap().? });
1790 try sema.declareDependency(.{ .decl_val = decl_index });
1791
1792 if (func.analysis(ip).inferred_error_set) {
1793 const ies = try arena.create(Sema.InferredErrorSet);
1794 ies.* = .{ .func = func_index };
1795 sema.fn_ret_ty_ies = ies;
1796 }
1797
1798 // reset in case calls to errorable functions are removed.
1799 func.analysis(ip).calls_or_awaits_errorable_fn = false;
1800
1801 // First few indexes of extra are reserved and set at the end.
1802 const reserved_count = @typeInfo(Air.ExtraIndex).Enum.fields.len;
1803 try sema.air_extra.ensureTotalCapacity(gpa, reserved_count);
1804 sema.air_extra.items.len += reserved_count;
1805
1806 var inner_block: Sema.Block = .{
1807 .parent = null,
1808 .sema = &sema,
1809 .namespace = decl.src_namespace,
1810 .instructions = .{},
1811 .inlining = null,
1812 .is_comptime = false,
1813 .src_base_inst = inst: {
1814 const owner_info = if (func.generic_owner == .none)
1815 func
1816 else
1817 mod.funcInfo(func.generic_owner);
1818 const orig_decl = mod.declPtr(owner_info.owner_decl);
1819 break :inst orig_decl.zir_decl_index.unwrap().?;
1820 },
1821 .type_name_ctx = decl.name,
1822 };
1823 defer inner_block.instructions.deinit(gpa);
1824
1825 const fn_info = sema.code.getFnInfo(func.zirBodyInst(ip).resolve(ip));
1826
1827 // Here we are performing "runtime semantic analysis" for a function body, which means
1828 // we must map the parameter ZIR instructions to `arg` AIR instructions.
1829 // AIR requires the `arg` parameters to be the first N instructions.
1830 // This could be a generic function instantiation, however, in which case we need to
1831 // map the comptime parameters to constant values and only emit arg AIR instructions
1832 // for the runtime ones.
1833 const runtime_params_len = fn_ty_info.param_types.len;
1834 try inner_block.instructions.ensureTotalCapacityPrecise(gpa, runtime_params_len);
1835 try sema.air_instructions.ensureUnusedCapacity(gpa, fn_info.total_params_len);
1836 try sema.inst_map.ensureSpaceForInstructions(gpa, fn_info.param_body);
1837
1838 // In the case of a generic function instance, pre-populate all the comptime args.
1839 if (func.comptime_args.len != 0) {
1840 for (
1841 fn_info.param_body[0..func.comptime_args.len],
1842 func.comptime_args.get(ip),
1843 ) |inst, comptime_arg| {
1844 if (comptime_arg == .none) continue;
1845 sema.inst_map.putAssumeCapacityNoClobber(inst, Air.internedToRef(comptime_arg));
1846 }
1847 }
1848
1849 const src_params_len = if (func.comptime_args.len != 0)
1850 func.comptime_args.len
1851 else
1852 runtime_params_len;
1853
1854 var runtime_param_index: usize = 0;
1855 for (fn_info.param_body[0..src_params_len], 0..) |inst, src_param_index| {
1856 const gop = sema.inst_map.getOrPutAssumeCapacity(inst);
1857 if (gop.found_existing) continue; // provided above by comptime arg
1858
1859 const param_ty = fn_ty_info.param_types.get(ip)[runtime_param_index];
1860 runtime_param_index += 1;
1861
1862 const opt_opv = sema.typeHasOnePossibleValue(Type.fromInterned(param_ty)) catch |err| switch (err) {
1863 error.GenericPoison => unreachable,
1864 error.ComptimeReturn => unreachable,
1865 error.ComptimeBreak => unreachable,
1866 else => |e| return e,
1867 };
1868 if (opt_opv) |opv| {
1869 gop.value_ptr.* = Air.internedToRef(opv.toIntern());
1870 continue;
1871 }
1872 const arg_index: Air.Inst.Index = @enumFromInt(sema.air_instructions.len);
1873 gop.value_ptr.* = arg_index.toRef();
1874 inner_block.instructions.appendAssumeCapacity(arg_index);
1875 sema.air_instructions.appendAssumeCapacity(.{
1876 .tag = .arg,
1877 .data = .{ .arg = .{
1878 .ty = Air.internedToRef(param_ty),
1879 .src_index = @intCast(src_param_index),
1880 } },
1881 });
1882 }
1883
1884 func.analysis(ip).state = .in_progress;
1885
1886 const last_arg_index = inner_block.instructions.items.len;
1887
1888 // Save the error trace as our first action in the function.
1889 // If this is unnecessary after all, Liveness will clean it up for us.
1890 const error_return_trace_index = try sema.analyzeSaveErrRetIndex(&inner_block);
1891 sema.error_return_trace_index_on_fn_entry = error_return_trace_index;
1892 inner_block.error_return_trace_index = error_return_trace_index;
1893
1894 sema.analyzeFnBody(&inner_block, fn_info.body) catch |err| switch (err) {
1895 // TODO make these unreachable instead of @panic
1896 error.GenericPoison => @panic("zig compiler bug: GenericPoison"),
1897 error.ComptimeReturn => @panic("zig compiler bug: ComptimeReturn"),
1898 else => |e| return e,
1899 };
1900
1901 for (sema.unresolved_inferred_allocs.keys()) |ptr_inst| {
1902 // The lack of a resolve_inferred_alloc means that this instruction
1903 // is unused so it just has to be a no-op.
1904 sema.air_instructions.set(@intFromEnum(ptr_inst), .{
1905 .tag = .alloc,
1906 .data = .{ .ty = Type.single_const_pointer_to_comptime_int },
1907 });
1908 }
1909
1910 // If we don't get an error return trace from a caller, create our own.
1911 if (func.analysis(ip).calls_or_awaits_errorable_fn and
1912 mod.comp.config.any_error_tracing and
1913 !sema.fn_ret_ty.isError(mod))
1914 {
1915 sema.setupErrorReturnTrace(&inner_block, last_arg_index) catch |err| switch (err) {
1916 // TODO make these unreachable instead of @panic
1917 error.GenericPoison => @panic("zig compiler bug: GenericPoison"),
1918 error.ComptimeReturn => @panic("zig compiler bug: ComptimeReturn"),
1919 error.ComptimeBreak => @panic("zig compiler bug: ComptimeBreak"),
1920 else => |e| return e,
1921 };
1922 }
1923
1924 // Copy the block into place and mark that as the main block.
1925 try sema.air_extra.ensureUnusedCapacity(gpa, @typeInfo(Air.Block).Struct.fields.len +
1926 inner_block.instructions.items.len);
1927 const main_block_index = sema.addExtraAssumeCapacity(Air.Block{
1928 .body_len = @intCast(inner_block.instructions.items.len),
1929 });
1930 sema.air_extra.appendSliceAssumeCapacity(@ptrCast(inner_block.instructions.items));
1931 sema.air_extra.items[@intFromEnum(Air.ExtraIndex.main_block)] = main_block_index;
1932
1933 // Resolving inferred error sets is done *before* setting the function
1934 // state to success, so that "unable to resolve inferred error set" errors
1935 // can be emitted here.
1936 if (sema.fn_ret_ty_ies) |ies| {
1937 sema.resolveInferredErrorSetPtr(&inner_block, .{
1938 .base_node_inst = inner_block.src_base_inst,
1939 .offset = Zcu.LazySrcLoc.Offset.nodeOffset(0),
1940 }, ies) catch |err| switch (err) {
1941 error.GenericPoison => unreachable,
1942 error.ComptimeReturn => unreachable,
1943 error.ComptimeBreak => unreachable,
1944 error.AnalysisFail => {
1945 // In this case our function depends on a type that had a compile error.
1946 // We should not try to lower this function.
1947 decl.analysis = .dependency_failure;
1948 return error.AnalysisFail;
1949 },
1950 else => |e| return e,
1951 };
1952 assert(ies.resolved != .none);
1953 ip.funcIesResolved(func_index).* = ies.resolved;
1954 }
1955
1956 func.analysis(ip).state = .success;
1957
1958 // Finally we must resolve the return type and parameter types so that backends
1959 // have full access to type information.
1960 // Crucially, this happens *after* we set the function state to success above,
1961 // so that dependencies on the function body will now be satisfied rather than
1962 // result in circular dependency errors.
1963 sema.resolveFnTypes(fn_ty) catch |err| switch (err) {
1964 error.GenericPoison => unreachable,
1965 error.ComptimeReturn => unreachable,
1966 error.ComptimeBreak => unreachable,
1967 error.AnalysisFail => {
1968 // In this case our function depends on a type that had a compile error.
1969 // We should not try to lower this function.
1970 decl.analysis = .dependency_failure;
1971 return error.AnalysisFail;
1972 },
1973 else => |e| return e,
1974 };
1975
1976 try sema.flushExports();
1977
1978 return .{
1979 .instructions = sema.air_instructions.toOwnedSlice(),
1980 .extra = try sema.air_extra.toOwnedSlice(gpa),
1981 };
1982}
1983
1984fn lockAndClearFileCompileError(pt: Zcu.PerThread, file: *Zcu.File) void {
1985 switch (file.status) {
1986 .success_zir, .retryable_failure => {},
1987 .never_loaded, .parse_failure, .astgen_failure => {
1988 pt.zcu.comp.mutex.lock();
1989 defer pt.zcu.comp.mutex.unlock();
1990 if (pt.zcu.failed_files.fetchSwapRemove(file)) |kv| {
1991 if (kv.value) |msg| msg.destroy(pt.zcu.gpa); // Delete previous error message.
1992 }
1993 },
1994 }
1995}
1996
1997/// Called from `Compilation.update`, after everything is done, just before
1998/// reporting compile errors. In this function we emit exported symbol collision
1999/// errors and communicate exported symbols to the linker backend.
2000pub fn processExports(pt: Zcu.PerThread) !void {
2001 const zcu = pt.zcu;
2002 const gpa = zcu.gpa;
2003
2004 // First, construct a mapping of every exported value and Decl to the indices of all its different exports.
2005 var decl_exports: std.AutoArrayHashMapUnmanaged(Zcu.Decl.Index, std.ArrayListUnmanaged(u32)) = .{};
2006 var value_exports: std.AutoArrayHashMapUnmanaged(InternPool.Index, std.ArrayListUnmanaged(u32)) = .{};
2007 defer {
2008 for (decl_exports.values()) |*exports| {
2009 exports.deinit(gpa);
2010 }
2011 decl_exports.deinit(gpa);
2012 for (value_exports.values()) |*exports| {
2013 exports.deinit(gpa);
2014 }
2015 value_exports.deinit(gpa);
2016 }
2017
2018 // We note as a heuristic:
2019 // * It is rare to export a value.
2020 // * It is rare for one Decl to be exported multiple times.
2021 // So, this ensureTotalCapacity serves as a reasonable (albeit very approximate) optimization.
2022 try decl_exports.ensureTotalCapacity(gpa, zcu.single_exports.count() + zcu.multi_exports.count());
2023
2024 for (zcu.single_exports.values()) |export_idx| {
2025 const exp = zcu.all_exports.items[export_idx];
2026 const value_ptr, const found_existing = switch (exp.exported) {
2027 .decl_index => |i| gop: {
2028 const gop = try decl_exports.getOrPut(gpa, i);
2029 break :gop .{ gop.value_ptr, gop.found_existing };
2030 },
2031 .value => |i| gop: {
2032 const gop = try value_exports.getOrPut(gpa, i);
2033 break :gop .{ gop.value_ptr, gop.found_existing };
2034 },
2035 };
2036 if (!found_existing) value_ptr.* = .{};
2037 try value_ptr.append(gpa, export_idx);
2038 }
2039
2040 for (zcu.multi_exports.values()) |info| {
2041 for (zcu.all_exports.items[info.index..][0..info.len], info.index..) |exp, export_idx| {
2042 const value_ptr, const found_existing = switch (exp.exported) {
2043 .decl_index => |i| gop: {
2044 const gop = try decl_exports.getOrPut(gpa, i);
2045 break :gop .{ gop.value_ptr, gop.found_existing };
2046 },
2047 .value => |i| gop: {
2048 const gop = try value_exports.getOrPut(gpa, i);
2049 break :gop .{ gop.value_ptr, gop.found_existing };
2050 },
2051 };
2052 if (!found_existing) value_ptr.* = .{};
2053 try value_ptr.append(gpa, @intCast(export_idx));
2054 }
2055 }
2056
2057 // Map symbol names to `Export` for name collision detection.
2058 var symbol_exports: SymbolExports = .{};
2059 defer symbol_exports.deinit(gpa);
2060
2061 for (decl_exports.keys(), decl_exports.values()) |exported_decl, exports_list| {
2062 const exported: Zcu.Exported = .{ .decl_index = exported_decl };
2063 try pt.processExportsInner(&symbol_exports, exported, exports_list.items);
2064 }
2065
2066 for (value_exports.keys(), value_exports.values()) |exported_value, exports_list| {
2067 const exported: Zcu.Exported = .{ .value = exported_value };
2068 try pt.processExportsInner(&symbol_exports, exported, exports_list.items);
2069 }
2070}
2071
2072const SymbolExports = std.AutoArrayHashMapUnmanaged(InternPool.NullTerminatedString, u32);
2073
2074fn processExportsInner(
2075 pt: Zcu.PerThread,
2076 symbol_exports: *SymbolExports,
2077 exported: Zcu.Exported,
2078 export_indices: []const u32,
2079) error{OutOfMemory}!void {
2080 const zcu = pt.zcu;
2081 const gpa = zcu.gpa;
2082
2083 for (export_indices) |export_idx| {
2084 const new_export = &zcu.all_exports.items[export_idx];
2085 const gop = try symbol_exports.getOrPut(gpa, new_export.opts.name);
2086 if (gop.found_existing) {
2087 new_export.status = .failed_retryable;
2088 try zcu.failed_exports.ensureUnusedCapacity(gpa, 1);
2089 const msg = try Zcu.ErrorMsg.create(gpa, new_export.src, "exported symbol collision: {}", .{
2090 new_export.opts.name.fmt(&zcu.intern_pool),
2091 });
2092 errdefer msg.destroy(gpa);
2093 const other_export = zcu.all_exports.items[gop.value_ptr.*];
2094 try zcu.errNote(other_export.src, msg, "other symbol here", .{});
2095 zcu.failed_exports.putAssumeCapacityNoClobber(export_idx, msg);
2096 new_export.status = .failed;
2097 } else {
2098 gop.value_ptr.* = export_idx;
2099 }
2100 }
2101 if (zcu.comp.bin_file) |lf| {
2102 try zcu.handleUpdateExports(export_indices, lf.updateExports(pt, exported, export_indices));
2103 } else if (zcu.llvm_object) |llvm_object| {
2104 if (build_options.only_c) unreachable;
2105 try zcu.handleUpdateExports(export_indices, llvm_object.updateExports(pt, exported, export_indices));
2106 }
2107}
2108
2109pub fn populateTestFunctions(
2110 pt: Zcu.PerThread,
2111 main_progress_node: std.Progress.Node,
2112) !void {
2113 const zcu = pt.zcu;
2114 const gpa = zcu.gpa;
2115 const ip = &zcu.intern_pool;
2116 const builtin_mod = zcu.root_mod.getBuiltinDependency();
2117 const builtin_file_index = (zcu.importPkg(builtin_mod) catch unreachable).file_index;
2118 const root_decl_index = zcu.fileRootDecl(builtin_file_index);
2119 const root_decl = zcu.declPtr(root_decl_index.unwrap().?);
2120 const builtin_namespace = zcu.namespacePtr(root_decl.src_namespace);
2121 const test_functions_str = try ip.getOrPutString(gpa, pt.tid, "test_functions", .no_embedded_nulls);
2122 const decl_index = builtin_namespace.decls.getKeyAdapted(
2123 test_functions_str,
2124 Zcu.DeclAdapter{ .zcu = zcu },
2125 ).?;
2126 {
2127 // We have to call `ensureDeclAnalyzed` here in case `builtin.test_functions`
2128 // was not referenced by start code.
2129 zcu.sema_prog_node = main_progress_node.start("Semantic Analysis", 0);
2130 defer {
2131 zcu.sema_prog_node.end();
2132 zcu.sema_prog_node = std.Progress.Node.none;
2133 }
2134 try pt.ensureDeclAnalyzed(decl_index);
2135 }
2136
2137 const decl = zcu.declPtr(decl_index);
2138 const test_fn_ty = decl.typeOf(zcu).slicePtrFieldType(zcu).childType(zcu);
2139
2140 const array_anon_decl: InternPool.Key.Ptr.BaseAddr.AnonDecl = array: {
2141 // Add zcu.test_functions to an array decl then make the test_functions
2142 // decl reference it as a slice.
2143 const test_fn_vals = try gpa.alloc(InternPool.Index, zcu.test_functions.count());
2144 defer gpa.free(test_fn_vals);
2145
2146 for (test_fn_vals, zcu.test_functions.keys()) |*test_fn_val, test_decl_index| {
2147 const test_decl = zcu.declPtr(test_decl_index);
2148 const test_decl_name = try test_decl.fullyQualifiedName(pt);
2149 const test_decl_name_len = test_decl_name.length(ip);
2150 const test_name_anon_decl: InternPool.Key.Ptr.BaseAddr.AnonDecl = n: {
2151 const test_name_ty = try pt.arrayType(.{
2152 .len = test_decl_name_len,
2153 .child = .u8_type,
2154 });
2155 const test_name_val = try pt.intern(.{ .aggregate = .{
2156 .ty = test_name_ty.toIntern(),
2157 .storage = .{ .bytes = test_decl_name.toString() },
2158 } });
2159 break :n .{
2160 .orig_ty = (try pt.singleConstPtrType(test_name_ty)).toIntern(),
2161 .val = test_name_val,
2162 };
2163 };
2164
2165 const test_fn_fields = .{
2166 // name
2167 try pt.intern(.{ .slice = .{
2168 .ty = .slice_const_u8_type,
2169 .ptr = try pt.intern(.{ .ptr = .{
2170 .ty = .manyptr_const_u8_type,
2171 .base_addr = .{ .anon_decl = test_name_anon_decl },
2172 .byte_offset = 0,
2173 } }),
2174 .len = try pt.intern(.{ .int = .{
2175 .ty = .usize_type,
2176 .storage = .{ .u64 = test_decl_name_len },
2177 } }),
2178 } }),
2179 // func
2180 try pt.intern(.{ .ptr = .{
2181 .ty = try pt.intern(.{ .ptr_type = .{
2182 .child = test_decl.typeOf(zcu).toIntern(),
2183 .flags = .{
2184 .is_const = true,
2185 },
2186 } }),
2187 .base_addr = .{ .decl = test_decl_index },
2188 .byte_offset = 0,
2189 } }),
2190 };
2191 test_fn_val.* = try pt.intern(.{ .aggregate = .{
2192 .ty = test_fn_ty.toIntern(),
2193 .storage = .{ .elems = &test_fn_fields },
2194 } });
2195 }
2196
2197 const array_ty = try pt.arrayType(.{
2198 .len = test_fn_vals.len,
2199 .child = test_fn_ty.toIntern(),
2200 .sentinel = .none,
2201 });
2202 const array_val = try pt.intern(.{ .aggregate = .{
2203 .ty = array_ty.toIntern(),
2204 .storage = .{ .elems = test_fn_vals },
2205 } });
2206 break :array .{
2207 .orig_ty = (try pt.singleConstPtrType(array_ty)).toIntern(),
2208 .val = array_val,
2209 };
2210 };
2211
2212 {
2213 const new_ty = try pt.ptrType(.{
2214 .child = test_fn_ty.toIntern(),
2215 .flags = .{
2216 .is_const = true,
2217 .size = .Slice,
2218 },
2219 });
2220 const new_val = decl.val;
2221 const new_init = try pt.intern(.{ .slice = .{
2222 .ty = new_ty.toIntern(),
2223 .ptr = try pt.intern(.{ .ptr = .{
2224 .ty = new_ty.slicePtrFieldType(zcu).toIntern(),
2225 .base_addr = .{ .anon_decl = array_anon_decl },
2226 .byte_offset = 0,
2227 } }),
2228 .len = (try pt.intValue(Type.usize, zcu.test_functions.count())).toIntern(),
2229 } });
2230 ip.mutateVarInit(decl.val.toIntern(), new_init);
2231
2232 // Since we are replacing the Decl's value we must perform cleanup on the
2233 // previous value.
2234 decl.val = new_val;
2235 decl.has_tv = true;
2236 }
2237 {
2238 zcu.codegen_prog_node = main_progress_node.start("Code Generation", 0);
2239 defer {
2240 zcu.codegen_prog_node.end();
2241 zcu.codegen_prog_node = std.Progress.Node.none;
2242 }
2243
2244 try pt.linkerUpdateDecl(decl_index);
2245 }
2246}
2247
2248pub fn linkerUpdateDecl(pt: Zcu.PerThread, decl_index: Zcu.Decl.Index) !void {
2249 const zcu = pt.zcu;
2250 const comp = zcu.comp;
2251
2252 const decl = zcu.declPtr(decl_index);
2253
2254 const codegen_prog_node = zcu.codegen_prog_node.start((try decl.fullyQualifiedName(pt)).toSlice(&zcu.intern_pool), 0);
2255 defer codegen_prog_node.end();
2256
2257 if (comp.bin_file) |lf| {
2258 lf.updateDecl(pt, decl_index) catch |err| switch (err) {
2259 error.OutOfMemory => return error.OutOfMemory,
2260 error.AnalysisFail => {
2261 decl.analysis = .codegen_failure;
2262 },
2263 else => {
2264 const gpa = zcu.gpa;
2265 try zcu.failed_analysis.ensureUnusedCapacity(gpa, 1);
2266 zcu.failed_analysis.putAssumeCapacityNoClobber(InternPool.AnalUnit.wrap(.{ .decl = decl_index }), try Zcu.ErrorMsg.create(
2267 gpa,
2268 decl.navSrcLoc(zcu),
2269 "unable to codegen: {s}",
2270 .{@errorName(err)},
2271 ));
2272 decl.analysis = .codegen_failure;
2273 try zcu.retryable_failures.append(zcu.gpa, InternPool.AnalUnit.wrap(.{ .decl = decl_index }));
2274 },
2275 };
2276 } else if (zcu.llvm_object) |llvm_object| {
2277 if (build_options.only_c) unreachable;
2278 llvm_object.updateDecl(pt, decl_index) catch |err| switch (err) {
2279 error.OutOfMemory => return error.OutOfMemory,
2280 };
2281 }
2282}
2283
2284/// Shortcut for calling `intern_pool.get`.
2285pub fn intern(pt: Zcu.PerThread, key: InternPool.Key) Allocator.Error!InternPool.Index {
2286 return pt.zcu.intern_pool.get(pt.zcu.gpa, pt.tid, key);
2287}
2288
2289/// Shortcut for calling `intern_pool.getCoerced`.
2290pub fn getCoerced(pt: Zcu.PerThread, val: Value, new_ty: Type) Allocator.Error!Value {
2291 return Value.fromInterned(try pt.zcu.intern_pool.getCoerced(pt.zcu.gpa, pt.tid, val.toIntern(), new_ty.toIntern()));
2292}
2293
2294pub fn intType(pt: Zcu.PerThread, signedness: std.builtin.Signedness, bits: u16) Allocator.Error!Type {
2295 return Type.fromInterned(try pt.intern(.{ .int_type = .{
2296 .signedness = signedness,
2297 .bits = bits,
2298 } }));
2299}
2300
2301pub fn errorIntType(pt: Zcu.PerThread) std.mem.Allocator.Error!Type {
2302 return pt.intType(.unsigned, pt.zcu.errorSetBits());
2303}
2304
2305pub fn arrayType(pt: Zcu.PerThread, info: InternPool.Key.ArrayType) Allocator.Error!Type {
2306 return Type.fromInterned(try pt.intern(.{ .array_type = info }));
2307}
2308
2309pub fn vectorType(pt: Zcu.PerThread, info: InternPool.Key.VectorType) Allocator.Error!Type {
2310 return Type.fromInterned(try pt.intern(.{ .vector_type = info }));
2311}
2312
2313pub fn optionalType(pt: Zcu.PerThread, child_type: InternPool.Index) Allocator.Error!Type {
2314 return Type.fromInterned(try pt.intern(.{ .opt_type = child_type }));
2315}
2316
2317pub fn ptrType(pt: Zcu.PerThread, info: InternPool.Key.PtrType) Allocator.Error!Type {
2318 var canon_info = info;
2319
2320 if (info.flags.size == .C) canon_info.flags.is_allowzero = true;
2321
2322 // Canonicalize non-zero alignment. If it matches the ABI alignment of the pointee
2323 // type, we change it to 0 here. If this causes an assertion trip because the
2324 // pointee type needs to be resolved more, that needs to be done before calling
2325 // this ptr() function.
2326 if (info.flags.alignment != .none and
2327 info.flags.alignment == Type.fromInterned(info.child).abiAlignment(pt))
2328 {
2329 canon_info.flags.alignment = .none;
2330 }
2331
2332 switch (info.flags.vector_index) {
2333 // Canonicalize host_size. If it matches the bit size of the pointee type,
2334 // we change it to 0 here. If this causes an assertion trip, the pointee type
2335 // needs to be resolved before calling this ptr() function.
2336 .none => if (info.packed_offset.host_size != 0) {
2337 const elem_bit_size = Type.fromInterned(info.child).bitSize(pt);
2338 assert(info.packed_offset.bit_offset + elem_bit_size <= info.packed_offset.host_size * 8);
2339 if (info.packed_offset.host_size * 8 == elem_bit_size) {
2340 canon_info.packed_offset.host_size = 0;
2341 }
2342 },
2343 .runtime => {},
2344 _ => assert(@intFromEnum(info.flags.vector_index) < info.packed_offset.host_size),
2345 }
2346
2347 return Type.fromInterned(try pt.intern(.{ .ptr_type = canon_info }));
2348}
2349
2350/// Like `ptrType`, but if `info` specifies an `alignment`, first ensures the pointer
2351/// child type's alignment is resolved so that an invalid alignment is not used.
2352/// In general, prefer this function during semantic analysis.
2353pub fn ptrTypeSema(pt: Zcu.PerThread, info: InternPool.Key.PtrType) Zcu.SemaError!Type {
2354 if (info.flags.alignment != .none) {
2355 _ = try Type.fromInterned(info.child).abiAlignmentAdvanced(pt, .sema);
2356 }
2357 return pt.ptrType(info);
2358}
2359
2360pub fn singleMutPtrType(pt: Zcu.PerThread, child_type: Type) Allocator.Error!Type {
2361 return pt.ptrType(.{ .child = child_type.toIntern() });
2362}
2363
2364pub fn singleConstPtrType(pt: Zcu.PerThread, child_type: Type) Allocator.Error!Type {
2365 return pt.ptrType(.{
2366 .child = child_type.toIntern(),
2367 .flags = .{
2368 .is_const = true,
2369 },
2370 });
2371}
2372
2373pub fn manyConstPtrType(pt: Zcu.PerThread, child_type: Type) Allocator.Error!Type {
2374 return pt.ptrType(.{
2375 .child = child_type.toIntern(),
2376 .flags = .{
2377 .size = .Many,
2378 .is_const = true,
2379 },
2380 });
2381}
2382
2383pub fn adjustPtrTypeChild(pt: Zcu.PerThread, ptr_ty: Type, new_child: Type) Allocator.Error!Type {
2384 var info = ptr_ty.ptrInfo(pt.zcu);
2385 info.child = new_child.toIntern();
2386 return pt.ptrType(info);
2387}
2388
2389pub fn funcType(pt: Zcu.PerThread, key: InternPool.GetFuncTypeKey) Allocator.Error!Type {
2390 return Type.fromInterned(try pt.zcu.intern_pool.getFuncType(pt.zcu.gpa, pt.tid, key));
2391}
2392
2393/// Use this for `anyframe->T` only.
2394/// For `anyframe`, use the `InternPool.Index.anyframe` tag directly.
2395pub fn anyframeType(pt: Zcu.PerThread, payload_ty: Type) Allocator.Error!Type {
2396 return Type.fromInterned(try pt.intern(.{ .anyframe_type = payload_ty.toIntern() }));
2397}
2398
2399pub fn errorUnionType(pt: Zcu.PerThread, error_set_ty: Type, payload_ty: Type) Allocator.Error!Type {
2400 return Type.fromInterned(try pt.intern(.{ .error_union_type = .{
2401 .error_set_type = error_set_ty.toIntern(),
2402 .payload_type = payload_ty.toIntern(),
2403 } }));
2404}
2405
2406pub fn singleErrorSetType(pt: Zcu.PerThread, name: InternPool.NullTerminatedString) Allocator.Error!Type {
2407 const names: *const [1]InternPool.NullTerminatedString = &name;
2408 return Type.fromInterned(try pt.zcu.intern_pool.getErrorSetType(pt.zcu.gpa, pt.tid, names));
2409}
2410
2411/// Sorts `names` in place.
2412pub fn errorSetFromUnsortedNames(
2413 pt: Zcu.PerThread,
2414 names: []InternPool.NullTerminatedString,
2415) Allocator.Error!Type {
2416 std.mem.sort(
2417 InternPool.NullTerminatedString,
2418 names,
2419 {},
2420 InternPool.NullTerminatedString.indexLessThan,
2421 );
2422 const new_ty = try pt.zcu.intern_pool.getErrorSetType(pt.zcu.gpa, pt.tid, names);
2423 return Type.fromInterned(new_ty);
2424}
2425
2426/// Supports only pointers, not pointer-like optionals.
2427pub fn ptrIntValue(pt: Zcu.PerThread, ty: Type, x: u64) Allocator.Error!Value {
2428 const mod = pt.zcu;
2429 assert(ty.zigTypeTag(mod) == .Pointer and !ty.isSlice(mod));
2430 assert(x != 0 or ty.isAllowzeroPtr(mod));
2431 return Value.fromInterned(try pt.intern(.{ .ptr = .{
2432 .ty = ty.toIntern(),
2433 .base_addr = .int,
2434 .byte_offset = x,
2435 } }));
2436}
2437
2438/// Creates an enum tag value based on the integer tag value.
2439pub fn enumValue(pt: Zcu.PerThread, ty: Type, tag_int: InternPool.Index) Allocator.Error!Value {
2440 if (std.debug.runtime_safety) {
2441 const tag = ty.zigTypeTag(pt.zcu);
2442 assert(tag == .Enum);
2443 }
2444 return Value.fromInterned(try pt.intern(.{ .enum_tag = .{
2445 .ty = ty.toIntern(),
2446 .int = tag_int,
2447 } }));
2448}
2449
2450/// Creates an enum tag value based on the field index according to source code
2451/// declaration order.
2452pub fn enumValueFieldIndex(pt: Zcu.PerThread, ty: Type, field_index: u32) Allocator.Error!Value {
2453 const ip = &pt.zcu.intern_pool;
2454 const enum_type = ip.loadEnumType(ty.toIntern());
2455
2456 if (enum_type.values.len == 0) {
2457 // Auto-numbered fields.
2458 return Value.fromInterned(try pt.intern(.{ .enum_tag = .{
2459 .ty = ty.toIntern(),
2460 .int = try pt.intern(.{ .int = .{
2461 .ty = enum_type.tag_ty,
2462 .storage = .{ .u64 = field_index },
2463 } }),
2464 } }));
2465 }
2466
2467 return Value.fromInterned(try pt.intern(.{ .enum_tag = .{
2468 .ty = ty.toIntern(),
2469 .int = enum_type.values.get(ip)[field_index],
2470 } }));
2471}
2472
2473pub fn undefValue(pt: Zcu.PerThread, ty: Type) Allocator.Error!Value {
2474 return Value.fromInterned(try pt.intern(.{ .undef = ty.toIntern() }));
2475}
2476
2477pub fn undefRef(pt: Zcu.PerThread, ty: Type) Allocator.Error!Air.Inst.Ref {
2478 return Air.internedToRef((try pt.undefValue(ty)).toIntern());
2479}
2480
2481pub fn intValue(pt: Zcu.PerThread, ty: Type, x: anytype) Allocator.Error!Value {
2482 if (std.math.cast(u64, x)) |casted| return pt.intValue_u64(ty, casted);
2483 if (std.math.cast(i64, x)) |casted| return pt.intValue_i64(ty, casted);
2484 var limbs_buffer: [4]usize = undefined;
2485 var big_int = BigIntMutable.init(&limbs_buffer, x);
2486 return pt.intValue_big(ty, big_int.toConst());
2487}
2488
2489pub fn intRef(pt: Zcu.PerThread, ty: Type, x: anytype) Allocator.Error!Air.Inst.Ref {
2490 return Air.internedToRef((try pt.intValue(ty, x)).toIntern());
2491}
2492
2493pub fn intValue_big(pt: Zcu.PerThread, ty: Type, x: BigIntConst) Allocator.Error!Value {
2494 return Value.fromInterned(try pt.intern(.{ .int = .{
2495 .ty = ty.toIntern(),
2496 .storage = .{ .big_int = x },
2497 } }));
2498}
2499
2500pub fn intValue_u64(pt: Zcu.PerThread, ty: Type, x: u64) Allocator.Error!Value {
2501 return Value.fromInterned(try pt.intern(.{ .int = .{
2502 .ty = ty.toIntern(),
2503 .storage = .{ .u64 = x },
2504 } }));
2505}
2506
2507pub fn intValue_i64(pt: Zcu.PerThread, ty: Type, x: i64) Allocator.Error!Value {
2508 return Value.fromInterned(try pt.intern(.{ .int = .{
2509 .ty = ty.toIntern(),
2510 .storage = .{ .i64 = x },
2511 } }));
2512}
2513
2514pub fn unionValue(pt: Zcu.PerThread, union_ty: Type, tag: Value, val: Value) Allocator.Error!Value {
2515 return Value.fromInterned(try pt.intern(.{ .un = .{
2516 .ty = union_ty.toIntern(),
2517 .tag = tag.toIntern(),
2518 .val = val.toIntern(),
2519 } }));
2520}
2521
2522/// This function casts the float representation down to the representation of the type, potentially
2523/// losing data if the representation wasn't correct.
2524pub fn floatValue(pt: Zcu.PerThread, ty: Type, x: anytype) Allocator.Error!Value {
2525 const storage: InternPool.Key.Float.Storage = switch (ty.floatBits(pt.zcu.getTarget())) {
2526 16 => .{ .f16 = @as(f16, @floatCast(x)) },
2527 32 => .{ .f32 = @as(f32, @floatCast(x)) },
2528 64 => .{ .f64 = @as(f64, @floatCast(x)) },
2529 80 => .{ .f80 = @as(f80, @floatCast(x)) },
2530 128 => .{ .f128 = @as(f128, @floatCast(x)) },
2531 else => unreachable,
2532 };
2533 return Value.fromInterned(try pt.intern(.{ .float = .{
2534 .ty = ty.toIntern(),
2535 .storage = storage,
2536 } }));
2537}
2538
2539pub fn nullValue(pt: Zcu.PerThread, opt_ty: Type) Allocator.Error!Value {
2540 assert(pt.zcu.intern_pool.isOptionalType(opt_ty.toIntern()));
2541 return Value.fromInterned(try pt.intern(.{ .opt = .{
2542 .ty = opt_ty.toIntern(),
2543 .val = .none,
2544 } }));
2545}
2546
2547pub fn smallestUnsignedInt(pt: Zcu.PerThread, max: u64) Allocator.Error!Type {
2548 return pt.intType(.unsigned, Type.smallestUnsignedBits(max));
2549}
2550
2551/// Returns the smallest possible integer type containing both `min` and
2552/// `max`. Asserts that neither value is undef.
2553/// TODO: if #3806 is implemented, this becomes trivial
2554pub fn intFittingRange(pt: Zcu.PerThread, min: Value, max: Value) !Type {
2555 const mod = pt.zcu;
2556 assert(!min.isUndef(mod));
2557 assert(!max.isUndef(mod));
2558
2559 if (std.debug.runtime_safety) {
2560 assert(Value.order(min, max, pt).compare(.lte));
2561 }
2562
2563 const sign = min.orderAgainstZero(pt) == .lt;
2564
2565 const min_val_bits = pt.intBitsForValue(min, sign);
2566 const max_val_bits = pt.intBitsForValue(max, sign);
2567
2568 return pt.intType(
2569 if (sign) .signed else .unsigned,
2570 @max(min_val_bits, max_val_bits),
2571 );
2572}
2573
2574/// Given a value representing an integer, returns the number of bits necessary to represent
2575/// this value in an integer. If `sign` is true, returns the number of bits necessary in a
2576/// twos-complement integer; otherwise in an unsigned integer.
2577/// Asserts that `val` is not undef. If `val` is negative, asserts that `sign` is true.
2578pub fn intBitsForValue(pt: Zcu.PerThread, val: Value, sign: bool) u16 {
2579 const mod = pt.zcu;
2580 assert(!val.isUndef(mod));
2581
2582 const key = mod.intern_pool.indexToKey(val.toIntern());
2583 switch (key.int.storage) {
2584 .i64 => |x| {
2585 if (std.math.cast(u64, x)) |casted| return Type.smallestUnsignedBits(casted) + @intFromBool(sign);
2586 assert(sign);
2587 // Protect against overflow in the following negation.
2588 if (x == std.math.minInt(i64)) return 64;
2589 return Type.smallestUnsignedBits(@as(u64, @intCast(-(x + 1)))) + 1;
2590 },
2591 .u64 => |x| {
2592 return Type.smallestUnsignedBits(x) + @intFromBool(sign);
2593 },
2594 .big_int => |big| {
2595 if (big.positive) return @as(u16, @intCast(big.bitCountAbs() + @intFromBool(sign)));
2596
2597 // Zero is still a possibility, in which case unsigned is fine
2598 if (big.eqlZero()) return 0;
2599
2600 return @as(u16, @intCast(big.bitCountTwosComp()));
2601 },
2602 .lazy_align => |lazy_ty| {
2603 return Type.smallestUnsignedBits(Type.fromInterned(lazy_ty).abiAlignment(pt).toByteUnits() orelse 0) + @intFromBool(sign);
2604 },
2605 .lazy_size => |lazy_ty| {
2606 return Type.smallestUnsignedBits(Type.fromInterned(lazy_ty).abiSize(pt)) + @intFromBool(sign);
2607 },
2608 }
2609}
2610
2611pub fn getUnionLayout(pt: Zcu.PerThread, loaded_union: InternPool.LoadedUnionType) Zcu.UnionLayout {
2612 const mod = pt.zcu;
2613 const ip = &mod.intern_pool;
2614 assert(loaded_union.haveLayout(ip));
2615 var most_aligned_field: u32 = undefined;
2616 var most_aligned_field_size: u64 = undefined;
2617 var biggest_field: u32 = undefined;
2618 var payload_size: u64 = 0;
2619 var payload_align: InternPool.Alignment = .@"1";
2620 for (loaded_union.field_types.get(ip), 0..) |field_ty, field_index| {
2621 if (!Type.fromInterned(field_ty).hasRuntimeBitsIgnoreComptime(pt)) continue;
2622
2623 const explicit_align = loaded_union.fieldAlign(ip, field_index);
2624 const field_align = if (explicit_align != .none)
2625 explicit_align
2626 else
2627 Type.fromInterned(field_ty).abiAlignment(pt);
2628 const field_size = Type.fromInterned(field_ty).abiSize(pt);
2629 if (field_size > payload_size) {
2630 payload_size = field_size;
2631 biggest_field = @intCast(field_index);
2632 }
2633 if (field_align.compare(.gte, payload_align)) {
2634 payload_align = field_align;
2635 most_aligned_field = @intCast(field_index);
2636 most_aligned_field_size = field_size;
2637 }
2638 }
2639 const have_tag = loaded_union.flagsPtr(ip).runtime_tag.hasTag();
2640 if (!have_tag or !Type.fromInterned(loaded_union.enum_tag_ty).hasRuntimeBits(pt)) {
2641 return .{
2642 .abi_size = payload_align.forward(payload_size),
2643 .abi_align = payload_align,
2644 .most_aligned_field = most_aligned_field,
2645 .most_aligned_field_size = most_aligned_field_size,
2646 .biggest_field = biggest_field,
2647 .payload_size = payload_size,
2648 .payload_align = payload_align,
2649 .tag_align = .none,
2650 .tag_size = 0,
2651 .padding = 0,
2652 };
2653 }
2654
2655 const tag_size = Type.fromInterned(loaded_union.enum_tag_ty).abiSize(pt);
2656 const tag_align = Type.fromInterned(loaded_union.enum_tag_ty).abiAlignment(pt).max(.@"1");
2657 return .{
2658 .abi_size = loaded_union.size(ip).*,
2659 .abi_align = tag_align.max(payload_align),
2660 .most_aligned_field = most_aligned_field,
2661 .most_aligned_field_size = most_aligned_field_size,
2662 .biggest_field = biggest_field,
2663 .payload_size = payload_size,
2664 .payload_align = payload_align,
2665 .tag_align = tag_align,
2666 .tag_size = tag_size,
2667 .padding = loaded_union.padding(ip).*,
2668 };
2669}
2670
2671pub fn unionAbiSize(mod: *Module, loaded_union: InternPool.LoadedUnionType) u64 {
2672 return mod.getUnionLayout(loaded_union).abi_size;
2673}
2674
2675/// Returns 0 if the union is represented with 0 bits at runtime.
2676pub fn unionAbiAlignment(pt: Zcu.PerThread, loaded_union: InternPool.LoadedUnionType) InternPool.Alignment {
2677 const mod = pt.zcu;
2678 const ip = &mod.intern_pool;
2679 const have_tag = loaded_union.flagsPtr(ip).runtime_tag.hasTag();
2680 var max_align: InternPool.Alignment = .none;
2681 if (have_tag) max_align = Type.fromInterned(loaded_union.enum_tag_ty).abiAlignment(pt);
2682 for (loaded_union.field_types.get(ip), 0..) |field_ty, field_index| {
2683 if (!Type.fromInterned(field_ty).hasRuntimeBits(pt)) continue;
2684
2685 const field_align = mod.unionFieldNormalAlignment(loaded_union, @intCast(field_index));
2686 max_align = max_align.max(field_align);
2687 }
2688 return max_align;
2689}
2690
2691/// Returns the field alignment of a non-packed union. Asserts the layout is not packed.
2692pub fn unionFieldNormalAlignment(
2693 pt: Zcu.PerThread,
2694 loaded_union: InternPool.LoadedUnionType,
2695 field_index: u32,
2696) InternPool.Alignment {
2697 return pt.unionFieldNormalAlignmentAdvanced(loaded_union, field_index, .normal) catch unreachable;
2698}
2699
2700/// Returns the field alignment of a non-packed union. Asserts the layout is not packed.
2701/// If `strat` is `.sema`, may perform type resolution.
2702pub fn unionFieldNormalAlignmentAdvanced(
2703 pt: Zcu.PerThread,
2704 loaded_union: InternPool.LoadedUnionType,
2705 field_index: u32,
2706 strat: Type.ResolveStrat,
2707) Zcu.SemaError!InternPool.Alignment {
2708 const ip = &pt.zcu.intern_pool;
2709 assert(loaded_union.flagsPtr(ip).layout != .@"packed");
2710 const field_align = loaded_union.fieldAlign(ip, field_index);
2711 if (field_align != .none) return field_align;
2712 const field_ty = Type.fromInterned(loaded_union.field_types.get(ip)[field_index]);
2713 if (field_ty.isNoReturn(pt.zcu)) return .none;
2714 return (try field_ty.abiAlignmentAdvanced(pt, strat.toLazy())).scalar;
2715}
2716
2717/// Returns the field alignment of a non-packed struct. Asserts the layout is not packed.
2718pub fn structFieldAlignment(
2719 pt: Zcu.PerThread,
2720 explicit_alignment: InternPool.Alignment,
2721 field_ty: Type,
2722 layout: std.builtin.Type.ContainerLayout,
2723) InternPool.Alignment {
2724 return pt.structFieldAlignmentAdvanced(explicit_alignment, field_ty, layout, .normal) catch unreachable;
2725}
2726
2727/// Returns the field alignment of a non-packed struct. Asserts the layout is not packed.
2728/// If `strat` is `.sema`, may perform type resolution.
2729pub fn structFieldAlignmentAdvanced(
2730 pt: Zcu.PerThread,
2731 explicit_alignment: InternPool.Alignment,
2732 field_ty: Type,
2733 layout: std.builtin.Type.ContainerLayout,
2734 strat: Type.ResolveStrat,
2735) Zcu.SemaError!InternPool.Alignment {
2736 assert(layout != .@"packed");
2737 if (explicit_alignment != .none) return explicit_alignment;
2738 const ty_abi_align = (try field_ty.abiAlignmentAdvanced(pt, strat.toLazy())).scalar;
2739 switch (layout) {
2740 .@"packed" => unreachable,
2741 .auto => if (pt.zcu.getTarget().ofmt != .c) return ty_abi_align,
2742 .@"extern" => {},
2743 }
2744 // extern
2745 if (field_ty.isAbiInt(pt.zcu) and field_ty.intInfo(pt.zcu).bits >= 128) {
2746 return ty_abi_align.maxStrict(.@"16");
2747 }
2748 return ty_abi_align;
2749}
2750
2751/// https://github.com/ziglang/zig/issues/17178 explored storing these bit offsets
2752/// into the packed struct InternPool data rather than computing this on the
2753/// fly, however it was found to perform worse when measured on real world
2754/// projects.
2755pub fn structPackedFieldBitOffset(
2756 pt: Zcu.PerThread,
2757 struct_type: InternPool.LoadedStructType,
2758 field_index: u32,
2759) u16 {
2760 const mod = pt.zcu;
2761 const ip = &mod.intern_pool;
2762 assert(struct_type.layout == .@"packed");
2763 assert(struct_type.haveLayout(ip));
2764 var bit_sum: u64 = 0;
2765 for (0..struct_type.field_types.len) |i| {
2766 if (i == field_index) {
2767 return @intCast(bit_sum);
2768 }
2769 const field_ty = Type.fromInterned(struct_type.field_types.get(ip)[i]);
2770 bit_sum += field_ty.bitSize(pt);
2771 }
2772 unreachable; // index out of bounds
2773}
2774
2775pub fn getBuiltin(pt: Zcu.PerThread, name: []const u8) Allocator.Error!Air.Inst.Ref {
2776 const decl_index = try pt.getBuiltinDecl(name);
2777 pt.ensureDeclAnalyzed(decl_index) catch @panic("std.builtin is corrupt");
2778 return Air.internedToRef(pt.zcu.declPtr(decl_index).val.toIntern());
2779}
2780
2781pub fn getBuiltinDecl(pt: Zcu.PerThread, name: []const u8) Allocator.Error!InternPool.DeclIndex {
2782 const zcu = pt.zcu;
2783 const gpa = zcu.gpa;
2784 const ip = &zcu.intern_pool;
2785 const std_file_imported = zcu.importPkg(zcu.std_mod) catch @panic("failed to import lib/std.zig");
2786 const std_file_root_decl = zcu.fileRootDecl(std_file_imported.file_index).unwrap().?;
2787 const std_namespace = zcu.declPtr(std_file_root_decl).getOwnedInnerNamespace(zcu).?;
2788 const builtin_str = try ip.getOrPutString(gpa, pt.tid, "builtin", .no_embedded_nulls);
2789 const builtin_decl = std_namespace.decls.getKeyAdapted(builtin_str, Zcu.DeclAdapter{ .zcu = zcu }) orelse @panic("lib/std.zig is corrupt and missing 'builtin'");
2790 pt.ensureDeclAnalyzed(builtin_decl) catch @panic("std.builtin is corrupt");
2791 const builtin_namespace = zcu.declPtr(builtin_decl).getInnerNamespace(zcu) orelse @panic("std.builtin is corrupt");
2792 const name_str = try ip.getOrPutString(gpa, pt.tid, name, .no_embedded_nulls);
2793 return builtin_namespace.decls.getKeyAdapted(name_str, Zcu.DeclAdapter{ .zcu = zcu }) orelse @panic("lib/std/builtin.zig is corrupt");
2794}
2795
2796pub fn getBuiltinType(pt: Zcu.PerThread, name: []const u8) Allocator.Error!Type {
2797 const ty_inst = try pt.getBuiltin(name);
2798 const ty = Type.fromInterned(ty_inst.toInterned() orelse @panic("std.builtin is corrupt"));
2799 ty.resolveFully(pt) catch @panic("std.builtin is corrupt");
2800 return ty;
2801}
2802
2803const Air = @import("../Air.zig");
2804const Allocator = std.mem.Allocator;
2805const assert = std.debug.assert;
2806const Ast = std.zig.Ast;
2807const AstGen = std.zig.AstGen;
2808const BigIntConst = std.math.big.int.Const;
2809const BigIntMutable = std.math.big.int.Mutable;
2810const build_options = @import("build_options");
2811const builtin = @import("builtin");
2812const Cache = std.Build.Cache;
2813const InternPool = @import("../InternPool.zig");
2814const isUpDir = @import("../introspect.zig").isUpDir;
2815const Liveness = @import("../Liveness.zig");
2816const log = std.log.scoped(.zcu);
2817const Module = @import("../Package.zig").Module;
2818const Sema = @import("../Sema.zig");
2819const std = @import("std");
2820const target_util = @import("../target.zig");
2821const trace = @import("../tracy.zig").trace;
2822const Type = @import("../Type.zig");
2823const Value = @import("../Value.zig");
2824const Zcu = @import("../Zcu.zig");
2825const Zir = std.zig.Zir;
src/arch/aarch64/CodeGen.zig+220-163
...@@ -12,11 +12,9 @@ const Type = @import("../../Type.zig");...@@ -12,11 +12,9 @@ const Type = @import("../../Type.zig");
12const Value = @import("../../Value.zig");12const Value = @import("../../Value.zig");
13const link = @import("../../link.zig");13const link = @import("../../link.zig");
14const Zcu = @import("../../Zcu.zig");14const Zcu = @import("../../Zcu.zig");
15/// Deprecated.
16const Module = Zcu;
17const InternPool = @import("../../InternPool.zig");15const InternPool = @import("../../InternPool.zig");
18const Compilation = @import("../../Compilation.zig");16const Compilation = @import("../../Compilation.zig");
19const ErrorMsg = Module.ErrorMsg;17const ErrorMsg = Zcu.ErrorMsg;
20const Target = std.Target;18const Target = std.Target;
21const Allocator = mem.Allocator;19const Allocator = mem.Allocator;
22const trace = @import("../../tracy.zig").trace;20const trace = @import("../../tracy.zig").trace;
...@@ -47,6 +45,7 @@ const gp = abi.RegisterClass.gp;...@@ -47,6 +45,7 @@ const gp = abi.RegisterClass.gp;
47const InnerError = CodeGenError || error{OutOfRegisters};45const InnerError = CodeGenError || error{OutOfRegisters};
4846
49gpa: Allocator,47gpa: Allocator,
48pt: Zcu.PerThread,
50air: Air,49air: Air,
51liveness: Liveness,50liveness: Liveness,
52bin_file: *link.File,51bin_file: *link.File,
...@@ -59,7 +58,7 @@ args: []MCValue,...@@ -59,7 +58,7 @@ args: []MCValue,
59ret_mcv: MCValue,58ret_mcv: MCValue,
60fn_type: Type,59fn_type: Type,
61arg_index: u32,60arg_index: u32,
62src_loc: Module.LazySrcLoc,61src_loc: Zcu.LazySrcLoc,
63stack_align: u32,62stack_align: u32,
6463
65/// MIR Instructions64/// MIR Instructions
...@@ -331,15 +330,16 @@ const Self = @This();...@@ -331,15 +330,16 @@ const Self = @This();
331330
332pub fn generate(331pub fn generate(
333 lf: *link.File,332 lf: *link.File,
334 src_loc: Module.LazySrcLoc,333 pt: Zcu.PerThread,
334 src_loc: Zcu.LazySrcLoc,
335 func_index: InternPool.Index,335 func_index: InternPool.Index,
336 air: Air,336 air: Air,
337 liveness: Liveness,337 liveness: Liveness,
338 code: *std.ArrayList(u8),338 code: *std.ArrayList(u8),
339 debug_output: DebugInfoOutput,339 debug_output: DebugInfoOutput,
340) CodeGenError!Result {340) CodeGenError!Result {
341 const gpa = lf.comp.gpa;341 const zcu = pt.zcu;
342 const zcu = lf.comp.module.?;342 const gpa = zcu.gpa;
343 const func = zcu.funcInfo(func_index);343 const func = zcu.funcInfo(func_index);
344 const fn_owner_decl = zcu.declPtr(func.owner_decl);344 const fn_owner_decl = zcu.declPtr(func.owner_decl);
345 assert(fn_owner_decl.has_tv);345 assert(fn_owner_decl.has_tv);
...@@ -355,8 +355,9 @@ pub fn generate(...@@ -355,8 +355,9 @@ pub fn generate(
355 }355 }
356 try branch_stack.append(.{});356 try branch_stack.append(.{});
357357
358 var function = Self{358 var function: Self = .{
359 .gpa = gpa,359 .gpa = gpa,
360 .pt = pt,
360 .air = air,361 .air = air,
361 .liveness = liveness,362 .liveness = liveness,
362 .debug_output = debug_output,363 .debug_output = debug_output,
...@@ -476,7 +477,8 @@ pub fn addExtraAssumeCapacity(self: *Self, extra: anytype) u32 {...@@ -476,7 +477,8 @@ pub fn addExtraAssumeCapacity(self: *Self, extra: anytype) u32 {
476}477}
477478
478fn gen(self: *Self) !void {479fn gen(self: *Self) !void {
479 const mod = self.bin_file.comp.module.?;480 const pt = self.pt;
481 const mod = pt.zcu;
480 const cc = self.fn_type.fnCallingConvention(mod);482 const cc = self.fn_type.fnCallingConvention(mod);
481 if (cc != .Naked) {483 if (cc != .Naked) {
482 // stp fp, lr, [sp, #-16]!484 // stp fp, lr, [sp, #-16]!
...@@ -526,8 +528,8 @@ fn gen(self: *Self) !void {...@@ -526,8 +528,8 @@ fn gen(self: *Self) !void {
526528
527 const ty = self.typeOfIndex(inst);529 const ty = self.typeOfIndex(inst);
528530
529 const abi_size = @as(u32, @intCast(ty.abiSize(mod)));531 const abi_size = @as(u32, @intCast(ty.abiSize(pt)));
530 const abi_align = ty.abiAlignment(mod);532 const abi_align = ty.abiAlignment(pt);
531 const stack_offset = try self.allocMem(abi_size, abi_align, inst);533 const stack_offset = try self.allocMem(abi_size, abi_align, inst);
532 try self.genSetStack(ty, stack_offset, MCValue{ .register = reg });534 try self.genSetStack(ty, stack_offset, MCValue{ .register = reg });
533535
...@@ -656,7 +658,8 @@ fn gen(self: *Self) !void {...@@ -656,7 +658,8 @@ fn gen(self: *Self) !void {
656}658}
657659
658fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {660fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {
659 const mod = self.bin_file.comp.module.?;661 const pt = self.pt;
662 const mod = pt.zcu;
660 const ip = &mod.intern_pool;663 const ip = &mod.intern_pool;
661 const air_tags = self.air.instructions.items(.tag);664 const air_tags = self.air.instructions.items(.tag);
662665
...@@ -1022,31 +1025,32 @@ fn allocMem(...@@ -1022,31 +1025,32 @@ fn allocMem(
10221025
1023/// Use a pointer instruction as the basis for allocating stack memory.1026/// Use a pointer instruction as the basis for allocating stack memory.
1024fn allocMemPtr(self: *Self, inst: Air.Inst.Index) !u32 {1027fn allocMemPtr(self: *Self, inst: Air.Inst.Index) !u32 {
1025 const mod = self.bin_file.comp.module.?;1028 const pt = self.pt;
1029 const mod = pt.zcu;
1026 const elem_ty = self.typeOfIndex(inst).childType(mod);1030 const elem_ty = self.typeOfIndex(inst).childType(mod);
10271031
1028 if (!elem_ty.hasRuntimeBits(mod)) {1032 if (!elem_ty.hasRuntimeBits(pt)) {
1029 // return the stack offset 0. Stack offset 0 will be where all1033 // return the stack offset 0. Stack offset 0 will be where all
1030 // zero-sized stack allocations live as non-zero-sized1034 // zero-sized stack allocations live as non-zero-sized
1031 // allocations will always have an offset > 0.1035 // allocations will always have an offset > 0.
1032 return @as(u32, 0);1036 return @as(u32, 0);
1033 }1037 }
10341038
1035 const abi_size = math.cast(u32, elem_ty.abiSize(mod)) orelse {1039 const abi_size = math.cast(u32, elem_ty.abiSize(pt)) orelse {
1036 return self.fail("type '{}' too big to fit into stack frame", .{elem_ty.fmt(mod)});1040 return self.fail("type '{}' too big to fit into stack frame", .{elem_ty.fmt(pt)});
1037 };1041 };
1038 // TODO swap this for inst.ty.ptrAlign1042 // TODO swap this for inst.ty.ptrAlign
1039 const abi_align = elem_ty.abiAlignment(mod);1043 const abi_align = elem_ty.abiAlignment(pt);
10401044
1041 return self.allocMem(abi_size, abi_align, inst);1045 return self.allocMem(abi_size, abi_align, inst);
1042}1046}
10431047
1044fn allocRegOrMem(self: *Self, elem_ty: Type, reg_ok: bool, maybe_inst: ?Air.Inst.Index) !MCValue {1048fn allocRegOrMem(self: *Self, elem_ty: Type, reg_ok: bool, maybe_inst: ?Air.Inst.Index) !MCValue {
1045 const mod = self.bin_file.comp.module.?;1049 const pt = self.pt;
1046 const abi_size = math.cast(u32, elem_ty.abiSize(mod)) orelse {1050 const abi_size = math.cast(u32, elem_ty.abiSize(pt)) orelse {
1047 return self.fail("type '{}' too big to fit into stack frame", .{elem_ty.fmt(mod)});1051 return self.fail("type '{}' too big to fit into stack frame", .{elem_ty.fmt(pt)});
1048 };1052 };
1049 const abi_align = elem_ty.abiAlignment(mod);1053 const abi_align = elem_ty.abiAlignment(pt);
10501054
1051 if (reg_ok) {1055 if (reg_ok) {
1052 // Make sure the type can fit in a register before we try to allocate one.1056 // Make sure the type can fit in a register before we try to allocate one.
...@@ -1133,14 +1137,15 @@ fn airAlloc(self: *Self, inst: Air.Inst.Index) !void {...@@ -1133,14 +1137,15 @@ fn airAlloc(self: *Self, inst: Air.Inst.Index) !void {
1133}1137}
11341138
1135fn airRetPtr(self: *Self, inst: Air.Inst.Index) !void {1139fn airRetPtr(self: *Self, inst: Air.Inst.Index) !void {
1136 const mod = self.bin_file.comp.module.?;1140 const pt = self.pt;
1141 const mod = pt.zcu;
1137 const result: MCValue = switch (self.ret_mcv) {1142 const result: MCValue = switch (self.ret_mcv) {
1138 .none, .register => .{ .ptr_stack_offset = try self.allocMemPtr(inst) },1143 .none, .register => .{ .ptr_stack_offset = try self.allocMemPtr(inst) },
1139 .stack_offset => blk: {1144 .stack_offset => blk: {
1140 // self.ret_mcv is an address to where this function1145 // self.ret_mcv is an address to where this function
1141 // should store its result into1146 // should store its result into
1142 const ret_ty = self.fn_type.fnReturnType(mod);1147 const ret_ty = self.fn_type.fnReturnType(mod);
1143 const ptr_ty = try mod.singleMutPtrType(ret_ty);1148 const ptr_ty = try pt.singleMutPtrType(ret_ty);
11441149
1145 // addr_reg will contain the address of where to store the1150 // addr_reg will contain the address of where to store the
1146 // result into1151 // result into
...@@ -1170,7 +1175,8 @@ fn airIntCast(self: *Self, inst: Air.Inst.Index) !void {...@@ -1170,7 +1175,8 @@ fn airIntCast(self: *Self, inst: Air.Inst.Index) !void {
1170 if (self.liveness.isUnused(inst))1175 if (self.liveness.isUnused(inst))
1171 return self.finishAir(inst, .dead, .{ ty_op.operand, .none, .none });1176 return self.finishAir(inst, .dead, .{ ty_op.operand, .none, .none });
11721177
1173 const mod = self.bin_file.comp.module.?;1178 const pt = self.pt;
1179 const mod = pt.zcu;
1174 const operand = ty_op.operand;1180 const operand = ty_op.operand;
1175 const operand_mcv = try self.resolveInst(operand);1181 const operand_mcv = try self.resolveInst(operand);
1176 const operand_ty = self.typeOf(operand);1182 const operand_ty = self.typeOf(operand);
...@@ -1251,7 +1257,8 @@ fn trunc(...@@ -1251,7 +1257,8 @@ fn trunc(
1251 operand_ty: Type,1257 operand_ty: Type,
1252 dest_ty: Type,1258 dest_ty: Type,
1253) !MCValue {1259) !MCValue {
1254 const mod = self.bin_file.comp.module.?;1260 const pt = self.pt;
1261 const mod = pt.zcu;
1255 const info_a = operand_ty.intInfo(mod);1262 const info_a = operand_ty.intInfo(mod);
1256 const info_b = dest_ty.intInfo(mod);1263 const info_b = dest_ty.intInfo(mod);
12571264
...@@ -1314,7 +1321,8 @@ fn airIntFromBool(self: *Self, inst: Air.Inst.Index) !void {...@@ -1314,7 +1321,8 @@ fn airIntFromBool(self: *Self, inst: Air.Inst.Index) !void {
13141321
1315fn airNot(self: *Self, inst: Air.Inst.Index) !void {1322fn airNot(self: *Self, inst: Air.Inst.Index) !void {
1316 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;1323 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
1317 const mod = self.bin_file.comp.module.?;1324 const pt = self.pt;
1325 const mod = pt.zcu;
1318 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {1326 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
1319 const operand = try self.resolveInst(ty_op.operand);1327 const operand = try self.resolveInst(ty_op.operand);
1320 const operand_ty = self.typeOf(ty_op.operand);1328 const operand_ty = self.typeOf(ty_op.operand);
...@@ -1409,7 +1417,8 @@ fn minMax(...@@ -1409,7 +1417,8 @@ fn minMax(
1409 rhs_ty: Type,1417 rhs_ty: Type,
1410 maybe_inst: ?Air.Inst.Index,1418 maybe_inst: ?Air.Inst.Index,
1411) !MCValue {1419) !MCValue {
1412 const mod = self.bin_file.comp.module.?;1420 const pt = self.pt;
1421 const mod = pt.zcu;
1413 switch (lhs_ty.zigTypeTag(mod)) {1422 switch (lhs_ty.zigTypeTag(mod)) {
1414 .Float => return self.fail("TODO ARM min/max on floats", .{}),1423 .Float => return self.fail("TODO ARM min/max on floats", .{}),
1415 .Vector => return self.fail("TODO ARM min/max on vectors", .{}),1424 .Vector => return self.fail("TODO ARM min/max on vectors", .{}),
...@@ -1899,7 +1908,8 @@ fn addSub(...@@ -1899,7 +1908,8 @@ fn addSub(
1899 rhs_ty: Type,1908 rhs_ty: Type,
1900 maybe_inst: ?Air.Inst.Index,1909 maybe_inst: ?Air.Inst.Index,
1901) InnerError!MCValue {1910) InnerError!MCValue {
1902 const mod = self.bin_file.comp.module.?;1911 const pt = self.pt;
1912 const mod = pt.zcu;
1903 switch (lhs_ty.zigTypeTag(mod)) {1913 switch (lhs_ty.zigTypeTag(mod)) {
1904 .Float => return self.fail("TODO binary operations on floats", .{}),1914 .Float => return self.fail("TODO binary operations on floats", .{}),
1905 .Vector => return self.fail("TODO binary operations on vectors", .{}),1915 .Vector => return self.fail("TODO binary operations on vectors", .{}),
...@@ -1960,7 +1970,8 @@ fn mul(...@@ -1960,7 +1970,8 @@ fn mul(
1960 rhs_ty: Type,1970 rhs_ty: Type,
1961 maybe_inst: ?Air.Inst.Index,1971 maybe_inst: ?Air.Inst.Index,
1962) InnerError!MCValue {1972) InnerError!MCValue {
1963 const mod = self.bin_file.comp.module.?;1973 const pt = self.pt;
1974 const mod = pt.zcu;
1964 switch (lhs_ty.zigTypeTag(mod)) {1975 switch (lhs_ty.zigTypeTag(mod)) {
1965 .Vector => return self.fail("TODO binary operations on vectors", .{}),1976 .Vector => return self.fail("TODO binary operations on vectors", .{}),
1966 .Int => {1977 .Int => {
...@@ -1992,7 +2003,8 @@ fn divFloat(...@@ -1992,7 +2003,8 @@ fn divFloat(
1992 _ = rhs_ty;2003 _ = rhs_ty;
1993 _ = maybe_inst;2004 _ = maybe_inst;
19942005
1995 const mod = self.bin_file.comp.module.?;2006 const pt = self.pt;
2007 const mod = pt.zcu;
1996 switch (lhs_ty.zigTypeTag(mod)) {2008 switch (lhs_ty.zigTypeTag(mod)) {
1997 .Float => return self.fail("TODO div_float", .{}),2009 .Float => return self.fail("TODO div_float", .{}),
1998 .Vector => return self.fail("TODO div_float on vectors", .{}),2010 .Vector => return self.fail("TODO div_float on vectors", .{}),
...@@ -2008,7 +2020,8 @@ fn divTrunc(...@@ -2008,7 +2020,8 @@ fn divTrunc(
2008 rhs_ty: Type,2020 rhs_ty: Type,
2009 maybe_inst: ?Air.Inst.Index,2021 maybe_inst: ?Air.Inst.Index,
2010) InnerError!MCValue {2022) InnerError!MCValue {
2011 const mod = self.bin_file.comp.module.?;2023 const pt = self.pt;
2024 const mod = pt.zcu;
2012 switch (lhs_ty.zigTypeTag(mod)) {2025 switch (lhs_ty.zigTypeTag(mod)) {
2013 .Float => return self.fail("TODO div on floats", .{}),2026 .Float => return self.fail("TODO div on floats", .{}),
2014 .Vector => return self.fail("TODO div on vectors", .{}),2027 .Vector => return self.fail("TODO div on vectors", .{}),
...@@ -2042,7 +2055,8 @@ fn divFloor(...@@ -2042,7 +2055,8 @@ fn divFloor(
2042 rhs_ty: Type,2055 rhs_ty: Type,
2043 maybe_inst: ?Air.Inst.Index,2056 maybe_inst: ?Air.Inst.Index,
2044) InnerError!MCValue {2057) InnerError!MCValue {
2045 const mod = self.bin_file.comp.module.?;2058 const pt = self.pt;
2059 const mod = pt.zcu;
2046 switch (lhs_ty.zigTypeTag(mod)) {2060 switch (lhs_ty.zigTypeTag(mod)) {
2047 .Float => return self.fail("TODO div on floats", .{}),2061 .Float => return self.fail("TODO div on floats", .{}),
2048 .Vector => return self.fail("TODO div on vectors", .{}),2062 .Vector => return self.fail("TODO div on vectors", .{}),
...@@ -2075,7 +2089,8 @@ fn divExact(...@@ -2075,7 +2089,8 @@ fn divExact(
2075 rhs_ty: Type,2089 rhs_ty: Type,
2076 maybe_inst: ?Air.Inst.Index,2090 maybe_inst: ?Air.Inst.Index,
2077) InnerError!MCValue {2091) InnerError!MCValue {
2078 const mod = self.bin_file.comp.module.?;2092 const pt = self.pt;
2093 const mod = pt.zcu;
2079 switch (lhs_ty.zigTypeTag(mod)) {2094 switch (lhs_ty.zigTypeTag(mod)) {
2080 .Float => return self.fail("TODO div on floats", .{}),2095 .Float => return self.fail("TODO div on floats", .{}),
2081 .Vector => return self.fail("TODO div on vectors", .{}),2096 .Vector => return self.fail("TODO div on vectors", .{}),
...@@ -2111,7 +2126,8 @@ fn rem(...@@ -2111,7 +2126,8 @@ fn rem(
2111) InnerError!MCValue {2126) InnerError!MCValue {
2112 _ = maybe_inst;2127 _ = maybe_inst;
21132128
2114 const mod = self.bin_file.comp.module.?;2129 const pt = self.pt;
2130 const mod = pt.zcu;
2115 switch (lhs_ty.zigTypeTag(mod)) {2131 switch (lhs_ty.zigTypeTag(mod)) {
2116 .Float => return self.fail("TODO rem/mod on floats", .{}),2132 .Float => return self.fail("TODO rem/mod on floats", .{}),
2117 .Vector => return self.fail("TODO rem/mod on vectors", .{}),2133 .Vector => return self.fail("TODO rem/mod on vectors", .{}),
...@@ -2182,7 +2198,8 @@ fn modulo(...@@ -2182,7 +2198,8 @@ fn modulo(
2182 _ = rhs_ty;2198 _ = rhs_ty;
2183 _ = maybe_inst;2199 _ = maybe_inst;
21842200
2185 const mod = self.bin_file.comp.module.?;2201 const pt = self.pt;
2202 const mod = pt.zcu;
2186 switch (lhs_ty.zigTypeTag(mod)) {2203 switch (lhs_ty.zigTypeTag(mod)) {
2187 .Float => return self.fail("TODO mod on floats", .{}),2204 .Float => return self.fail("TODO mod on floats", .{}),
2188 .Vector => return self.fail("TODO mod on vectors", .{}),2205 .Vector => return self.fail("TODO mod on vectors", .{}),
...@@ -2200,7 +2217,8 @@ fn wrappingArithmetic(...@@ -2200,7 +2217,8 @@ fn wrappingArithmetic(
2200 rhs_ty: Type,2217 rhs_ty: Type,
2201 maybe_inst: ?Air.Inst.Index,2218 maybe_inst: ?Air.Inst.Index,
2202) InnerError!MCValue {2219) InnerError!MCValue {
2203 const mod = self.bin_file.comp.module.?;2220 const pt = self.pt;
2221 const mod = pt.zcu;
2204 switch (lhs_ty.zigTypeTag(mod)) {2222 switch (lhs_ty.zigTypeTag(mod)) {
2205 .Vector => return self.fail("TODO binary operations on vectors", .{}),2223 .Vector => return self.fail("TODO binary operations on vectors", .{}),
2206 .Int => {2224 .Int => {
...@@ -2235,7 +2253,8 @@ fn bitwise(...@@ -2235,7 +2253,8 @@ fn bitwise(
2235 rhs_ty: Type,2253 rhs_ty: Type,
2236 maybe_inst: ?Air.Inst.Index,2254 maybe_inst: ?Air.Inst.Index,
2237) InnerError!MCValue {2255) InnerError!MCValue {
2238 const mod = self.bin_file.comp.module.?;2256 const pt = self.pt;
2257 const mod = pt.zcu;
2239 switch (lhs_ty.zigTypeTag(mod)) {2258 switch (lhs_ty.zigTypeTag(mod)) {
2240 .Vector => return self.fail("TODO binary operations on vectors", .{}),2259 .Vector => return self.fail("TODO binary operations on vectors", .{}),
2241 .Int => {2260 .Int => {
...@@ -2270,7 +2289,8 @@ fn shiftExact(...@@ -2270,7 +2289,8 @@ fn shiftExact(
2270) InnerError!MCValue {2289) InnerError!MCValue {
2271 _ = rhs_ty;2290 _ = rhs_ty;
22722291
2273 const mod = self.bin_file.comp.module.?;2292 const pt = self.pt;
2293 const mod = pt.zcu;
2274 switch (lhs_ty.zigTypeTag(mod)) {2294 switch (lhs_ty.zigTypeTag(mod)) {
2275 .Vector => return self.fail("TODO binary operations on vectors", .{}),2295 .Vector => return self.fail("TODO binary operations on vectors", .{}),
2276 .Int => {2296 .Int => {
...@@ -2320,7 +2340,8 @@ fn shiftNormal(...@@ -2320,7 +2340,8 @@ fn shiftNormal(
2320 rhs_ty: Type,2340 rhs_ty: Type,
2321 maybe_inst: ?Air.Inst.Index,2341 maybe_inst: ?Air.Inst.Index,
2322) InnerError!MCValue {2342) InnerError!MCValue {
2323 const mod = self.bin_file.comp.module.?;2343 const pt = self.pt;
2344 const mod = pt.zcu;
2324 switch (lhs_ty.zigTypeTag(mod)) {2345 switch (lhs_ty.zigTypeTag(mod)) {
2325 .Vector => return self.fail("TODO binary operations on vectors", .{}),2346 .Vector => return self.fail("TODO binary operations on vectors", .{}),
2326 .Int => {2347 .Int => {
...@@ -2360,7 +2381,8 @@ fn booleanOp(...@@ -2360,7 +2381,8 @@ fn booleanOp(
2360 rhs_ty: Type,2381 rhs_ty: Type,
2361 maybe_inst: ?Air.Inst.Index,2382 maybe_inst: ?Air.Inst.Index,
2362) InnerError!MCValue {2383) InnerError!MCValue {
2363 const mod = self.bin_file.comp.module.?;2384 const pt = self.pt;
2385 const mod = pt.zcu;
2364 switch (lhs_ty.zigTypeTag(mod)) {2386 switch (lhs_ty.zigTypeTag(mod)) {
2365 .Bool => {2387 .Bool => {
2366 assert((try lhs_bind.resolveToImmediate(self)) == null); // should have been handled by Sema2388 assert((try lhs_bind.resolveToImmediate(self)) == null); // should have been handled by Sema
...@@ -2387,7 +2409,8 @@ fn ptrArithmetic(...@@ -2387,7 +2409,8 @@ fn ptrArithmetic(
2387 rhs_ty: Type,2409 rhs_ty: Type,
2388 maybe_inst: ?Air.Inst.Index,2410 maybe_inst: ?Air.Inst.Index,
2389) InnerError!MCValue {2411) InnerError!MCValue {
2390 const mod = self.bin_file.comp.module.?;2412 const pt = self.pt;
2413 const mod = pt.zcu;
2391 switch (lhs_ty.zigTypeTag(mod)) {2414 switch (lhs_ty.zigTypeTag(mod)) {
2392 .Pointer => {2415 .Pointer => {
2393 assert(rhs_ty.eql(Type.usize, mod));2416 assert(rhs_ty.eql(Type.usize, mod));
...@@ -2397,7 +2420,7 @@ fn ptrArithmetic(...@@ -2397,7 +2420,7 @@ fn ptrArithmetic(
2397 .One => ptr_ty.childType(mod).childType(mod), // ptr to array, so get array element type2420 .One => ptr_ty.childType(mod).childType(mod), // ptr to array, so get array element type
2398 else => ptr_ty.childType(mod),2421 else => ptr_ty.childType(mod),
2399 };2422 };
2400 const elem_size = elem_ty.abiSize(mod);2423 const elem_size = elem_ty.abiSize(pt);
24012424
2402 const base_tag: Air.Inst.Tag = switch (tag) {2425 const base_tag: Air.Inst.Tag = switch (tag) {
2403 .ptr_add => .add,2426 .ptr_add => .add,
...@@ -2510,7 +2533,8 @@ fn airOverflow(self: *Self, inst: Air.Inst.Index) !void {...@@ -2510,7 +2533,8 @@ fn airOverflow(self: *Self, inst: Air.Inst.Index) !void {
2510 const tag = self.air.instructions.items(.tag)[@intFromEnum(inst)];2533 const tag = self.air.instructions.items(.tag)[@intFromEnum(inst)];
2511 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;2534 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
2512 const extra = self.air.extraData(Air.Bin, ty_pl.payload).data;2535 const extra = self.air.extraData(Air.Bin, ty_pl.payload).data;
2513 const mod = self.bin_file.comp.module.?;2536 const pt = self.pt;
2537 const mod = pt.zcu;
2514 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {2538 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
2515 const lhs_bind: ReadArg.Bind = .{ .inst = extra.lhs };2539 const lhs_bind: ReadArg.Bind = .{ .inst = extra.lhs };
2516 const rhs_bind: ReadArg.Bind = .{ .inst = extra.rhs };2540 const rhs_bind: ReadArg.Bind = .{ .inst = extra.rhs };
...@@ -2518,9 +2542,9 @@ fn airOverflow(self: *Self, inst: Air.Inst.Index) !void {...@@ -2518,9 +2542,9 @@ fn airOverflow(self: *Self, inst: Air.Inst.Index) !void {
2518 const rhs_ty = self.typeOf(extra.rhs);2542 const rhs_ty = self.typeOf(extra.rhs);
25192543
2520 const tuple_ty = self.typeOfIndex(inst);2544 const tuple_ty = self.typeOfIndex(inst);
2521 const tuple_size = @as(u32, @intCast(tuple_ty.abiSize(mod)));2545 const tuple_size = @as(u32, @intCast(tuple_ty.abiSize(pt)));
2522 const tuple_align = tuple_ty.abiAlignment(mod);2546 const tuple_align = tuple_ty.abiAlignment(pt);
2523 const overflow_bit_offset = @as(u32, @intCast(tuple_ty.structFieldOffset(1, mod)));2547 const overflow_bit_offset = @as(u32, @intCast(tuple_ty.structFieldOffset(1, pt)));
25242548
2525 switch (lhs_ty.zigTypeTag(mod)) {2549 switch (lhs_ty.zigTypeTag(mod)) {
2526 .Vector => return self.fail("TODO implement add_with_overflow/sub_with_overflow for vectors", .{}),2550 .Vector => return self.fail("TODO implement add_with_overflow/sub_with_overflow for vectors", .{}),
...@@ -2638,7 +2662,8 @@ fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) !void {...@@ -2638,7 +2662,8 @@ fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) !void {
2638 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;2662 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
2639 const extra = self.air.extraData(Air.Bin, ty_pl.payload).data;2663 const extra = self.air.extraData(Air.Bin, ty_pl.payload).data;
2640 if (self.liveness.isUnused(inst)) return self.finishAir(inst, .dead, .{ extra.lhs, extra.rhs, .none });2664 if (self.liveness.isUnused(inst)) return self.finishAir(inst, .dead, .{ extra.lhs, extra.rhs, .none });
2641 const mod = self.bin_file.comp.module.?;2665 const pt = self.pt;
2666 const mod = pt.zcu;
2642 const result: MCValue = result: {2667 const result: MCValue = result: {
2643 const lhs_bind: ReadArg.Bind = .{ .inst = extra.lhs };2668 const lhs_bind: ReadArg.Bind = .{ .inst = extra.lhs };
2644 const rhs_bind: ReadArg.Bind = .{ .inst = extra.rhs };2669 const rhs_bind: ReadArg.Bind = .{ .inst = extra.rhs };
...@@ -2646,9 +2671,9 @@ fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) !void {...@@ -2646,9 +2671,9 @@ fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) !void {
2646 const rhs_ty = self.typeOf(extra.rhs);2671 const rhs_ty = self.typeOf(extra.rhs);
26472672
2648 const tuple_ty = self.typeOfIndex(inst);2673 const tuple_ty = self.typeOfIndex(inst);
2649 const tuple_size = @as(u32, @intCast(tuple_ty.abiSize(mod)));2674 const tuple_size = @as(u32, @intCast(tuple_ty.abiSize(pt)));
2650 const tuple_align = tuple_ty.abiAlignment(mod);2675 const tuple_align = tuple_ty.abiAlignment(pt);
2651 const overflow_bit_offset = @as(u32, @intCast(tuple_ty.structFieldOffset(1, mod)));2676 const overflow_bit_offset = @as(u32, @intCast(tuple_ty.structFieldOffset(1, pt)));
26522677
2653 switch (lhs_ty.zigTypeTag(mod)) {2678 switch (lhs_ty.zigTypeTag(mod)) {
2654 .Vector => return self.fail("TODO implement mul_with_overflow for vectors", .{}),2679 .Vector => return self.fail("TODO implement mul_with_overflow for vectors", .{}),
...@@ -2862,7 +2887,8 @@ fn airShlWithOverflow(self: *Self, inst: Air.Inst.Index) !void {...@@ -2862,7 +2887,8 @@ fn airShlWithOverflow(self: *Self, inst: Air.Inst.Index) !void {
2862 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;2887 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
2863 const extra = self.air.extraData(Air.Bin, ty_pl.payload).data;2888 const extra = self.air.extraData(Air.Bin, ty_pl.payload).data;
2864 if (self.liveness.isUnused(inst)) return self.finishAir(inst, .dead, .{ extra.lhs, extra.rhs, .none });2889 if (self.liveness.isUnused(inst)) return self.finishAir(inst, .dead, .{ extra.lhs, extra.rhs, .none });
2865 const mod = self.bin_file.comp.module.?;2890 const pt = self.pt;
2891 const mod = pt.zcu;
2866 const result: MCValue = result: {2892 const result: MCValue = result: {
2867 const lhs_bind: ReadArg.Bind = .{ .inst = extra.lhs };2893 const lhs_bind: ReadArg.Bind = .{ .inst = extra.lhs };
2868 const rhs_bind: ReadArg.Bind = .{ .inst = extra.rhs };2894 const rhs_bind: ReadArg.Bind = .{ .inst = extra.rhs };
...@@ -2870,9 +2896,9 @@ fn airShlWithOverflow(self: *Self, inst: Air.Inst.Index) !void {...@@ -2870,9 +2896,9 @@ fn airShlWithOverflow(self: *Self, inst: Air.Inst.Index) !void {
2870 const rhs_ty = self.typeOf(extra.rhs);2896 const rhs_ty = self.typeOf(extra.rhs);
28712897
2872 const tuple_ty = self.typeOfIndex(inst);2898 const tuple_ty = self.typeOfIndex(inst);
2873 const tuple_size = @as(u32, @intCast(tuple_ty.abiSize(mod)));2899 const tuple_size = @as(u32, @intCast(tuple_ty.abiSize(pt)));
2874 const tuple_align = tuple_ty.abiAlignment(mod);2900 const tuple_align = tuple_ty.abiAlignment(pt);
2875 const overflow_bit_offset = @as(u32, @intCast(tuple_ty.structFieldOffset(1, mod)));2901 const overflow_bit_offset = @as(u32, @intCast(tuple_ty.structFieldOffset(1, pt)));
28762902
2877 switch (lhs_ty.zigTypeTag(mod)) {2903 switch (lhs_ty.zigTypeTag(mod)) {
2878 .Vector => return self.fail("TODO implement shl_with_overflow for vectors", .{}),2904 .Vector => return self.fail("TODO implement shl_with_overflow for vectors", .{}),
...@@ -3010,9 +3036,10 @@ fn airOptionalPayload(self: *Self, inst: Air.Inst.Index) !void {...@@ -3010,9 +3036,10 @@ fn airOptionalPayload(self: *Self, inst: Air.Inst.Index) !void {
3010}3036}
30113037
3012fn optionalPayload(self: *Self, inst: Air.Inst.Index, mcv: MCValue, optional_ty: Type) !MCValue {3038fn optionalPayload(self: *Self, inst: Air.Inst.Index, mcv: MCValue, optional_ty: Type) !MCValue {
3013 const mod = self.bin_file.comp.module.?;3039 const pt = self.pt;
3040 const mod = pt.zcu;
3014 const payload_ty = optional_ty.optionalChild(mod);3041 const payload_ty = optional_ty.optionalChild(mod);
3015 if (!payload_ty.hasRuntimeBits(mod)) return MCValue.none;3042 if (!payload_ty.hasRuntimeBits(pt)) return MCValue.none;
3016 if (optional_ty.isPtrLikeOptional(mod)) {3043 if (optional_ty.isPtrLikeOptional(mod)) {
3017 // TODO should we reuse the operand here?3044 // TODO should we reuse the operand here?
3018 const raw_reg = try self.register_manager.allocReg(inst, gp);3045 const raw_reg = try self.register_manager.allocReg(inst, gp);
...@@ -3054,17 +3081,18 @@ fn errUnionErr(...@@ -3054,17 +3081,18 @@ fn errUnionErr(
3054 error_union_ty: Type,3081 error_union_ty: Type,
3055 maybe_inst: ?Air.Inst.Index,3082 maybe_inst: ?Air.Inst.Index,
3056) !MCValue {3083) !MCValue {
3057 const mod = self.bin_file.comp.module.?;3084 const pt = self.pt;
3085 const mod = pt.zcu;
3058 const err_ty = error_union_ty.errorUnionSet(mod);3086 const err_ty = error_union_ty.errorUnionSet(mod);
3059 const payload_ty = error_union_ty.errorUnionPayload(mod);3087 const payload_ty = error_union_ty.errorUnionPayload(mod);
3060 if (err_ty.errorSetIsEmpty(mod)) {3088 if (err_ty.errorSetIsEmpty(mod)) {
3061 return MCValue{ .immediate = 0 };3089 return MCValue{ .immediate = 0 };
3062 }3090 }
3063 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) {3091 if (!payload_ty.hasRuntimeBitsIgnoreComptime(pt)) {
3064 return try error_union_bind.resolveToMcv(self);3092 return try error_union_bind.resolveToMcv(self);
3065 }3093 }
30663094
3067 const err_offset = @as(u32, @intCast(errUnionErrorOffset(payload_ty, mod)));3095 const err_offset: u32 = @intCast(errUnionErrorOffset(payload_ty, pt));
3068 switch (try error_union_bind.resolveToMcv(self)) {3096 switch (try error_union_bind.resolveToMcv(self)) {
3069 .register => {3097 .register => {
3070 var operand_reg: Register = undefined;3098 var operand_reg: Register = undefined;
...@@ -3086,7 +3114,7 @@ fn errUnionErr(...@@ -3086,7 +3114,7 @@ fn errUnionErr(
3086 );3114 );
30873115
3088 const err_bit_offset = err_offset * 8;3116 const err_bit_offset = err_offset * 8;
3089 const err_bit_size = @as(u32, @intCast(err_ty.abiSize(mod))) * 8;3117 const err_bit_size = @as(u32, @intCast(err_ty.abiSize(pt))) * 8;
30903118
3091 _ = try self.addInst(.{3119 _ = try self.addInst(.{
3092 .tag = .ubfx, // errors are unsigned integers3120 .tag = .ubfx, // errors are unsigned integers
...@@ -3134,17 +3162,18 @@ fn errUnionPayload(...@@ -3134,17 +3162,18 @@ fn errUnionPayload(
3134 error_union_ty: Type,3162 error_union_ty: Type,
3135 maybe_inst: ?Air.Inst.Index,3163 maybe_inst: ?Air.Inst.Index,
3136) !MCValue {3164) !MCValue {
3137 const mod = self.bin_file.comp.module.?;3165 const pt = self.pt;
3166 const mod = pt.zcu;
3138 const err_ty = error_union_ty.errorUnionSet(mod);3167 const err_ty = error_union_ty.errorUnionSet(mod);
3139 const payload_ty = error_union_ty.errorUnionPayload(mod);3168 const payload_ty = error_union_ty.errorUnionPayload(mod);
3140 if (err_ty.errorSetIsEmpty(mod)) {3169 if (err_ty.errorSetIsEmpty(mod)) {
3141 return try error_union_bind.resolveToMcv(self);3170 return try error_union_bind.resolveToMcv(self);
3142 }3171 }
3143 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) {3172 if (!payload_ty.hasRuntimeBitsIgnoreComptime(pt)) {
3144 return MCValue.none;3173 return MCValue.none;
3145 }3174 }
31463175
3147 const payload_offset = @as(u32, @intCast(errUnionPayloadOffset(payload_ty, mod)));3176 const payload_offset = @as(u32, @intCast(errUnionPayloadOffset(payload_ty, pt)));
3148 switch (try error_union_bind.resolveToMcv(self)) {3177 switch (try error_union_bind.resolveToMcv(self)) {
3149 .register => {3178 .register => {
3150 var operand_reg: Register = undefined;3179 var operand_reg: Register = undefined;
...@@ -3166,7 +3195,7 @@ fn errUnionPayload(...@@ -3166,7 +3195,7 @@ fn errUnionPayload(
3166 );3195 );
31673196
3168 const payload_bit_offset = payload_offset * 8;3197 const payload_bit_offset = payload_offset * 8;
3169 const payload_bit_size = @as(u32, @intCast(payload_ty.abiSize(mod))) * 8;3198 const payload_bit_size = @as(u32, @intCast(payload_ty.abiSize(pt))) * 8;
31703199
3171 _ = try self.addInst(.{3200 _ = try self.addInst(.{
3172 .tag = if (payload_ty.isSignedInt(mod)) Mir.Inst.Tag.sbfx else .ubfx,3201 .tag = if (payload_ty.isSignedInt(mod)) Mir.Inst.Tag.sbfx else .ubfx,
...@@ -3246,7 +3275,8 @@ fn airSaveErrReturnTraceIndex(self: *Self, inst: Air.Inst.Index) !void {...@@ -3246,7 +3275,8 @@ fn airSaveErrReturnTraceIndex(self: *Self, inst: Air.Inst.Index) !void {
3246}3275}
32473276
3248fn airWrapOptional(self: *Self, inst: Air.Inst.Index) !void {3277fn airWrapOptional(self: *Self, inst: Air.Inst.Index) !void {
3249 const mod = self.bin_file.comp.module.?;3278 const pt = self.pt;
3279 const mod = pt.zcu;
3250 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;3280 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
32513281
3252 if (self.liveness.isUnused(inst)) {3282 if (self.liveness.isUnused(inst)) {
...@@ -3255,7 +3285,7 @@ fn airWrapOptional(self: *Self, inst: Air.Inst.Index) !void {...@@ -3255,7 +3285,7 @@ fn airWrapOptional(self: *Self, inst: Air.Inst.Index) !void {
32553285
3256 const result: MCValue = result: {3286 const result: MCValue = result: {
3257 const payload_ty = self.typeOf(ty_op.operand);3287 const payload_ty = self.typeOf(ty_op.operand);
3258 if (!payload_ty.hasRuntimeBits(mod)) {3288 if (!payload_ty.hasRuntimeBits(pt)) {
3259 break :result MCValue{ .immediate = 1 };3289 break :result MCValue{ .immediate = 1 };
3260 }3290 }
32613291
...@@ -3275,9 +3305,9 @@ fn airWrapOptional(self: *Self, inst: Air.Inst.Index) !void {...@@ -3275,9 +3305,9 @@ fn airWrapOptional(self: *Self, inst: Air.Inst.Index) !void {
3275 break :result MCValue{ .register = reg };3305 break :result MCValue{ .register = reg };
3276 }3306 }
32773307
3278 const optional_abi_size: u32 = @intCast(optional_ty.abiSize(mod));3308 const optional_abi_size: u32 = @intCast(optional_ty.abiSize(pt));
3279 const optional_abi_align = optional_ty.abiAlignment(mod);3309 const optional_abi_align = optional_ty.abiAlignment(pt);
3280 const offset: u32 = @intCast(payload_ty.abiSize(mod));3310 const offset: u32 = @intCast(payload_ty.abiSize(pt));
32813311
3282 const stack_offset = try self.allocMem(optional_abi_size, optional_abi_align, inst);3312 const stack_offset = try self.allocMem(optional_abi_size, optional_abi_align, inst);
3283 try self.genSetStack(payload_ty, stack_offset, operand);3313 try self.genSetStack(payload_ty, stack_offset, operand);
...@@ -3291,20 +3321,21 @@ fn airWrapOptional(self: *Self, inst: Air.Inst.Index) !void {...@@ -3291,20 +3321,21 @@ fn airWrapOptional(self: *Self, inst: Air.Inst.Index) !void {
32913321
3292/// T to E!T3322/// T to E!T
3293fn airWrapErrUnionPayload(self: *Self, inst: Air.Inst.Index) !void {3323fn airWrapErrUnionPayload(self: *Self, inst: Air.Inst.Index) !void {
3294 const mod = self.bin_file.comp.module.?;3324 const pt = self.pt;
3325 const mod = pt.zcu;
3295 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;3326 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
3296 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {3327 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
3297 const error_union_ty = ty_op.ty.toType();3328 const error_union_ty = ty_op.ty.toType();
3298 const error_ty = error_union_ty.errorUnionSet(mod);3329 const error_ty = error_union_ty.errorUnionSet(mod);
3299 const payload_ty = error_union_ty.errorUnionPayload(mod);3330 const payload_ty = error_union_ty.errorUnionPayload(mod);
3300 const operand = try self.resolveInst(ty_op.operand);3331 const operand = try self.resolveInst(ty_op.operand);
3301 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) break :result operand;3332 if (!payload_ty.hasRuntimeBitsIgnoreComptime(pt)) break :result operand;
33023333
3303 const abi_size = @as(u32, @intCast(error_union_ty.abiSize(mod)));3334 const abi_size = @as(u32, @intCast(error_union_ty.abiSize(pt)));
3304 const abi_align = error_union_ty.abiAlignment(mod);3335 const abi_align = error_union_ty.abiAlignment(pt);
3305 const stack_offset = try self.allocMem(abi_size, abi_align, inst);3336 const stack_offset = try self.allocMem(abi_size, abi_align, inst);
3306 const payload_off = errUnionPayloadOffset(payload_ty, mod);3337 const payload_off = errUnionPayloadOffset(payload_ty, pt);
3307 const err_off = errUnionErrorOffset(payload_ty, mod);3338 const err_off = errUnionErrorOffset(payload_ty, pt);
3308 try self.genSetStack(payload_ty, stack_offset - @as(u32, @intCast(payload_off)), operand);3339 try self.genSetStack(payload_ty, stack_offset - @as(u32, @intCast(payload_off)), operand);
3309 try self.genSetStack(error_ty, stack_offset - @as(u32, @intCast(err_off)), .{ .immediate = 0 });3340 try self.genSetStack(error_ty, stack_offset - @as(u32, @intCast(err_off)), .{ .immediate = 0 });
33103341
...@@ -3317,18 +3348,19 @@ fn airWrapErrUnionPayload(self: *Self, inst: Air.Inst.Index) !void {...@@ -3317,18 +3348,19 @@ fn airWrapErrUnionPayload(self: *Self, inst: Air.Inst.Index) !void {
3317fn airWrapErrUnionErr(self: *Self, inst: Air.Inst.Index) !void {3348fn airWrapErrUnionErr(self: *Self, inst: Air.Inst.Index) !void {
3318 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;3349 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
3319 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {3350 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
3320 const mod = self.bin_file.comp.module.?;3351 const pt = self.pt;
3352 const mod = pt.zcu;
3321 const error_union_ty = ty_op.ty.toType();3353 const error_union_ty = ty_op.ty.toType();
3322 const error_ty = error_union_ty.errorUnionSet(mod);3354 const error_ty = error_union_ty.errorUnionSet(mod);
3323 const payload_ty = error_union_ty.errorUnionPayload(mod);3355 const payload_ty = error_union_ty.errorUnionPayload(mod);
3324 const operand = try self.resolveInst(ty_op.operand);3356 const operand = try self.resolveInst(ty_op.operand);
3325 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) break :result operand;3357 if (!payload_ty.hasRuntimeBitsIgnoreComptime(pt)) break :result operand;
33263358
3327 const abi_size = @as(u32, @intCast(error_union_ty.abiSize(mod)));3359 const abi_size = @as(u32, @intCast(error_union_ty.abiSize(pt)));
3328 const abi_align = error_union_ty.abiAlignment(mod);3360 const abi_align = error_union_ty.abiAlignment(pt);
3329 const stack_offset = try self.allocMem(abi_size, abi_align, inst);3361 const stack_offset = try self.allocMem(abi_size, abi_align, inst);
3330 const payload_off = errUnionPayloadOffset(payload_ty, mod);3362 const payload_off = errUnionPayloadOffset(payload_ty, pt);
3331 const err_off = errUnionErrorOffset(payload_ty, mod);3363 const err_off = errUnionErrorOffset(payload_ty, pt);
3332 try self.genSetStack(error_ty, stack_offset - @as(u32, @intCast(err_off)), operand);3364 try self.genSetStack(error_ty, stack_offset - @as(u32, @intCast(err_off)), operand);
3333 try self.genSetStack(payload_ty, stack_offset - @as(u32, @intCast(payload_off)), .undef);3365 try self.genSetStack(payload_ty, stack_offset - @as(u32, @intCast(payload_off)), .undef);
33343366
...@@ -3420,7 +3452,8 @@ fn airPtrSlicePtrPtr(self: *Self, inst: Air.Inst.Index) !void {...@@ -3420,7 +3452,8 @@ fn airPtrSlicePtrPtr(self: *Self, inst: Air.Inst.Index) !void {
3420}3452}
34213453
3422fn airSliceElemVal(self: *Self, inst: Air.Inst.Index) !void {3454fn airSliceElemVal(self: *Self, inst: Air.Inst.Index) !void {
3423 const mod = self.bin_file.comp.module.?;3455 const pt = self.pt;
3456 const mod = pt.zcu;
3424 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;3457 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
3425 const slice_ty = self.typeOf(bin_op.lhs);3458 const slice_ty = self.typeOf(bin_op.lhs);
3426 const result: MCValue = if (!slice_ty.isVolatilePtr(mod) and self.liveness.isUnused(inst)) .dead else result: {3459 const result: MCValue = if (!slice_ty.isVolatilePtr(mod) and self.liveness.isUnused(inst)) .dead else result: {
...@@ -3444,9 +3477,10 @@ fn ptrElemVal(...@@ -3444,9 +3477,10 @@ fn ptrElemVal(
3444 ptr_ty: Type,3477 ptr_ty: Type,
3445 maybe_inst: ?Air.Inst.Index,3478 maybe_inst: ?Air.Inst.Index,
3446) !MCValue {3479) !MCValue {
3447 const mod = self.bin_file.comp.module.?;3480 const pt = self.pt;
3481 const mod = pt.zcu;
3448 const elem_ty = ptr_ty.childType(mod);3482 const elem_ty = ptr_ty.childType(mod);
3449 const elem_size = @as(u32, @intCast(elem_ty.abiSize(mod)));3483 const elem_size = @as(u32, @intCast(elem_ty.abiSize(pt)));
34503484
3451 // TODO optimize for elem_sizes of 1, 2, 4, 83485 // TODO optimize for elem_sizes of 1, 2, 4, 8
3452 switch (elem_size) {3486 switch (elem_size) {
...@@ -3486,7 +3520,8 @@ fn airArrayElemVal(self: *Self, inst: Air.Inst.Index) !void {...@@ -3486,7 +3520,8 @@ fn airArrayElemVal(self: *Self, inst: Air.Inst.Index) !void {
3486}3520}
34873521
3488fn airPtrElemVal(self: *Self, inst: Air.Inst.Index) !void {3522fn airPtrElemVal(self: *Self, inst: Air.Inst.Index) !void {
3489 const mod = self.bin_file.comp.module.?;3523 const pt = self.pt;
3524 const mod = pt.zcu;
3490 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;3525 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
3491 const ptr_ty = self.typeOf(bin_op.lhs);3526 const ptr_ty = self.typeOf(bin_op.lhs);
3492 const result: MCValue = if (!ptr_ty.isVolatilePtr(mod) and self.liveness.isUnused(inst)) .dead else result: {3527 const result: MCValue = if (!ptr_ty.isVolatilePtr(mod) and self.liveness.isUnused(inst)) .dead else result: {
...@@ -3609,9 +3644,10 @@ fn reuseOperand(...@@ -3609,9 +3644,10 @@ fn reuseOperand(
3609}3644}
36103645
3611fn load(self: *Self, dst_mcv: MCValue, ptr: MCValue, ptr_ty: Type) InnerError!void {3646fn load(self: *Self, dst_mcv: MCValue, ptr: MCValue, ptr_ty: Type) InnerError!void {
3612 const mod = self.bin_file.comp.module.?;3647 const pt = self.pt;
3648 const mod = pt.zcu;
3613 const elem_ty = ptr_ty.childType(mod);3649 const elem_ty = ptr_ty.childType(mod);
3614 const elem_size = elem_ty.abiSize(mod);3650 const elem_size = elem_ty.abiSize(pt);
36153651
3616 switch (ptr) {3652 switch (ptr) {
3617 .none => unreachable,3653 .none => unreachable,
...@@ -3857,12 +3893,13 @@ fn genInlineMemsetCode(...@@ -3857,12 +3893,13 @@ fn genInlineMemsetCode(
3857}3893}
38583894
3859fn airLoad(self: *Self, inst: Air.Inst.Index) !void {3895fn airLoad(self: *Self, inst: Air.Inst.Index) !void {
3860 const mod = self.bin_file.comp.module.?;3896 const pt = self.pt;
3897 const mod = pt.zcu;
3861 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;3898 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
3862 const elem_ty = self.typeOfIndex(inst);3899 const elem_ty = self.typeOfIndex(inst);
3863 const elem_size = elem_ty.abiSize(mod);3900 const elem_size = elem_ty.abiSize(pt);
3864 const result: MCValue = result: {3901 const result: MCValue = result: {
3865 if (!elem_ty.hasRuntimeBits(mod))3902 if (!elem_ty.hasRuntimeBits(pt))
3866 break :result MCValue.none;3903 break :result MCValue.none;
38673904
3868 const ptr = try self.resolveInst(ty_op.operand);3905 const ptr = try self.resolveInst(ty_op.operand);
...@@ -3888,8 +3925,9 @@ fn airLoad(self: *Self, inst: Air.Inst.Index) !void {...@@ -3888,8 +3925,9 @@ fn airLoad(self: *Self, inst: Air.Inst.Index) !void {
3888}3925}
38893926
3890fn genLdrRegister(self: *Self, value_reg: Register, addr_reg: Register, ty: Type) !void {3927fn genLdrRegister(self: *Self, value_reg: Register, addr_reg: Register, ty: Type) !void {
3891 const mod = self.bin_file.comp.module.?;3928 const pt = self.pt;
3892 const abi_size = ty.abiSize(mod);3929 const mod = pt.zcu;
3930 const abi_size = ty.abiSize(pt);
38933931
3894 const tag: Mir.Inst.Tag = switch (abi_size) {3932 const tag: Mir.Inst.Tag = switch (abi_size) {
3895 1 => if (ty.isSignedInt(mod)) Mir.Inst.Tag.ldrsb_immediate else .ldrb_immediate,3933 1 => if (ty.isSignedInt(mod)) Mir.Inst.Tag.ldrsb_immediate else .ldrb_immediate,
...@@ -3911,8 +3949,8 @@ fn genLdrRegister(self: *Self, value_reg: Register, addr_reg: Register, ty: Type...@@ -3911,8 +3949,8 @@ fn genLdrRegister(self: *Self, value_reg: Register, addr_reg: Register, ty: Type
3911}3949}
39123950
3913fn genStrRegister(self: *Self, value_reg: Register, addr_reg: Register, ty: Type) !void {3951fn genStrRegister(self: *Self, value_reg: Register, addr_reg: Register, ty: Type) !void {
3914 const mod = self.bin_file.comp.module.?;3952 const pt = self.pt;
3915 const abi_size = ty.abiSize(mod);3953 const abi_size = ty.abiSize(pt);
39163954
3917 const tag: Mir.Inst.Tag = switch (abi_size) {3955 const tag: Mir.Inst.Tag = switch (abi_size) {
3918 1 => .strb_immediate,3956 1 => .strb_immediate,
...@@ -3933,9 +3971,9 @@ fn genStrRegister(self: *Self, value_reg: Register, addr_reg: Register, ty: Type...@@ -3933,9 +3971,9 @@ fn genStrRegister(self: *Self, value_reg: Register, addr_reg: Register, ty: Type
3933}3971}
39343972
3935fn store(self: *Self, ptr: MCValue, value: MCValue, ptr_ty: Type, value_ty: Type) InnerError!void {3973fn store(self: *Self, ptr: MCValue, value: MCValue, ptr_ty: Type, value_ty: Type) InnerError!void {
3936 const mod = self.bin_file.comp.module.?;3974 const pt = self.pt;
3937 log.debug("store: storing {} to {}", .{ value, ptr });3975 log.debug("store: storing {} to {}", .{ value, ptr });
3938 const abi_size = value_ty.abiSize(mod);3976 const abi_size = value_ty.abiSize(pt);
39393977
3940 switch (ptr) {3978 switch (ptr) {
3941 .none => unreachable,3979 .none => unreachable,
...@@ -4087,11 +4125,12 @@ fn airStructFieldPtrIndex(self: *Self, inst: Air.Inst.Index, index: u8) !void {...@@ -4087,11 +4125,12 @@ fn airStructFieldPtrIndex(self: *Self, inst: Air.Inst.Index, index: u8) !void {
40874125
4088fn structFieldPtr(self: *Self, inst: Air.Inst.Index, operand: Air.Inst.Ref, index: u32) !MCValue {4126fn structFieldPtr(self: *Self, inst: Air.Inst.Index, operand: Air.Inst.Ref, index: u32) !MCValue {
4089 return if (self.liveness.isUnused(inst)) .dead else result: {4127 return if (self.liveness.isUnused(inst)) .dead else result: {
4090 const mod = self.bin_file.comp.module.?;4128 const pt = self.pt;
4129 const mod = pt.zcu;
4091 const mcv = try self.resolveInst(operand);4130 const mcv = try self.resolveInst(operand);
4092 const ptr_ty = self.typeOf(operand);4131 const ptr_ty = self.typeOf(operand);
4093 const struct_ty = ptr_ty.childType(mod);4132 const struct_ty = ptr_ty.childType(mod);
4094 const struct_field_offset = @as(u32, @intCast(struct_ty.structFieldOffset(index, mod)));4133 const struct_field_offset = @as(u32, @intCast(struct_ty.structFieldOffset(index, pt)));
4095 switch (mcv) {4134 switch (mcv) {
4096 .ptr_stack_offset => |off| {4135 .ptr_stack_offset => |off| {
4097 break :result MCValue{ .ptr_stack_offset = off - struct_field_offset };4136 break :result MCValue{ .ptr_stack_offset = off - struct_field_offset };
...@@ -4112,11 +4151,12 @@ fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void {...@@ -4112,11 +4151,12 @@ fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void {
4112 const operand = extra.struct_operand;4151 const operand = extra.struct_operand;
4113 const index = extra.field_index;4152 const index = extra.field_index;
4114 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {4153 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
4115 const mod = self.bin_file.comp.module.?;4154 const pt = self.pt;
4155 const mod = pt.zcu;
4116 const mcv = try self.resolveInst(operand);4156 const mcv = try self.resolveInst(operand);
4117 const struct_ty = self.typeOf(operand);4157 const struct_ty = self.typeOf(operand);
4118 const struct_field_ty = struct_ty.structFieldType(index, mod);4158 const struct_field_ty = struct_ty.structFieldType(index, mod);
4119 const struct_field_offset = @as(u32, @intCast(struct_ty.structFieldOffset(index, mod)));4159 const struct_field_offset = @as(u32, @intCast(struct_ty.structFieldOffset(index, pt)));
41204160
4121 switch (mcv) {4161 switch (mcv) {
4122 .dead, .unreach => unreachable,4162 .dead, .unreach => unreachable,
...@@ -4162,13 +4202,14 @@ fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void {...@@ -4162,13 +4202,14 @@ fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void {
4162}4202}
41634203
4164fn airFieldParentPtr(self: *Self, inst: Air.Inst.Index) !void {4204fn airFieldParentPtr(self: *Self, inst: Air.Inst.Index) !void {
4165 const mod = self.bin_file.comp.module.?;4205 const pt = self.pt;
4206 const mod = pt.zcu;
4166 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;4207 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
4167 const extra = self.air.extraData(Air.FieldParentPtr, ty_pl.payload).data;4208 const extra = self.air.extraData(Air.FieldParentPtr, ty_pl.payload).data;
4168 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {4209 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
4169 const field_ptr = try self.resolveInst(extra.field_ptr);4210 const field_ptr = try self.resolveInst(extra.field_ptr);
4170 const struct_ty = ty_pl.ty.toType().childType(mod);4211 const struct_ty = ty_pl.ty.toType().childType(mod);
4171 const struct_field_offset = @as(u32, @intCast(struct_ty.structFieldOffset(extra.field_index, mod)));4212 const struct_field_offset = @as(u32, @intCast(struct_ty.structFieldOffset(extra.field_index, pt)));
4172 switch (field_ptr) {4213 switch (field_ptr) {
4173 .ptr_stack_offset => |off| {4214 .ptr_stack_offset => |off| {
4174 break :result MCValue{ .ptr_stack_offset = off + struct_field_offset };4215 break :result MCValue{ .ptr_stack_offset = off + struct_field_offset };
...@@ -4190,7 +4231,8 @@ fn airArg(self: *Self, inst: Air.Inst.Index) !void {...@@ -4190,7 +4231,8 @@ fn airArg(self: *Self, inst: Air.Inst.Index) !void {
4190 while (self.args[arg_index] == .none) arg_index += 1;4231 while (self.args[arg_index] == .none) arg_index += 1;
4191 self.arg_index = arg_index + 1;4232 self.arg_index = arg_index + 1;
41924233
4193 const mod = self.bin_file.comp.module.?;4234 const pt = self.pt;
4235 const mod = pt.zcu;
4194 const ty = self.typeOfIndex(inst);4236 const ty = self.typeOfIndex(inst);
4195 const tag = self.air.instructions.items(.tag)[@intFromEnum(inst)];4237 const tag = self.air.instructions.items(.tag)[@intFromEnum(inst)];
4196 const src_index = self.air.instructions.items(.data)[@intFromEnum(inst)].arg.src_index;4238 const src_index = self.air.instructions.items(.data)[@intFromEnum(inst)].arg.src_index;
...@@ -4245,7 +4287,8 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier...@@ -4245,7 +4287,8 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier
4245 const extra = self.air.extraData(Air.Call, pl_op.payload);4287 const extra = self.air.extraData(Air.Call, pl_op.payload);
4246 const args = @as([]const Air.Inst.Ref, @ptrCast(self.air.extra[extra.end..][0..extra.data.args_len]));4288 const args = @as([]const Air.Inst.Ref, @ptrCast(self.air.extra[extra.end..][0..extra.data.args_len]));
4247 const ty = self.typeOf(callee);4289 const ty = self.typeOf(callee);
4248 const mod = self.bin_file.comp.module.?;4290 const pt = self.pt;
4291 const mod = pt.zcu;
42494292
4250 const fn_ty = switch (ty.zigTypeTag(mod)) {4293 const fn_ty = switch (ty.zigTypeTag(mod)) {
4251 .Fn => ty,4294 .Fn => ty,
...@@ -4269,13 +4312,13 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier...@@ -4269,13 +4312,13 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier
4269 if (info.return_value == .stack_offset) {4312 if (info.return_value == .stack_offset) {
4270 log.debug("airCall: return by reference", .{});4313 log.debug("airCall: return by reference", .{});
4271 const ret_ty = fn_ty.fnReturnType(mod);4314 const ret_ty = fn_ty.fnReturnType(mod);
4272 const ret_abi_size: u32 = @intCast(ret_ty.abiSize(mod));4315 const ret_abi_size: u32 = @intCast(ret_ty.abiSize(pt));
4273 const ret_abi_align = ret_ty.abiAlignment(mod);4316 const ret_abi_align = ret_ty.abiAlignment(pt);
4274 const stack_offset = try self.allocMem(ret_abi_size, ret_abi_align, inst);4317 const stack_offset = try self.allocMem(ret_abi_size, ret_abi_align, inst);
42754318
4276 const ret_ptr_reg = self.registerAlias(.x0, Type.usize);4319 const ret_ptr_reg = self.registerAlias(.x0, Type.usize);
42774320
4278 const ptr_ty = try mod.singleMutPtrType(ret_ty);4321 const ptr_ty = try pt.singleMutPtrType(ret_ty);
4279 try self.register_manager.getReg(ret_ptr_reg, null);4322 try self.register_manager.getReg(ret_ptr_reg, null);
4280 try self.genSetReg(ptr_ty, ret_ptr_reg, .{ .ptr_stack_offset = stack_offset });4323 try self.genSetReg(ptr_ty, ret_ptr_reg, .{ .ptr_stack_offset = stack_offset });
42814324
...@@ -4308,7 +4351,7 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier...@@ -4308,7 +4351,7 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier
43084351
4309 // Due to incremental compilation, how function calls are generated depends4352 // Due to incremental compilation, how function calls are generated depends
4310 // on linking.4353 // on linking.
4311 if (try self.air.value(callee, mod)) |func_value| {4354 if (try self.air.value(callee, pt)) |func_value| {
4312 if (func_value.getFunction(mod)) |func| {4355 if (func_value.getFunction(mod)) |func| {
4313 if (self.bin_file.cast(link.File.Elf)) |elf_file| {4356 if (self.bin_file.cast(link.File.Elf)) |elf_file| {
4314 const sym_index = try elf_file.zigObjectPtr().?.getOrCreateMetadataForDecl(elf_file, func.owner_decl);4357 const sym_index = try elf_file.zigObjectPtr().?.getOrCreateMetadataForDecl(elf_file, func.owner_decl);
...@@ -4421,7 +4464,8 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier...@@ -4421,7 +4464,8 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier
4421}4464}
44224465
4423fn airRet(self: *Self, inst: Air.Inst.Index) !void {4466fn airRet(self: *Self, inst: Air.Inst.Index) !void {
4424 const mod = self.bin_file.comp.module.?;4467 const pt = self.pt;
4468 const mod = pt.zcu;
4425 const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op;4469 const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op;
4426 const operand = try self.resolveInst(un_op);4470 const operand = try self.resolveInst(un_op);
4427 const ret_ty = self.fn_type.fnReturnType(mod);4471 const ret_ty = self.fn_type.fnReturnType(mod);
...@@ -4440,7 +4484,7 @@ fn airRet(self: *Self, inst: Air.Inst.Index) !void {...@@ -4440,7 +4484,7 @@ fn airRet(self: *Self, inst: Air.Inst.Index) !void {
4440 //4484 //
4441 // self.ret_mcv is an address to where this function4485 // self.ret_mcv is an address to where this function
4442 // should store its result into4486 // should store its result into
4443 const ptr_ty = try mod.singleMutPtrType(ret_ty);4487 const ptr_ty = try pt.singleMutPtrType(ret_ty);
4444 try self.store(self.ret_mcv, operand, ptr_ty, ret_ty);4488 try self.store(self.ret_mcv, operand, ptr_ty, ret_ty);
4445 },4489 },
4446 else => unreachable,4490 else => unreachable,
...@@ -4453,7 +4497,8 @@ fn airRet(self: *Self, inst: Air.Inst.Index) !void {...@@ -4453,7 +4497,8 @@ fn airRet(self: *Self, inst: Air.Inst.Index) !void {
4453}4497}
44544498
4455fn airRetLoad(self: *Self, inst: Air.Inst.Index) !void {4499fn airRetLoad(self: *Self, inst: Air.Inst.Index) !void {
4456 const mod = self.bin_file.comp.module.?;4500 const pt = self.pt;
4501 const mod = pt.zcu;
4457 const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op;4502 const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op;
4458 const ptr = try self.resolveInst(un_op);4503 const ptr = try self.resolveInst(un_op);
4459 const ptr_ty = self.typeOf(un_op);4504 const ptr_ty = self.typeOf(un_op);
...@@ -4477,8 +4522,8 @@ fn airRetLoad(self: *Self, inst: Air.Inst.Index) !void {...@@ -4477,8 +4522,8 @@ fn airRetLoad(self: *Self, inst: Air.Inst.Index) !void {
4477 // location.4522 // location.
4478 const op_inst = un_op.toIndex().?;4523 const op_inst = un_op.toIndex().?;
4479 if (self.air.instructions.items(.tag)[@intFromEnum(op_inst)] != .ret_ptr) {4524 if (self.air.instructions.items(.tag)[@intFromEnum(op_inst)] != .ret_ptr) {
4480 const abi_size = @as(u32, @intCast(ret_ty.abiSize(mod)));4525 const abi_size = @as(u32, @intCast(ret_ty.abiSize(pt)));
4481 const abi_align = ret_ty.abiAlignment(mod);4526 const abi_align = ret_ty.abiAlignment(pt);
44824527
4483 const offset = try self.allocMem(abi_size, abi_align, null);4528 const offset = try self.allocMem(abi_size, abi_align, null);
44844529
...@@ -4513,11 +4558,12 @@ fn cmp(...@@ -4513,11 +4558,12 @@ fn cmp(
4513 lhs_ty: Type,4558 lhs_ty: Type,
4514 op: math.CompareOperator,4559 op: math.CompareOperator,
4515) !MCValue {4560) !MCValue {
4516 const mod = self.bin_file.comp.module.?;4561 const pt = self.pt;
4562 const mod = pt.zcu;
4517 const int_ty = switch (lhs_ty.zigTypeTag(mod)) {4563 const int_ty = switch (lhs_ty.zigTypeTag(mod)) {
4518 .Optional => blk: {4564 .Optional => blk: {
4519 const payload_ty = lhs_ty.optionalChild(mod);4565 const payload_ty = lhs_ty.optionalChild(mod);
4520 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) {4566 if (!payload_ty.hasRuntimeBitsIgnoreComptime(pt)) {
4521 break :blk Type.u1;4567 break :blk Type.u1;
4522 } else if (lhs_ty.isPtrLikeOptional(mod)) {4568 } else if (lhs_ty.isPtrLikeOptional(mod)) {
4523 break :blk Type.usize;4569 break :blk Type.usize;
...@@ -4620,7 +4666,8 @@ fn airDbgStmt(self: *Self, inst: Air.Inst.Index) !void {...@@ -4620,7 +4666,8 @@ fn airDbgStmt(self: *Self, inst: Air.Inst.Index) !void {
4620}4666}
46214667
4622fn airDbgInlineBlock(self: *Self, inst: Air.Inst.Index) !void {4668fn airDbgInlineBlock(self: *Self, inst: Air.Inst.Index) !void {
4623 const mod = self.bin_file.comp.module.?;4669 const pt = self.pt;
4670 const mod = pt.zcu;
4624 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;4671 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
4625 const extra = self.air.extraData(Air.DbgInlineBlock, ty_pl.payload);4672 const extra = self.air.extraData(Air.DbgInlineBlock, ty_pl.payload);
4626 const func = mod.funcInfo(extra.data.func);4673 const func = mod.funcInfo(extra.data.func);
...@@ -4825,13 +4872,14 @@ fn airCondBr(self: *Self, inst: Air.Inst.Index) !void {...@@ -4825,13 +4872,14 @@ fn airCondBr(self: *Self, inst: Air.Inst.Index) !void {
4825}4872}
48264873
4827fn isNull(self: *Self, operand_bind: ReadArg.Bind, operand_ty: Type) !MCValue {4874fn isNull(self: *Self, operand_bind: ReadArg.Bind, operand_ty: Type) !MCValue {
4828 const mod = self.bin_file.comp.module.?;4875 const pt = self.pt;
4876 const mod = pt.zcu;
4829 const sentinel: struct { ty: Type, bind: ReadArg.Bind } = if (!operand_ty.isPtrLikeOptional(mod)) blk: {4877 const sentinel: struct { ty: Type, bind: ReadArg.Bind } = if (!operand_ty.isPtrLikeOptional(mod)) blk: {
4830 const payload_ty = operand_ty.optionalChild(mod);4878 const payload_ty = operand_ty.optionalChild(mod);
4831 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod))4879 if (!payload_ty.hasRuntimeBitsIgnoreComptime(pt))
4832 break :blk .{ .ty = operand_ty, .bind = operand_bind };4880 break :blk .{ .ty = operand_ty, .bind = operand_bind };
48334881
4834 const offset = @as(u32, @intCast(payload_ty.abiSize(mod)));4882 const offset = @as(u32, @intCast(payload_ty.abiSize(pt)));
4835 const operand_mcv = try operand_bind.resolveToMcv(self);4883 const operand_mcv = try operand_bind.resolveToMcv(self);
4836 const new_mcv: MCValue = switch (operand_mcv) {4884 const new_mcv: MCValue = switch (operand_mcv) {
4837 .register => |source_reg| new: {4885 .register => |source_reg| new: {
...@@ -4881,7 +4929,8 @@ fn isErr(...@@ -4881,7 +4929,8 @@ fn isErr(
4881 error_union_bind: ReadArg.Bind,4929 error_union_bind: ReadArg.Bind,
4882 error_union_ty: Type,4930 error_union_ty: Type,
4883) !MCValue {4931) !MCValue {
4884 const mod = self.bin_file.comp.module.?;4932 const pt = self.pt;
4933 const mod = pt.zcu;
4885 const error_type = error_union_ty.errorUnionSet(mod);4934 const error_type = error_union_ty.errorUnionSet(mod);
48864935
4887 if (error_type.errorSetIsEmpty(mod)) {4936 if (error_type.errorSetIsEmpty(mod)) {
...@@ -4923,7 +4972,8 @@ fn airIsNull(self: *Self, inst: Air.Inst.Index) !void {...@@ -4923,7 +4972,8 @@ fn airIsNull(self: *Self, inst: Air.Inst.Index) !void {
4923}4972}
49244973
4925fn airIsNullPtr(self: *Self, inst: Air.Inst.Index) !void {4974fn airIsNullPtr(self: *Self, inst: Air.Inst.Index) !void {
4926 const mod = self.bin_file.comp.module.?;4975 const pt = self.pt;
4976 const mod = pt.zcu;
4927 const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op;4977 const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op;
4928 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {4978 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
4929 const operand_ptr = try self.resolveInst(un_op);4979 const operand_ptr = try self.resolveInst(un_op);
...@@ -4950,7 +5000,8 @@ fn airIsNonNull(self: *Self, inst: Air.Inst.Index) !void {...@@ -4950,7 +5000,8 @@ fn airIsNonNull(self: *Self, inst: Air.Inst.Index) !void {
4950}5000}
49515001
4952fn airIsNonNullPtr(self: *Self, inst: Air.Inst.Index) !void {5002fn airIsNonNullPtr(self: *Self, inst: Air.Inst.Index) !void {
4953 const mod = self.bin_file.comp.module.?;5003 const pt = self.pt;
5004 const mod = pt.zcu;
4954 const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op;5005 const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op;
4955 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {5006 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
4956 const operand_ptr = try self.resolveInst(un_op);5007 const operand_ptr = try self.resolveInst(un_op);
...@@ -4977,7 +5028,8 @@ fn airIsErr(self: *Self, inst: Air.Inst.Index) !void {...@@ -4977,7 +5028,8 @@ fn airIsErr(self: *Self, inst: Air.Inst.Index) !void {
4977}5028}
49785029
4979fn airIsErrPtr(self: *Self, inst: Air.Inst.Index) !void {5030fn airIsErrPtr(self: *Self, inst: Air.Inst.Index) !void {
4980 const mod = self.bin_file.comp.module.?;5031 const pt = self.pt;
5032 const mod = pt.zcu;
4981 const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op;5033 const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op;
4982 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {5034 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
4983 const operand_ptr = try self.resolveInst(un_op);5035 const operand_ptr = try self.resolveInst(un_op);
...@@ -5004,7 +5056,8 @@ fn airIsNonErr(self: *Self, inst: Air.Inst.Index) !void {...@@ -5004,7 +5056,8 @@ fn airIsNonErr(self: *Self, inst: Air.Inst.Index) !void {
5004}5056}
50055057
5006fn airIsNonErrPtr(self: *Self, inst: Air.Inst.Index) !void {5058fn airIsNonErrPtr(self: *Self, inst: Air.Inst.Index) !void {
5007 const mod = self.bin_file.comp.module.?;5059 const pt = self.pt;
5060 const mod = pt.zcu;
5008 const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op;5061 const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op;
5009 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {5062 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
5010 const operand_ptr = try self.resolveInst(un_op);5063 const operand_ptr = try self.resolveInst(un_op);
...@@ -5225,10 +5278,10 @@ fn airBr(self: *Self, inst: Air.Inst.Index) !void {...@@ -5225,10 +5278,10 @@ fn airBr(self: *Self, inst: Air.Inst.Index) !void {
5225}5278}
52265279
5227fn br(self: *Self, block: Air.Inst.Index, operand: Air.Inst.Ref) !void {5280fn br(self: *Self, block: Air.Inst.Index, operand: Air.Inst.Ref) !void {
5228 const mod = self.bin_file.comp.module.?;5281 const pt = self.pt;
5229 const block_data = self.blocks.getPtr(block).?;5282 const block_data = self.blocks.getPtr(block).?;
52305283
5231 if (self.typeOf(operand).hasRuntimeBits(mod)) {5284 if (self.typeOf(operand).hasRuntimeBits(pt)) {
5232 const operand_mcv = try self.resolveInst(operand);5285 const operand_mcv = try self.resolveInst(operand);
5233 const block_mcv = block_data.mcv;5286 const block_mcv = block_data.mcv;
5234 if (block_mcv == .none) {5287 if (block_mcv == .none) {
...@@ -5402,8 +5455,9 @@ fn setRegOrMem(self: *Self, ty: Type, loc: MCValue, val: MCValue) !void {...@@ -5402,8 +5455,9 @@ fn setRegOrMem(self: *Self, ty: Type, loc: MCValue, val: MCValue) !void {
5402}5455}
54035456
5404fn genSetStack(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) InnerError!void {5457fn genSetStack(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) InnerError!void {
5405 const mod = self.bin_file.comp.module.?;5458 const pt = self.pt;
5406 const abi_size = @as(u32, @intCast(ty.abiSize(mod)));5459 const mod = pt.zcu;
5460 const abi_size = @as(u32, @intCast(ty.abiSize(pt)));
5407 switch (mcv) {5461 switch (mcv) {
5408 .dead => unreachable,5462 .dead => unreachable,
5409 .unreach, .none => return, // Nothing to do.5463 .unreach, .none => return, // Nothing to do.
...@@ -5462,7 +5516,7 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) InnerErro...@@ -5462,7 +5516,7 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) InnerErro
5462 try self.genSetStack(wrapped_ty, stack_offset, .{ .register = rwo.reg });5516 try self.genSetStack(wrapped_ty, stack_offset, .{ .register = rwo.reg });
54635517
5464 const overflow_bit_ty = ty.structFieldType(1, mod);5518 const overflow_bit_ty = ty.structFieldType(1, mod);
5465 const overflow_bit_offset = @as(u32, @intCast(ty.structFieldOffset(1, mod)));5519 const overflow_bit_offset = @as(u32, @intCast(ty.structFieldOffset(1, pt)));
5466 const raw_cond_reg = try self.register_manager.allocReg(null, gp);5520 const raw_cond_reg = try self.register_manager.allocReg(null, gp);
5467 const cond_reg = self.registerAlias(raw_cond_reg, overflow_bit_ty);5521 const cond_reg = self.registerAlias(raw_cond_reg, overflow_bit_ty);
54685522
...@@ -5495,7 +5549,7 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) InnerErro...@@ -5495,7 +5549,7 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) InnerErro
5495 const reg = try self.copyToTmpRegister(ty, mcv);5549 const reg = try self.copyToTmpRegister(ty, mcv);
5496 return self.genSetStack(ty, stack_offset, MCValue{ .register = reg });5550 return self.genSetStack(ty, stack_offset, MCValue{ .register = reg });
5497 } else {5551 } else {
5498 const ptr_ty = try mod.singleMutPtrType(ty);5552 const ptr_ty = try pt.singleMutPtrType(ty);
54995553
5500 // TODO call extern memcpy5554 // TODO call extern memcpy
5501 const regs = try self.register_manager.allocRegs(5, .{ null, null, null, null, null }, gp);5555 const regs = try self.register_manager.allocRegs(5, .{ null, null, null, null, null }, gp);
...@@ -5573,7 +5627,8 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) InnerErro...@@ -5573,7 +5627,8 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) InnerErro
5573}5627}
55745628
5575fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void {5629fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void {
5576 const mod = self.bin_file.comp.module.?;5630 const pt = self.pt;
5631 const mod = pt.zcu;
5577 switch (mcv) {5632 switch (mcv) {
5578 .dead => unreachable,5633 .dead => unreachable,
5579 .unreach, .none => return, // Nothing to do.5634 .unreach, .none => return, // Nothing to do.
...@@ -5685,7 +5740,7 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void...@@ -5685,7 +5740,7 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void
5685 try self.genLdrRegister(reg, reg.toX(), ty);5740 try self.genLdrRegister(reg, reg.toX(), ty);
5686 },5741 },
5687 .stack_offset => |off| {5742 .stack_offset => |off| {
5688 const abi_size = ty.abiSize(mod);5743 const abi_size = ty.abiSize(pt);
56895744
5690 switch (abi_size) {5745 switch (abi_size) {
5691 1, 2, 4, 8 => {5746 1, 2, 4, 8 => {
...@@ -5709,7 +5764,7 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void...@@ -5709,7 +5764,7 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void
5709 }5764 }
5710 },5765 },
5711 .stack_argument_offset => |off| {5766 .stack_argument_offset => |off| {
5712 const abi_size = ty.abiSize(mod);5767 const abi_size = ty.abiSize(pt);
57135768
5714 switch (abi_size) {5769 switch (abi_size) {
5715 1, 2, 4, 8 => {5770 1, 2, 4, 8 => {
...@@ -5736,8 +5791,8 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void...@@ -5736,8 +5791,8 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void
5736}5791}
57375792
5738fn genSetStackArgument(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) InnerError!void {5793fn genSetStackArgument(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) InnerError!void {
5739 const mod = self.bin_file.comp.module.?;5794 const pt = self.pt;
5740 const abi_size = @as(u32, @intCast(ty.abiSize(mod)));5795 const abi_size = @as(u32, @intCast(ty.abiSize(pt)));
5741 switch (mcv) {5796 switch (mcv) {
5742 .dead => unreachable,5797 .dead => unreachable,
5743 .none, .unreach => return,5798 .none, .unreach => return,
...@@ -5745,7 +5800,7 @@ fn genSetStackArgument(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) I...@@ -5745,7 +5800,7 @@ fn genSetStackArgument(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) I
5745 if (!self.wantSafety())5800 if (!self.wantSafety())
5746 return; // The already existing value will do just fine.5801 return; // The already existing value will do just fine.
5747 // TODO Upgrade this to a memset call when we have that available.5802 // TODO Upgrade this to a memset call when we have that available.
5748 switch (ty.abiSize(mod)) {5803 switch (ty.abiSize(pt)) {
5749 1 => return self.genSetStack(ty, stack_offset, .{ .immediate = 0xaa }),5804 1 => return self.genSetStack(ty, stack_offset, .{ .immediate = 0xaa }),
5750 2 => return self.genSetStack(ty, stack_offset, .{ .immediate = 0xaaaa }),5805 2 => return self.genSetStack(ty, stack_offset, .{ .immediate = 0xaaaa }),
5751 4 => return self.genSetStack(ty, stack_offset, .{ .immediate = 0xaaaaaaaa }),5806 4 => return self.genSetStack(ty, stack_offset, .{ .immediate = 0xaaaaaaaa }),
...@@ -5815,7 +5870,7 @@ fn genSetStackArgument(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) I...@@ -5815,7 +5870,7 @@ fn genSetStackArgument(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) I
5815 const reg = try self.copyToTmpRegister(ty, mcv);5870 const reg = try self.copyToTmpRegister(ty, mcv);
5816 return self.genSetStackArgument(ty, stack_offset, MCValue{ .register = reg });5871 return self.genSetStackArgument(ty, stack_offset, MCValue{ .register = reg });
5817 } else {5872 } else {
5818 const ptr_ty = try mod.singleMutPtrType(ty);5873 const ptr_ty = try pt.singleMutPtrType(ty);
58195874
5820 // TODO call extern memcpy5875 // TODO call extern memcpy
5821 const regs = try self.register_manager.allocRegs(5, .{ null, null, null, null, null }, gp);5876 const regs = try self.register_manager.allocRegs(5, .{ null, null, null, null, null }, gp);
...@@ -5936,7 +5991,8 @@ fn airBitCast(self: *Self, inst: Air.Inst.Index) !void {...@@ -5936,7 +5991,8 @@ fn airBitCast(self: *Self, inst: Air.Inst.Index) !void {
5936}5991}
59375992
5938fn airArrayToSlice(self: *Self, inst: Air.Inst.Index) !void {5993fn airArrayToSlice(self: *Self, inst: Air.Inst.Index) !void {
5939 const mod = self.bin_file.comp.module.?;5994 const pt = self.pt;
5995 const mod = pt.zcu;
5940 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;5996 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
5941 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {5997 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
5942 const ptr_ty = self.typeOf(ty_op.operand);5998 const ptr_ty = self.typeOf(ty_op.operand);
...@@ -6056,7 +6112,8 @@ fn airReduce(self: *Self, inst: Air.Inst.Index) !void {...@@ -6056,7 +6112,8 @@ fn airReduce(self: *Self, inst: Air.Inst.Index) !void {
6056}6112}
60576113
6058fn airAggregateInit(self: *Self, inst: Air.Inst.Index) !void {6114fn airAggregateInit(self: *Self, inst: Air.Inst.Index) !void {
6059 const mod = self.bin_file.comp.module.?;6115 const pt = self.pt;
6116 const mod = pt.zcu;
6060 const vector_ty = self.typeOfIndex(inst);6117 const vector_ty = self.typeOfIndex(inst);
6061 const len = vector_ty.vectorLen(mod);6118 const len = vector_ty.vectorLen(mod);
6062 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;6119 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
...@@ -6100,15 +6157,15 @@ fn airMulAdd(self: *Self, inst: Air.Inst.Index) !void {...@@ -6100,15 +6157,15 @@ fn airMulAdd(self: *Self, inst: Air.Inst.Index) !void {
6100}6157}
61016158
6102fn airTry(self: *Self, inst: Air.Inst.Index) !void {6159fn airTry(self: *Self, inst: Air.Inst.Index) !void {
6103 const mod = self.bin_file.comp.module.?;6160 const pt = self.pt;
6104 const pl_op = self.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;6161 const pl_op = self.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;
6105 const extra = self.air.extraData(Air.Try, pl_op.payload);6162 const extra = self.air.extraData(Air.Try, pl_op.payload);
6106 const body: []const Air.Inst.Index = @ptrCast(self.air.extra[extra.end..][0..extra.data.body_len]);6163 const body: []const Air.Inst.Index = @ptrCast(self.air.extra[extra.end..][0..extra.data.body_len]);
6107 const result: MCValue = result: {6164 const result: MCValue = result: {
6108 const error_union_bind: ReadArg.Bind = .{ .inst = pl_op.operand };6165 const error_union_bind: ReadArg.Bind = .{ .inst = pl_op.operand };
6109 const error_union_ty = self.typeOf(pl_op.operand);6166 const error_union_ty = self.typeOf(pl_op.operand);
6110 const error_union_size = @as(u32, @intCast(error_union_ty.abiSize(mod)));6167 const error_union_size = @as(u32, @intCast(error_union_ty.abiSize(pt)));
6111 const error_union_align = error_union_ty.abiAlignment(mod);6168 const error_union_align = error_union_ty.abiAlignment(pt);
61126169
6113 // The error union will die in the body. However, we need the6170 // The error union will die in the body. However, we need the
6114 // error union after the body in order to extract the payload6171 // error union after the body in order to extract the payload
...@@ -6137,14 +6194,15 @@ fn airTryPtr(self: *Self, inst: Air.Inst.Index) !void {...@@ -6137,14 +6194,15 @@ fn airTryPtr(self: *Self, inst: Air.Inst.Index) !void {
6137}6194}
61386195
6139fn resolveInst(self: *Self, inst: Air.Inst.Ref) InnerError!MCValue {6196fn resolveInst(self: *Self, inst: Air.Inst.Ref) InnerError!MCValue {
6140 const mod = self.bin_file.comp.module.?;6197 const pt = self.pt;
6198 const mod = pt.zcu;
61416199
6142 // If the type has no codegen bits, no need to store it.6200 // If the type has no codegen bits, no need to store it.
6143 const inst_ty = self.typeOf(inst);6201 const inst_ty = self.typeOf(inst);
6144 if (!inst_ty.hasRuntimeBitsIgnoreComptime(mod) and !inst_ty.isError(mod))6202 if (!inst_ty.hasRuntimeBitsIgnoreComptime(pt) and !inst_ty.isError(mod))
6145 return MCValue{ .none = {} };6203 return MCValue{ .none = {} };
61466204
6147 const inst_index = inst.toIndex() orelse return self.genTypedValue((try self.air.value(inst, mod)).?);6205 const inst_index = inst.toIndex() orelse return self.genTypedValue((try self.air.value(inst, pt)).?);
61486206
6149 return self.getResolvedInstValue(inst_index);6207 return self.getResolvedInstValue(inst_index);
6150}6208}
...@@ -6164,6 +6222,7 @@ fn getResolvedInstValue(self: *Self, inst: Air.Inst.Index) MCValue {...@@ -6164,6 +6222,7 @@ fn getResolvedInstValue(self: *Self, inst: Air.Inst.Index) MCValue {
6164fn genTypedValue(self: *Self, val: Value) InnerError!MCValue {6222fn genTypedValue(self: *Self, val: Value) InnerError!MCValue {
6165 const mcv: MCValue = switch (try codegen.genTypedValue(6223 const mcv: MCValue = switch (try codegen.genTypedValue(
6166 self.bin_file,6224 self.bin_file,
6225 self.pt,
6167 self.src_loc,6226 self.src_loc,
6168 val,6227 val,
6169 self.owner_decl,6228 self.owner_decl,
...@@ -6199,7 +6258,8 @@ const CallMCValues = struct {...@@ -6199,7 +6258,8 @@ const CallMCValues = struct {
61996258
6200/// Caller must call `CallMCValues.deinit`.6259/// Caller must call `CallMCValues.deinit`.
6201fn resolveCallingConventionValues(self: *Self, fn_ty: Type) !CallMCValues {6260fn resolveCallingConventionValues(self: *Self, fn_ty: Type) !CallMCValues {
6202 const mod = self.bin_file.comp.module.?;6261 const pt = self.pt;
6262 const mod = pt.zcu;
6203 const ip = &mod.intern_pool;6263 const ip = &mod.intern_pool;
6204 const fn_info = mod.typeToFunc(fn_ty).?;6264 const fn_info = mod.typeToFunc(fn_ty).?;
6205 const cc = fn_info.cc;6265 const cc = fn_info.cc;
...@@ -6229,10 +6289,10 @@ fn resolveCallingConventionValues(self: *Self, fn_ty: Type) !CallMCValues {...@@ -6229,10 +6289,10 @@ fn resolveCallingConventionValues(self: *Self, fn_ty: Type) !CallMCValues {
62296289
6230 if (ret_ty.zigTypeTag(mod) == .NoReturn) {6290 if (ret_ty.zigTypeTag(mod) == .NoReturn) {
6231 result.return_value = .{ .unreach = {} };6291 result.return_value = .{ .unreach = {} };
6232 } else if (!ret_ty.hasRuntimeBitsIgnoreComptime(mod) and !ret_ty.isError(mod)) {6292 } else if (!ret_ty.hasRuntimeBitsIgnoreComptime(pt) and !ret_ty.isError(mod)) {
6233 result.return_value = .{ .none = {} };6293 result.return_value = .{ .none = {} };
6234 } else {6294 } else {
6235 const ret_ty_size = @as(u32, @intCast(ret_ty.abiSize(mod)));6295 const ret_ty_size: u32 = @intCast(ret_ty.abiSize(pt));
6236 if (ret_ty_size == 0) {6296 if (ret_ty_size == 0) {
6237 assert(ret_ty.isError(mod));6297 assert(ret_ty.isError(mod));
6238 result.return_value = .{ .immediate = 0 };6298 result.return_value = .{ .immediate = 0 };
...@@ -6244,7 +6304,7 @@ fn resolveCallingConventionValues(self: *Self, fn_ty: Type) !CallMCValues {...@@ -6244,7 +6304,7 @@ fn resolveCallingConventionValues(self: *Self, fn_ty: Type) !CallMCValues {
6244 }6304 }
62456305
6246 for (fn_info.param_types.get(ip), result.args) |ty, *result_arg| {6306 for (fn_info.param_types.get(ip), result.args) |ty, *result_arg| {
6247 const param_size = @as(u32, @intCast(Type.fromInterned(ty).abiSize(mod)));6307 const param_size = @as(u32, @intCast(Type.fromInterned(ty).abiSize(pt)));
6248 if (param_size == 0) {6308 if (param_size == 0) {
6249 result_arg.* = .{ .none = {} };6309 result_arg.* = .{ .none = {} };
6250 continue;6310 continue;
...@@ -6252,7 +6312,7 @@ fn resolveCallingConventionValues(self: *Self, fn_ty: Type) !CallMCValues {...@@ -6252,7 +6312,7 @@ fn resolveCallingConventionValues(self: *Self, fn_ty: Type) !CallMCValues {
62526312
6253 // We round up NCRN only for non-Apple platforms which allow the 16-byte aligned6313 // We round up NCRN only for non-Apple platforms which allow the 16-byte aligned
6254 // values to spread across odd-numbered registers.6314 // values to spread across odd-numbered registers.
6255 if (Type.fromInterned(ty).abiAlignment(mod) == .@"16" and !self.target.isDarwin()) {6315 if (Type.fromInterned(ty).abiAlignment(pt) == .@"16" and !self.target.isDarwin()) {
6256 // Round up NCRN to the next even number6316 // Round up NCRN to the next even number
6257 ncrn += ncrn % 2;6317 ncrn += ncrn % 2;
6258 }6318 }
...@@ -6270,7 +6330,7 @@ fn resolveCallingConventionValues(self: *Self, fn_ty: Type) !CallMCValues {...@@ -6270,7 +6330,7 @@ fn resolveCallingConventionValues(self: *Self, fn_ty: Type) !CallMCValues {
6270 ncrn = 8;6330 ncrn = 8;
6271 // TODO Apple allows the arguments on the stack to be non-8-byte aligned provided6331 // TODO Apple allows the arguments on the stack to be non-8-byte aligned provided
6272 // that the entire stack space consumed by the arguments is 8-byte aligned.6332 // that the entire stack space consumed by the arguments is 8-byte aligned.
6273 if (Type.fromInterned(ty).abiAlignment(mod) == .@"8") {6333 if (Type.fromInterned(ty).abiAlignment(pt) == .@"8") {
6274 if (nsaa % 8 != 0) {6334 if (nsaa % 8 != 0) {
6275 nsaa += 8 - (nsaa % 8);6335 nsaa += 8 - (nsaa % 8);
6276 }6336 }
...@@ -6287,10 +6347,10 @@ fn resolveCallingConventionValues(self: *Self, fn_ty: Type) !CallMCValues {...@@ -6287,10 +6347,10 @@ fn resolveCallingConventionValues(self: *Self, fn_ty: Type) !CallMCValues {
6287 .Unspecified => {6347 .Unspecified => {
6288 if (ret_ty.zigTypeTag(mod) == .NoReturn) {6348 if (ret_ty.zigTypeTag(mod) == .NoReturn) {
6289 result.return_value = .{ .unreach = {} };6349 result.return_value = .{ .unreach = {} };
6290 } else if (!ret_ty.hasRuntimeBitsIgnoreComptime(mod) and !ret_ty.isError(mod)) {6350 } else if (!ret_ty.hasRuntimeBitsIgnoreComptime(pt) and !ret_ty.isError(mod)) {
6291 result.return_value = .{ .none = {} };6351 result.return_value = .{ .none = {} };
6292 } else {6352 } else {
6293 const ret_ty_size = @as(u32, @intCast(ret_ty.abiSize(mod)));6353 const ret_ty_size = @as(u32, @intCast(ret_ty.abiSize(pt)));
6294 if (ret_ty_size == 0) {6354 if (ret_ty_size == 0) {
6295 assert(ret_ty.isError(mod));6355 assert(ret_ty.isError(mod));
6296 result.return_value = .{ .immediate = 0 };6356 result.return_value = .{ .immediate = 0 };
...@@ -6309,9 +6369,9 @@ fn resolveCallingConventionValues(self: *Self, fn_ty: Type) !CallMCValues {...@@ -6309,9 +6369,9 @@ fn resolveCallingConventionValues(self: *Self, fn_ty: Type) !CallMCValues {
6309 var stack_offset: u32 = 0;6369 var stack_offset: u32 = 0;
63106370
6311 for (fn_info.param_types.get(ip), result.args) |ty, *result_arg| {6371 for (fn_info.param_types.get(ip), result.args) |ty, *result_arg| {
6312 if (Type.fromInterned(ty).abiSize(mod) > 0) {6372 if (Type.fromInterned(ty).abiSize(pt) > 0) {
6313 const param_size: u32 = @intCast(Type.fromInterned(ty).abiSize(mod));6373 const param_size: u32 = @intCast(Type.fromInterned(ty).abiSize(pt));
6314 const param_alignment = Type.fromInterned(ty).abiAlignment(mod);6374 const param_alignment = Type.fromInterned(ty).abiAlignment(pt);
63156375
6316 stack_offset = @intCast(param_alignment.forward(stack_offset));6376 stack_offset = @intCast(param_alignment.forward(stack_offset));
6317 result_arg.* = .{ .stack_argument_offset = stack_offset };6377 result_arg.* = .{ .stack_argument_offset = stack_offset };
...@@ -6330,7 +6390,7 @@ fn resolveCallingConventionValues(self: *Self, fn_ty: Type) !CallMCValues {...@@ -6330,7 +6390,7 @@ fn resolveCallingConventionValues(self: *Self, fn_ty: Type) !CallMCValues {
6330 return result;6390 return result;
6331}6391}
63326392
6333/// TODO support scope overrides. Also note this logic is duplicated with `Module.wantSafety`.6393/// TODO support scope overrides. Also note this logic is duplicated with `Zcu.wantSafety`.
6334fn wantSafety(self: *Self) bool {6394fn wantSafety(self: *Self) bool {
6335 return switch (self.bin_file.comp.root_mod.optimize_mode) {6395 return switch (self.bin_file.comp.root_mod.optimize_mode) {
6336 .Debug => true,6396 .Debug => true,
...@@ -6362,8 +6422,7 @@ fn parseRegName(name: []const u8) ?Register {...@@ -6362,8 +6422,7 @@ fn parseRegName(name: []const u8) ?Register {
6362}6422}
63636423
6364fn registerAlias(self: *Self, reg: Register, ty: Type) Register {6424fn registerAlias(self: *Self, reg: Register, ty: Type) Register {
6365 const mod = self.bin_file.comp.module.?;6425 const abi_size = ty.abiSize(self.pt);
6366 const abi_size = ty.abiSize(mod);
63676426
6368 switch (reg.class()) {6427 switch (reg.class()) {
6369 .general_purpose => {6428 .general_purpose => {
...@@ -6391,11 +6450,9 @@ fn registerAlias(self: *Self, reg: Register, ty: Type) Register {...@@ -6391,11 +6450,9 @@ fn registerAlias(self: *Self, reg: Register, ty: Type) Register {
6391}6450}
63926451
6393fn typeOf(self: *Self, inst: Air.Inst.Ref) Type {6452fn typeOf(self: *Self, inst: Air.Inst.Ref) Type {
6394 const mod = self.bin_file.comp.module.?;6453 return self.air.typeOf(inst, &self.pt.zcu.intern_pool);
6395 return self.air.typeOf(inst, &mod.intern_pool);
6396}6454}
63976455
6398fn typeOfIndex(self: *Self, inst: Air.Inst.Index) Type {6456fn typeOfIndex(self: *Self, inst: Air.Inst.Index) Type {
6399 const mod = self.bin_file.comp.module.?;6457 return self.air.typeOfIndex(inst, &self.pt.zcu.intern_pool);
6400 return self.air.typeOfIndex(inst, &mod.intern_pool);
6401}6458}
src/arch/aarch64/Emit.zig+2-4
...@@ -8,9 +8,7 @@ const Mir = @import("Mir.zig");...@@ -8,9 +8,7 @@ const Mir = @import("Mir.zig");
8const bits = @import("bits.zig");8const bits = @import("bits.zig");
9const link = @import("../../link.zig");9const link = @import("../../link.zig");
10const Zcu = @import("../../Zcu.zig");10const Zcu = @import("../../Zcu.zig");
11/// Deprecated.11const ErrorMsg = Zcu.ErrorMsg;
12const Module = Zcu;
13const ErrorMsg = Module.ErrorMsg;
14const assert = std.debug.assert;12const assert = std.debug.assert;
15const Instruction = bits.Instruction;13const Instruction = bits.Instruction;
16const Register = bits.Register;14const Register = bits.Register;
...@@ -22,7 +20,7 @@ bin_file: *link.File,...@@ -22,7 +20,7 @@ bin_file: *link.File,
22debug_output: DebugInfoOutput,20debug_output: DebugInfoOutput,
23target: *const std.Target,21target: *const std.Target,
24err_msg: ?*ErrorMsg = null,22err_msg: ?*ErrorMsg = null,
25src_loc: Module.LazySrcLoc,23src_loc: Zcu.LazySrcLoc,
26code: *std.ArrayList(u8),24code: *std.ArrayList(u8),
2725
28prev_di_line: u32,26prev_di_line: u32,
src/arch/aarch64/abi.zig+29-31
...@@ -5,8 +5,6 @@ const Register = bits.Register;...@@ -5,8 +5,6 @@ const Register = bits.Register;
5const RegisterManagerFn = @import("../../register_manager.zig").RegisterManager;5const RegisterManagerFn = @import("../../register_manager.zig").RegisterManager;
6const Type = @import("../../Type.zig");6const Type = @import("../../Type.zig");
7const Zcu = @import("../../Zcu.zig");7const Zcu = @import("../../Zcu.zig");
8/// Deprecated.
9const Module = Zcu;
108
11pub const Class = union(enum) {9pub const Class = union(enum) {
12 memory,10 memory,
...@@ -17,44 +15,44 @@ pub const Class = union(enum) {...@@ -17,44 +15,44 @@ pub const Class = union(enum) {
17};15};
1816
19/// For `float_array` the second element will be the amount of floats.17/// For `float_array` the second element will be the amount of floats.
20pub fn classifyType(ty: Type, mod: *Module) Class {18pub fn classifyType(ty: Type, pt: Zcu.PerThread) Class {
21 std.debug.assert(ty.hasRuntimeBitsIgnoreComptime(mod));19 std.debug.assert(ty.hasRuntimeBitsIgnoreComptime(pt));
2220
23 var maybe_float_bits: ?u16 = null;21 var maybe_float_bits: ?u16 = null;
24 switch (ty.zigTypeTag(mod)) {22 switch (ty.zigTypeTag(pt.zcu)) {
25 .Struct => {23 .Struct => {
26 if (ty.containerLayout(mod) == .@"packed") return .byval;24 if (ty.containerLayout(pt.zcu) == .@"packed") return .byval;
27 const float_count = countFloats(ty, mod, &maybe_float_bits);25 const float_count = countFloats(ty, pt.zcu, &maybe_float_bits);
28 if (float_count <= sret_float_count) return .{ .float_array = float_count };26 if (float_count <= sret_float_count) return .{ .float_array = float_count };
2927
30 const bit_size = ty.bitSize(mod);28 const bit_size = ty.bitSize(pt);
31 if (bit_size > 128) return .memory;29 if (bit_size > 128) return .memory;
32 if (bit_size > 64) return .double_integer;30 if (bit_size > 64) return .double_integer;
33 return .integer;31 return .integer;
34 },32 },
35 .Union => {33 .Union => {
36 if (ty.containerLayout(mod) == .@"packed") return .byval;34 if (ty.containerLayout(pt.zcu) == .@"packed") return .byval;
37 const float_count = countFloats(ty, mod, &maybe_float_bits);35 const float_count = countFloats(ty, pt.zcu, &maybe_float_bits);
38 if (float_count <= sret_float_count) return .{ .float_array = float_count };36 if (float_count <= sret_float_count) return .{ .float_array = float_count };
3937
40 const bit_size = ty.bitSize(mod);38 const bit_size = ty.bitSize(pt);
41 if (bit_size > 128) return .memory;39 if (bit_size > 128) return .memory;
42 if (bit_size > 64) return .double_integer;40 if (bit_size > 64) return .double_integer;
43 return .integer;41 return .integer;
44 },42 },
45 .Int, .Enum, .ErrorSet, .Float, .Bool => return .byval,43 .Int, .Enum, .ErrorSet, .Float, .Bool => return .byval,
46 .Vector => {44 .Vector => {
47 const bit_size = ty.bitSize(mod);45 const bit_size = ty.bitSize(pt);
48 // TODO is this controlled by a cpu feature?46 // TODO is this controlled by a cpu feature?
49 if (bit_size > 128) return .memory;47 if (bit_size > 128) return .memory;
50 return .byval;48 return .byval;
51 },49 },
52 .Optional => {50 .Optional => {
53 std.debug.assert(ty.isPtrLikeOptional(mod));51 std.debug.assert(ty.isPtrLikeOptional(pt.zcu));
54 return .byval;52 return .byval;
55 },53 },
56 .Pointer => {54 .Pointer => {
57 std.debug.assert(!ty.isSlice(mod));55 std.debug.assert(!ty.isSlice(pt.zcu));
58 return .byval;56 return .byval;
59 },57 },
60 .ErrorUnion,58 .ErrorUnion,
...@@ -76,16 +74,16 @@ pub fn classifyType(ty: Type, mod: *Module) Class {...@@ -76,16 +74,16 @@ pub fn classifyType(ty: Type, mod: *Module) Class {
76}74}
7775
78const sret_float_count = 4;76const sret_float_count = 4;
79fn countFloats(ty: Type, mod: *Module, maybe_float_bits: *?u16) u8 {77fn countFloats(ty: Type, zcu: *Zcu, maybe_float_bits: *?u16) u8 {
80 const ip = &mod.intern_pool;78 const ip = &zcu.intern_pool;
81 const target = mod.getTarget();79 const target = zcu.getTarget();
82 const invalid = std.math.maxInt(u8);80 const invalid = std.math.maxInt(u8);
83 switch (ty.zigTypeTag(mod)) {81 switch (ty.zigTypeTag(zcu)) {
84 .Union => {82 .Union => {
85 const union_obj = mod.typeToUnion(ty).?;83 const union_obj = zcu.typeToUnion(ty).?;
86 var max_count: u8 = 0;84 var max_count: u8 = 0;
87 for (union_obj.field_types.get(ip)) |field_ty| {85 for (union_obj.field_types.get(ip)) |field_ty| {
88 const field_count = countFloats(Type.fromInterned(field_ty), mod, maybe_float_bits);86 const field_count = countFloats(Type.fromInterned(field_ty), zcu, maybe_float_bits);
89 if (field_count == invalid) return invalid;87 if (field_count == invalid) return invalid;
90 if (field_count > max_count) max_count = field_count;88 if (field_count > max_count) max_count = field_count;
91 if (max_count > sret_float_count) return invalid;89 if (max_count > sret_float_count) return invalid;
...@@ -93,12 +91,12 @@ fn countFloats(ty: Type, mod: *Module, maybe_float_bits: *?u16) u8 {...@@ -93,12 +91,12 @@ fn countFloats(ty: Type, mod: *Module, maybe_float_bits: *?u16) u8 {
93 return max_count;91 return max_count;
94 },92 },
95 .Struct => {93 .Struct => {
96 const fields_len = ty.structFieldCount(mod);94 const fields_len = ty.structFieldCount(zcu);
97 var count: u8 = 0;95 var count: u8 = 0;
98 var i: u32 = 0;96 var i: u32 = 0;
99 while (i < fields_len) : (i += 1) {97 while (i < fields_len) : (i += 1) {
100 const field_ty = ty.structFieldType(i, mod);98 const field_ty = ty.structFieldType(i, zcu);
101 const field_count = countFloats(field_ty, mod, maybe_float_bits);99 const field_count = countFloats(field_ty, zcu, maybe_float_bits);
102 if (field_count == invalid) return invalid;100 if (field_count == invalid) return invalid;
103 count += field_count;101 count += field_count;
104 if (count > sret_float_count) return invalid;102 if (count > sret_float_count) return invalid;
...@@ -118,22 +116,22 @@ fn countFloats(ty: Type, mod: *Module, maybe_float_bits: *?u16) u8 {...@@ -118,22 +116,22 @@ fn countFloats(ty: Type, mod: *Module, maybe_float_bits: *?u16) u8 {
118 }116 }
119}117}
120118
121pub fn getFloatArrayType(ty: Type, mod: *Module) ?Type {119pub fn getFloatArrayType(ty: Type, zcu: *Zcu) ?Type {
122 const ip = &mod.intern_pool;120 const ip = &zcu.intern_pool;
123 switch (ty.zigTypeTag(mod)) {121 switch (ty.zigTypeTag(zcu)) {
124 .Union => {122 .Union => {
125 const union_obj = mod.typeToUnion(ty).?;123 const union_obj = zcu.typeToUnion(ty).?;
126 for (union_obj.field_types.get(ip)) |field_ty| {124 for (union_obj.field_types.get(ip)) |field_ty| {
127 if (getFloatArrayType(Type.fromInterned(field_ty), mod)) |some| return some;125 if (getFloatArrayType(Type.fromInterned(field_ty), zcu)) |some| return some;
128 }126 }
129 return null;127 return null;
130 },128 },
131 .Struct => {129 .Struct => {
132 const fields_len = ty.structFieldCount(mod);130 const fields_len = ty.structFieldCount(zcu);
133 var i: u32 = 0;131 var i: u32 = 0;
134 while (i < fields_len) : (i += 1) {132 while (i < fields_len) : (i += 1) {
135 const field_ty = ty.structFieldType(i, mod);133 const field_ty = ty.structFieldType(i, zcu);
136 if (getFloatArrayType(field_ty, mod)) |some| return some;134 if (getFloatArrayType(field_ty, zcu)) |some| return some;
137 }135 }
138 return null;136 return null;
139 },137 },
src/arch/arm/CodeGen.zig+219-164
...@@ -12,11 +12,9 @@ const Type = @import("../../Type.zig");...@@ -12,11 +12,9 @@ const Type = @import("../../Type.zig");
12const Value = @import("../../Value.zig");12const Value = @import("../../Value.zig");
13const link = @import("../../link.zig");13const link = @import("../../link.zig");
14const Zcu = @import("../../Zcu.zig");14const Zcu = @import("../../Zcu.zig");
15/// Deprecated.
16const Module = Zcu;
17const InternPool = @import("../../InternPool.zig");15const InternPool = @import("../../InternPool.zig");
18const Compilation = @import("../../Compilation.zig");16const Compilation = @import("../../Compilation.zig");
19const ErrorMsg = Module.ErrorMsg;17const ErrorMsg = Zcu.ErrorMsg;
20const Target = std.Target;18const Target = std.Target;
21const Allocator = mem.Allocator;19const Allocator = mem.Allocator;
22const trace = @import("../../tracy.zig").trace;20const trace = @import("../../tracy.zig").trace;
...@@ -48,6 +46,7 @@ const gp = abi.RegisterClass.gp;...@@ -48,6 +46,7 @@ const gp = abi.RegisterClass.gp;
48const InnerError = CodeGenError || error{OutOfRegisters};46const InnerError = CodeGenError || error{OutOfRegisters};
4947
50gpa: Allocator,48gpa: Allocator,
49pt: Zcu.PerThread,
51air: Air,50air: Air,
52liveness: Liveness,51liveness: Liveness,
53bin_file: *link.File,52bin_file: *link.File,
...@@ -59,7 +58,7 @@ args: []MCValue,...@@ -59,7 +58,7 @@ args: []MCValue,
59ret_mcv: MCValue,58ret_mcv: MCValue,
60fn_type: Type,59fn_type: Type,
61arg_index: u32,60arg_index: u32,
62src_loc: Module.LazySrcLoc,61src_loc: Zcu.LazySrcLoc,
63stack_align: u32,62stack_align: u32,
6463
65/// MIR Instructions64/// MIR Instructions
...@@ -261,7 +260,6 @@ const DbgInfoReloc = struct {...@@ -261,7 +260,6 @@ const DbgInfoReloc = struct {
261 }260 }
262261
263 fn genArgDbgInfo(reloc: DbgInfoReloc, function: Self) error{OutOfMemory}!void {262 fn genArgDbgInfo(reloc: DbgInfoReloc, function: Self) error{OutOfMemory}!void {
264 const mod = function.bin_file.comp.module.?;
265 switch (function.debug_output) {263 switch (function.debug_output) {
266 .dwarf => |dw| {264 .dwarf => |dw| {
267 const loc: link.File.Dwarf.DeclState.DbgInfoLoc = switch (reloc.mcv) {265 const loc: link.File.Dwarf.DeclState.DbgInfoLoc = switch (reloc.mcv) {
...@@ -282,7 +280,7 @@ const DbgInfoReloc = struct {...@@ -282,7 +280,7 @@ const DbgInfoReloc = struct {
282 else => unreachable, // not a possible argument280 else => unreachable, // not a possible argument
283 };281 };
284282
285 try dw.genArgDbgInfo(reloc.name, reloc.ty, mod.funcOwnerDeclIndex(function.func_index), loc);283 try dw.genArgDbgInfo(reloc.name, reloc.ty, function.pt.zcu.funcOwnerDeclIndex(function.func_index), loc);
286 },284 },
287 .plan9 => {},285 .plan9 => {},
288 .none => {},286 .none => {},
...@@ -290,7 +288,6 @@ const DbgInfoReloc = struct {...@@ -290,7 +288,6 @@ const DbgInfoReloc = struct {
290 }288 }
291289
292 fn genVarDbgInfo(reloc: DbgInfoReloc, function: Self) !void {290 fn genVarDbgInfo(reloc: DbgInfoReloc, function: Self) !void {
293 const mod = function.bin_file.comp.module.?;
294 const is_ptr = switch (reloc.tag) {291 const is_ptr = switch (reloc.tag) {
295 .dbg_var_ptr => true,292 .dbg_var_ptr => true,
296 .dbg_var_val => false,293 .dbg_var_val => false,
...@@ -326,7 +323,7 @@ const DbgInfoReloc = struct {...@@ -326,7 +323,7 @@ const DbgInfoReloc = struct {
326 break :blk .nop;323 break :blk .nop;
327 },324 },
328 };325 };
329 try dw.genVarDbgInfo(reloc.name, reloc.ty, mod.funcOwnerDeclIndex(function.func_index), is_ptr, loc);326 try dw.genVarDbgInfo(reloc.name, reloc.ty, function.pt.zcu.funcOwnerDeclIndex(function.func_index), is_ptr, loc);
330 },327 },
331 .plan9 => {},328 .plan9 => {},
332 .none => {},329 .none => {},
...@@ -338,15 +335,16 @@ const Self = @This();...@@ -338,15 +335,16 @@ const Self = @This();
338335
339pub fn generate(336pub fn generate(
340 lf: *link.File,337 lf: *link.File,
341 src_loc: Module.LazySrcLoc,338 pt: Zcu.PerThread,
339 src_loc: Zcu.LazySrcLoc,
342 func_index: InternPool.Index,340 func_index: InternPool.Index,
343 air: Air,341 air: Air,
344 liveness: Liveness,342 liveness: Liveness,
345 code: *std.ArrayList(u8),343 code: *std.ArrayList(u8),
346 debug_output: DebugInfoOutput,344 debug_output: DebugInfoOutput,
347) CodeGenError!Result {345) CodeGenError!Result {
348 const gpa = lf.comp.gpa;346 const zcu = pt.zcu;
349 const zcu = lf.comp.module.?;347 const gpa = zcu.gpa;
350 const func = zcu.funcInfo(func_index);348 const func = zcu.funcInfo(func_index);
351 const fn_owner_decl = zcu.declPtr(func.owner_decl);349 const fn_owner_decl = zcu.declPtr(func.owner_decl);
352 assert(fn_owner_decl.has_tv);350 assert(fn_owner_decl.has_tv);
...@@ -364,6 +362,7 @@ pub fn generate(...@@ -364,6 +362,7 @@ pub fn generate(
364362
365 var function: Self = .{363 var function: Self = .{
366 .gpa = gpa,364 .gpa = gpa,
365 .pt = pt,
367 .air = air,366 .air = air,
368 .liveness = liveness,367 .liveness = liveness,
369 .target = target,368 .target = target,
...@@ -482,7 +481,8 @@ pub fn addExtraAssumeCapacity(self: *Self, extra: anytype) u32 {...@@ -482,7 +481,8 @@ pub fn addExtraAssumeCapacity(self: *Self, extra: anytype) u32 {
482}481}
483482
484fn gen(self: *Self) !void {483fn gen(self: *Self) !void {
485 const mod = self.bin_file.comp.module.?;484 const pt = self.pt;
485 const mod = pt.zcu;
486 const cc = self.fn_type.fnCallingConvention(mod);486 const cc = self.fn_type.fnCallingConvention(mod);
487 if (cc != .Naked) {487 if (cc != .Naked) {
488 // push {fp, lr}488 // push {fp, lr}
...@@ -526,8 +526,8 @@ fn gen(self: *Self) !void {...@@ -526,8 +526,8 @@ fn gen(self: *Self) !void {
526526
527 const ty = self.typeOfIndex(inst);527 const ty = self.typeOfIndex(inst);
528528
529 const abi_size: u32 = @intCast(ty.abiSize(mod));529 const abi_size: u32 = @intCast(ty.abiSize(pt));
530 const abi_align = ty.abiAlignment(mod);530 const abi_align = ty.abiAlignment(pt);
531 const stack_offset = try self.allocMem(abi_size, abi_align, inst);531 const stack_offset = try self.allocMem(abi_size, abi_align, inst);
532 try self.genSetStack(ty, stack_offset, MCValue{ .register = reg });532 try self.genSetStack(ty, stack_offset, MCValue{ .register = reg });
533533
...@@ -642,7 +642,8 @@ fn gen(self: *Self) !void {...@@ -642,7 +642,8 @@ fn gen(self: *Self) !void {
642}642}
643643
644fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {644fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {
645 const mod = self.bin_file.comp.module.?;645 const pt = self.pt;
646 const mod = pt.zcu;
646 const ip = &mod.intern_pool;647 const ip = &mod.intern_pool;
647 const air_tags = self.air.instructions.items(.tag);648 const air_tags = self.air.instructions.items(.tag);
648649
...@@ -1004,10 +1005,11 @@ fn allocMem(...@@ -1004,10 +1005,11 @@ fn allocMem(
10041005
1005/// Use a pointer instruction as the basis for allocating stack memory.1006/// Use a pointer instruction as the basis for allocating stack memory.
1006fn allocMemPtr(self: *Self, inst: Air.Inst.Index) !u32 {1007fn allocMemPtr(self: *Self, inst: Air.Inst.Index) !u32 {
1007 const mod = self.bin_file.comp.module.?;1008 const pt = self.pt;
1009 const mod = pt.zcu;
1008 const elem_ty = self.typeOfIndex(inst).childType(mod);1010 const elem_ty = self.typeOfIndex(inst).childType(mod);
10091011
1010 if (!elem_ty.hasRuntimeBits(mod)) {1012 if (!elem_ty.hasRuntimeBits(pt)) {
1011 // As this stack item will never be dereferenced at runtime,1013 // As this stack item will never be dereferenced at runtime,
1012 // return the stack offset 0. Stack offset 0 will be where all1014 // return the stack offset 0. Stack offset 0 will be where all
1013 // zero-sized stack allocations live as non-zero-sized1015 // zero-sized stack allocations live as non-zero-sized
...@@ -1015,21 +1017,21 @@ fn allocMemPtr(self: *Self, inst: Air.Inst.Index) !u32 {...@@ -1015,21 +1017,21 @@ fn allocMemPtr(self: *Self, inst: Air.Inst.Index) !u32 {
1015 return 0;1017 return 0;
1016 }1018 }
10171019
1018 const abi_size = math.cast(u32, elem_ty.abiSize(mod)) orelse {1020 const abi_size = math.cast(u32, elem_ty.abiSize(pt)) orelse {
1019 return self.fail("type '{}' too big to fit into stack frame", .{elem_ty.fmt(mod)});1021 return self.fail("type '{}' too big to fit into stack frame", .{elem_ty.fmt(pt)});
1020 };1022 };
1021 // TODO swap this for inst.ty.ptrAlign1023 // TODO swap this for inst.ty.ptrAlign
1022 const abi_align = elem_ty.abiAlignment(mod);1024 const abi_align = elem_ty.abiAlignment(pt);
10231025
1024 return self.allocMem(abi_size, abi_align, inst);1026 return self.allocMem(abi_size, abi_align, inst);
1025}1027}
10261028
1027fn allocRegOrMem(self: *Self, elem_ty: Type, reg_ok: bool, maybe_inst: ?Air.Inst.Index) !MCValue {1029fn allocRegOrMem(self: *Self, elem_ty: Type, reg_ok: bool, maybe_inst: ?Air.Inst.Index) !MCValue {
1028 const mod = self.bin_file.comp.module.?;1030 const pt = self.pt;
1029 const abi_size = math.cast(u32, elem_ty.abiSize(mod)) orelse {1031 const abi_size = math.cast(u32, elem_ty.abiSize(pt)) orelse {
1030 return self.fail("type '{}' too big to fit into stack frame", .{elem_ty.fmt(mod)});1032 return self.fail("type '{}' too big to fit into stack frame", .{elem_ty.fmt(pt)});
1031 };1033 };
1032 const abi_align = elem_ty.abiAlignment(mod);1034 const abi_align = elem_ty.abiAlignment(pt);
10331035
1034 if (reg_ok) {1036 if (reg_ok) {
1035 // Make sure the type can fit in a register before we try to allocate one.1037 // Make sure the type can fit in a register before we try to allocate one.
...@@ -1112,14 +1114,15 @@ fn airAlloc(self: *Self, inst: Air.Inst.Index) !void {...@@ -1112,14 +1114,15 @@ fn airAlloc(self: *Self, inst: Air.Inst.Index) !void {
1112}1114}
11131115
1114fn airRetPtr(self: *Self, inst: Air.Inst.Index) !void {1116fn airRetPtr(self: *Self, inst: Air.Inst.Index) !void {
1115 const mod = self.bin_file.comp.module.?;1117 const pt = self.pt;
1118 const mod = pt.zcu;
1116 const result: MCValue = switch (self.ret_mcv) {1119 const result: MCValue = switch (self.ret_mcv) {
1117 .none, .register => .{ .ptr_stack_offset = try self.allocMemPtr(inst) },1120 .none, .register => .{ .ptr_stack_offset = try self.allocMemPtr(inst) },
1118 .stack_offset => blk: {1121 .stack_offset => blk: {
1119 // self.ret_mcv is an address to where this function1122 // self.ret_mcv is an address to where this function
1120 // should store its result into1123 // should store its result into
1121 const ret_ty = self.fn_type.fnReturnType(mod);1124 const ret_ty = self.fn_type.fnReturnType(mod);
1122 const ptr_ty = try mod.singleMutPtrType(ret_ty);1125 const ptr_ty = try pt.singleMutPtrType(ret_ty);
11231126
1124 // addr_reg will contain the address of where to store the1127 // addr_reg will contain the address of where to store the
1125 // result into1128 // result into
...@@ -1145,7 +1148,8 @@ fn airFpext(self: *Self, inst: Air.Inst.Index) !void {...@@ -1145,7 +1148,8 @@ fn airFpext(self: *Self, inst: Air.Inst.Index) !void {
1145}1148}
11461149
1147fn airIntCast(self: *Self, inst: Air.Inst.Index) !void {1150fn airIntCast(self: *Self, inst: Air.Inst.Index) !void {
1148 const mod = self.bin_file.comp.module.?;1151 const pt = self.pt;
1152 const mod = pt.zcu;
1149 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;1153 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
1150 if (self.liveness.isUnused(inst))1154 if (self.liveness.isUnused(inst))
1151 return self.finishAir(inst, .dead, .{ ty_op.operand, .none, .none });1155 return self.finishAir(inst, .dead, .{ ty_op.operand, .none, .none });
...@@ -1154,8 +1158,8 @@ fn airIntCast(self: *Self, inst: Air.Inst.Index) !void {...@@ -1154,8 +1158,8 @@ fn airIntCast(self: *Self, inst: Air.Inst.Index) !void {
1154 const operand_ty = self.typeOf(ty_op.operand);1158 const operand_ty = self.typeOf(ty_op.operand);
1155 const dest_ty = self.typeOfIndex(inst);1159 const dest_ty = self.typeOfIndex(inst);
11561160
1157 const operand_abi_size = operand_ty.abiSize(mod);1161 const operand_abi_size = operand_ty.abiSize(pt);
1158 const dest_abi_size = dest_ty.abiSize(mod);1162 const dest_abi_size = dest_ty.abiSize(pt);
1159 const info_a = operand_ty.intInfo(mod);1163 const info_a = operand_ty.intInfo(mod);
1160 const info_b = dest_ty.intInfo(mod);1164 const info_b = dest_ty.intInfo(mod);
11611165
...@@ -1211,7 +1215,8 @@ fn trunc(...@@ -1211,7 +1215,8 @@ fn trunc(
1211 operand_ty: Type,1215 operand_ty: Type,
1212 dest_ty: Type,1216 dest_ty: Type,
1213) !MCValue {1217) !MCValue {
1214 const mod = self.bin_file.comp.module.?;1218 const pt = self.pt;
1219 const mod = pt.zcu;
1215 const info_a = operand_ty.intInfo(mod);1220 const info_a = operand_ty.intInfo(mod);
1216 const info_b = dest_ty.intInfo(mod);1221 const info_b = dest_ty.intInfo(mod);
12171222
...@@ -1275,7 +1280,8 @@ fn airIntFromBool(self: *Self, inst: Air.Inst.Index) !void {...@@ -1275,7 +1280,8 @@ fn airIntFromBool(self: *Self, inst: Air.Inst.Index) !void {
12751280
1276fn airNot(self: *Self, inst: Air.Inst.Index) !void {1281fn airNot(self: *Self, inst: Air.Inst.Index) !void {
1277 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;1282 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
1278 const mod = self.bin_file.comp.module.?;1283 const pt = self.pt;
1284 const mod = pt.zcu;
1279 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {1285 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
1280 const operand_bind: ReadArg.Bind = .{ .inst = ty_op.operand };1286 const operand_bind: ReadArg.Bind = .{ .inst = ty_op.operand };
1281 const operand_ty = self.typeOf(ty_op.operand);1287 const operand_ty = self.typeOf(ty_op.operand);
...@@ -1371,7 +1377,8 @@ fn minMax(...@@ -1371,7 +1377,8 @@ fn minMax(
1371 rhs_ty: Type,1377 rhs_ty: Type,
1372 maybe_inst: ?Air.Inst.Index,1378 maybe_inst: ?Air.Inst.Index,
1373) !MCValue {1379) !MCValue {
1374 const mod = self.bin_file.comp.module.?;1380 const pt = self.pt;
1381 const mod = pt.zcu;
1375 switch (lhs_ty.zigTypeTag(mod)) {1382 switch (lhs_ty.zigTypeTag(mod)) {
1376 .Float => return self.fail("TODO ARM min/max on floats", .{}),1383 .Float => return self.fail("TODO ARM min/max on floats", .{}),
1377 .Vector => return self.fail("TODO ARM min/max on vectors", .{}),1384 .Vector => return self.fail("TODO ARM min/max on vectors", .{}),
...@@ -1580,7 +1587,8 @@ fn airOverflow(self: *Self, inst: Air.Inst.Index) !void {...@@ -1580,7 +1587,8 @@ fn airOverflow(self: *Self, inst: Air.Inst.Index) !void {
1580 const tag = self.air.instructions.items(.tag)[@intFromEnum(inst)];1587 const tag = self.air.instructions.items(.tag)[@intFromEnum(inst)];
1581 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;1588 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
1582 const extra = self.air.extraData(Air.Bin, ty_pl.payload).data;1589 const extra = self.air.extraData(Air.Bin, ty_pl.payload).data;
1583 const mod = self.bin_file.comp.module.?;1590 const pt = self.pt;
1591 const mod = pt.zcu;
1584 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {1592 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
1585 const lhs_bind: ReadArg.Bind = .{ .inst = extra.lhs };1593 const lhs_bind: ReadArg.Bind = .{ .inst = extra.lhs };
1586 const rhs_bind: ReadArg.Bind = .{ .inst = extra.rhs };1594 const rhs_bind: ReadArg.Bind = .{ .inst = extra.rhs };
...@@ -1588,9 +1596,9 @@ fn airOverflow(self: *Self, inst: Air.Inst.Index) !void {...@@ -1588,9 +1596,9 @@ fn airOverflow(self: *Self, inst: Air.Inst.Index) !void {
1588 const rhs_ty = self.typeOf(extra.rhs);1596 const rhs_ty = self.typeOf(extra.rhs);
15891597
1590 const tuple_ty = self.typeOfIndex(inst);1598 const tuple_ty = self.typeOfIndex(inst);
1591 const tuple_size: u32 = @intCast(tuple_ty.abiSize(mod));1599 const tuple_size: u32 = @intCast(tuple_ty.abiSize(pt));
1592 const tuple_align = tuple_ty.abiAlignment(mod);1600 const tuple_align = tuple_ty.abiAlignment(pt);
1593 const overflow_bit_offset: u32 = @intCast(tuple_ty.structFieldOffset(1, mod));1601 const overflow_bit_offset: u32 = @intCast(tuple_ty.structFieldOffset(1, pt));
15941602
1595 switch (lhs_ty.zigTypeTag(mod)) {1603 switch (lhs_ty.zigTypeTag(mod)) {
1596 .Vector => return self.fail("TODO implement add_with_overflow/sub_with_overflow for vectors", .{}),1604 .Vector => return self.fail("TODO implement add_with_overflow/sub_with_overflow for vectors", .{}),
...@@ -1693,7 +1701,8 @@ fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) !void {...@@ -1693,7 +1701,8 @@ fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) !void {
1693 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;1701 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
1694 const extra = self.air.extraData(Air.Bin, ty_pl.payload).data;1702 const extra = self.air.extraData(Air.Bin, ty_pl.payload).data;
1695 if (self.liveness.isUnused(inst)) return self.finishAir(inst, .dead, .{ extra.lhs, extra.rhs, .none });1703 if (self.liveness.isUnused(inst)) return self.finishAir(inst, .dead, .{ extra.lhs, extra.rhs, .none });
1696 const mod = self.bin_file.comp.module.?;1704 const pt = self.pt;
1705 const mod = pt.zcu;
1697 const result: MCValue = result: {1706 const result: MCValue = result: {
1698 const lhs_bind: ReadArg.Bind = .{ .inst = extra.lhs };1707 const lhs_bind: ReadArg.Bind = .{ .inst = extra.lhs };
1699 const rhs_bind: ReadArg.Bind = .{ .inst = extra.rhs };1708 const rhs_bind: ReadArg.Bind = .{ .inst = extra.rhs };
...@@ -1701,9 +1710,9 @@ fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) !void {...@@ -1701,9 +1710,9 @@ fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) !void {
1701 const rhs_ty = self.typeOf(extra.rhs);1710 const rhs_ty = self.typeOf(extra.rhs);
17021711
1703 const tuple_ty = self.typeOfIndex(inst);1712 const tuple_ty = self.typeOfIndex(inst);
1704 const tuple_size: u32 = @intCast(tuple_ty.abiSize(mod));1713 const tuple_size: u32 = @intCast(tuple_ty.abiSize(pt));
1705 const tuple_align = tuple_ty.abiAlignment(mod);1714 const tuple_align = tuple_ty.abiAlignment(pt);
1706 const overflow_bit_offset: u32 = @intCast(tuple_ty.structFieldOffset(1, mod));1715 const overflow_bit_offset: u32 = @intCast(tuple_ty.structFieldOffset(1, pt));
17071716
1708 switch (lhs_ty.zigTypeTag(mod)) {1717 switch (lhs_ty.zigTypeTag(mod)) {
1709 .Vector => return self.fail("TODO implement mul_with_overflow for vectors", .{}),1718 .Vector => return self.fail("TODO implement mul_with_overflow for vectors", .{}),
...@@ -1857,15 +1866,16 @@ fn airShlWithOverflow(self: *Self, inst: Air.Inst.Index) !void {...@@ -1857,15 +1866,16 @@ fn airShlWithOverflow(self: *Self, inst: Air.Inst.Index) !void {
1857 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;1866 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
1858 const extra = self.air.extraData(Air.Bin, ty_pl.payload).data;1867 const extra = self.air.extraData(Air.Bin, ty_pl.payload).data;
1859 if (self.liveness.isUnused(inst)) return self.finishAir(inst, .dead, .{ extra.lhs, extra.rhs, .none });1868 if (self.liveness.isUnused(inst)) return self.finishAir(inst, .dead, .{ extra.lhs, extra.rhs, .none });
1860 const mod = self.bin_file.comp.module.?;1869 const pt = self.pt;
1870 const mod = pt.zcu;
1861 const result: MCValue = result: {1871 const result: MCValue = result: {
1862 const lhs_ty = self.typeOf(extra.lhs);1872 const lhs_ty = self.typeOf(extra.lhs);
1863 const rhs_ty = self.typeOf(extra.rhs);1873 const rhs_ty = self.typeOf(extra.rhs);
18641874
1865 const tuple_ty = self.typeOfIndex(inst);1875 const tuple_ty = self.typeOfIndex(inst);
1866 const tuple_size: u32 = @intCast(tuple_ty.abiSize(mod));1876 const tuple_size: u32 = @intCast(tuple_ty.abiSize(pt));
1867 const tuple_align = tuple_ty.abiAlignment(mod);1877 const tuple_align = tuple_ty.abiAlignment(pt);
1868 const overflow_bit_offset: u32 = @intCast(tuple_ty.structFieldOffset(1, mod));1878 const overflow_bit_offset: u32 = @intCast(tuple_ty.structFieldOffset(1, pt));
18691879
1870 switch (lhs_ty.zigTypeTag(mod)) {1880 switch (lhs_ty.zigTypeTag(mod)) {
1871 .Vector => return self.fail("TODO implement shl_with_overflow for vectors", .{}),1881 .Vector => return self.fail("TODO implement shl_with_overflow for vectors", .{}),
...@@ -2013,11 +2023,11 @@ fn airOptionalPayloadPtrSet(self: *Self, inst: Air.Inst.Index) !void {...@@ -2013,11 +2023,11 @@ fn airOptionalPayloadPtrSet(self: *Self, inst: Air.Inst.Index) !void {
2013}2023}
20142024
2015fn airWrapOptional(self: *Self, inst: Air.Inst.Index) !void {2025fn airWrapOptional(self: *Self, inst: Air.Inst.Index) !void {
2016 const mod = self.bin_file.comp.module.?;2026 const pt = self.pt;
2017 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;2027 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
2018 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {2028 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
2019 const optional_ty = self.typeOfIndex(inst);2029 const optional_ty = self.typeOfIndex(inst);
2020 const abi_size: u32 = @intCast(optional_ty.abiSize(mod));2030 const abi_size: u32 = @intCast(optional_ty.abiSize(pt));
20212031
2022 // Optional with a zero-bit payload type is just a boolean true2032 // Optional with a zero-bit payload type is just a boolean true
2023 if (abi_size == 1) {2033 if (abi_size == 1) {
...@@ -2036,17 +2046,18 @@ fn errUnionErr(...@@ -2036,17 +2046,18 @@ fn errUnionErr(
2036 error_union_ty: Type,2046 error_union_ty: Type,
2037 maybe_inst: ?Air.Inst.Index,2047 maybe_inst: ?Air.Inst.Index,
2038) !MCValue {2048) !MCValue {
2039 const mod = self.bin_file.comp.module.?;2049 const pt = self.pt;
2050 const mod = pt.zcu;
2040 const err_ty = error_union_ty.errorUnionSet(mod);2051 const err_ty = error_union_ty.errorUnionSet(mod);
2041 const payload_ty = error_union_ty.errorUnionPayload(mod);2052 const payload_ty = error_union_ty.errorUnionPayload(mod);
2042 if (err_ty.errorSetIsEmpty(mod)) {2053 if (err_ty.errorSetIsEmpty(mod)) {
2043 return MCValue{ .immediate = 0 };2054 return MCValue{ .immediate = 0 };
2044 }2055 }
2045 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) {2056 if (!payload_ty.hasRuntimeBitsIgnoreComptime(pt)) {
2046 return try error_union_bind.resolveToMcv(self);2057 return try error_union_bind.resolveToMcv(self);
2047 }2058 }
20482059
2049 const err_offset: u32 = @intCast(errUnionErrorOffset(payload_ty, mod));2060 const err_offset: u32 = @intCast(errUnionErrorOffset(payload_ty, pt));
2050 switch (try error_union_bind.resolveToMcv(self)) {2061 switch (try error_union_bind.resolveToMcv(self)) {
2051 .register => {2062 .register => {
2052 var operand_reg: Register = undefined;2063 var operand_reg: Register = undefined;
...@@ -2068,7 +2079,7 @@ fn errUnionErr(...@@ -2068,7 +2079,7 @@ fn errUnionErr(
2068 );2079 );
20692080
2070 const err_bit_offset = err_offset * 8;2081 const err_bit_offset = err_offset * 8;
2071 const err_bit_size: u32 = @intCast(err_ty.abiSize(mod) * 8);2082 const err_bit_size: u32 = @intCast(err_ty.abiSize(pt) * 8);
20722083
2073 _ = try self.addInst(.{2084 _ = try self.addInst(.{
2074 .tag = .ubfx, // errors are unsigned integers2085 .tag = .ubfx, // errors are unsigned integers
...@@ -2113,17 +2124,18 @@ fn errUnionPayload(...@@ -2113,17 +2124,18 @@ fn errUnionPayload(
2113 error_union_ty: Type,2124 error_union_ty: Type,
2114 maybe_inst: ?Air.Inst.Index,2125 maybe_inst: ?Air.Inst.Index,
2115) !MCValue {2126) !MCValue {
2116 const mod = self.bin_file.comp.module.?;2127 const pt = self.pt;
2128 const mod = pt.zcu;
2117 const err_ty = error_union_ty.errorUnionSet(mod);2129 const err_ty = error_union_ty.errorUnionSet(mod);
2118 const payload_ty = error_union_ty.errorUnionPayload(mod);2130 const payload_ty = error_union_ty.errorUnionPayload(mod);
2119 if (err_ty.errorSetIsEmpty(mod)) {2131 if (err_ty.errorSetIsEmpty(mod)) {
2120 return try error_union_bind.resolveToMcv(self);2132 return try error_union_bind.resolveToMcv(self);
2121 }2133 }
2122 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) {2134 if (!payload_ty.hasRuntimeBitsIgnoreComptime(pt)) {
2123 return MCValue.none;2135 return MCValue.none;
2124 }2136 }
21252137
2126 const payload_offset: u32 = @intCast(errUnionPayloadOffset(payload_ty, mod));2138 const payload_offset: u32 = @intCast(errUnionPayloadOffset(payload_ty, pt));
2127 switch (try error_union_bind.resolveToMcv(self)) {2139 switch (try error_union_bind.resolveToMcv(self)) {
2128 .register => {2140 .register => {
2129 var operand_reg: Register = undefined;2141 var operand_reg: Register = undefined;
...@@ -2145,7 +2157,7 @@ fn errUnionPayload(...@@ -2145,7 +2157,7 @@ fn errUnionPayload(
2145 );2157 );
21462158
2147 const payload_bit_offset = payload_offset * 8;2159 const payload_bit_offset = payload_offset * 8;
2148 const payload_bit_size: u32 = @intCast(payload_ty.abiSize(mod) * 8);2160 const payload_bit_size: u32 = @intCast(payload_ty.abiSize(pt) * 8);
21492161
2150 _ = try self.addInst(.{2162 _ = try self.addInst(.{
2151 .tag = if (payload_ty.isSignedInt(mod)) Mir.Inst.Tag.sbfx else .ubfx,2163 .tag = if (payload_ty.isSignedInt(mod)) Mir.Inst.Tag.sbfx else .ubfx,
...@@ -2223,20 +2235,21 @@ fn airSaveErrReturnTraceIndex(self: *Self, inst: Air.Inst.Index) !void {...@@ -2223,20 +2235,21 @@ fn airSaveErrReturnTraceIndex(self: *Self, inst: Air.Inst.Index) !void {
22232235
2224/// T to E!T2236/// T to E!T
2225fn airWrapErrUnionPayload(self: *Self, inst: Air.Inst.Index) !void {2237fn airWrapErrUnionPayload(self: *Self, inst: Air.Inst.Index) !void {
2226 const mod = self.bin_file.comp.module.?;2238 const pt = self.pt;
2239 const mod = pt.zcu;
2227 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;2240 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
2228 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {2241 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
2229 const error_union_ty = ty_op.ty.toType();2242 const error_union_ty = ty_op.ty.toType();
2230 const error_ty = error_union_ty.errorUnionSet(mod);2243 const error_ty = error_union_ty.errorUnionSet(mod);
2231 const payload_ty = error_union_ty.errorUnionPayload(mod);2244 const payload_ty = error_union_ty.errorUnionPayload(mod);
2232 const operand = try self.resolveInst(ty_op.operand);2245 const operand = try self.resolveInst(ty_op.operand);
2233 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) break :result operand;2246 if (!payload_ty.hasRuntimeBitsIgnoreComptime(pt)) break :result operand;
22342247
2235 const abi_size: u32 = @intCast(error_union_ty.abiSize(mod));2248 const abi_size: u32 = @intCast(error_union_ty.abiSize(pt));
2236 const abi_align = error_union_ty.abiAlignment(mod);2249 const abi_align = error_union_ty.abiAlignment(pt);
2237 const stack_offset: u32 = @intCast(try self.allocMem(abi_size, abi_align, inst));2250 const stack_offset: u32 = @intCast(try self.allocMem(abi_size, abi_align, inst));
2238 const payload_off = errUnionPayloadOffset(payload_ty, mod);2251 const payload_off = errUnionPayloadOffset(payload_ty, pt);
2239 const err_off = errUnionErrorOffset(payload_ty, mod);2252 const err_off = errUnionErrorOffset(payload_ty, pt);
2240 try self.genSetStack(payload_ty, stack_offset - @as(u32, @intCast(payload_off)), operand);2253 try self.genSetStack(payload_ty, stack_offset - @as(u32, @intCast(payload_off)), operand);
2241 try self.genSetStack(error_ty, stack_offset - @as(u32, @intCast(err_off)), .{ .immediate = 0 });2254 try self.genSetStack(error_ty, stack_offset - @as(u32, @intCast(err_off)), .{ .immediate = 0 });
22422255
...@@ -2247,20 +2260,21 @@ fn airWrapErrUnionPayload(self: *Self, inst: Air.Inst.Index) !void {...@@ -2247,20 +2260,21 @@ fn airWrapErrUnionPayload(self: *Self, inst: Air.Inst.Index) !void {
22472260
2248/// E to E!T2261/// E to E!T
2249fn airWrapErrUnionErr(self: *Self, inst: Air.Inst.Index) !void {2262fn airWrapErrUnionErr(self: *Self, inst: Air.Inst.Index) !void {
2250 const mod = self.bin_file.comp.module.?;2263 const pt = self.pt;
2264 const mod = pt.zcu;
2251 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;2265 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
2252 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {2266 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
2253 const error_union_ty = ty_op.ty.toType();2267 const error_union_ty = ty_op.ty.toType();
2254 const error_ty = error_union_ty.errorUnionSet(mod);2268 const error_ty = error_union_ty.errorUnionSet(mod);
2255 const payload_ty = error_union_ty.errorUnionPayload(mod);2269 const payload_ty = error_union_ty.errorUnionPayload(mod);
2256 const operand = try self.resolveInst(ty_op.operand);2270 const operand = try self.resolveInst(ty_op.operand);
2257 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) break :result operand;2271 if (!payload_ty.hasRuntimeBitsIgnoreComptime(pt)) break :result operand;
22582272
2259 const abi_size: u32 = @intCast(error_union_ty.abiSize(mod));2273 const abi_size: u32 = @intCast(error_union_ty.abiSize(pt));
2260 const abi_align = error_union_ty.abiAlignment(mod);2274 const abi_align = error_union_ty.abiAlignment(pt);
2261 const stack_offset: u32 = @intCast(try self.allocMem(abi_size, abi_align, inst));2275 const stack_offset: u32 = @intCast(try self.allocMem(abi_size, abi_align, inst));
2262 const payload_off = errUnionPayloadOffset(payload_ty, mod);2276 const payload_off = errUnionPayloadOffset(payload_ty, pt);
2263 const err_off = errUnionErrorOffset(payload_ty, mod);2277 const err_off = errUnionErrorOffset(payload_ty, pt);
2264 try self.genSetStack(error_ty, stack_offset - @as(u32, @intCast(err_off)), operand);2278 try self.genSetStack(error_ty, stack_offset - @as(u32, @intCast(err_off)), operand);
2265 try self.genSetStack(payload_ty, stack_offset - @as(u32, @intCast(payload_off)), .undef);2279 try self.genSetStack(payload_ty, stack_offset - @as(u32, @intCast(payload_off)), .undef);
22662280
...@@ -2364,9 +2378,10 @@ fn ptrElemVal(...@@ -2364,9 +2378,10 @@ fn ptrElemVal(
2364 ptr_ty: Type,2378 ptr_ty: Type,
2365 maybe_inst: ?Air.Inst.Index,2379 maybe_inst: ?Air.Inst.Index,
2366) !MCValue {2380) !MCValue {
2367 const mod = self.bin_file.comp.module.?;2381 const pt = self.pt;
2382 const mod = pt.zcu;
2368 const elem_ty = ptr_ty.childType(mod);2383 const elem_ty = ptr_ty.childType(mod);
2369 const elem_size: u32 = @intCast(elem_ty.abiSize(mod));2384 const elem_size: u32 = @intCast(elem_ty.abiSize(pt));
23702385
2371 switch (elem_size) {2386 switch (elem_size) {
2372 1, 4 => {2387 1, 4 => {
...@@ -2423,7 +2438,8 @@ fn ptrElemVal(...@@ -2423,7 +2438,8 @@ fn ptrElemVal(
2423}2438}
24242439
2425fn airSliceElemVal(self: *Self, inst: Air.Inst.Index) !void {2440fn airSliceElemVal(self: *Self, inst: Air.Inst.Index) !void {
2426 const mod = self.bin_file.comp.module.?;2441 const pt = self.pt;
2442 const mod = pt.zcu;
2427 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;2443 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
2428 const slice_ty = self.typeOf(bin_op.lhs);2444 const slice_ty = self.typeOf(bin_op.lhs);
2429 const result: MCValue = if (!slice_ty.isVolatilePtr(mod) and self.liveness.isUnused(inst)) .dead else result: {2445 const result: MCValue = if (!slice_ty.isVolatilePtr(mod) and self.liveness.isUnused(inst)) .dead else result: {
...@@ -2466,7 +2482,8 @@ fn arrayElemVal(...@@ -2466,7 +2482,8 @@ fn arrayElemVal(
2466 array_ty: Type,2482 array_ty: Type,
2467 maybe_inst: ?Air.Inst.Index,2483 maybe_inst: ?Air.Inst.Index,
2468) InnerError!MCValue {2484) InnerError!MCValue {
2469 const mod = self.bin_file.comp.module.?;2485 const pt = self.pt;
2486 const mod = pt.zcu;
2470 const elem_ty = array_ty.childType(mod);2487 const elem_ty = array_ty.childType(mod);
24712488
2472 const mcv = try array_bind.resolveToMcv(self);2489 const mcv = try array_bind.resolveToMcv(self);
...@@ -2501,7 +2518,7 @@ fn arrayElemVal(...@@ -2501,7 +2518,7 @@ fn arrayElemVal(
25012518
2502 const base_bind: ReadArg.Bind = .{ .mcv = ptr_to_mcv };2519 const base_bind: ReadArg.Bind = .{ .mcv = ptr_to_mcv };
25032520
2504 const ptr_ty = try mod.singleMutPtrType(elem_ty);2521 const ptr_ty = try pt.singleMutPtrType(elem_ty);
25052522
2506 return try self.ptrElemVal(base_bind, index_bind, ptr_ty, maybe_inst);2523 return try self.ptrElemVal(base_bind, index_bind, ptr_ty, maybe_inst);
2507 },2524 },
...@@ -2522,7 +2539,8 @@ fn airArrayElemVal(self: *Self, inst: Air.Inst.Index) !void {...@@ -2522,7 +2539,8 @@ fn airArrayElemVal(self: *Self, inst: Air.Inst.Index) !void {
2522}2539}
25232540
2524fn airPtrElemVal(self: *Self, inst: Air.Inst.Index) !void {2541fn airPtrElemVal(self: *Self, inst: Air.Inst.Index) !void {
2525 const mod = self.bin_file.comp.module.?;2542 const pt = self.pt;
2543 const mod = pt.zcu;
2526 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;2544 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
2527 const ptr_ty = self.typeOf(bin_op.lhs);2545 const ptr_ty = self.typeOf(bin_op.lhs);
2528 const result: MCValue = if (!ptr_ty.isVolatilePtr(mod) and self.liveness.isUnused(inst)) .dead else result: {2546 const result: MCValue = if (!ptr_ty.isVolatilePtr(mod) and self.liveness.isUnused(inst)) .dead else result: {
...@@ -2656,9 +2674,10 @@ fn reuseOperand(...@@ -2656,9 +2674,10 @@ fn reuseOperand(
2656}2674}
26572675
2658fn load(self: *Self, dst_mcv: MCValue, ptr: MCValue, ptr_ty: Type) InnerError!void {2676fn load(self: *Self, dst_mcv: MCValue, ptr: MCValue, ptr_ty: Type) InnerError!void {
2659 const mod = self.bin_file.comp.module.?;2677 const pt = self.pt;
2678 const mod = pt.zcu;
2660 const elem_ty = ptr_ty.childType(mod);2679 const elem_ty = ptr_ty.childType(mod);
2661 const elem_size: u32 = @intCast(elem_ty.abiSize(mod));2680 const elem_size: u32 = @intCast(elem_ty.abiSize(pt));
26622681
2663 switch (ptr) {2682 switch (ptr) {
2664 .none => unreachable,2683 .none => unreachable,
...@@ -2733,11 +2752,12 @@ fn load(self: *Self, dst_mcv: MCValue, ptr: MCValue, ptr_ty: Type) InnerError!vo...@@ -2733,11 +2752,12 @@ fn load(self: *Self, dst_mcv: MCValue, ptr: MCValue, ptr_ty: Type) InnerError!vo
2733}2752}
27342753
2735fn airLoad(self: *Self, inst: Air.Inst.Index) !void {2754fn airLoad(self: *Self, inst: Air.Inst.Index) !void {
2736 const mod = self.bin_file.comp.module.?;2755 const pt = self.pt;
2756 const mod = pt.zcu;
2737 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;2757 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
2738 const elem_ty = self.typeOfIndex(inst);2758 const elem_ty = self.typeOfIndex(inst);
2739 const result: MCValue = result: {2759 const result: MCValue = result: {
2740 if (!elem_ty.hasRuntimeBits(mod))2760 if (!elem_ty.hasRuntimeBits(pt))
2741 break :result MCValue.none;2761 break :result MCValue.none;
27422762
2743 const ptr = try self.resolveInst(ty_op.operand);2763 const ptr = try self.resolveInst(ty_op.operand);
...@@ -2746,7 +2766,7 @@ fn airLoad(self: *Self, inst: Air.Inst.Index) !void {...@@ -2746,7 +2766,7 @@ fn airLoad(self: *Self, inst: Air.Inst.Index) !void {
2746 break :result MCValue.dead;2766 break :result MCValue.dead;
27472767
2748 const dest_mcv: MCValue = blk: {2768 const dest_mcv: MCValue = blk: {
2749 const ptr_fits_dest = elem_ty.abiSize(mod) <= 4;2769 const ptr_fits_dest = elem_ty.abiSize(pt) <= 4;
2750 if (ptr_fits_dest and self.reuseOperand(inst, ty_op.operand, 0, ptr)) {2770 if (ptr_fits_dest and self.reuseOperand(inst, ty_op.operand, 0, ptr)) {
2751 // The MCValue that holds the pointer can be re-used as the value.2771 // The MCValue that holds the pointer can be re-used as the value.
2752 break :blk ptr;2772 break :blk ptr;
...@@ -2762,8 +2782,8 @@ fn airLoad(self: *Self, inst: Air.Inst.Index) !void {...@@ -2762,8 +2782,8 @@ fn airLoad(self: *Self, inst: Air.Inst.Index) !void {
2762}2782}
27632783
2764fn store(self: *Self, ptr: MCValue, value: MCValue, ptr_ty: Type, value_ty: Type) InnerError!void {2784fn store(self: *Self, ptr: MCValue, value: MCValue, ptr_ty: Type, value_ty: Type) InnerError!void {
2765 const mod = self.bin_file.comp.module.?;2785 const pt = self.pt;
2766 const elem_size: u32 = @intCast(value_ty.abiSize(mod));2786 const elem_size: u32 = @intCast(value_ty.abiSize(pt));
27672787
2768 switch (ptr) {2788 switch (ptr) {
2769 .none => unreachable,2789 .none => unreachable,
...@@ -2882,11 +2902,12 @@ fn airStructFieldPtrIndex(self: *Self, inst: Air.Inst.Index, index: u8) !void {...@@ -2882,11 +2902,12 @@ fn airStructFieldPtrIndex(self: *Self, inst: Air.Inst.Index, index: u8) !void {
28822902
2883fn structFieldPtr(self: *Self, inst: Air.Inst.Index, operand: Air.Inst.Ref, index: u32) !MCValue {2903fn structFieldPtr(self: *Self, inst: Air.Inst.Index, operand: Air.Inst.Ref, index: u32) !MCValue {
2884 return if (self.liveness.isUnused(inst)) .dead else result: {2904 return if (self.liveness.isUnused(inst)) .dead else result: {
2885 const mod = self.bin_file.comp.module.?;2905 const pt = self.pt;
2906 const mod = pt.zcu;
2886 const mcv = try self.resolveInst(operand);2907 const mcv = try self.resolveInst(operand);
2887 const ptr_ty = self.typeOf(operand);2908 const ptr_ty = self.typeOf(operand);
2888 const struct_ty = ptr_ty.childType(mod);2909 const struct_ty = ptr_ty.childType(mod);
2889 const struct_field_offset: u32 = @intCast(struct_ty.structFieldOffset(index, mod));2910 const struct_field_offset: u32 = @intCast(struct_ty.structFieldOffset(index, pt));
2890 switch (mcv) {2911 switch (mcv) {
2891 .ptr_stack_offset => |off| {2912 .ptr_stack_offset => |off| {
2892 break :result MCValue{ .ptr_stack_offset = off - struct_field_offset };2913 break :result MCValue{ .ptr_stack_offset = off - struct_field_offset };
...@@ -2906,11 +2927,12 @@ fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void {...@@ -2906,11 +2927,12 @@ fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void {
2906 const extra = self.air.extraData(Air.StructField, ty_pl.payload).data;2927 const extra = self.air.extraData(Air.StructField, ty_pl.payload).data;
2907 const operand = extra.struct_operand;2928 const operand = extra.struct_operand;
2908 const index = extra.field_index;2929 const index = extra.field_index;
2909 const mod = self.bin_file.comp.module.?;2930 const pt = self.pt;
2931 const mod = pt.zcu;
2910 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {2932 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
2911 const mcv = try self.resolveInst(operand);2933 const mcv = try self.resolveInst(operand);
2912 const struct_ty = self.typeOf(operand);2934 const struct_ty = self.typeOf(operand);
2913 const struct_field_offset: u32 = @intCast(struct_ty.structFieldOffset(index, mod));2935 const struct_field_offset: u32 = @intCast(struct_ty.structFieldOffset(index, pt));
2914 const struct_field_ty = struct_ty.structFieldType(index, mod);2936 const struct_field_ty = struct_ty.structFieldType(index, mod);
29152937
2916 switch (mcv) {2938 switch (mcv) {
...@@ -2974,7 +2996,7 @@ fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void {...@@ -2974,7 +2996,7 @@ fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void {
2974 );2996 );
29752997
2976 const field_bit_offset = struct_field_offset * 8;2998 const field_bit_offset = struct_field_offset * 8;
2977 const field_bit_size: u32 = @intCast(struct_field_ty.abiSize(mod) * 8);2999 const field_bit_size: u32 = @intCast(struct_field_ty.abiSize(pt) * 8);
29783000
2979 _ = try self.addInst(.{3001 _ = try self.addInst(.{
2980 .tag = if (struct_field_ty.isSignedInt(mod)) Mir.Inst.Tag.sbfx else .ubfx,3002 .tag = if (struct_field_ty.isSignedInt(mod)) Mir.Inst.Tag.sbfx else .ubfx,
...@@ -2996,7 +3018,8 @@ fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void {...@@ -2996,7 +3018,8 @@ fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void {
2996}3018}
29973019
2998fn airFieldParentPtr(self: *Self, inst: Air.Inst.Index) !void {3020fn airFieldParentPtr(self: *Self, inst: Air.Inst.Index) !void {
2999 const mod = self.bin_file.comp.module.?;3021 const pt = self.pt;
3022 const mod = pt.zcu;
3000 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;3023 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
3001 const extra = self.air.extraData(Air.FieldParentPtr, ty_pl.payload).data;3024 const extra = self.air.extraData(Air.FieldParentPtr, ty_pl.payload).data;
3002 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {3025 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
...@@ -3007,7 +3030,7 @@ fn airFieldParentPtr(self: *Self, inst: Air.Inst.Index) !void {...@@ -3007,7 +3030,7 @@ fn airFieldParentPtr(self: *Self, inst: Air.Inst.Index) !void {
3007 return self.fail("TODO implement @fieldParentPtr codegen for unions", .{});3030 return self.fail("TODO implement @fieldParentPtr codegen for unions", .{});
3008 }3031 }
30093032
3010 const struct_field_offset: u32 = @intCast(struct_ty.structFieldOffset(extra.field_index, mod));3033 const struct_field_offset: u32 = @intCast(struct_ty.structFieldOffset(extra.field_index, pt));
3011 switch (field_ptr) {3034 switch (field_ptr) {
3012 .ptr_stack_offset => |off| {3035 .ptr_stack_offset => |off| {
3013 break :result MCValue{ .ptr_stack_offset = off + struct_field_offset };3036 break :result MCValue{ .ptr_stack_offset = off + struct_field_offset };
...@@ -3390,7 +3413,8 @@ fn addSub(...@@ -3390,7 +3413,8 @@ fn addSub(
3390 rhs_ty: Type,3413 rhs_ty: Type,
3391 maybe_inst: ?Air.Inst.Index,3414 maybe_inst: ?Air.Inst.Index,
3392) InnerError!MCValue {3415) InnerError!MCValue {
3393 const mod = self.bin_file.comp.module.?;3416 const pt = self.pt;
3417 const mod = pt.zcu;
3394 switch (lhs_ty.zigTypeTag(mod)) {3418 switch (lhs_ty.zigTypeTag(mod)) {
3395 .Float => return self.fail("TODO ARM binary operations on floats", .{}),3419 .Float => return self.fail("TODO ARM binary operations on floats", .{}),
3396 .Vector => return self.fail("TODO ARM binary operations on vectors", .{}),3420 .Vector => return self.fail("TODO ARM binary operations on vectors", .{}),
...@@ -3446,7 +3470,8 @@ fn mul(...@@ -3446,7 +3470,8 @@ fn mul(
3446 rhs_ty: Type,3470 rhs_ty: Type,
3447 maybe_inst: ?Air.Inst.Index,3471 maybe_inst: ?Air.Inst.Index,
3448) InnerError!MCValue {3472) InnerError!MCValue {
3449 const mod = self.bin_file.comp.module.?;3473 const pt = self.pt;
3474 const mod = pt.zcu;
3450 switch (lhs_ty.zigTypeTag(mod)) {3475 switch (lhs_ty.zigTypeTag(mod)) {
3451 .Float => return self.fail("TODO ARM binary operations on floats", .{}),3476 .Float => return self.fail("TODO ARM binary operations on floats", .{}),
3452 .Vector => return self.fail("TODO ARM binary operations on vectors", .{}),3477 .Vector => return self.fail("TODO ARM binary operations on vectors", .{}),
...@@ -3479,7 +3504,8 @@ fn divFloat(...@@ -3479,7 +3504,8 @@ fn divFloat(
3479 _ = rhs_ty;3504 _ = rhs_ty;
3480 _ = maybe_inst;3505 _ = maybe_inst;
34813506
3482 const mod = self.bin_file.comp.module.?;3507 const pt = self.pt;
3508 const mod = pt.zcu;
3483 switch (lhs_ty.zigTypeTag(mod)) {3509 switch (lhs_ty.zigTypeTag(mod)) {
3484 .Float => return self.fail("TODO ARM binary operations on floats", .{}),3510 .Float => return self.fail("TODO ARM binary operations on floats", .{}),
3485 .Vector => return self.fail("TODO ARM binary operations on vectors", .{}),3511 .Vector => return self.fail("TODO ARM binary operations on vectors", .{}),
...@@ -3495,7 +3521,8 @@ fn divTrunc(...@@ -3495,7 +3521,8 @@ fn divTrunc(
3495 rhs_ty: Type,3521 rhs_ty: Type,
3496 maybe_inst: ?Air.Inst.Index,3522 maybe_inst: ?Air.Inst.Index,
3497) InnerError!MCValue {3523) InnerError!MCValue {
3498 const mod = self.bin_file.comp.module.?;3524 const pt = self.pt;
3525 const mod = pt.zcu;
3499 switch (lhs_ty.zigTypeTag(mod)) {3526 switch (lhs_ty.zigTypeTag(mod)) {
3500 .Float => return self.fail("TODO ARM binary operations on floats", .{}),3527 .Float => return self.fail("TODO ARM binary operations on floats", .{}),
3501 .Vector => return self.fail("TODO ARM binary operations on vectors", .{}),3528 .Vector => return self.fail("TODO ARM binary operations on vectors", .{}),
...@@ -3538,7 +3565,8 @@ fn divFloor(...@@ -3538,7 +3565,8 @@ fn divFloor(
3538 rhs_ty: Type,3565 rhs_ty: Type,
3539 maybe_inst: ?Air.Inst.Index,3566 maybe_inst: ?Air.Inst.Index,
3540) InnerError!MCValue {3567) InnerError!MCValue {
3541 const mod = self.bin_file.comp.module.?;3568 const pt = self.pt;
3569 const mod = pt.zcu;
3542 switch (lhs_ty.zigTypeTag(mod)) {3570 switch (lhs_ty.zigTypeTag(mod)) {
3543 .Float => return self.fail("TODO ARM binary operations on floats", .{}),3571 .Float => return self.fail("TODO ARM binary operations on floats", .{}),
3544 .Vector => return self.fail("TODO ARM binary operations on vectors", .{}),3572 .Vector => return self.fail("TODO ARM binary operations on vectors", .{}),
...@@ -3586,7 +3614,8 @@ fn divExact(...@@ -3586,7 +3614,8 @@ fn divExact(
3586 _ = rhs_ty;3614 _ = rhs_ty;
3587 _ = maybe_inst;3615 _ = maybe_inst;
35883616
3589 const mod = self.bin_file.comp.module.?;3617 const pt = self.pt;
3618 const mod = pt.zcu;
3590 switch (lhs_ty.zigTypeTag(mod)) {3619 switch (lhs_ty.zigTypeTag(mod)) {
3591 .Float => return self.fail("TODO ARM binary operations on floats", .{}),3620 .Float => return self.fail("TODO ARM binary operations on floats", .{}),
3592 .Vector => return self.fail("TODO ARM binary operations on vectors", .{}),3621 .Vector => return self.fail("TODO ARM binary operations on vectors", .{}),
...@@ -3603,7 +3632,8 @@ fn rem(...@@ -3603,7 +3632,8 @@ fn rem(
3603 rhs_ty: Type,3632 rhs_ty: Type,
3604 maybe_inst: ?Air.Inst.Index,3633 maybe_inst: ?Air.Inst.Index,
3605) InnerError!MCValue {3634) InnerError!MCValue {
3606 const mod = self.bin_file.comp.module.?;3635 const pt = self.pt;
3636 const mod = pt.zcu;
3607 switch (lhs_ty.zigTypeTag(mod)) {3637 switch (lhs_ty.zigTypeTag(mod)) {
3608 .Float => return self.fail("TODO ARM binary operations on floats", .{}),3638 .Float => return self.fail("TODO ARM binary operations on floats", .{}),
3609 .Vector => return self.fail("TODO ARM binary operations on vectors", .{}),3639 .Vector => return self.fail("TODO ARM binary operations on vectors", .{}),
...@@ -3672,7 +3702,8 @@ fn modulo(...@@ -3672,7 +3702,8 @@ fn modulo(
3672 _ = rhs_ty;3702 _ = rhs_ty;
3673 _ = maybe_inst;3703 _ = maybe_inst;
36743704
3675 const mod = self.bin_file.comp.module.?;3705 const pt = self.pt;
3706 const mod = pt.zcu;
3676 switch (lhs_ty.zigTypeTag(mod)) {3707 switch (lhs_ty.zigTypeTag(mod)) {
3677 .Float => return self.fail("TODO ARM binary operations on floats", .{}),3708 .Float => return self.fail("TODO ARM binary operations on floats", .{}),
3678 .Vector => return self.fail("TODO ARM binary operations on vectors", .{}),3709 .Vector => return self.fail("TODO ARM binary operations on vectors", .{}),
...@@ -3690,7 +3721,8 @@ fn wrappingArithmetic(...@@ -3690,7 +3721,8 @@ fn wrappingArithmetic(
3690 rhs_ty: Type,3721 rhs_ty: Type,
3691 maybe_inst: ?Air.Inst.Index,3722 maybe_inst: ?Air.Inst.Index,
3692) InnerError!MCValue {3723) InnerError!MCValue {
3693 const mod = self.bin_file.comp.module.?;3724 const pt = self.pt;
3725 const mod = pt.zcu;
3694 switch (lhs_ty.zigTypeTag(mod)) {3726 switch (lhs_ty.zigTypeTag(mod)) {
3695 .Vector => return self.fail("TODO ARM binary operations on vectors", .{}),3727 .Vector => return self.fail("TODO ARM binary operations on vectors", .{}),
3696 .Int => {3728 .Int => {
...@@ -3728,7 +3760,8 @@ fn bitwise(...@@ -3728,7 +3760,8 @@ fn bitwise(
3728 rhs_ty: Type,3760 rhs_ty: Type,
3729 maybe_inst: ?Air.Inst.Index,3761 maybe_inst: ?Air.Inst.Index,
3730) InnerError!MCValue {3762) InnerError!MCValue {
3731 const mod = self.bin_file.comp.module.?;3763 const pt = self.pt;
3764 const mod = pt.zcu;
3732 switch (lhs_ty.zigTypeTag(mod)) {3765 switch (lhs_ty.zigTypeTag(mod)) {
3733 .Vector => return self.fail("TODO ARM binary operations on vectors", .{}),3766 .Vector => return self.fail("TODO ARM binary operations on vectors", .{}),
3734 .Int => {3767 .Int => {
...@@ -3773,7 +3806,8 @@ fn shiftExact(...@@ -3773,7 +3806,8 @@ fn shiftExact(
3773 rhs_ty: Type,3806 rhs_ty: Type,
3774 maybe_inst: ?Air.Inst.Index,3807 maybe_inst: ?Air.Inst.Index,
3775) InnerError!MCValue {3808) InnerError!MCValue {
3776 const mod = self.bin_file.comp.module.?;3809 const pt = self.pt;
3810 const mod = pt.zcu;
3777 switch (lhs_ty.zigTypeTag(mod)) {3811 switch (lhs_ty.zigTypeTag(mod)) {
3778 .Vector => return self.fail("TODO ARM binary operations on vectors", .{}),3812 .Vector => return self.fail("TODO ARM binary operations on vectors", .{}),
3779 .Int => {3813 .Int => {
...@@ -3812,7 +3846,8 @@ fn shiftNormal(...@@ -3812,7 +3846,8 @@ fn shiftNormal(
3812 rhs_ty: Type,3846 rhs_ty: Type,
3813 maybe_inst: ?Air.Inst.Index,3847 maybe_inst: ?Air.Inst.Index,
3814) InnerError!MCValue {3848) InnerError!MCValue {
3815 const mod = self.bin_file.comp.module.?;3849 const pt = self.pt;
3850 const mod = pt.zcu;
3816 switch (lhs_ty.zigTypeTag(mod)) {3851 switch (lhs_ty.zigTypeTag(mod)) {
3817 .Vector => return self.fail("TODO ARM binary operations on vectors", .{}),3852 .Vector => return self.fail("TODO ARM binary operations on vectors", .{}),
3818 .Int => {3853 .Int => {
...@@ -3855,7 +3890,8 @@ fn booleanOp(...@@ -3855,7 +3890,8 @@ fn booleanOp(
3855 rhs_ty: Type,3890 rhs_ty: Type,
3856 maybe_inst: ?Air.Inst.Index,3891 maybe_inst: ?Air.Inst.Index,
3857) InnerError!MCValue {3892) InnerError!MCValue {
3858 const mod = self.bin_file.comp.module.?;3893 const pt = self.pt;
3894 const mod = pt.zcu;
3859 switch (lhs_ty.zigTypeTag(mod)) {3895 switch (lhs_ty.zigTypeTag(mod)) {
3860 .Bool => {3896 .Bool => {
3861 const lhs_immediate = try lhs_bind.resolveToImmediate(self);3897 const lhs_immediate = try lhs_bind.resolveToImmediate(self);
...@@ -3889,7 +3925,8 @@ fn ptrArithmetic(...@@ -3889,7 +3925,8 @@ fn ptrArithmetic(
3889 rhs_ty: Type,3925 rhs_ty: Type,
3890 maybe_inst: ?Air.Inst.Index,3926 maybe_inst: ?Air.Inst.Index,
3891) InnerError!MCValue {3927) InnerError!MCValue {
3892 const mod = self.bin_file.comp.module.?;3928 const pt = self.pt;
3929 const mod = pt.zcu;
3893 switch (lhs_ty.zigTypeTag(mod)) {3930 switch (lhs_ty.zigTypeTag(mod)) {
3894 .Pointer => {3931 .Pointer => {
3895 assert(rhs_ty.eql(Type.usize, mod));3932 assert(rhs_ty.eql(Type.usize, mod));
...@@ -3899,7 +3936,7 @@ fn ptrArithmetic(...@@ -3899,7 +3936,7 @@ fn ptrArithmetic(
3899 .One => ptr_ty.childType(mod).childType(mod), // ptr to array, so get array element type3936 .One => ptr_ty.childType(mod).childType(mod), // ptr to array, so get array element type
3900 else => ptr_ty.childType(mod),3937 else => ptr_ty.childType(mod),
3901 };3938 };
3902 const elem_size: u32 = @intCast(elem_ty.abiSize(mod));3939 const elem_size: u32 = @intCast(elem_ty.abiSize(pt));
39033940
3904 const base_tag: Air.Inst.Tag = switch (tag) {3941 const base_tag: Air.Inst.Tag = switch (tag) {
3905 .ptr_add => .add,3942 .ptr_add => .add,
...@@ -3926,8 +3963,9 @@ fn ptrArithmetic(...@@ -3926,8 +3963,9 @@ fn ptrArithmetic(
3926}3963}
39273964
3928fn genLdrRegister(self: *Self, dest_reg: Register, addr_reg: Register, ty: Type) !void {3965fn genLdrRegister(self: *Self, dest_reg: Register, addr_reg: Register, ty: Type) !void {
3929 const mod = self.bin_file.comp.module.?;3966 const pt = self.pt;
3930 const abi_size = ty.abiSize(mod);3967 const mod = pt.zcu;
3968 const abi_size = ty.abiSize(pt);
39313969
3932 const tag: Mir.Inst.Tag = switch (abi_size) {3970 const tag: Mir.Inst.Tag = switch (abi_size) {
3933 1 => if (ty.isSignedInt(mod)) Mir.Inst.Tag.ldrsb else .ldrb,3971 1 => if (ty.isSignedInt(mod)) Mir.Inst.Tag.ldrsb else .ldrb,
...@@ -3961,8 +3999,8 @@ fn genLdrRegister(self: *Self, dest_reg: Register, addr_reg: Register, ty: Type)...@@ -3961,8 +3999,8 @@ fn genLdrRegister(self: *Self, dest_reg: Register, addr_reg: Register, ty: Type)
3961}3999}
39624000
3963fn genStrRegister(self: *Self, source_reg: Register, addr_reg: Register, ty: Type) !void {4001fn genStrRegister(self: *Self, source_reg: Register, addr_reg: Register, ty: Type) !void {
3964 const mod = self.bin_file.comp.module.?;4002 const pt = self.pt;
3965 const abi_size = ty.abiSize(mod);4003 const abi_size = ty.abiSize(pt);
39664004
3967 const tag: Mir.Inst.Tag = switch (abi_size) {4005 const tag: Mir.Inst.Tag = switch (abi_size) {
3968 1 => .strb,4006 1 => .strb,
...@@ -4168,7 +4206,8 @@ fn airArg(self: *Self, inst: Air.Inst.Index) !void {...@@ -4168,7 +4206,8 @@ fn airArg(self: *Self, inst: Air.Inst.Index) !void {
4168 while (self.args[arg_index] == .none) arg_index += 1;4206 while (self.args[arg_index] == .none) arg_index += 1;
4169 self.arg_index = arg_index + 1;4207 self.arg_index = arg_index + 1;
41704208
4171 const mod = self.bin_file.comp.module.?;4209 const pt = self.pt;
4210 const mod = pt.zcu;
4172 const ty = self.typeOfIndex(inst);4211 const ty = self.typeOfIndex(inst);
4173 const tag = self.air.instructions.items(.tag)[@intFromEnum(inst)];4212 const tag = self.air.instructions.items(.tag)[@intFromEnum(inst)];
4174 const src_index = self.air.instructions.items(.data)[@intFromEnum(inst)].arg.src_index;4213 const src_index = self.air.instructions.items(.data)[@intFromEnum(inst)].arg.src_index;
...@@ -4223,7 +4262,8 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier...@@ -4223,7 +4262,8 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier
4223 const extra = self.air.extraData(Air.Call, pl_op.payload);4262 const extra = self.air.extraData(Air.Call, pl_op.payload);
4224 const args: []const Air.Inst.Ref = @ptrCast(self.air.extra[extra.end..][0..extra.data.args_len]);4263 const args: []const Air.Inst.Ref = @ptrCast(self.air.extra[extra.end..][0..extra.data.args_len]);
4225 const ty = self.typeOf(callee);4264 const ty = self.typeOf(callee);
4226 const mod = self.bin_file.comp.module.?;4265 const pt = self.pt;
4266 const mod = pt.zcu;
42274267
4228 const fn_ty = switch (ty.zigTypeTag(mod)) {4268 const fn_ty = switch (ty.zigTypeTag(mod)) {
4229 .Fn => ty,4269 .Fn => ty,
...@@ -4253,11 +4293,11 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier...@@ -4253,11 +4293,11 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier
4253 const r0_lock: ?RegisterLock = if (info.return_value == .stack_offset) blk: {4293 const r0_lock: ?RegisterLock = if (info.return_value == .stack_offset) blk: {
4254 log.debug("airCall: return by reference", .{});4294 log.debug("airCall: return by reference", .{});
4255 const ret_ty = fn_ty.fnReturnType(mod);4295 const ret_ty = fn_ty.fnReturnType(mod);
4256 const ret_abi_size: u32 = @intCast(ret_ty.abiSize(mod));4296 const ret_abi_size: u32 = @intCast(ret_ty.abiSize(pt));
4257 const ret_abi_align = ret_ty.abiAlignment(mod);4297 const ret_abi_align = ret_ty.abiAlignment(pt);
4258 const stack_offset = try self.allocMem(ret_abi_size, ret_abi_align, inst);4298 const stack_offset = try self.allocMem(ret_abi_size, ret_abi_align, inst);
42594299
4260 const ptr_ty = try mod.singleMutPtrType(ret_ty);4300 const ptr_ty = try pt.singleMutPtrType(ret_ty);
4261 try self.register_manager.getReg(.r0, null);4301 try self.register_manager.getReg(.r0, null);
4262 try self.genSetReg(ptr_ty, .r0, .{ .ptr_stack_offset = stack_offset });4302 try self.genSetReg(ptr_ty, .r0, .{ .ptr_stack_offset = stack_offset });
42634303
...@@ -4293,7 +4333,7 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier...@@ -4293,7 +4333,7 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier
42934333
4294 // Due to incremental compilation, how function calls are generated depends4334 // Due to incremental compilation, how function calls are generated depends
4295 // on linking.4335 // on linking.
4296 if (try self.air.value(callee, mod)) |func_value| {4336 if (try self.air.value(callee, pt)) |func_value| {
4297 if (func_value.getFunction(mod)) |func| {4337 if (func_value.getFunction(mod)) |func| {
4298 if (self.bin_file.cast(link.File.Elf)) |elf_file| {4338 if (self.bin_file.cast(link.File.Elf)) |elf_file| {
4299 const sym_index = try elf_file.zigObjectPtr().?.getOrCreateMetadataForDecl(elf_file, func.owner_decl);4339 const sym_index = try elf_file.zigObjectPtr().?.getOrCreateMetadataForDecl(elf_file, func.owner_decl);
...@@ -4374,7 +4414,8 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier...@@ -4374,7 +4414,8 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier
4374}4414}
43754415
4376fn airRet(self: *Self, inst: Air.Inst.Index) !void {4416fn airRet(self: *Self, inst: Air.Inst.Index) !void {
4377 const mod = self.bin_file.comp.module.?;4417 const pt = self.pt;
4418 const mod = pt.zcu;
4378 const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op;4419 const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op;
4379 const operand = try self.resolveInst(un_op);4420 const operand = try self.resolveInst(un_op);
4380 const ret_ty = self.fn_type.fnReturnType(mod);4421 const ret_ty = self.fn_type.fnReturnType(mod);
...@@ -4393,7 +4434,7 @@ fn airRet(self: *Self, inst: Air.Inst.Index) !void {...@@ -4393,7 +4434,7 @@ fn airRet(self: *Self, inst: Air.Inst.Index) !void {
4393 //4434 //
4394 // self.ret_mcv is an address to where this function4435 // self.ret_mcv is an address to where this function
4395 // should store its result into4436 // should store its result into
4396 const ptr_ty = try mod.singleMutPtrType(ret_ty);4437 const ptr_ty = try pt.singleMutPtrType(ret_ty);
4397 try self.store(self.ret_mcv, operand, ptr_ty, ret_ty);4438 try self.store(self.ret_mcv, operand, ptr_ty, ret_ty);
4398 },4439 },
4399 else => unreachable, // invalid return result4440 else => unreachable, // invalid return result
...@@ -4406,7 +4447,8 @@ fn airRet(self: *Self, inst: Air.Inst.Index) !void {...@@ -4406,7 +4447,8 @@ fn airRet(self: *Self, inst: Air.Inst.Index) !void {
4406}4447}
44074448
4408fn airRetLoad(self: *Self, inst: Air.Inst.Index) !void {4449fn airRetLoad(self: *Self, inst: Air.Inst.Index) !void {
4409 const mod = self.bin_file.comp.module.?;4450 const pt = self.pt;
4451 const mod = pt.zcu;
4410 const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op;4452 const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op;
4411 const ptr = try self.resolveInst(un_op);4453 const ptr = try self.resolveInst(un_op);
4412 const ptr_ty = self.typeOf(un_op);4454 const ptr_ty = self.typeOf(un_op);
...@@ -4430,8 +4472,8 @@ fn airRetLoad(self: *Self, inst: Air.Inst.Index) !void {...@@ -4430,8 +4472,8 @@ fn airRetLoad(self: *Self, inst: Air.Inst.Index) !void {
4430 // location.4472 // location.
4431 const op_inst = un_op.toIndex().?;4473 const op_inst = un_op.toIndex().?;
4432 if (self.air.instructions.items(.tag)[@intFromEnum(op_inst)] != .ret_ptr) {4474 if (self.air.instructions.items(.tag)[@intFromEnum(op_inst)] != .ret_ptr) {
4433 const abi_size: u32 = @intCast(ret_ty.abiSize(mod));4475 const abi_size: u32 = @intCast(ret_ty.abiSize(pt));
4434 const abi_align = ret_ty.abiAlignment(mod);4476 const abi_align = ret_ty.abiAlignment(pt);
44354477
4436 const offset = try self.allocMem(abi_size, abi_align, null);4478 const offset = try self.allocMem(abi_size, abi_align, null);
44374479
...@@ -4467,11 +4509,12 @@ fn cmp(...@@ -4467,11 +4509,12 @@ fn cmp(
4467 lhs_ty: Type,4509 lhs_ty: Type,
4468 op: math.CompareOperator,4510 op: math.CompareOperator,
4469) !MCValue {4511) !MCValue {
4470 const mod = self.bin_file.comp.module.?;4512 const pt = self.pt;
4513 const mod = pt.zcu;
4471 const int_ty = switch (lhs_ty.zigTypeTag(mod)) {4514 const int_ty = switch (lhs_ty.zigTypeTag(mod)) {
4472 .Optional => blk: {4515 .Optional => blk: {
4473 const payload_ty = lhs_ty.optionalChild(mod);4516 const payload_ty = lhs_ty.optionalChild(mod);
4474 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) {4517 if (!payload_ty.hasRuntimeBitsIgnoreComptime(pt)) {
4475 break :blk Type.u1;4518 break :blk Type.u1;
4476 } else if (lhs_ty.isPtrLikeOptional(mod)) {4519 } else if (lhs_ty.isPtrLikeOptional(mod)) {
4477 break :blk Type.usize;4520 break :blk Type.usize;
...@@ -4573,7 +4616,8 @@ fn airDbgStmt(self: *Self, inst: Air.Inst.Index) !void {...@@ -4573,7 +4616,8 @@ fn airDbgStmt(self: *Self, inst: Air.Inst.Index) !void {
4573}4616}
45744617
4575fn airDbgInlineBlock(self: *Self, inst: Air.Inst.Index) !void {4618fn airDbgInlineBlock(self: *Self, inst: Air.Inst.Index) !void {
4576 const mod = self.bin_file.comp.module.?;4619 const pt = self.pt;
4620 const mod = pt.zcu;
4577 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;4621 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
4578 const extra = self.air.extraData(Air.DbgInlineBlock, ty_pl.payload);4622 const extra = self.air.extraData(Air.DbgInlineBlock, ty_pl.payload);
4579 const func = mod.funcInfo(extra.data.func);4623 const func = mod.funcInfo(extra.data.func);
...@@ -4785,9 +4829,10 @@ fn isNull(...@@ -4785,9 +4829,10 @@ fn isNull(
4785 operand_bind: ReadArg.Bind,4829 operand_bind: ReadArg.Bind,
4786 operand_ty: Type,4830 operand_ty: Type,
4787) !MCValue {4831) !MCValue {
4788 const mod = self.bin_file.comp.module.?;4832 const pt = self.pt;
4833 const mod = pt.zcu;
4789 if (operand_ty.isPtrLikeOptional(mod)) {4834 if (operand_ty.isPtrLikeOptional(mod)) {
4790 assert(operand_ty.abiSize(mod) == 4);4835 assert(operand_ty.abiSize(pt) == 4);
47914836
4792 const imm_bind: ReadArg.Bind = .{ .mcv = .{ .immediate = 0 } };4837 const imm_bind: ReadArg.Bind = .{ .mcv = .{ .immediate = 0 } };
4793 return self.cmp(operand_bind, imm_bind, Type.usize, .eq);4838 return self.cmp(operand_bind, imm_bind, Type.usize, .eq);
...@@ -4819,7 +4864,8 @@ fn airIsNull(self: *Self, inst: Air.Inst.Index) !void {...@@ -4819,7 +4864,8 @@ fn airIsNull(self: *Self, inst: Air.Inst.Index) !void {
4819}4864}
48204865
4821fn airIsNullPtr(self: *Self, inst: Air.Inst.Index) !void {4866fn airIsNullPtr(self: *Self, inst: Air.Inst.Index) !void {
4822 const mod = self.bin_file.comp.module.?;4867 const pt = self.pt;
4868 const mod = pt.zcu;
4823 const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op;4869 const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op;
4824 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {4870 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
4825 const operand_ptr = try self.resolveInst(un_op);4871 const operand_ptr = try self.resolveInst(un_op);
...@@ -4846,7 +4892,8 @@ fn airIsNonNull(self: *Self, inst: Air.Inst.Index) !void {...@@ -4846,7 +4892,8 @@ fn airIsNonNull(self: *Self, inst: Air.Inst.Index) !void {
4846}4892}
48474893
4848fn airIsNonNullPtr(self: *Self, inst: Air.Inst.Index) !void {4894fn airIsNonNullPtr(self: *Self, inst: Air.Inst.Index) !void {
4849 const mod = self.bin_file.comp.module.?;4895 const pt = self.pt;
4896 const mod = pt.zcu;
4850 const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op;4897 const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op;
4851 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {4898 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
4852 const operand_ptr = try self.resolveInst(un_op);4899 const operand_ptr = try self.resolveInst(un_op);
...@@ -4866,7 +4913,8 @@ fn isErr(...@@ -4866,7 +4913,8 @@ fn isErr(
4866 error_union_bind: ReadArg.Bind,4913 error_union_bind: ReadArg.Bind,
4867 error_union_ty: Type,4914 error_union_ty: Type,
4868) !MCValue {4915) !MCValue {
4869 const mod = self.bin_file.comp.module.?;4916 const pt = self.pt;
4917 const mod = pt.zcu;
4870 const error_type = error_union_ty.errorUnionSet(mod);4918 const error_type = error_union_ty.errorUnionSet(mod);
48714919
4872 if (error_type.errorSetIsEmpty(mod)) {4920 if (error_type.errorSetIsEmpty(mod)) {
...@@ -4908,7 +4956,8 @@ fn airIsErr(self: *Self, inst: Air.Inst.Index) !void {...@@ -4908,7 +4956,8 @@ fn airIsErr(self: *Self, inst: Air.Inst.Index) !void {
4908}4956}
49094957
4910fn airIsErrPtr(self: *Self, inst: Air.Inst.Index) !void {4958fn airIsErrPtr(self: *Self, inst: Air.Inst.Index) !void {
4911 const mod = self.bin_file.comp.module.?;4959 const pt = self.pt;
4960 const mod = pt.zcu;
4912 const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op;4961 const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op;
4913 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {4962 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
4914 const operand_ptr = try self.resolveInst(un_op);4963 const operand_ptr = try self.resolveInst(un_op);
...@@ -4935,7 +4984,8 @@ fn airIsNonErr(self: *Self, inst: Air.Inst.Index) !void {...@@ -4935,7 +4984,8 @@ fn airIsNonErr(self: *Self, inst: Air.Inst.Index) !void {
4935}4984}
49364985
4937fn airIsNonErrPtr(self: *Self, inst: Air.Inst.Index) !void {4986fn airIsNonErrPtr(self: *Self, inst: Air.Inst.Index) !void {
4938 const mod = self.bin_file.comp.module.?;4987 const pt = self.pt;
4988 const mod = pt.zcu;
4939 const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op;4989 const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op;
4940 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {4990 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
4941 const operand_ptr = try self.resolveInst(un_op);4991 const operand_ptr = try self.resolveInst(un_op);
...@@ -5154,10 +5204,10 @@ fn airBr(self: *Self, inst: Air.Inst.Index) !void {...@@ -5154,10 +5204,10 @@ fn airBr(self: *Self, inst: Air.Inst.Index) !void {
5154}5204}
51555205
5156fn br(self: *Self, block: Air.Inst.Index, operand: Air.Inst.Ref) !void {5206fn br(self: *Self, block: Air.Inst.Index, operand: Air.Inst.Ref) !void {
5157 const mod = self.bin_file.comp.module.?;5207 const pt = self.pt;
5158 const block_data = self.blocks.getPtr(block).?;5208 const block_data = self.blocks.getPtr(block).?;
51595209
5160 if (self.typeOf(operand).hasRuntimeBits(mod)) {5210 if (self.typeOf(operand).hasRuntimeBits(pt)) {
5161 const operand_mcv = try self.resolveInst(operand);5211 const operand_mcv = try self.resolveInst(operand);
5162 const block_mcv = block_data.mcv;5212 const block_mcv = block_data.mcv;
5163 if (block_mcv == .none) {5213 if (block_mcv == .none) {
...@@ -5325,8 +5375,9 @@ fn setRegOrMem(self: *Self, ty: Type, loc: MCValue, val: MCValue) !void {...@@ -5325,8 +5375,9 @@ fn setRegOrMem(self: *Self, ty: Type, loc: MCValue, val: MCValue) !void {
5325}5375}
53265376
5327fn genSetStack(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) InnerError!void {5377fn genSetStack(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) InnerError!void {
5328 const mod = self.bin_file.comp.module.?;5378 const pt = self.pt;
5329 const abi_size: u32 = @intCast(ty.abiSize(mod));5379 const mod = pt.zcu;
5380 const abi_size: u32 = @intCast(ty.abiSize(pt));
5330 switch (mcv) {5381 switch (mcv) {
5331 .dead => unreachable,5382 .dead => unreachable,
5332 .unreach, .none => return, // Nothing to do.5383 .unreach, .none => return, // Nothing to do.
...@@ -5407,7 +5458,7 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) InnerErro...@@ -5407,7 +5458,7 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) InnerErro
5407 try self.genSetStack(wrapped_ty, stack_offset, .{ .register = reg });5458 try self.genSetStack(wrapped_ty, stack_offset, .{ .register = reg });
54085459
5409 const overflow_bit_ty = ty.structFieldType(1, mod);5460 const overflow_bit_ty = ty.structFieldType(1, mod);
5410 const overflow_bit_offset: u32 = @intCast(ty.structFieldOffset(1, mod));5461 const overflow_bit_offset: u32 = @intCast(ty.structFieldOffset(1, pt));
5411 const cond_reg = try self.register_manager.allocReg(null, gp);5462 const cond_reg = try self.register_manager.allocReg(null, gp);
54125463
5413 // C flag: movcs reg, #15464 // C flag: movcs reg, #1
...@@ -5445,7 +5496,7 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) InnerErro...@@ -5445,7 +5496,7 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) InnerErro
5445 const reg = try self.copyToTmpRegister(ty, mcv);5496 const reg = try self.copyToTmpRegister(ty, mcv);
5446 return self.genSetStack(ty, stack_offset, MCValue{ .register = reg });5497 return self.genSetStack(ty, stack_offset, MCValue{ .register = reg });
5447 } else {5498 } else {
5448 const ptr_ty = try mod.singleMutPtrType(ty);5499 const ptr_ty = try pt.singleMutPtrType(ty);
54495500
5450 // TODO call extern memcpy5501 // TODO call extern memcpy
5451 const regs = try self.register_manager.allocRegs(5, .{ null, null, null, null, null }, gp);5502 const regs = try self.register_manager.allocRegs(5, .{ null, null, null, null, null }, gp);
...@@ -5487,7 +5538,8 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) InnerErro...@@ -5487,7 +5538,8 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) InnerErro
5487}5538}
54885539
5489fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void {5540fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void {
5490 const mod = self.bin_file.comp.module.?;5541 const pt = self.pt;
5542 const mod = pt.zcu;
5491 switch (mcv) {5543 switch (mcv) {
5492 .dead => unreachable,5544 .dead => unreachable,
5493 .unreach, .none => return, // Nothing to do.5545 .unreach, .none => return, // Nothing to do.
...@@ -5662,7 +5714,7 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void...@@ -5662,7 +5714,7 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void
5662 },5714 },
5663 .stack_offset => |off| {5715 .stack_offset => |off| {
5664 // TODO: maybe addressing from sp instead of fp5716 // TODO: maybe addressing from sp instead of fp
5665 const abi_size: u32 = @intCast(ty.abiSize(mod));5717 const abi_size: u32 = @intCast(ty.abiSize(pt));
56665718
5667 const tag: Mir.Inst.Tag = switch (abi_size) {5719 const tag: Mir.Inst.Tag = switch (abi_size) {
5668 1 => if (ty.isSignedInt(mod)) Mir.Inst.Tag.ldrsb else .ldrb,5720 1 => if (ty.isSignedInt(mod)) Mir.Inst.Tag.ldrsb else .ldrb,
...@@ -5713,7 +5765,7 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void...@@ -5713,7 +5765,7 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void
5713 }5765 }
5714 },5766 },
5715 .stack_argument_offset => |off| {5767 .stack_argument_offset => |off| {
5716 const abi_size = ty.abiSize(mod);5768 const abi_size = ty.abiSize(pt);
57175769
5718 const tag: Mir.Inst.Tag = switch (abi_size) {5770 const tag: Mir.Inst.Tag = switch (abi_size) {
5719 1 => if (ty.isSignedInt(mod)) Mir.Inst.Tag.ldrsb_stack_argument else .ldrb_stack_argument,5771 1 => if (ty.isSignedInt(mod)) Mir.Inst.Tag.ldrsb_stack_argument else .ldrb_stack_argument,
...@@ -5734,8 +5786,8 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void...@@ -5734,8 +5786,8 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void
5734}5786}
57355787
5736fn genSetStackArgument(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) InnerError!void {5788fn genSetStackArgument(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) InnerError!void {
5737 const mod = self.bin_file.comp.module.?;5789 const pt = self.pt;
5738 const abi_size: u32 = @intCast(ty.abiSize(mod));5790 const abi_size: u32 = @intCast(ty.abiSize(pt));
5739 switch (mcv) {5791 switch (mcv) {
5740 .dead => unreachable,5792 .dead => unreachable,
5741 .none, .unreach => return,5793 .none, .unreach => return,
...@@ -5802,7 +5854,7 @@ fn genSetStackArgument(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) I...@@ -5802,7 +5854,7 @@ fn genSetStackArgument(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) I
5802 const reg = try self.copyToTmpRegister(ty, mcv);5854 const reg = try self.copyToTmpRegister(ty, mcv);
5803 return self.genSetStackArgument(ty, stack_offset, MCValue{ .register = reg });5855 return self.genSetStackArgument(ty, stack_offset, MCValue{ .register = reg });
5804 } else {5856 } else {
5805 const ptr_ty = try mod.singleMutPtrType(ty);5857 const ptr_ty = try pt.singleMutPtrType(ty);
58065858
5807 // TODO call extern memcpy5859 // TODO call extern memcpy
5808 const regs = try self.register_manager.allocRegs(5, .{ null, null, null, null, null }, gp);5860 const regs = try self.register_manager.allocRegs(5, .{ null, null, null, null, null }, gp);
...@@ -5890,7 +5942,8 @@ fn airBitCast(self: *Self, inst: Air.Inst.Index) !void {...@@ -5890,7 +5942,8 @@ fn airBitCast(self: *Self, inst: Air.Inst.Index) !void {
5890}5942}
58915943
5892fn airArrayToSlice(self: *Self, inst: Air.Inst.Index) !void {5944fn airArrayToSlice(self: *Self, inst: Air.Inst.Index) !void {
5893 const mod = self.bin_file.comp.module.?;5945 const pt = self.pt;
5946 const mod = pt.zcu;
5894 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;5947 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
5895 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {5948 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
5896 const ptr_ty = self.typeOf(ty_op.operand);5949 const ptr_ty = self.typeOf(ty_op.operand);
...@@ -6009,7 +6062,8 @@ fn airReduce(self: *Self, inst: Air.Inst.Index) !void {...@@ -6009,7 +6062,8 @@ fn airReduce(self: *Self, inst: Air.Inst.Index) !void {
6009}6062}
60106063
6011fn airAggregateInit(self: *Self, inst: Air.Inst.Index) !void {6064fn airAggregateInit(self: *Self, inst: Air.Inst.Index) !void {
6012 const mod = self.bin_file.comp.module.?;6065 const pt = self.pt;
6066 const mod = pt.zcu;
6013 const vector_ty = self.typeOfIndex(inst);6067 const vector_ty = self.typeOfIndex(inst);
6014 const len = vector_ty.vectorLen(mod);6068 const len = vector_ty.vectorLen(mod);
6015 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;6069 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
...@@ -6054,15 +6108,15 @@ fn airMulAdd(self: *Self, inst: Air.Inst.Index) !void {...@@ -6054,15 +6108,15 @@ fn airMulAdd(self: *Self, inst: Air.Inst.Index) !void {
6054}6108}
60556109
6056fn airTry(self: *Self, inst: Air.Inst.Index) !void {6110fn airTry(self: *Self, inst: Air.Inst.Index) !void {
6111 const pt = self.pt;
6057 const pl_op = self.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;6112 const pl_op = self.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;
6058 const extra = self.air.extraData(Air.Try, pl_op.payload);6113 const extra = self.air.extraData(Air.Try, pl_op.payload);
6059 const body: []const Air.Inst.Index = @ptrCast(self.air.extra[extra.end..][0..extra.data.body_len]);6114 const body: []const Air.Inst.Index = @ptrCast(self.air.extra[extra.end..][0..extra.data.body_len]);
6060 const result: MCValue = result: {6115 const result: MCValue = result: {
6061 const error_union_bind: ReadArg.Bind = .{ .inst = pl_op.operand };6116 const error_union_bind: ReadArg.Bind = .{ .inst = pl_op.operand };
6062 const error_union_ty = self.typeOf(pl_op.operand);6117 const error_union_ty = self.typeOf(pl_op.operand);
6063 const mod = self.bin_file.comp.module.?;6118 const error_union_size: u32 = @intCast(error_union_ty.abiSize(pt));
6064 const error_union_size: u32 = @intCast(error_union_ty.abiSize(mod));6119 const error_union_align = error_union_ty.abiAlignment(pt);
6065 const error_union_align = error_union_ty.abiAlignment(mod);
60666120
6067 // The error union will die in the body. However, we need the6121 // The error union will die in the body. However, we need the
6068 // error union after the body in order to extract the payload6122 // error union after the body in order to extract the payload
...@@ -6091,14 +6145,15 @@ fn airTryPtr(self: *Self, inst: Air.Inst.Index) !void {...@@ -6091,14 +6145,15 @@ fn airTryPtr(self: *Self, inst: Air.Inst.Index) !void {
6091}6145}
60926146
6093fn resolveInst(self: *Self, inst: Air.Inst.Ref) InnerError!MCValue {6147fn resolveInst(self: *Self, inst: Air.Inst.Ref) InnerError!MCValue {
6094 const mod = self.bin_file.comp.module.?;6148 const pt = self.pt;
6149 const mod = pt.zcu;
60956150
6096 // If the type has no codegen bits, no need to store it.6151 // If the type has no codegen bits, no need to store it.
6097 const inst_ty = self.typeOf(inst);6152 const inst_ty = self.typeOf(inst);
6098 if (!inst_ty.hasRuntimeBitsIgnoreComptime(mod) and !inst_ty.isError(mod))6153 if (!inst_ty.hasRuntimeBitsIgnoreComptime(pt) and !inst_ty.isError(mod))
6099 return MCValue{ .none = {} };6154 return MCValue{ .none = {} };
61006155
6101 const inst_index = inst.toIndex() orelse return self.genTypedValue((try self.air.value(inst, mod)).?);6156 const inst_index = inst.toIndex() orelse return self.genTypedValue((try self.air.value(inst, pt)).?);
61026157
6103 return self.getResolvedInstValue(inst_index);6158 return self.getResolvedInstValue(inst_index);
6104}6159}
...@@ -6116,12 +6171,13 @@ fn getResolvedInstValue(self: *Self, inst: Air.Inst.Index) MCValue {...@@ -6116,12 +6171,13 @@ fn getResolvedInstValue(self: *Self, inst: Air.Inst.Index) MCValue {
6116}6171}
61176172
6118fn genTypedValue(self: *Self, val: Value) InnerError!MCValue {6173fn genTypedValue(self: *Self, val: Value) InnerError!MCValue {
6119 const mod = self.bin_file.comp.module.?;6174 const pt = self.pt;
6120 const mcv: MCValue = switch (try codegen.genTypedValue(6175 const mcv: MCValue = switch (try codegen.genTypedValue(
6121 self.bin_file,6176 self.bin_file,
6177 pt,
6122 self.src_loc,6178 self.src_loc,
6123 val,6179 val,
6124 mod.funcOwnerDeclIndex(self.func_index),6180 pt.zcu.funcOwnerDeclIndex(self.func_index),
6125 )) {6181 )) {
6126 .mcv => |mcv| switch (mcv) {6182 .mcv => |mcv| switch (mcv) {
6127 .none => .none,6183 .none => .none,
...@@ -6152,7 +6208,8 @@ const CallMCValues = struct {...@@ -6152,7 +6208,8 @@ const CallMCValues = struct {
61526208
6153/// Caller must call `CallMCValues.deinit`.6209/// Caller must call `CallMCValues.deinit`.
6154fn resolveCallingConventionValues(self: *Self, fn_ty: Type) !CallMCValues {6210fn resolveCallingConventionValues(self: *Self, fn_ty: Type) !CallMCValues {
6155 const mod = self.bin_file.comp.module.?;6211 const pt = self.pt;
6212 const mod = pt.zcu;
6156 const ip = &mod.intern_pool;6213 const ip = &mod.intern_pool;
6157 const fn_info = mod.typeToFunc(fn_ty).?;6214 const fn_info = mod.typeToFunc(fn_ty).?;
6158 const cc = fn_info.cc;6215 const cc = fn_info.cc;
...@@ -6182,10 +6239,10 @@ fn resolveCallingConventionValues(self: *Self, fn_ty: Type) !CallMCValues {...@@ -6182,10 +6239,10 @@ fn resolveCallingConventionValues(self: *Self, fn_ty: Type) !CallMCValues {
61826239
6183 if (ret_ty.zigTypeTag(mod) == .NoReturn) {6240 if (ret_ty.zigTypeTag(mod) == .NoReturn) {
6184 result.return_value = .{ .unreach = {} };6241 result.return_value = .{ .unreach = {} };
6185 } else if (!ret_ty.hasRuntimeBitsIgnoreComptime(mod)) {6242 } else if (!ret_ty.hasRuntimeBitsIgnoreComptime(pt)) {
6186 result.return_value = .{ .none = {} };6243 result.return_value = .{ .none = {} };
6187 } else {6244 } else {
6188 const ret_ty_size: u32 = @intCast(ret_ty.abiSize(mod));6245 const ret_ty_size: u32 = @intCast(ret_ty.abiSize(pt));
6189 // TODO handle cases where multiple registers are used6246 // TODO handle cases where multiple registers are used
6190 if (ret_ty_size <= 4) {6247 if (ret_ty_size <= 4) {
6191 result.return_value = .{ .register = c_abi_int_return_regs[0] };6248 result.return_value = .{ .register = c_abi_int_return_regs[0] };
...@@ -6200,10 +6257,10 @@ fn resolveCallingConventionValues(self: *Self, fn_ty: Type) !CallMCValues {...@@ -6200,10 +6257,10 @@ fn resolveCallingConventionValues(self: *Self, fn_ty: Type) !CallMCValues {
6200 }6257 }
62016258
6202 for (fn_info.param_types.get(ip), result.args) |ty, *result_arg| {6259 for (fn_info.param_types.get(ip), result.args) |ty, *result_arg| {
6203 if (Type.fromInterned(ty).abiAlignment(mod) == .@"8")6260 if (Type.fromInterned(ty).abiAlignment(pt) == .@"8")
6204 ncrn = std.mem.alignForward(usize, ncrn, 2);6261 ncrn = std.mem.alignForward(usize, ncrn, 2);
62056262
6206 const param_size: u32 = @intCast(Type.fromInterned(ty).abiSize(mod));6263 const param_size: u32 = @intCast(Type.fromInterned(ty).abiSize(pt));
6207 if (std.math.divCeil(u32, param_size, 4) catch unreachable <= 4 - ncrn) {6264 if (std.math.divCeil(u32, param_size, 4) catch unreachable <= 4 - ncrn) {
6208 if (param_size <= 4) {6265 if (param_size <= 4) {
6209 result_arg.* = .{ .register = c_abi_int_param_regs[ncrn] };6266 result_arg.* = .{ .register = c_abi_int_param_regs[ncrn] };
...@@ -6215,7 +6272,7 @@ fn resolveCallingConventionValues(self: *Self, fn_ty: Type) !CallMCValues {...@@ -6215,7 +6272,7 @@ fn resolveCallingConventionValues(self: *Self, fn_ty: Type) !CallMCValues {
6215 return self.fail("TODO MCValues split between registers and stack", .{});6272 return self.fail("TODO MCValues split between registers and stack", .{});
6216 } else {6273 } else {
6217 ncrn = 4;6274 ncrn = 4;
6218 if (Type.fromInterned(ty).abiAlignment(mod) == .@"8")6275 if (Type.fromInterned(ty).abiAlignment(pt) == .@"8")
6219 nsaa = std.mem.alignForward(u32, nsaa, 8);6276 nsaa = std.mem.alignForward(u32, nsaa, 8);
62206277
6221 result_arg.* = .{ .stack_argument_offset = nsaa };6278 result_arg.* = .{ .stack_argument_offset = nsaa };
...@@ -6229,10 +6286,10 @@ fn resolveCallingConventionValues(self: *Self, fn_ty: Type) !CallMCValues {...@@ -6229,10 +6286,10 @@ fn resolveCallingConventionValues(self: *Self, fn_ty: Type) !CallMCValues {
6229 .Unspecified => {6286 .Unspecified => {
6230 if (ret_ty.zigTypeTag(mod) == .NoReturn) {6287 if (ret_ty.zigTypeTag(mod) == .NoReturn) {
6231 result.return_value = .{ .unreach = {} };6288 result.return_value = .{ .unreach = {} };
6232 } else if (!ret_ty.hasRuntimeBitsIgnoreComptime(mod) and !ret_ty.isError(mod)) {6289 } else if (!ret_ty.hasRuntimeBitsIgnoreComptime(pt) and !ret_ty.isError(mod)) {
6233 result.return_value = .{ .none = {} };6290 result.return_value = .{ .none = {} };
6234 } else {6291 } else {
6235 const ret_ty_size: u32 = @intCast(ret_ty.abiSize(mod));6292 const ret_ty_size: u32 = @intCast(ret_ty.abiSize(pt));
6236 if (ret_ty_size == 0) {6293 if (ret_ty_size == 0) {
6237 assert(ret_ty.isError(mod));6294 assert(ret_ty.isError(mod));
6238 result.return_value = .{ .immediate = 0 };6295 result.return_value = .{ .immediate = 0 };
...@@ -6250,9 +6307,9 @@ fn resolveCallingConventionValues(self: *Self, fn_ty: Type) !CallMCValues {...@@ -6250,9 +6307,9 @@ fn resolveCallingConventionValues(self: *Self, fn_ty: Type) !CallMCValues {
6250 var stack_offset: u32 = 0;6307 var stack_offset: u32 = 0;
62516308
6252 for (fn_info.param_types.get(ip), result.args) |ty, *result_arg| {6309 for (fn_info.param_types.get(ip), result.args) |ty, *result_arg| {
6253 if (Type.fromInterned(ty).abiSize(mod) > 0) {6310 if (Type.fromInterned(ty).abiSize(pt) > 0) {
6254 const param_size: u32 = @intCast(Type.fromInterned(ty).abiSize(mod));6311 const param_size: u32 = @intCast(Type.fromInterned(ty).abiSize(pt));
6255 const param_alignment = Type.fromInterned(ty).abiAlignment(mod);6312 const param_alignment = Type.fromInterned(ty).abiAlignment(pt);
62566313
6257 stack_offset = @intCast(param_alignment.forward(stack_offset));6314 stack_offset = @intCast(param_alignment.forward(stack_offset));
6258 result_arg.* = .{ .stack_argument_offset = stack_offset };6315 result_arg.* = .{ .stack_argument_offset = stack_offset };
...@@ -6271,7 +6328,7 @@ fn resolveCallingConventionValues(self: *Self, fn_ty: Type) !CallMCValues {...@@ -6271,7 +6328,7 @@ fn resolveCallingConventionValues(self: *Self, fn_ty: Type) !CallMCValues {
6271 return result;6328 return result;
6272}6329}
62736330
6274/// TODO support scope overrides. Also note this logic is duplicated with `Module.wantSafety`.6331/// TODO support scope overrides. Also note this logic is duplicated with `Zcu.wantSafety`.
6275fn wantSafety(self: *Self) bool {6332fn wantSafety(self: *Self) bool {
6276 return switch (self.bin_file.comp.root_mod.optimize_mode) {6333 return switch (self.bin_file.comp.root_mod.optimize_mode) {
6277 .Debug => true,6334 .Debug => true,
...@@ -6305,11 +6362,9 @@ fn parseRegName(name: []const u8) ?Register {...@@ -6305,11 +6362,9 @@ fn parseRegName(name: []const u8) ?Register {
6305}6362}
63066363
6307fn typeOf(self: *Self, inst: Air.Inst.Ref) Type {6364fn typeOf(self: *Self, inst: Air.Inst.Ref) Type {
6308 const mod = self.bin_file.comp.module.?;6365 return self.air.typeOf(inst, &self.pt.zcu.intern_pool);
6309 return self.air.typeOf(inst, &mod.intern_pool);
6310}6366}
63116367
6312fn typeOfIndex(self: *Self, inst: Air.Inst.Index) Type {6368fn typeOfIndex(self: *Self, inst: Air.Inst.Index) Type {
6313 const mod = self.bin_file.comp.module.?;6369 return self.air.typeOfIndex(inst, &self.pt.zcu.intern_pool);
6314 return self.air.typeOfIndex(inst, &mod.intern_pool);
6315}6370}
src/arch/arm/Emit.zig+2-4
...@@ -9,10 +9,8 @@ const Mir = @import("Mir.zig");...@@ -9,10 +9,8 @@ const Mir = @import("Mir.zig");
9const bits = @import("bits.zig");9const bits = @import("bits.zig");
10const link = @import("../../link.zig");10const link = @import("../../link.zig");
11const Zcu = @import("../../Zcu.zig");11const Zcu = @import("../../Zcu.zig");
12/// Deprecated.
13const Module = Zcu;
14const Type = @import("../../Type.zig");12const Type = @import("../../Type.zig");
15const ErrorMsg = Module.ErrorMsg;13const ErrorMsg = Zcu.ErrorMsg;
16const Target = std.Target;14const Target = std.Target;
17const assert = std.debug.assert;15const assert = std.debug.assert;
18const Instruction = bits.Instruction;16const Instruction = bits.Instruction;
...@@ -26,7 +24,7 @@ bin_file: *link.File,...@@ -26,7 +24,7 @@ bin_file: *link.File,
26debug_output: DebugInfoOutput,24debug_output: DebugInfoOutput,
27target: *const std.Target,25target: *const std.Target,
28err_msg: ?*ErrorMsg = null,26err_msg: ?*ErrorMsg = null,
29src_loc: Module.LazySrcLoc,27src_loc: Zcu.LazySrcLoc,
30code: *std.ArrayList(u8),28code: *std.ArrayList(u8),
3129
32prev_di_line: u32,30prev_di_line: u32,
src/arch/arm/abi.zig+30-32
...@@ -5,8 +5,6 @@ const Register = bits.Register;...@@ -5,8 +5,6 @@ const Register = bits.Register;
5const RegisterManagerFn = @import("../../register_manager.zig").RegisterManager;5const RegisterManagerFn = @import("../../register_manager.zig").RegisterManager;
6const Type = @import("../../Type.zig");6const Type = @import("../../Type.zig");
7const Zcu = @import("../../Zcu.zig");7const Zcu = @import("../../Zcu.zig");
8/// Deprecated.
9const Module = Zcu;
108
11pub const Class = union(enum) {9pub const Class = union(enum) {
12 memory,10 memory,
...@@ -26,29 +24,29 @@ pub const Class = union(enum) {...@@ -26,29 +24,29 @@ pub const Class = union(enum) {
2624
27pub const Context = enum { ret, arg };25pub const Context = enum { ret, arg };
2826
29pub fn classifyType(ty: Type, mod: *Module, ctx: Context) Class {27pub fn classifyType(ty: Type, pt: Zcu.PerThread, ctx: Context) Class {
30 assert(ty.hasRuntimeBitsIgnoreComptime(mod));28 assert(ty.hasRuntimeBitsIgnoreComptime(pt));
3129
32 var maybe_float_bits: ?u16 = null;30 var maybe_float_bits: ?u16 = null;
33 const max_byval_size = 512;31 const max_byval_size = 512;
34 const ip = &mod.intern_pool;32 const ip = &pt.zcu.intern_pool;
35 switch (ty.zigTypeTag(mod)) {33 switch (ty.zigTypeTag(pt.zcu)) {
36 .Struct => {34 .Struct => {
37 const bit_size = ty.bitSize(mod);35 const bit_size = ty.bitSize(pt);
38 if (ty.containerLayout(mod) == .@"packed") {36 if (ty.containerLayout(pt.zcu) == .@"packed") {
39 if (bit_size > 64) return .memory;37 if (bit_size > 64) return .memory;
40 return .byval;38 return .byval;
41 }39 }
42 if (bit_size > max_byval_size) return .memory;40 if (bit_size > max_byval_size) return .memory;
43 const float_count = countFloats(ty, mod, &maybe_float_bits);41 const float_count = countFloats(ty, pt.zcu, &maybe_float_bits);
44 if (float_count <= byval_float_count) return .byval;42 if (float_count <= byval_float_count) return .byval;
4543
46 const fields = ty.structFieldCount(mod);44 const fields = ty.structFieldCount(pt.zcu);
47 var i: u32 = 0;45 var i: u32 = 0;
48 while (i < fields) : (i += 1) {46 while (i < fields) : (i += 1) {
49 const field_ty = ty.structFieldType(i, mod);47 const field_ty = ty.structFieldType(i, pt.zcu);
50 const field_alignment = ty.structFieldAlign(i, mod);48 const field_alignment = ty.structFieldAlign(i, pt);
51 const field_size = field_ty.bitSize(mod);49 const field_size = field_ty.bitSize(pt);
52 if (field_size > 32 or field_alignment.compare(.gt, .@"32")) {50 if (field_size > 32 or field_alignment.compare(.gt, .@"32")) {
53 return Class.arrSize(bit_size, 64);51 return Class.arrSize(bit_size, 64);
54 }52 }
...@@ -56,19 +54,19 @@ pub fn classifyType(ty: Type, mod: *Module, ctx: Context) Class {...@@ -56,19 +54,19 @@ pub fn classifyType(ty: Type, mod: *Module, ctx: Context) Class {
56 return Class.arrSize(bit_size, 32);54 return Class.arrSize(bit_size, 32);
57 },55 },
58 .Union => {56 .Union => {
59 const bit_size = ty.bitSize(mod);57 const bit_size = ty.bitSize(pt);
60 const union_obj = mod.typeToUnion(ty).?;58 const union_obj = pt.zcu.typeToUnion(ty).?;
61 if (union_obj.getLayout(ip) == .@"packed") {59 if (union_obj.getLayout(ip) == .@"packed") {
62 if (bit_size > 64) return .memory;60 if (bit_size > 64) return .memory;
63 return .byval;61 return .byval;
64 }62 }
65 if (bit_size > max_byval_size) return .memory;63 if (bit_size > max_byval_size) return .memory;
66 const float_count = countFloats(ty, mod, &maybe_float_bits);64 const float_count = countFloats(ty, pt.zcu, &maybe_float_bits);
67 if (float_count <= byval_float_count) return .byval;65 if (float_count <= byval_float_count) return .byval;
6866
69 for (union_obj.field_types.get(ip), 0..) |field_ty, field_index| {67 for (union_obj.field_types.get(ip), 0..) |field_ty, field_index| {
70 if (Type.fromInterned(field_ty).bitSize(mod) > 32 or68 if (Type.fromInterned(field_ty).bitSize(pt) > 32 or
71 mod.unionFieldNormalAlignment(union_obj, @intCast(field_index)).compare(.gt, .@"32"))69 pt.unionFieldNormalAlignment(union_obj, @intCast(field_index)).compare(.gt, .@"32"))
72 {70 {
73 return Class.arrSize(bit_size, 64);71 return Class.arrSize(bit_size, 64);
74 }72 }
...@@ -79,28 +77,28 @@ pub fn classifyType(ty: Type, mod: *Module, ctx: Context) Class {...@@ -79,28 +77,28 @@ pub fn classifyType(ty: Type, mod: *Module, ctx: Context) Class {
79 .Int => {77 .Int => {
80 // TODO this is incorrect for _BitInt(128) but implementing78 // TODO this is incorrect for _BitInt(128) but implementing
81 // this correctly makes implementing compiler-rt impossible.79 // this correctly makes implementing compiler-rt impossible.
82 // const bit_size = ty.bitSize(mod);80 // const bit_size = ty.bitSize(pt);
83 // if (bit_size > 64) return .memory;81 // if (bit_size > 64) return .memory;
84 return .byval;82 return .byval;
85 },83 },
86 .Enum, .ErrorSet => {84 .Enum, .ErrorSet => {
87 const bit_size = ty.bitSize(mod);85 const bit_size = ty.bitSize(pt);
88 if (bit_size > 64) return .memory;86 if (bit_size > 64) return .memory;
89 return .byval;87 return .byval;
90 },88 },
91 .Vector => {89 .Vector => {
92 const bit_size = ty.bitSize(mod);90 const bit_size = ty.bitSize(pt);
93 // TODO is this controlled by a cpu feature?91 // TODO is this controlled by a cpu feature?
94 if (ctx == .ret and bit_size > 128) return .memory;92 if (ctx == .ret and bit_size > 128) return .memory;
95 if (bit_size > 512) return .memory;93 if (bit_size > 512) return .memory;
96 return .byval;94 return .byval;
97 },95 },
98 .Optional => {96 .Optional => {
99 assert(ty.isPtrLikeOptional(mod));97 assert(ty.isPtrLikeOptional(pt.zcu));
100 return .byval;98 return .byval;
101 },99 },
102 .Pointer => {100 .Pointer => {
103 assert(!ty.isSlice(mod));101 assert(!ty.isSlice(pt.zcu));
104 return .byval;102 return .byval;
105 },103 },
106 .ErrorUnion,104 .ErrorUnion,
...@@ -122,16 +120,16 @@ pub fn classifyType(ty: Type, mod: *Module, ctx: Context) Class {...@@ -122,16 +120,16 @@ pub fn classifyType(ty: Type, mod: *Module, ctx: Context) Class {
122}120}
123121
124const byval_float_count = 4;122const byval_float_count = 4;
125fn countFloats(ty: Type, mod: *Module, maybe_float_bits: *?u16) u32 {123fn countFloats(ty: Type, zcu: *Zcu, maybe_float_bits: *?u16) u32 {
126 const ip = &mod.intern_pool;124 const ip = &zcu.intern_pool;
127 const target = mod.getTarget();125 const target = zcu.getTarget();
128 const invalid = std.math.maxInt(u32);126 const invalid = std.math.maxInt(u32);
129 switch (ty.zigTypeTag(mod)) {127 switch (ty.zigTypeTag(zcu)) {
130 .Union => {128 .Union => {
131 const union_obj = mod.typeToUnion(ty).?;129 const union_obj = zcu.typeToUnion(ty).?;
132 var max_count: u32 = 0;130 var max_count: u32 = 0;
133 for (union_obj.field_types.get(ip)) |field_ty| {131 for (union_obj.field_types.get(ip)) |field_ty| {
134 const field_count = countFloats(Type.fromInterned(field_ty), mod, maybe_float_bits);132 const field_count = countFloats(Type.fromInterned(field_ty), zcu, maybe_float_bits);
135 if (field_count == invalid) return invalid;133 if (field_count == invalid) return invalid;
136 if (field_count > max_count) max_count = field_count;134 if (field_count > max_count) max_count = field_count;
137 if (max_count > byval_float_count) return invalid;135 if (max_count > byval_float_count) return invalid;
...@@ -139,12 +137,12 @@ fn countFloats(ty: Type, mod: *Module, maybe_float_bits: *?u16) u32 {...@@ -139,12 +137,12 @@ fn countFloats(ty: Type, mod: *Module, maybe_float_bits: *?u16) u32 {
139 return max_count;137 return max_count;
140 },138 },
141 .Struct => {139 .Struct => {
142 const fields_len = ty.structFieldCount(mod);140 const fields_len = ty.structFieldCount(zcu);
143 var count: u32 = 0;141 var count: u32 = 0;
144 var i: u32 = 0;142 var i: u32 = 0;
145 while (i < fields_len) : (i += 1) {143 while (i < fields_len) : (i += 1) {
146 const field_ty = ty.structFieldType(i, mod);144 const field_ty = ty.structFieldType(i, zcu);
147 const field_count = countFloats(field_ty, mod, maybe_float_bits);145 const field_count = countFloats(field_ty, zcu, maybe_float_bits);
148 if (field_count == invalid) return invalid;146 if (field_count == invalid) return invalid;
149 count += field_count;147 count += field_count;
150 if (count > byval_float_count) return invalid;148 if (count > byval_float_count) return invalid;
src/arch/riscv64/CodeGen.zig+267-216
...@@ -46,6 +46,7 @@ const RegisterLock = RegisterManager.RegisterLock;...@@ -46,6 +46,7 @@ const RegisterLock = RegisterManager.RegisterLock;
46const InnerError = CodeGenError || error{OutOfRegisters};46const InnerError = CodeGenError || error{OutOfRegisters};
4747
48gpa: Allocator,48gpa: Allocator,
49pt: Zcu.PerThread,
49air: Air,50air: Air,
50mod: *Package.Module,51mod: *Package.Module,
51liveness: Liveness,52liveness: Liveness,
...@@ -541,14 +542,14 @@ const FrameAlloc = struct {...@@ -541,14 +542,14 @@ const FrameAlloc = struct {
541 .ref_count = 0,542 .ref_count = 0,
542 };543 };
543 }544 }
544 fn initType(ty: Type, zcu: *Zcu) FrameAlloc {545 fn initType(ty: Type, pt: Zcu.PerThread) FrameAlloc {
545 return init(.{546 return init(.{
546 .size = ty.abiSize(zcu),547 .size = ty.abiSize(pt),
547 .alignment = ty.abiAlignment(zcu),548 .alignment = ty.abiAlignment(pt),
548 });549 });
549 }550 }
550 fn initSpill(ty: Type, zcu: *Zcu) FrameAlloc {551 fn initSpill(ty: Type, pt: Zcu.PerThread) FrameAlloc {
551 const abi_size = ty.abiSize(zcu);552 const abi_size = ty.abiSize(pt);
552 const spill_size = if (abi_size < 8)553 const spill_size = if (abi_size < 8)
553 math.ceilPowerOfTwoAssert(u64, abi_size)554 math.ceilPowerOfTwoAssert(u64, abi_size)
554 else555 else
...@@ -556,7 +557,7 @@ const FrameAlloc = struct {...@@ -556,7 +557,7 @@ const FrameAlloc = struct {
556 return init(.{557 return init(.{
557 .size = spill_size,558 .size = spill_size,
558 .pad = @intCast(spill_size - abi_size),559 .pad = @intCast(spill_size - abi_size),
559 .alignment = ty.abiAlignment(zcu).maxStrict(560 .alignment = ty.abiAlignment(pt).maxStrict(
560 Alignment.fromNonzeroByteUnits(@min(spill_size, 8)),561 Alignment.fromNonzeroByteUnits(@min(spill_size, 8)),
561 ),562 ),
562 });563 });
...@@ -696,6 +697,7 @@ const CallView = enum(u1) {...@@ -696,6 +697,7 @@ const CallView = enum(u1) {
696697
697pub fn generate(698pub fn generate(
698 bin_file: *link.File,699 bin_file: *link.File,
700 pt: Zcu.PerThread,
699 src_loc: Zcu.LazySrcLoc,701 src_loc: Zcu.LazySrcLoc,
700 func_index: InternPool.Index,702 func_index: InternPool.Index,
701 air: Air,703 air: Air,
...@@ -703,9 +705,9 @@ pub fn generate(...@@ -703,9 +705,9 @@ pub fn generate(
703 code: *std.ArrayList(u8),705 code: *std.ArrayList(u8),
704 debug_output: DebugInfoOutput,706 debug_output: DebugInfoOutput,
705) CodeGenError!Result {707) CodeGenError!Result {
706 const comp = bin_file.comp;708 const zcu = pt.zcu;
707 const gpa = comp.gpa;709 const comp = zcu.comp;
708 const zcu = comp.module.?;710 const gpa = zcu.gpa;
709 const ip = &zcu.intern_pool;711 const ip = &zcu.intern_pool;
710 const func = zcu.funcInfo(func_index);712 const func = zcu.funcInfo(func_index);
711 const fn_owner_decl = zcu.declPtr(func.owner_decl);713 const fn_owner_decl = zcu.declPtr(func.owner_decl);
...@@ -726,6 +728,7 @@ pub fn generate(...@@ -726,6 +728,7 @@ pub fn generate(
726 var function = Func{728 var function = Func{
727 .gpa = gpa,729 .gpa = gpa,
728 .air = air,730 .air = air,
731 .pt = pt,
729 .mod = mod,732 .mod = mod,
730 .liveness = liveness,733 .liveness = liveness,
731 .target = target,734 .target = target,
...@@ -787,11 +790,11 @@ pub fn generate(...@@ -787,11 +790,11 @@ pub fn generate(
787 function.args = call_info.args;790 function.args = call_info.args;
788 function.ret_mcv = call_info.return_value;791 function.ret_mcv = call_info.return_value;
789 function.frame_allocs.set(@intFromEnum(FrameIndex.ret_addr), FrameAlloc.init(.{792 function.frame_allocs.set(@intFromEnum(FrameIndex.ret_addr), FrameAlloc.init(.{
790 .size = Type.usize.abiSize(zcu),793 .size = Type.usize.abiSize(pt),
791 .alignment = Type.usize.abiAlignment(zcu).min(call_info.stack_align),794 .alignment = Type.usize.abiAlignment(pt).min(call_info.stack_align),
792 }));795 }));
793 function.frame_allocs.set(@intFromEnum(FrameIndex.base_ptr), FrameAlloc.init(.{796 function.frame_allocs.set(@intFromEnum(FrameIndex.base_ptr), FrameAlloc.init(.{
794 .size = Type.usize.abiSize(zcu),797 .size = Type.usize.abiSize(pt),
795 .alignment = Alignment.min(798 .alignment = Alignment.min(
796 call_info.stack_align,799 call_info.stack_align,
797 Alignment.fromNonzeroByteUnits(function.target.stackAlignment()),800 Alignment.fromNonzeroByteUnits(function.target.stackAlignment()),
...@@ -803,7 +806,7 @@ pub fn generate(...@@ -803,7 +806,7 @@ pub fn generate(
803 }));806 }));
804 function.frame_allocs.set(@intFromEnum(FrameIndex.spill_frame), FrameAlloc.init(.{807 function.frame_allocs.set(@intFromEnum(FrameIndex.spill_frame), FrameAlloc.init(.{
805 .size = 0,808 .size = 0,
806 .alignment = Type.usize.abiAlignment(zcu),809 .alignment = Type.usize.abiAlignment(pt),
807 }));810 }));
808811
809 function.gen() catch |err| switch (err) {812 function.gen() catch |err| switch (err) {
...@@ -821,9 +824,10 @@ pub fn generate(...@@ -821,9 +824,10 @@ pub fn generate(
821 };824 };
822 defer mir.deinit(gpa);825 defer mir.deinit(gpa);
823826
824 var emit = Emit{827 var emit: Emit = .{
828 .bin_file = bin_file,
825 .lower = .{829 .lower = .{
826 .bin_file = bin_file,830 .pt = pt,
827 .allocator = gpa,831 .allocator = gpa,
828 .mir = mir,832 .mir = mir,
829 .cc = fn_info.cc,833 .cc = fn_info.cc,
...@@ -875,10 +879,10 @@ fn formatWipMir(...@@ -875,10 +879,10 @@ fn formatWipMir(
875 _: std.fmt.FormatOptions,879 _: std.fmt.FormatOptions,
876 writer: anytype,880 writer: anytype,
877) @TypeOf(writer).Error!void {881) @TypeOf(writer).Error!void {
878 const comp = data.func.bin_file.comp;882 const pt = data.func.pt;
879 const mod = comp.root_mod;883 const comp = pt.zcu.comp;
880 var lower = Lower{884 var lower: Lower = .{
881 .bin_file = data.func.bin_file,885 .pt = pt,
882 .allocator = data.func.gpa,886 .allocator = data.func.gpa,
883 .mir = .{887 .mir = .{
884 .instructions = data.func.mir_instructions.slice(),888 .instructions = data.func.mir_instructions.slice(),
...@@ -889,7 +893,7 @@ fn formatWipMir(...@@ -889,7 +893,7 @@ fn formatWipMir(
889 .src_loc = data.func.src_loc,893 .src_loc = data.func.src_loc,
890 .output_mode = comp.config.output_mode,894 .output_mode = comp.config.output_mode,
891 .link_mode = comp.config.link_mode,895 .link_mode = comp.config.link_mode,
892 .pic = mod.pic,896 .pic = comp.root_mod.pic,
893 };897 };
894 var first = true;898 var first = true;
895 for ((lower.lowerMir(data.inst) catch |err| switch (err) {899 for ((lower.lowerMir(data.inst) catch |err| switch (err) {
...@@ -933,7 +937,7 @@ fn formatDecl(...@@ -933,7 +937,7 @@ fn formatDecl(
933}937}
934fn fmtDecl(func: *Func, decl_index: InternPool.DeclIndex) std.fmt.Formatter(formatDecl) {938fn fmtDecl(func: *Func, decl_index: InternPool.DeclIndex) std.fmt.Formatter(formatDecl) {
935 return .{ .data = .{939 return .{ .data = .{
936 .mod = func.bin_file.comp.module.?,940 .mod = func.pt.zcu,
937 .decl_index = decl_index,941 .decl_index = decl_index,
938 } };942 } };
939}943}
...@@ -950,7 +954,7 @@ fn formatAir(...@@ -950,7 +954,7 @@ fn formatAir(
950) @TypeOf(writer).Error!void {954) @TypeOf(writer).Error!void {
951 @import("../../print_air.zig").dumpInst(955 @import("../../print_air.zig").dumpInst(
952 data.inst,956 data.inst,
953 data.func.bin_file.comp.module.?,957 data.func.pt,
954 data.func.air,958 data.func.air,
955 data.func.liveness,959 data.func.liveness,
956 );960 );
...@@ -1044,8 +1048,9 @@ const required_features = [_]Target.riscv.Feature{...@@ -1044,8 +1048,9 @@ const required_features = [_]Target.riscv.Feature{
1044};1048};
10451049
1046fn gen(func: *Func) !void {1050fn gen(func: *Func) !void {
1047 const mod = func.bin_file.comp.module.?;1051 const pt = func.pt;
1048 const fn_info = mod.typeToFunc(func.fn_type).?;1052 const zcu = pt.zcu;
1053 const fn_info = zcu.typeToFunc(func.fn_type).?;
10491054
1050 inline for (required_features) |feature| {1055 inline for (required_features) |feature| {
1051 if (!func.hasFeature(feature)) {1056 if (!func.hasFeature(feature)) {
...@@ -1071,7 +1076,7 @@ fn gen(func: *Func) !void {...@@ -1071,7 +1076,7 @@ fn gen(func: *Func) !void {
1071 // The address where to store the return value for the caller is in a1076 // The address where to store the return value for the caller is in a
1072 // register which the callee is free to clobber. Therefore, we purposely1077 // register which the callee is free to clobber. Therefore, we purposely
1073 // spill it to stack immediately.1078 // spill it to stack immediately.
1074 const frame_index = try func.allocFrameIndex(FrameAlloc.initSpill(Type.usize, mod));1079 const frame_index = try func.allocFrameIndex(FrameAlloc.initSpill(Type.usize, pt));
1075 try func.genSetMem(1080 try func.genSetMem(
1076 .{ .frame = frame_index },1081 .{ .frame = frame_index },
1077 0,1082 0,
...@@ -1205,7 +1210,8 @@ fn gen(func: *Func) !void {...@@ -1205,7 +1210,8 @@ fn gen(func: *Func) !void {
1205}1210}
12061211
1207fn genBody(func: *Func, body: []const Air.Inst.Index) InnerError!void {1212fn genBody(func: *Func, body: []const Air.Inst.Index) InnerError!void {
1208 const zcu = func.bin_file.comp.module.?;1213 const pt = func.pt;
1214 const zcu = pt.zcu;
1209 const ip = &zcu.intern_pool;1215 const ip = &zcu.intern_pool;
1210 const air_tags = func.air.instructions.items(.tag);1216 const air_tags = func.air.instructions.items(.tag);
12111217
...@@ -1672,44 +1678,46 @@ fn ensureProcessDeathCapacity(func: *Func, additional_count: usize) !void {...@@ -1672,44 +1678,46 @@ fn ensureProcessDeathCapacity(func: *Func, additional_count: usize) !void {
1672}1678}
16731679
1674fn memSize(func: *Func, ty: Type) Memory.Size {1680fn memSize(func: *Func, ty: Type) Memory.Size {
1675 const mod = func.bin_file.comp.module.?;1681 const pt = func.pt;
1676 return switch (ty.zigTypeTag(mod)) {1682 const zcu = pt.zcu;
1683 return switch (ty.zigTypeTag(zcu)) {
1677 .Float => Memory.Size.fromBitSize(ty.floatBits(func.target.*)),1684 .Float => Memory.Size.fromBitSize(ty.floatBits(func.target.*)),
1678 else => Memory.Size.fromByteSize(ty.abiSize(mod)),1685 else => Memory.Size.fromByteSize(ty.abiSize(pt)),
1679 };1686 };
1680}1687}
16811688
1682fn splitType(func: *Func, ty: Type) ![2]Type {1689fn splitType(func: *Func, ty: Type) ![2]Type {
1683 const zcu = func.bin_file.comp.module.?;1690 const pt = func.pt;
1684 const classes = mem.sliceTo(&abi.classifySystem(ty, zcu), .none);1691 const classes = mem.sliceTo(&abi.classifySystem(ty, pt), .none);
1685 var parts: [2]Type = undefined;1692 var parts: [2]Type = undefined;
1686 if (classes.len == 2) for (&parts, classes, 0..) |*part, class, part_i| {1693 if (classes.len == 2) for (&parts, classes, 0..) |*part, class, part_i| {
1687 part.* = switch (class) {1694 part.* = switch (class) {
1688 .integer => switch (part_i) {1695 .integer => switch (part_i) {
1689 0 => Type.u64,1696 0 => Type.u64,
1690 1 => part: {1697 1 => part: {
1691 const elem_size = ty.abiAlignment(zcu).minStrict(.@"8").toByteUnits().?;1698 const elem_size = ty.abiAlignment(pt).minStrict(.@"8").toByteUnits().?;
1692 const elem_ty = try zcu.intType(.unsigned, @intCast(elem_size * 8));1699 const elem_ty = try pt.intType(.unsigned, @intCast(elem_size * 8));
1693 break :part switch (@divExact(ty.abiSize(zcu) - 8, elem_size)) {1700 break :part switch (@divExact(ty.abiSize(pt) - 8, elem_size)) {
1694 1 => elem_ty,1701 1 => elem_ty,
1695 else => |len| try zcu.arrayType(.{ .len = len, .child = elem_ty.toIntern() }),1702 else => |len| try pt.arrayType(.{ .len = len, .child = elem_ty.toIntern() }),
1696 };1703 };
1697 },1704 },
1698 else => unreachable,1705 else => unreachable,
1699 },1706 },
1700 else => return func.fail("TODO: splitType class {}", .{class}),1707 else => return func.fail("TODO: splitType class {}", .{class}),
1701 };1708 };
1702 } else if (parts[0].abiSize(zcu) + parts[1].abiSize(zcu) == ty.abiSize(zcu)) return parts;1709 } else if (parts[0].abiSize(pt) + parts[1].abiSize(pt) == ty.abiSize(pt)) return parts;
1703 return func.fail("TODO implement splitType for {}", .{ty.fmt(zcu)});1710 return func.fail("TODO implement splitType for {}", .{ty.fmt(pt)});
1704}1711}
17051712
1706/// Truncates the value in the register in place.1713/// Truncates the value in the register in place.
1707/// Clobbers any remaining bits.1714/// Clobbers any remaining bits.
1708fn truncateRegister(func: *Func, ty: Type, reg: Register) !void {1715fn truncateRegister(func: *Func, ty: Type, reg: Register) !void {
1709 const mod = func.bin_file.comp.module.?;1716 const pt = func.pt;
1710 const int_info = if (ty.isAbiInt(mod)) ty.intInfo(mod) else std.builtin.Type.Int{1717 const zcu = pt.zcu;
1718 const int_info = if (ty.isAbiInt(zcu)) ty.intInfo(zcu) else std.builtin.Type.Int{
1711 .signedness = .unsigned,1719 .signedness = .unsigned,
1712 .bits = @intCast(ty.bitSize(mod)),1720 .bits = @intCast(ty.bitSize(pt)),
1713 };1721 };
1714 const shift = math.cast(u6, 64 - int_info.bits % 64) orelse return;1722 const shift = math.cast(u6, 64 - int_info.bits % 64) orelse return;
1715 switch (int_info.signedness) {1723 switch (int_info.signedness) {
...@@ -1780,7 +1788,8 @@ fn truncateRegister(func: *Func, ty: Type, reg: Register) !void {...@@ -1780,7 +1788,8 @@ fn truncateRegister(func: *Func, ty: Type, reg: Register) !void {
1780}1788}
17811789
1782fn symbolIndex(func: *Func) !u32 {1790fn symbolIndex(func: *Func) !u32 {
1783 const zcu = func.bin_file.comp.module.?;1791 const pt = func.pt;
1792 const zcu = pt.zcu;
1784 const decl_index = zcu.funcOwnerDeclIndex(func.func_index);1793 const decl_index = zcu.funcOwnerDeclIndex(func.func_index);
1785 return switch (func.bin_file.tag) {1794 return switch (func.bin_file.tag) {
1786 .elf => blk: {1795 .elf => blk: {
...@@ -1817,19 +1826,21 @@ fn allocFrameIndex(func: *Func, alloc: FrameAlloc) !FrameIndex {...@@ -1817,19 +1826,21 @@ fn allocFrameIndex(func: *Func, alloc: FrameAlloc) !FrameIndex {
18171826
1818/// Use a pointer instruction as the basis for allocating stack memory.1827/// Use a pointer instruction as the basis for allocating stack memory.
1819fn allocMemPtr(func: *Func, inst: Air.Inst.Index) !FrameIndex {1828fn allocMemPtr(func: *Func, inst: Air.Inst.Index) !FrameIndex {
1820 const zcu = func.bin_file.comp.module.?;1829 const pt = func.pt;
1830 const zcu = pt.zcu;
1821 const ptr_ty = func.typeOfIndex(inst);1831 const ptr_ty = func.typeOfIndex(inst);
1822 const val_ty = ptr_ty.childType(zcu);1832 const val_ty = ptr_ty.childType(zcu);
1823 return func.allocFrameIndex(FrameAlloc.init(.{1833 return func.allocFrameIndex(FrameAlloc.init(.{
1824 .size = math.cast(u32, val_ty.abiSize(zcu)) orelse {1834 .size = math.cast(u32, val_ty.abiSize(pt)) orelse {
1825 return func.fail("type '{}' too big to fit into stack frame", .{val_ty.fmt(zcu)});1835 return func.fail("type '{}' too big to fit into stack frame", .{val_ty.fmt(pt)});
1826 },1836 },
1827 .alignment = ptr_ty.ptrAlignment(zcu).max(.@"1"),1837 .alignment = ptr_ty.ptrAlignment(pt).max(.@"1"),
1828 }));1838 }));
1829}1839}
18301840
1831fn typeRegClass(func: *Func, ty: Type) abi.RegisterClass {1841fn typeRegClass(func: *Func, ty: Type) abi.RegisterClass {
1832 const zcu = func.bin_file.comp.module.?;1842 const pt = func.pt;
1843 const zcu = pt.zcu;
1833 return switch (ty.zigTypeTag(zcu)) {1844 return switch (ty.zigTypeTag(zcu)) {
1834 .Float => .float,1845 .Float => .float,
1835 .Vector => @panic("TODO: typeRegClass for Vectors"),1846 .Vector => @panic("TODO: typeRegClass for Vectors"),
...@@ -1838,7 +1849,8 @@ fn typeRegClass(func: *Func, ty: Type) abi.RegisterClass {...@@ -1838,7 +1849,8 @@ fn typeRegClass(func: *Func, ty: Type) abi.RegisterClass {
1838}1849}
18391850
1840fn regGeneralClassForType(func: *Func, ty: Type) RegisterManager.RegisterBitSet {1851fn regGeneralClassForType(func: *Func, ty: Type) RegisterManager.RegisterBitSet {
1841 const zcu = func.bin_file.comp.module.?;1852 const pt = func.pt;
1853 const zcu = pt.zcu;
1842 return switch (ty.zigTypeTag(zcu)) {1854 return switch (ty.zigTypeTag(zcu)) {
1843 .Float => abi.Registers.Float.general_purpose,1855 .Float => abi.Registers.Float.general_purpose,
1844 .Vector => @panic("TODO: regGeneralClassForType for Vectors"),1856 .Vector => @panic("TODO: regGeneralClassForType for Vectors"),
...@@ -1847,7 +1859,8 @@ fn regGeneralClassForType(func: *Func, ty: Type) RegisterManager.RegisterBitSet...@@ -1847,7 +1859,8 @@ fn regGeneralClassForType(func: *Func, ty: Type) RegisterManager.RegisterBitSet
1847}1859}
18481860
1849fn regTempClassForType(func: *Func, ty: Type) RegisterManager.RegisterBitSet {1861fn regTempClassForType(func: *Func, ty: Type) RegisterManager.RegisterBitSet {
1850 const zcu = func.bin_file.comp.module.?;1862 const pt = func.pt;
1863 const zcu = pt.zcu;
1851 return switch (ty.zigTypeTag(zcu)) {1864 return switch (ty.zigTypeTag(zcu)) {
1852 .Float => abi.Registers.Float.temporary,1865 .Float => abi.Registers.Float.temporary,
1853 .Vector => @panic("TODO: regTempClassForType for Vectors"),1866 .Vector => @panic("TODO: regTempClassForType for Vectors"),
...@@ -1856,13 +1869,13 @@ fn regTempClassForType(func: *Func, ty: Type) RegisterManager.RegisterBitSet {...@@ -1856,13 +1869,13 @@ fn regTempClassForType(func: *Func, ty: Type) RegisterManager.RegisterBitSet {
1856}1869}
18571870
1858fn allocRegOrMem(func: *Func, elem_ty: Type, inst: ?Air.Inst.Index, reg_ok: bool) !MCValue {1871fn allocRegOrMem(func: *Func, elem_ty: Type, inst: ?Air.Inst.Index, reg_ok: bool) !MCValue {
1859 const zcu = func.bin_file.comp.module.?;1872 const pt = func.pt;
18601873
1861 const abi_size = math.cast(u32, elem_ty.abiSize(zcu)) orelse {1874 const abi_size = math.cast(u32, elem_ty.abiSize(pt)) orelse {
1862 return func.fail("type '{}' too big to fit into stack frame", .{elem_ty.fmt(zcu)});1875 return func.fail("type '{}' too big to fit into stack frame", .{elem_ty.fmt(pt)});
1863 };1876 };
18641877
1865 const min_size: u32 = switch (elem_ty.zigTypeTag(zcu)) {1878 const min_size: u32 = switch (elem_ty.zigTypeTag(pt.zcu)) {
1866 .Float => 4,1879 .Float => 4,
1867 .Vector => @panic("allocRegOrMem Vector"),1880 .Vector => @panic("allocRegOrMem Vector"),
1868 else => 8,1881 else => 8,
...@@ -1874,7 +1887,7 @@ fn allocRegOrMem(func: *Func, elem_ty: Type, inst: ?Air.Inst.Index, reg_ok: bool...@@ -1874,7 +1887,7 @@ fn allocRegOrMem(func: *Func, elem_ty: Type, inst: ?Air.Inst.Index, reg_ok: bool
1874 }1887 }
1875 }1888 }
18761889
1877 const frame_index = try func.allocFrameIndex(FrameAlloc.initSpill(elem_ty, zcu));1890 const frame_index = try func.allocFrameIndex(FrameAlloc.initSpill(elem_ty, pt));
1878 return .{ .load_frame = .{ .index = frame_index } };1891 return .{ .load_frame = .{ .index = frame_index } };
1879}1892}
18801893
...@@ -1955,7 +1968,7 @@ pub fn spillInstruction(func: *Func, reg: Register, inst: Air.Inst.Index) !void...@@ -1955,7 +1968,7 @@ pub fn spillInstruction(func: *Func, reg: Register, inst: Air.Inst.Index) !void
1955/// allocated. A second call to `copyToTmpRegister` may return the same register.1968/// allocated. A second call to `copyToTmpRegister` may return the same register.
1956/// This can have a side effect of spilling instructions to the stack to free up a register.1969/// This can have a side effect of spilling instructions to the stack to free up a register.
1957fn copyToTmpRegister(func: *Func, ty: Type, mcv: MCValue) !Register {1970fn copyToTmpRegister(func: *Func, ty: Type, mcv: MCValue) !Register {
1958 log.debug("copyToTmpRegister ty: {}", .{ty.fmt(func.bin_file.comp.module.?)});1971 log.debug("copyToTmpRegister ty: {}", .{ty.fmt(func.pt)});
1959 const reg = try func.register_manager.allocReg(null, func.regTempClassForType(ty));1972 const reg = try func.register_manager.allocReg(null, func.regTempClassForType(ty));
1960 try func.genSetReg(ty, reg, mcv);1973 try func.genSetReg(ty, reg, mcv);
1961 return reg;1974 return reg;
...@@ -2004,7 +2017,8 @@ fn airFpext(func: *Func, inst: Air.Inst.Index) !void {...@@ -2004,7 +2017,8 @@ fn airFpext(func: *Func, inst: Air.Inst.Index) !void {
2004}2017}
20052018
2006fn airIntCast(func: *Func, inst: Air.Inst.Index) !void {2019fn airIntCast(func: *Func, inst: Air.Inst.Index) !void {
2007 const zcu = func.bin_file.comp.module.?;2020 const pt = func.pt;
2021 const zcu = pt.zcu;
2008 const ty_op = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;2022 const ty_op = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
2009 const src_ty = func.typeOf(ty_op.operand);2023 const src_ty = func.typeOf(ty_op.operand);
2010 const dst_ty = func.typeOfIndex(inst);2024 const dst_ty = func.typeOfIndex(inst);
...@@ -2040,7 +2054,7 @@ fn airIntCast(func: *Func, inst: Air.Inst.Index) !void {...@@ -2040,7 +2054,7 @@ fn airIntCast(func: *Func, inst: Air.Inst.Index) !void {
20402054
2041 break :result dst_mcv;2055 break :result dst_mcv;
2042 } orelse return func.fail("TODO: implement airIntCast from {} to {}", .{2056 } orelse return func.fail("TODO: implement airIntCast from {} to {}", .{
2043 src_ty.fmt(zcu), dst_ty.fmt(zcu),2057 src_ty.fmt(pt), dst_ty.fmt(pt),
2044 });2058 });
20452059
2046 return func.finishAir(inst, result, .{ ty_op.operand, .none, .none });2060 return func.finishAir(inst, result, .{ ty_op.operand, .none, .none });
...@@ -2067,7 +2081,8 @@ fn airIntFromBool(func: *Func, inst: Air.Inst.Index) !void {...@@ -2067,7 +2081,8 @@ fn airIntFromBool(func: *Func, inst: Air.Inst.Index) !void {
2067fn airNot(func: *Func, inst: Air.Inst.Index) !void {2081fn airNot(func: *Func, inst: Air.Inst.Index) !void {
2068 const ty_op = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;2082 const ty_op = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
2069 const result: MCValue = if (func.liveness.isUnused(inst)) .unreach else result: {2083 const result: MCValue = if (func.liveness.isUnused(inst)) .unreach else result: {
2070 const zcu = func.bin_file.comp.module.?;2084 const pt = func.pt;
2085 const zcu = pt.zcu;
20712086
2072 const operand = try func.resolveInst(ty_op.operand);2087 const operand = try func.resolveInst(ty_op.operand);
2073 const ty = func.typeOf(ty_op.operand);2088 const ty = func.typeOf(ty_op.operand);
...@@ -2106,12 +2121,12 @@ fn airNot(func: *Func, inst: Air.Inst.Index) !void {...@@ -2106,12 +2121,12 @@ fn airNot(func: *Func, inst: Air.Inst.Index) !void {
2106}2121}
21072122
2108fn airSlice(func: *Func, inst: Air.Inst.Index) !void {2123fn airSlice(func: *Func, inst: Air.Inst.Index) !void {
2109 const zcu = func.bin_file.comp.module.?;2124 const pt = func.pt;
2110 const ty_pl = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;2125 const ty_pl = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
2111 const bin_op = func.air.extraData(Air.Bin, ty_pl.payload).data;2126 const bin_op = func.air.extraData(Air.Bin, ty_pl.payload).data;
21122127
2113 const slice_ty = func.typeOfIndex(inst);2128 const slice_ty = func.typeOfIndex(inst);
2114 const frame_index = try func.allocFrameIndex(FrameAlloc.initSpill(slice_ty, zcu));2129 const frame_index = try func.allocFrameIndex(FrameAlloc.initSpill(slice_ty, pt));
21152130
2116 const ptr_ty = func.typeOf(bin_op.lhs);2131 const ptr_ty = func.typeOf(bin_op.lhs);
2117 try func.genSetMem(.{ .frame = frame_index }, 0, ptr_ty, .{ .air_ref = bin_op.lhs });2132 try func.genSetMem(.{ .frame = frame_index }, 0, ptr_ty, .{ .air_ref = bin_op.lhs });
...@@ -2119,7 +2134,7 @@ fn airSlice(func: *Func, inst: Air.Inst.Index) !void {...@@ -2119,7 +2134,7 @@ fn airSlice(func: *Func, inst: Air.Inst.Index) !void {
2119 const len_ty = func.typeOf(bin_op.rhs);2134 const len_ty = func.typeOf(bin_op.rhs);
2120 try func.genSetMem(2135 try func.genSetMem(
2121 .{ .frame = frame_index },2136 .{ .frame = frame_index },
2122 @intCast(ptr_ty.abiSize(zcu)),2137 @intCast(ptr_ty.abiSize(pt)),
2123 len_ty,2138 len_ty,
2124 .{ .air_ref = bin_op.rhs },2139 .{ .air_ref = bin_op.rhs },
2125 );2140 );
...@@ -2129,14 +2144,15 @@ fn airSlice(func: *Func, inst: Air.Inst.Index) !void {...@@ -2129,14 +2144,15 @@ fn airSlice(func: *Func, inst: Air.Inst.Index) !void {
2129}2144}
21302145
2131fn airBinOp(func: *Func, inst: Air.Inst.Index, tag: Air.Inst.Tag) !void {2146fn airBinOp(func: *Func, inst: Air.Inst.Index, tag: Air.Inst.Tag) !void {
2132 const zcu = func.bin_file.comp.module.?;2147 const pt = func.pt;
2148 const zcu = pt.zcu;
2133 const bin_op = func.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;2149 const bin_op = func.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
2134 const dst_mcv = try func.binOp(inst, tag, bin_op.lhs, bin_op.rhs);2150 const dst_mcv = try func.binOp(inst, tag, bin_op.lhs, bin_op.rhs);
21352151
2136 const dst_ty = func.typeOfIndex(inst);2152 const dst_ty = func.typeOfIndex(inst);
2137 if (dst_ty.isAbiInt(zcu)) {2153 if (dst_ty.isAbiInt(zcu)) {
2138 const abi_size: u32 = @intCast(dst_ty.abiSize(zcu));2154 const abi_size: u32 = @intCast(dst_ty.abiSize(pt));
2139 const bit_size: u32 = @intCast(dst_ty.bitSize(zcu));2155 const bit_size: u32 = @intCast(dst_ty.bitSize(pt));
2140 if (abi_size * 8 > bit_size) {2156 if (abi_size * 8 > bit_size) {
2141 const dst_lock = switch (dst_mcv) {2157 const dst_lock = switch (dst_mcv) {
2142 .register => |dst_reg| func.register_manager.lockRegAssumeUnused(dst_reg),2158 .register => |dst_reg| func.register_manager.lockRegAssumeUnused(dst_reg),
...@@ -2150,7 +2166,7 @@ fn airBinOp(func: *Func, inst: Air.Inst.Index, tag: Air.Inst.Tag) !void {...@@ -2150,7 +2166,7 @@ fn airBinOp(func: *Func, inst: Air.Inst.Index, tag: Air.Inst.Tag) !void {
2150 const tmp_reg, const tmp_lock = try func.allocReg(.int);2166 const tmp_reg, const tmp_lock = try func.allocReg(.int);
2151 defer func.register_manager.unlockReg(tmp_lock);2167 defer func.register_manager.unlockReg(tmp_lock);
21522168
2153 const hi_ty = try zcu.intType(.unsigned, @intCast((dst_ty.bitSize(zcu) - 1) % 64 + 1));2169 const hi_ty = try pt.intType(.unsigned, @intCast((dst_ty.bitSize(pt) - 1) % 64 + 1));
2154 const hi_mcv = dst_mcv.address().offset(@intCast(bit_size / 64 * 8)).deref();2170 const hi_mcv = dst_mcv.address().offset(@intCast(bit_size / 64 * 8)).deref();
2155 try func.genSetReg(hi_ty, tmp_reg, hi_mcv);2171 try func.genSetReg(hi_ty, tmp_reg, hi_mcv);
2156 try func.truncateRegister(dst_ty, tmp_reg);2172 try func.truncateRegister(dst_ty, tmp_reg);
...@@ -2170,7 +2186,7 @@ fn binOp(...@@ -2170,7 +2186,7 @@ fn binOp(
2170 rhs_air: Air.Inst.Ref,2186 rhs_air: Air.Inst.Ref,
2171) !MCValue {2187) !MCValue {
2172 _ = maybe_inst;2188 _ = maybe_inst;
2173 const zcu = func.bin_file.comp.module.?;2189 const pt = func.pt;
2174 const lhs_ty = func.typeOf(lhs_air);2190 const lhs_ty = func.typeOf(lhs_air);
2175 const rhs_ty = func.typeOf(rhs_air);2191 const rhs_ty = func.typeOf(rhs_air);
21762192
...@@ -2189,7 +2205,7 @@ fn binOp(...@@ -2189,7 +2205,7 @@ fn binOp(
2189 return func.fail("binOp libcall runtime-float ops", .{});2205 return func.fail("binOp libcall runtime-float ops", .{});
2190 }2206 }
21912207
2192 if (lhs_ty.bitSize(zcu) > 64) return func.fail("TODO: binOp >= 64 bits", .{});2208 if (lhs_ty.bitSize(pt) > 64) return func.fail("TODO: binOp >= 64 bits", .{});
21932209
2194 const lhs_mcv = try func.resolveInst(lhs_air);2210 const lhs_mcv = try func.resolveInst(lhs_air);
2195 const rhs_mcv = try func.resolveInst(rhs_air);2211 const rhs_mcv = try func.resolveInst(rhs_air);
...@@ -2237,8 +2253,9 @@ fn genBinOp(...@@ -2237,8 +2253,9 @@ fn genBinOp(
2237 rhs_ty: Type,2253 rhs_ty: Type,
2238 dst_reg: Register,2254 dst_reg: Register,
2239) !void {2255) !void {
2240 const zcu = func.bin_file.comp.module.?;2256 const pt = func.pt;
2241 const bit_size = lhs_ty.bitSize(zcu);2257 const zcu = pt.zcu;
2258 const bit_size = lhs_ty.bitSize(pt);
2242 assert(bit_size <= 64);2259 assert(bit_size <= 64);
22432260
2244 const is_unsigned = lhs_ty.isUnsignedInt(zcu);2261 const is_unsigned = lhs_ty.isUnsignedInt(zcu);
...@@ -2349,7 +2366,7 @@ fn genBinOp(...@@ -2349,7 +2366,7 @@ fn genBinOp(
2349 defer func.register_manager.unlockReg(tmp_lock);2366 defer func.register_manager.unlockReg(tmp_lock);
23502367
2351 // RISC-V has no immediate mul, so we copy the size to a temporary register2368 // RISC-V has no immediate mul, so we copy the size to a temporary register
2352 const elem_size = lhs_ty.elemType2(zcu).abiSize(zcu);2369 const elem_size = lhs_ty.elemType2(zcu).abiSize(pt);
2353 const elem_size_reg = try func.copyToTmpRegister(Type.usize, .{ .immediate = elem_size });2370 const elem_size_reg = try func.copyToTmpRegister(Type.usize, .{ .immediate = elem_size });
23542371
2355 try func.genBinOp(2372 try func.genBinOp(
...@@ -2613,7 +2630,8 @@ fn airPtrArithmetic(func: *Func, inst: Air.Inst.Index, tag: Air.Inst.Tag) !void...@@ -2613,7 +2630,8 @@ fn airPtrArithmetic(func: *Func, inst: Air.Inst.Index, tag: Air.Inst.Tag) !void
2613}2630}
26142631
2615fn airAddWithOverflow(func: *Func, inst: Air.Inst.Index) !void {2632fn airAddWithOverflow(func: *Func, inst: Air.Inst.Index) !void {
2616 const zcu = func.bin_file.comp.module.?;2633 const pt = func.pt;
2634 const zcu = pt.zcu;
2617 const ty_pl = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;2635 const ty_pl = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
2618 const extra = func.air.extraData(Air.Bin, ty_pl.payload).data;2636 const extra = func.air.extraData(Air.Bin, ty_pl.payload).data;
26192637
...@@ -2632,7 +2650,7 @@ fn airAddWithOverflow(func: *Func, inst: Air.Inst.Index) !void {...@@ -2632,7 +2650,7 @@ fn airAddWithOverflow(func: *Func, inst: Air.Inst.Index) !void {
2632 const add_result_reg_lock = func.register_manager.lockRegAssumeUnused(add_result_reg);2650 const add_result_reg_lock = func.register_manager.lockRegAssumeUnused(add_result_reg);
2633 defer func.register_manager.unlockReg(add_result_reg_lock);2651 defer func.register_manager.unlockReg(add_result_reg_lock);
26342652
2635 const shift_amount: u6 = @intCast(Type.usize.bitSize(zcu) - int_info.bits);2653 const shift_amount: u6 = @intCast(Type.usize.bitSize(pt) - int_info.bits);
26362654
2637 const shift_reg, const shift_lock = try func.allocReg(.int);2655 const shift_reg, const shift_lock = try func.allocReg(.int);
2638 defer func.register_manager.unlockReg(shift_lock);2656 defer func.register_manager.unlockReg(shift_lock);
...@@ -2663,7 +2681,7 @@ fn airAddWithOverflow(func: *Func, inst: Air.Inst.Index) !void {...@@ -2663,7 +2681,7 @@ fn airAddWithOverflow(func: *Func, inst: Air.Inst.Index) !void {
26632681
2664 try func.genSetMem(2682 try func.genSetMem(
2665 .{ .frame = offset.index },2683 .{ .frame = offset.index },
2666 offset.off + @as(i32, @intCast(tuple_ty.structFieldOffset(0, zcu))),2684 offset.off + @as(i32, @intCast(tuple_ty.structFieldOffset(0, pt))),
2667 lhs_ty,2685 lhs_ty,
2668 add_result,2686 add_result,
2669 );2687 );
...@@ -2682,7 +2700,7 @@ fn airAddWithOverflow(func: *Func, inst: Air.Inst.Index) !void {...@@ -2682,7 +2700,7 @@ fn airAddWithOverflow(func: *Func, inst: Air.Inst.Index) !void {
26822700
2683 try func.genSetMem(2701 try func.genSetMem(
2684 .{ .frame = offset.index },2702 .{ .frame = offset.index },
2685 offset.off + @as(i32, @intCast(tuple_ty.structFieldOffset(1, zcu))),2703 offset.off + @as(i32, @intCast(tuple_ty.structFieldOffset(1, pt))),
2686 Type.u1,2704 Type.u1,
2687 .{ .register = overflow_reg },2705 .{ .register = overflow_reg },
2688 );2706 );
...@@ -2697,7 +2715,8 @@ fn airAddWithOverflow(func: *Func, inst: Air.Inst.Index) !void {...@@ -2697,7 +2715,8 @@ fn airAddWithOverflow(func: *Func, inst: Air.Inst.Index) !void {
2697}2715}
26982716
2699fn airSubWithOverflow(func: *Func, inst: Air.Inst.Index) !void {2717fn airSubWithOverflow(func: *Func, inst: Air.Inst.Index) !void {
2700 const zcu = func.bin_file.comp.module.?;2718 const pt = func.pt;
2719 const zcu = pt.zcu;
2701 const ty_pl = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;2720 const ty_pl = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
2702 const extra = func.air.extraData(Air.Bin, ty_pl.payload).data;2721 const extra = func.air.extraData(Air.Bin, ty_pl.payload).data;
27032722
...@@ -2727,7 +2746,7 @@ fn airSubWithOverflow(func: *Func, inst: Air.Inst.Index) !void {...@@ -2727,7 +2746,7 @@ fn airSubWithOverflow(func: *Func, inst: Air.Inst.Index) !void {
27272746
2728 try func.genSetMem(2747 try func.genSetMem(
2729 .{ .frame = offset.index },2748 .{ .frame = offset.index },
2730 offset.off + @as(i32, @intCast(tuple_ty.structFieldOffset(0, zcu))),2749 offset.off + @as(i32, @intCast(tuple_ty.structFieldOffset(0, pt))),
2731 lhs_ty,2750 lhs_ty,
2732 .{ .register = dest_reg },2751 .{ .register = dest_reg },
2733 );2752 );
...@@ -2757,7 +2776,7 @@ fn airSubWithOverflow(func: *Func, inst: Air.Inst.Index) !void {...@@ -2757,7 +2776,7 @@ fn airSubWithOverflow(func: *Func, inst: Air.Inst.Index) !void {
27572776
2758 try func.genSetMem(2777 try func.genSetMem(
2759 .{ .frame = offset.index },2778 .{ .frame = offset.index },
2760 offset.off + @as(i32, @intCast(tuple_ty.structFieldOffset(1, zcu))),2779 offset.off + @as(i32, @intCast(tuple_ty.structFieldOffset(1, pt))),
2761 Type.u1,2780 Type.u1,
2762 .{ .register = overflow_reg },2781 .{ .register = overflow_reg },
2763 );2782 );
...@@ -2808,7 +2827,7 @@ fn airSubWithOverflow(func: *Func, inst: Air.Inst.Index) !void {...@@ -2808,7 +2827,7 @@ fn airSubWithOverflow(func: *Func, inst: Air.Inst.Index) !void {
28082827
2809 try func.genSetMem(2828 try func.genSetMem(
2810 .{ .frame = offset.index },2829 .{ .frame = offset.index },
2811 offset.off + @as(i32, @intCast(tuple_ty.structFieldOffset(1, zcu))),2830 offset.off + @as(i32, @intCast(tuple_ty.structFieldOffset(1, pt))),
2812 Type.u1,2831 Type.u1,
2813 .{ .register = overflow_reg },2832 .{ .register = overflow_reg },
2814 );2833 );
...@@ -2825,7 +2844,8 @@ fn airSubWithOverflow(func: *Func, inst: Air.Inst.Index) !void {...@@ -2825,7 +2844,8 @@ fn airSubWithOverflow(func: *Func, inst: Air.Inst.Index) !void {
2825}2844}
28262845
2827fn airMulWithOverflow(func: *Func, inst: Air.Inst.Index) !void {2846fn airMulWithOverflow(func: *Func, inst: Air.Inst.Index) !void {
2828 const zcu = func.bin_file.comp.module.?;2847 const pt = func.pt;
2848 const zcu = pt.zcu;
2829 const ty_pl = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;2849 const ty_pl = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
2830 const extra = func.air.extraData(Air.Bin, ty_pl.payload).data;2850 const extra = func.air.extraData(Air.Bin, ty_pl.payload).data;
28312851
...@@ -2840,8 +2860,8 @@ fn airMulWithOverflow(func: *Func, inst: Air.Inst.Index) !void {...@@ -2840,8 +2860,8 @@ fn airMulWithOverflow(func: *Func, inst: Air.Inst.Index) !void {
2840 // genSetReg needs to support register_offset src_mcv for this to be true.2860 // genSetReg needs to support register_offset src_mcv for this to be true.
2841 const result_mcv = try func.allocRegOrMem(tuple_ty, inst, false);2861 const result_mcv = try func.allocRegOrMem(tuple_ty, inst, false);
28422862
2843 const result_off: i32 = @intCast(tuple_ty.structFieldOffset(0, zcu));2863 const result_off: i32 = @intCast(tuple_ty.structFieldOffset(0, pt));
2844 const overflow_off: i32 = @intCast(tuple_ty.structFieldOffset(1, zcu));2864 const overflow_off: i32 = @intCast(tuple_ty.structFieldOffset(1, pt));
28452865
2846 const dest_reg, const dest_lock = try func.allocReg(.int);2866 const dest_reg, const dest_lock = try func.allocReg(.int);
2847 defer func.register_manager.unlockReg(dest_lock);2867 defer func.register_manager.unlockReg(dest_lock);
...@@ -2957,11 +2977,11 @@ fn airShlSat(func: *Func, inst: Air.Inst.Index) !void {...@@ -2957,11 +2977,11 @@ fn airShlSat(func: *Func, inst: Air.Inst.Index) !void {
2957}2977}
29582978
2959fn airOptionalPayload(func: *Func, inst: Air.Inst.Index) !void {2979fn airOptionalPayload(func: *Func, inst: Air.Inst.Index) !void {
2960 const zcu = func.bin_file.comp.module.?;2980 const pt = func.pt;
2961 const ty_op = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;2981 const ty_op = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
2962 const result: MCValue = result: {2982 const result: MCValue = result: {
2963 const pl_ty = func.typeOfIndex(inst);2983 const pl_ty = func.typeOfIndex(inst);
2964 if (!pl_ty.hasRuntimeBitsIgnoreComptime(zcu)) break :result .none;2984 if (!pl_ty.hasRuntimeBitsIgnoreComptime(pt)) break :result .none;
29652985
2966 const opt_mcv = try func.resolveInst(ty_op.operand);2986 const opt_mcv = try func.resolveInst(ty_op.operand);
2967 if (func.reuseOperand(inst, ty_op.operand, 0, opt_mcv)) {2987 if (func.reuseOperand(inst, ty_op.operand, 0, opt_mcv)) {
...@@ -2993,7 +3013,8 @@ fn airOptionalPayloadPtrSet(func: *Func, inst: Air.Inst.Index) !void {...@@ -2993,7 +3013,8 @@ fn airOptionalPayloadPtrSet(func: *Func, inst: Air.Inst.Index) !void {
29933013
2994fn airUnwrapErrErr(func: *Func, inst: Air.Inst.Index) !void {3014fn airUnwrapErrErr(func: *Func, inst: Air.Inst.Index) !void {
2995 const ty_op = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;3015 const ty_op = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
2996 const zcu = func.bin_file.comp.module.?;3016 const pt = func.pt;
3017 const zcu = pt.zcu;
2997 const err_union_ty = func.typeOf(ty_op.operand);3018 const err_union_ty = func.typeOf(ty_op.operand);
2998 const err_ty = err_union_ty.errorUnionSet(zcu);3019 const err_ty = err_union_ty.errorUnionSet(zcu);
2999 const payload_ty = err_union_ty.errorUnionPayload(zcu);3020 const payload_ty = err_union_ty.errorUnionPayload(zcu);
...@@ -3004,11 +3025,11 @@ fn airUnwrapErrErr(func: *Func, inst: Air.Inst.Index) !void {...@@ -3004,11 +3025,11 @@ fn airUnwrapErrErr(func: *Func, inst: Air.Inst.Index) !void {
3004 break :result .{ .immediate = 0 };3025 break :result .{ .immediate = 0 };
3005 }3026 }
30063027
3007 if (!payload_ty.hasRuntimeBitsIgnoreComptime(zcu)) {3028 if (!payload_ty.hasRuntimeBitsIgnoreComptime(pt)) {
3008 break :result operand;3029 break :result operand;
3009 }3030 }
30103031
3011 const err_off: u32 = @intCast(errUnionErrorOffset(payload_ty, zcu));3032 const err_off: u32 = @intCast(errUnionErrorOffset(payload_ty, pt));
30123033
3013 switch (operand) {3034 switch (operand) {
3014 .register => |reg| {3035 .register => |reg| {
...@@ -3052,13 +3073,14 @@ fn genUnwrapErrUnionPayloadMir(...@@ -3052,13 +3073,14 @@ fn genUnwrapErrUnionPayloadMir(
3052 err_union_ty: Type,3073 err_union_ty: Type,
3053 err_union: MCValue,3074 err_union: MCValue,
3054) !MCValue {3075) !MCValue {
3055 const zcu = func.bin_file.comp.module.?;3076 const pt = func.pt;
3077 const zcu = pt.zcu;
3056 const payload_ty = err_union_ty.errorUnionPayload(zcu);3078 const payload_ty = err_union_ty.errorUnionPayload(zcu);
30573079
3058 const result: MCValue = result: {3080 const result: MCValue = result: {
3059 if (!payload_ty.hasRuntimeBitsIgnoreComptime(zcu)) break :result .none;3081 if (!payload_ty.hasRuntimeBitsIgnoreComptime(pt)) break :result .none;
30603082
3061 const payload_off: u31 = @intCast(errUnionPayloadOffset(payload_ty, zcu));3083 const payload_off: u31 = @intCast(errUnionPayloadOffset(payload_ty, pt));
3062 switch (err_union) {3084 switch (err_union) {
3063 .load_frame => |frame_addr| break :result .{ .load_frame = .{3085 .load_frame => |frame_addr| break :result .{ .load_frame = .{
3064 .index = frame_addr.index,3086 .index = frame_addr.index,
...@@ -3127,11 +3149,12 @@ fn airSaveErrReturnTraceIndex(func: *Func, inst: Air.Inst.Index) !void {...@@ -3127,11 +3149,12 @@ fn airSaveErrReturnTraceIndex(func: *Func, inst: Air.Inst.Index) !void {
3127}3149}
31283150
3129fn airWrapOptional(func: *Func, inst: Air.Inst.Index) !void {3151fn airWrapOptional(func: *Func, inst: Air.Inst.Index) !void {
3130 const zcu = func.bin_file.comp.module.?;3152 const pt = func.pt;
3153 const zcu = pt.zcu;
3131 const ty_op = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;3154 const ty_op = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
3132 const result: MCValue = result: {3155 const result: MCValue = result: {
3133 const pl_ty = func.typeOf(ty_op.operand);3156 const pl_ty = func.typeOf(ty_op.operand);
3134 if (!pl_ty.hasRuntimeBits(zcu)) break :result .{ .immediate = 1 };3157 if (!pl_ty.hasRuntimeBits(pt)) break :result .{ .immediate = 1 };
31353158
3136 const opt_ty = func.typeOfIndex(inst);3159 const opt_ty = func.typeOfIndex(inst);
3137 const pl_mcv = try func.resolveInst(ty_op.operand);3160 const pl_mcv = try func.resolveInst(ty_op.operand);
...@@ -3148,7 +3171,7 @@ fn airWrapOptional(func: *Func, inst: Air.Inst.Index) !void {...@@ -3148,7 +3171,7 @@ fn airWrapOptional(func: *Func, inst: Air.Inst.Index) !void {
3148 try func.genCopy(pl_ty, opt_mcv, pl_mcv);3171 try func.genCopy(pl_ty, opt_mcv, pl_mcv);
31493172
3150 if (!same_repr) {3173 if (!same_repr) {
3151 const pl_abi_size: i32 = @intCast(pl_ty.abiSize(zcu));3174 const pl_abi_size: i32 = @intCast(pl_ty.abiSize(pt));
3152 switch (opt_mcv) {3175 switch (opt_mcv) {
3153 .load_frame => |frame_addr| try func.genSetMem(3176 .load_frame => |frame_addr| try func.genSetMem(
3154 .{ .frame = frame_addr.index },3177 .{ .frame = frame_addr.index },
...@@ -3167,7 +3190,8 @@ fn airWrapOptional(func: *Func, inst: Air.Inst.Index) !void {...@@ -3167,7 +3190,8 @@ fn airWrapOptional(func: *Func, inst: Air.Inst.Index) !void {
31673190
3168/// T to E!T3191/// T to E!T
3169fn airWrapErrUnionPayload(func: *Func, inst: Air.Inst.Index) !void {3192fn airWrapErrUnionPayload(func: *Func, inst: Air.Inst.Index) !void {
3170 const zcu = func.bin_file.comp.module.?;3193 const pt = func.pt;
3194 const zcu = pt.zcu;
3171 const ty_op = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;3195 const ty_op = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
31723196
3173 const eu_ty = ty_op.ty.toType();3197 const eu_ty = ty_op.ty.toType();
...@@ -3176,11 +3200,11 @@ fn airWrapErrUnionPayload(func: *Func, inst: Air.Inst.Index) !void {...@@ -3176,11 +3200,11 @@ fn airWrapErrUnionPayload(func: *Func, inst: Air.Inst.Index) !void {
3176 const operand = try func.resolveInst(ty_op.operand);3200 const operand = try func.resolveInst(ty_op.operand);
31773201
3178 const result: MCValue = result: {3202 const result: MCValue = result: {
3179 if (!pl_ty.hasRuntimeBitsIgnoreComptime(zcu)) break :result .{ .immediate = 0 };3203 if (!pl_ty.hasRuntimeBitsIgnoreComptime(pt)) break :result .{ .immediate = 0 };
31803204
3181 const frame_index = try func.allocFrameIndex(FrameAlloc.initSpill(eu_ty, zcu));3205 const frame_index = try func.allocFrameIndex(FrameAlloc.initSpill(eu_ty, pt));
3182 const pl_off: i32 = @intCast(errUnionPayloadOffset(pl_ty, zcu));3206 const pl_off: i32 = @intCast(errUnionPayloadOffset(pl_ty, pt));
3183 const err_off: i32 = @intCast(errUnionErrorOffset(pl_ty, zcu));3207 const err_off: i32 = @intCast(errUnionErrorOffset(pl_ty, pt));
3184 try func.genSetMem(.{ .frame = frame_index }, pl_off, pl_ty, operand);3208 try func.genSetMem(.{ .frame = frame_index }, pl_off, pl_ty, operand);
3185 try func.genSetMem(.{ .frame = frame_index }, err_off, err_ty, .{ .immediate = 0 });3209 try func.genSetMem(.{ .frame = frame_index }, err_off, err_ty, .{ .immediate = 0 });
3186 break :result .{ .load_frame = .{ .index = frame_index } };3210 break :result .{ .load_frame = .{ .index = frame_index } };
...@@ -3191,7 +3215,8 @@ fn airWrapErrUnionPayload(func: *Func, inst: Air.Inst.Index) !void {...@@ -3191,7 +3215,8 @@ fn airWrapErrUnionPayload(func: *Func, inst: Air.Inst.Index) !void {
31913215
3192/// E to E!T3216/// E to E!T
3193fn airWrapErrUnionErr(func: *Func, inst: Air.Inst.Index) !void {3217fn airWrapErrUnionErr(func: *Func, inst: Air.Inst.Index) !void {
3194 const zcu = func.bin_file.comp.module.?;3218 const pt = func.pt;
3219 const zcu = pt.zcu;
3195 const ty_op = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;3220 const ty_op = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
31963221
3197 const eu_ty = ty_op.ty.toType();3222 const eu_ty = ty_op.ty.toType();
...@@ -3199,11 +3224,11 @@ fn airWrapErrUnionErr(func: *Func, inst: Air.Inst.Index) !void {...@@ -3199,11 +3224,11 @@ fn airWrapErrUnionErr(func: *Func, inst: Air.Inst.Index) !void {
3199 const err_ty = eu_ty.errorUnionSet(zcu);3224 const err_ty = eu_ty.errorUnionSet(zcu);
32003225
3201 const result: MCValue = result: {3226 const result: MCValue = result: {
3202 if (!pl_ty.hasRuntimeBitsIgnoreComptime(zcu)) break :result try func.resolveInst(ty_op.operand);3227 if (!pl_ty.hasRuntimeBitsIgnoreComptime(pt)) break :result try func.resolveInst(ty_op.operand);
32033228
3204 const frame_index = try func.allocFrameIndex(FrameAlloc.initSpill(eu_ty, zcu));3229 const frame_index = try func.allocFrameIndex(FrameAlloc.initSpill(eu_ty, pt));
3205 const pl_off: i32 = @intCast(errUnionPayloadOffset(pl_ty, zcu));3230 const pl_off: i32 = @intCast(errUnionPayloadOffset(pl_ty, pt));
3206 const err_off: i32 = @intCast(errUnionErrorOffset(pl_ty, zcu));3231 const err_off: i32 = @intCast(errUnionErrorOffset(pl_ty, pt));
3207 try func.genSetMem(.{ .frame = frame_index }, pl_off, pl_ty, .undef);3232 try func.genSetMem(.{ .frame = frame_index }, pl_off, pl_ty, .undef);
3208 const operand = try func.resolveInst(ty_op.operand);3233 const operand = try func.resolveInst(ty_op.operand);
3209 try func.genSetMem(.{ .frame = frame_index }, err_off, err_ty, operand);3234 try func.genSetMem(.{ .frame = frame_index }, err_off, err_ty, operand);
...@@ -3327,15 +3352,16 @@ fn airPtrSlicePtrPtr(func: *Func, inst: Air.Inst.Index) !void {...@@ -3327,15 +3352,16 @@ fn airPtrSlicePtrPtr(func: *Func, inst: Air.Inst.Index) !void {
3327}3352}
33283353
3329fn airSliceElemVal(func: *Func, inst: Air.Inst.Index) !void {3354fn airSliceElemVal(func: *Func, inst: Air.Inst.Index) !void {
3330 const mod = func.bin_file.comp.module.?;3355 const pt = func.pt;
3356 const zcu = pt.zcu;
3331 const bin_op = func.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;3357 const bin_op = func.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
33323358
3333 const result: MCValue = result: {3359 const result: MCValue = result: {
3334 const elem_ty = func.typeOfIndex(inst);3360 const elem_ty = func.typeOfIndex(inst);
3335 if (!elem_ty.hasRuntimeBitsIgnoreComptime(mod)) break :result .none;3361 if (!elem_ty.hasRuntimeBitsIgnoreComptime(pt)) break :result .none;
33363362
3337 const slice_ty = func.typeOf(bin_op.lhs);3363 const slice_ty = func.typeOf(bin_op.lhs);
3338 const slice_ptr_field_type = slice_ty.slicePtrFieldType(mod);3364 const slice_ptr_field_type = slice_ty.slicePtrFieldType(zcu);
3339 const elem_ptr = try func.genSliceElemPtr(bin_op.lhs, bin_op.rhs);3365 const elem_ptr = try func.genSliceElemPtr(bin_op.lhs, bin_op.rhs);
3340 const dst_mcv = try func.allocRegOrMem(elem_ty, inst, false);3366 const dst_mcv = try func.allocRegOrMem(elem_ty, inst, false);
3341 try func.load(dst_mcv, elem_ptr, slice_ptr_field_type);3367 try func.load(dst_mcv, elem_ptr, slice_ptr_field_type);
...@@ -3352,7 +3378,8 @@ fn airSliceElemPtr(func: *Func, inst: Air.Inst.Index) !void {...@@ -3352,7 +3378,8 @@ fn airSliceElemPtr(func: *Func, inst: Air.Inst.Index) !void {
3352}3378}
33533379
3354fn genSliceElemPtr(func: *Func, lhs: Air.Inst.Ref, rhs: Air.Inst.Ref) !MCValue {3380fn genSliceElemPtr(func: *Func, lhs: Air.Inst.Ref, rhs: Air.Inst.Ref) !MCValue {
3355 const zcu = func.bin_file.comp.module.?;3381 const pt = func.pt;
3382 const zcu = pt.zcu;
3356 const slice_ty = func.typeOf(lhs);3383 const slice_ty = func.typeOf(lhs);
3357 const slice_mcv = try func.resolveInst(lhs);3384 const slice_mcv = try func.resolveInst(lhs);
3358 const slice_mcv_lock: ?RegisterLock = switch (slice_mcv) {3385 const slice_mcv_lock: ?RegisterLock = switch (slice_mcv) {
...@@ -3362,7 +3389,7 @@ fn genSliceElemPtr(func: *Func, lhs: Air.Inst.Ref, rhs: Air.Inst.Ref) !MCValue {...@@ -3362,7 +3389,7 @@ fn genSliceElemPtr(func: *Func, lhs: Air.Inst.Ref, rhs: Air.Inst.Ref) !MCValue {
3362 defer if (slice_mcv_lock) |lock| func.register_manager.unlockReg(lock);3389 defer if (slice_mcv_lock) |lock| func.register_manager.unlockReg(lock);
33633390
3364 const elem_ty = slice_ty.childType(zcu);3391 const elem_ty = slice_ty.childType(zcu);
3365 const elem_size = elem_ty.abiSize(zcu);3392 const elem_size = elem_ty.abiSize(pt);
33663393
3367 const index_ty = func.typeOf(rhs);3394 const index_ty = func.typeOf(rhs);
3368 const index_mcv = try func.resolveInst(rhs);3395 const index_mcv = try func.resolveInst(rhs);
...@@ -3394,7 +3421,8 @@ fn genSliceElemPtr(func: *Func, lhs: Air.Inst.Ref, rhs: Air.Inst.Ref) !MCValue {...@@ -3394,7 +3421,8 @@ fn genSliceElemPtr(func: *Func, lhs: Air.Inst.Ref, rhs: Air.Inst.Ref) !MCValue {
3394}3421}
33953422
3396fn airArrayElemVal(func: *Func, inst: Air.Inst.Index) !void {3423fn airArrayElemVal(func: *Func, inst: Air.Inst.Index) !void {
3397 const zcu = func.bin_file.comp.module.?;3424 const pt = func.pt;
3425 const zcu = pt.zcu;
3398 const bin_op = func.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;3426 const bin_op = func.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
3399 const result: MCValue = if (func.liveness.isUnused(inst)) .unreach else result: {3427 const result: MCValue = if (func.liveness.isUnused(inst)) .unreach else result: {
3400 const result_ty = func.typeOfIndex(inst);3428 const result_ty = func.typeOfIndex(inst);
...@@ -3406,14 +3434,14 @@ fn airArrayElemVal(func: *Func, inst: Air.Inst.Index) !void {...@@ -3406,14 +3434,14 @@ fn airArrayElemVal(func: *Func, inst: Air.Inst.Index) !void {
3406 const index_ty = func.typeOf(bin_op.rhs);3434 const index_ty = func.typeOf(bin_op.rhs);
34073435
3408 const elem_ty = array_ty.childType(zcu);3436 const elem_ty = array_ty.childType(zcu);
3409 const elem_abi_size = elem_ty.abiSize(zcu);3437 const elem_abi_size = elem_ty.abiSize(pt);
34103438
3411 const addr_reg, const addr_reg_lock = try func.allocReg(.int);3439 const addr_reg, const addr_reg_lock = try func.allocReg(.int);
3412 defer func.register_manager.unlockReg(addr_reg_lock);3440 defer func.register_manager.unlockReg(addr_reg_lock);
34133441
3414 switch (array_mcv) {3442 switch (array_mcv) {
3415 .register => {3443 .register => {
3416 const frame_index = try func.allocFrameIndex(FrameAlloc.initType(array_ty, zcu));3444 const frame_index = try func.allocFrameIndex(FrameAlloc.initType(array_ty, pt));
3417 try func.genSetMem(.{ .frame = frame_index }, 0, array_ty, array_mcv);3445 try func.genSetMem(.{ .frame = frame_index }, 0, array_ty, array_mcv);
3418 try func.genSetReg(Type.usize, addr_reg, .{ .lea_frame = .{ .index = frame_index } });3446 try func.genSetReg(Type.usize, addr_reg, .{ .lea_frame = .{ .index = frame_index } });
3419 },3447 },
...@@ -3451,7 +3479,8 @@ fn airPtrElemVal(func: *Func, inst: Air.Inst.Index) !void {...@@ -3451,7 +3479,8 @@ fn airPtrElemVal(func: *Func, inst: Air.Inst.Index) !void {
3451}3479}
34523480
3453fn airPtrElemPtr(func: *Func, inst: Air.Inst.Index) !void {3481fn airPtrElemPtr(func: *Func, inst: Air.Inst.Index) !void {
3454 const zcu = func.bin_file.comp.module.?;3482 const pt = func.pt;
3483 const zcu = pt.zcu;
3455 const ty_pl = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;3484 const ty_pl = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
3456 const extra = func.air.extraData(Air.Bin, ty_pl.payload).data;3485 const extra = func.air.extraData(Air.Bin, ty_pl.payload).data;
34573486
...@@ -3474,7 +3503,7 @@ fn airPtrElemPtr(func: *Func, inst: Air.Inst.Index) !void {...@@ -3474,7 +3503,7 @@ fn airPtrElemPtr(func: *Func, inst: Air.Inst.Index) !void {
3474 }3503 }
34753504
3476 const elem_ty = base_ptr_ty.elemType2(zcu);3505 const elem_ty = base_ptr_ty.elemType2(zcu);
3477 const elem_abi_size = elem_ty.abiSize(zcu);3506 const elem_abi_size = elem_ty.abiSize(pt);
3478 const index_ty = func.typeOf(extra.rhs);3507 const index_ty = func.typeOf(extra.rhs);
3479 const index_mcv = try func.resolveInst(extra.rhs);3508 const index_mcv = try func.resolveInst(extra.rhs);
3480 const index_lock: ?RegisterLock = switch (index_mcv) {3509 const index_lock: ?RegisterLock = switch (index_mcv) {
...@@ -3536,7 +3565,8 @@ fn airPopcount(func: *Func, inst: Air.Inst.Index) !void {...@@ -3536,7 +3565,8 @@ fn airPopcount(func: *Func, inst: Air.Inst.Index) !void {
3536}3565}
35373566
3538fn airAbs(func: *Func, inst: Air.Inst.Index) !void {3567fn airAbs(func: *Func, inst: Air.Inst.Index) !void {
3539 const zcu = func.bin_file.comp.module.?;3568 const pt = func.pt;
3569 const zcu = pt.zcu;
3540 const ty_op = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;3570 const ty_op = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
3541 const result: MCValue = if (func.liveness.isUnused(inst)) .unreach else result: {3571 const result: MCValue = if (func.liveness.isUnused(inst)) .unreach else result: {
3542 const ty = func.typeOf(ty_op.operand);3572 const ty = func.typeOf(ty_op.operand);
...@@ -3545,7 +3575,7 @@ fn airAbs(func: *Func, inst: Air.Inst.Index) !void {...@@ -3545,7 +3575,7 @@ fn airAbs(func: *Func, inst: Air.Inst.Index) !void {
35453575
3546 switch (scalar_ty.zigTypeTag(zcu)) {3576 switch (scalar_ty.zigTypeTag(zcu)) {
3547 .Int => if (ty.zigTypeTag(zcu) == .Vector) {3577 .Int => if (ty.zigTypeTag(zcu) == .Vector) {
3548 return func.fail("TODO implement airAbs for {}", .{ty.fmt(zcu)});3578 return func.fail("TODO implement airAbs for {}", .{ty.fmt(pt)});
3549 } else {3579 } else {
3550 const return_mcv = try func.copyToNewRegister(inst, operand);3580 const return_mcv = try func.copyToNewRegister(inst, operand);
3551 const operand_reg = return_mcv.register;3581 const operand_reg = return_mcv.register;
...@@ -3615,7 +3645,7 @@ fn airAbs(func: *Func, inst: Air.Inst.Index) !void {...@@ -3615,7 +3645,7 @@ fn airAbs(func: *Func, inst: Air.Inst.Index) !void {
36153645
3616 break :result return_mcv;3646 break :result return_mcv;
3617 },3647 },
3618 else => return func.fail("TODO: implement airAbs {}", .{scalar_ty.fmt(zcu)}),3648 else => return func.fail("TODO: implement airAbs {}", .{scalar_ty.fmt(pt)}),
3619 }3649 }
36203650
3621 break :result .unreach;3651 break :result .unreach;
...@@ -3626,7 +3656,8 @@ fn airAbs(func: *Func, inst: Air.Inst.Index) !void {...@@ -3626,7 +3656,8 @@ fn airAbs(func: *Func, inst: Air.Inst.Index) !void {
3626fn airByteSwap(func: *Func, inst: Air.Inst.Index) !void {3656fn airByteSwap(func: *Func, inst: Air.Inst.Index) !void {
3627 const ty_op = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;3657 const ty_op = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
3628 const result: MCValue = if (func.liveness.isUnused(inst)) .unreach else result: {3658 const result: MCValue = if (func.liveness.isUnused(inst)) .unreach else result: {
3629 const zcu = func.bin_file.comp.module.?;3659 const pt = func.pt;
3660 const zcu = pt.zcu;
3630 const ty = func.typeOf(ty_op.operand);3661 const ty = func.typeOf(ty_op.operand);
3631 const operand = try func.resolveInst(ty_op.operand);3662 const operand = try func.resolveInst(ty_op.operand);
36323663
...@@ -3746,12 +3777,13 @@ fn reuseOperandAdvanced(...@@ -3746,12 +3777,13 @@ fn reuseOperandAdvanced(
3746}3777}
37473778
3748fn airLoad(func: *Func, inst: Air.Inst.Index) !void {3779fn airLoad(func: *Func, inst: Air.Inst.Index) !void {
3749 const zcu = func.bin_file.comp.module.?;3780 const pt = func.pt;
3781 const zcu = pt.zcu;
3750 const ty_op = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;3782 const ty_op = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
3751 const elem_ty = func.typeOfIndex(inst);3783 const elem_ty = func.typeOfIndex(inst);
37523784
3753 const result: MCValue = result: {3785 const result: MCValue = result: {
3754 if (!elem_ty.hasRuntimeBits(zcu))3786 if (!elem_ty.hasRuntimeBits(pt))
3755 break :result .none;3787 break :result .none;
37563788
3757 const ptr = try func.resolveInst(ty_op.operand);3789 const ptr = try func.resolveInst(ty_op.operand);
...@@ -3759,7 +3791,7 @@ fn airLoad(func: *Func, inst: Air.Inst.Index) !void {...@@ -3759,7 +3791,7 @@ fn airLoad(func: *Func, inst: Air.Inst.Index) !void {
3759 if (func.liveness.isUnused(inst) and !is_volatile)3791 if (func.liveness.isUnused(inst) and !is_volatile)
3760 break :result .unreach;3792 break :result .unreach;
37613793
3762 const elem_size = elem_ty.abiSize(zcu);3794 const elem_size = elem_ty.abiSize(pt);
37633795
3764 const dst_mcv: MCValue = blk: {3796 const dst_mcv: MCValue = blk: {
3765 // Pointer is 8 bytes, and if the element is more than that, we cannot reuse it.3797 // Pointer is 8 bytes, and if the element is more than that, we cannot reuse it.
...@@ -3778,10 +3810,11 @@ fn airLoad(func: *Func, inst: Air.Inst.Index) !void {...@@ -3778,10 +3810,11 @@ fn airLoad(func: *Func, inst: Air.Inst.Index) !void {
3778}3810}
37793811
3780fn load(func: *Func, dst_mcv: MCValue, ptr_mcv: MCValue, ptr_ty: Type) InnerError!void {3812fn load(func: *Func, dst_mcv: MCValue, ptr_mcv: MCValue, ptr_ty: Type) InnerError!void {
3781 const zcu = func.bin_file.comp.module.?;3813 const pt = func.pt;
3814 const zcu = pt.zcu;
3782 const dst_ty = ptr_ty.childType(zcu);3815 const dst_ty = ptr_ty.childType(zcu);
37833816
3784 log.debug("loading {}:{} into {}", .{ ptr_mcv, ptr_ty.fmt(zcu), dst_mcv });3817 log.debug("loading {}:{} into {}", .{ ptr_mcv, ptr_ty.fmt(pt), dst_mcv });
37853818
3786 switch (ptr_mcv) {3819 switch (ptr_mcv) {
3787 .none,3820 .none,
...@@ -3833,9 +3866,7 @@ fn airStore(func: *Func, inst: Air.Inst.Index, safety: bool) !void {...@@ -3833,9 +3866,7 @@ fn airStore(func: *Func, inst: Air.Inst.Index, safety: bool) !void {
38333866
3834/// Loads `value` into the "payload" of `pointer`.3867/// Loads `value` into the "payload" of `pointer`.
3835fn store(func: *Func, ptr_mcv: MCValue, src_mcv: MCValue, ptr_ty: Type, src_ty: Type) !void {3868fn store(func: *Func, ptr_mcv: MCValue, src_mcv: MCValue, ptr_ty: Type, src_ty: Type) !void {
3836 const zcu = func.bin_file.comp.module.?;3869 log.debug("storing {}:{} in {}:{}", .{ src_mcv, src_ty.fmt(func.pt), ptr_mcv, ptr_ty.fmt(func.pt) });
3837
3838 log.debug("storing {}:{} in {}:{}", .{ src_mcv, src_ty.fmt(zcu), ptr_mcv, ptr_ty.fmt(zcu) });
38393870
3840 switch (ptr_mcv) {3871 switch (ptr_mcv) {
3841 .none => unreachable,3872 .none => unreachable,
...@@ -3881,7 +3912,8 @@ fn airStructFieldPtrIndex(func: *Func, inst: Air.Inst.Index, index: u8) !void {...@@ -3881,7 +3912,8 @@ fn airStructFieldPtrIndex(func: *Func, inst: Air.Inst.Index, index: u8) !void {
3881}3912}
38823913
3883fn structFieldPtr(func: *Func, inst: Air.Inst.Index, operand: Air.Inst.Ref, index: u32) !MCValue {3914fn structFieldPtr(func: *Func, inst: Air.Inst.Index, operand: Air.Inst.Ref, index: u32) !MCValue {
3884 const zcu = func.bin_file.comp.module.?;3915 const pt = func.pt;
3916 const zcu = pt.zcu;
3885 const ptr_field_ty = func.typeOfIndex(inst);3917 const ptr_field_ty = func.typeOfIndex(inst);
3886 const ptr_container_ty = func.typeOf(operand);3918 const ptr_container_ty = func.typeOf(operand);
3887 const ptr_container_ty_info = ptr_container_ty.ptrInfo(zcu);3919 const ptr_container_ty_info = ptr_container_ty.ptrInfo(zcu);
...@@ -3889,12 +3921,12 @@ fn structFieldPtr(func: *Func, inst: Air.Inst.Index, operand: Air.Inst.Ref, inde...@@ -3889,12 +3921,12 @@ fn structFieldPtr(func: *Func, inst: Air.Inst.Index, operand: Air.Inst.Ref, inde
38893921
3890 const field_offset: i32 = if (zcu.typeToPackedStruct(container_ty)) |struct_obj|3922 const field_offset: i32 = if (zcu.typeToPackedStruct(container_ty)) |struct_obj|
3891 if (ptr_field_ty.ptrInfo(zcu).packed_offset.host_size == 0)3923 if (ptr_field_ty.ptrInfo(zcu).packed_offset.host_size == 0)
3892 @divExact(zcu.structPackedFieldBitOffset(struct_obj, index) +3924 @divExact(pt.structPackedFieldBitOffset(struct_obj, index) +
3893 ptr_container_ty_info.packed_offset.bit_offset, 8)3925 ptr_container_ty_info.packed_offset.bit_offset, 8)
3894 else3926 else
3895 03927 0
3896 else3928 else
3897 @intCast(container_ty.structFieldOffset(index, zcu));3929 @intCast(container_ty.structFieldOffset(index, pt));
38983930
3899 const src_mcv = try func.resolveInst(operand);3931 const src_mcv = try func.resolveInst(operand);
3900 const dst_mcv = if (switch (src_mcv) {3932 const dst_mcv = if (switch (src_mcv) {
...@@ -3906,7 +3938,8 @@ fn structFieldPtr(func: *Func, inst: Air.Inst.Index, operand: Air.Inst.Ref, inde...@@ -3906,7 +3938,8 @@ fn structFieldPtr(func: *Func, inst: Air.Inst.Index, operand: Air.Inst.Ref, inde
3906}3938}
39073939
3908fn airStructFieldVal(func: *Func, inst: Air.Inst.Index) !void {3940fn airStructFieldVal(func: *Func, inst: Air.Inst.Index) !void {
3909 const mod = func.bin_file.comp.module.?;3941 const pt = func.pt;
3942 const zcu = pt.zcu;
39103943
3911 const ty_pl = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;3944 const ty_pl = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
3912 const extra = func.air.extraData(Air.StructField, ty_pl.payload).data;3945 const extra = func.air.extraData(Air.StructField, ty_pl.payload).data;
...@@ -3914,16 +3947,15 @@ fn airStructFieldVal(func: *Func, inst: Air.Inst.Index) !void {...@@ -3914,16 +3947,15 @@ fn airStructFieldVal(func: *Func, inst: Air.Inst.Index) !void {
3914 const index = extra.field_index;3947 const index = extra.field_index;
39153948
3916 const result: MCValue = if (func.liveness.isUnused(inst)) .unreach else result: {3949 const result: MCValue = if (func.liveness.isUnused(inst)) .unreach else result: {
3917 const zcu = func.bin_file.comp.module.?;
3918 const src_mcv = try func.resolveInst(operand);3950 const src_mcv = try func.resolveInst(operand);
3919 const struct_ty = func.typeOf(operand);3951 const struct_ty = func.typeOf(operand);
3920 const field_ty = struct_ty.structFieldType(index, zcu);3952 const field_ty = struct_ty.structFieldType(index, zcu);
3921 if (!field_ty.hasRuntimeBitsIgnoreComptime(zcu)) break :result .none;3953 if (!field_ty.hasRuntimeBitsIgnoreComptime(pt)) break :result .none;
39223954
3923 const field_off: u32 = switch (struct_ty.containerLayout(zcu)) {3955 const field_off: u32 = switch (struct_ty.containerLayout(zcu)) {
3924 .auto, .@"extern" => @intCast(struct_ty.structFieldOffset(index, zcu) * 8),3956 .auto, .@"extern" => @intCast(struct_ty.structFieldOffset(index, pt) * 8),
3925 .@"packed" => if (zcu.typeToStruct(struct_ty)) |struct_type|3957 .@"packed" => if (zcu.typeToStruct(struct_ty)) |struct_type|
3926 zcu.structPackedFieldBitOffset(struct_type, index)3958 pt.structPackedFieldBitOffset(struct_type, index)
3927 else3959 else
3928 0,3960 0,
3929 };3961 };
...@@ -3958,15 +3990,15 @@ fn airStructFieldVal(func: *Func, inst: Air.Inst.Index) !void {...@@ -3958,15 +3990,15 @@ fn airStructFieldVal(func: *Func, inst: Air.Inst.Index) !void {
3958 break :result if (field_off == 0) dst_mcv else try func.copyToNewRegister(inst, dst_mcv);3990 break :result if (field_off == 0) dst_mcv else try func.copyToNewRegister(inst, dst_mcv);
3959 },3991 },
3960 .load_frame => {3992 .load_frame => {
3961 const field_abi_size: u32 = @intCast(field_ty.abiSize(mod));3993 const field_abi_size: u32 = @intCast(field_ty.abiSize(pt));
3962 if (field_off % 8 == 0) {3994 if (field_off % 8 == 0) {
3963 const field_byte_off = @divExact(field_off, 8);3995 const field_byte_off = @divExact(field_off, 8);
3964 const off_mcv = src_mcv.address().offset(@intCast(field_byte_off)).deref();3996 const off_mcv = src_mcv.address().offset(@intCast(field_byte_off)).deref();
3965 const field_bit_size = field_ty.bitSize(mod);3997 const field_bit_size = field_ty.bitSize(pt);
39663998
3967 if (field_abi_size <= 8) {3999 if (field_abi_size <= 8) {
3968 const int_ty = try mod.intType(4000 const int_ty = try pt.intType(
3969 if (field_ty.isAbiInt(mod)) field_ty.intInfo(mod).signedness else .unsigned,4001 if (field_ty.isAbiInt(zcu)) field_ty.intInfo(zcu).signedness else .unsigned,
3970 @intCast(field_bit_size),4002 @intCast(field_bit_size),
3971 );4003 );
39724004
...@@ -3978,7 +4010,7 @@ fn airStructFieldVal(func: *Func, inst: Air.Inst.Index) !void {...@@ -3978,7 +4010,7 @@ fn airStructFieldVal(func: *Func, inst: Air.Inst.Index) !void {
3978 break :result try func.copyToNewRegister(inst, dst_mcv);4010 break :result try func.copyToNewRegister(inst, dst_mcv);
3979 }4011 }
39804012
3981 const container_abi_size: u32 = @intCast(struct_ty.abiSize(mod));4013 const container_abi_size: u32 = @intCast(struct_ty.abiSize(pt));
3982 const dst_mcv = if (field_byte_off + field_abi_size <= container_abi_size and4014 const dst_mcv = if (field_byte_off + field_abi_size <= container_abi_size and
3983 func.reuseOperand(inst, operand, 0, src_mcv))4015 func.reuseOperand(inst, operand, 0, src_mcv))
3984 off_mcv4016 off_mcv
...@@ -4014,7 +4046,8 @@ fn airFieldParentPtr(func: *Func, inst: Air.Inst.Index) !void {...@@ -4014,7 +4046,8 @@ fn airFieldParentPtr(func: *Func, inst: Air.Inst.Index) !void {
4014}4046}
40154047
4016fn genArgDbgInfo(func: Func, inst: Air.Inst.Index, mcv: MCValue) !void {4048fn genArgDbgInfo(func: Func, inst: Air.Inst.Index, mcv: MCValue) !void {
4017 const zcu = func.bin_file.comp.module.?;4049 const pt = func.pt;
4050 const zcu = pt.zcu;
4018 const arg = func.air.instructions.items(.data)[@intFromEnum(inst)].arg;4051 const arg = func.air.instructions.items(.data)[@intFromEnum(inst)].arg;
4019 const ty = arg.ty.toType();4052 const ty = arg.ty.toType();
4020 const owner_decl = zcu.funcOwnerDeclIndex(func.func_index);4053 const owner_decl = zcu.funcOwnerDeclIndex(func.func_index);
...@@ -4139,7 +4172,8 @@ fn genCall(...@@ -4139,7 +4172,8 @@ fn genCall(
4139 arg_tys: []const Type,4172 arg_tys: []const Type,
4140 args: []const MCValue,4173 args: []const MCValue,
4141) !MCValue {4174) !MCValue {
4142 const zcu = func.bin_file.comp.module.?;4175 const pt = func.pt;
4176 const zcu = pt.zcu;
41434177
4144 const fn_ty = switch (info) {4178 const fn_ty = switch (info) {
4145 .air => |callee| fn_info: {4179 .air => |callee| fn_info: {
...@@ -4150,7 +4184,7 @@ fn genCall(...@@ -4150,7 +4184,7 @@ fn genCall(
4150 else => unreachable,4184 else => unreachable,
4151 };4185 };
4152 },4186 },
4153 .lib => |lib| try zcu.funcType(.{4187 .lib => |lib| try pt.funcType(.{
4154 .param_types = lib.param_types,4188 .param_types = lib.param_types,
4155 .return_type = lib.return_type,4189 .return_type = lib.return_type,
4156 .cc = .C,4190 .cc = .C,
...@@ -4208,7 +4242,7 @@ fn genCall(...@@ -4208,7 +4242,7 @@ fn genCall(
4208 try reg_locks.appendSlice(&func.register_manager.lockRegs(2, regs));4242 try reg_locks.appendSlice(&func.register_manager.lockRegs(2, regs));
4209 },4243 },
4210 .indirect => |reg_off| {4244 .indirect => |reg_off| {
4211 frame_index.* = try func.allocFrameIndex(FrameAlloc.initType(arg_ty, zcu));4245 frame_index.* = try func.allocFrameIndex(FrameAlloc.initType(arg_ty, pt));
4212 try func.genSetMem(.{ .frame = frame_index.* }, 0, arg_ty, src_arg);4246 try func.genSetMem(.{ .frame = frame_index.* }, 0, arg_ty, src_arg);
4213 try func.register_manager.getReg(reg_off.reg, null);4247 try func.register_manager.getReg(reg_off.reg, null);
4214 try reg_locks.append(func.register_manager.lockReg(reg_off.reg));4248 try reg_locks.append(func.register_manager.lockReg(reg_off.reg));
...@@ -4221,7 +4255,7 @@ fn genCall(...@@ -4221,7 +4255,7 @@ fn genCall(
4221 .none, .unreach => {},4255 .none, .unreach => {},
4222 .indirect => |reg_off| {4256 .indirect => |reg_off| {
4223 const ret_ty = Type.fromInterned(fn_info.return_type);4257 const ret_ty = Type.fromInterned(fn_info.return_type);
4224 const frame_index = try func.allocFrameIndex(FrameAlloc.initSpill(ret_ty, zcu));4258 const frame_index = try func.allocFrameIndex(FrameAlloc.initSpill(ret_ty, pt));
4225 try func.genSetReg(Type.usize, reg_off.reg, .{4259 try func.genSetReg(Type.usize, reg_off.reg, .{
4226 .lea_frame = .{ .index = frame_index, .off = -reg_off.off },4260 .lea_frame = .{ .index = frame_index, .off = -reg_off.off },
4227 });4261 });
...@@ -4251,7 +4285,7 @@ fn genCall(...@@ -4251,7 +4285,7 @@ fn genCall(
4251 // on linking.4285 // on linking.
4252 switch (info) {4286 switch (info) {
4253 .air => |callee| {4287 .air => |callee| {
4254 if (try func.air.value(callee, zcu)) |func_value| {4288 if (try func.air.value(callee, pt)) |func_value| {
4255 const func_key = zcu.intern_pool.indexToKey(func_value.ip_index);4289 const func_key = zcu.intern_pool.indexToKey(func_value.ip_index);
4256 switch (switch (func_key) {4290 switch (switch (func_key) {
4257 else => func_key,4291 else => func_key,
...@@ -4324,7 +4358,8 @@ fn genCall(...@@ -4324,7 +4358,8 @@ fn genCall(
4324}4358}
43254359
4326fn airRet(func: *Func, inst: Air.Inst.Index, safety: bool) !void {4360fn airRet(func: *Func, inst: Air.Inst.Index, safety: bool) !void {
4327 const zcu = func.bin_file.comp.module.?;4361 const pt = func.pt;
4362 const zcu = pt.zcu;
4328 const un_op = func.air.instructions.items(.data)[@intFromEnum(inst)].un_op;4363 const un_op = func.air.instructions.items(.data)[@intFromEnum(inst)].un_op;
43294364
4330 if (safety) {4365 if (safety) {
...@@ -4394,7 +4429,8 @@ fn airRetLoad(func: *Func, inst: Air.Inst.Index) !void {...@@ -4394,7 +4429,8 @@ fn airRetLoad(func: *Func, inst: Air.Inst.Index) !void {
43944429
4395fn airCmp(func: *Func, inst: Air.Inst.Index, tag: Air.Inst.Tag) !void {4430fn airCmp(func: *Func, inst: Air.Inst.Index, tag: Air.Inst.Tag) !void {
4396 const bin_op = func.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;4431 const bin_op = func.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
4397 const zcu = func.bin_file.comp.module.?;4432 const pt = func.pt;
4433 const zcu = pt.zcu;
43984434
4399 const result: MCValue = if (func.liveness.isUnused(inst)) .unreach else result: {4435 const result: MCValue = if (func.liveness.isUnused(inst)) .unreach else result: {
4400 const lhs_ty = func.typeOf(bin_op.lhs);4436 const lhs_ty = func.typeOf(bin_op.lhs);
...@@ -4415,7 +4451,7 @@ fn airCmp(func: *Func, inst: Air.Inst.Index, tag: Air.Inst.Tag) !void {...@@ -4415,7 +4451,7 @@ fn airCmp(func: *Func, inst: Air.Inst.Index, tag: Air.Inst.Tag) !void {
4415 .ErrorSet => Type.anyerror,4451 .ErrorSet => Type.anyerror,
4416 .Optional => blk: {4452 .Optional => blk: {
4417 const payload_ty = lhs_ty.optionalChild(zcu);4453 const payload_ty = lhs_ty.optionalChild(zcu);
4418 if (!payload_ty.hasRuntimeBitsIgnoreComptime(zcu)) {4454 if (!payload_ty.hasRuntimeBitsIgnoreComptime(pt)) {
4419 break :blk Type.u1;4455 break :blk Type.u1;
4420 } else if (lhs_ty.isPtrLikeOptional(zcu)) {4456 } else if (lhs_ty.isPtrLikeOptional(zcu)) {
4421 break :blk Type.usize;4457 break :blk Type.usize;
...@@ -4503,7 +4539,8 @@ fn genVarDbgInfo(...@@ -4503,7 +4539,8 @@ fn genVarDbgInfo(
4503 mcv: MCValue,4539 mcv: MCValue,
4504 name: [:0]const u8,4540 name: [:0]const u8,
4505) !void {4541) !void {
4506 const zcu = func.bin_file.comp.module.?;4542 const pt = func.pt;
4543 const zcu = pt.zcu;
4507 const is_ptr = switch (tag) {4544 const is_ptr = switch (tag) {
4508 .dbg_var_ptr => true,4545 .dbg_var_ptr => true,
4509 .dbg_var_val => false,4546 .dbg_var_val => false,
...@@ -4595,13 +4632,14 @@ fn condBr(func: *Func, cond_ty: Type, condition: MCValue) !Mir.Inst.Index {...@@ -4595,13 +4632,14 @@ fn condBr(func: *Func, cond_ty: Type, condition: MCValue) !Mir.Inst.Index {
4595}4632}
45964633
4597fn isNull(func: *Func, inst: Air.Inst.Index, opt_ty: Type, opt_mcv: MCValue) !MCValue {4634fn isNull(func: *Func, inst: Air.Inst.Index, opt_ty: Type, opt_mcv: MCValue) !MCValue {
4598 const zcu = func.bin_file.comp.module.?;4635 const pt = func.pt;
4636 const zcu = pt.zcu;
4599 const pl_ty = opt_ty.optionalChild(zcu);4637 const pl_ty = opt_ty.optionalChild(zcu);
46004638
4601 const some_info: struct { off: i32, ty: Type } = if (opt_ty.optionalReprIsPayload(zcu))4639 const some_info: struct { off: i32, ty: Type } = if (opt_ty.optionalReprIsPayload(zcu))
4602 .{ .off = 0, .ty = if (pl_ty.isSlice(zcu)) pl_ty.slicePtrFieldType(zcu) else pl_ty }4640 .{ .off = 0, .ty = if (pl_ty.isSlice(zcu)) pl_ty.slicePtrFieldType(zcu) else pl_ty }
4603 else4641 else
4604 .{ .off = @intCast(pl_ty.abiSize(zcu)), .ty = Type.bool };4642 .{ .off = @intCast(pl_ty.abiSize(pt)), .ty = Type.bool };
46054643
4606 const return_mcv = try func.allocRegOrMem(func.typeOfIndex(inst), inst, true);4644 const return_mcv = try func.allocRegOrMem(func.typeOfIndex(inst), inst, true);
4607 assert(return_mcv == .register); // should not be larger 8 bytes4645 assert(return_mcv == .register); // should not be larger 8 bytes
...@@ -4642,7 +4680,7 @@ fn isNull(func: *Func, inst: Air.Inst.Index, opt_ty: Type, opt_mcv: MCValue) !MC...@@ -4642,7 +4680,7 @@ fn isNull(func: *Func, inst: Air.Inst.Index, opt_ty: Type, opt_mcv: MCValue) !MC
4642 return return_mcv;4680 return return_mcv;
4643 }4681 }
4644 assert(some_info.ty.ip_index == .bool_type);4682 assert(some_info.ty.ip_index == .bool_type);
4645 const opt_abi_size: u32 = @intCast(opt_ty.abiSize(zcu));4683 const opt_abi_size: u32 = @intCast(opt_ty.abiSize(pt));
4646 _ = opt_abi_size;4684 _ = opt_abi_size;
4647 return func.fail("TODO: isNull some_info.off != 0 register", .{});4685 return func.fail("TODO: isNull some_info.off != 0 register", .{});
4648 },4686 },
...@@ -4742,7 +4780,8 @@ fn airIsErr(func: *Func, inst: Air.Inst.Index) !void {...@@ -4742,7 +4780,8 @@ fn airIsErr(func: *Func, inst: Air.Inst.Index) !void {
4742}4780}
47434781
4744fn airIsErrPtr(func: *Func, inst: Air.Inst.Index) !void {4782fn airIsErrPtr(func: *Func, inst: Air.Inst.Index) !void {
4745 const zcu = func.bin_file.comp.module.?;4783 const pt = func.pt;
4784 const zcu = pt.zcu;
4746 const un_op = func.air.instructions.items(.data)[@intFromEnum(inst)].un_op;4785 const un_op = func.air.instructions.items(.data)[@intFromEnum(inst)].un_op;
4747 const result: MCValue = if (func.liveness.isUnused(inst)) .unreach else result: {4786 const result: MCValue = if (func.liveness.isUnused(inst)) .unreach else result: {
4748 const operand_ptr = try func.resolveInst(un_op);4787 const operand_ptr = try func.resolveInst(un_op);
...@@ -4768,10 +4807,11 @@ fn airIsErrPtr(func: *Func, inst: Air.Inst.Index) !void {...@@ -4768,10 +4807,11 @@ fn airIsErrPtr(func: *Func, inst: Air.Inst.Index) !void {
4768/// Result is in the return register.4807/// Result is in the return register.
4769fn isErr(func: *Func, maybe_inst: ?Air.Inst.Index, eu_ty: Type, eu_mcv: MCValue) !MCValue {4808fn isErr(func: *Func, maybe_inst: ?Air.Inst.Index, eu_ty: Type, eu_mcv: MCValue) !MCValue {
4770 _ = maybe_inst;4809 _ = maybe_inst;
4771 const zcu = func.bin_file.comp.module.?;4810 const pt = func.pt;
4811 const zcu = pt.zcu;
4772 const err_ty = eu_ty.errorUnionSet(zcu);4812 const err_ty = eu_ty.errorUnionSet(zcu);
4773 if (err_ty.errorSetIsEmpty(zcu)) return MCValue{ .immediate = 0 }; // always false4813 if (err_ty.errorSetIsEmpty(zcu)) return MCValue{ .immediate = 0 }; // always false
4774 const err_off: u31 = @intCast(errUnionErrorOffset(eu_ty.errorUnionPayload(zcu), zcu));4814 const err_off: u31 = @intCast(errUnionErrorOffset(eu_ty.errorUnionPayload(zcu), pt));
47754815
4776 const return_reg, const return_lock = try func.allocReg(.int);4816 const return_reg, const return_lock = try func.allocReg(.int);
4777 defer func.register_manager.unlockReg(return_lock);4817 defer func.register_manager.unlockReg(return_lock);
...@@ -4858,7 +4898,8 @@ fn isNonErr(func: *Func, inst: Air.Inst.Index, eu_ty: Type, eu_mcv: MCValue) !MC...@@ -4858,7 +4898,8 @@ fn isNonErr(func: *Func, inst: Air.Inst.Index, eu_ty: Type, eu_mcv: MCValue) !MC
4858}4898}
48594899
4860fn airIsNonErrPtr(func: *Func, inst: Air.Inst.Index) !void {4900fn airIsNonErrPtr(func: *Func, inst: Air.Inst.Index) !void {
4861 const zcu = func.bin_file.comp.module.?;4901 const pt = func.pt;
4902 const zcu = pt.zcu;
4862 const un_op = func.air.instructions.items(.data)[@intFromEnum(inst)].un_op;4903 const un_op = func.air.instructions.items(.data)[@intFromEnum(inst)].un_op;
4863 const result: MCValue = if (func.liveness.isUnused(inst)) .unreach else result: {4904 const result: MCValue = if (func.liveness.isUnused(inst)) .unreach else result: {
4864 const operand_ptr = try func.resolveInst(un_op);4905 const operand_ptr = try func.resolveInst(un_op);
...@@ -5063,12 +5104,12 @@ fn performReloc(func: *Func, inst: Mir.Inst.Index) void {...@@ -5063,12 +5104,12 @@ fn performReloc(func: *Func, inst: Mir.Inst.Index) void {
5063}5104}
50645105
5065fn airBr(func: *Func, inst: Air.Inst.Index) !void {5106fn airBr(func: *Func, inst: Air.Inst.Index) !void {
5066 const mod = func.bin_file.comp.module.?;5107 const pt = func.pt;
5067 const br = func.air.instructions.items(.data)[@intFromEnum(inst)].br;5108 const br = func.air.instructions.items(.data)[@intFromEnum(inst)].br;
50685109
5069 const block_ty = func.typeOfIndex(br.block_inst);5110 const block_ty = func.typeOfIndex(br.block_inst);
5070 const block_unused =5111 const block_unused =
5071 !block_ty.hasRuntimeBitsIgnoreComptime(mod) or func.liveness.isUnused(br.block_inst);5112 !block_ty.hasRuntimeBitsIgnoreComptime(pt) or func.liveness.isUnused(br.block_inst);
5072 const block_tracking = func.inst_tracking.getPtr(br.block_inst).?;5113 const block_tracking = func.inst_tracking.getPtr(br.block_inst).?;
5073 const block_data = func.blocks.getPtr(br.block_inst).?;5114 const block_data = func.blocks.getPtr(br.block_inst).?;
5074 const first_br = block_data.relocs.items.len == 0;5115 const first_br = block_data.relocs.items.len == 0;
...@@ -5288,8 +5329,6 @@ fn airAsm(func: *Func, inst: Air.Inst.Index) !void {...@@ -5288,8 +5329,6 @@ fn airAsm(func: *Func, inst: Air.Inst.Index) !void {
52885329
5289/// Sets the value of `dst_mcv` to the value of `src_mcv`.5330/// Sets the value of `dst_mcv` to the value of `src_mcv`.
5290fn genCopy(func: *Func, ty: Type, dst_mcv: MCValue, src_mcv: MCValue) !void {5331fn genCopy(func: *Func, ty: Type, dst_mcv: MCValue, src_mcv: MCValue) !void {
5291 const zcu = func.bin_file.comp.module.?;
5292
5293 // There isn't anything to store5332 // There isn't anything to store
5294 if (dst_mcv == .none) return;5333 if (dst_mcv == .none) return;
52955334
...@@ -5362,7 +5401,7 @@ fn genCopy(func: *Func, ty: Type, dst_mcv: MCValue, src_mcv: MCValue) !void {...@@ -5362,7 +5401,7 @@ fn genCopy(func: *Func, ty: Type, dst_mcv: MCValue, src_mcv: MCValue) !void {
5362 } },5401 } },
5363 else => unreachable,5402 else => unreachable,
5364 });5403 });
5365 part_disp += @intCast(dst_ty.abiSize(zcu));5404 part_disp += @intCast(dst_ty.abiSize(func.pt));
5366 }5405 }
5367 },5406 },
5368 else => return func.fail("TODO: genCopy to {s} from {s}", .{ @tagName(dst_mcv), @tagName(src_mcv) }),5407 else => return func.fail("TODO: genCopy to {s} from {s}", .{ @tagName(dst_mcv), @tagName(src_mcv) }),
...@@ -5555,8 +5594,9 @@ fn genInlineMemset(...@@ -5555,8 +5594,9 @@ fn genInlineMemset(
55555594
5556/// Sets the value of `src_mcv` into `reg`. Assumes you have a lock on it.5595/// Sets the value of `src_mcv` into `reg`. Assumes you have a lock on it.
5557fn genSetReg(func: *Func, ty: Type, reg: Register, src_mcv: MCValue) InnerError!void {5596fn genSetReg(func: *Func, ty: Type, reg: Register, src_mcv: MCValue) InnerError!void {
5558 const zcu = func.bin_file.comp.module.?;5597 const pt = func.pt;
5559 const abi_size: u32 = @intCast(ty.abiSize(zcu));5598 const zcu = pt.zcu;
5599 const abi_size: u32 = @intCast(ty.abiSize(pt));
55605600
5561 if (abi_size > 8) return std.debug.panic("tried to set reg with size {}", .{abi_size});5601 if (abi_size > 8) return std.debug.panic("tried to set reg with size {}", .{abi_size});
55625602
...@@ -5784,8 +5824,8 @@ fn genSetMem(...@@ -5784,8 +5824,8 @@ fn genSetMem(
5784 ty: Type,5824 ty: Type,
5785 src_mcv: MCValue,5825 src_mcv: MCValue,
5786) InnerError!void {5826) InnerError!void {
5787 const mod = func.bin_file.comp.module.?;5827 const pt = func.pt;
5788 const abi_size: u32 = @intCast(ty.abiSize(mod));5828 const abi_size: u32 = @intCast(ty.abiSize(pt));
5789 const dst_ptr_mcv: MCValue = switch (base) {5829 const dst_ptr_mcv: MCValue = switch (base) {
5790 .reg => |base_reg| .{ .register_offset = .{ .reg = base_reg, .off = disp } },5830 .reg => |base_reg| .{ .register_offset = .{ .reg = base_reg, .off = disp } },
5791 .frame => |base_frame_index| .{ .lea_frame = .{ .index = base_frame_index, .off = disp } },5831 .frame => |base_frame_index| .{ .lea_frame = .{ .index = base_frame_index, .off = disp } },
...@@ -5883,7 +5923,7 @@ fn genSetMem(...@@ -5883,7 +5923,7 @@ fn genSetMem(
5883 var part_disp: i32 = disp;5923 var part_disp: i32 = disp;
5884 for (try func.splitType(ty), src_regs) |src_ty, src_reg| {5924 for (try func.splitType(ty), src_regs) |src_ty, src_reg| {
5885 try func.genSetMem(base, part_disp, src_ty, .{ .register = src_reg });5925 try func.genSetMem(base, part_disp, src_ty, .{ .register = src_reg });
5886 part_disp += @intCast(src_ty.abiSize(mod));5926 part_disp += @intCast(src_ty.abiSize(pt));
5887 }5927 }
5888 },5928 },
5889 .immediate => {5929 .immediate => {
...@@ -5914,7 +5954,8 @@ fn airIntFromPtr(func: *Func, inst: Air.Inst.Index) !void {...@@ -5914,7 +5954,8 @@ fn airIntFromPtr(func: *Func, inst: Air.Inst.Index) !void {
5914}5954}
59155955
5916fn airBitCast(func: *Func, inst: Air.Inst.Index) !void {5956fn airBitCast(func: *Func, inst: Air.Inst.Index) !void {
5917 const zcu = func.bin_file.comp.module.?;5957 const pt = func.pt;
5958 const zcu = pt.zcu;
59185959
5919 const ty_op = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;5960 const ty_op = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
5920 const result = if (func.liveness.isUnused(inst)) .unreach else result: {5961 const result = if (func.liveness.isUnused(inst)) .unreach else result: {
...@@ -5926,10 +5967,10 @@ fn airBitCast(func: *Func, inst: Air.Inst.Index) !void {...@@ -5926,10 +5967,10 @@ fn airBitCast(func: *Func, inst: Air.Inst.Index) !void {
5926 const src_lock = if (src_mcv.getReg()) |reg| func.register_manager.lockReg(reg) else null;5967 const src_lock = if (src_mcv.getReg()) |reg| func.register_manager.lockReg(reg) else null;
5927 defer if (src_lock) |lock| func.register_manager.unlockReg(lock);5968 defer if (src_lock) |lock| func.register_manager.unlockReg(lock);
59285969
5929 const dst_mcv = if (dst_ty.abiSize(zcu) <= src_ty.abiSize(zcu) and5970 const dst_mcv = if (dst_ty.abiSize(pt) <= src_ty.abiSize(pt) and
5930 func.reuseOperand(inst, ty_op.operand, 0, src_mcv)) src_mcv else dst: {5971 func.reuseOperand(inst, ty_op.operand, 0, src_mcv)) src_mcv else dst: {
5931 const dst_mcv = try func.allocRegOrMem(dst_ty, inst, true);5972 const dst_mcv = try func.allocRegOrMem(dst_ty, inst, true);
5932 try func.genCopy(switch (math.order(dst_ty.abiSize(zcu), src_ty.abiSize(zcu))) {5973 try func.genCopy(switch (math.order(dst_ty.abiSize(pt), src_ty.abiSize(pt))) {
5933 .lt => dst_ty,5974 .lt => dst_ty,
5934 .eq => if (!dst_mcv.isMemory() or src_mcv.isMemory()) dst_ty else src_ty,5975 .eq => if (!dst_mcv.isMemory() or src_mcv.isMemory()) dst_ty else src_ty,
5935 .gt => src_ty,5976 .gt => src_ty,
...@@ -5940,17 +5981,18 @@ fn airBitCast(func: *Func, inst: Air.Inst.Index) !void {...@@ -5940,17 +5981,18 @@ fn airBitCast(func: *Func, inst: Air.Inst.Index) !void {
5940 if (dst_ty.isAbiInt(zcu) and src_ty.isAbiInt(zcu) and5981 if (dst_ty.isAbiInt(zcu) and src_ty.isAbiInt(zcu) and
5941 dst_ty.intInfo(zcu).signedness == src_ty.intInfo(zcu).signedness) break :result dst_mcv;5982 dst_ty.intInfo(zcu).signedness == src_ty.intInfo(zcu).signedness) break :result dst_mcv;
59425983
5943 const abi_size = dst_ty.abiSize(zcu);5984 const abi_size = dst_ty.abiSize(pt);
5944 const bit_size = dst_ty.bitSize(zcu);5985 const bit_size = dst_ty.bitSize(pt);
5945 if (abi_size * 8 <= bit_size) break :result dst_mcv;5986 if (abi_size * 8 <= bit_size) break :result dst_mcv;
59465987
5947 return func.fail("TODO: airBitCast {} to {}", .{ src_ty.fmt(zcu), dst_ty.fmt(zcu) });5988 return func.fail("TODO: airBitCast {} to {}", .{ src_ty.fmt(pt), dst_ty.fmt(pt) });
5948 };5989 };
5949 return func.finishAir(inst, result, .{ ty_op.operand, .none, .none });5990 return func.finishAir(inst, result, .{ ty_op.operand, .none, .none });
5950}5991}
59515992
5952fn airArrayToSlice(func: *Func, inst: Air.Inst.Index) !void {5993fn airArrayToSlice(func: *Func, inst: Air.Inst.Index) !void {
5953 const zcu = func.bin_file.comp.module.?;5994 const pt = func.pt;
5995 const zcu = pt.zcu;
5954 const ty_op = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;5996 const ty_op = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
59555997
5956 const slice_ty = func.typeOfIndex(inst);5998 const slice_ty = func.typeOfIndex(inst);
...@@ -5959,11 +6001,11 @@ fn airArrayToSlice(func: *Func, inst: Air.Inst.Index) !void {...@@ -5959,11 +6001,11 @@ fn airArrayToSlice(func: *Func, inst: Air.Inst.Index) !void {
5959 const array_ty = ptr_ty.childType(zcu);6001 const array_ty = ptr_ty.childType(zcu);
5960 const array_len = array_ty.arrayLen(zcu);6002 const array_len = array_ty.arrayLen(zcu);
59616003
5962 const frame_index = try func.allocFrameIndex(FrameAlloc.initSpill(slice_ty, zcu));6004 const frame_index = try func.allocFrameIndex(FrameAlloc.initSpill(slice_ty, pt));
5963 try func.genSetMem(.{ .frame = frame_index }, 0, ptr_ty, ptr);6005 try func.genSetMem(.{ .frame = frame_index }, 0, ptr_ty, ptr);
5964 try func.genSetMem(6006 try func.genSetMem(
5965 .{ .frame = frame_index },6007 .{ .frame = frame_index },
5966 @intCast(ptr_ty.abiSize(zcu)),6008 @intCast(ptr_ty.abiSize(pt)),
5967 Type.usize,6009 Type.usize,
5968 .{ .immediate = array_len },6010 .{ .immediate = array_len },
5969 );6011 );
...@@ -6015,7 +6057,8 @@ fn airAtomicStore(func: *Func, inst: Air.Inst.Index, order: std.builtin.AtomicOr...@@ -6015,7 +6057,8 @@ fn airAtomicStore(func: *Func, inst: Air.Inst.Index, order: std.builtin.AtomicOr
6015}6057}
60166058
6017fn airMemset(func: *Func, inst: Air.Inst.Index, safety: bool) !void {6059fn airMemset(func: *Func, inst: Air.Inst.Index, safety: bool) !void {
6018 const zcu = func.bin_file.comp.module.?;6060 const pt = func.pt;
6061 const zcu = pt.zcu;
6019 const bin_op = func.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;6062 const bin_op = func.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
60206063
6021 result: {6064 result: {
...@@ -6037,7 +6080,7 @@ fn airMemset(func: *Func, inst: Air.Inst.Index, safety: bool) !void {...@@ -6037,7 +6080,7 @@ fn airMemset(func: *Func, inst: Air.Inst.Index, safety: bool) !void {
6037 };6080 };
6038 defer if (src_val_lock) |lock| func.register_manager.unlockReg(lock);6081 defer if (src_val_lock) |lock| func.register_manager.unlockReg(lock);
60396082
6040 const elem_abi_size: u31 = @intCast(elem_ty.abiSize(zcu));6083 const elem_abi_size: u31 = @intCast(elem_ty.abiSize(pt));
60416084
6042 if (elem_abi_size == 1) {6085 if (elem_abi_size == 1) {
6043 const ptr: MCValue = switch (dst_ptr_ty.ptrSize(zcu)) {6086 const ptr: MCValue = switch (dst_ptr_ty.ptrSize(zcu)) {
...@@ -6068,7 +6111,7 @@ fn airMemset(func: *Func, inst: Air.Inst.Index, safety: bool) !void {...@@ -6068,7 +6111,7 @@ fn airMemset(func: *Func, inst: Air.Inst.Index, safety: bool) !void {
6068 switch (dst_ptr_ty.ptrSize(zcu)) {6111 switch (dst_ptr_ty.ptrSize(zcu)) {
6069 .Slice => return func.fail("TODO: airMemset Slices", .{}),6112 .Slice => return func.fail("TODO: airMemset Slices", .{}),
6070 .One => {6113 .One => {
6071 const elem_ptr_ty = try zcu.singleMutPtrType(elem_ty);6114 const elem_ptr_ty = try pt.singleMutPtrType(elem_ty);
60726115
6073 const len = dst_ptr_ty.childType(zcu).arrayLen(zcu);6116 const len = dst_ptr_ty.childType(zcu).arrayLen(zcu);
60746117
...@@ -6110,7 +6153,8 @@ fn airTagName(func: *Func, inst: Air.Inst.Index) !void {...@@ -6110,7 +6153,8 @@ fn airTagName(func: *Func, inst: Air.Inst.Index) !void {
6110}6153}
61116154
6112fn airErrorName(func: *Func, inst: Air.Inst.Index) !void {6155fn airErrorName(func: *Func, inst: Air.Inst.Index) !void {
6113 const zcu = func.bin_file.comp.module.?;6156 const pt = func.pt;
6157 const zcu = pt.zcu;
6114 const un_op = func.air.instructions.items(.data)[@intFromEnum(inst)].un_op;6158 const un_op = func.air.instructions.items(.data)[@intFromEnum(inst)].un_op;
61156159
6116 const err_ty = func.typeOf(un_op);6160 const err_ty = func.typeOf(un_op);
...@@ -6126,7 +6170,7 @@ fn airErrorName(func: *Func, inst: Air.Inst.Index) !void {...@@ -6126,7 +6170,7 @@ fn airErrorName(func: *Func, inst: Air.Inst.Index) !void {
6126 // this is now the base address of the error name table6170 // this is now the base address of the error name table
6127 const lazy_sym = link.File.LazySymbol.initDecl(.const_data, null, zcu);6171 const lazy_sym = link.File.LazySymbol.initDecl(.const_data, null, zcu);
6128 if (func.bin_file.cast(link.File.Elf)) |elf_file| {6172 if (func.bin_file.cast(link.File.Elf)) |elf_file| {
6129 const sym_index = elf_file.zigObjectPtr().?.getOrCreateMetadataForLazySymbol(elf_file, lazy_sym) catch |err|6173 const sym_index = elf_file.zigObjectPtr().?.getOrCreateMetadataForLazySymbol(elf_file, pt, lazy_sym) catch |err|
6130 return func.fail("{s} creating lazy symbol", .{@errorName(err)});6174 return func.fail("{s} creating lazy symbol", .{@errorName(err)});
6131 const sym = elf_file.symbol(sym_index);6175 const sym = elf_file.symbol(sym_index);
6132 try func.genSetReg(Type.usize, addr_reg, .{ .load_symbol = .{ .sym = sym.esym_index } });6176 try func.genSetReg(Type.usize, addr_reg, .{ .load_symbol = .{ .sym = sym.esym_index } });
...@@ -6239,7 +6283,8 @@ fn airReduce(func: *Func, inst: Air.Inst.Index) !void {...@@ -6239,7 +6283,8 @@ fn airReduce(func: *Func, inst: Air.Inst.Index) !void {
6239}6283}
62406284
6241fn airAggregateInit(func: *Func, inst: Air.Inst.Index) !void {6285fn airAggregateInit(func: *Func, inst: Air.Inst.Index) !void {
6242 const zcu = func.bin_file.comp.module.?;6286 const pt = func.pt;
6287 const zcu = pt.zcu;
6243 const result_ty = func.typeOfIndex(inst);6288 const result_ty = func.typeOfIndex(inst);
6244 const len: usize = @intCast(result_ty.arrayLen(zcu));6289 const len: usize = @intCast(result_ty.arrayLen(zcu));
6245 const ty_pl = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;6290 const ty_pl = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
...@@ -6248,21 +6293,21 @@ fn airAggregateInit(func: *Func, inst: Air.Inst.Index) !void {...@@ -6248,21 +6293,21 @@ fn airAggregateInit(func: *Func, inst: Air.Inst.Index) !void {
6248 const result: MCValue = result: {6293 const result: MCValue = result: {
6249 switch (result_ty.zigTypeTag(zcu)) {6294 switch (result_ty.zigTypeTag(zcu)) {
6250 .Struct => {6295 .Struct => {
6251 const frame_index = try func.allocFrameIndex(FrameAlloc.initSpill(result_ty, zcu));6296 const frame_index = try func.allocFrameIndex(FrameAlloc.initSpill(result_ty, pt));
6252 if (result_ty.containerLayout(zcu) == .@"packed") {6297 if (result_ty.containerLayout(zcu) == .@"packed") {
6253 const struct_obj = zcu.typeToStruct(result_ty).?;6298 const struct_obj = zcu.typeToStruct(result_ty).?;
6254 try func.genInlineMemset(6299 try func.genInlineMemset(
6255 .{ .lea_frame = .{ .index = frame_index } },6300 .{ .lea_frame = .{ .index = frame_index } },
6256 .{ .immediate = 0 },6301 .{ .immediate = 0 },
6257 .{ .immediate = result_ty.abiSize(zcu) },6302 .{ .immediate = result_ty.abiSize(pt) },
6258 );6303 );
62596304
6260 for (elements, 0..) |elem, elem_i_usize| {6305 for (elements, 0..) |elem, elem_i_usize| {
6261 const elem_i: u32 = @intCast(elem_i_usize);6306 const elem_i: u32 = @intCast(elem_i_usize);
6262 if ((try result_ty.structFieldValueComptime(zcu, elem_i)) != null) continue;6307 if ((try result_ty.structFieldValueComptime(pt, elem_i)) != null) continue;
62636308
6264 const elem_ty = result_ty.structFieldType(elem_i, zcu);6309 const elem_ty = result_ty.structFieldType(elem_i, zcu);
6265 const elem_bit_size: u32 = @intCast(elem_ty.bitSize(zcu));6310 const elem_bit_size: u32 = @intCast(elem_ty.bitSize(pt));
6266 if (elem_bit_size > 64) {6311 if (elem_bit_size > 64) {
6267 return func.fail(6312 return func.fail(
6268 "TODO airAggregateInit implement packed structs with large fields",6313 "TODO airAggregateInit implement packed structs with large fields",
...@@ -6270,9 +6315,9 @@ fn airAggregateInit(func: *Func, inst: Air.Inst.Index) !void {...@@ -6270,9 +6315,9 @@ fn airAggregateInit(func: *Func, inst: Air.Inst.Index) !void {
6270 );6315 );
6271 }6316 }
62726317
6273 const elem_abi_size: u32 = @intCast(elem_ty.abiSize(zcu));6318 const elem_abi_size: u32 = @intCast(elem_ty.abiSize(pt));
6274 const elem_abi_bits = elem_abi_size * 8;6319 const elem_abi_bits = elem_abi_size * 8;
6275 const elem_off = zcu.structPackedFieldBitOffset(struct_obj, elem_i);6320 const elem_off = pt.structPackedFieldBitOffset(struct_obj, elem_i);
6276 const elem_byte_off: i32 = @intCast(elem_off / elem_abi_bits * elem_abi_size);6321 const elem_byte_off: i32 = @intCast(elem_off / elem_abi_bits * elem_abi_size);
6277 const elem_bit_off = elem_off % elem_abi_bits;6322 const elem_bit_off = elem_off % elem_abi_bits;
6278 const elem_mcv = try func.resolveInst(elem);6323 const elem_mcv = try func.resolveInst(elem);
...@@ -6293,10 +6338,10 @@ fn airAggregateInit(func: *Func, inst: Air.Inst.Index) !void {...@@ -6293,10 +6338,10 @@ fn airAggregateInit(func: *Func, inst: Air.Inst.Index) !void {
6293 return func.fail("TODO: airAggregateInit packed structs", .{});6338 return func.fail("TODO: airAggregateInit packed structs", .{});
6294 }6339 }
6295 } else for (elements, 0..) |elem, elem_i| {6340 } else for (elements, 0..) |elem, elem_i| {
6296 if ((try result_ty.structFieldValueComptime(zcu, elem_i)) != null) continue;6341 if ((try result_ty.structFieldValueComptime(pt, elem_i)) != null) continue;
62976342
6298 const elem_ty = result_ty.structFieldType(elem_i, zcu);6343 const elem_ty = result_ty.structFieldType(elem_i, zcu);
6299 const elem_off: i32 = @intCast(result_ty.structFieldOffset(elem_i, zcu));6344 const elem_off: i32 = @intCast(result_ty.structFieldOffset(elem_i, pt));
6300 const elem_mcv = try func.resolveInst(elem);6345 const elem_mcv = try func.resolveInst(elem);
6301 try func.genSetMem(.{ .frame = frame_index }, elem_off, elem_ty, elem_mcv);6346 try func.genSetMem(.{ .frame = frame_index }, elem_off, elem_ty, elem_mcv);
6302 }6347 }
...@@ -6304,8 +6349,8 @@ fn airAggregateInit(func: *Func, inst: Air.Inst.Index) !void {...@@ -6304,8 +6349,8 @@ fn airAggregateInit(func: *Func, inst: Air.Inst.Index) !void {
6304 },6349 },
6305 .Array => {6350 .Array => {
6306 const elem_ty = result_ty.childType(zcu);6351 const elem_ty = result_ty.childType(zcu);
6307 const frame_index = try func.allocFrameIndex(FrameAlloc.initSpill(result_ty, zcu));6352 const frame_index = try func.allocFrameIndex(FrameAlloc.initSpill(result_ty, pt));
6308 const elem_size: u32 = @intCast(elem_ty.abiSize(zcu));6353 const elem_size: u32 = @intCast(elem_ty.abiSize(pt));
63096354
6310 for (elements, 0..) |elem, elem_i| {6355 for (elements, 0..) |elem, elem_i| {
6311 const elem_mcv = try func.resolveInst(elem);6356 const elem_mcv = try func.resolveInst(elem);
...@@ -6325,7 +6370,7 @@ fn airAggregateInit(func: *Func, inst: Air.Inst.Index) !void {...@@ -6325,7 +6370,7 @@ fn airAggregateInit(func: *Func, inst: Air.Inst.Index) !void {
6325 );6370 );
6326 break :result .{ .load_frame = .{ .index = frame_index } };6371 break :result .{ .load_frame = .{ .index = frame_index } };
6327 },6372 },
6328 else => return func.fail("TODO: airAggregate {}", .{result_ty.fmt(zcu)}),6373 else => return func.fail("TODO: airAggregate {}", .{result_ty.fmt(pt)}),
6329 }6374 }
6330 };6375 };
63316376
...@@ -6364,11 +6409,11 @@ fn airMulAdd(func: *Func, inst: Air.Inst.Index) !void {...@@ -6364,11 +6409,11 @@ fn airMulAdd(func: *Func, inst: Air.Inst.Index) !void {
6364}6409}
63656410
6366fn resolveInst(func: *Func, ref: Air.Inst.Ref) InnerError!MCValue {6411fn resolveInst(func: *Func, ref: Air.Inst.Ref) InnerError!MCValue {
6367 const zcu = func.bin_file.comp.module.?;6412 const pt = func.pt;
63686413
6369 // If the type has no codegen bits, no need to store it.6414 // If the type has no codegen bits, no need to store it.
6370 const inst_ty = func.typeOf(ref);6415 const inst_ty = func.typeOf(ref);
6371 if (!inst_ty.hasRuntimeBits(zcu))6416 if (!inst_ty.hasRuntimeBits(pt))
6372 return .none;6417 return .none;
63736418
6374 const mcv = if (ref.toIndex()) |inst| mcv: {6419 const mcv = if (ref.toIndex()) |inst| mcv: {
...@@ -6394,9 +6439,11 @@ fn getResolvedInstValue(func: *Func, inst: Air.Inst.Index) *InstTracking {...@@ -6394,9 +6439,11 @@ fn getResolvedInstValue(func: *Func, inst: Air.Inst.Index) *InstTracking {
6394}6439}
63956440
6396fn genTypedValue(func: *Func, val: Value) InnerError!MCValue {6441fn genTypedValue(func: *Func, val: Value) InnerError!MCValue {
6397 const zcu = func.bin_file.comp.module.?;6442 const pt = func.pt;
6443 const zcu = pt.zcu;
6398 const result = try codegen.genTypedValue(6444 const result = try codegen.genTypedValue(
6399 func.bin_file,6445 func.bin_file,
6446 pt,
6400 func.src_loc,6447 func.src_loc,
6401 val,6448 val,
6402 zcu.funcOwnerDeclIndex(func.func_index),6449 zcu.funcOwnerDeclIndex(func.func_index),
...@@ -6438,7 +6485,8 @@ fn resolveCallingConventionValues(...@@ -6438,7 +6485,8 @@ fn resolveCallingConventionValues(
6438 fn_info: InternPool.Key.FuncType,6485 fn_info: InternPool.Key.FuncType,
6439 var_args: []const Type,6486 var_args: []const Type,
6440) !CallMCValues {6487) !CallMCValues {
6441 const zcu = func.bin_file.comp.module.?;6488 const pt = func.pt;
6489 const zcu = pt.zcu;
6442 const ip = &zcu.intern_pool;6490 const ip = &zcu.intern_pool;
64436491
6444 const param_types = try func.gpa.alloc(Type, fn_info.param_types.len + var_args.len);6492 const param_types = try func.gpa.alloc(Type, fn_info.param_types.len + var_args.len);
...@@ -6481,14 +6529,14 @@ fn resolveCallingConventionValues(...@@ -6481,14 +6529,14 @@ fn resolveCallingConventionValues(
6481 // Return values6529 // Return values
6482 if (ret_ty.zigTypeTag(zcu) == .NoReturn) {6530 if (ret_ty.zigTypeTag(zcu) == .NoReturn) {
6483 result.return_value = InstTracking.init(.unreach);6531 result.return_value = InstTracking.init(.unreach);
6484 } else if (!ret_ty.hasRuntimeBitsIgnoreComptime(zcu)) {6532 } else if (!ret_ty.hasRuntimeBitsIgnoreComptime(pt)) {
6485 result.return_value = InstTracking.init(.none);6533 result.return_value = InstTracking.init(.none);
6486 } else {6534 } else {
6487 var ret_tracking: [2]InstTracking = undefined;6535 var ret_tracking: [2]InstTracking = undefined;
6488 var ret_tracking_i: usize = 0;6536 var ret_tracking_i: usize = 0;
6489 var ret_float_reg_i: usize = 0;6537 var ret_float_reg_i: usize = 0;
64906538
6491 const classes = mem.sliceTo(&abi.classifySystem(ret_ty, zcu), .none);6539 const classes = mem.sliceTo(&abi.classifySystem(ret_ty, pt), .none);
64926540
6493 for (classes) |class| switch (class) {6541 for (classes) |class| switch (class) {
6494 .integer => {6542 .integer => {
...@@ -6521,7 +6569,7 @@ fn resolveCallingConventionValues(...@@ -6521,7 +6569,7 @@ fn resolveCallingConventionValues(
6521 };6569 };
65226570
6523 result.return_value = switch (ret_tracking_i) {6571 result.return_value = switch (ret_tracking_i) {
6524 else => return func.fail("ty {} took {} tracking return indices", .{ ret_ty.fmt(zcu), ret_tracking_i }),6572 else => return func.fail("ty {} took {} tracking return indices", .{ ret_ty.fmt(pt), ret_tracking_i }),
6525 1 => ret_tracking[0],6573 1 => ret_tracking[0],
6526 2 => InstTracking.init(.{ .register_pair = .{6574 2 => InstTracking.init(.{ .register_pair = .{
6527 ret_tracking[0].short.register, ret_tracking[1].short.register,6575 ret_tracking[0].short.register, ret_tracking[1].short.register,
...@@ -6532,7 +6580,7 @@ fn resolveCallingConventionValues(...@@ -6532,7 +6580,7 @@ fn resolveCallingConventionValues(
6532 var param_float_reg_i: usize = 0;6580 var param_float_reg_i: usize = 0;
65336581
6534 for (param_types, result.args) |ty, *arg| {6582 for (param_types, result.args) |ty, *arg| {
6535 if (!ty.hasRuntimeBitsIgnoreComptime(zcu)) {6583 if (!ty.hasRuntimeBitsIgnoreComptime(pt)) {
6536 assert(cc == .Unspecified);6584 assert(cc == .Unspecified);
6537 arg.* = .none;6585 arg.* = .none;
6538 continue;6586 continue;
...@@ -6541,7 +6589,7 @@ fn resolveCallingConventionValues(...@@ -6541,7 +6589,7 @@ fn resolveCallingConventionValues(
6541 var arg_mcv: [2]MCValue = undefined;6589 var arg_mcv: [2]MCValue = undefined;
6542 var arg_mcv_i: usize = 0;6590 var arg_mcv_i: usize = 0;
65436591
6544 const classes = mem.sliceTo(&abi.classifySystem(ty, zcu), .none);6592 const classes = mem.sliceTo(&abi.classifySystem(ty, pt), .none);
65456593
6546 for (classes) |class| switch (class) {6594 for (classes) |class| switch (class) {
6547 .integer => {6595 .integer => {
...@@ -6576,7 +6624,7 @@ fn resolveCallingConventionValues(...@@ -6576,7 +6624,7 @@ fn resolveCallingConventionValues(
6576 else => return func.fail("TODO: C calling convention arg class {}", .{class}),6624 else => return func.fail("TODO: C calling convention arg class {}", .{class}),
6577 } else {6625 } else {
6578 arg.* = switch (arg_mcv_i) {6626 arg.* = switch (arg_mcv_i) {
6579 else => return func.fail("ty {} took {} tracking arg indices", .{ ty.fmt(zcu), arg_mcv_i }),6627 else => return func.fail("ty {} took {} tracking arg indices", .{ ty.fmt(pt), arg_mcv_i }),
6580 1 => arg_mcv[0],6628 1 => arg_mcv[0],
6581 2 => .{ .register_pair = .{ arg_mcv[0].register, arg_mcv[1].register } },6629 2 => .{ .register_pair = .{ arg_mcv[0].register, arg_mcv[1].register } },
6582 };6630 };
...@@ -6621,12 +6669,14 @@ fn parseRegName(name: []const u8) ?Register {...@@ -6621,12 +6669,14 @@ fn parseRegName(name: []const u8) ?Register {
6621}6669}
66226670
6623fn typeOf(func: *Func, inst: Air.Inst.Ref) Type {6671fn typeOf(func: *Func, inst: Air.Inst.Ref) Type {
6624 const zcu = func.bin_file.comp.module.?;6672 const pt = func.pt;
6673 const zcu = pt.zcu;
6625 return func.air.typeOf(inst, &zcu.intern_pool);6674 return func.air.typeOf(inst, &zcu.intern_pool);
6626}6675}
66276676
6628fn typeOfIndex(func: *Func, inst: Air.Inst.Index) Type {6677fn typeOfIndex(func: *Func, inst: Air.Inst.Index) Type {
6629 const zcu = func.bin_file.comp.module.?;6678 const pt = func.pt;
6679 const zcu = pt.zcu;
6630 return func.air.typeOfIndex(inst, &zcu.intern_pool);6680 return func.air.typeOfIndex(inst, &zcu.intern_pool);
6631}6681}
66326682
...@@ -6634,40 +6684,41 @@ fn hasFeature(func: *Func, feature: Target.riscv.Feature) bool {...@@ -6634,40 +6684,41 @@ fn hasFeature(func: *Func, feature: Target.riscv.Feature) bool {
6634 return Target.riscv.featureSetHas(func.target.cpu.features, feature);6684 return Target.riscv.featureSetHas(func.target.cpu.features, feature);
6635}6685}
66366686
6637pub fn errUnionPayloadOffset(payload_ty: Type, zcu: *Zcu) u64 {6687pub fn errUnionPayloadOffset(payload_ty: Type, pt: Zcu.PerThread) u64 {
6638 if (!payload_ty.hasRuntimeBitsIgnoreComptime(zcu)) return 0;6688 if (!payload_ty.hasRuntimeBitsIgnoreComptime(pt)) return 0;
6639 const payload_align = payload_ty.abiAlignment(zcu);6689 const payload_align = payload_ty.abiAlignment(pt);
6640 const error_align = Type.anyerror.abiAlignment(zcu);6690 const error_align = Type.anyerror.abiAlignment(pt);
6641 if (payload_align.compare(.gte, error_align) or !payload_ty.hasRuntimeBitsIgnoreComptime(zcu)) {6691 if (payload_align.compare(.gte, error_align) or !payload_ty.hasRuntimeBitsIgnoreComptime(pt)) {
6642 return 0;6692 return 0;
6643 } else {6693 } else {
6644 return payload_align.forward(Type.anyerror.abiSize(zcu));6694 return payload_align.forward(Type.anyerror.abiSize(pt));
6645 }6695 }
6646}6696}
66476697
6648pub fn errUnionErrorOffset(payload_ty: Type, zcu: *Zcu) u64 {6698pub fn errUnionErrorOffset(payload_ty: Type, pt: Zcu.PerThread) u64 {
6649 if (!payload_ty.hasRuntimeBitsIgnoreComptime(zcu)) return 0;6699 if (!payload_ty.hasRuntimeBitsIgnoreComptime(pt)) return 0;
6650 const payload_align = payload_ty.abiAlignment(zcu);6700 const payload_align = payload_ty.abiAlignment(pt);
6651 const error_align = Type.anyerror.abiAlignment(zcu);6701 const error_align = Type.anyerror.abiAlignment(pt);
6652 if (payload_align.compare(.gte, error_align) and payload_ty.hasRuntimeBitsIgnoreComptime(zcu)) {6702 if (payload_align.compare(.gte, error_align) and payload_ty.hasRuntimeBitsIgnoreComptime(pt)) {
6653 return error_align.forward(payload_ty.abiSize(zcu));6703 return error_align.forward(payload_ty.abiSize(pt));
6654 } else {6704 } else {
6655 return 0;6705 return 0;
6656 }6706 }
6657}6707}
66586708
6659fn promoteInt(func: *Func, ty: Type) Type {6709fn promoteInt(func: *Func, ty: Type) Type {
6660 const mod = func.bin_file.comp.module.?;6710 const pt = func.pt;
6711 const zcu = pt.zcu;
6661 const int_info: InternPool.Key.IntType = switch (ty.toIntern()) {6712 const int_info: InternPool.Key.IntType = switch (ty.toIntern()) {
6662 .bool_type => .{ .signedness = .unsigned, .bits = 1 },6713 .bool_type => .{ .signedness = .unsigned, .bits = 1 },
6663 else => if (ty.isAbiInt(mod)) ty.intInfo(mod) else return ty,6714 else => if (ty.isAbiInt(zcu)) ty.intInfo(zcu) else return ty,
6664 };6715 };
6665 for ([_]Type{6716 for ([_]Type{
6666 Type.c_int, Type.c_uint,6717 Type.c_int, Type.c_uint,
6667 Type.c_long, Type.c_ulong,6718 Type.c_long, Type.c_ulong,
6668 Type.c_longlong, Type.c_ulonglong,6719 Type.c_longlong, Type.c_ulonglong,
6669 }) |promote_ty| {6720 }) |promote_ty| {
6670 const promote_info = promote_ty.intInfo(mod);6721 const promote_info = promote_ty.intInfo(zcu);
6671 if (int_info.signedness == .signed and promote_info.signedness == .unsigned) continue;6722 if (int_info.signedness == .signed and promote_info.signedness == .unsigned) continue;
6672 if (int_info.bits + @intFromBool(int_info.signedness == .unsigned and6723 if (int_info.bits + @intFromBool(int_info.signedness == .unsigned and
6673 promote_info.signedness == .signed) <= promote_info.bits) return promote_ty;6724 promote_info.signedness == .signed) <= promote_info.bits) return promote_ty;
src/arch/riscv64/Emit.zig+3-2
...@@ -1,5 +1,6 @@...@@ -1,5 +1,6 @@
1//! This file contains the functionality for emitting RISC-V MIR as machine code1//! This file contains the functionality for emitting RISC-V MIR as machine code
22
3bin_file: *link.File,
3lower: Lower,4lower: Lower,
4debug_output: DebugInfoOutput,5debug_output: DebugInfoOutput,
5code: *std.ArrayList(u8),6code: *std.ArrayList(u8),
...@@ -48,7 +49,7 @@ pub fn emitMir(emit: *Emit) Error!void {...@@ -48,7 +49,7 @@ pub fn emitMir(emit: *Emit) Error!void {
48 .Lib => emit.lower.link_mode == .static,49 .Lib => emit.lower.link_mode == .static,
49 };50 };
5051
51 if (emit.lower.bin_file.cast(link.File.Elf)) |elf_file| {52 if (emit.bin_file.cast(link.File.Elf)) |elf_file| {
52 const atom_ptr = elf_file.symbol(symbol.atom_index).atom(elf_file).?;53 const atom_ptr = elf_file.symbol(symbol.atom_index).atom(elf_file).?;
53 const sym_index = elf_file.zigObjectPtr().?.symbol(symbol.sym_index);54 const sym_index = elf_file.zigObjectPtr().?.symbol(symbol.sym_index);
54 const sym = elf_file.symbol(sym_index);55 const sym = elf_file.symbol(sym_index);
...@@ -77,7 +78,7 @@ pub fn emitMir(emit: *Emit) Error!void {...@@ -77,7 +78,7 @@ pub fn emitMir(emit: *Emit) Error!void {
77 } else return emit.fail("TODO: load_symbol_reloc non-ELF", .{});78 } else return emit.fail("TODO: load_symbol_reloc non-ELF", .{});
78 },79 },
79 .call_extern_fn_reloc => |symbol| {80 .call_extern_fn_reloc => |symbol| {
80 if (emit.lower.bin_file.cast(link.File.Elf)) |elf_file| {81 if (emit.bin_file.cast(link.File.Elf)) |elf_file| {
81 const atom_ptr = elf_file.symbol(symbol.atom_index).atom(elf_file).?;82 const atom_ptr = elf_file.symbol(symbol.atom_index).atom(elf_file).?;
8283
83 const r_type: u32 = @intFromEnum(std.elf.R_RISCV.CALL_PLT);84 const r_type: u32 = @intFromEnum(std.elf.R_RISCV.CALL_PLT);
src/arch/riscv64/Lower.zig+6-6
...@@ -1,6 +1,6 @@...@@ -1,6 +1,6 @@
1//! This file contains the functionality for lowering RISC-V MIR to Instructions1//! This file contains the functionality for lowering RISC-V MIR to Instructions
22
3bin_file: *link.File,3pt: Zcu.PerThread,
4output_mode: std.builtin.OutputMode,4output_mode: std.builtin.OutputMode,
5link_mode: std.builtin.LinkMode,5link_mode: std.builtin.LinkMode,
6pic: bool,6pic: bool,
...@@ -44,7 +44,7 @@ pub fn lowerMir(lower: *Lower, index: Mir.Inst.Index) Error!struct {...@@ -44,7 +44,7 @@ pub fn lowerMir(lower: *Lower, index: Mir.Inst.Index) Error!struct {
44 insts: []const Instruction,44 insts: []const Instruction,
45 relocs: []const Reloc,45 relocs: []const Reloc,
46} {46} {
47 const zcu = lower.bin_file.comp.module.?;47 const pt = lower.pt;
4848
49 lower.result_insts = undefined;49 lower.result_insts = undefined;
50 lower.result_relocs = undefined;50 lower.result_relocs = undefined;
...@@ -243,11 +243,11 @@ pub fn lowerMir(lower: *Lower, index: Mir.Inst.Index) Error!struct {...@@ -243,11 +243,11 @@ pub fn lowerMir(lower: *Lower, index: Mir.Inst.Index) Error!struct {
243243
244 const class = rs1.class();244 const class = rs1.class();
245 const ty = compare.ty;245 const ty = compare.ty;
246 const size = std.math.ceilPowerOfTwo(u64, ty.bitSize(zcu)) catch {246 const size = std.math.ceilPowerOfTwo(u64, ty.bitSize(pt)) catch {
247 return lower.fail("pseudo_compare size {}", .{ty.bitSize(zcu)});247 return lower.fail("pseudo_compare size {}", .{ty.bitSize(pt)});
248 };248 };
249249
250 const is_unsigned = ty.isUnsignedInt(zcu);250 const is_unsigned = ty.isUnsignedInt(pt.zcu);
251251
252 const less_than: Encoding.Mnemonic = if (is_unsigned) .sltu else .slt;252 const less_than: Encoding.Mnemonic = if (is_unsigned) .sltu else .slt;
253253
...@@ -502,7 +502,7 @@ pub fn fail(lower: *Lower, comptime format: []const u8, args: anytype) Error {...@@ -502,7 +502,7 @@ pub fn fail(lower: *Lower, comptime format: []const u8, args: anytype) Error {
502}502}
503503
504fn hasFeature(lower: *Lower, feature: std.Target.riscv.Feature) bool {504fn hasFeature(lower: *Lower, feature: std.Target.riscv.Feature) bool {
505 const target = lower.bin_file.comp.module.?.getTarget();505 const target = lower.pt.zcu.getTarget();
506 const features = target.cpu.features;506 const features = target.cpu.features;
507 return std.Target.riscv.featureSetHas(features, feature);507 return std.Target.riscv.featureSetHas(features, feature);
508}508}
src/arch/riscv64/abi.zig+28-27
...@@ -9,15 +9,15 @@ const assert = std.debug.assert;...@@ -9,15 +9,15 @@ const assert = std.debug.assert;
99
10pub const Class = enum { memory, byval, integer, double_integer, fields };10pub const Class = enum { memory, byval, integer, double_integer, fields };
1111
12pub fn classifyType(ty: Type, mod: *Zcu) Class {12pub fn classifyType(ty: Type, pt: Zcu.PerThread) Class {
13 const target = mod.getTarget();13 const target = pt.zcu.getTarget();
14 std.debug.assert(ty.hasRuntimeBitsIgnoreComptime(mod));14 std.debug.assert(ty.hasRuntimeBitsIgnoreComptime(pt));
1515
16 const max_byval_size = target.ptrBitWidth() * 2;16 const max_byval_size = target.ptrBitWidth() * 2;
17 switch (ty.zigTypeTag(mod)) {17 switch (ty.zigTypeTag(pt.zcu)) {
18 .Struct => {18 .Struct => {
19 const bit_size = ty.bitSize(mod);19 const bit_size = ty.bitSize(pt);
20 if (ty.containerLayout(mod) == .@"packed") {20 if (ty.containerLayout(pt.zcu) == .@"packed") {
21 if (bit_size > max_byval_size) return .memory;21 if (bit_size > max_byval_size) return .memory;
22 return .byval;22 return .byval;
23 }23 }
...@@ -25,12 +25,12 @@ pub fn classifyType(ty: Type, mod: *Zcu) Class {...@@ -25,12 +25,12 @@ pub fn classifyType(ty: Type, mod: *Zcu) Class {
25 if (std.Target.riscv.featureSetHas(target.cpu.features, .d)) fields: {25 if (std.Target.riscv.featureSetHas(target.cpu.features, .d)) fields: {
26 var any_fp = false;26 var any_fp = false;
27 var field_count: usize = 0;27 var field_count: usize = 0;
28 for (0..ty.structFieldCount(mod)) |field_index| {28 for (0..ty.structFieldCount(pt.zcu)) |field_index| {
29 const field_ty = ty.structFieldType(field_index, mod);29 const field_ty = ty.structFieldType(field_index, pt.zcu);
30 if (!field_ty.hasRuntimeBitsIgnoreComptime(mod)) continue;30 if (!field_ty.hasRuntimeBitsIgnoreComptime(pt)) continue;
31 if (field_ty.isRuntimeFloat())31 if (field_ty.isRuntimeFloat())
32 any_fp = true32 any_fp = true
33 else if (!field_ty.isAbiInt(mod))33 else if (!field_ty.isAbiInt(pt.zcu))
34 break :fields;34 break :fields;
35 field_count += 1;35 field_count += 1;
36 if (field_count > 2) break :fields;36 if (field_count > 2) break :fields;
...@@ -45,8 +45,8 @@ pub fn classifyType(ty: Type, mod: *Zcu) Class {...@@ -45,8 +45,8 @@ pub fn classifyType(ty: Type, mod: *Zcu) Class {
45 return .integer;45 return .integer;
46 },46 },
47 .Union => {47 .Union => {
48 const bit_size = ty.bitSize(mod);48 const bit_size = ty.bitSize(pt);
49 if (ty.containerLayout(mod) == .@"packed") {49 if (ty.containerLayout(pt.zcu) == .@"packed") {
50 if (bit_size > max_byval_size) return .memory;50 if (bit_size > max_byval_size) return .memory;
51 return .byval;51 return .byval;
52 }52 }
...@@ -58,21 +58,21 @@ pub fn classifyType(ty: Type, mod: *Zcu) Class {...@@ -58,21 +58,21 @@ pub fn classifyType(ty: Type, mod: *Zcu) Class {
58 .Bool => return .integer,58 .Bool => return .integer,
59 .Float => return .byval,59 .Float => return .byval,
60 .Int, .Enum, .ErrorSet => {60 .Int, .Enum, .ErrorSet => {
61 const bit_size = ty.bitSize(mod);61 const bit_size = ty.bitSize(pt);
62 if (bit_size > max_byval_size) return .memory;62 if (bit_size > max_byval_size) return .memory;
63 return .byval;63 return .byval;
64 },64 },
65 .Vector => {65 .Vector => {
66 const bit_size = ty.bitSize(mod);66 const bit_size = ty.bitSize(pt);
67 if (bit_size > max_byval_size) return .memory;67 if (bit_size > max_byval_size) return .memory;
68 return .integer;68 return .integer;
69 },69 },
70 .Optional => {70 .Optional => {
71 std.debug.assert(ty.isPtrLikeOptional(mod));71 std.debug.assert(ty.isPtrLikeOptional(pt.zcu));
72 return .byval;72 return .byval;
73 },73 },
74 .Pointer => {74 .Pointer => {
75 std.debug.assert(!ty.isSlice(mod));75 std.debug.assert(!ty.isSlice(pt.zcu));
76 return .byval;76 return .byval;
77 },77 },
78 .ErrorUnion,78 .ErrorUnion,
...@@ -97,18 +97,19 @@ pub const SystemClass = enum { integer, float, memory, none };...@@ -97,18 +97,19 @@ pub const SystemClass = enum { integer, float, memory, none };
9797
98/// There are a maximum of 8 possible return slots. Returned values are in98/// There are a maximum of 8 possible return slots. Returned values are in
99/// the beginning of the array; unused slots are filled with .none.99/// the beginning of the array; unused slots are filled with .none.
100pub fn classifySystem(ty: Type, zcu: *Zcu) [8]SystemClass {100pub fn classifySystem(ty: Type, pt: Zcu.PerThread) [8]SystemClass {
101 const zcu = pt.zcu;
101 var result = [1]SystemClass{.none} ** 8;102 var result = [1]SystemClass{.none} ** 8;
102 const memory_class = [_]SystemClass{103 const memory_class = [_]SystemClass{
103 .memory, .none, .none, .none,104 .memory, .none, .none, .none,
104 .none, .none, .none, .none,105 .none, .none, .none, .none,
105 };106 };
106 switch (ty.zigTypeTag(zcu)) {107 switch (ty.zigTypeTag(pt.zcu)) {
107 .Bool, .Void, .NoReturn => {108 .Bool, .Void, .NoReturn => {
108 result[0] = .integer;109 result[0] = .integer;
109 return result;110 return result;
110 },111 },
111 .Pointer => switch (ty.ptrSize(zcu)) {112 .Pointer => switch (ty.ptrSize(pt.zcu)) {
112 .Slice => {113 .Slice => {
113 result[0] = .integer;114 result[0] = .integer;
114 result[1] = .integer;115 result[1] = .integer;
...@@ -120,17 +121,17 @@ pub fn classifySystem(ty: Type, zcu: *Zcu) [8]SystemClass {...@@ -120,17 +121,17 @@ pub fn classifySystem(ty: Type, zcu: *Zcu) [8]SystemClass {
120 },121 },
121 },122 },
122 .Optional => {123 .Optional => {
123 if (ty.isPtrLikeOptional(zcu)) {124 if (ty.isPtrLikeOptional(pt.zcu)) {
124 result[0] = .integer;125 result[0] = .integer;
125 return result;126 return result;
126 }127 }
127 result[0] = .integer;128 result[0] = .integer;
128 if (ty.optionalChild(zcu).abiSize(zcu) == 0) return result;129 if (ty.optionalChild(zcu).abiSize(pt) == 0) return result;
129 result[1] = .integer;130 result[1] = .integer;
130 return result;131 return result;
131 },132 },
132 .Int, .Enum, .ErrorSet => {133 .Int, .Enum, .ErrorSet => {
133 const int_bits = ty.intInfo(zcu).bits;134 const int_bits = ty.intInfo(pt.zcu).bits;
134 if (int_bits <= 64) {135 if (int_bits <= 64) {
135 result[0] = .integer;136 result[0] = .integer;
136 return result;137 return result;
...@@ -155,8 +156,8 @@ pub fn classifySystem(ty: Type, zcu: *Zcu) [8]SystemClass {...@@ -155,8 +156,8 @@ pub fn classifySystem(ty: Type, zcu: *Zcu) [8]SystemClass {
155 unreachable; // support split float args156 unreachable; // support split float args
156 },157 },
157 .ErrorUnion => {158 .ErrorUnion => {
158 const payload_ty = ty.errorUnionPayload(zcu);159 const payload_ty = ty.errorUnionPayload(pt.zcu);
159 const payload_bits = payload_ty.bitSize(zcu);160 const payload_bits = payload_ty.bitSize(pt);
160161
161 // the error union itself162 // the error union itself
162 result[0] = .integer;163 result[0] = .integer;
...@@ -167,8 +168,8 @@ pub fn classifySystem(ty: Type, zcu: *Zcu) [8]SystemClass {...@@ -167,8 +168,8 @@ pub fn classifySystem(ty: Type, zcu: *Zcu) [8]SystemClass {
167 return memory_class;168 return memory_class;
168 },169 },
169 .Struct => {170 .Struct => {
170 const layout = ty.containerLayout(zcu);171 const layout = ty.containerLayout(pt.zcu);
171 const ty_size = ty.abiSize(zcu);172 const ty_size = ty.abiSize(pt);
172173
173 if (layout == .@"packed") {174 if (layout == .@"packed") {
174 assert(ty_size <= 16);175 assert(ty_size <= 16);
...@@ -180,7 +181,7 @@ pub fn classifySystem(ty: Type, zcu: *Zcu) [8]SystemClass {...@@ -180,7 +181,7 @@ pub fn classifySystem(ty: Type, zcu: *Zcu) [8]SystemClass {
180 return memory_class;181 return memory_class;
181 },182 },
182 .Array => {183 .Array => {
183 const ty_size = ty.abiSize(zcu);184 const ty_size = ty.abiSize(pt);
184 if (ty_size <= 8) {185 if (ty_size <= 8) {
185 result[0] = .integer;186 result[0] = .integer;
186 return result;187 return result;
src/arch/sparc64/CodeGen.zig+125-95
...@@ -11,11 +11,9 @@ const Allocator = mem.Allocator;...@@ -11,11 +11,9 @@ const Allocator = mem.Allocator;
11const builtin = @import("builtin");11const builtin = @import("builtin");
12const link = @import("../../link.zig");12const link = @import("../../link.zig");
13const Zcu = @import("../../Zcu.zig");13const Zcu = @import("../../Zcu.zig");
14/// Deprecated.
15const Module = Zcu;
16const InternPool = @import("../../InternPool.zig");14const InternPool = @import("../../InternPool.zig");
17const Value = @import("../../Value.zig");15const Value = @import("../../Value.zig");
18const ErrorMsg = Module.ErrorMsg;16const ErrorMsg = Zcu.ErrorMsg;
19const codegen = @import("../../codegen.zig");17const codegen = @import("../../codegen.zig");
20const Air = @import("../../Air.zig");18const Air = @import("../../Air.zig");
21const Mir = @import("Mir.zig");19const Mir = @import("Mir.zig");
...@@ -52,6 +50,7 @@ const RegisterView = enum(u1) {...@@ -52,6 +50,7 @@ const RegisterView = enum(u1) {
52};50};
5351
54gpa: Allocator,52gpa: Allocator,
53pt: Zcu.PerThread,
55air: Air,54air: Air,
56liveness: Liveness,55liveness: Liveness,
57bin_file: *link.File,56bin_file: *link.File,
...@@ -64,7 +63,7 @@ args: []MCValue,...@@ -64,7 +63,7 @@ args: []MCValue,
64ret_mcv: MCValue,63ret_mcv: MCValue,
65fn_type: Type,64fn_type: Type,
66arg_index: usize,65arg_index: usize,
67src_loc: Module.LazySrcLoc,66src_loc: Zcu.LazySrcLoc,
68stack_align: Alignment,67stack_align: Alignment,
6968
70/// MIR Instructions69/// MIR Instructions
...@@ -263,15 +262,16 @@ const BigTomb = struct {...@@ -263,15 +262,16 @@ const BigTomb = struct {
263262
264pub fn generate(263pub fn generate(
265 lf: *link.File,264 lf: *link.File,
266 src_loc: Module.LazySrcLoc,265 pt: Zcu.PerThread,
266 src_loc: Zcu.LazySrcLoc,
267 func_index: InternPool.Index,267 func_index: InternPool.Index,
268 air: Air,268 air: Air,
269 liveness: Liveness,269 liveness: Liveness,
270 code: *std.ArrayList(u8),270 code: *std.ArrayList(u8),
271 debug_output: DebugInfoOutput,271 debug_output: DebugInfoOutput,
272) CodeGenError!Result {272) CodeGenError!Result {
273 const gpa = lf.comp.gpa;273 const zcu = pt.zcu;
274 const zcu = lf.comp.module.?;274 const gpa = zcu.gpa;
275 const func = zcu.funcInfo(func_index);275 const func = zcu.funcInfo(func_index);
276 const fn_owner_decl = zcu.declPtr(func.owner_decl);276 const fn_owner_decl = zcu.declPtr(func.owner_decl);
277 assert(fn_owner_decl.has_tv);277 assert(fn_owner_decl.has_tv);
...@@ -289,11 +289,12 @@ pub fn generate(...@@ -289,11 +289,12 @@ pub fn generate(
289289
290 var function = Self{290 var function = Self{
291 .gpa = gpa,291 .gpa = gpa,
292 .pt = pt,
292 .air = air,293 .air = air,
293 .liveness = liveness,294 .liveness = liveness,
294 .target = target,295 .target = target,
295 .func_index = func_index,
296 .bin_file = lf,296 .bin_file = lf,
297 .func_index = func_index,
297 .code = code,298 .code = code,
298 .debug_output = debug_output,299 .debug_output = debug_output,
299 .err_msg = null,300 .err_msg = null,
...@@ -365,7 +366,8 @@ pub fn generate(...@@ -365,7 +366,8 @@ pub fn generate(
365}366}
366367
367fn gen(self: *Self) !void {368fn gen(self: *Self) !void {
368 const mod = self.bin_file.comp.module.?;369 const pt = self.pt;
370 const mod = pt.zcu;
369 const cc = self.fn_type.fnCallingConvention(mod);371 const cc = self.fn_type.fnCallingConvention(mod);
370 if (cc != .Naked) {372 if (cc != .Naked) {
371 // TODO Finish function prologue and epilogue for sparc64.373 // TODO Finish function prologue and epilogue for sparc64.
...@@ -493,7 +495,8 @@ fn gen(self: *Self) !void {...@@ -493,7 +495,8 @@ fn gen(self: *Self) !void {
493}495}
494496
495fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {497fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {
496 const mod = self.bin_file.comp.module.?;498 const pt = self.pt;
499 const mod = pt.zcu;
497 const ip = &mod.intern_pool;500 const ip = &mod.intern_pool;
498 const air_tags = self.air.instructions.items(.tag);501 const air_tags = self.air.instructions.items(.tag);
499502
...@@ -757,7 +760,8 @@ fn airAddSubWithOverflow(self: *Self, inst: Air.Inst.Index) !void {...@@ -757,7 +760,8 @@ fn airAddSubWithOverflow(self: *Self, inst: Air.Inst.Index) !void {
757 const tag = self.air.instructions.items(.tag)[@intFromEnum(inst)];760 const tag = self.air.instructions.items(.tag)[@intFromEnum(inst)];
758 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;761 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
759 const extra = self.air.extraData(Air.Bin, ty_pl.payload).data;762 const extra = self.air.extraData(Air.Bin, ty_pl.payload).data;
760 const mod = self.bin_file.comp.module.?;763 const pt = self.pt;
764 const mod = pt.zcu;
761 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {765 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
762 const lhs = try self.resolveInst(extra.lhs);766 const lhs = try self.resolveInst(extra.lhs);
763 const rhs = try self.resolveInst(extra.rhs);767 const rhs = try self.resolveInst(extra.rhs);
...@@ -835,7 +839,8 @@ fn airAddSubWithOverflow(self: *Self, inst: Air.Inst.Index) !void {...@@ -835,7 +839,8 @@ fn airAddSubWithOverflow(self: *Self, inst: Air.Inst.Index) !void {
835}839}
836840
837fn airAggregateInit(self: *Self, inst: Air.Inst.Index) !void {841fn airAggregateInit(self: *Self, inst: Air.Inst.Index) !void {
838 const mod = self.bin_file.comp.module.?;842 const pt = self.pt;
843 const mod = pt.zcu;
839 const vector_ty = self.typeOfIndex(inst);844 const vector_ty = self.typeOfIndex(inst);
840 const len = vector_ty.vectorLen(mod);845 const len = vector_ty.vectorLen(mod);
841 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;846 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
...@@ -869,7 +874,8 @@ fn airArrayElemVal(self: *Self, inst: Air.Inst.Index) !void {...@@ -869,7 +874,8 @@ fn airArrayElemVal(self: *Self, inst: Air.Inst.Index) !void {
869}874}
870875
871fn airArrayToSlice(self: *Self, inst: Air.Inst.Index) !void {876fn airArrayToSlice(self: *Self, inst: Air.Inst.Index) !void {
872 const mod = self.bin_file.comp.module.?;877 const pt = self.pt;
878 const mod = pt.zcu;
873 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;879 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
874 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {880 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
875 const ptr_ty = self.typeOf(ty_op.operand);881 const ptr_ty = self.typeOf(ty_op.operand);
...@@ -1006,7 +1012,7 @@ fn airAsm(self: *Self, inst: Air.Inst.Index) !void {...@@ -1006,7 +1012,7 @@ fn airAsm(self: *Self, inst: Air.Inst.Index) !void {
1006}1012}
10071013
1008fn airArg(self: *Self, inst: Air.Inst.Index) !void {1014fn airArg(self: *Self, inst: Air.Inst.Index) !void {
1009 const mod = self.bin_file.comp.module.?;1015 const pt = self.pt;
1010 const arg_index = self.arg_index;1016 const arg_index = self.arg_index;
1011 self.arg_index += 1;1017 self.arg_index += 1;
10121018
...@@ -1016,8 +1022,8 @@ fn airArg(self: *Self, inst: Air.Inst.Index) !void {...@@ -1016,8 +1022,8 @@ fn airArg(self: *Self, inst: Air.Inst.Index) !void {
1016 const mcv = blk: {1022 const mcv = blk: {
1017 switch (arg) {1023 switch (arg) {
1018 .stack_offset => |off| {1024 .stack_offset => |off| {
1019 const abi_size = math.cast(u32, ty.abiSize(mod)) orelse {1025 const abi_size = math.cast(u32, ty.abiSize(pt)) orelse {
1020 return self.fail("type '{}' too big to fit into stack frame", .{ty.fmt(mod)});1026 return self.fail("type '{}' too big to fit into stack frame", .{ty.fmt(pt)});
1021 };1027 };
1022 const offset = off + abi_size;1028 const offset = off + abi_size;
1023 break :blk MCValue{ .stack_offset = offset };1029 break :blk MCValue{ .stack_offset = offset };
...@@ -1205,7 +1211,8 @@ fn airBreakpoint(self: *Self) !void {...@@ -1205,7 +1211,8 @@ fn airBreakpoint(self: *Self) !void {
1205}1211}
12061212
1207fn airByteSwap(self: *Self, inst: Air.Inst.Index) !void {1213fn airByteSwap(self: *Self, inst: Air.Inst.Index) !void {
1208 const mod = self.bin_file.comp.module.?;1214 const pt = self.pt;
1215 const mod = pt.zcu;
1209 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;1216 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
12101217
1211 // We have hardware byteswapper in SPARCv9, don't let mainstream compilers mislead you.1218 // We have hardware byteswapper in SPARCv9, don't let mainstream compilers mislead you.
...@@ -1228,7 +1235,7 @@ fn airByteSwap(self: *Self, inst: Air.Inst.Index) !void {...@@ -1228,7 +1235,7 @@ fn airByteSwap(self: *Self, inst: Air.Inst.Index) !void {
1228 if (int_info.bits == 8) break :result operand;1235 if (int_info.bits == 8) break :result operand;
12291236
1230 const abi_size = int_info.bits >> 3;1237 const abi_size = int_info.bits >> 3;
1231 const abi_align = operand_ty.abiAlignment(mod);1238 const abi_align = operand_ty.abiAlignment(pt);
1232 const opposite_endian_asi = switch (self.target.cpu.arch.endian()) {1239 const opposite_endian_asi = switch (self.target.cpu.arch.endian()) {
1233 Endian.big => ASI.asi_primary_little,1240 Endian.big => ASI.asi_primary_little,
1234 Endian.little => ASI.asi_primary,1241 Endian.little => ASI.asi_primary,
...@@ -1297,7 +1304,8 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier...@@ -1297,7 +1304,8 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier
1297 const extra = self.air.extraData(Air.Call, pl_op.payload);1304 const extra = self.air.extraData(Air.Call, pl_op.payload);
1298 const args = @as([]const Air.Inst.Ref, @ptrCast(self.air.extra[extra.end .. extra.end + extra.data.args_len]));1305 const args = @as([]const Air.Inst.Ref, @ptrCast(self.air.extra[extra.end .. extra.end + extra.data.args_len]));
1299 const ty = self.typeOf(callee);1306 const ty = self.typeOf(callee);
1300 const mod = self.bin_file.comp.module.?;1307 const pt = self.pt;
1308 const mod = pt.zcu;
1301 const fn_ty = switch (ty.zigTypeTag(mod)) {1309 const fn_ty = switch (ty.zigTypeTag(mod)) {
1302 .Fn => ty,1310 .Fn => ty,
1303 .Pointer => ty.childType(mod),1311 .Pointer => ty.childType(mod),
...@@ -1341,7 +1349,7 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier...@@ -1341,7 +1349,7 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier
13411349
1342 // Due to incremental compilation, how function calls are generated depends1350 // Due to incremental compilation, how function calls are generated depends
1343 // on linking.1351 // on linking.
1344 if (try self.air.value(callee, mod)) |func_value| {1352 if (try self.air.value(callee, pt)) |func_value| {
1345 if (self.bin_file.tag == link.File.Elf.base_tag) {1353 if (self.bin_file.tag == link.File.Elf.base_tag) {
1346 switch (mod.intern_pool.indexToKey(func_value.ip_index)) {1354 switch (mod.intern_pool.indexToKey(func_value.ip_index)) {
1347 .func => |func| {1355 .func => |func| {
...@@ -1429,7 +1437,8 @@ fn airClz(self: *Self, inst: Air.Inst.Index) !void {...@@ -1429,7 +1437,8 @@ fn airClz(self: *Self, inst: Air.Inst.Index) !void {
14291437
1430fn airCmp(self: *Self, inst: Air.Inst.Index, op: math.CompareOperator) !void {1438fn airCmp(self: *Self, inst: Air.Inst.Index, op: math.CompareOperator) !void {
1431 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;1439 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
1432 const mod = self.bin_file.comp.module.?;1440 const pt = self.pt;
1441 const mod = pt.zcu;
1433 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {1442 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
1434 const lhs = try self.resolveInst(bin_op.lhs);1443 const lhs = try self.resolveInst(bin_op.lhs);
1435 const rhs = try self.resolveInst(bin_op.rhs);1444 const rhs = try self.resolveInst(bin_op.rhs);
...@@ -1444,7 +1453,7 @@ fn airCmp(self: *Self, inst: Air.Inst.Index, op: math.CompareOperator) !void {...@@ -1444,7 +1453,7 @@ fn airCmp(self: *Self, inst: Air.Inst.Index, op: math.CompareOperator) !void {
1444 .ErrorSet => Type.u16,1453 .ErrorSet => Type.u16,
1445 .Optional => blk: {1454 .Optional => blk: {
1446 const payload_ty = lhs_ty.optionalChild(mod);1455 const payload_ty = lhs_ty.optionalChild(mod);
1447 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) {1456 if (!payload_ty.hasRuntimeBitsIgnoreComptime(pt)) {
1448 break :blk Type.u1;1457 break :blk Type.u1;
1449 } else if (lhs_ty.isPtrLikeOptional(mod)) {1458 } else if (lhs_ty.isPtrLikeOptional(mod)) {
1450 break :blk Type.usize;1459 break :blk Type.usize;
...@@ -1655,7 +1664,8 @@ fn airCtz(self: *Self, inst: Air.Inst.Index) !void {...@@ -1655,7 +1664,8 @@ fn airCtz(self: *Self, inst: Air.Inst.Index) !void {
1655}1664}
16561665
1657fn airDbgInlineBlock(self: *Self, inst: Air.Inst.Index) !void {1666fn airDbgInlineBlock(self: *Self, inst: Air.Inst.Index) !void {
1658 const mod = self.bin_file.comp.module.?;1667 const pt = self.pt;
1668 const mod = pt.zcu;
1659 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;1669 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
1660 const extra = self.air.extraData(Air.DbgInlineBlock, ty_pl.payload);1670 const extra = self.air.extraData(Air.DbgInlineBlock, ty_pl.payload);
1661 const func = mod.funcInfo(extra.data.func);1671 const func = mod.funcInfo(extra.data.func);
...@@ -1753,7 +1763,8 @@ fn airIntCast(self: *Self, inst: Air.Inst.Index) !void {...@@ -1753,7 +1763,8 @@ fn airIntCast(self: *Self, inst: Air.Inst.Index) !void {
1753 if (self.liveness.isUnused(inst))1763 if (self.liveness.isUnused(inst))
1754 return self.finishAir(inst, .dead, .{ ty_op.operand, .none, .none });1764 return self.finishAir(inst, .dead, .{ ty_op.operand, .none, .none });
17551765
1756 const mod = self.bin_file.comp.module.?;1766 const pt = self.pt;
1767 const mod = pt.zcu;
1757 const operand_ty = self.typeOf(ty_op.operand);1768 const operand_ty = self.typeOf(ty_op.operand);
1758 const operand = try self.resolveInst(ty_op.operand);1769 const operand = try self.resolveInst(ty_op.operand);
1759 const info_a = operand_ty.intInfo(mod);1770 const info_a = operand_ty.intInfo(mod);
...@@ -1814,12 +1825,13 @@ fn airIsNonNull(self: *Self, inst: Air.Inst.Index) !void {...@@ -1814,12 +1825,13 @@ fn airIsNonNull(self: *Self, inst: Air.Inst.Index) !void {
1814}1825}
18151826
1816fn airLoad(self: *Self, inst: Air.Inst.Index) !void {1827fn airLoad(self: *Self, inst: Air.Inst.Index) !void {
1817 const mod = self.bin_file.comp.module.?;1828 const pt = self.pt;
1829 const mod = pt.zcu;
1818 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;1830 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
1819 const elem_ty = self.typeOfIndex(inst);1831 const elem_ty = self.typeOfIndex(inst);
1820 const elem_size = elem_ty.abiSize(mod);1832 const elem_size = elem_ty.abiSize(pt);
1821 const result: MCValue = result: {1833 const result: MCValue = result: {
1822 if (!elem_ty.hasRuntimeBits(mod))1834 if (!elem_ty.hasRuntimeBits(pt))
1823 break :result MCValue.none;1835 break :result MCValue.none;
18241836
1825 const ptr = try self.resolveInst(ty_op.operand);1837 const ptr = try self.resolveInst(ty_op.operand);
...@@ -1898,7 +1910,7 @@ fn airMod(self: *Self, inst: Air.Inst.Index) !void {...@@ -1898,7 +1910,7 @@ fn airMod(self: *Self, inst: Air.Inst.Index) !void {
1898 const rhs = try self.resolveInst(bin_op.rhs);1910 const rhs = try self.resolveInst(bin_op.rhs);
1899 const lhs_ty = self.typeOf(bin_op.lhs);1911 const lhs_ty = self.typeOf(bin_op.lhs);
1900 const rhs_ty = self.typeOf(bin_op.rhs);1912 const rhs_ty = self.typeOf(bin_op.rhs);
1901 assert(lhs_ty.eql(rhs_ty, self.bin_file.comp.module.?));1913 assert(lhs_ty.eql(rhs_ty, self.pt.zcu));
19021914
1903 if (self.liveness.isUnused(inst))1915 if (self.liveness.isUnused(inst))
1904 return self.finishAir(inst, .dead, .{ bin_op.lhs, bin_op.rhs, .none });1916 return self.finishAir(inst, .dead, .{ bin_op.lhs, bin_op.rhs, .none });
...@@ -2040,7 +2052,8 @@ fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) !void {...@@ -2040,7 +2052,8 @@ fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) !void {
2040 //const tag = self.air.instructions.items(.tag)[@intFromEnum(inst)];2052 //const tag = self.air.instructions.items(.tag)[@intFromEnum(inst)];
2041 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;2053 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
2042 const extra = self.air.extraData(Air.Bin, ty_pl.payload).data;2054 const extra = self.air.extraData(Air.Bin, ty_pl.payload).data;
2043 const mod = self.bin_file.comp.module.?;2055 const pt = self.pt;
2056 const mod = pt.zcu;
2044 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {2057 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
2045 const lhs = try self.resolveInst(extra.lhs);2058 const lhs = try self.resolveInst(extra.lhs);
2046 const rhs = try self.resolveInst(extra.rhs);2059 const rhs = try self.resolveInst(extra.rhs);
...@@ -2104,7 +2117,8 @@ fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) !void {...@@ -2104,7 +2117,8 @@ fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) !void {
21042117
2105fn airNot(self: *Self, inst: Air.Inst.Index) !void {2118fn airNot(self: *Self, inst: Air.Inst.Index) !void {
2106 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;2119 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
2107 const mod = self.bin_file.comp.module.?;2120 const pt = self.pt;
2121 const mod = pt.zcu;
2108 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {2122 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
2109 const operand = try self.resolveInst(ty_op.operand);2123 const operand = try self.resolveInst(ty_op.operand);
2110 const operand_ty = self.typeOf(ty_op.operand);2124 const operand_ty = self.typeOf(ty_op.operand);
...@@ -2336,7 +2350,8 @@ fn airShlSat(self: *Self, inst: Air.Inst.Index) !void {...@@ -2336,7 +2350,8 @@ fn airShlSat(self: *Self, inst: Air.Inst.Index) !void {
2336fn airShlWithOverflow(self: *Self, inst: Air.Inst.Index) !void {2350fn airShlWithOverflow(self: *Self, inst: Air.Inst.Index) !void {
2337 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;2351 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
2338 const extra = self.air.extraData(Air.Bin, ty_pl.payload).data;2352 const extra = self.air.extraData(Air.Bin, ty_pl.payload).data;
2339 const mod = self.bin_file.comp.module.?;2353 const pt = self.pt;
2354 const mod = pt.zcu;
2340 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {2355 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
2341 const lhs = try self.resolveInst(extra.lhs);2356 const lhs = try self.resolveInst(extra.lhs);
2342 const rhs = try self.resolveInst(extra.rhs);2357 const rhs = try self.resolveInst(extra.rhs);
...@@ -2441,7 +2456,8 @@ fn airSlice(self: *Self, inst: Air.Inst.Index) !void {...@@ -2441,7 +2456,8 @@ fn airSlice(self: *Self, inst: Air.Inst.Index) !void {
2441}2456}
24422457
2443fn airSliceElemVal(self: *Self, inst: Air.Inst.Index) !void {2458fn airSliceElemVal(self: *Self, inst: Air.Inst.Index) !void {
2444 const mod = self.bin_file.comp.module.?;2459 const pt = self.pt;
2460 const mod = pt.zcu;
2445 const is_volatile = false; // TODO2461 const is_volatile = false; // TODO
2446 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;2462 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
24472463
...@@ -2452,7 +2468,7 @@ fn airSliceElemVal(self: *Self, inst: Air.Inst.Index) !void {...@@ -2452,7 +2468,7 @@ fn airSliceElemVal(self: *Self, inst: Air.Inst.Index) !void {
24522468
2453 const slice_ty = self.typeOf(bin_op.lhs);2469 const slice_ty = self.typeOf(bin_op.lhs);
2454 const elem_ty = slice_ty.childType(mod);2470 const elem_ty = slice_ty.childType(mod);
2455 const elem_size = elem_ty.abiSize(mod);2471 const elem_size = elem_ty.abiSize(pt);
24562472
2457 const slice_ptr_field_type = slice_ty.slicePtrFieldType(mod);2473 const slice_ptr_field_type = slice_ty.slicePtrFieldType(mod);
24582474
...@@ -2566,10 +2582,10 @@ fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void {...@@ -2566,10 +2582,10 @@ fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void {
2566 const operand = extra.struct_operand;2582 const operand = extra.struct_operand;
2567 const index = extra.field_index;2583 const index = extra.field_index;
2568 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {2584 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
2569 const mod = self.bin_file.comp.module.?;2585 const pt = self.pt;
2570 const mcv = try self.resolveInst(operand);2586 const mcv = try self.resolveInst(operand);
2571 const struct_ty = self.typeOf(operand);2587 const struct_ty = self.typeOf(operand);
2572 const struct_field_offset = @as(u32, @intCast(struct_ty.structFieldOffset(index, mod)));2588 const struct_field_offset = @as(u32, @intCast(struct_ty.structFieldOffset(index, pt)));
25732589
2574 switch (mcv) {2590 switch (mcv) {
2575 .dead, .unreach => unreachable,2591 .dead, .unreach => unreachable,
...@@ -2699,13 +2715,14 @@ fn airUnionInit(self: *Self, inst: Air.Inst.Index) !void {...@@ -2699,13 +2715,14 @@ fn airUnionInit(self: *Self, inst: Air.Inst.Index) !void {
2699}2715}
27002716
2701fn airUnwrapErrErr(self: *Self, inst: Air.Inst.Index) !void {2717fn airUnwrapErrErr(self: *Self, inst: Air.Inst.Index) !void {
2702 const mod = self.bin_file.comp.module.?;2718 const pt = self.pt;
2719 const mod = pt.zcu;
2703 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;2720 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
2704 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {2721 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
2705 const error_union_ty = self.typeOf(ty_op.operand);2722 const error_union_ty = self.typeOf(ty_op.operand);
2706 const payload_ty = error_union_ty.errorUnionPayload(mod);2723 const payload_ty = error_union_ty.errorUnionPayload(mod);
2707 const mcv = try self.resolveInst(ty_op.operand);2724 const mcv = try self.resolveInst(ty_op.operand);
2708 if (!payload_ty.hasRuntimeBits(mod)) break :result mcv;2725 if (!payload_ty.hasRuntimeBits(pt)) break :result mcv;
27092726
2710 return self.fail("TODO implement unwrap error union error for non-empty payloads", .{});2727 return self.fail("TODO implement unwrap error union error for non-empty payloads", .{});
2711 };2728 };
...@@ -2713,12 +2730,13 @@ fn airUnwrapErrErr(self: *Self, inst: Air.Inst.Index) !void {...@@ -2713,12 +2730,13 @@ fn airUnwrapErrErr(self: *Self, inst: Air.Inst.Index) !void {
2713}2730}
27142731
2715fn airUnwrapErrPayload(self: *Self, inst: Air.Inst.Index) !void {2732fn airUnwrapErrPayload(self: *Self, inst: Air.Inst.Index) !void {
2716 const mod = self.bin_file.comp.module.?;2733 const pt = self.pt;
2734 const mod = pt.zcu;
2717 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;2735 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
2718 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {2736 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
2719 const error_union_ty = self.typeOf(ty_op.operand);2737 const error_union_ty = self.typeOf(ty_op.operand);
2720 const payload_ty = error_union_ty.errorUnionPayload(mod);2738 const payload_ty = error_union_ty.errorUnionPayload(mod);
2721 if (!payload_ty.hasRuntimeBits(mod)) break :result MCValue.none;2739 if (!payload_ty.hasRuntimeBits(pt)) break :result MCValue.none;
27222740
2723 return self.fail("TODO implement unwrap error union payload for non-empty payloads", .{});2741 return self.fail("TODO implement unwrap error union payload for non-empty payloads", .{});
2724 };2742 };
...@@ -2727,13 +2745,14 @@ fn airUnwrapErrPayload(self: *Self, inst: Air.Inst.Index) !void {...@@ -2727,13 +2745,14 @@ fn airUnwrapErrPayload(self: *Self, inst: Air.Inst.Index) !void {
27272745
2728/// E to E!T2746/// E to E!T
2729fn airWrapErrUnionErr(self: *Self, inst: Air.Inst.Index) !void {2747fn airWrapErrUnionErr(self: *Self, inst: Air.Inst.Index) !void {
2730 const mod = self.bin_file.comp.module.?;2748 const pt = self.pt;
2749 const mod = pt.zcu;
2731 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;2750 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
2732 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {2751 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
2733 const error_union_ty = ty_op.ty.toType();2752 const error_union_ty = ty_op.ty.toType();
2734 const payload_ty = error_union_ty.errorUnionPayload(mod);2753 const payload_ty = error_union_ty.errorUnionPayload(mod);
2735 const mcv = try self.resolveInst(ty_op.operand);2754 const mcv = try self.resolveInst(ty_op.operand);
2736 if (!payload_ty.hasRuntimeBits(mod)) break :result mcv;2755 if (!payload_ty.hasRuntimeBits(pt)) break :result mcv;
27372756
2738 return self.fail("TODO implement wrap errunion error for non-empty payloads", .{});2757 return self.fail("TODO implement wrap errunion error for non-empty payloads", .{});
2739 };2758 };
...@@ -2748,13 +2767,13 @@ fn airWrapErrUnionPayload(self: *Self, inst: Air.Inst.Index) !void {...@@ -2748,13 +2767,13 @@ fn airWrapErrUnionPayload(self: *Self, inst: Air.Inst.Index) !void {
2748}2767}
27492768
2750fn airWrapOptional(self: *Self, inst: Air.Inst.Index) !void {2769fn airWrapOptional(self: *Self, inst: Air.Inst.Index) !void {
2751 const mod = self.bin_file.comp.module.?;2770 const pt = self.pt;
2752 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;2771 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
2753 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {2772 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
2754 const optional_ty = self.typeOfIndex(inst);2773 const optional_ty = self.typeOfIndex(inst);
27552774
2756 // Optional with a zero-bit payload type is just a boolean true2775 // Optional with a zero-bit payload type is just a boolean true
2757 if (optional_ty.abiSize(mod) == 1)2776 if (optional_ty.abiSize(pt) == 1)
2758 break :result MCValue{ .immediate = 1 };2777 break :result MCValue{ .immediate = 1 };
27592778
2760 return self.fail("TODO implement wrap optional for {}", .{self.target.cpu.arch});2779 return self.fail("TODO implement wrap optional for {}", .{self.target.cpu.arch});
...@@ -2788,10 +2807,11 @@ fn allocMem(self: *Self, inst: Air.Inst.Index, abi_size: u32, abi_align: Alignme...@@ -2788,10 +2807,11 @@ fn allocMem(self: *Self, inst: Air.Inst.Index, abi_size: u32, abi_align: Alignme
27882807
2789/// Use a pointer instruction as the basis for allocating stack memory.2808/// Use a pointer instruction as the basis for allocating stack memory.
2790fn allocMemPtr(self: *Self, inst: Air.Inst.Index) !u32 {2809fn allocMemPtr(self: *Self, inst: Air.Inst.Index) !u32 {
2791 const mod = self.bin_file.comp.module.?;2810 const pt = self.pt;
2811 const mod = pt.zcu;
2792 const elem_ty = self.typeOfIndex(inst).childType(mod);2812 const elem_ty = self.typeOfIndex(inst).childType(mod);
27932813
2794 if (!elem_ty.hasRuntimeBits(mod)) {2814 if (!elem_ty.hasRuntimeBits(pt)) {
2795 // As this stack item will never be dereferenced at runtime,2815 // As this stack item will never be dereferenced at runtime,
2796 // return the stack offset 0. Stack offset 0 will be where all2816 // return the stack offset 0. Stack offset 0 will be where all
2797 // zero-sized stack allocations live as non-zero-sized2817 // zero-sized stack allocations live as non-zero-sized
...@@ -2799,21 +2819,21 @@ fn allocMemPtr(self: *Self, inst: Air.Inst.Index) !u32 {...@@ -2799,21 +2819,21 @@ fn allocMemPtr(self: *Self, inst: Air.Inst.Index) !u32 {
2799 return @as(u32, 0);2819 return @as(u32, 0);
2800 }2820 }
28012821
2802 const abi_size = math.cast(u32, elem_ty.abiSize(mod)) orelse {2822 const abi_size = math.cast(u32, elem_ty.abiSize(pt)) orelse {
2803 return self.fail("type '{}' too big to fit into stack frame", .{elem_ty.fmt(mod)});2823 return self.fail("type '{}' too big to fit into stack frame", .{elem_ty.fmt(pt)});
2804 };2824 };
2805 // TODO swap this for inst.ty.ptrAlign2825 // TODO swap this for inst.ty.ptrAlign
2806 const abi_align = elem_ty.abiAlignment(mod);2826 const abi_align = elem_ty.abiAlignment(pt);
2807 return self.allocMem(inst, abi_size, abi_align);2827 return self.allocMem(inst, abi_size, abi_align);
2808}2828}
28092829
2810fn allocRegOrMem(self: *Self, inst: Air.Inst.Index, reg_ok: bool) !MCValue {2830fn allocRegOrMem(self: *Self, inst: Air.Inst.Index, reg_ok: bool) !MCValue {
2811 const mod = self.bin_file.comp.module.?;2831 const pt = self.pt;
2812 const elem_ty = self.typeOfIndex(inst);2832 const elem_ty = self.typeOfIndex(inst);
2813 const abi_size = math.cast(u32, elem_ty.abiSize(mod)) orelse {2833 const abi_size = math.cast(u32, elem_ty.abiSize(pt)) orelse {
2814 return self.fail("type '{}' too big to fit into stack frame", .{elem_ty.fmt(mod)});2834 return self.fail("type '{}' too big to fit into stack frame", .{elem_ty.fmt(pt)});
2815 };2835 };
2816 const abi_align = elem_ty.abiAlignment(mod);2836 const abi_align = elem_ty.abiAlignment(pt);
2817 self.stack_align = self.stack_align.max(abi_align);2837 self.stack_align = self.stack_align.max(abi_align);
28182838
2819 if (reg_ok) {2839 if (reg_ok) {
...@@ -2855,7 +2875,8 @@ fn binOp(...@@ -2855,7 +2875,8 @@ fn binOp(
2855 rhs_ty: Type,2875 rhs_ty: Type,
2856 metadata: ?BinOpMetadata,2876 metadata: ?BinOpMetadata,
2857) InnerError!MCValue {2877) InnerError!MCValue {
2858 const mod = self.bin_file.comp.module.?;2878 const pt = self.pt;
2879 const mod = pt.zcu;
2859 switch (tag) {2880 switch (tag) {
2860 .add,2881 .add,
2861 .sub,2882 .sub,
...@@ -2996,7 +3017,7 @@ fn binOp(...@@ -2996,7 +3017,7 @@ fn binOp(
2996 .One => ptr_ty.childType(mod).childType(mod), // ptr to array, so get array element type3017 .One => ptr_ty.childType(mod).childType(mod), // ptr to array, so get array element type
2997 else => ptr_ty.childType(mod),3018 else => ptr_ty.childType(mod),
2998 };3019 };
2999 const elem_size = elem_ty.abiSize(mod);3020 const elem_size = elem_ty.abiSize(pt);
30003021
3001 if (elem_size == 1) {3022 if (elem_size == 1) {
3002 const base_tag: Mir.Inst.Tag = switch (tag) {3023 const base_tag: Mir.Inst.Tag = switch (tag) {
...@@ -3396,8 +3417,8 @@ fn binOpRegister(...@@ -3396,8 +3417,8 @@ fn binOpRegister(
3396fn br(self: *Self, block: Air.Inst.Index, operand: Air.Inst.Ref) !void {3417fn br(self: *Self, block: Air.Inst.Index, operand: Air.Inst.Ref) !void {
3397 const block_data = self.blocks.getPtr(block).?;3418 const block_data = self.blocks.getPtr(block).?;
33983419
3399 const mod = self.bin_file.comp.module.?;3420 const pt = self.pt;
3400 if (self.typeOf(operand).hasRuntimeBits(mod)) {3421 if (self.typeOf(operand).hasRuntimeBits(pt)) {
3401 const operand_mcv = try self.resolveInst(operand);3422 const operand_mcv = try self.resolveInst(operand);
3402 const block_mcv = block_data.mcv;3423 const block_mcv = block_data.mcv;
3403 if (block_mcv == .none) {3424 if (block_mcv == .none) {
...@@ -3516,17 +3537,18 @@ fn ensureProcessDeathCapacity(self: *Self, additional_count: usize) !void {...@@ -3516,17 +3537,18 @@ fn ensureProcessDeathCapacity(self: *Self, additional_count: usize) !void {
35163537
3517/// Given an error union, returns the payload3538/// Given an error union, returns the payload
3518fn errUnionPayload(self: *Self, error_union_mcv: MCValue, error_union_ty: Type) !MCValue {3539fn errUnionPayload(self: *Self, error_union_mcv: MCValue, error_union_ty: Type) !MCValue {
3519 const mod = self.bin_file.comp.module.?;3540 const pt = self.pt;
3541 const mod = pt.zcu;
3520 const err_ty = error_union_ty.errorUnionSet(mod);3542 const err_ty = error_union_ty.errorUnionSet(mod);
3521 const payload_ty = error_union_ty.errorUnionPayload(mod);3543 const payload_ty = error_union_ty.errorUnionPayload(mod);
3522 if (err_ty.errorSetIsEmpty(mod)) {3544 if (err_ty.errorSetIsEmpty(mod)) {
3523 return error_union_mcv;3545 return error_union_mcv;
3524 }3546 }
3525 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) {3547 if (!payload_ty.hasRuntimeBitsIgnoreComptime(pt)) {
3526 return MCValue.none;3548 return MCValue.none;
3527 }3549 }
35283550
3529 const payload_offset = @as(u32, @intCast(errUnionPayloadOffset(payload_ty, mod)));3551 const payload_offset = @as(u32, @intCast(errUnionPayloadOffset(payload_ty, pt)));
3530 switch (error_union_mcv) {3552 switch (error_union_mcv) {
3531 .register => return self.fail("TODO errUnionPayload for registers", .{}),3553 .register => return self.fail("TODO errUnionPayload for registers", .{}),
3532 .stack_offset => |off| {3554 .stack_offset => |off| {
...@@ -3587,7 +3609,8 @@ fn finishAir(self: *Self, inst: Air.Inst.Index, result: MCValue, operands: [Live...@@ -3587,7 +3609,8 @@ fn finishAir(self: *Self, inst: Air.Inst.Index, result: MCValue, operands: [Live
3587}3609}
35883610
3589fn genArgDbgInfo(self: Self, inst: Air.Inst.Index, mcv: MCValue) !void {3611fn genArgDbgInfo(self: Self, inst: Air.Inst.Index, mcv: MCValue) !void {
3590 const mod = self.bin_file.comp.module.?;3612 const pt = self.pt;
3613 const mod = pt.zcu;
3591 const arg = self.air.instructions.items(.data)[@intFromEnum(inst)].arg;3614 const arg = self.air.instructions.items(.data)[@intFromEnum(inst)].arg;
3592 const ty = arg.ty.toType();3615 const ty = arg.ty.toType();
3593 const owner_decl = mod.funcOwnerDeclIndex(self.func_index);3616 const owner_decl = mod.funcOwnerDeclIndex(self.func_index);
...@@ -3736,7 +3759,7 @@ fn genLoadASI(self: *Self, value_reg: Register, addr_reg: Register, off_reg: Reg...@@ -3736,7 +3759,7 @@ fn genLoadASI(self: *Self, value_reg: Register, addr_reg: Register, off_reg: Reg
3736}3759}
37373760
3738fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void {3761fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void {
3739 const mod = self.bin_file.comp.module.?;3762 const pt = self.pt;
3740 switch (mcv) {3763 switch (mcv) {
3741 .dead => unreachable,3764 .dead => unreachable,
3742 .unreach, .none => return, // Nothing to do.3765 .unreach, .none => return, // Nothing to do.
...@@ -3935,20 +3958,21 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void...@@ -3935,20 +3958,21 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void
3935 // The value is in memory at a hard-coded address.3958 // The value is in memory at a hard-coded address.
3936 // If the type is a pointer, it means the pointer address is at this memory location.3959 // If the type is a pointer, it means the pointer address is at this memory location.
3937 try self.genSetReg(ty, reg, .{ .immediate = addr });3960 try self.genSetReg(ty, reg, .{ .immediate = addr });
3938 try self.genLoad(reg, reg, i13, 0, ty.abiSize(mod));3961 try self.genLoad(reg, reg, i13, 0, ty.abiSize(pt));
3939 },3962 },
3940 .stack_offset => |off| {3963 .stack_offset => |off| {
3941 const real_offset = realStackOffset(off);3964 const real_offset = realStackOffset(off);
3942 const simm13 = math.cast(i13, real_offset) orelse3965 const simm13 = math.cast(i13, real_offset) orelse
3943 return self.fail("TODO larger stack offsets: {}", .{real_offset});3966 return self.fail("TODO larger stack offsets: {}", .{real_offset});
3944 try self.genLoad(reg, .sp, i13, simm13, ty.abiSize(mod));3967 try self.genLoad(reg, .sp, i13, simm13, ty.abiSize(pt));
3945 },3968 },
3946 }3969 }
3947}3970}
39483971
3949fn genSetStack(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) InnerError!void {3972fn genSetStack(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) InnerError!void {
3950 const mod = self.bin_file.comp.module.?;3973 const pt = self.pt;
3951 const abi_size = ty.abiSize(mod);3974 const mod = pt.zcu;
3975 const abi_size = ty.abiSize(pt);
3952 switch (mcv) {3976 switch (mcv) {
3953 .dead => unreachable,3977 .dead => unreachable,
3954 .unreach, .none => return, // Nothing to do.3978 .unreach, .none => return, // Nothing to do.
...@@ -3956,7 +3980,7 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) InnerErro...@@ -3956,7 +3980,7 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) InnerErro
3956 if (!self.wantSafety())3980 if (!self.wantSafety())
3957 return; // The already existing value will do just fine.3981 return; // The already existing value will do just fine.
3958 // TODO Upgrade this to a memset call when we have that available.3982 // TODO Upgrade this to a memset call when we have that available.
3959 switch (ty.abiSize(mod)) {3983 switch (ty.abiSize(pt)) {
3960 1 => return self.genSetStack(ty, stack_offset, .{ .immediate = 0xaa }),3984 1 => return self.genSetStack(ty, stack_offset, .{ .immediate = 0xaa }),
3961 2 => return self.genSetStack(ty, stack_offset, .{ .immediate = 0xaaaa }),3985 2 => return self.genSetStack(ty, stack_offset, .{ .immediate = 0xaaaa }),
3962 4 => return self.genSetStack(ty, stack_offset, .{ .immediate = 0xaaaaaaaa }),3986 4 => return self.genSetStack(ty, stack_offset, .{ .immediate = 0xaaaaaaaa }),
...@@ -3986,7 +4010,7 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) InnerErro...@@ -3986,7 +4010,7 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) InnerErro
3986 try self.genSetStack(wrapped_ty, stack_offset, .{ .register = rwo.reg });4010 try self.genSetStack(wrapped_ty, stack_offset, .{ .register = rwo.reg });
39874011
3988 const overflow_bit_ty = ty.structFieldType(1, mod);4012 const overflow_bit_ty = ty.structFieldType(1, mod);
3989 const overflow_bit_offset = @as(u32, @intCast(ty.structFieldOffset(1, mod)));4013 const overflow_bit_offset = @as(u32, @intCast(ty.structFieldOffset(1, pt)));
3990 const cond_reg = try self.register_manager.allocReg(null, gp);4014 const cond_reg = try self.register_manager.allocReg(null, gp);
39914015
3992 // TODO handle floating point CCRs4016 // TODO handle floating point CCRs
...@@ -4032,7 +4056,7 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) InnerErro...@@ -4032,7 +4056,7 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) InnerErro
4032 const reg = try self.copyToTmpRegister(ty, mcv);4056 const reg = try self.copyToTmpRegister(ty, mcv);
4033 return self.genSetStack(ty, stack_offset, MCValue{ .register = reg });4057 return self.genSetStack(ty, stack_offset, MCValue{ .register = reg });
4034 } else {4058 } else {
4035 const ptr_ty = try mod.singleMutPtrType(ty);4059 const ptr_ty = try pt.singleMutPtrType(ty);
40364060
4037 const regs = try self.register_manager.allocRegs(4, .{ null, null, null, null }, gp);4061 const regs = try self.register_manager.allocRegs(4, .{ null, null, null, null }, gp);
4038 const regs_locks = self.register_manager.lockRegsAssumeUnused(4, regs);4062 const regs_locks = self.register_manager.lockRegsAssumeUnused(4, regs);
...@@ -4121,12 +4145,13 @@ fn genStoreASI(self: *Self, value_reg: Register, addr_reg: Register, off_reg: Re...@@ -4121,12 +4145,13 @@ fn genStoreASI(self: *Self, value_reg: Register, addr_reg: Register, off_reg: Re
4121}4145}
41224146
4123fn genTypedValue(self: *Self, val: Value) InnerError!MCValue {4147fn genTypedValue(self: *Self, val: Value) InnerError!MCValue {
4124 const mod = self.bin_file.comp.module.?;4148 const pt = self.pt;
4125 const mcv: MCValue = switch (try codegen.genTypedValue(4149 const mcv: MCValue = switch (try codegen.genTypedValue(
4126 self.bin_file,4150 self.bin_file,
4151 pt,
4127 self.src_loc,4152 self.src_loc,
4128 val,4153 val,
4129 mod.funcOwnerDeclIndex(self.func_index),4154 pt.zcu.funcOwnerDeclIndex(self.func_index),
4130 )) {4155 )) {
4131 .mcv => |mcv| switch (mcv) {4156 .mcv => |mcv| switch (mcv) {
4132 .none => .none,4157 .none => .none,
...@@ -4157,14 +4182,15 @@ fn getResolvedInstValue(self: *Self, inst: Air.Inst.Index) MCValue {...@@ -4157,14 +4182,15 @@ fn getResolvedInstValue(self: *Self, inst: Air.Inst.Index) MCValue {
4157}4182}
41584183
4159fn isErr(self: *Self, ty: Type, operand: MCValue) !MCValue {4184fn isErr(self: *Self, ty: Type, operand: MCValue) !MCValue {
4160 const mod = self.bin_file.comp.module.?;4185 const pt = self.pt;
4186 const mod = pt.zcu;
4161 const error_type = ty.errorUnionSet(mod);4187 const error_type = ty.errorUnionSet(mod);
4162 const payload_type = ty.errorUnionPayload(mod);4188 const payload_type = ty.errorUnionPayload(mod);
41634189
4164 if (!error_type.hasRuntimeBits(mod)) {4190 if (!error_type.hasRuntimeBits(pt)) {
4165 return MCValue{ .immediate = 0 }; // always false4191 return MCValue{ .immediate = 0 }; // always false
4166 } else if (!payload_type.hasRuntimeBits(mod)) {4192 } else if (!payload_type.hasRuntimeBits(pt)) {
4167 if (error_type.abiSize(mod) <= 8) {4193 if (error_type.abiSize(pt) <= 8) {
4168 const reg_mcv: MCValue = switch (operand) {4194 const reg_mcv: MCValue = switch (operand) {
4169 .register => operand,4195 .register => operand,
4170 else => .{ .register = try self.copyToTmpRegister(error_type, operand) },4196 else => .{ .register = try self.copyToTmpRegister(error_type, operand) },
...@@ -4255,9 +4281,10 @@ fn jump(self: *Self, inst: Mir.Inst.Index) !void {...@@ -4255,9 +4281,10 @@ fn jump(self: *Self, inst: Mir.Inst.Index) !void {
4255}4281}
42564282
4257fn load(self: *Self, dst_mcv: MCValue, ptr: MCValue, ptr_ty: Type) InnerError!void {4283fn load(self: *Self, dst_mcv: MCValue, ptr: MCValue, ptr_ty: Type) InnerError!void {
4258 const mod = self.bin_file.comp.module.?;4284 const pt = self.pt;
4285 const mod = pt.zcu;
4259 const elem_ty = ptr_ty.childType(mod);4286 const elem_ty = ptr_ty.childType(mod);
4260 const elem_size = elem_ty.abiSize(mod);4287 const elem_size = elem_ty.abiSize(pt);
42614288
4262 switch (ptr) {4289 switch (ptr) {
4263 .none => unreachable,4290 .none => unreachable,
...@@ -4326,7 +4353,8 @@ fn minMax(...@@ -4326,7 +4353,8 @@ fn minMax(
4326 lhs_ty: Type,4353 lhs_ty: Type,
4327 rhs_ty: Type,4354 rhs_ty: Type,
4328) InnerError!MCValue {4355) InnerError!MCValue {
4329 const mod = self.bin_file.comp.module.?;4356 const pt = self.pt;
4357 const mod = pt.zcu;
4330 assert(lhs_ty.eql(rhs_ty, mod));4358 assert(lhs_ty.eql(rhs_ty, mod));
4331 switch (lhs_ty.zigTypeTag(mod)) {4359 switch (lhs_ty.zigTypeTag(mod)) {
4332 .Float => return self.fail("TODO min/max on floats", .{}),4360 .Float => return self.fail("TODO min/max on floats", .{}),
...@@ -4446,7 +4474,8 @@ fn realStackOffset(off: u32) u32 {...@@ -4446,7 +4474,8 @@ fn realStackOffset(off: u32) u32 {
44464474
4447/// Caller must call `CallMCValues.deinit`.4475/// Caller must call `CallMCValues.deinit`.
4448fn resolveCallingConventionValues(self: *Self, fn_ty: Type, role: RegisterView) !CallMCValues {4476fn resolveCallingConventionValues(self: *Self, fn_ty: Type, role: RegisterView) !CallMCValues {
4449 const mod = self.bin_file.comp.module.?;4477 const pt = self.pt;
4478 const mod = pt.zcu;
4450 const ip = &mod.intern_pool;4479 const ip = &mod.intern_pool;
4451 const fn_info = mod.typeToFunc(fn_ty).?;4480 const fn_info = mod.typeToFunc(fn_ty).?;
4452 const cc = fn_info.cc;4481 const cc = fn_info.cc;
...@@ -4487,7 +4516,7 @@ fn resolveCallingConventionValues(self: *Self, fn_ty: Type, role: RegisterView)...@@ -4487,7 +4516,7 @@ fn resolveCallingConventionValues(self: *Self, fn_ty: Type, role: RegisterView)
4487 };4516 };
44884517
4489 for (fn_info.param_types.get(ip), result.args) |ty, *result_arg| {4518 for (fn_info.param_types.get(ip), result.args) |ty, *result_arg| {
4490 const param_size = @as(u32, @intCast(Type.fromInterned(ty).abiSize(mod)));4519 const param_size = @as(u32, @intCast(Type.fromInterned(ty).abiSize(pt)));
4491 if (param_size <= 8) {4520 if (param_size <= 8) {
4492 if (next_register < argument_registers.len) {4521 if (next_register < argument_registers.len) {
4493 result_arg.* = .{ .register = argument_registers[next_register] };4522 result_arg.* = .{ .register = argument_registers[next_register] };
...@@ -4516,10 +4545,10 @@ fn resolveCallingConventionValues(self: *Self, fn_ty: Type, role: RegisterView)...@@ -4516,10 +4545,10 @@ fn resolveCallingConventionValues(self: *Self, fn_ty: Type, role: RegisterView)
45164545
4517 if (ret_ty.zigTypeTag(mod) == .NoReturn) {4546 if (ret_ty.zigTypeTag(mod) == .NoReturn) {
4518 result.return_value = .{ .unreach = {} };4547 result.return_value = .{ .unreach = {} };
4519 } else if (!ret_ty.hasRuntimeBits(mod)) {4548 } else if (!ret_ty.hasRuntimeBits(pt)) {
4520 result.return_value = .{ .none = {} };4549 result.return_value = .{ .none = {} };
4521 } else {4550 } else {
4522 const ret_ty_size = @as(u32, @intCast(ret_ty.abiSize(mod)));4551 const ret_ty_size: u32 = @intCast(ret_ty.abiSize(pt));
4523 // The callee puts the return values in %i0-%i3, which becomes %o0-%o3 inside the caller.4552 // The callee puts the return values in %i0-%i3, which becomes %o0-%o3 inside the caller.
4524 if (ret_ty_size <= 8) {4553 if (ret_ty_size <= 8) {
4525 result.return_value = switch (role) {4554 result.return_value = switch (role) {
...@@ -4538,21 +4567,22 @@ fn resolveCallingConventionValues(self: *Self, fn_ty: Type, role: RegisterView)...@@ -4538,21 +4567,22 @@ fn resolveCallingConventionValues(self: *Self, fn_ty: Type, role: RegisterView)
4538}4567}
45394568
4540fn resolveInst(self: *Self, ref: Air.Inst.Ref) InnerError!MCValue {4569fn resolveInst(self: *Self, ref: Air.Inst.Ref) InnerError!MCValue {
4541 const mod = self.bin_file.comp.module.?;4570 const pt = self.pt;
4542 const ty = self.typeOf(ref);4571 const ty = self.typeOf(ref);
45434572
4544 // If the type has no codegen bits, no need to store it.4573 // If the type has no codegen bits, no need to store it.
4545 if (!ty.hasRuntimeBitsIgnoreComptime(mod)) return .none;4574 if (!ty.hasRuntimeBitsIgnoreComptime(pt)) return .none;
45464575
4547 if (ref.toIndex()) |inst| {4576 if (ref.toIndex()) |inst| {
4548 return self.getResolvedInstValue(inst);4577 return self.getResolvedInstValue(inst);
4549 }4578 }
45504579
4551 return self.genTypedValue((try self.air.value(ref, mod)).?);4580 return self.genTypedValue((try self.air.value(ref, pt)).?);
4552}4581}
45534582
4554fn ret(self: *Self, mcv: MCValue) !void {4583fn ret(self: *Self, mcv: MCValue) !void {
4555 const mod = self.bin_file.comp.module.?;4584 const pt = self.pt;
4585 const mod = pt.zcu;
4556 const ret_ty = self.fn_type.fnReturnType(mod);4586 const ret_ty = self.fn_type.fnReturnType(mod);
4557 try self.setRegOrMem(ret_ty, self.ret_mcv, mcv);4587 try self.setRegOrMem(ret_ty, self.ret_mcv, mcv);
45584588
...@@ -4654,8 +4684,8 @@ pub fn spillInstruction(self: *Self, reg: Register, inst: Air.Inst.Index) !void...@@ -4654,8 +4684,8 @@ pub fn spillInstruction(self: *Self, reg: Register, inst: Air.Inst.Index) !void
4654}4684}
46554685
4656fn store(self: *Self, ptr: MCValue, value: MCValue, ptr_ty: Type, value_ty: Type) InnerError!void {4686fn store(self: *Self, ptr: MCValue, value: MCValue, ptr_ty: Type, value_ty: Type) InnerError!void {
4657 const mod = self.bin_file.comp.module.?;4687 const pt = self.pt;
4658 const abi_size = value_ty.abiSize(mod);4688 const abi_size = value_ty.abiSize(pt);
46594689
4660 switch (ptr) {4690 switch (ptr) {
4661 .none => unreachable,4691 .none => unreachable,
...@@ -4696,11 +4726,12 @@ fn store(self: *Self, ptr: MCValue, value: MCValue, ptr_ty: Type, value_ty: Type...@@ -4696,11 +4726,12 @@ fn store(self: *Self, ptr: MCValue, value: MCValue, ptr_ty: Type, value_ty: Type
46964726
4697fn structFieldPtr(self: *Self, inst: Air.Inst.Index, operand: Air.Inst.Ref, index: u32) !MCValue {4727fn structFieldPtr(self: *Self, inst: Air.Inst.Index, operand: Air.Inst.Ref, index: u32) !MCValue {
4698 return if (self.liveness.isUnused(inst)) .dead else result: {4728 return if (self.liveness.isUnused(inst)) .dead else result: {
4699 const mod = self.bin_file.comp.module.?;4729 const pt = self.pt;
4730 const mod = pt.zcu;
4700 const mcv = try self.resolveInst(operand);4731 const mcv = try self.resolveInst(operand);
4701 const ptr_ty = self.typeOf(operand);4732 const ptr_ty = self.typeOf(operand);
4702 const struct_ty = ptr_ty.childType(mod);4733 const struct_ty = ptr_ty.childType(mod);
4703 const struct_field_offset = @as(u32, @intCast(struct_ty.structFieldOffset(index, mod)));4734 const struct_field_offset = @as(u32, @intCast(struct_ty.structFieldOffset(index, pt)));
4704 switch (mcv) {4735 switch (mcv) {
4705 .ptr_stack_offset => |off| {4736 .ptr_stack_offset => |off| {
4706 break :result MCValue{ .ptr_stack_offset = off - struct_field_offset };4737 break :result MCValue{ .ptr_stack_offset = off - struct_field_offset };
...@@ -4738,7 +4769,8 @@ fn trunc(...@@ -4738,7 +4769,8 @@ fn trunc(
4738 operand_ty: Type,4769 operand_ty: Type,
4739 dest_ty: Type,4770 dest_ty: Type,
4740) !MCValue {4771) !MCValue {
4741 const mod = self.bin_file.comp.module.?;4772 const pt = self.pt;
4773 const mod = pt.zcu;
4742 const info_a = operand_ty.intInfo(mod);4774 const info_a = operand_ty.intInfo(mod);
4743 const info_b = dest_ty.intInfo(mod);4775 const info_b = dest_ty.intInfo(mod);
47444776
...@@ -4848,7 +4880,7 @@ fn truncRegister(...@@ -4848,7 +4880,7 @@ fn truncRegister(
4848 }4880 }
4849}4881}
48504882
4851/// TODO support scope overrides. Also note this logic is duplicated with `Module.wantSafety`.4883/// TODO support scope overrides. Also note this logic is duplicated with `Zcu.wantSafety`.
4852fn wantSafety(self: *Self) bool {4884fn wantSafety(self: *Self) bool {
4853 return switch (self.bin_file.comp.root_mod.optimize_mode) {4885 return switch (self.bin_file.comp.root_mod.optimize_mode) {
4854 .Debug => true,4886 .Debug => true,
...@@ -4859,11 +4891,9 @@ fn wantSafety(self: *Self) bool {...@@ -4859,11 +4891,9 @@ fn wantSafety(self: *Self) bool {
4859}4891}
48604892
4861fn typeOf(self: *Self, inst: Air.Inst.Ref) Type {4893fn typeOf(self: *Self, inst: Air.Inst.Ref) Type {
4862 const mod = self.bin_file.comp.module.?;4894 return self.air.typeOf(inst, &self.pt.zcu.intern_pool);
4863 return self.air.typeOf(inst, &mod.intern_pool);
4864}4895}
48654896
4866fn typeOfIndex(self: *Self, inst: Air.Inst.Index) Type {4897fn typeOfIndex(self: *Self, inst: Air.Inst.Index) Type {
4867 const mod = self.bin_file.comp.module.?;4898 return self.air.typeOfIndex(inst, &self.pt.zcu.intern_pool);
4868 return self.air.typeOfIndex(inst, &mod.intern_pool);
4869}4899}
src/arch/sparc64/Emit.zig+2-4
...@@ -6,9 +6,7 @@ const Endian = std.builtin.Endian;...@@ -6,9 +6,7 @@ const Endian = std.builtin.Endian;
6const assert = std.debug.assert;6const assert = std.debug.assert;
7const link = @import("../../link.zig");7const link = @import("../../link.zig");
8const Zcu = @import("../../Zcu.zig");8const Zcu = @import("../../Zcu.zig");
9/// Deprecated.9const ErrorMsg = Zcu.ErrorMsg;
10const Module = Zcu;
11const ErrorMsg = Module.ErrorMsg;
12const Liveness = @import("../../Liveness.zig");10const Liveness = @import("../../Liveness.zig");
13const log = std.log.scoped(.sparcv9_emit);11const log = std.log.scoped(.sparcv9_emit);
14const DebugInfoOutput = @import("../../codegen.zig").DebugInfoOutput;12const DebugInfoOutput = @import("../../codegen.zig").DebugInfoOutput;
...@@ -24,7 +22,7 @@ bin_file: *link.File,...@@ -24,7 +22,7 @@ bin_file: *link.File,
24debug_output: DebugInfoOutput,22debug_output: DebugInfoOutput,
25target: *const std.Target,23target: *const std.Target,
26err_msg: ?*ErrorMsg = null,24err_msg: ?*ErrorMsg = null,
27src_loc: Module.LazySrcLoc,25src_loc: Zcu.LazySrcLoc,
28code: *std.ArrayList(u8),26code: *std.ArrayList(u8),
2927
30prev_di_line: u32,28prev_di_line: u32,
src/arch/wasm/CodeGen.zig+537-434
...@@ -684,6 +684,7 @@ simd_immediates: std.ArrayListUnmanaged([16]u8) = .{},...@@ -684,6 +684,7 @@ simd_immediates: std.ArrayListUnmanaged([16]u8) = .{},
684target: std.Target,684target: std.Target,
685/// Represents the wasm binary file that is being linked.685/// Represents the wasm binary file that is being linked.
686bin_file: *link.File.Wasm,686bin_file: *link.File.Wasm,
687pt: Zcu.PerThread,
687/// List of MIR Instructions688/// List of MIR Instructions
688mir_instructions: std.MultiArrayList(Mir.Inst) = .{},689mir_instructions: std.MultiArrayList(Mir.Inst) = .{},
689/// Contains extra data for MIR690/// Contains extra data for MIR
...@@ -764,8 +765,7 @@ pub fn deinit(func: *CodeGen) void {...@@ -764,8 +765,7 @@ pub fn deinit(func: *CodeGen) void {
764765
765/// Sets `err_msg` on `CodeGen` and returns `error.CodegenFail` which is caught in link/Wasm.zig766/// Sets `err_msg` on `CodeGen` and returns `error.CodegenFail` which is caught in link/Wasm.zig
766fn fail(func: *CodeGen, comptime fmt: []const u8, args: anytype) InnerError {767fn fail(func: *CodeGen, comptime fmt: []const u8, args: anytype) InnerError {
767 const mod = func.bin_file.base.comp.module.?;768 const src_loc = func.decl.navSrcLoc(func.pt.zcu);
768 const src_loc = func.decl.navSrcLoc(mod);
769 func.err_msg = try Zcu.ErrorMsg.create(func.gpa, src_loc, fmt, args);769 func.err_msg = try Zcu.ErrorMsg.create(func.gpa, src_loc, fmt, args);
770 return error.CodegenFail;770 return error.CodegenFail;
771}771}
...@@ -788,10 +788,11 @@ fn resolveInst(func: *CodeGen, ref: Air.Inst.Ref) InnerError!WValue {...@@ -788,10 +788,11 @@ fn resolveInst(func: *CodeGen, ref: Air.Inst.Ref) InnerError!WValue {
788 const gop = try func.branches.items[0].values.getOrPut(func.gpa, ref);788 const gop = try func.branches.items[0].values.getOrPut(func.gpa, ref);
789 assert(!gop.found_existing);789 assert(!gop.found_existing);
790790
791 const mod = func.bin_file.base.comp.module.?;791 const pt = func.pt;
792 const val = (try func.air.value(ref, mod)).?;792 const mod = pt.zcu;
793 const val = (try func.air.value(ref, pt)).?;
793 const ty = func.typeOf(ref);794 const ty = func.typeOf(ref);
794 if (!ty.hasRuntimeBitsIgnoreComptime(mod) and !ty.isInt(mod) and !ty.isError(mod)) {795 if (!ty.hasRuntimeBitsIgnoreComptime(pt) and !ty.isInt(mod) and !ty.isError(mod)) {
795 gop.value_ptr.* = WValue{ .none = {} };796 gop.value_ptr.* = WValue{ .none = {} };
796 return gop.value_ptr.*;797 return gop.value_ptr.*;
797 }798 }
...@@ -802,8 +803,8 @@ fn resolveInst(func: *CodeGen, ref: Air.Inst.Ref) InnerError!WValue {...@@ -802,8 +803,8 @@ fn resolveInst(func: *CodeGen, ref: Air.Inst.Ref) InnerError!WValue {
802 //803 //
803 // In the other cases, we will simply lower the constant to a value that fits804 // In the other cases, we will simply lower the constant to a value that fits
804 // into a single local (such as a pointer, integer, bool, etc).805 // into a single local (such as a pointer, integer, bool, etc).
805 const result = if (isByRef(ty, mod)) blk: {806 const result = if (isByRef(ty, pt)) blk: {
806 const sym_index = try func.bin_file.lowerUnnamedConst(val, func.decl_index);807 const sym_index = try func.bin_file.lowerUnnamedConst(pt, val, func.decl_index);
807 break :blk WValue{ .memory = sym_index };808 break :blk WValue{ .memory = sym_index };
808 } else try func.lowerConstant(val, ty);809 } else try func.lowerConstant(val, ty);
809810
...@@ -990,7 +991,8 @@ fn addExtraAssumeCapacity(func: *CodeGen, extra: anytype) error{OutOfMemory}!u32...@@ -990,7 +991,8 @@ fn addExtraAssumeCapacity(func: *CodeGen, extra: anytype) error{OutOfMemory}!u32
990}991}
991992
992/// Using a given `Type`, returns the corresponding type993/// Using a given `Type`, returns the corresponding type
993fn typeToValtype(ty: Type, mod: *Zcu) wasm.Valtype {994fn typeToValtype(ty: Type, pt: Zcu.PerThread) wasm.Valtype {
995 const mod = pt.zcu;
994 const target = mod.getTarget();996 const target = mod.getTarget();
995 const ip = &mod.intern_pool;997 const ip = &mod.intern_pool;
996 return switch (ty.zigTypeTag(mod)) {998 return switch (ty.zigTypeTag(mod)) {
...@@ -1002,26 +1004,26 @@ fn typeToValtype(ty: Type, mod: *Zcu) wasm.Valtype {...@@ -1002,26 +1004,26 @@ fn typeToValtype(ty: Type, mod: *Zcu) wasm.Valtype {
1002 else => unreachable,1004 else => unreachable,
1003 },1005 },
1004 .Int, .Enum => blk: {1006 .Int, .Enum => blk: {
1005 const info = ty.intInfo(mod);1007 const info = ty.intInfo(pt.zcu);
1006 if (info.bits <= 32) break :blk wasm.Valtype.i32;1008 if (info.bits <= 32) break :blk wasm.Valtype.i32;
1007 if (info.bits > 32 and info.bits <= 128) break :blk wasm.Valtype.i64;1009 if (info.bits > 32 and info.bits <= 128) break :blk wasm.Valtype.i64;
1008 break :blk wasm.Valtype.i32; // represented as pointer to stack1010 break :blk wasm.Valtype.i32; // represented as pointer to stack
1009 },1011 },
1010 .Struct => {1012 .Struct => {
1011 if (mod.typeToPackedStruct(ty)) |packed_struct| {1013 if (pt.zcu.typeToPackedStruct(ty)) |packed_struct| {
1012 return typeToValtype(Type.fromInterned(packed_struct.backingIntType(ip).*), mod);1014 return typeToValtype(Type.fromInterned(packed_struct.backingIntType(ip).*), pt);
1013 } else {1015 } else {
1014 return wasm.Valtype.i32;1016 return wasm.Valtype.i32;
1015 }1017 }
1016 },1018 },
1017 .Vector => switch (determineSimdStoreStrategy(ty, mod)) {1019 .Vector => switch (determineSimdStoreStrategy(ty, pt)) {
1018 .direct => wasm.Valtype.v128,1020 .direct => wasm.Valtype.v128,
1019 .unrolled => wasm.Valtype.i32,1021 .unrolled => wasm.Valtype.i32,
1020 },1022 },
1021 .Union => switch (ty.containerLayout(mod)) {1023 .Union => switch (ty.containerLayout(pt.zcu)) {
1022 .@"packed" => {1024 .@"packed" => {
1023 const int_ty = mod.intType(.unsigned, @as(u16, @intCast(ty.bitSize(mod)))) catch @panic("out of memory");1025 const int_ty = pt.intType(.unsigned, @as(u16, @intCast(ty.bitSize(pt)))) catch @panic("out of memory");
1024 return typeToValtype(int_ty, mod);1026 return typeToValtype(int_ty, pt);
1025 },1027 },
1026 else => wasm.Valtype.i32,1028 else => wasm.Valtype.i32,
1027 },1029 },
...@@ -1030,17 +1032,17 @@ fn typeToValtype(ty: Type, mod: *Zcu) wasm.Valtype {...@@ -1030,17 +1032,17 @@ fn typeToValtype(ty: Type, mod: *Zcu) wasm.Valtype {
1030}1032}
10311033
1032/// Using a given `Type`, returns the byte representation of its wasm value type1034/// Using a given `Type`, returns the byte representation of its wasm value type
1033fn genValtype(ty: Type, mod: *Zcu) u8 {1035fn genValtype(ty: Type, pt: Zcu.PerThread) u8 {
1034 return wasm.valtype(typeToValtype(ty, mod));1036 return wasm.valtype(typeToValtype(ty, pt));
1035}1037}
10361038
1037/// Using a given `Type`, returns the corresponding wasm value type1039/// Using a given `Type`, returns the corresponding wasm value type
1038/// Differently from `genValtype` this also allows `void` to create a block1040/// Differently from `genValtype` this also allows `void` to create a block
1039/// with no return type1041/// with no return type
1040fn genBlockType(ty: Type, mod: *Zcu) u8 {1042fn genBlockType(ty: Type, pt: Zcu.PerThread) u8 {
1041 return switch (ty.ip_index) {1043 return switch (ty.ip_index) {
1042 .void_type, .noreturn_type => wasm.block_empty,1044 .void_type, .noreturn_type => wasm.block_empty,
1043 else => genValtype(ty, mod),1045 else => genValtype(ty, pt),
1044 };1046 };
1045}1047}
10461048
...@@ -1101,8 +1103,8 @@ fn getResolvedInst(func: *CodeGen, ref: Air.Inst.Ref) *WValue {...@@ -1101,8 +1103,8 @@ fn getResolvedInst(func: *CodeGen, ref: Air.Inst.Ref) *WValue {
1101/// Creates one locals for a given `Type`.1103/// Creates one locals for a given `Type`.
1102/// Returns a corresponding `Wvalue` with `local` as active tag1104/// Returns a corresponding `Wvalue` with `local` as active tag
1103fn allocLocal(func: *CodeGen, ty: Type) InnerError!WValue {1105fn allocLocal(func: *CodeGen, ty: Type) InnerError!WValue {
1104 const mod = func.bin_file.base.comp.module.?;1106 const pt = func.pt;
1105 const valtype = typeToValtype(ty, mod);1107 const valtype = typeToValtype(ty, pt);
1106 switch (valtype) {1108 switch (valtype) {
1107 .i32 => if (func.free_locals_i32.popOrNull()) |index| {1109 .i32 => if (func.free_locals_i32.popOrNull()) |index| {
1108 log.debug("reusing local ({d}) of type {}", .{ index, valtype });1110 log.debug("reusing local ({d}) of type {}", .{ index, valtype });
...@@ -1133,8 +1135,8 @@ fn allocLocal(func: *CodeGen, ty: Type) InnerError!WValue {...@@ -1133,8 +1135,8 @@ fn allocLocal(func: *CodeGen, ty: Type) InnerError!WValue {
1133/// Ensures a new local will be created. This is useful when it's useful1135/// Ensures a new local will be created. This is useful when it's useful
1134/// to use a zero-initialized local.1136/// to use a zero-initialized local.
1135fn ensureAllocLocal(func: *CodeGen, ty: Type) InnerError!WValue {1137fn ensureAllocLocal(func: *CodeGen, ty: Type) InnerError!WValue {
1136 const mod = func.bin_file.base.comp.module.?;1138 const pt = func.pt;
1137 try func.locals.append(func.gpa, genValtype(ty, mod));1139 try func.locals.append(func.gpa, genValtype(ty, pt));
1138 const initial_index = func.local_index;1140 const initial_index = func.local_index;
1139 func.local_index += 1;1141 func.local_index += 1;
1140 return WValue{ .local = .{ .value = initial_index, .references = 1 } };1142 return WValue{ .local = .{ .value = initial_index, .references = 1 } };
...@@ -1147,23 +1149,24 @@ fn genFunctype(...@@ -1147,23 +1149,24 @@ fn genFunctype(
1147 cc: std.builtin.CallingConvention,1149 cc: std.builtin.CallingConvention,
1148 params: []const InternPool.Index,1150 params: []const InternPool.Index,
1149 return_type: Type,1151 return_type: Type,
1150 mod: *Zcu,1152 pt: Zcu.PerThread,
1151) !wasm.Type {1153) !wasm.Type {
1154 const mod = pt.zcu;
1152 var temp_params = std.ArrayList(wasm.Valtype).init(gpa);1155 var temp_params = std.ArrayList(wasm.Valtype).init(gpa);
1153 defer temp_params.deinit();1156 defer temp_params.deinit();
1154 var returns = std.ArrayList(wasm.Valtype).init(gpa);1157 var returns = std.ArrayList(wasm.Valtype).init(gpa);
1155 defer returns.deinit();1158 defer returns.deinit();
11561159
1157 if (firstParamSRet(cc, return_type, mod)) {1160 if (firstParamSRet(cc, return_type, pt)) {
1158 try temp_params.append(.i32); // memory address is always a 32-bit handle1161 try temp_params.append(.i32); // memory address is always a 32-bit handle
1159 } else if (return_type.hasRuntimeBitsIgnoreComptime(mod)) {1162 } else if (return_type.hasRuntimeBitsIgnoreComptime(pt)) {
1160 if (cc == .C) {1163 if (cc == .C) {
1161 const res_classes = abi.classifyType(return_type, mod);1164 const res_classes = abi.classifyType(return_type, pt);
1162 assert(res_classes[0] == .direct and res_classes[1] == .none);1165 assert(res_classes[0] == .direct and res_classes[1] == .none);
1163 const scalar_type = abi.scalarType(return_type, mod);1166 const scalar_type = abi.scalarType(return_type, pt);
1164 try returns.append(typeToValtype(scalar_type, mod));1167 try returns.append(typeToValtype(scalar_type, pt));
1165 } else {1168 } else {
1166 try returns.append(typeToValtype(return_type, mod));1169 try returns.append(typeToValtype(return_type, pt));
1167 }1170 }
1168 } else if (return_type.isError(mod)) {1171 } else if (return_type.isError(mod)) {
1169 try returns.append(.i32);1172 try returns.append(.i32);
...@@ -1172,25 +1175,25 @@ fn genFunctype(...@@ -1172,25 +1175,25 @@ fn genFunctype(
1172 // param types1175 // param types
1173 for (params) |param_type_ip| {1176 for (params) |param_type_ip| {
1174 const param_type = Type.fromInterned(param_type_ip);1177 const param_type = Type.fromInterned(param_type_ip);
1175 if (!param_type.hasRuntimeBitsIgnoreComptime(mod)) continue;1178 if (!param_type.hasRuntimeBitsIgnoreComptime(pt)) continue;
11761179
1177 switch (cc) {1180 switch (cc) {
1178 .C => {1181 .C => {
1179 const param_classes = abi.classifyType(param_type, mod);1182 const param_classes = abi.classifyType(param_type, pt);
1180 for (param_classes) |class| {1183 for (param_classes) |class| {
1181 if (class == .none) continue;1184 if (class == .none) continue;
1182 if (class == .direct) {1185 if (class == .direct) {
1183 const scalar_type = abi.scalarType(param_type, mod);1186 const scalar_type = abi.scalarType(param_type, pt);
1184 try temp_params.append(typeToValtype(scalar_type, mod));1187 try temp_params.append(typeToValtype(scalar_type, pt));
1185 } else {1188 } else {
1186 try temp_params.append(typeToValtype(param_type, mod));1189 try temp_params.append(typeToValtype(param_type, pt));
1187 }1190 }
1188 }1191 }
1189 },1192 },
1190 else => if (isByRef(param_type, mod))1193 else => if (isByRef(param_type, pt))
1191 try temp_params.append(.i32)1194 try temp_params.append(.i32)
1192 else1195 else
1193 try temp_params.append(typeToValtype(param_type, mod)),1196 try temp_params.append(typeToValtype(param_type, pt)),
1194 }1197 }
1195 }1198 }
11961199
...@@ -1202,6 +1205,7 @@ fn genFunctype(...@@ -1202,6 +1205,7 @@ fn genFunctype(
12021205
1203pub fn generate(1206pub fn generate(
1204 bin_file: *link.File,1207 bin_file: *link.File,
1208 pt: Zcu.PerThread,
1205 src_loc: Zcu.LazySrcLoc,1209 src_loc: Zcu.LazySrcLoc,
1206 func_index: InternPool.Index,1210 func_index: InternPool.Index,
1207 air: Air,1211 air: Air,
...@@ -1210,15 +1214,15 @@ pub fn generate(...@@ -1210,15 +1214,15 @@ pub fn generate(
1210 debug_output: codegen.DebugInfoOutput,1214 debug_output: codegen.DebugInfoOutput,
1211) codegen.CodeGenError!codegen.Result {1215) codegen.CodeGenError!codegen.Result {
1212 _ = src_loc;1216 _ = src_loc;
1213 const comp = bin_file.comp;1217 const zcu = pt.zcu;
1214 const gpa = comp.gpa;1218 const gpa = zcu.gpa;
1215 const zcu = comp.module.?;
1216 const func = zcu.funcInfo(func_index);1219 const func = zcu.funcInfo(func_index);
1217 const decl = zcu.declPtr(func.owner_decl);1220 const decl = zcu.declPtr(func.owner_decl);
1218 const namespace = zcu.namespacePtr(decl.src_namespace);1221 const namespace = zcu.namespacePtr(decl.src_namespace);
1219 const target = namespace.fileScope(zcu).mod.resolved_target.result;1222 const target = namespace.fileScope(zcu).mod.resolved_target.result;
1220 var code_gen: CodeGen = .{1223 var code_gen: CodeGen = .{
1221 .gpa = gpa,1224 .gpa = gpa,
1225 .pt = pt,
1222 .air = air,1226 .air = air,
1223 .liveness = liveness,1227 .liveness = liveness,
1224 .code = code,1228 .code = code,
...@@ -1242,10 +1246,11 @@ pub fn generate(...@@ -1242,10 +1246,11 @@ pub fn generate(
1242}1246}
12431247
1244fn genFunc(func: *CodeGen) InnerError!void {1248fn genFunc(func: *CodeGen) InnerError!void {
1245 const mod = func.bin_file.base.comp.module.?;1249 const pt = func.pt;
1250 const mod = pt.zcu;
1246 const ip = &mod.intern_pool;1251 const ip = &mod.intern_pool;
1247 const fn_info = mod.typeToFunc(func.decl.typeOf(mod)).?;1252 const fn_info = mod.typeToFunc(func.decl.typeOf(mod)).?;
1248 var func_type = try genFunctype(func.gpa, fn_info.cc, fn_info.param_types.get(ip), Type.fromInterned(fn_info.return_type), mod);1253 var func_type = try genFunctype(func.gpa, fn_info.cc, fn_info.param_types.get(ip), Type.fromInterned(fn_info.return_type), pt);
1249 defer func_type.deinit(func.gpa);1254 defer func_type.deinit(func.gpa);
1250 _ = try func.bin_file.storeDeclType(func.decl_index, func_type);1255 _ = try func.bin_file.storeDeclType(func.decl_index, func_type);
12511256
...@@ -1272,7 +1277,7 @@ fn genFunc(func: *CodeGen) InnerError!void {...@@ -1272,7 +1277,7 @@ fn genFunc(func: *CodeGen) InnerError!void {
1272 if (func_type.returns.len != 0 and func.air.instructions.len > 0) {1277 if (func_type.returns.len != 0 and func.air.instructions.len > 0) {
1273 const inst: Air.Inst.Index = @enumFromInt(func.air.instructions.len - 1);1278 const inst: Air.Inst.Index = @enumFromInt(func.air.instructions.len - 1);
1274 const last_inst_ty = func.typeOfIndex(inst);1279 const last_inst_ty = func.typeOfIndex(inst);
1275 if (!last_inst_ty.hasRuntimeBitsIgnoreComptime(mod) or last_inst_ty.isNoReturn(mod)) {1280 if (!last_inst_ty.hasRuntimeBitsIgnoreComptime(pt) or last_inst_ty.isNoReturn(mod)) {
1276 try func.addTag(.@"unreachable");1281 try func.addTag(.@"unreachable");
1277 }1282 }
1278 }1283 }
...@@ -1354,7 +1359,8 @@ const CallWValues = struct {...@@ -1354,7 +1359,8 @@ const CallWValues = struct {
1354};1359};
13551360
1356fn resolveCallingConventionValues(func: *CodeGen, fn_ty: Type) InnerError!CallWValues {1361fn resolveCallingConventionValues(func: *CodeGen, fn_ty: Type) InnerError!CallWValues {
1357 const mod = func.bin_file.base.comp.module.?;1362 const pt = func.pt;
1363 const mod = pt.zcu;
1358 const ip = &mod.intern_pool;1364 const ip = &mod.intern_pool;
1359 const fn_info = mod.typeToFunc(fn_ty).?;1365 const fn_info = mod.typeToFunc(fn_ty).?;
1360 const cc = fn_info.cc;1366 const cc = fn_info.cc;
...@@ -1369,7 +1375,7 @@ fn resolveCallingConventionValues(func: *CodeGen, fn_ty: Type) InnerError!CallWV...@@ -1369,7 +1375,7 @@ fn resolveCallingConventionValues(func: *CodeGen, fn_ty: Type) InnerError!CallWV
13691375
1370 // Check if we store the result as a pointer to the stack rather than1376 // Check if we store the result as a pointer to the stack rather than
1371 // by value1377 // by value
1372 if (firstParamSRet(fn_info.cc, Type.fromInterned(fn_info.return_type), mod)) {1378 if (firstParamSRet(fn_info.cc, Type.fromInterned(fn_info.return_type), pt)) {
1373 // the sret arg will be passed as first argument, therefore we1379 // the sret arg will be passed as first argument, therefore we
1374 // set the `return_value` before allocating locals for regular args.1380 // set the `return_value` before allocating locals for regular args.
1375 result.return_value = .{ .local = .{ .value = func.local_index, .references = 1 } };1381 result.return_value = .{ .local = .{ .value = func.local_index, .references = 1 } };
...@@ -1379,7 +1385,7 @@ fn resolveCallingConventionValues(func: *CodeGen, fn_ty: Type) InnerError!CallWV...@@ -1379,7 +1385,7 @@ fn resolveCallingConventionValues(func: *CodeGen, fn_ty: Type) InnerError!CallWV
1379 switch (cc) {1385 switch (cc) {
1380 .Unspecified => {1386 .Unspecified => {
1381 for (fn_info.param_types.get(ip)) |ty| {1387 for (fn_info.param_types.get(ip)) |ty| {
1382 if (!Type.fromInterned(ty).hasRuntimeBitsIgnoreComptime(mod)) {1388 if (!Type.fromInterned(ty).hasRuntimeBitsIgnoreComptime(pt)) {
1383 continue;1389 continue;
1384 }1390 }
13851391
...@@ -1389,7 +1395,7 @@ fn resolveCallingConventionValues(func: *CodeGen, fn_ty: Type) InnerError!CallWV...@@ -1389,7 +1395,7 @@ fn resolveCallingConventionValues(func: *CodeGen, fn_ty: Type) InnerError!CallWV
1389 },1395 },
1390 .C => {1396 .C => {
1391 for (fn_info.param_types.get(ip)) |ty| {1397 for (fn_info.param_types.get(ip)) |ty| {
1392 const ty_classes = abi.classifyType(Type.fromInterned(ty), mod);1398 const ty_classes = abi.classifyType(Type.fromInterned(ty), pt);
1393 for (ty_classes) |class| {1399 for (ty_classes) |class| {
1394 if (class == .none) continue;1400 if (class == .none) continue;
1395 try args.append(.{ .local = .{ .value = func.local_index, .references = 1 } });1401 try args.append(.{ .local = .{ .value = func.local_index, .references = 1 } });
...@@ -1403,11 +1409,11 @@ fn resolveCallingConventionValues(func: *CodeGen, fn_ty: Type) InnerError!CallWV...@@ -1403,11 +1409,11 @@ fn resolveCallingConventionValues(func: *CodeGen, fn_ty: Type) InnerError!CallWV
1403 return result;1409 return result;
1404}1410}
14051411
1406fn firstParamSRet(cc: std.builtin.CallingConvention, return_type: Type, mod: *Zcu) bool {1412fn firstParamSRet(cc: std.builtin.CallingConvention, return_type: Type, pt: Zcu.PerThread) bool {
1407 switch (cc) {1413 switch (cc) {
1408 .Unspecified, .Inline => return isByRef(return_type, mod),1414 .Unspecified, .Inline => return isByRef(return_type, pt),
1409 .C => {1415 .C => {
1410 const ty_classes = abi.classifyType(return_type, mod);1416 const ty_classes = abi.classifyType(return_type, pt);
1411 if (ty_classes[0] == .indirect) return true;1417 if (ty_classes[0] == .indirect) return true;
1412 if (ty_classes[0] == .direct and ty_classes[1] == .direct) return true;1418 if (ty_classes[0] == .direct and ty_classes[1] == .direct) return true;
1413 return false;1419 return false;
...@@ -1423,8 +1429,9 @@ fn lowerArg(func: *CodeGen, cc: std.builtin.CallingConvention, ty: Type, value:...@@ -1423,8 +1429,9 @@ fn lowerArg(func: *CodeGen, cc: std.builtin.CallingConvention, ty: Type, value:
1423 return func.lowerToStack(value);1429 return func.lowerToStack(value);
1424 }1430 }
14251431
1426 const mod = func.bin_file.base.comp.module.?;1432 const pt = func.pt;
1427 const ty_classes = abi.classifyType(ty, mod);1433 const mod = pt.zcu;
1434 const ty_classes = abi.classifyType(ty, pt);
1428 assert(ty_classes[0] != .none);1435 assert(ty_classes[0] != .none);
1429 switch (ty.zigTypeTag(mod)) {1436 switch (ty.zigTypeTag(mod)) {
1430 .Struct, .Union => {1437 .Struct, .Union => {
...@@ -1432,7 +1439,7 @@ fn lowerArg(func: *CodeGen, cc: std.builtin.CallingConvention, ty: Type, value:...@@ -1432,7 +1439,7 @@ fn lowerArg(func: *CodeGen, cc: std.builtin.CallingConvention, ty: Type, value:
1432 return func.lowerToStack(value);1439 return func.lowerToStack(value);
1433 }1440 }
1434 assert(ty_classes[0] == .direct);1441 assert(ty_classes[0] == .direct);
1435 const scalar_type = abi.scalarType(ty, mod);1442 const scalar_type = abi.scalarType(ty, pt);
1436 switch (value) {1443 switch (value) {
1437 .memory,1444 .memory,
1438 .memory_offset,1445 .memory_offset,
...@@ -1447,7 +1454,7 @@ fn lowerArg(func: *CodeGen, cc: std.builtin.CallingConvention, ty: Type, value:...@@ -1447,7 +1454,7 @@ fn lowerArg(func: *CodeGen, cc: std.builtin.CallingConvention, ty: Type, value:
1447 return func.lowerToStack(value);1454 return func.lowerToStack(value);
1448 }1455 }
1449 assert(ty_classes[0] == .direct and ty_classes[1] == .direct);1456 assert(ty_classes[0] == .direct and ty_classes[1] == .direct);
1450 assert(ty.abiSize(mod) == 16);1457 assert(ty.abiSize(pt) == 16);
1451 // in this case we have an integer or float that must be lowered as 2 i64's.1458 // in this case we have an integer or float that must be lowered as 2 i64's.
1452 try func.emitWValue(value);1459 try func.emitWValue(value);
1453 try func.addMemArg(.i64_load, .{ .offset = value.offset(), .alignment = 8 });1460 try func.addMemArg(.i64_load, .{ .offset = value.offset(), .alignment = 8 });
...@@ -1514,18 +1521,18 @@ fn restoreStackPointer(func: *CodeGen) !void {...@@ -1514,18 +1521,18 @@ fn restoreStackPointer(func: *CodeGen) !void {
1514///1521///
1515/// Asserts Type has codegenbits1522/// Asserts Type has codegenbits
1516fn allocStack(func: *CodeGen, ty: Type) !WValue {1523fn allocStack(func: *CodeGen, ty: Type) !WValue {
1517 const mod = func.bin_file.base.comp.module.?;1524 const pt = func.pt;
1518 assert(ty.hasRuntimeBitsIgnoreComptime(mod));1525 assert(ty.hasRuntimeBitsIgnoreComptime(pt));
1519 if (func.initial_stack_value == .none) {1526 if (func.initial_stack_value == .none) {
1520 try func.initializeStack();1527 try func.initializeStack();
1521 }1528 }
15221529
1523 const abi_size = std.math.cast(u32, ty.abiSize(mod)) orelse {1530 const abi_size = std.math.cast(u32, ty.abiSize(pt)) orelse {
1524 return func.fail("Type {} with ABI size of {d} exceeds stack frame size", .{1531 return func.fail("Type {} with ABI size of {d} exceeds stack frame size", .{
1525 ty.fmt(mod), ty.abiSize(mod),1532 ty.fmt(pt), ty.abiSize(pt),
1526 });1533 });
1527 };1534 };
1528 const abi_align = ty.abiAlignment(mod);1535 const abi_align = ty.abiAlignment(pt);
15291536
1530 func.stack_alignment = func.stack_alignment.max(abi_align);1537 func.stack_alignment = func.stack_alignment.max(abi_align);
15311538
...@@ -1540,7 +1547,8 @@ fn allocStack(func: *CodeGen, ty: Type) !WValue {...@@ -1540,7 +1547,8 @@ fn allocStack(func: *CodeGen, ty: Type) !WValue {
1540/// This is different from allocStack where this will use the pointer's alignment1547/// This is different from allocStack where this will use the pointer's alignment
1541/// if it is set, to ensure the stack alignment will be set correctly.1548/// if it is set, to ensure the stack alignment will be set correctly.
1542fn allocStackPtr(func: *CodeGen, inst: Air.Inst.Index) !WValue {1549fn allocStackPtr(func: *CodeGen, inst: Air.Inst.Index) !WValue {
1543 const mod = func.bin_file.base.comp.module.?;1550 const pt = func.pt;
1551 const mod = pt.zcu;
1544 const ptr_ty = func.typeOfIndex(inst);1552 const ptr_ty = func.typeOfIndex(inst);
1545 const pointee_ty = ptr_ty.childType(mod);1553 const pointee_ty = ptr_ty.childType(mod);
15461554
...@@ -1548,14 +1556,14 @@ fn allocStackPtr(func: *CodeGen, inst: Air.Inst.Index) !WValue {...@@ -1548,14 +1556,14 @@ fn allocStackPtr(func: *CodeGen, inst: Air.Inst.Index) !WValue {
1548 try func.initializeStack();1556 try func.initializeStack();
1549 }1557 }
15501558
1551 if (!pointee_ty.hasRuntimeBitsIgnoreComptime(mod)) {1559 if (!pointee_ty.hasRuntimeBitsIgnoreComptime(pt)) {
1552 return func.allocStack(Type.usize); // create a value containing just the stack pointer.1560 return func.allocStack(Type.usize); // create a value containing just the stack pointer.
1553 }1561 }
15541562
1555 const abi_alignment = ptr_ty.ptrAlignment(mod);1563 const abi_alignment = ptr_ty.ptrAlignment(pt);
1556 const abi_size = std.math.cast(u32, pointee_ty.abiSize(mod)) orelse {1564 const abi_size = std.math.cast(u32, pointee_ty.abiSize(pt)) orelse {
1557 return func.fail("Type {} with ABI size of {d} exceeds stack frame size", .{1565 return func.fail("Type {} with ABI size of {d} exceeds stack frame size", .{
1558 pointee_ty.fmt(mod), pointee_ty.abiSize(mod),1566 pointee_ty.fmt(pt), pointee_ty.abiSize(pt),
1559 });1567 });
1560 };1568 };
1561 func.stack_alignment = func.stack_alignment.max(abi_alignment);1569 func.stack_alignment = func.stack_alignment.max(abi_alignment);
...@@ -1711,7 +1719,8 @@ fn arch(func: *const CodeGen) std.Target.Cpu.Arch {...@@ -1711,7 +1719,8 @@ fn arch(func: *const CodeGen) std.Target.Cpu.Arch {
17111719
1712/// For a given `Type`, will return true when the type will be passed1720/// For a given `Type`, will return true when the type will be passed
1713/// by reference, rather than by value1721/// by reference, rather than by value
1714fn isByRef(ty: Type, mod: *Zcu) bool {1722fn isByRef(ty: Type, pt: Zcu.PerThread) bool {
1723 const mod = pt.zcu;
1715 const ip = &mod.intern_pool;1724 const ip = &mod.intern_pool;
1716 const target = mod.getTarget();1725 const target = mod.getTarget();
1717 switch (ty.zigTypeTag(mod)) {1726 switch (ty.zigTypeTag(mod)) {
...@@ -1734,28 +1743,28 @@ fn isByRef(ty: Type, mod: *Zcu) bool {...@@ -1734,28 +1743,28 @@ fn isByRef(ty: Type, mod: *Zcu) bool {
17341743
1735 .Array,1744 .Array,
1736 .Frame,1745 .Frame,
1737 => return ty.hasRuntimeBitsIgnoreComptime(mod),1746 => return ty.hasRuntimeBitsIgnoreComptime(pt),
1738 .Union => {1747 .Union => {
1739 if (mod.typeToUnion(ty)) |union_obj| {1748 if (mod.typeToUnion(ty)) |union_obj| {
1740 if (union_obj.getLayout(ip) == .@"packed") {1749 if (union_obj.getLayout(ip) == .@"packed") {
1741 return ty.abiSize(mod) > 8;1750 return ty.abiSize(pt) > 8;
1742 }1751 }
1743 }1752 }
1744 return ty.hasRuntimeBitsIgnoreComptime(mod);1753 return ty.hasRuntimeBitsIgnoreComptime(pt);
1745 },1754 },
1746 .Struct => {1755 .Struct => {
1747 if (mod.typeToPackedStruct(ty)) |packed_struct| {1756 if (mod.typeToPackedStruct(ty)) |packed_struct| {
1748 return isByRef(Type.fromInterned(packed_struct.backingIntType(ip).*), mod);1757 return isByRef(Type.fromInterned(packed_struct.backingIntType(ip).*), pt);
1749 }1758 }
1750 return ty.hasRuntimeBitsIgnoreComptime(mod);1759 return ty.hasRuntimeBitsIgnoreComptime(pt);
1751 },1760 },
1752 .Vector => return determineSimdStoreStrategy(ty, mod) == .unrolled,1761 .Vector => return determineSimdStoreStrategy(ty, pt) == .unrolled,
1753 .Int => return ty.intInfo(mod).bits > 64,1762 .Int => return ty.intInfo(mod).bits > 64,
1754 .Enum => return ty.intInfo(mod).bits > 64,1763 .Enum => return ty.intInfo(mod).bits > 64,
1755 .Float => return ty.floatBits(target) > 64,1764 .Float => return ty.floatBits(target) > 64,
1756 .ErrorUnion => {1765 .ErrorUnion => {
1757 const pl_ty = ty.errorUnionPayload(mod);1766 const pl_ty = ty.errorUnionPayload(mod);
1758 if (!pl_ty.hasRuntimeBitsIgnoreComptime(mod)) {1767 if (!pl_ty.hasRuntimeBitsIgnoreComptime(pt)) {
1759 return false;1768 return false;
1760 }1769 }
1761 return true;1770 return true;
...@@ -1764,7 +1773,7 @@ fn isByRef(ty: Type, mod: *Zcu) bool {...@@ -1764,7 +1773,7 @@ fn isByRef(ty: Type, mod: *Zcu) bool {
1764 if (ty.isPtrLikeOptional(mod)) return false;1773 if (ty.isPtrLikeOptional(mod)) return false;
1765 const pl_type = ty.optionalChild(mod);1774 const pl_type = ty.optionalChild(mod);
1766 if (pl_type.zigTypeTag(mod) == .ErrorSet) return false;1775 if (pl_type.zigTypeTag(mod) == .ErrorSet) return false;
1767 return pl_type.hasRuntimeBitsIgnoreComptime(mod);1776 return pl_type.hasRuntimeBitsIgnoreComptime(pt);
1768 },1777 },
1769 .Pointer => {1778 .Pointer => {
1770 // Slices act like struct and will be passed by reference1779 // Slices act like struct and will be passed by reference
...@@ -1783,11 +1792,11 @@ const SimdStoreStrategy = enum {...@@ -1783,11 +1792,11 @@ const SimdStoreStrategy = enum {
1783/// This means when a given type is 128 bits and either the simd128 or relaxed-simd1792/// This means when a given type is 128 bits and either the simd128 or relaxed-simd
1784/// features are enabled, the function will return `.direct`. This would allow to store1793/// features are enabled, the function will return `.direct`. This would allow to store
1785/// it using a instruction, rather than an unrolled version.1794/// it using a instruction, rather than an unrolled version.
1786fn determineSimdStoreStrategy(ty: Type, mod: *Zcu) SimdStoreStrategy {1795fn determineSimdStoreStrategy(ty: Type, pt: Zcu.PerThread) SimdStoreStrategy {
1787 std.debug.assert(ty.zigTypeTag(mod) == .Vector);1796 std.debug.assert(ty.zigTypeTag(pt.zcu) == .Vector);
1788 if (ty.bitSize(mod) != 128) return .unrolled;1797 if (ty.bitSize(pt) != 128) return .unrolled;
1789 const hasFeature = std.Target.wasm.featureSetHas;1798 const hasFeature = std.Target.wasm.featureSetHas;
1790 const target = mod.getTarget();1799 const target = pt.zcu.getTarget();
1791 const features = target.cpu.features;1800 const features = target.cpu.features;
1792 if (hasFeature(features, .relaxed_simd) or hasFeature(features, .simd128)) {1801 if (hasFeature(features, .relaxed_simd) or hasFeature(features, .simd128)) {
1793 return .direct;1802 return .direct;
...@@ -2064,7 +2073,8 @@ fn genInst(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -2064,7 +2073,8 @@ fn genInst(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
2064}2073}
20652074
2066fn genBody(func: *CodeGen, body: []const Air.Inst.Index) InnerError!void {2075fn genBody(func: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
2067 const mod = func.bin_file.base.comp.module.?;2076 const pt = func.pt;
2077 const mod = pt.zcu;
2068 const ip = &mod.intern_pool;2078 const ip = &mod.intern_pool;
20692079
2070 for (body) |inst| {2080 for (body) |inst| {
...@@ -2085,7 +2095,8 @@ fn genBody(func: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -2085,7 +2095,8 @@ fn genBody(func: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
2085}2095}
20862096
2087fn airRet(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {2097fn airRet(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
2088 const mod = func.bin_file.base.comp.module.?;2098 const pt = func.pt;
2099 const mod = pt.zcu;
2089 const un_op = func.air.instructions.items(.data)[@intFromEnum(inst)].un_op;2100 const un_op = func.air.instructions.items(.data)[@intFromEnum(inst)].un_op;
2090 const operand = try func.resolveInst(un_op);2101 const operand = try func.resolveInst(un_op);
2091 const fn_info = mod.typeToFunc(func.decl.typeOf(mod)).?;2102 const fn_info = mod.typeToFunc(func.decl.typeOf(mod)).?;
...@@ -2095,27 +2106,27 @@ fn airRet(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -2095,27 +2106,27 @@ fn airRet(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
2095 // to the stack instead2106 // to the stack instead
2096 if (func.return_value != .none) {2107 if (func.return_value != .none) {
2097 try func.store(func.return_value, operand, ret_ty, 0);2108 try func.store(func.return_value, operand, ret_ty, 0);
2098 } else if (fn_info.cc == .C and ret_ty.hasRuntimeBitsIgnoreComptime(mod)) {2109 } else if (fn_info.cc == .C and ret_ty.hasRuntimeBitsIgnoreComptime(pt)) {
2099 switch (ret_ty.zigTypeTag(mod)) {2110 switch (ret_ty.zigTypeTag(mod)) {
2100 // Aggregate types can be lowered as a singular value2111 // Aggregate types can be lowered as a singular value
2101 .Struct, .Union => {2112 .Struct, .Union => {
2102 const scalar_type = abi.scalarType(ret_ty, mod);2113 const scalar_type = abi.scalarType(ret_ty, pt);
2103 try func.emitWValue(operand);2114 try func.emitWValue(operand);
2104 const opcode = buildOpcode(.{2115 const opcode = buildOpcode(.{
2105 .op = .load,2116 .op = .load,
2106 .width = @as(u8, @intCast(scalar_type.abiSize(mod) * 8)),2117 .width = @as(u8, @intCast(scalar_type.abiSize(pt) * 8)),
2107 .signedness = if (scalar_type.isSignedInt(mod)) .signed else .unsigned,2118 .signedness = if (scalar_type.isSignedInt(mod)) .signed else .unsigned,
2108 .valtype1 = typeToValtype(scalar_type, mod),2119 .valtype1 = typeToValtype(scalar_type, pt),
2109 });2120 });
2110 try func.addMemArg(Mir.Inst.Tag.fromOpcode(opcode), .{2121 try func.addMemArg(Mir.Inst.Tag.fromOpcode(opcode), .{
2111 .offset = operand.offset(),2122 .offset = operand.offset(),
2112 .alignment = @intCast(scalar_type.abiAlignment(mod).toByteUnits().?),2123 .alignment = @intCast(scalar_type.abiAlignment(pt).toByteUnits().?),
2113 });2124 });
2114 },2125 },
2115 else => try func.emitWValue(operand),2126 else => try func.emitWValue(operand),
2116 }2127 }
2117 } else {2128 } else {
2118 if (!ret_ty.hasRuntimeBitsIgnoreComptime(mod) and ret_ty.isError(mod)) {2129 if (!ret_ty.hasRuntimeBitsIgnoreComptime(pt) and ret_ty.isError(mod)) {
2119 try func.addImm32(0);2130 try func.addImm32(0);
2120 } else {2131 } else {
2121 try func.emitWValue(operand);2132 try func.emitWValue(operand);
...@@ -2128,16 +2139,17 @@ fn airRet(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -2128,16 +2139,17 @@ fn airRet(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
2128}2139}
21292140
2130fn airRetPtr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {2141fn airRetPtr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
2131 const mod = func.bin_file.base.comp.module.?;2142 const pt = func.pt;
2143 const mod = pt.zcu;
2132 const child_type = func.typeOfIndex(inst).childType(mod);2144 const child_type = func.typeOfIndex(inst).childType(mod);
21332145
2134 const result = result: {2146 const result = result: {
2135 if (!child_type.isFnOrHasRuntimeBitsIgnoreComptime(mod)) {2147 if (!child_type.isFnOrHasRuntimeBitsIgnoreComptime(pt)) {
2136 break :result try func.allocStack(Type.usize); // create pointer to void2148 break :result try func.allocStack(Type.usize); // create pointer to void
2137 }2149 }
21382150
2139 const fn_info = mod.typeToFunc(func.decl.typeOf(mod)).?;2151 const fn_info = mod.typeToFunc(func.decl.typeOf(mod)).?;
2140 if (firstParamSRet(fn_info.cc, Type.fromInterned(fn_info.return_type), mod)) {2152 if (firstParamSRet(fn_info.cc, Type.fromInterned(fn_info.return_type), pt)) {
2141 break :result func.return_value;2153 break :result func.return_value;
2142 }2154 }
21432155
...@@ -2148,17 +2160,18 @@ fn airRetPtr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -2148,17 +2160,18 @@ fn airRetPtr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
2148}2160}
21492161
2150fn airRetLoad(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {2162fn airRetLoad(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
2151 const mod = func.bin_file.base.comp.module.?;2163 const pt = func.pt;
2164 const mod = pt.zcu;
2152 const un_op = func.air.instructions.items(.data)[@intFromEnum(inst)].un_op;2165 const un_op = func.air.instructions.items(.data)[@intFromEnum(inst)].un_op;
2153 const operand = try func.resolveInst(un_op);2166 const operand = try func.resolveInst(un_op);
2154 const ret_ty = func.typeOf(un_op).childType(mod);2167 const ret_ty = func.typeOf(un_op).childType(mod);
21552168
2156 const fn_info = mod.typeToFunc(func.decl.typeOf(mod)).?;2169 const fn_info = mod.typeToFunc(func.decl.typeOf(mod)).?;
2157 if (!ret_ty.hasRuntimeBitsIgnoreComptime(mod)) {2170 if (!ret_ty.hasRuntimeBitsIgnoreComptime(pt)) {
2158 if (ret_ty.isError(mod)) {2171 if (ret_ty.isError(mod)) {
2159 try func.addImm32(0);2172 try func.addImm32(0);
2160 }2173 }
2161 } else if (!firstParamSRet(fn_info.cc, Type.fromInterned(fn_info.return_type), mod)) {2174 } else if (!firstParamSRet(fn_info.cc, Type.fromInterned(fn_info.return_type), pt)) {
2162 // leave on the stack2175 // leave on the stack
2163 _ = try func.load(operand, ret_ty, 0);2176 _ = try func.load(operand, ret_ty, 0);
2164 }2177 }
...@@ -2175,7 +2188,8 @@ fn airCall(func: *CodeGen, inst: Air.Inst.Index, modifier: std.builtin.CallModif...@@ -2175,7 +2188,8 @@ fn airCall(func: *CodeGen, inst: Air.Inst.Index, modifier: std.builtin.CallModif
2175 const args = @as([]const Air.Inst.Ref, @ptrCast(func.air.extra[extra.end..][0..extra.data.args_len]));2188 const args = @as([]const Air.Inst.Ref, @ptrCast(func.air.extra[extra.end..][0..extra.data.args_len]));
2176 const ty = func.typeOf(pl_op.operand);2189 const ty = func.typeOf(pl_op.operand);
21772190
2178 const mod = func.bin_file.base.comp.module.?;2191 const pt = func.pt;
2192 const mod = pt.zcu;
2179 const ip = &mod.intern_pool;2193 const ip = &mod.intern_pool;
2180 const fn_ty = switch (ty.zigTypeTag(mod)) {2194 const fn_ty = switch (ty.zigTypeTag(mod)) {
2181 .Fn => ty,2195 .Fn => ty,
...@@ -2184,20 +2198,20 @@ fn airCall(func: *CodeGen, inst: Air.Inst.Index, modifier: std.builtin.CallModif...@@ -2184,20 +2198,20 @@ fn airCall(func: *CodeGen, inst: Air.Inst.Index, modifier: std.builtin.CallModif
2184 };2198 };
2185 const ret_ty = fn_ty.fnReturnType(mod);2199 const ret_ty = fn_ty.fnReturnType(mod);
2186 const fn_info = mod.typeToFunc(fn_ty).?;2200 const fn_info = mod.typeToFunc(fn_ty).?;
2187 const first_param_sret = firstParamSRet(fn_info.cc, Type.fromInterned(fn_info.return_type), mod);2201 const first_param_sret = firstParamSRet(fn_info.cc, Type.fromInterned(fn_info.return_type), pt);
21882202
2189 const callee: ?InternPool.DeclIndex = blk: {2203 const callee: ?InternPool.DeclIndex = blk: {
2190 const func_val = (try func.air.value(pl_op.operand, mod)) orelse break :blk null;2204 const func_val = (try func.air.value(pl_op.operand, pt)) orelse break :blk null;
21912205
2192 if (func_val.getFunction(mod)) |function| {2206 if (func_val.getFunction(mod)) |function| {
2193 _ = try func.bin_file.getOrCreateAtomForDecl(function.owner_decl);2207 _ = try func.bin_file.getOrCreateAtomForDecl(pt, function.owner_decl);
2194 break :blk function.owner_decl;2208 break :blk function.owner_decl;
2195 } else if (func_val.getExternFunc(mod)) |extern_func| {2209 } else if (func_val.getExternFunc(mod)) |extern_func| {
2196 const ext_decl = mod.declPtr(extern_func.decl);2210 const ext_decl = mod.declPtr(extern_func.decl);
2197 const ext_info = mod.typeToFunc(ext_decl.typeOf(mod)).?;2211 const ext_info = mod.typeToFunc(ext_decl.typeOf(mod)).?;
2198 var func_type = try genFunctype(func.gpa, ext_info.cc, ext_info.param_types.get(ip), Type.fromInterned(ext_info.return_type), mod);2212 var func_type = try genFunctype(func.gpa, ext_info.cc, ext_info.param_types.get(ip), Type.fromInterned(ext_info.return_type), pt);
2199 defer func_type.deinit(func.gpa);2213 defer func_type.deinit(func.gpa);
2200 const atom_index = try func.bin_file.getOrCreateAtomForDecl(extern_func.decl);2214 const atom_index = try func.bin_file.getOrCreateAtomForDecl(pt, extern_func.decl);
2201 const atom = func.bin_file.getAtomPtr(atom_index);2215 const atom = func.bin_file.getAtomPtr(atom_index);
2202 const type_index = try func.bin_file.storeDeclType(extern_func.decl, func_type);2216 const type_index = try func.bin_file.storeDeclType(extern_func.decl, func_type);
2203 try func.bin_file.addOrUpdateImport(2217 try func.bin_file.addOrUpdateImport(
...@@ -2210,7 +2224,7 @@ fn airCall(func: *CodeGen, inst: Air.Inst.Index, modifier: std.builtin.CallModif...@@ -2210,7 +2224,7 @@ fn airCall(func: *CodeGen, inst: Air.Inst.Index, modifier: std.builtin.CallModif
2210 } else switch (mod.intern_pool.indexToKey(func_val.ip_index)) {2224 } else switch (mod.intern_pool.indexToKey(func_val.ip_index)) {
2211 .ptr => |ptr| if (ptr.byte_offset == 0) switch (ptr.base_addr) {2225 .ptr => |ptr| if (ptr.byte_offset == 0) switch (ptr.base_addr) {
2212 .decl => |decl| {2226 .decl => |decl| {
2213 _ = try func.bin_file.getOrCreateAtomForDecl(decl);2227 _ = try func.bin_file.getOrCreateAtomForDecl(pt, decl);
2214 break :blk decl;2228 break :blk decl;
2215 },2229 },
2216 else => {},2230 else => {},
...@@ -2230,7 +2244,7 @@ fn airCall(func: *CodeGen, inst: Air.Inst.Index, modifier: std.builtin.CallModif...@@ -2230,7 +2244,7 @@ fn airCall(func: *CodeGen, inst: Air.Inst.Index, modifier: std.builtin.CallModif
2230 const arg_val = try func.resolveInst(arg);2244 const arg_val = try func.resolveInst(arg);
22312245
2232 const arg_ty = func.typeOf(arg);2246 const arg_ty = func.typeOf(arg);
2233 if (!arg_ty.hasRuntimeBitsIgnoreComptime(mod)) continue;2247 if (!arg_ty.hasRuntimeBitsIgnoreComptime(pt)) continue;
22342248
2235 try func.lowerArg(mod.typeToFunc(fn_ty).?.cc, arg_ty, arg_val);2249 try func.lowerArg(mod.typeToFunc(fn_ty).?.cc, arg_ty, arg_val);
2236 }2250 }
...@@ -2245,7 +2259,7 @@ fn airCall(func: *CodeGen, inst: Air.Inst.Index, modifier: std.builtin.CallModif...@@ -2245,7 +2259,7 @@ fn airCall(func: *CodeGen, inst: Air.Inst.Index, modifier: std.builtin.CallModif
2245 const operand = try func.resolveInst(pl_op.operand);2259 const operand = try func.resolveInst(pl_op.operand);
2246 try func.emitWValue(operand);2260 try func.emitWValue(operand);
22472261
2248 var fn_type = try genFunctype(func.gpa, fn_info.cc, fn_info.param_types.get(ip), Type.fromInterned(fn_info.return_type), mod);2262 var fn_type = try genFunctype(func.gpa, fn_info.cc, fn_info.param_types.get(ip), Type.fromInterned(fn_info.return_type), pt);
2249 defer fn_type.deinit(func.gpa);2263 defer fn_type.deinit(func.gpa);
22502264
2251 const fn_type_index = try func.bin_file.zigObjectPtr().?.putOrGetFuncType(func.gpa, fn_type);2265 const fn_type_index = try func.bin_file.zigObjectPtr().?.putOrGetFuncType(func.gpa, fn_type);
...@@ -2253,7 +2267,7 @@ fn airCall(func: *CodeGen, inst: Air.Inst.Index, modifier: std.builtin.CallModif...@@ -2253,7 +2267,7 @@ fn airCall(func: *CodeGen, inst: Air.Inst.Index, modifier: std.builtin.CallModif
2253 }2267 }
22542268
2255 const result_value = result_value: {2269 const result_value = result_value: {
2256 if (!ret_ty.hasRuntimeBitsIgnoreComptime(mod) and !ret_ty.isError(mod)) {2270 if (!ret_ty.hasRuntimeBitsIgnoreComptime(pt) and !ret_ty.isError(mod)) {
2257 break :result_value WValue{ .none = {} };2271 break :result_value WValue{ .none = {} };
2258 } else if (ret_ty.isNoReturn(mod)) {2272 } else if (ret_ty.isNoReturn(mod)) {
2259 try func.addTag(.@"unreachable");2273 try func.addTag(.@"unreachable");
...@@ -2264,7 +2278,7 @@ fn airCall(func: *CodeGen, inst: Air.Inst.Index, modifier: std.builtin.CallModif...@@ -2264,7 +2278,7 @@ fn airCall(func: *CodeGen, inst: Air.Inst.Index, modifier: std.builtin.CallModif
2264 } else if (mod.typeToFunc(fn_ty).?.cc == .C and ret_ty.zigTypeTag(mod) == .Struct or ret_ty.zigTypeTag(mod) == .Union) {2278 } else if (mod.typeToFunc(fn_ty).?.cc == .C and ret_ty.zigTypeTag(mod) == .Struct or ret_ty.zigTypeTag(mod) == .Union) {
2265 const result_local = try func.allocLocal(ret_ty);2279 const result_local = try func.allocLocal(ret_ty);
2266 try func.addLabel(.local_set, result_local.local.value);2280 try func.addLabel(.local_set, result_local.local.value);
2267 const scalar_type = abi.scalarType(ret_ty, mod);2281 const scalar_type = abi.scalarType(ret_ty, pt);
2268 const result = try func.allocStack(scalar_type);2282 const result = try func.allocStack(scalar_type);
2269 try func.store(result, result_local, scalar_type, 0);2283 try func.store(result, result_local, scalar_type, 0);
2270 break :result_value result;2284 break :result_value result;
...@@ -2287,7 +2301,8 @@ fn airAlloc(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -2287,7 +2301,8 @@ fn airAlloc(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
2287}2301}
22882302
2289fn airStore(func: *CodeGen, inst: Air.Inst.Index, safety: bool) InnerError!void {2303fn airStore(func: *CodeGen, inst: Air.Inst.Index, safety: bool) InnerError!void {
2290 const mod = func.bin_file.base.comp.module.?;2304 const pt = func.pt;
2305 const mod = pt.zcu;
2291 if (safety) {2306 if (safety) {
2292 // TODO if the value is undef, write 0xaa bytes to dest2307 // TODO if the value is undef, write 0xaa bytes to dest
2293 } else {2308 } else {
...@@ -2306,13 +2321,13 @@ fn airStore(func: *CodeGen, inst: Air.Inst.Index, safety: bool) InnerError!void...@@ -2306,13 +2321,13 @@ fn airStore(func: *CodeGen, inst: Air.Inst.Index, safety: bool) InnerError!void
2306 } else {2321 } else {
2307 // at this point we have a non-natural alignment, we must2322 // at this point we have a non-natural alignment, we must
2308 // load the value, and then shift+or the rhs into the result location.2323 // load the value, and then shift+or the rhs into the result location.
2309 const int_elem_ty = try mod.intType(.unsigned, ptr_info.packed_offset.host_size * 8);2324 const int_elem_ty = try pt.intType(.unsigned, ptr_info.packed_offset.host_size * 8);
23102325
2311 if (isByRef(int_elem_ty, mod)) {2326 if (isByRef(int_elem_ty, pt)) {
2312 return func.fail("TODO: airStore for pointers to bitfields with backing type larger than 64bits", .{});2327 return func.fail("TODO: airStore for pointers to bitfields with backing type larger than 64bits", .{});
2313 }2328 }
23142329
2315 var mask = @as(u64, @intCast((@as(u65, 1) << @as(u7, @intCast(ty.bitSize(mod)))) - 1));2330 var mask = @as(u64, @intCast((@as(u65, 1) << @as(u7, @intCast(ty.bitSize(pt)))) - 1));
2316 mask <<= @as(u6, @intCast(ptr_info.packed_offset.bit_offset));2331 mask <<= @as(u6, @intCast(ptr_info.packed_offset.bit_offset));
2317 mask ^= ~@as(u64, 0);2332 mask ^= ~@as(u64, 0);
2318 const shift_val = if (ptr_info.packed_offset.host_size <= 4)2333 const shift_val = if (ptr_info.packed_offset.host_size <= 4)
...@@ -2324,9 +2339,9 @@ fn airStore(func: *CodeGen, inst: Air.Inst.Index, safety: bool) InnerError!void...@@ -2324,9 +2339,9 @@ fn airStore(func: *CodeGen, inst: Air.Inst.Index, safety: bool) InnerError!void
2324 else2339 else
2325 WValue{ .imm64 = mask };2340 WValue{ .imm64 = mask };
2326 const wrap_mask_val = if (ptr_info.packed_offset.host_size <= 4)2341 const wrap_mask_val = if (ptr_info.packed_offset.host_size <= 4)
2327 WValue{ .imm32 = @truncate(~@as(u64, 0) >> @intCast(64 - ty.bitSize(mod))) }2342 WValue{ .imm32 = @truncate(~@as(u64, 0) >> @intCast(64 - ty.bitSize(pt))) }
2328 else2343 else
2329 WValue{ .imm64 = ~@as(u64, 0) >> @intCast(64 - ty.bitSize(mod)) };2344 WValue{ .imm64 = ~@as(u64, 0) >> @intCast(64 - ty.bitSize(pt)) };
23302345
2331 try func.emitWValue(lhs);2346 try func.emitWValue(lhs);
2332 const loaded = try func.load(lhs, int_elem_ty, 0);2347 const loaded = try func.load(lhs, int_elem_ty, 0);
...@@ -2346,12 +2361,13 @@ fn airStore(func: *CodeGen, inst: Air.Inst.Index, safety: bool) InnerError!void...@@ -2346,12 +2361,13 @@ fn airStore(func: *CodeGen, inst: Air.Inst.Index, safety: bool) InnerError!void
23462361
2347fn store(func: *CodeGen, lhs: WValue, rhs: WValue, ty: Type, offset: u32) InnerError!void {2362fn store(func: *CodeGen, lhs: WValue, rhs: WValue, ty: Type, offset: u32) InnerError!void {
2348 assert(!(lhs != .stack and rhs == .stack));2363 assert(!(lhs != .stack and rhs == .stack));
2349 const mod = func.bin_file.base.comp.module.?;2364 const pt = func.pt;
2350 const abi_size = ty.abiSize(mod);2365 const mod = pt.zcu;
2366 const abi_size = ty.abiSize(pt);
2351 switch (ty.zigTypeTag(mod)) {2367 switch (ty.zigTypeTag(mod)) {
2352 .ErrorUnion => {2368 .ErrorUnion => {
2353 const pl_ty = ty.errorUnionPayload(mod);2369 const pl_ty = ty.errorUnionPayload(mod);
2354 if (!pl_ty.hasRuntimeBitsIgnoreComptime(mod)) {2370 if (!pl_ty.hasRuntimeBitsIgnoreComptime(pt)) {
2355 return func.store(lhs, rhs, Type.anyerror, 0);2371 return func.store(lhs, rhs, Type.anyerror, 0);
2356 }2372 }
23572373
...@@ -2363,7 +2379,7 @@ fn store(func: *CodeGen, lhs: WValue, rhs: WValue, ty: Type, offset: u32) InnerE...@@ -2363,7 +2379,7 @@ fn store(func: *CodeGen, lhs: WValue, rhs: WValue, ty: Type, offset: u32) InnerE
2363 return func.store(lhs, rhs, Type.usize, 0);2379 return func.store(lhs, rhs, Type.usize, 0);
2364 }2380 }
2365 const pl_ty = ty.optionalChild(mod);2381 const pl_ty = ty.optionalChild(mod);
2366 if (!pl_ty.hasRuntimeBitsIgnoreComptime(mod)) {2382 if (!pl_ty.hasRuntimeBitsIgnoreComptime(pt)) {
2367 return func.store(lhs, rhs, Type.u8, 0);2383 return func.store(lhs, rhs, Type.u8, 0);
2368 }2384 }
2369 if (pl_ty.zigTypeTag(mod) == .ErrorSet) {2385 if (pl_ty.zigTypeTag(mod) == .ErrorSet) {
...@@ -2373,11 +2389,11 @@ fn store(func: *CodeGen, lhs: WValue, rhs: WValue, ty: Type, offset: u32) InnerE...@@ -2373,11 +2389,11 @@ fn store(func: *CodeGen, lhs: WValue, rhs: WValue, ty: Type, offset: u32) InnerE
2373 const len = @as(u32, @intCast(abi_size));2389 const len = @as(u32, @intCast(abi_size));
2374 return func.memcpy(lhs, rhs, .{ .imm32 = len });2390 return func.memcpy(lhs, rhs, .{ .imm32 = len });
2375 },2391 },
2376 .Struct, .Array, .Union => if (isByRef(ty, mod)) {2392 .Struct, .Array, .Union => if (isByRef(ty, pt)) {
2377 const len = @as(u32, @intCast(abi_size));2393 const len = @as(u32, @intCast(abi_size));
2378 return func.memcpy(lhs, rhs, .{ .imm32 = len });2394 return func.memcpy(lhs, rhs, .{ .imm32 = len });
2379 },2395 },
2380 .Vector => switch (determineSimdStoreStrategy(ty, mod)) {2396 .Vector => switch (determineSimdStoreStrategy(ty, pt)) {
2381 .unrolled => {2397 .unrolled => {
2382 const len: u32 = @intCast(abi_size);2398 const len: u32 = @intCast(abi_size);
2383 return func.memcpy(lhs, rhs, .{ .imm32 = len });2399 return func.memcpy(lhs, rhs, .{ .imm32 = len });
...@@ -2391,7 +2407,7 @@ fn store(func: *CodeGen, lhs: WValue, rhs: WValue, ty: Type, offset: u32) InnerE...@@ -2391,7 +2407,7 @@ fn store(func: *CodeGen, lhs: WValue, rhs: WValue, ty: Type, offset: u32) InnerE
2391 try func.mir_extra.appendSlice(func.gpa, &[_]u32{2407 try func.mir_extra.appendSlice(func.gpa, &[_]u32{
2392 std.wasm.simdOpcode(.v128_store),2408 std.wasm.simdOpcode(.v128_store),
2393 offset + lhs.offset(),2409 offset + lhs.offset(),
2394 @intCast(ty.abiAlignment(mod).toByteUnits() orelse 0),2410 @intCast(ty.abiAlignment(pt).toByteUnits() orelse 0),
2395 });2411 });
2396 return func.addInst(.{ .tag = .simd_prefix, .data = .{ .payload = extra_index } });2412 return func.addInst(.{ .tag = .simd_prefix, .data = .{ .payload = extra_index } });
2397 },2413 },
...@@ -2421,11 +2437,11 @@ fn store(func: *CodeGen, lhs: WValue, rhs: WValue, ty: Type, offset: u32) InnerE...@@ -2421,11 +2437,11 @@ fn store(func: *CodeGen, lhs: WValue, rhs: WValue, ty: Type, offset: u32) InnerE
2421 try func.store(.{ .stack = {} }, msb, Type.u64, 8 + lhs.offset());2437 try func.store(.{ .stack = {} }, msb, Type.u64, 8 + lhs.offset());
2422 return;2438 return;
2423 } else if (abi_size > 16) {2439 } else if (abi_size > 16) {
2424 try func.memcpy(lhs, rhs, .{ .imm32 = @as(u32, @intCast(ty.abiSize(mod))) });2440 try func.memcpy(lhs, rhs, .{ .imm32 = @as(u32, @intCast(ty.abiSize(pt))) });
2425 },2441 },
2426 else => if (abi_size > 8) {2442 else => if (abi_size > 8) {
2427 return func.fail("TODO: `store` for type `{}` with abisize `{d}`", .{2443 return func.fail("TODO: `store` for type `{}` with abisize `{d}`", .{
2428 ty.fmt(func.bin_file.base.comp.module.?),2444 ty.fmt(pt),
2429 abi_size,2445 abi_size,
2430 });2446 });
2431 },2447 },
...@@ -2435,7 +2451,7 @@ fn store(func: *CodeGen, lhs: WValue, rhs: WValue, ty: Type, offset: u32) InnerE...@@ -2435,7 +2451,7 @@ fn store(func: *CodeGen, lhs: WValue, rhs: WValue, ty: Type, offset: u32) InnerE
2435 // into lhs, so we calculate that and emit that instead2451 // into lhs, so we calculate that and emit that instead
2436 try func.lowerToStack(rhs);2452 try func.lowerToStack(rhs);
24372453
2438 const valtype = typeToValtype(ty, mod);2454 const valtype = typeToValtype(ty, pt);
2439 const opcode = buildOpcode(.{2455 const opcode = buildOpcode(.{
2440 .valtype1 = valtype,2456 .valtype1 = valtype,
2441 .width = @as(u8, @intCast(abi_size * 8)),2457 .width = @as(u8, @intCast(abi_size * 8)),
...@@ -2447,23 +2463,24 @@ fn store(func: *CodeGen, lhs: WValue, rhs: WValue, ty: Type, offset: u32) InnerE...@@ -2447,23 +2463,24 @@ fn store(func: *CodeGen, lhs: WValue, rhs: WValue, ty: Type, offset: u32) InnerE
2447 Mir.Inst.Tag.fromOpcode(opcode),2463 Mir.Inst.Tag.fromOpcode(opcode),
2448 .{2464 .{
2449 .offset = offset + lhs.offset(),2465 .offset = offset + lhs.offset(),
2450 .alignment = @intCast(ty.abiAlignment(mod).toByteUnits().?),2466 .alignment = @intCast(ty.abiAlignment(pt).toByteUnits().?),
2451 },2467 },
2452 );2468 );
2453}2469}
24542470
2455fn airLoad(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {2471fn airLoad(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
2456 const mod = func.bin_file.base.comp.module.?;2472 const pt = func.pt;
2473 const mod = pt.zcu;
2457 const ty_op = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;2474 const ty_op = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
2458 const operand = try func.resolveInst(ty_op.operand);2475 const operand = try func.resolveInst(ty_op.operand);
2459 const ty = ty_op.ty.toType();2476 const ty = ty_op.ty.toType();
2460 const ptr_ty = func.typeOf(ty_op.operand);2477 const ptr_ty = func.typeOf(ty_op.operand);
2461 const ptr_info = ptr_ty.ptrInfo(mod);2478 const ptr_info = ptr_ty.ptrInfo(mod);
24622479
2463 if (!ty.hasRuntimeBitsIgnoreComptime(mod)) return func.finishAir(inst, .none, &.{ty_op.operand});2480 if (!ty.hasRuntimeBitsIgnoreComptime(pt)) return func.finishAir(inst, .none, &.{ty_op.operand});
24642481
2465 const result = result: {2482 const result = result: {
2466 if (isByRef(ty, mod)) {2483 if (isByRef(ty, pt)) {
2467 const new_local = try func.allocStack(ty);2484 const new_local = try func.allocStack(ty);
2468 try func.store(new_local, operand, ty, 0);2485 try func.store(new_local, operand, ty, 0);
2469 break :result new_local;2486 break :result new_local;
...@@ -2476,7 +2493,7 @@ fn airLoad(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -2476,7 +2493,7 @@ fn airLoad(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
24762493
2477 // at this point we have a non-natural alignment, we must2494 // at this point we have a non-natural alignment, we must
2478 // shift the value to obtain the correct bit.2495 // shift the value to obtain the correct bit.
2479 const int_elem_ty = try mod.intType(.unsigned, ptr_info.packed_offset.host_size * 8);2496 const int_elem_ty = try pt.intType(.unsigned, ptr_info.packed_offset.host_size * 8);
2480 const shift_val = if (ptr_info.packed_offset.host_size <= 4)2497 const shift_val = if (ptr_info.packed_offset.host_size <= 4)
2481 WValue{ .imm32 = ptr_info.packed_offset.bit_offset }2498 WValue{ .imm32 = ptr_info.packed_offset.bit_offset }
2482 else if (ptr_info.packed_offset.host_size <= 8)2499 else if (ptr_info.packed_offset.host_size <= 8)
...@@ -2496,7 +2513,8 @@ fn airLoad(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -2496,7 +2513,8 @@ fn airLoad(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
2496/// Loads an operand from the linear memory section.2513/// Loads an operand from the linear memory section.
2497/// NOTE: Leaves the value on the stack.2514/// NOTE: Leaves the value on the stack.
2498fn load(func: *CodeGen, operand: WValue, ty: Type, offset: u32) InnerError!WValue {2515fn load(func: *CodeGen, operand: WValue, ty: Type, offset: u32) InnerError!WValue {
2499 const mod = func.bin_file.base.comp.module.?;2516 const pt = func.pt;
2517 const mod = pt.zcu;
2500 // load local's value from memory by its stack position2518 // load local's value from memory by its stack position
2501 try func.emitWValue(operand);2519 try func.emitWValue(operand);
25022520
...@@ -2507,15 +2525,15 @@ fn load(func: *CodeGen, operand: WValue, ty: Type, offset: u32) InnerError!WValu...@@ -2507,15 +2525,15 @@ fn load(func: *CodeGen, operand: WValue, ty: Type, offset: u32) InnerError!WValu
2507 try func.mir_extra.appendSlice(func.gpa, &[_]u32{2525 try func.mir_extra.appendSlice(func.gpa, &[_]u32{
2508 std.wasm.simdOpcode(.v128_load),2526 std.wasm.simdOpcode(.v128_load),
2509 offset + operand.offset(),2527 offset + operand.offset(),
2510 @intCast(ty.abiAlignment(mod).toByteUnits().?),2528 @intCast(ty.abiAlignment(pt).toByteUnits().?),
2511 });2529 });
2512 try func.addInst(.{ .tag = .simd_prefix, .data = .{ .payload = extra_index } });2530 try func.addInst(.{ .tag = .simd_prefix, .data = .{ .payload = extra_index } });
2513 return WValue{ .stack = {} };2531 return WValue{ .stack = {} };
2514 }2532 }
25152533
2516 const abi_size: u8 = @intCast(ty.abiSize(mod));2534 const abi_size: u8 = @intCast(ty.abiSize(pt));
2517 const opcode = buildOpcode(.{2535 const opcode = buildOpcode(.{
2518 .valtype1 = typeToValtype(ty, mod),2536 .valtype1 = typeToValtype(ty, pt),
2519 .width = abi_size * 8,2537 .width = abi_size * 8,
2520 .op = .load,2538 .op = .load,
2521 .signedness = if (ty.isSignedInt(mod)) .signed else .unsigned,2539 .signedness = if (ty.isSignedInt(mod)) .signed else .unsigned,
...@@ -2525,7 +2543,7 @@ fn load(func: *CodeGen, operand: WValue, ty: Type, offset: u32) InnerError!WValu...@@ -2525,7 +2543,7 @@ fn load(func: *CodeGen, operand: WValue, ty: Type, offset: u32) InnerError!WValu
2525 Mir.Inst.Tag.fromOpcode(opcode),2543 Mir.Inst.Tag.fromOpcode(opcode),
2526 .{2544 .{
2527 .offset = offset + operand.offset(),2545 .offset = offset + operand.offset(),
2528 .alignment = @intCast(ty.abiAlignment(mod).toByteUnits().?),2546 .alignment = @intCast(ty.abiAlignment(pt).toByteUnits().?),
2529 },2547 },
2530 );2548 );
25312549
...@@ -2533,13 +2551,14 @@ fn load(func: *CodeGen, operand: WValue, ty: Type, offset: u32) InnerError!WValu...@@ -2533,13 +2551,14 @@ fn load(func: *CodeGen, operand: WValue, ty: Type, offset: u32) InnerError!WValu
2533}2551}
25342552
2535fn airArg(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {2553fn airArg(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
2536 const mod = func.bin_file.base.comp.module.?;2554 const pt = func.pt;
2555 const mod = pt.zcu;
2537 const arg_index = func.arg_index;2556 const arg_index = func.arg_index;
2538 const arg = func.args[arg_index];2557 const arg = func.args[arg_index];
2539 const cc = mod.typeToFunc(func.decl.typeOf(mod)).?.cc;2558 const cc = mod.typeToFunc(func.decl.typeOf(mod)).?.cc;
2540 const arg_ty = func.typeOfIndex(inst);2559 const arg_ty = func.typeOfIndex(inst);
2541 if (cc == .C) {2560 if (cc == .C) {
2542 const arg_classes = abi.classifyType(arg_ty, mod);2561 const arg_classes = abi.classifyType(arg_ty, pt);
2543 for (arg_classes) |class| {2562 for (arg_classes) |class| {
2544 if (class != .none) {2563 if (class != .none) {
2545 func.arg_index += 1;2564 func.arg_index += 1;
...@@ -2552,7 +2571,7 @@ fn airArg(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -2552,7 +2571,7 @@ fn airArg(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
2552 if (arg_ty.zigTypeTag(mod) != .Int and arg_ty.zigTypeTag(mod) != .Float) {2571 if (arg_ty.zigTypeTag(mod) != .Int and arg_ty.zigTypeTag(mod) != .Float) {
2553 return func.fail(2572 return func.fail(
2554 "TODO: Implement C-ABI argument for type '{}'",2573 "TODO: Implement C-ABI argument for type '{}'",
2555 .{arg_ty.fmt(func.bin_file.base.comp.module.?)},2574 .{arg_ty.fmt(pt)},
2556 );2575 );
2557 }2576 }
2558 const result = try func.allocStack(arg_ty);2577 const result = try func.allocStack(arg_ty);
...@@ -2579,7 +2598,7 @@ fn airArg(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -2579,7 +2598,7 @@ fn airArg(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
2579}2598}
25802599
2581fn airBinOp(func: *CodeGen, inst: Air.Inst.Index, op: Op) InnerError!void {2600fn airBinOp(func: *CodeGen, inst: Air.Inst.Index, op: Op) InnerError!void {
2582 const mod = func.bin_file.base.comp.module.?;2601 const pt = func.pt;
2583 const bin_op = func.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;2602 const bin_op = func.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
2584 const lhs = try func.resolveInst(bin_op.lhs);2603 const lhs = try func.resolveInst(bin_op.lhs);
2585 const rhs = try func.resolveInst(bin_op.rhs);2604 const rhs = try func.resolveInst(bin_op.rhs);
...@@ -2593,10 +2612,10 @@ fn airBinOp(func: *CodeGen, inst: Air.Inst.Index, op: Op) InnerError!void {...@@ -2593,10 +2612,10 @@ fn airBinOp(func: *CodeGen, inst: Air.Inst.Index, op: Op) InnerError!void {
2593 // For big integers we can ignore this as we will call into compiler-rt which handles this.2612 // For big integers we can ignore this as we will call into compiler-rt which handles this.
2594 const result = switch (op) {2613 const result = switch (op) {
2595 .shr, .shl => res: {2614 .shr, .shl => res: {
2596 const lhs_wasm_bits = toWasmBits(@as(u16, @intCast(lhs_ty.bitSize(mod)))) orelse {2615 const lhs_wasm_bits = toWasmBits(@intCast(lhs_ty.bitSize(pt))) orelse {
2597 return func.fail("TODO: implement '{s}' for types larger than 128 bits", .{@tagName(op)});2616 return func.fail("TODO: implement '{s}' for types larger than 128 bits", .{@tagName(op)});
2598 };2617 };
2599 const rhs_wasm_bits = toWasmBits(@as(u16, @intCast(rhs_ty.bitSize(mod)))).?;2618 const rhs_wasm_bits = toWasmBits(@intCast(rhs_ty.bitSize(pt))).?;
2600 const new_rhs = if (lhs_wasm_bits != rhs_wasm_bits and lhs_wasm_bits != 128) blk: {2619 const new_rhs = if (lhs_wasm_bits != rhs_wasm_bits and lhs_wasm_bits != 128) blk: {
2601 const tmp = try func.intcast(rhs, rhs_ty, lhs_ty);2620 const tmp = try func.intcast(rhs, rhs_ty, lhs_ty);
2602 break :blk try tmp.toLocal(func, lhs_ty);2621 break :blk try tmp.toLocal(func, lhs_ty);
...@@ -2616,7 +2635,8 @@ fn airBinOp(func: *CodeGen, inst: Air.Inst.Index, op: Op) InnerError!void {...@@ -2616,7 +2635,8 @@ fn airBinOp(func: *CodeGen, inst: Air.Inst.Index, op: Op) InnerError!void {
2616/// Performs a binary operation on the given `WValue`'s2635/// Performs a binary operation on the given `WValue`'s
2617/// NOTE: THis leaves the value on top of the stack.2636/// NOTE: THis leaves the value on top of the stack.
2618fn binOp(func: *CodeGen, lhs: WValue, rhs: WValue, ty: Type, op: Op) InnerError!WValue {2637fn binOp(func: *CodeGen, lhs: WValue, rhs: WValue, ty: Type, op: Op) InnerError!WValue {
2619 const mod = func.bin_file.base.comp.module.?;2638 const pt = func.pt;
2639 const mod = pt.zcu;
2620 assert(!(lhs != .stack and rhs == .stack));2640 assert(!(lhs != .stack and rhs == .stack));
26212641
2622 if (ty.isAnyFloat()) {2642 if (ty.isAnyFloat()) {
...@@ -2624,20 +2644,20 @@ fn binOp(func: *CodeGen, lhs: WValue, rhs: WValue, ty: Type, op: Op) InnerError!...@@ -2624,20 +2644,20 @@ fn binOp(func: *CodeGen, lhs: WValue, rhs: WValue, ty: Type, op: Op) InnerError!
2624 return func.floatOp(float_op, ty, &.{ lhs, rhs });2644 return func.floatOp(float_op, ty, &.{ lhs, rhs });
2625 }2645 }
26262646
2627 if (isByRef(ty, mod)) {2647 if (isByRef(ty, pt)) {
2628 if (ty.zigTypeTag(mod) == .Int) {2648 if (ty.zigTypeTag(mod) == .Int) {
2629 return func.binOpBigInt(lhs, rhs, ty, op);2649 return func.binOpBigInt(lhs, rhs, ty, op);
2630 } else {2650 } else {
2631 return func.fail(2651 return func.fail(
2632 "TODO: Implement binary operation for type: {}",2652 "TODO: Implement binary operation for type: {}",
2633 .{ty.fmt(func.bin_file.base.comp.module.?)},2653 .{ty.fmt(pt)},
2634 );2654 );
2635 }2655 }
2636 }2656 }
26372657
2638 const opcode: wasm.Opcode = buildOpcode(.{2658 const opcode: wasm.Opcode = buildOpcode(.{
2639 .op = op,2659 .op = op,
2640 .valtype1 = typeToValtype(ty, mod),2660 .valtype1 = typeToValtype(ty, pt),
2641 .signedness = if (ty.isSignedInt(mod)) .signed else .unsigned,2661 .signedness = if (ty.isSignedInt(mod)) .signed else .unsigned,
2642 });2662 });
2643 try func.emitWValue(lhs);2663 try func.emitWValue(lhs);
...@@ -2649,7 +2669,8 @@ fn binOp(func: *CodeGen, lhs: WValue, rhs: WValue, ty: Type, op: Op) InnerError!...@@ -2649,7 +2669,8 @@ fn binOp(func: *CodeGen, lhs: WValue, rhs: WValue, ty: Type, op: Op) InnerError!
2649}2669}
26502670
2651fn binOpBigInt(func: *CodeGen, lhs: WValue, rhs: WValue, ty: Type, op: Op) InnerError!WValue {2671fn binOpBigInt(func: *CodeGen, lhs: WValue, rhs: WValue, ty: Type, op: Op) InnerError!WValue {
2652 const mod = func.bin_file.base.comp.module.?;2672 const pt = func.pt;
2673 const mod = pt.zcu;
2653 const int_info = ty.intInfo(mod);2674 const int_info = ty.intInfo(mod);
2654 if (int_info.bits > 128) {2675 if (int_info.bits > 128) {
2655 return func.fail("TODO: Implement binary operation for big integers larger than 128 bits", .{});2676 return func.fail("TODO: Implement binary operation for big integers larger than 128 bits", .{});
...@@ -2785,7 +2806,8 @@ const FloatOp = enum {...@@ -2785,7 +2806,8 @@ const FloatOp = enum {
2785};2806};
27862807
2787fn airAbs(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {2808fn airAbs(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
2788 const mod = func.bin_file.base.comp.module.?;2809 const pt = func.pt;
2810 const mod = pt.zcu;
2789 const ty_op = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;2811 const ty_op = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
2790 const operand = try func.resolveInst(ty_op.operand);2812 const operand = try func.resolveInst(ty_op.operand);
2791 const ty = func.typeOf(ty_op.operand);2813 const ty = func.typeOf(ty_op.operand);
...@@ -2793,7 +2815,7 @@ fn airAbs(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -2793,7 +2815,7 @@ fn airAbs(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
27932815
2794 switch (scalar_ty.zigTypeTag(mod)) {2816 switch (scalar_ty.zigTypeTag(mod)) {
2795 .Int => if (ty.zigTypeTag(mod) == .Vector) {2817 .Int => if (ty.zigTypeTag(mod) == .Vector) {
2796 return func.fail("TODO implement airAbs for {}", .{ty.fmt(mod)});2818 return func.fail("TODO implement airAbs for {}", .{ty.fmt(pt)});
2797 } else {2819 } else {
2798 const int_bits = ty.intInfo(mod).bits;2820 const int_bits = ty.intInfo(mod).bits;
2799 const wasm_bits = toWasmBits(int_bits) orelse {2821 const wasm_bits = toWasmBits(int_bits) orelse {
...@@ -2877,7 +2899,8 @@ fn airUnaryFloatOp(func: *CodeGen, inst: Air.Inst.Index, op: FloatOp) InnerError...@@ -2877,7 +2899,8 @@ fn airUnaryFloatOp(func: *CodeGen, inst: Air.Inst.Index, op: FloatOp) InnerError
2877}2899}
28782900
2879fn floatOp(func: *CodeGen, float_op: FloatOp, ty: Type, args: []const WValue) InnerError!WValue {2901fn floatOp(func: *CodeGen, float_op: FloatOp, ty: Type, args: []const WValue) InnerError!WValue {
2880 const mod = func.bin_file.base.comp.module.?;2902 const pt = func.pt;
2903 const mod = pt.zcu;
2881 if (ty.zigTypeTag(mod) == .Vector) {2904 if (ty.zigTypeTag(mod) == .Vector) {
2882 return func.fail("TODO: Implement floatOps for vectors", .{});2905 return func.fail("TODO: Implement floatOps for vectors", .{});
2883 }2906 }
...@@ -2893,7 +2916,7 @@ fn floatOp(func: *CodeGen, float_op: FloatOp, ty: Type, args: []const WValue) In...@@ -2893,7 +2916,7 @@ fn floatOp(func: *CodeGen, float_op: FloatOp, ty: Type, args: []const WValue) In
2893 for (args) |operand| {2916 for (args) |operand| {
2894 try func.emitWValue(operand);2917 try func.emitWValue(operand);
2895 }2918 }
2896 const opcode = buildOpcode(.{ .op = op, .valtype1 = typeToValtype(ty, mod) });2919 const opcode = buildOpcode(.{ .op = op, .valtype1 = typeToValtype(ty, pt) });
2897 try func.addTag(Mir.Inst.Tag.fromOpcode(opcode));2920 try func.addTag(Mir.Inst.Tag.fromOpcode(opcode));
2898 return .stack;2921 return .stack;
2899 }2922 }
...@@ -2983,7 +3006,8 @@ fn floatNeg(func: *CodeGen, ty: Type, arg: WValue) InnerError!WValue {...@@ -2983,7 +3006,8 @@ fn floatNeg(func: *CodeGen, ty: Type, arg: WValue) InnerError!WValue {
2983}3006}
29843007
2985fn airWrapBinOp(func: *CodeGen, inst: Air.Inst.Index, op: Op) InnerError!void {3008fn airWrapBinOp(func: *CodeGen, inst: Air.Inst.Index, op: Op) InnerError!void {
2986 const mod = func.bin_file.base.comp.module.?;3009 const pt = func.pt;
3010 const mod = pt.zcu;
2987 const bin_op = func.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;3011 const bin_op = func.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
29883012
2989 const lhs = try func.resolveInst(bin_op.lhs);3013 const lhs = try func.resolveInst(bin_op.lhs);
...@@ -3002,10 +3026,10 @@ fn airWrapBinOp(func: *CodeGen, inst: Air.Inst.Index, op: Op) InnerError!void {...@@ -3002,10 +3026,10 @@ fn airWrapBinOp(func: *CodeGen, inst: Air.Inst.Index, op: Op) InnerError!void {
3002 // For big integers we can ignore this as we will call into compiler-rt which handles this.3026 // For big integers we can ignore this as we will call into compiler-rt which handles this.
3003 const result = switch (op) {3027 const result = switch (op) {
3004 .shr, .shl => res: {3028 .shr, .shl => res: {
3005 const lhs_wasm_bits = toWasmBits(@as(u16, @intCast(lhs_ty.bitSize(mod)))) orelse {3029 const lhs_wasm_bits = toWasmBits(@intCast(lhs_ty.bitSize(pt))) orelse {
3006 return func.fail("TODO: implement '{s}' for types larger than 128 bits", .{@tagName(op)});3030 return func.fail("TODO: implement '{s}' for types larger than 128 bits", .{@tagName(op)});
3007 };3031 };
3008 const rhs_wasm_bits = toWasmBits(@as(u16, @intCast(rhs_ty.bitSize(mod)))).?;3032 const rhs_wasm_bits = toWasmBits(@intCast(rhs_ty.bitSize(pt))).?;
3009 const new_rhs = if (lhs_wasm_bits != rhs_wasm_bits and lhs_wasm_bits != 128) blk: {3033 const new_rhs = if (lhs_wasm_bits != rhs_wasm_bits and lhs_wasm_bits != 128) blk: {
3010 const tmp = try func.intcast(rhs, rhs_ty, lhs_ty);3034 const tmp = try func.intcast(rhs, rhs_ty, lhs_ty);
3011 break :blk try tmp.toLocal(func, lhs_ty);3035 break :blk try tmp.toLocal(func, lhs_ty);
...@@ -3034,9 +3058,10 @@ fn wrapBinOp(func: *CodeGen, lhs: WValue, rhs: WValue, ty: Type, op: Op) InnerEr...@@ -3034,9 +3058,10 @@ fn wrapBinOp(func: *CodeGen, lhs: WValue, rhs: WValue, ty: Type, op: Op) InnerEr
3034/// Asserts `Type` is <= 128 bits.3058/// Asserts `Type` is <= 128 bits.
3035/// NOTE: When the Type is <= 64 bits, leaves the value on top of the stack, if wrapping was needed.3059/// NOTE: When the Type is <= 64 bits, leaves the value on top of the stack, if wrapping was needed.
3036fn wrapOperand(func: *CodeGen, operand: WValue, ty: Type) InnerError!WValue {3060fn wrapOperand(func: *CodeGen, operand: WValue, ty: Type) InnerError!WValue {
3037 const mod = func.bin_file.base.comp.module.?;3061 const pt = func.pt;
3038 assert(ty.abiSize(mod) <= 16);3062 const mod = pt.zcu;
3039 const int_bits = @as(u16, @intCast(ty.bitSize(mod))); // TODO use ty.intInfo(mod).bits3063 assert(ty.abiSize(pt) <= 16);
3064 const int_bits: u16 = @intCast(ty.bitSize(pt)); // TODO use ty.intInfo(mod).bits
3040 const wasm_bits = toWasmBits(int_bits) orelse {3065 const wasm_bits = toWasmBits(int_bits) orelse {
3041 return func.fail("TODO: Implement wrapOperand for bitsize '{d}'", .{int_bits});3066 return func.fail("TODO: Implement wrapOperand for bitsize '{d}'", .{int_bits});
3042 };3067 };
...@@ -3098,13 +3123,14 @@ fn wrapOperand(func: *CodeGen, operand: WValue, ty: Type) InnerError!WValue {...@@ -3098,13 +3123,14 @@ fn wrapOperand(func: *CodeGen, operand: WValue, ty: Type) InnerError!WValue {
3098}3123}
30993124
3100fn lowerPtr(func: *CodeGen, ptr_val: InternPool.Index, prev_offset: u64) InnerError!WValue {3125fn lowerPtr(func: *CodeGen, ptr_val: InternPool.Index, prev_offset: u64) InnerError!WValue {
3101 const zcu = func.bin_file.base.comp.module.?;3126 const pt = func.pt;
3127 const zcu = pt.zcu;
3102 const ptr = zcu.intern_pool.indexToKey(ptr_val).ptr;3128 const ptr = zcu.intern_pool.indexToKey(ptr_val).ptr;
3103 const offset: u64 = prev_offset + ptr.byte_offset;3129 const offset: u64 = prev_offset + ptr.byte_offset;
3104 return switch (ptr.base_addr) {3130 return switch (ptr.base_addr) {
3105 .decl => |decl| return func.lowerDeclRefValue(decl, @intCast(offset)),3131 .decl => |decl| return func.lowerDeclRefValue(decl, @intCast(offset)),
3106 .anon_decl => |ad| return func.lowerAnonDeclRef(ad, @intCast(offset)),3132 .anon_decl => |ad| return func.lowerAnonDeclRef(ad, @intCast(offset)),
3107 .int => return func.lowerConstant(try zcu.intValue(Type.usize, offset), Type.usize),3133 .int => return func.lowerConstant(try pt.intValue(Type.usize, offset), Type.usize),
3108 .eu_payload => return func.fail("Wasm TODO: lower error union payload pointer", .{}),3134 .eu_payload => return func.fail("Wasm TODO: lower error union payload pointer", .{}),
3109 .opt_payload => |opt_ptr| return func.lowerPtr(opt_ptr, offset),3135 .opt_payload => |opt_ptr| return func.lowerPtr(opt_ptr, offset),
3110 .field => |field| {3136 .field => |field| {
...@@ -3120,13 +3146,13 @@ fn lowerPtr(func: *CodeGen, ptr_val: InternPool.Index, prev_offset: u64) InnerEr...@@ -3120,13 +3146,13 @@ fn lowerPtr(func: *CodeGen, ptr_val: InternPool.Index, prev_offset: u64) InnerEr
3120 };3146 };
3121 },3147 },
3122 .Struct => switch (base_ty.containerLayout(zcu)) {3148 .Struct => switch (base_ty.containerLayout(zcu)) {
3123 .auto => base_ty.structFieldOffset(@intCast(field.index), zcu),3149 .auto => base_ty.structFieldOffset(@intCast(field.index), pt),
3124 .@"extern", .@"packed" => unreachable,3150 .@"extern", .@"packed" => unreachable,
3125 },3151 },
3126 .Union => switch (base_ty.containerLayout(zcu)) {3152 .Union => switch (base_ty.containerLayout(zcu)) {
3127 .auto => off: {3153 .auto => off: {
3128 // Keep in sync with the `un` case of `generateSymbol`.3154 // Keep in sync with the `un` case of `generateSymbol`.
3129 const layout = base_ty.unionGetLayout(zcu);3155 const layout = base_ty.unionGetLayout(pt);
3130 if (layout.payload_size == 0) break :off 0;3156 if (layout.payload_size == 0) break :off 0;
3131 if (layout.tag_size == 0) break :off 0;3157 if (layout.tag_size == 0) break :off 0;
3132 if (layout.tag_align.compare(.gte, layout.payload_align)) {3158 if (layout.tag_align.compare(.gte, layout.payload_align)) {
...@@ -3152,17 +3178,18 @@ fn lowerAnonDeclRef(...@@ -3152,17 +3178,18 @@ fn lowerAnonDeclRef(
3152 anon_decl: InternPool.Key.Ptr.BaseAddr.AnonDecl,3178 anon_decl: InternPool.Key.Ptr.BaseAddr.AnonDecl,
3153 offset: u32,3179 offset: u32,
3154) InnerError!WValue {3180) InnerError!WValue {
3155 const mod = func.bin_file.base.comp.module.?;3181 const pt = func.pt;
3182 const mod = pt.zcu;
3156 const decl_val = anon_decl.val;3183 const decl_val = anon_decl.val;
3157 const ty = Type.fromInterned(mod.intern_pool.typeOf(decl_val));3184 const ty = Type.fromInterned(mod.intern_pool.typeOf(decl_val));
31583185
3159 const is_fn_body = ty.zigTypeTag(mod) == .Fn;3186 const is_fn_body = ty.zigTypeTag(mod) == .Fn;
3160 if (!is_fn_body and !ty.hasRuntimeBitsIgnoreComptime(mod)) {3187 if (!is_fn_body and !ty.hasRuntimeBitsIgnoreComptime(pt)) {
3161 return WValue{ .imm32 = 0xaaaaaaaa };3188 return WValue{ .imm32 = 0xaaaaaaaa };
3162 }3189 }
31633190
3164 const decl_align = mod.intern_pool.indexToKey(anon_decl.orig_ty).ptr_type.flags.alignment;3191 const decl_align = mod.intern_pool.indexToKey(anon_decl.orig_ty).ptr_type.flags.alignment;
3165 const res = try func.bin_file.lowerAnonDecl(decl_val, decl_align, func.decl.navSrcLoc(mod));3192 const res = try func.bin_file.lowerAnonDecl(pt, decl_val, decl_align, func.decl.navSrcLoc(mod));
3166 switch (res) {3193 switch (res) {
3167 .ok => {},3194 .ok => {},
3168 .fail => |em| {3195 .fail => |em| {
...@@ -3180,7 +3207,8 @@ fn lowerAnonDeclRef(...@@ -3180,7 +3207,8 @@ fn lowerAnonDeclRef(
3180}3207}
31813208
3182fn lowerDeclRefValue(func: *CodeGen, decl_index: InternPool.DeclIndex, offset: u32) InnerError!WValue {3209fn lowerDeclRefValue(func: *CodeGen, decl_index: InternPool.DeclIndex, offset: u32) InnerError!WValue {
3183 const mod = func.bin_file.base.comp.module.?;3210 const pt = func.pt;
3211 const mod = pt.zcu;
31843212
3185 const decl = mod.declPtr(decl_index);3213 const decl = mod.declPtr(decl_index);
3186 // check if decl is an alias to a function, in which case we3214 // check if decl is an alias to a function, in which case we
...@@ -3195,11 +3223,11 @@ fn lowerDeclRefValue(func: *CodeGen, decl_index: InternPool.DeclIndex, offset: u...@@ -3195,11 +3223,11 @@ fn lowerDeclRefValue(func: *CodeGen, decl_index: InternPool.DeclIndex, offset: u
3195 }3223 }
3196 }3224 }
3197 const decl_ty = decl.typeOf(mod);3225 const decl_ty = decl.typeOf(mod);
3198 if (decl_ty.zigTypeTag(mod) != .Fn and !decl_ty.hasRuntimeBitsIgnoreComptime(mod)) {3226 if (decl_ty.zigTypeTag(mod) != .Fn and !decl_ty.hasRuntimeBitsIgnoreComptime(pt)) {
3199 return WValue{ .imm32 = 0xaaaaaaaa };3227 return WValue{ .imm32 = 0xaaaaaaaa };
3200 }3228 }
32013229
3202 const atom_index = try func.bin_file.getOrCreateAtomForDecl(decl_index);3230 const atom_index = try func.bin_file.getOrCreateAtomForDecl(pt, decl_index);
3203 const atom = func.bin_file.getAtom(atom_index);3231 const atom = func.bin_file.getAtom(atom_index);
32043232
3205 const target_sym_index = @intFromEnum(atom.sym_index);3233 const target_sym_index = @intFromEnum(atom.sym_index);
...@@ -3212,8 +3240,9 @@ fn lowerDeclRefValue(func: *CodeGen, decl_index: InternPool.DeclIndex, offset: u...@@ -3212,8 +3240,9 @@ fn lowerDeclRefValue(func: *CodeGen, decl_index: InternPool.DeclIndex, offset: u
32123240
3213/// Asserts that `isByRef` returns `false` for `ty`.3241/// Asserts that `isByRef` returns `false` for `ty`.
3214fn lowerConstant(func: *CodeGen, val: Value, ty: Type) InnerError!WValue {3242fn lowerConstant(func: *CodeGen, val: Value, ty: Type) InnerError!WValue {
3215 const mod = func.bin_file.base.comp.module.?;3243 const pt = func.pt;
3216 assert(!isByRef(ty, mod));3244 const mod = pt.zcu;
3245 assert(!isByRef(ty, pt));
3217 const ip = &mod.intern_pool;3246 const ip = &mod.intern_pool;
3218 if (val.isUndefDeep(mod)) return func.emitUndefined(ty);3247 if (val.isUndefDeep(mod)) return func.emitUndefined(ty);
32193248
...@@ -3261,13 +3290,13 @@ fn lowerConstant(func: *CodeGen, val: Value, ty: Type) InnerError!WValue {...@@ -3261,13 +3290,13 @@ fn lowerConstant(func: *CodeGen, val: Value, ty: Type) InnerError!WValue {
3261 const int_info = ty.intInfo(mod);3290 const int_info = ty.intInfo(mod);
3262 switch (int_info.signedness) {3291 switch (int_info.signedness) {
3263 .signed => switch (int_info.bits) {3292 .signed => switch (int_info.bits) {
3264 0...32 => return WValue{ .imm32 = @bitCast(@as(i32, @intCast(val.toSignedInt(mod)))) },3293 0...32 => return WValue{ .imm32 = @bitCast(@as(i32, @intCast(val.toSignedInt(pt)))) },
3265 33...64 => return WValue{ .imm64 = @bitCast(val.toSignedInt(mod)) },3294 33...64 => return WValue{ .imm64 = @bitCast(val.toSignedInt(pt)) },
3266 else => unreachable,3295 else => unreachable,
3267 },3296 },
3268 .unsigned => switch (int_info.bits) {3297 .unsigned => switch (int_info.bits) {
3269 0...32 => return WValue{ .imm32 = @intCast(val.toUnsignedInt(mod)) },3298 0...32 => return WValue{ .imm32 = @intCast(val.toUnsignedInt(pt)) },
3270 33...64 => return WValue{ .imm64 = val.toUnsignedInt(mod) },3299 33...64 => return WValue{ .imm64 = val.toUnsignedInt(pt) },
3271 else => unreachable,3300 else => unreachable,
3272 },3301 },
3273 }3302 }
...@@ -3277,22 +3306,22 @@ fn lowerConstant(func: *CodeGen, val: Value, ty: Type) InnerError!WValue {...@@ -3277,22 +3306,22 @@ fn lowerConstant(func: *CodeGen, val: Value, ty: Type) InnerError!WValue {
3277 return WValue{ .imm32 = int };3306 return WValue{ .imm32 = int };
3278 },3307 },
3279 .error_union => |error_union| {3308 .error_union => |error_union| {
3280 const err_int_ty = try mod.errorIntType();3309 const err_int_ty = try pt.errorIntType();
3281 const err_ty, const err_val = switch (error_union.val) {3310 const err_ty, const err_val = switch (error_union.val) {
3282 .err_name => |err_name| .{3311 .err_name => |err_name| .{
3283 ty.errorUnionSet(mod),3312 ty.errorUnionSet(mod),
3284 Value.fromInterned((try mod.intern(.{ .err = .{3313 Value.fromInterned(try pt.intern(.{ .err = .{
3285 .ty = ty.errorUnionSet(mod).toIntern(),3314 .ty = ty.errorUnionSet(mod).toIntern(),
3286 .name = err_name,3315 .name = err_name,
3287 } }))),3316 } })),
3288 },3317 },
3289 .payload => .{3318 .payload => .{
3290 err_int_ty,3319 err_int_ty,
3291 try mod.intValue(err_int_ty, 0),3320 try pt.intValue(err_int_ty, 0),
3292 },3321 },
3293 };3322 };
3294 const payload_type = ty.errorUnionPayload(mod);3323 const payload_type = ty.errorUnionPayload(mod);
3295 if (!payload_type.hasRuntimeBitsIgnoreComptime(mod)) {3324 if (!payload_type.hasRuntimeBitsIgnoreComptime(pt)) {
3296 // We use the error type directly as the type.3325 // We use the error type directly as the type.
3297 return func.lowerConstant(err_val, err_ty);3326 return func.lowerConstant(err_val, err_ty);
3298 }3327 }
...@@ -3318,7 +3347,7 @@ fn lowerConstant(func: *CodeGen, val: Value, ty: Type) InnerError!WValue {...@@ -3318,7 +3347,7 @@ fn lowerConstant(func: *CodeGen, val: Value, ty: Type) InnerError!WValue {
3318 .field => |base_index| ptr = ip.indexToKey(base_index.base).ptr,3347 .field => |base_index| ptr = ip.indexToKey(base_index.base).ptr,
3319 .arr_elem, .comptime_field, .comptime_alloc => unreachable,3348 .arr_elem, .comptime_field, .comptime_alloc => unreachable,
3320 };3349 };
3321 return .{ .memory = try func.bin_file.lowerUnnamedConst(val, owner_decl) };3350 return .{ .memory = try func.bin_file.lowerUnnamedConst(pt, val, owner_decl) };
3322 },3351 },
3323 .ptr => return func.lowerPtr(val.toIntern(), 0),3352 .ptr => return func.lowerPtr(val.toIntern(), 0),
3324 .opt => if (ty.optionalReprIsPayload(mod)) {3353 .opt => if (ty.optionalReprIsPayload(mod)) {
...@@ -3332,11 +3361,11 @@ fn lowerConstant(func: *CodeGen, val: Value, ty: Type) InnerError!WValue {...@@ -3332,11 +3361,11 @@ fn lowerConstant(func: *CodeGen, val: Value, ty: Type) InnerError!WValue {
3332 return WValue{ .imm32 = @intFromBool(!val.isNull(mod)) };3361 return WValue{ .imm32 = @intFromBool(!val.isNull(mod)) };
3333 },3362 },
3334 .aggregate => switch (ip.indexToKey(ty.ip_index)) {3363 .aggregate => switch (ip.indexToKey(ty.ip_index)) {
3335 .array_type => return func.fail("Wasm TODO: LowerConstant for {}", .{ty.fmt(mod)}),3364 .array_type => return func.fail("Wasm TODO: LowerConstant for {}", .{ty.fmt(pt)}),
3336 .vector_type => {3365 .vector_type => {
3337 assert(determineSimdStoreStrategy(ty, mod) == .direct);3366 assert(determineSimdStoreStrategy(ty, pt) == .direct);
3338 var buf: [16]u8 = undefined;3367 var buf: [16]u8 = undefined;
3339 val.writeToMemory(ty, mod, &buf) catch unreachable;3368 val.writeToMemory(ty, pt, &buf) catch unreachable;
3340 return func.storeSimdImmd(buf);3369 return func.storeSimdImmd(buf);
3341 },3370 },
3342 .struct_type => {3371 .struct_type => {
...@@ -3345,9 +3374,9 @@ fn lowerConstant(func: *CodeGen, val: Value, ty: Type) InnerError!WValue {...@@ -3345,9 +3374,9 @@ fn lowerConstant(func: *CodeGen, val: Value, ty: Type) InnerError!WValue {
3345 // are by-ref types.3374 // are by-ref types.
3346 assert(struct_type.layout == .@"packed");3375 assert(struct_type.layout == .@"packed");
3347 var buf: [8]u8 = .{0} ** 8; // zero the buffer so we do not read 0xaa as integer3376 var buf: [8]u8 = .{0} ** 8; // zero the buffer so we do not read 0xaa as integer
3348 val.writeToPackedMemory(ty, mod, &buf, 0) catch unreachable;3377 val.writeToPackedMemory(ty, pt, &buf, 0) catch unreachable;
3349 const backing_int_ty = Type.fromInterned(struct_type.backingIntType(ip).*);3378 const backing_int_ty = Type.fromInterned(struct_type.backingIntType(ip).*);
3350 const int_val = try mod.intValue(3379 const int_val = try pt.intValue(
3351 backing_int_ty,3380 backing_int_ty,
3352 mem.readInt(u64, &buf, .little),3381 mem.readInt(u64, &buf, .little),
3353 );3382 );
...@@ -3358,7 +3387,7 @@ fn lowerConstant(func: *CodeGen, val: Value, ty: Type) InnerError!WValue {...@@ -3358,7 +3387,7 @@ fn lowerConstant(func: *CodeGen, val: Value, ty: Type) InnerError!WValue {
3358 .un => |un| {3387 .un => |un| {
3359 // in this case we have a packed union which will not be passed by reference.3388 // in this case we have a packed union which will not be passed by reference.
3360 const constant_ty = if (un.tag == .none)3389 const constant_ty = if (un.tag == .none)
3361 try ty.unionBackingType(mod)3390 try ty.unionBackingType(pt)
3362 else field_ty: {3391 else field_ty: {
3363 const union_obj = mod.typeToUnion(ty).?;3392 const union_obj = mod.typeToUnion(ty).?;
3364 const field_index = mod.unionTagFieldIndex(union_obj, Value.fromInterned(un.tag)).?;3393 const field_index = mod.unionTagFieldIndex(union_obj, Value.fromInterned(un.tag)).?;
...@@ -3379,7 +3408,8 @@ fn storeSimdImmd(func: *CodeGen, value: [16]u8) !WValue {...@@ -3379,7 +3408,8 @@ fn storeSimdImmd(func: *CodeGen, value: [16]u8) !WValue {
3379}3408}
33803409
3381fn emitUndefined(func: *CodeGen, ty: Type) InnerError!WValue {3410fn emitUndefined(func: *CodeGen, ty: Type) InnerError!WValue {
3382 const mod = func.bin_file.base.comp.module.?;3411 const pt = func.pt;
3412 const mod = pt.zcu;
3383 const ip = &mod.intern_pool;3413 const ip = &mod.intern_pool;
3384 switch (ty.zigTypeTag(mod)) {3414 switch (ty.zigTypeTag(mod)) {
3385 .Bool, .ErrorSet => return WValue{ .imm32 = 0xaaaaaaaa },3415 .Bool, .ErrorSet => return WValue{ .imm32 = 0xaaaaaaaa },
...@@ -3421,15 +3451,16 @@ fn emitUndefined(func: *CodeGen, ty: Type) InnerError!WValue {...@@ -3421,15 +3451,16 @@ fn emitUndefined(func: *CodeGen, ty: Type) InnerError!WValue {
3421/// It's illegal to provide a value with a type that cannot be represented3451/// It's illegal to provide a value with a type that cannot be represented
3422/// as an integer value.3452/// as an integer value.
3423fn valueAsI32(func: *const CodeGen, val: Value, ty: Type) i32 {3453fn valueAsI32(func: *const CodeGen, val: Value, ty: Type) i32 {
3424 const mod = func.bin_file.base.comp.module.?;3454 const pt = func.pt;
3455 const mod = pt.zcu;
34253456
3426 switch (val.ip_index) {3457 switch (val.ip_index) {
3427 .none => {},3458 .none => {},
3428 .bool_true => return 1,3459 .bool_true => return 1,
3429 .bool_false => return 0,3460 .bool_false => return 0,
3430 else => return switch (mod.intern_pool.indexToKey(val.ip_index)) {3461 else => return switch (mod.intern_pool.indexToKey(val.ip_index)) {
3431 .enum_tag => |enum_tag| intIndexAsI32(&mod.intern_pool, enum_tag.int, mod),3462 .enum_tag => |enum_tag| intIndexAsI32(&mod.intern_pool, enum_tag.int, pt),
3432 .int => |int| intStorageAsI32(int.storage, mod),3463 .int => |int| intStorageAsI32(int.storage, pt),
3433 .ptr => |ptr| {3464 .ptr => |ptr| {
3434 assert(ptr.base_addr == .int);3465 assert(ptr.base_addr == .int);
3435 return @intCast(ptr.byte_offset);3466 return @intCast(ptr.byte_offset);
...@@ -3445,17 +3476,17 @@ fn valueAsI32(func: *const CodeGen, val: Value, ty: Type) i32 {...@@ -3445,17 +3476,17 @@ fn valueAsI32(func: *const CodeGen, val: Value, ty: Type) i32 {
3445 };3476 };
3446}3477}
34473478
3448fn intIndexAsI32(ip: *const InternPool, int: InternPool.Index, mod: *Zcu) i32 {3479fn intIndexAsI32(ip: *const InternPool, int: InternPool.Index, pt: Zcu.PerThread) i32 {
3449 return intStorageAsI32(ip.indexToKey(int).int.storage, mod);3480 return intStorageAsI32(ip.indexToKey(int).int.storage, pt);
3450}3481}
34513482
3452fn intStorageAsI32(storage: InternPool.Key.Int.Storage, mod: *Zcu) i32 {3483fn intStorageAsI32(storage: InternPool.Key.Int.Storage, pt: Zcu.PerThread) i32 {
3453 return switch (storage) {3484 return switch (storage) {
3454 .i64 => |x| @as(i32, @intCast(x)),3485 .i64 => |x| @as(i32, @intCast(x)),
3455 .u64 => |x| @as(i32, @bitCast(@as(u32, @intCast(x)))),3486 .u64 => |x| @as(i32, @bitCast(@as(u32, @intCast(x)))),
3456 .big_int => unreachable,3487 .big_int => unreachable,
3457 .lazy_align => |ty| @as(i32, @bitCast(@as(u32, @intCast(Type.fromInterned(ty).abiAlignment(mod).toByteUnits() orelse 0)))),3488 .lazy_align => |ty| @as(i32, @bitCast(@as(u32, @intCast(Type.fromInterned(ty).abiAlignment(pt).toByteUnits() orelse 0)))),
3458 .lazy_size => |ty| @as(i32, @bitCast(@as(u32, @intCast(Type.fromInterned(ty).abiSize(mod))))),3489 .lazy_size => |ty| @as(i32, @bitCast(@as(u32, @intCast(Type.fromInterned(ty).abiSize(pt))))),
3459 };3490 };
3460}3491}
34613492
...@@ -3466,12 +3497,12 @@ fn airBlock(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -3466,12 +3497,12 @@ fn airBlock(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
3466}3497}
34673498
3468fn lowerBlock(func: *CodeGen, inst: Air.Inst.Index, block_ty: Type, body: []const Air.Inst.Index) InnerError!void {3499fn lowerBlock(func: *CodeGen, inst: Air.Inst.Index, block_ty: Type, body: []const Air.Inst.Index) InnerError!void {
3469 const mod = func.bin_file.base.comp.module.?;3500 const pt = func.pt;
3470 const wasm_block_ty = genBlockType(block_ty, mod);3501 const wasm_block_ty = genBlockType(block_ty, pt);
34713502
3472 // if wasm_block_ty is non-empty, we create a register to store the temporary value3503 // if wasm_block_ty is non-empty, we create a register to store the temporary value
3473 const block_result: WValue = if (wasm_block_ty != wasm.block_empty) blk: {3504 const block_result: WValue = if (wasm_block_ty != wasm.block_empty) blk: {
3474 const ty: Type = if (isByRef(block_ty, mod)) Type.u32 else block_ty;3505 const ty: Type = if (isByRef(block_ty, pt)) Type.u32 else block_ty;
3475 break :blk try func.ensureAllocLocal(ty); // make sure it's a clean local as it may never get overwritten3506 break :blk try func.ensureAllocLocal(ty); // make sure it's a clean local as it may never get overwritten
3476 } else WValue.none;3507 } else WValue.none;
34773508
...@@ -3583,10 +3614,11 @@ fn airCmp(func: *CodeGen, inst: Air.Inst.Index, op: std.math.CompareOperator) In...@@ -3583,10 +3614,11 @@ fn airCmp(func: *CodeGen, inst: Air.Inst.Index, op: std.math.CompareOperator) In
3583/// NOTE: This leaves the result on top of the stack, rather than a new local.3614/// NOTE: This leaves the result on top of the stack, rather than a new local.
3584fn cmp(func: *CodeGen, lhs: WValue, rhs: WValue, ty: Type, op: std.math.CompareOperator) InnerError!WValue {3615fn cmp(func: *CodeGen, lhs: WValue, rhs: WValue, ty: Type, op: std.math.CompareOperator) InnerError!WValue {
3585 assert(!(lhs != .stack and rhs == .stack));3616 assert(!(lhs != .stack and rhs == .stack));
3586 const mod = func.bin_file.base.comp.module.?;3617 const pt = func.pt;
3618 const mod = pt.zcu;
3587 if (ty.zigTypeTag(mod) == .Optional and !ty.optionalReprIsPayload(mod)) {3619 if (ty.zigTypeTag(mod) == .Optional and !ty.optionalReprIsPayload(mod)) {
3588 const payload_ty = ty.optionalChild(mod);3620 const payload_ty = ty.optionalChild(mod);
3589 if (payload_ty.hasRuntimeBitsIgnoreComptime(mod)) {3621 if (payload_ty.hasRuntimeBitsIgnoreComptime(pt)) {
3590 // When we hit this case, we must check the value of optionals3622 // When we hit this case, we must check the value of optionals
3591 // that are not pointers. This means first checking against non-null for3623 // that are not pointers. This means first checking against non-null for
3592 // both lhs and rhs, as well as checking the payload are matching of lhs and rhs3624 // both lhs and rhs, as well as checking the payload are matching of lhs and rhs
...@@ -3594,7 +3626,7 @@ fn cmp(func: *CodeGen, lhs: WValue, rhs: WValue, ty: Type, op: std.math.CompareO...@@ -3594,7 +3626,7 @@ fn cmp(func: *CodeGen, lhs: WValue, rhs: WValue, ty: Type, op: std.math.CompareO
3594 }3626 }
3595 } else if (ty.isAnyFloat()) {3627 } else if (ty.isAnyFloat()) {
3596 return func.cmpFloat(ty, lhs, rhs, op);3628 return func.cmpFloat(ty, lhs, rhs, op);
3597 } else if (isByRef(ty, mod)) {3629 } else if (isByRef(ty, pt)) {
3598 return func.cmpBigInt(lhs, rhs, ty, op);3630 return func.cmpBigInt(lhs, rhs, ty, op);
3599 }3631 }
36003632
...@@ -3612,7 +3644,7 @@ fn cmp(func: *CodeGen, lhs: WValue, rhs: WValue, ty: Type, op: std.math.CompareO...@@ -3612,7 +3644,7 @@ fn cmp(func: *CodeGen, lhs: WValue, rhs: WValue, ty: Type, op: std.math.CompareO
3612 try func.lowerToStack(rhs);3644 try func.lowerToStack(rhs);
36133645
3614 const opcode: wasm.Opcode = buildOpcode(.{3646 const opcode: wasm.Opcode = buildOpcode(.{
3615 .valtype1 = typeToValtype(ty, mod),3647 .valtype1 = typeToValtype(ty, pt),
3616 .op = switch (op) {3648 .op = switch (op) {
3617 .lt => .lt,3649 .lt => .lt,
3618 .lte => .le,3650 .lte => .le,
...@@ -3683,8 +3715,8 @@ fn airCmpLtErrorsLen(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -3683,8 +3715,8 @@ fn airCmpLtErrorsLen(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
3683 const errors_len = WValue{ .memory = @intFromEnum(sym_index) };3715 const errors_len = WValue{ .memory = @intFromEnum(sym_index) };
36843716
3685 try func.emitWValue(operand);3717 try func.emitWValue(operand);
3686 const mod = func.bin_file.base.comp.module.?;3718 const pt = func.pt;
3687 const err_int_ty = try mod.errorIntType();3719 const err_int_ty = try pt.errorIntType();
3688 const errors_len_val = try func.load(errors_len, err_int_ty, 0);3720 const errors_len_val = try func.load(errors_len, err_int_ty, 0);
3689 const result = try func.cmp(.stack, errors_len_val, err_int_ty, .lt);3721 const result = try func.cmp(.stack, errors_len_val, err_int_ty, .lt);
36903722
...@@ -3692,12 +3724,12 @@ fn airCmpLtErrorsLen(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -3692,12 +3724,12 @@ fn airCmpLtErrorsLen(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
3692}3724}
36933725
3694fn airBr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {3726fn airBr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
3695 const mod = func.bin_file.base.comp.module.?;3727 const pt = func.pt;
3696 const br = func.air.instructions.items(.data)[@intFromEnum(inst)].br;3728 const br = func.air.instructions.items(.data)[@intFromEnum(inst)].br;
3697 const block = func.blocks.get(br.block_inst).?;3729 const block = func.blocks.get(br.block_inst).?;
36983730
3699 // if operand has codegen bits we should break with a value3731 // if operand has codegen bits we should break with a value
3700 if (func.typeOf(br.operand).hasRuntimeBitsIgnoreComptime(mod)) {3732 if (func.typeOf(br.operand).hasRuntimeBitsIgnoreComptime(pt)) {
3701 const operand = try func.resolveInst(br.operand);3733 const operand = try func.resolveInst(br.operand);
3702 try func.lowerToStack(operand);3734 try func.lowerToStack(operand);
37033735
...@@ -3719,7 +3751,8 @@ fn airNot(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -3719,7 +3751,8 @@ fn airNot(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
37193751
3720 const operand = try func.resolveInst(ty_op.operand);3752 const operand = try func.resolveInst(ty_op.operand);
3721 const operand_ty = func.typeOf(ty_op.operand);3753 const operand_ty = func.typeOf(ty_op.operand);
3722 const mod = func.bin_file.base.comp.module.?;3754 const pt = func.pt;
3755 const mod = pt.zcu;
37233756
3724 const result = result: {3757 const result = result: {
3725 if (operand_ty.zigTypeTag(mod) == .Bool) {3758 if (operand_ty.zigTypeTag(mod) == .Bool) {
...@@ -3731,7 +3764,7 @@ fn airNot(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -3731,7 +3764,7 @@ fn airNot(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
3731 } else {3764 } else {
3732 const int_info = operand_ty.intInfo(mod);3765 const int_info = operand_ty.intInfo(mod);
3733 const wasm_bits = toWasmBits(int_info.bits) orelse {3766 const wasm_bits = toWasmBits(int_info.bits) orelse {
3734 return func.fail("TODO: Implement binary NOT for {}", .{operand_ty.fmt(mod)});3767 return func.fail("TODO: Implement binary NOT for {}", .{operand_ty.fmt(pt)});
3735 };3768 };
37363769
3737 switch (wasm_bits) {3770 switch (wasm_bits) {
...@@ -3798,13 +3831,14 @@ fn airUnreachable(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -3798,13 +3831,14 @@ fn airUnreachable(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
3798}3831}
37993832
3800fn airBitcast(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {3833fn airBitcast(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
3801 const mod = func.bin_file.base.comp.module.?;3834 const pt = func.pt;
3835 const mod = pt.zcu;
3802 const ty_op = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;3836 const ty_op = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
3803 const operand = try func.resolveInst(ty_op.operand);3837 const operand = try func.resolveInst(ty_op.operand);
3804 const wanted_ty = func.typeOfIndex(inst);3838 const wanted_ty = func.typeOfIndex(inst);
3805 const given_ty = func.typeOf(ty_op.operand);3839 const given_ty = func.typeOf(ty_op.operand);
38063840
3807 const bit_size = given_ty.bitSize(mod);3841 const bit_size = given_ty.bitSize(pt);
3808 const needs_wrapping = (given_ty.isSignedInt(mod) != wanted_ty.isSignedInt(mod)) and3842 const needs_wrapping = (given_ty.isSignedInt(mod) != wanted_ty.isSignedInt(mod)) and
3809 bit_size != 32 and bit_size != 64 and bit_size != 128;3843 bit_size != 32 and bit_size != 64 and bit_size != 128;
38103844
...@@ -3814,7 +3848,7 @@ fn airBitcast(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -3814,7 +3848,7 @@ fn airBitcast(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
3814 break :result try bitcast_result.toLocal(func, wanted_ty);3848 break :result try bitcast_result.toLocal(func, wanted_ty);
3815 }3849 }
38163850
3817 if (isByRef(given_ty, mod) and !isByRef(wanted_ty, mod)) {3851 if (isByRef(given_ty, pt) and !isByRef(wanted_ty, pt)) {
3818 const loaded_memory = try func.load(operand, wanted_ty, 0);3852 const loaded_memory = try func.load(operand, wanted_ty, 0);
3819 if (needs_wrapping) {3853 if (needs_wrapping) {
3820 break :result try (try func.wrapOperand(loaded_memory, wanted_ty)).toLocal(func, wanted_ty);3854 break :result try (try func.wrapOperand(loaded_memory, wanted_ty)).toLocal(func, wanted_ty);
...@@ -3822,7 +3856,7 @@ fn airBitcast(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -3822,7 +3856,7 @@ fn airBitcast(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
3822 break :result try loaded_memory.toLocal(func, wanted_ty);3856 break :result try loaded_memory.toLocal(func, wanted_ty);
3823 }3857 }
3824 }3858 }
3825 if (!isByRef(given_ty, mod) and isByRef(wanted_ty, mod)) {3859 if (!isByRef(given_ty, pt) and isByRef(wanted_ty, pt)) {
3826 const stack_memory = try func.allocStack(wanted_ty);3860 const stack_memory = try func.allocStack(wanted_ty);
3827 try func.store(stack_memory, operand, given_ty, 0);3861 try func.store(stack_memory, operand, given_ty, 0);
3828 if (needs_wrapping) {3862 if (needs_wrapping) {
...@@ -3842,17 +3876,18 @@ fn airBitcast(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -3842,17 +3876,18 @@ fn airBitcast(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
3842}3876}
38433877
3844fn bitcast(func: *CodeGen, wanted_ty: Type, given_ty: Type, operand: WValue) InnerError!WValue {3878fn bitcast(func: *CodeGen, wanted_ty: Type, given_ty: Type, operand: WValue) InnerError!WValue {
3845 const mod = func.bin_file.base.comp.module.?;3879 const pt = func.pt;
3880 const mod = pt.zcu;
3846 // if we bitcast a float to or from an integer we must use the 'reinterpret' instruction3881 // if we bitcast a float to or from an integer we must use the 'reinterpret' instruction
3847 if (!(wanted_ty.isAnyFloat() or given_ty.isAnyFloat())) return operand;3882 if (!(wanted_ty.isAnyFloat() or given_ty.isAnyFloat())) return operand;
3848 if (wanted_ty.ip_index == .f16_type or given_ty.ip_index == .f16_type) return operand;3883 if (wanted_ty.ip_index == .f16_type or given_ty.ip_index == .f16_type) return operand;
3849 if (wanted_ty.bitSize(mod) > 64) return operand;3884 if (wanted_ty.bitSize(pt) > 64) return operand;
3850 assert((wanted_ty.isInt(mod) and given_ty.isAnyFloat()) or (wanted_ty.isAnyFloat() and given_ty.isInt(mod)));3885 assert((wanted_ty.isInt(mod) and given_ty.isAnyFloat()) or (wanted_ty.isAnyFloat() and given_ty.isInt(mod)));
38513886
3852 const opcode = buildOpcode(.{3887 const opcode = buildOpcode(.{
3853 .op = .reinterpret,3888 .op = .reinterpret,
3854 .valtype1 = typeToValtype(wanted_ty, mod),3889 .valtype1 = typeToValtype(wanted_ty, pt),
3855 .valtype2 = typeToValtype(given_ty, mod),3890 .valtype2 = typeToValtype(given_ty, pt),
3856 });3891 });
3857 try func.emitWValue(operand);3892 try func.emitWValue(operand);
3858 try func.addTag(Mir.Inst.Tag.fromOpcode(opcode));3893 try func.addTag(Mir.Inst.Tag.fromOpcode(opcode));
...@@ -3860,7 +3895,8 @@ fn bitcast(func: *CodeGen, wanted_ty: Type, given_ty: Type, operand: WValue) Inn...@@ -3860,7 +3895,8 @@ fn bitcast(func: *CodeGen, wanted_ty: Type, given_ty: Type, operand: WValue) Inn
3860}3895}
38613896
3862fn airStructFieldPtr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {3897fn airStructFieldPtr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
3863 const mod = func.bin_file.base.comp.module.?;3898 const pt = func.pt;
3899 const mod = pt.zcu;
3864 const ty_pl = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;3900 const ty_pl = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
3865 const extra = func.air.extraData(Air.StructField, ty_pl.payload);3901 const extra = func.air.extraData(Air.StructField, ty_pl.payload);
38663902
...@@ -3872,7 +3908,8 @@ fn airStructFieldPtr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -3872,7 +3908,8 @@ fn airStructFieldPtr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
3872}3908}
38733909
3874fn airStructFieldPtrIndex(func: *CodeGen, inst: Air.Inst.Index, index: u32) InnerError!void {3910fn airStructFieldPtrIndex(func: *CodeGen, inst: Air.Inst.Index, index: u32) InnerError!void {
3875 const mod = func.bin_file.base.comp.module.?;3911 const pt = func.pt;
3912 const mod = pt.zcu;
3876 const ty_op = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;3913 const ty_op = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
3877 const struct_ptr = try func.resolveInst(ty_op.operand);3914 const struct_ptr = try func.resolveInst(ty_op.operand);
3878 const struct_ptr_ty = func.typeOf(ty_op.operand);3915 const struct_ptr_ty = func.typeOf(ty_op.operand);
...@@ -3891,7 +3928,8 @@ fn structFieldPtr(...@@ -3891,7 +3928,8 @@ fn structFieldPtr(
3891 struct_ty: Type,3928 struct_ty: Type,
3892 index: u32,3929 index: u32,
3893) InnerError!WValue {3930) InnerError!WValue {
3894 const mod = func.bin_file.base.comp.module.?;3931 const pt = func.pt;
3932 const mod = pt.zcu;
3895 const result_ty = func.typeOfIndex(inst);3933 const result_ty = func.typeOfIndex(inst);
3896 const struct_ptr_ty_info = struct_ptr_ty.ptrInfo(mod);3934 const struct_ptr_ty_info = struct_ptr_ty.ptrInfo(mod);
38973935
...@@ -3902,12 +3940,12 @@ fn structFieldPtr(...@@ -3902,12 +3940,12 @@ fn structFieldPtr(
3902 break :offset @as(u32, 0);3940 break :offset @as(u32, 0);
3903 }3941 }
3904 const struct_type = mod.typeToStruct(struct_ty).?;3942 const struct_type = mod.typeToStruct(struct_ty).?;
3905 break :offset @divExact(mod.structPackedFieldBitOffset(struct_type, index) + struct_ptr_ty_info.packed_offset.bit_offset, 8);3943 break :offset @divExact(pt.structPackedFieldBitOffset(struct_type, index) + struct_ptr_ty_info.packed_offset.bit_offset, 8);
3906 },3944 },
3907 .Union => 0,3945 .Union => 0,
3908 else => unreachable,3946 else => unreachable,
3909 },3947 },
3910 else => struct_ty.structFieldOffset(index, mod),3948 else => struct_ty.structFieldOffset(index, pt),
3911 };3949 };
3912 // save a load and store when we can simply reuse the operand3950 // save a load and store when we can simply reuse the operand
3913 if (offset == 0) {3951 if (offset == 0) {
...@@ -3922,7 +3960,8 @@ fn structFieldPtr(...@@ -3922,7 +3960,8 @@ fn structFieldPtr(
3922}3960}
39233961
3924fn airStructFieldVal(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {3962fn airStructFieldVal(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
3925 const mod = func.bin_file.base.comp.module.?;3963 const pt = func.pt;
3964 const mod = pt.zcu;
3926 const ip = &mod.intern_pool;3965 const ip = &mod.intern_pool;
3927 const ty_pl = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;3966 const ty_pl = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
3928 const struct_field = func.air.extraData(Air.StructField, ty_pl.payload).data;3967 const struct_field = func.air.extraData(Air.StructField, ty_pl.payload).data;
...@@ -3931,13 +3970,13 @@ fn airStructFieldVal(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -3931,13 +3970,13 @@ fn airStructFieldVal(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
3931 const operand = try func.resolveInst(struct_field.struct_operand);3970 const operand = try func.resolveInst(struct_field.struct_operand);
3932 const field_index = struct_field.field_index;3971 const field_index = struct_field.field_index;
3933 const field_ty = struct_ty.structFieldType(field_index, mod);3972 const field_ty = struct_ty.structFieldType(field_index, mod);
3934 if (!field_ty.hasRuntimeBitsIgnoreComptime(mod)) return func.finishAir(inst, .none, &.{struct_field.struct_operand});3973 if (!field_ty.hasRuntimeBitsIgnoreComptime(pt)) return func.finishAir(inst, .none, &.{struct_field.struct_operand});
39353974
3936 const result = switch (struct_ty.containerLayout(mod)) {3975 const result = switch (struct_ty.containerLayout(mod)) {
3937 .@"packed" => switch (struct_ty.zigTypeTag(mod)) {3976 .@"packed" => switch (struct_ty.zigTypeTag(mod)) {
3938 .Struct => result: {3977 .Struct => result: {
3939 const packed_struct = mod.typeToPackedStruct(struct_ty).?;3978 const packed_struct = mod.typeToPackedStruct(struct_ty).?;
3940 const offset = mod.structPackedFieldBitOffset(packed_struct, field_index);3979 const offset = pt.structPackedFieldBitOffset(packed_struct, field_index);
3941 const backing_ty = Type.fromInterned(packed_struct.backingIntType(ip).*);3980 const backing_ty = Type.fromInterned(packed_struct.backingIntType(ip).*);
3942 const wasm_bits = toWasmBits(backing_ty.intInfo(mod).bits) orelse {3981 const wasm_bits = toWasmBits(backing_ty.intInfo(mod).bits) orelse {
3943 return func.fail("TODO: airStructFieldVal for packed structs larger than 128 bits", .{});3982 return func.fail("TODO: airStructFieldVal for packed structs larger than 128 bits", .{});
...@@ -3956,7 +3995,7 @@ fn airStructFieldVal(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -3956,7 +3995,7 @@ fn airStructFieldVal(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
3956 try func.binOp(operand, const_wvalue, backing_ty, .shr);3995 try func.binOp(operand, const_wvalue, backing_ty, .shr);
39573996
3958 if (field_ty.zigTypeTag(mod) == .Float) {3997 if (field_ty.zigTypeTag(mod) == .Float) {
3959 const int_type = try mod.intType(.unsigned, @as(u16, @intCast(field_ty.bitSize(mod))));3998 const int_type = try pt.intType(.unsigned, @as(u16, @intCast(field_ty.bitSize(pt))));
3960 const truncated = try func.trunc(shifted_value, int_type, backing_ty);3999 const truncated = try func.trunc(shifted_value, int_type, backing_ty);
3961 const bitcasted = try func.bitcast(field_ty, int_type, truncated);4000 const bitcasted = try func.bitcast(field_ty, int_type, truncated);
3962 break :result try bitcasted.toLocal(func, field_ty);4001 break :result try bitcasted.toLocal(func, field_ty);
...@@ -3965,7 +4004,7 @@ fn airStructFieldVal(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -3965,7 +4004,7 @@ fn airStructFieldVal(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
3965 // we can simply reuse the operand.4004 // we can simply reuse the operand.
3966 break :result func.reuseOperand(struct_field.struct_operand, operand);4005 break :result func.reuseOperand(struct_field.struct_operand, operand);
3967 } else if (field_ty.isPtrAtRuntime(mod)) {4006 } else if (field_ty.isPtrAtRuntime(mod)) {
3968 const int_type = try mod.intType(.unsigned, @as(u16, @intCast(field_ty.bitSize(mod))));4007 const int_type = try pt.intType(.unsigned, @as(u16, @intCast(field_ty.bitSize(pt))));
3969 const truncated = try func.trunc(shifted_value, int_type, backing_ty);4008 const truncated = try func.trunc(shifted_value, int_type, backing_ty);
3970 break :result try truncated.toLocal(func, field_ty);4009 break :result try truncated.toLocal(func, field_ty);
3971 }4010 }
...@@ -3973,8 +4012,8 @@ fn airStructFieldVal(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -3973,8 +4012,8 @@ fn airStructFieldVal(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
3973 break :result try truncated.toLocal(func, field_ty);4012 break :result try truncated.toLocal(func, field_ty);
3974 },4013 },
3975 .Union => result: {4014 .Union => result: {
3976 if (isByRef(struct_ty, mod)) {4015 if (isByRef(struct_ty, pt)) {
3977 if (!isByRef(field_ty, mod)) {4016 if (!isByRef(field_ty, pt)) {
3978 const val = try func.load(operand, field_ty, 0);4017 const val = try func.load(operand, field_ty, 0);
3979 break :result try val.toLocal(func, field_ty);4018 break :result try val.toLocal(func, field_ty);
3980 } else {4019 } else {
...@@ -3984,14 +4023,14 @@ fn airStructFieldVal(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -3984,14 +4023,14 @@ fn airStructFieldVal(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
3984 }4023 }
3985 }4024 }
39864025
3987 const union_int_type = try mod.intType(.unsigned, @as(u16, @intCast(struct_ty.bitSize(mod))));4026 const union_int_type = try pt.intType(.unsigned, @as(u16, @intCast(struct_ty.bitSize(pt))));
3988 if (field_ty.zigTypeTag(mod) == .Float) {4027 if (field_ty.zigTypeTag(mod) == .Float) {
3989 const int_type = try mod.intType(.unsigned, @as(u16, @intCast(field_ty.bitSize(mod))));4028 const int_type = try pt.intType(.unsigned, @as(u16, @intCast(field_ty.bitSize(pt))));
3990 const truncated = try func.trunc(operand, int_type, union_int_type);4029 const truncated = try func.trunc(operand, int_type, union_int_type);
3991 const bitcasted = try func.bitcast(field_ty, int_type, truncated);4030 const bitcasted = try func.bitcast(field_ty, int_type, truncated);
3992 break :result try bitcasted.toLocal(func, field_ty);4031 break :result try bitcasted.toLocal(func, field_ty);
3993 } else if (field_ty.isPtrAtRuntime(mod)) {4032 } else if (field_ty.isPtrAtRuntime(mod)) {
3994 const int_type = try mod.intType(.unsigned, @as(u16, @intCast(field_ty.bitSize(mod))));4033 const int_type = try pt.intType(.unsigned, @as(u16, @intCast(field_ty.bitSize(pt))));
3995 const truncated = try func.trunc(operand, int_type, union_int_type);4034 const truncated = try func.trunc(operand, int_type, union_int_type);
3996 break :result try truncated.toLocal(func, field_ty);4035 break :result try truncated.toLocal(func, field_ty);
3997 }4036 }
...@@ -4001,10 +4040,10 @@ fn airStructFieldVal(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -4001,10 +4040,10 @@ fn airStructFieldVal(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
4001 else => unreachable,4040 else => unreachable,
4002 },4041 },
4003 else => result: {4042 else => result: {
4004 const offset = std.math.cast(u32, struct_ty.structFieldOffset(field_index, mod)) orelse {4043 const offset = std.math.cast(u32, struct_ty.structFieldOffset(field_index, pt)) orelse {
4005 return func.fail("Field type '{}' too big to fit into stack frame", .{field_ty.fmt(mod)});4044 return func.fail("Field type '{}' too big to fit into stack frame", .{field_ty.fmt(pt)});
4006 };4045 };
4007 if (isByRef(field_ty, mod)) {4046 if (isByRef(field_ty, pt)) {
4008 switch (operand) {4047 switch (operand) {
4009 .stack_offset => |stack_offset| {4048 .stack_offset => |stack_offset| {
4010 break :result WValue{ .stack_offset = .{ .value = stack_offset.value + offset, .references = 1 } };4049 break :result WValue{ .stack_offset = .{ .value = stack_offset.value + offset, .references = 1 } };
...@@ -4021,7 +4060,8 @@ fn airStructFieldVal(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -4021,7 +4060,8 @@ fn airStructFieldVal(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
4021}4060}
40224061
4023fn airSwitchBr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {4062fn airSwitchBr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
4024 const mod = func.bin_file.base.comp.module.?;4063 const pt = func.pt;
4064 const mod = pt.zcu;
4025 // result type is always 'noreturn'4065 // result type is always 'noreturn'
4026 const blocktype = wasm.block_empty;4066 const blocktype = wasm.block_empty;
4027 const pl_op = func.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;4067 const pl_op = func.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;
...@@ -4055,7 +4095,7 @@ fn airSwitchBr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -4055,7 +4095,7 @@ fn airSwitchBr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
4055 errdefer func.gpa.free(values);4095 errdefer func.gpa.free(values);
40564096
4057 for (items, 0..) |ref, i| {4097 for (items, 0..) |ref, i| {
4058 const item_val = (try func.air.value(ref, mod)).?;4098 const item_val = (try func.air.value(ref, pt)).?;
4059 const int_val = func.valueAsI32(item_val, target_ty);4099 const int_val = func.valueAsI32(item_val, target_ty);
4060 if (lowest_maybe == null or int_val < lowest_maybe.?) {4100 if (lowest_maybe == null or int_val < lowest_maybe.?) {
4061 lowest_maybe = int_val;4101 lowest_maybe = int_val;
...@@ -4078,7 +4118,7 @@ fn airSwitchBr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -4078,7 +4118,7 @@ fn airSwitchBr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
4078 // When the target is an integer size larger than u32, we have no way to use the value4118 // When the target is an integer size larger than u32, we have no way to use the value
4079 // as an index, therefore we also use an if/else-chain for those cases.4119 // as an index, therefore we also use an if/else-chain for those cases.
4080 // TODO: Benchmark this to find a proper value, LLVM seems to draw the line at '40~45'.4120 // TODO: Benchmark this to find a proper value, LLVM seems to draw the line at '40~45'.
4081 const is_sparse = highest - lowest > 50 or target_ty.bitSize(mod) > 32;4121 const is_sparse = highest - lowest > 50 or target_ty.bitSize(pt) > 32;
40824122
4083 const else_body: []const Air.Inst.Index = @ptrCast(func.air.extra[extra_index..][0..switch_br.data.else_body_len]);4123 const else_body: []const Air.Inst.Index = @ptrCast(func.air.extra[extra_index..][0..switch_br.data.else_body_len]);
4084 const has_else_body = else_body.len != 0;4124 const has_else_body = else_body.len != 0;
...@@ -4150,7 +4190,7 @@ fn airSwitchBr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -4150,7 +4190,7 @@ fn airSwitchBr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
4150 const val = try func.lowerConstant(case.values[0].value, target_ty);4190 const val = try func.lowerConstant(case.values[0].value, target_ty);
4151 try func.emitWValue(val);4191 try func.emitWValue(val);
4152 const opcode = buildOpcode(.{4192 const opcode = buildOpcode(.{
4153 .valtype1 = typeToValtype(target_ty, mod),4193 .valtype1 = typeToValtype(target_ty, pt),
4154 .op = .ne, // not equal, because we want to jump out of this block if it does not match the condition.4194 .op = .ne, // not equal, because we want to jump out of this block if it does not match the condition.
4155 .signedness = signedness,4195 .signedness = signedness,
4156 });4196 });
...@@ -4164,7 +4204,7 @@ fn airSwitchBr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -4164,7 +4204,7 @@ fn airSwitchBr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
4164 const val = try func.lowerConstant(value.value, target_ty);4204 const val = try func.lowerConstant(value.value, target_ty);
4165 try func.emitWValue(val);4205 try func.emitWValue(val);
4166 const opcode = buildOpcode(.{4206 const opcode = buildOpcode(.{
4167 .valtype1 = typeToValtype(target_ty, mod),4207 .valtype1 = typeToValtype(target_ty, pt),
4168 .op = .eq,4208 .op = .eq,
4169 .signedness = signedness,4209 .signedness = signedness,
4170 });4210 });
...@@ -4201,7 +4241,8 @@ fn airSwitchBr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -4201,7 +4241,8 @@ fn airSwitchBr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
4201}4241}
42024242
4203fn airIsErr(func: *CodeGen, inst: Air.Inst.Index, opcode: wasm.Opcode) InnerError!void {4243fn airIsErr(func: *CodeGen, inst: Air.Inst.Index, opcode: wasm.Opcode) InnerError!void {
4204 const mod = func.bin_file.base.comp.module.?;4244 const pt = func.pt;
4245 const mod = pt.zcu;
4205 const un_op = func.air.instructions.items(.data)[@intFromEnum(inst)].un_op;4246 const un_op = func.air.instructions.items(.data)[@intFromEnum(inst)].un_op;
4206 const operand = try func.resolveInst(un_op);4247 const operand = try func.resolveInst(un_op);
4207 const err_union_ty = func.typeOf(un_op);4248 const err_union_ty = func.typeOf(un_op);
...@@ -4217,10 +4258,10 @@ fn airIsErr(func: *CodeGen, inst: Air.Inst.Index, opcode: wasm.Opcode) InnerErro...@@ -4217,10 +4258,10 @@ fn airIsErr(func: *CodeGen, inst: Air.Inst.Index, opcode: wasm.Opcode) InnerErro
4217 }4258 }
42184259
4219 try func.emitWValue(operand);4260 try func.emitWValue(operand);
4220 if (pl_ty.hasRuntimeBitsIgnoreComptime(mod)) {4261 if (pl_ty.hasRuntimeBitsIgnoreComptime(pt)) {
4221 try func.addMemArg(.i32_load16_u, .{4262 try func.addMemArg(.i32_load16_u, .{
4222 .offset = operand.offset() + @as(u32, @intCast(errUnionErrorOffset(pl_ty, mod))),4263 .offset = operand.offset() + @as(u32, @intCast(errUnionErrorOffset(pl_ty, pt))),
4223 .alignment = @intCast(Type.anyerror.abiAlignment(mod).toByteUnits().?),4264 .alignment = @intCast(Type.anyerror.abiAlignment(pt).toByteUnits().?),
4224 });4265 });
4225 }4266 }
42264267
...@@ -4236,7 +4277,8 @@ fn airIsErr(func: *CodeGen, inst: Air.Inst.Index, opcode: wasm.Opcode) InnerErro...@@ -4236,7 +4277,8 @@ fn airIsErr(func: *CodeGen, inst: Air.Inst.Index, opcode: wasm.Opcode) InnerErro
4236}4277}
42374278
4238fn airUnwrapErrUnionPayload(func: *CodeGen, inst: Air.Inst.Index, op_is_ptr: bool) InnerError!void {4279fn airUnwrapErrUnionPayload(func: *CodeGen, inst: Air.Inst.Index, op_is_ptr: bool) InnerError!void {
4239 const mod = func.bin_file.base.comp.module.?;4280 const pt = func.pt;
4281 const mod = pt.zcu;
4240 const ty_op = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;4282 const ty_op = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
42414283
4242 const operand = try func.resolveInst(ty_op.operand);4284 const operand = try func.resolveInst(ty_op.operand);
...@@ -4245,15 +4287,15 @@ fn airUnwrapErrUnionPayload(func: *CodeGen, inst: Air.Inst.Index, op_is_ptr: boo...@@ -4245,15 +4287,15 @@ fn airUnwrapErrUnionPayload(func: *CodeGen, inst: Air.Inst.Index, op_is_ptr: boo
4245 const payload_ty = err_ty.errorUnionPayload(mod);4287 const payload_ty = err_ty.errorUnionPayload(mod);
42464288
4247 const result = result: {4289 const result = result: {
4248 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) {4290 if (!payload_ty.hasRuntimeBitsIgnoreComptime(pt)) {
4249 if (op_is_ptr) {4291 if (op_is_ptr) {
4250 break :result func.reuseOperand(ty_op.operand, operand);4292 break :result func.reuseOperand(ty_op.operand, operand);
4251 }4293 }
4252 break :result WValue{ .none = {} };4294 break :result WValue{ .none = {} };
4253 }4295 }
42544296
4255 const pl_offset = @as(u32, @intCast(errUnionPayloadOffset(payload_ty, mod)));4297 const pl_offset = @as(u32, @intCast(errUnionPayloadOffset(payload_ty, pt)));
4256 if (op_is_ptr or isByRef(payload_ty, mod)) {4298 if (op_is_ptr or isByRef(payload_ty, pt)) {
4257 break :result try func.buildPointerOffset(operand, pl_offset, .new);4299 break :result try func.buildPointerOffset(operand, pl_offset, .new);
4258 }4300 }
42594301
...@@ -4264,7 +4306,8 @@ fn airUnwrapErrUnionPayload(func: *CodeGen, inst: Air.Inst.Index, op_is_ptr: boo...@@ -4264,7 +4306,8 @@ fn airUnwrapErrUnionPayload(func: *CodeGen, inst: Air.Inst.Index, op_is_ptr: boo
4264}4306}
42654307
4266fn airUnwrapErrUnionError(func: *CodeGen, inst: Air.Inst.Index, op_is_ptr: bool) InnerError!void {4308fn airUnwrapErrUnionError(func: *CodeGen, inst: Air.Inst.Index, op_is_ptr: bool) InnerError!void {
4267 const mod = func.bin_file.base.comp.module.?;4309 const pt = func.pt;
4310 const mod = pt.zcu;
4268 const ty_op = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;4311 const ty_op = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
42694312
4270 const operand = try func.resolveInst(ty_op.operand);4313 const operand = try func.resolveInst(ty_op.operand);
...@@ -4277,18 +4320,18 @@ fn airUnwrapErrUnionError(func: *CodeGen, inst: Air.Inst.Index, op_is_ptr: bool)...@@ -4277,18 +4320,18 @@ fn airUnwrapErrUnionError(func: *CodeGen, inst: Air.Inst.Index, op_is_ptr: bool)
4277 break :result WValue{ .imm32 = 0 };4320 break :result WValue{ .imm32 = 0 };
4278 }4321 }
42794322
4280 if (op_is_ptr or !payload_ty.hasRuntimeBitsIgnoreComptime(mod)) {4323 if (op_is_ptr or !payload_ty.hasRuntimeBitsIgnoreComptime(pt)) {
4281 break :result func.reuseOperand(ty_op.operand, operand);4324 break :result func.reuseOperand(ty_op.operand, operand);
4282 }4325 }
42834326
4284 const error_val = try func.load(operand, Type.anyerror, @as(u32, @intCast(errUnionErrorOffset(payload_ty, mod))));4327 const error_val = try func.load(operand, Type.anyerror, @intCast(errUnionErrorOffset(payload_ty, pt)));
4285 break :result try error_val.toLocal(func, Type.anyerror);4328 break :result try error_val.toLocal(func, Type.anyerror);
4286 };4329 };
4287 func.finishAir(inst, result, &.{ty_op.operand});4330 func.finishAir(inst, result, &.{ty_op.operand});
4288}4331}
42894332
4290fn airWrapErrUnionPayload(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {4333fn airWrapErrUnionPayload(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
4291 const mod = func.bin_file.base.comp.module.?;4334 const pt = func.pt;
4292 const ty_op = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;4335 const ty_op = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
42934336
4294 const operand = try func.resolveInst(ty_op.operand);4337 const operand = try func.resolveInst(ty_op.operand);
...@@ -4296,18 +4339,18 @@ fn airWrapErrUnionPayload(func: *CodeGen, inst: Air.Inst.Index) InnerError!void...@@ -4296,18 +4339,18 @@ fn airWrapErrUnionPayload(func: *CodeGen, inst: Air.Inst.Index) InnerError!void
42964339
4297 const pl_ty = func.typeOf(ty_op.operand);4340 const pl_ty = func.typeOf(ty_op.operand);
4298 const result = result: {4341 const result = result: {
4299 if (!pl_ty.hasRuntimeBitsIgnoreComptime(mod)) {4342 if (!pl_ty.hasRuntimeBitsIgnoreComptime(pt)) {
4300 break :result func.reuseOperand(ty_op.operand, operand);4343 break :result func.reuseOperand(ty_op.operand, operand);
4301 }4344 }
43024345
4303 const err_union = try func.allocStack(err_ty);4346 const err_union = try func.allocStack(err_ty);
4304 const payload_ptr = try func.buildPointerOffset(err_union, @as(u32, @intCast(errUnionPayloadOffset(pl_ty, mod))), .new);4347 const payload_ptr = try func.buildPointerOffset(err_union, @as(u32, @intCast(errUnionPayloadOffset(pl_ty, pt))), .new);
4305 try func.store(payload_ptr, operand, pl_ty, 0);4348 try func.store(payload_ptr, operand, pl_ty, 0);
43064349
4307 // ensure we also write '0' to the error part, so any present stack value gets overwritten by it.4350 // ensure we also write '0' to the error part, so any present stack value gets overwritten by it.
4308 try func.emitWValue(err_union);4351 try func.emitWValue(err_union);
4309 try func.addImm32(0);4352 try func.addImm32(0);
4310 const err_val_offset = @as(u32, @intCast(errUnionErrorOffset(pl_ty, mod)));4353 const err_val_offset: u32 = @intCast(errUnionErrorOffset(pl_ty, pt));
4311 try func.addMemArg(.i32_store16, .{4354 try func.addMemArg(.i32_store16, .{
4312 .offset = err_union.offset() + err_val_offset,4355 .offset = err_union.offset() + err_val_offset,
4313 .alignment = 2,4356 .alignment = 2,
...@@ -4318,7 +4361,8 @@ fn airWrapErrUnionPayload(func: *CodeGen, inst: Air.Inst.Index) InnerError!void...@@ -4318,7 +4361,8 @@ fn airWrapErrUnionPayload(func: *CodeGen, inst: Air.Inst.Index) InnerError!void
4318}4361}
43194362
4320fn airWrapErrUnionErr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {4363fn airWrapErrUnionErr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
4321 const mod = func.bin_file.base.comp.module.?;4364 const pt = func.pt;
4365 const mod = pt.zcu;
4322 const ty_op = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;4366 const ty_op = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
43234367
4324 const operand = try func.resolveInst(ty_op.operand);4368 const operand = try func.resolveInst(ty_op.operand);
...@@ -4326,17 +4370,17 @@ fn airWrapErrUnionErr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -4326,17 +4370,17 @@ fn airWrapErrUnionErr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
4326 const pl_ty = err_ty.errorUnionPayload(mod);4370 const pl_ty = err_ty.errorUnionPayload(mod);
43274371
4328 const result = result: {4372 const result = result: {
4329 if (!pl_ty.hasRuntimeBitsIgnoreComptime(mod)) {4373 if (!pl_ty.hasRuntimeBitsIgnoreComptime(pt)) {
4330 break :result func.reuseOperand(ty_op.operand, operand);4374 break :result func.reuseOperand(ty_op.operand, operand);
4331 }4375 }
43324376
4333 const err_union = try func.allocStack(err_ty);4377 const err_union = try func.allocStack(err_ty);
4334 // store error value4378 // store error value
4335 try func.store(err_union, operand, Type.anyerror, @as(u32, @intCast(errUnionErrorOffset(pl_ty, mod))));4379 try func.store(err_union, operand, Type.anyerror, @intCast(errUnionErrorOffset(pl_ty, pt)));
43364380
4337 // write 'undefined' to the payload4381 // write 'undefined' to the payload
4338 const payload_ptr = try func.buildPointerOffset(err_union, @as(u32, @intCast(errUnionPayloadOffset(pl_ty, mod))), .new);4382 const payload_ptr = try func.buildPointerOffset(err_union, @as(u32, @intCast(errUnionPayloadOffset(pl_ty, pt))), .new);
4339 const len = @as(u32, @intCast(err_ty.errorUnionPayload(mod).abiSize(mod)));4383 const len = @as(u32, @intCast(err_ty.errorUnionPayload(mod).abiSize(pt)));
4340 try func.memset(Type.u8, payload_ptr, .{ .imm32 = len }, .{ .imm32 = 0xaa });4384 try func.memset(Type.u8, payload_ptr, .{ .imm32 = len }, .{ .imm32 = 0xaa });
43414385
4342 break :result err_union;4386 break :result err_union;
...@@ -4350,16 +4394,17 @@ fn airIntcast(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -4350,16 +4394,17 @@ fn airIntcast(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
4350 const ty = ty_op.ty.toType();4394 const ty = ty_op.ty.toType();
4351 const operand = try func.resolveInst(ty_op.operand);4395 const operand = try func.resolveInst(ty_op.operand);
4352 const operand_ty = func.typeOf(ty_op.operand);4396 const operand_ty = func.typeOf(ty_op.operand);
4353 const mod = func.bin_file.base.comp.module.?;4397 const pt = func.pt;
4398 const mod = pt.zcu;
4354 if (ty.zigTypeTag(mod) == .Vector or operand_ty.zigTypeTag(mod) == .Vector) {4399 if (ty.zigTypeTag(mod) == .Vector or operand_ty.zigTypeTag(mod) == .Vector) {
4355 return func.fail("todo Wasm intcast for vectors", .{});4400 return func.fail("todo Wasm intcast for vectors", .{});
4356 }4401 }
4357 if (ty.abiSize(mod) > 16 or operand_ty.abiSize(mod) > 16) {4402 if (ty.abiSize(pt) > 16 or operand_ty.abiSize(pt) > 16) {
4358 return func.fail("todo Wasm intcast for bitsize > 128", .{});4403 return func.fail("todo Wasm intcast for bitsize > 128", .{});
4359 }4404 }
43604405
4361 const op_bits = toWasmBits(@as(u16, @intCast(operand_ty.bitSize(mod)))).?;4406 const op_bits = toWasmBits(@intCast(operand_ty.bitSize(pt))).?;
4362 const wanted_bits = toWasmBits(@as(u16, @intCast(ty.bitSize(mod)))).?;4407 const wanted_bits = toWasmBits(@intCast(ty.bitSize(pt))).?;
4363 const result = if (op_bits == wanted_bits)4408 const result = if (op_bits == wanted_bits)
4364 func.reuseOperand(ty_op.operand, operand)4409 func.reuseOperand(ty_op.operand, operand)
4365 else4410 else
...@@ -4373,9 +4418,10 @@ fn airIntcast(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -4373,9 +4418,10 @@ fn airIntcast(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
4373/// Asserts type's bitsize <= 1284418/// Asserts type's bitsize <= 128
4374/// NOTE: May leave the result on the top of the stack.4419/// NOTE: May leave the result on the top of the stack.
4375fn intcast(func: *CodeGen, operand: WValue, given: Type, wanted: Type) InnerError!WValue {4420fn intcast(func: *CodeGen, operand: WValue, given: Type, wanted: Type) InnerError!WValue {
4376 const mod = func.bin_file.base.comp.module.?;4421 const pt = func.pt;
4377 const given_bitsize = @as(u16, @intCast(given.bitSize(mod)));4422 const mod = pt.zcu;
4378 const wanted_bitsize = @as(u16, @intCast(wanted.bitSize(mod)));4423 const given_bitsize = @as(u16, @intCast(given.bitSize(pt)));
4424 const wanted_bitsize = @as(u16, @intCast(wanted.bitSize(pt)));
4379 assert(given_bitsize <= 128);4425 assert(given_bitsize <= 128);
4380 assert(wanted_bitsize <= 128);4426 assert(wanted_bitsize <= 128);
43814427
...@@ -4422,7 +4468,8 @@ fn intcast(func: *CodeGen, operand: WValue, given: Type, wanted: Type) InnerErro...@@ -4422,7 +4468,8 @@ fn intcast(func: *CodeGen, operand: WValue, given: Type, wanted: Type) InnerErro
4422}4468}
44234469
4424fn airIsNull(func: *CodeGen, inst: Air.Inst.Index, opcode: wasm.Opcode, op_kind: enum { value, ptr }) InnerError!void {4470fn airIsNull(func: *CodeGen, inst: Air.Inst.Index, opcode: wasm.Opcode, op_kind: enum { value, ptr }) InnerError!void {
4425 const mod = func.bin_file.base.comp.module.?;4471 const pt = func.pt;
4472 const mod = pt.zcu;
4426 const un_op = func.air.instructions.items(.data)[@intFromEnum(inst)].un_op;4473 const un_op = func.air.instructions.items(.data)[@intFromEnum(inst)].un_op;
4427 const operand = try func.resolveInst(un_op);4474 const operand = try func.resolveInst(un_op);
44284475
...@@ -4436,15 +4483,16 @@ fn airIsNull(func: *CodeGen, inst: Air.Inst.Index, opcode: wasm.Opcode, op_kind:...@@ -4436,15 +4483,16 @@ fn airIsNull(func: *CodeGen, inst: Air.Inst.Index, opcode: wasm.Opcode, op_kind:
4436/// For a given type and operand, checks if it's considered `null`.4483/// For a given type and operand, checks if it's considered `null`.
4437/// NOTE: Leaves the result on the stack4484/// NOTE: Leaves the result on the stack
4438fn isNull(func: *CodeGen, operand: WValue, optional_ty: Type, opcode: wasm.Opcode) InnerError!WValue {4485fn isNull(func: *CodeGen, operand: WValue, optional_ty: Type, opcode: wasm.Opcode) InnerError!WValue {
4439 const mod = func.bin_file.base.comp.module.?;4486 const pt = func.pt;
4487 const mod = pt.zcu;
4440 try func.emitWValue(operand);4488 try func.emitWValue(operand);
4441 const payload_ty = optional_ty.optionalChild(mod);4489 const payload_ty = optional_ty.optionalChild(mod);
4442 if (!optional_ty.optionalReprIsPayload(mod)) {4490 if (!optional_ty.optionalReprIsPayload(mod)) {
4443 // When payload is zero-bits, we can treat operand as a value, rather than4491 // When payload is zero-bits, we can treat operand as a value, rather than
4444 // a pointer to the stack value4492 // a pointer to the stack value
4445 if (payload_ty.hasRuntimeBitsIgnoreComptime(mod)) {4493 if (payload_ty.hasRuntimeBitsIgnoreComptime(pt)) {
4446 const offset = std.math.cast(u32, payload_ty.abiSize(mod)) orelse {4494 const offset = std.math.cast(u32, payload_ty.abiSize(pt)) orelse {
4447 return func.fail("Optional type {} too big to fit into stack frame", .{optional_ty.fmt(mod)});4495 return func.fail("Optional type {} too big to fit into stack frame", .{optional_ty.fmt(pt)});
4448 };4496 };
4449 try func.addMemArg(.i32_load8_u, .{ .offset = operand.offset() + offset, .alignment = 1 });4497 try func.addMemArg(.i32_load8_u, .{ .offset = operand.offset() + offset, .alignment = 1 });
4450 }4498 }
...@@ -4464,11 +4512,12 @@ fn isNull(func: *CodeGen, operand: WValue, optional_ty: Type, opcode: wasm.Opcod...@@ -4464,11 +4512,12 @@ fn isNull(func: *CodeGen, operand: WValue, optional_ty: Type, opcode: wasm.Opcod
4464}4512}
44654513
4466fn airOptionalPayload(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {4514fn airOptionalPayload(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
4467 const mod = func.bin_file.base.comp.module.?;4515 const pt = func.pt;
4516 const mod = pt.zcu;
4468 const ty_op = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;4517 const ty_op = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
4469 const opt_ty = func.typeOf(ty_op.operand);4518 const opt_ty = func.typeOf(ty_op.operand);
4470 const payload_ty = func.typeOfIndex(inst);4519 const payload_ty = func.typeOfIndex(inst);
4471 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) {4520 if (!payload_ty.hasRuntimeBitsIgnoreComptime(pt)) {
4472 return func.finishAir(inst, .none, &.{ty_op.operand});4521 return func.finishAir(inst, .none, &.{ty_op.operand});
4473 }4522 }
44744523
...@@ -4476,7 +4525,7 @@ fn airOptionalPayload(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -4476,7 +4525,7 @@ fn airOptionalPayload(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
4476 const operand = try func.resolveInst(ty_op.operand);4525 const operand = try func.resolveInst(ty_op.operand);
4477 if (opt_ty.optionalReprIsPayload(mod)) break :result func.reuseOperand(ty_op.operand, operand);4526 if (opt_ty.optionalReprIsPayload(mod)) break :result func.reuseOperand(ty_op.operand, operand);
44784527
4479 if (isByRef(payload_ty, mod)) {4528 if (isByRef(payload_ty, pt)) {
4480 break :result try func.buildPointerOffset(operand, 0, .new);4529 break :result try func.buildPointerOffset(operand, 0, .new);
4481 }4530 }
44824531
...@@ -4487,14 +4536,15 @@ fn airOptionalPayload(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -4487,14 +4536,15 @@ fn airOptionalPayload(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
4487}4536}
44884537
4489fn airOptionalPayloadPtr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {4538fn airOptionalPayloadPtr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
4490 const mod = func.bin_file.base.comp.module.?;4539 const pt = func.pt;
4540 const mod = pt.zcu;
4491 const ty_op = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;4541 const ty_op = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
4492 const operand = try func.resolveInst(ty_op.operand);4542 const operand = try func.resolveInst(ty_op.operand);
4493 const opt_ty = func.typeOf(ty_op.operand).childType(mod);4543 const opt_ty = func.typeOf(ty_op.operand).childType(mod);
44944544
4495 const result = result: {4545 const result = result: {
4496 const payload_ty = opt_ty.optionalChild(mod);4546 const payload_ty = opt_ty.optionalChild(mod);
4497 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod) or opt_ty.optionalReprIsPayload(mod)) {4547 if (!payload_ty.hasRuntimeBitsIgnoreComptime(pt) or opt_ty.optionalReprIsPayload(mod)) {
4498 break :result func.reuseOperand(ty_op.operand, operand);4548 break :result func.reuseOperand(ty_op.operand, operand);
4499 }4549 }
45004550
...@@ -4504,12 +4554,13 @@ fn airOptionalPayloadPtr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -4504,12 +4554,13 @@ fn airOptionalPayloadPtr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
4504}4554}
45054555
4506fn airOptionalPayloadPtrSet(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {4556fn airOptionalPayloadPtrSet(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
4507 const mod = func.bin_file.base.comp.module.?;4557 const pt = func.pt;
4558 const mod = pt.zcu;
4508 const ty_op = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;4559 const ty_op = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
4509 const operand = try func.resolveInst(ty_op.operand);4560 const operand = try func.resolveInst(ty_op.operand);
4510 const opt_ty = func.typeOf(ty_op.operand).childType(mod);4561 const opt_ty = func.typeOf(ty_op.operand).childType(mod);
4511 const payload_ty = opt_ty.optionalChild(mod);4562 const payload_ty = opt_ty.optionalChild(mod);
4512 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) {4563 if (!payload_ty.hasRuntimeBitsIgnoreComptime(pt)) {
4513 return func.fail("TODO: Implement OptionalPayloadPtrSet for optional with zero-sized type {}", .{payload_ty.fmtDebug()});4564 return func.fail("TODO: Implement OptionalPayloadPtrSet for optional with zero-sized type {}", .{payload_ty.fmtDebug()});
4514 }4565 }
45154566
...@@ -4517,8 +4568,8 @@ fn airOptionalPayloadPtrSet(func: *CodeGen, inst: Air.Inst.Index) InnerError!voi...@@ -4517,8 +4568,8 @@ fn airOptionalPayloadPtrSet(func: *CodeGen, inst: Air.Inst.Index) InnerError!voi
4517 return func.finishAir(inst, operand, &.{ty_op.operand});4568 return func.finishAir(inst, operand, &.{ty_op.operand});
4518 }4569 }
45194570
4520 const offset = std.math.cast(u32, payload_ty.abiSize(mod)) orelse {4571 const offset = std.math.cast(u32, payload_ty.abiSize(pt)) orelse {
4521 return func.fail("Optional type {} too big to fit into stack frame", .{opt_ty.fmt(mod)});4572 return func.fail("Optional type {} too big to fit into stack frame", .{opt_ty.fmt(pt)});
4522 };4573 };
45234574
4524 try func.emitWValue(operand);4575 try func.emitWValue(operand);
...@@ -4532,10 +4583,11 @@ fn airOptionalPayloadPtrSet(func: *CodeGen, inst: Air.Inst.Index) InnerError!voi...@@ -4532,10 +4583,11 @@ fn airOptionalPayloadPtrSet(func: *CodeGen, inst: Air.Inst.Index) InnerError!voi
4532fn airWrapOptional(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {4583fn airWrapOptional(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
4533 const ty_op = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;4584 const ty_op = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
4534 const payload_ty = func.typeOf(ty_op.operand);4585 const payload_ty = func.typeOf(ty_op.operand);
4535 const mod = func.bin_file.base.comp.module.?;4586 const pt = func.pt;
4587 const mod = pt.zcu;
45364588
4537 const result = result: {4589 const result = result: {
4538 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) {4590 if (!payload_ty.hasRuntimeBitsIgnoreComptime(pt)) {
4539 const non_null_bit = try func.allocStack(Type.u1);4591 const non_null_bit = try func.allocStack(Type.u1);
4540 try func.emitWValue(non_null_bit);4592 try func.emitWValue(non_null_bit);
4541 try func.addImm32(1);4593 try func.addImm32(1);
...@@ -4548,8 +4600,8 @@ fn airWrapOptional(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -4548,8 +4600,8 @@ fn airWrapOptional(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
4548 if (op_ty.optionalReprIsPayload(mod)) {4600 if (op_ty.optionalReprIsPayload(mod)) {
4549 break :result func.reuseOperand(ty_op.operand, operand);4601 break :result func.reuseOperand(ty_op.operand, operand);
4550 }4602 }
4551 const offset = std.math.cast(u32, payload_ty.abiSize(mod)) orelse {4603 const offset = std.math.cast(u32, payload_ty.abiSize(pt)) orelse {
4552 return func.fail("Optional type {} too big to fit into stack frame", .{op_ty.fmt(mod)});4604 return func.fail("Optional type {} too big to fit into stack frame", .{op_ty.fmt(pt)});
4553 };4605 };
45544606
4555 // Create optional type, set the non-null bit, and store the operand inside the optional type4607 // Create optional type, set the non-null bit, and store the operand inside the optional type
...@@ -4589,14 +4641,15 @@ fn airSliceLen(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -4589,14 +4641,15 @@ fn airSliceLen(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
4589}4641}
45904642
4591fn airSliceElemVal(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {4643fn airSliceElemVal(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
4592 const mod = func.bin_file.base.comp.module.?;4644 const pt = func.pt;
4645 const mod = pt.zcu;
4593 const bin_op = func.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;4646 const bin_op = func.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
45944647
4595 const slice_ty = func.typeOf(bin_op.lhs);4648 const slice_ty = func.typeOf(bin_op.lhs);
4596 const slice = try func.resolveInst(bin_op.lhs);4649 const slice = try func.resolveInst(bin_op.lhs);
4597 const index = try func.resolveInst(bin_op.rhs);4650 const index = try func.resolveInst(bin_op.rhs);
4598 const elem_ty = slice_ty.childType(mod);4651 const elem_ty = slice_ty.childType(mod);
4599 const elem_size = elem_ty.abiSize(mod);4652 const elem_size = elem_ty.abiSize(pt);
46004653
4601 // load pointer onto stack4654 // load pointer onto stack
4602 _ = try func.load(slice, Type.usize, 0);4655 _ = try func.load(slice, Type.usize, 0);
...@@ -4610,7 +4663,7 @@ fn airSliceElemVal(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -4610,7 +4663,7 @@ fn airSliceElemVal(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
4610 const result_ptr = try func.allocLocal(Type.usize);4663 const result_ptr = try func.allocLocal(Type.usize);
4611 try func.addLabel(.local_set, result_ptr.local.value);4664 try func.addLabel(.local_set, result_ptr.local.value);
46124665
4613 const result = if (!isByRef(elem_ty, mod)) result: {4666 const result = if (!isByRef(elem_ty, pt)) result: {
4614 const elem_val = try func.load(result_ptr, elem_ty, 0);4667 const elem_val = try func.load(result_ptr, elem_ty, 0);
4615 break :result try elem_val.toLocal(func, elem_ty);4668 break :result try elem_val.toLocal(func, elem_ty);
4616 } else result_ptr;4669 } else result_ptr;
...@@ -4619,12 +4672,13 @@ fn airSliceElemVal(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -4619,12 +4672,13 @@ fn airSliceElemVal(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
4619}4672}
46204673
4621fn airSliceElemPtr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {4674fn airSliceElemPtr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
4622 const mod = func.bin_file.base.comp.module.?;4675 const pt = func.pt;
4676 const mod = pt.zcu;
4623 const ty_pl = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;4677 const ty_pl = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
4624 const bin_op = func.air.extraData(Air.Bin, ty_pl.payload).data;4678 const bin_op = func.air.extraData(Air.Bin, ty_pl.payload).data;
46254679
4626 const elem_ty = ty_pl.ty.toType().childType(mod);4680 const elem_ty = ty_pl.ty.toType().childType(mod);
4627 const elem_size = elem_ty.abiSize(mod);4681 const elem_size = elem_ty.abiSize(pt);
46284682
4629 const slice = try func.resolveInst(bin_op.lhs);4683 const slice = try func.resolveInst(bin_op.lhs);
4630 const index = try func.resolveInst(bin_op.rhs);4684 const index = try func.resolveInst(bin_op.rhs);
...@@ -4672,14 +4726,14 @@ fn airTrunc(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -4672,14 +4726,14 @@ fn airTrunc(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
4672/// Truncates a given operand to a given type, discarding any overflown bits.4726/// Truncates a given operand to a given type, discarding any overflown bits.
4673/// NOTE: Resulting value is left on the stack.4727/// NOTE: Resulting value is left on the stack.
4674fn trunc(func: *CodeGen, operand: WValue, wanted_ty: Type, given_ty: Type) InnerError!WValue {4728fn trunc(func: *CodeGen, operand: WValue, wanted_ty: Type, given_ty: Type) InnerError!WValue {
4675 const mod = func.bin_file.base.comp.module.?;4729 const pt = func.pt;
4676 const given_bits = @as(u16, @intCast(given_ty.bitSize(mod)));4730 const given_bits = @as(u16, @intCast(given_ty.bitSize(pt)));
4677 if (toWasmBits(given_bits) == null) {4731 if (toWasmBits(given_bits) == null) {
4678 return func.fail("TODO: Implement wasm integer truncation for integer bitsize: {d}", .{given_bits});4732 return func.fail("TODO: Implement wasm integer truncation for integer bitsize: {d}", .{given_bits});
4679 }4733 }
46804734
4681 var result = try func.intcast(operand, given_ty, wanted_ty);4735 var result = try func.intcast(operand, given_ty, wanted_ty);
4682 const wanted_bits = @as(u16, @intCast(wanted_ty.bitSize(mod)));4736 const wanted_bits = @as(u16, @intCast(wanted_ty.bitSize(pt)));
4683 const wasm_bits = toWasmBits(wanted_bits).?;4737 const wasm_bits = toWasmBits(wanted_bits).?;
4684 if (wasm_bits != wanted_bits) {4738 if (wasm_bits != wanted_bits) {
4685 result = try func.wrapOperand(result, wanted_ty);4739 result = try func.wrapOperand(result, wanted_ty);
...@@ -4696,7 +4750,8 @@ fn airIntFromBool(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -4696,7 +4750,8 @@ fn airIntFromBool(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
4696}4750}
46974751
4698fn airArrayToSlice(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {4752fn airArrayToSlice(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
4699 const mod = func.bin_file.base.comp.module.?;4753 const pt = func.pt;
4754 const mod = pt.zcu;
4700 const ty_op = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;4755 const ty_op = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
47014756
4702 const operand = try func.resolveInst(ty_op.operand);4757 const operand = try func.resolveInst(ty_op.operand);
...@@ -4707,7 +4762,7 @@ fn airArrayToSlice(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -4707,7 +4762,7 @@ fn airArrayToSlice(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
4707 const slice_local = try func.allocStack(slice_ty);4762 const slice_local = try func.allocStack(slice_ty);
47084763
4709 // store the array ptr in the slice4764 // store the array ptr in the slice
4710 if (array_ty.hasRuntimeBitsIgnoreComptime(mod)) {4765 if (array_ty.hasRuntimeBitsIgnoreComptime(pt)) {
4711 try func.store(slice_local, operand, Type.usize, 0);4766 try func.store(slice_local, operand, Type.usize, 0);
4712 }4767 }
47134768
...@@ -4719,7 +4774,8 @@ fn airArrayToSlice(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -4719,7 +4774,8 @@ fn airArrayToSlice(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
4719}4774}
47204775
4721fn airIntFromPtr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {4776fn airIntFromPtr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
4722 const mod = func.bin_file.base.comp.module.?;4777 const pt = func.pt;
4778 const mod = pt.zcu;
4723 const un_op = func.air.instructions.items(.data)[@intFromEnum(inst)].un_op;4779 const un_op = func.air.instructions.items(.data)[@intFromEnum(inst)].un_op;
4724 const operand = try func.resolveInst(un_op);4780 const operand = try func.resolveInst(un_op);
4725 const ptr_ty = func.typeOf(un_op);4781 const ptr_ty = func.typeOf(un_op);
...@@ -4734,14 +4790,15 @@ fn airIntFromPtr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -4734,14 +4790,15 @@ fn airIntFromPtr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
4734}4790}
47354791
4736fn airPtrElemVal(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {4792fn airPtrElemVal(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
4737 const mod = func.bin_file.base.comp.module.?;4793 const pt = func.pt;
4794 const mod = pt.zcu;
4738 const bin_op = func.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;4795 const bin_op = func.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
47394796
4740 const ptr_ty = func.typeOf(bin_op.lhs);4797 const ptr_ty = func.typeOf(bin_op.lhs);
4741 const ptr = try func.resolveInst(bin_op.lhs);4798 const ptr = try func.resolveInst(bin_op.lhs);
4742 const index = try func.resolveInst(bin_op.rhs);4799 const index = try func.resolveInst(bin_op.rhs);
4743 const elem_ty = ptr_ty.childType(mod);4800 const elem_ty = ptr_ty.childType(mod);
4744 const elem_size = elem_ty.abiSize(mod);4801 const elem_size = elem_ty.abiSize(pt);
47454802
4746 // load pointer onto the stack4803 // load pointer onto the stack
4747 if (ptr_ty.isSlice(mod)) {4804 if (ptr_ty.isSlice(mod)) {
...@@ -4759,7 +4816,7 @@ fn airPtrElemVal(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -4759,7 +4816,7 @@ fn airPtrElemVal(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
4759 const elem_result = val: {4816 const elem_result = val: {
4760 var result = try func.allocLocal(Type.usize);4817 var result = try func.allocLocal(Type.usize);
4761 try func.addLabel(.local_set, result.local.value);4818 try func.addLabel(.local_set, result.local.value);
4762 if (isByRef(elem_ty, mod)) {4819 if (isByRef(elem_ty, pt)) {
4763 break :val result;4820 break :val result;
4764 }4821 }
4765 defer result.free(func); // only free if it's not returned like above4822 defer result.free(func); // only free if it's not returned like above
...@@ -4771,13 +4828,14 @@ fn airPtrElemVal(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -4771,13 +4828,14 @@ fn airPtrElemVal(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
4771}4828}
47724829
4773fn airPtrElemPtr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {4830fn airPtrElemPtr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
4774 const mod = func.bin_file.base.comp.module.?;4831 const pt = func.pt;
4832 const mod = pt.zcu;
4775 const ty_pl = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;4833 const ty_pl = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
4776 const bin_op = func.air.extraData(Air.Bin, ty_pl.payload).data;4834 const bin_op = func.air.extraData(Air.Bin, ty_pl.payload).data;
47774835
4778 const ptr_ty = func.typeOf(bin_op.lhs);4836 const ptr_ty = func.typeOf(bin_op.lhs);
4779 const elem_ty = ty_pl.ty.toType().childType(mod);4837 const elem_ty = ty_pl.ty.toType().childType(mod);
4780 const elem_size = elem_ty.abiSize(mod);4838 const elem_size = elem_ty.abiSize(pt);
47814839
4782 const ptr = try func.resolveInst(bin_op.lhs);4840 const ptr = try func.resolveInst(bin_op.lhs);
4783 const index = try func.resolveInst(bin_op.rhs);4841 const index = try func.resolveInst(bin_op.rhs);
...@@ -4801,7 +4859,8 @@ fn airPtrElemPtr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -4801,7 +4859,8 @@ fn airPtrElemPtr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
4801}4859}
48024860
4803fn airPtrBinOp(func: *CodeGen, inst: Air.Inst.Index, op: Op) InnerError!void {4861fn airPtrBinOp(func: *CodeGen, inst: Air.Inst.Index, op: Op) InnerError!void {
4804 const mod = func.bin_file.base.comp.module.?;4862 const pt = func.pt;
4863 const mod = pt.zcu;
4805 const ty_pl = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;4864 const ty_pl = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
4806 const bin_op = func.air.extraData(Air.Bin, ty_pl.payload).data;4865 const bin_op = func.air.extraData(Air.Bin, ty_pl.payload).data;
48074866
...@@ -4813,13 +4872,13 @@ fn airPtrBinOp(func: *CodeGen, inst: Air.Inst.Index, op: Op) InnerError!void {...@@ -4813,13 +4872,13 @@ fn airPtrBinOp(func: *CodeGen, inst: Air.Inst.Index, op: Op) InnerError!void {
4813 else => ptr_ty.childType(mod),4872 else => ptr_ty.childType(mod),
4814 };4873 };
48154874
4816 const valtype = typeToValtype(Type.usize, mod);4875 const valtype = typeToValtype(Type.usize, pt);
4817 const mul_opcode = buildOpcode(.{ .valtype1 = valtype, .op = .mul });4876 const mul_opcode = buildOpcode(.{ .valtype1 = valtype, .op = .mul });
4818 const bin_opcode = buildOpcode(.{ .valtype1 = valtype, .op = op });4877 const bin_opcode = buildOpcode(.{ .valtype1 = valtype, .op = op });
48194878
4820 try func.lowerToStack(ptr);4879 try func.lowerToStack(ptr);
4821 try func.emitWValue(offset);4880 try func.emitWValue(offset);
4822 try func.addImm32(@intCast(pointee_ty.abiSize(mod)));4881 try func.addImm32(@intCast(pointee_ty.abiSize(pt)));
4823 try func.addTag(Mir.Inst.Tag.fromOpcode(mul_opcode));4882 try func.addTag(Mir.Inst.Tag.fromOpcode(mul_opcode));
4824 try func.addTag(Mir.Inst.Tag.fromOpcode(bin_opcode));4883 try func.addTag(Mir.Inst.Tag.fromOpcode(bin_opcode));
48254884
...@@ -4829,7 +4888,8 @@ fn airPtrBinOp(func: *CodeGen, inst: Air.Inst.Index, op: Op) InnerError!void {...@@ -4829,7 +4888,8 @@ fn airPtrBinOp(func: *CodeGen, inst: Air.Inst.Index, op: Op) InnerError!void {
4829}4888}
48304889
4831fn airMemset(func: *CodeGen, inst: Air.Inst.Index, safety: bool) InnerError!void {4890fn airMemset(func: *CodeGen, inst: Air.Inst.Index, safety: bool) InnerError!void {
4832 const mod = func.bin_file.base.comp.module.?;4891 const pt = func.pt;
4892 const mod = pt.zcu;
4833 if (safety) {4893 if (safety) {
4834 // TODO if the value is undef, write 0xaa bytes to dest4894 // TODO if the value is undef, write 0xaa bytes to dest
4835 } else {4895 } else {
...@@ -4862,8 +4922,8 @@ fn airMemset(func: *CodeGen, inst: Air.Inst.Index, safety: bool) InnerError!void...@@ -4862,8 +4922,8 @@ fn airMemset(func: *CodeGen, inst: Air.Inst.Index, safety: bool) InnerError!void
4862/// this to wasm's memset instruction. When the feature is not present,4922/// this to wasm's memset instruction. When the feature is not present,
4863/// we implement it manually.4923/// we implement it manually.
4864fn memset(func: *CodeGen, elem_ty: Type, ptr: WValue, len: WValue, value: WValue) InnerError!void {4924fn memset(func: *CodeGen, elem_ty: Type, ptr: WValue, len: WValue, value: WValue) InnerError!void {
4865 const mod = func.bin_file.base.comp.module.?;4925 const pt = func.pt;
4866 const abi_size = @as(u32, @intCast(elem_ty.abiSize(mod)));4926 const abi_size = @as(u32, @intCast(elem_ty.abiSize(pt)));
48674927
4868 // When bulk_memory is enabled, we lower it to wasm's memset instruction.4928 // When bulk_memory is enabled, we lower it to wasm's memset instruction.
4869 // If not, we lower it ourselves.4929 // If not, we lower it ourselves.
...@@ -4951,16 +5011,17 @@ fn memset(func: *CodeGen, elem_ty: Type, ptr: WValue, len: WValue, value: WValue...@@ -4951,16 +5011,17 @@ fn memset(func: *CodeGen, elem_ty: Type, ptr: WValue, len: WValue, value: WValue
4951}5011}
49525012
4953fn airArrayElemVal(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {5013fn airArrayElemVal(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
4954 const mod = func.bin_file.base.comp.module.?;5014 const pt = func.pt;
5015 const mod = pt.zcu;
4955 const bin_op = func.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;5016 const bin_op = func.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
49565017
4957 const array_ty = func.typeOf(bin_op.lhs);5018 const array_ty = func.typeOf(bin_op.lhs);
4958 const array = try func.resolveInst(bin_op.lhs);5019 const array = try func.resolveInst(bin_op.lhs);
4959 const index = try func.resolveInst(bin_op.rhs);5020 const index = try func.resolveInst(bin_op.rhs);
4960 const elem_ty = array_ty.childType(mod);5021 const elem_ty = array_ty.childType(mod);
4961 const elem_size = elem_ty.abiSize(mod);5022 const elem_size = elem_ty.abiSize(pt);
49625023
4963 if (isByRef(array_ty, mod)) {5024 if (isByRef(array_ty, pt)) {
4964 try func.lowerToStack(array);5025 try func.lowerToStack(array);
4965 try func.emitWValue(index);5026 try func.emitWValue(index);
4966 try func.addImm32(@intCast(elem_size));5027 try func.addImm32(@intCast(elem_size));
...@@ -4971,7 +5032,7 @@ fn airArrayElemVal(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -4971,7 +5032,7 @@ fn airArrayElemVal(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
49715032
4972 switch (index) {5033 switch (index) {
4973 inline .imm32, .imm64 => |lane| {5034 inline .imm32, .imm64 => |lane| {
4974 const opcode: wasm.SimdOpcode = switch (elem_ty.bitSize(mod)) {5035 const opcode: wasm.SimdOpcode = switch (elem_ty.bitSize(pt)) {
4975 8 => if (elem_ty.isSignedInt(mod)) .i8x16_extract_lane_s else .i8x16_extract_lane_u,5036 8 => if (elem_ty.isSignedInt(mod)) .i8x16_extract_lane_s else .i8x16_extract_lane_u,
4976 16 => if (elem_ty.isSignedInt(mod)) .i16x8_extract_lane_s else .i16x8_extract_lane_u,5037 16 => if (elem_ty.isSignedInt(mod)) .i16x8_extract_lane_s else .i16x8_extract_lane_u,
4977 32 => if (elem_ty.isInt(mod)) .i32x4_extract_lane else .f32x4_extract_lane,5038 32 => if (elem_ty.isInt(mod)) .i32x4_extract_lane else .f32x4_extract_lane,
...@@ -5007,7 +5068,7 @@ fn airArrayElemVal(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -5007,7 +5068,7 @@ fn airArrayElemVal(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
5007 var result = try func.allocLocal(Type.usize);5068 var result = try func.allocLocal(Type.usize);
5008 try func.addLabel(.local_set, result.local.value);5069 try func.addLabel(.local_set, result.local.value);
50095070
5010 if (isByRef(elem_ty, mod)) {5071 if (isByRef(elem_ty, pt)) {
5011 break :val result;5072 break :val result;
5012 }5073 }
5013 defer result.free(func); // only free if no longer needed and not returned like above5074 defer result.free(func); // only free if no longer needed and not returned like above
...@@ -5020,7 +5081,8 @@ fn airArrayElemVal(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -5020,7 +5081,8 @@ fn airArrayElemVal(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
5020}5081}
50215082
5022fn airIntFromFloat(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {5083fn airIntFromFloat(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
5023 const mod = func.bin_file.base.comp.module.?;5084 const pt = func.pt;
5085 const mod = pt.zcu;
5024 const ty_op = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;5086 const ty_op = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
50255087
5026 const operand = try func.resolveInst(ty_op.operand);5088 const operand = try func.resolveInst(ty_op.operand);
...@@ -5054,8 +5116,8 @@ fn airIntFromFloat(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -5054,8 +5116,8 @@ fn airIntFromFloat(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
5054 try func.emitWValue(operand);5116 try func.emitWValue(operand);
5055 const op = buildOpcode(.{5117 const op = buildOpcode(.{
5056 .op = .trunc,5118 .op = .trunc,
5057 .valtype1 = typeToValtype(dest_ty, mod),5119 .valtype1 = typeToValtype(dest_ty, pt),
5058 .valtype2 = typeToValtype(op_ty, mod),5120 .valtype2 = typeToValtype(op_ty, pt),
5059 .signedness = dest_info.signedness,5121 .signedness = dest_info.signedness,
5060 });5122 });
5061 try func.addTag(Mir.Inst.Tag.fromOpcode(op));5123 try func.addTag(Mir.Inst.Tag.fromOpcode(op));
...@@ -5065,7 +5127,8 @@ fn airIntFromFloat(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -5065,7 +5127,8 @@ fn airIntFromFloat(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
5065}5127}
50665128
5067fn airFloatFromInt(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {5129fn airFloatFromInt(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
5068 const mod = func.bin_file.base.comp.module.?;5130 const pt = func.pt;
5131 const mod = pt.zcu;
5069 const ty_op = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;5132 const ty_op = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
50705133
5071 const operand = try func.resolveInst(ty_op.operand);5134 const operand = try func.resolveInst(ty_op.operand);
...@@ -5099,8 +5162,8 @@ fn airFloatFromInt(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -5099,8 +5162,8 @@ fn airFloatFromInt(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
5099 try func.emitWValue(operand);5162 try func.emitWValue(operand);
5100 const op = buildOpcode(.{5163 const op = buildOpcode(.{
5101 .op = .convert,5164 .op = .convert,
5102 .valtype1 = typeToValtype(dest_ty, mod),5165 .valtype1 = typeToValtype(dest_ty, pt),
5103 .valtype2 = typeToValtype(op_ty, mod),5166 .valtype2 = typeToValtype(op_ty, pt),
5104 .signedness = op_info.signedness,5167 .signedness = op_info.signedness,
5105 });5168 });
5106 try func.addTag(Mir.Inst.Tag.fromOpcode(op));5169 try func.addTag(Mir.Inst.Tag.fromOpcode(op));
...@@ -5111,19 +5174,20 @@ fn airFloatFromInt(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -5111,19 +5174,20 @@ fn airFloatFromInt(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
5111}5174}
51125175
5113fn airSplat(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {5176fn airSplat(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
5114 const mod = func.bin_file.base.comp.module.?;5177 const pt = func.pt;
5178 const mod = pt.zcu;
5115 const ty_op = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;5179 const ty_op = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
5116 const operand = try func.resolveInst(ty_op.operand);5180 const operand = try func.resolveInst(ty_op.operand);
5117 const ty = func.typeOfIndex(inst);5181 const ty = func.typeOfIndex(inst);
5118 const elem_ty = ty.childType(mod);5182 const elem_ty = ty.childType(mod);
51195183
5120 if (determineSimdStoreStrategy(ty, mod) == .direct) blk: {5184 if (determineSimdStoreStrategy(ty, pt) == .direct) blk: {
5121 switch (operand) {5185 switch (operand) {
5122 // when the operand lives in the linear memory section, we can directly5186 // when the operand lives in the linear memory section, we can directly
5123 // load and splat the value at once. Meaning we do not first have to load5187 // load and splat the value at once. Meaning we do not first have to load
5124 // the scalar value onto the stack.5188 // the scalar value onto the stack.
5125 .stack_offset, .memory, .memory_offset => {5189 .stack_offset, .memory, .memory_offset => {
5126 const opcode = switch (elem_ty.bitSize(mod)) {5190 const opcode = switch (elem_ty.bitSize(pt)) {
5127 8 => std.wasm.simdOpcode(.v128_load8_splat),5191 8 => std.wasm.simdOpcode(.v128_load8_splat),
5128 16 => std.wasm.simdOpcode(.v128_load16_splat),5192 16 => std.wasm.simdOpcode(.v128_load16_splat),
5129 32 => std.wasm.simdOpcode(.v128_load32_splat),5193 32 => std.wasm.simdOpcode(.v128_load32_splat),
...@@ -5138,14 +5202,14 @@ fn airSplat(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -5138,14 +5202,14 @@ fn airSplat(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
5138 try func.mir_extra.appendSlice(func.gpa, &[_]u32{5202 try func.mir_extra.appendSlice(func.gpa, &[_]u32{
5139 opcode,5203 opcode,
5140 operand.offset(),5204 operand.offset(),
5141 @intCast(elem_ty.abiAlignment(mod).toByteUnits().?),5205 @intCast(elem_ty.abiAlignment(pt).toByteUnits().?),
5142 });5206 });
5143 try func.addInst(.{ .tag = .simd_prefix, .data = .{ .payload = extra_index } });5207 try func.addInst(.{ .tag = .simd_prefix, .data = .{ .payload = extra_index } });
5144 try func.addLabel(.local_set, result.local.value);5208 try func.addLabel(.local_set, result.local.value);
5145 return func.finishAir(inst, result, &.{ty_op.operand});5209 return func.finishAir(inst, result, &.{ty_op.operand});
5146 },5210 },
5147 .local => {5211 .local => {
5148 const opcode = switch (elem_ty.bitSize(mod)) {5212 const opcode = switch (elem_ty.bitSize(pt)) {
5149 8 => std.wasm.simdOpcode(.i8x16_splat),5213 8 => std.wasm.simdOpcode(.i8x16_splat),
5150 16 => std.wasm.simdOpcode(.i16x8_splat),5214 16 => std.wasm.simdOpcode(.i16x8_splat),
5151 32 => if (elem_ty.isInt(mod)) std.wasm.simdOpcode(.i32x4_splat) else std.wasm.simdOpcode(.f32x4_splat),5215 32 => if (elem_ty.isInt(mod)) std.wasm.simdOpcode(.i32x4_splat) else std.wasm.simdOpcode(.f32x4_splat),
...@@ -5163,14 +5227,14 @@ fn airSplat(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -5163,14 +5227,14 @@ fn airSplat(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
5163 else => unreachable,5227 else => unreachable,
5164 }5228 }
5165 }5229 }
5166 const elem_size = elem_ty.bitSize(mod);5230 const elem_size = elem_ty.bitSize(pt);
5167 const vector_len = @as(usize, @intCast(ty.vectorLen(mod)));5231 const vector_len = @as(usize, @intCast(ty.vectorLen(mod)));
5168 if ((!std.math.isPowerOfTwo(elem_size) or elem_size % 8 != 0) and vector_len > 1) {5232 if ((!std.math.isPowerOfTwo(elem_size) or elem_size % 8 != 0) and vector_len > 1) {
5169 return func.fail("TODO: WebAssembly `@splat` for arbitrary element bitsize {d}", .{elem_size});5233 return func.fail("TODO: WebAssembly `@splat` for arbitrary element bitsize {d}", .{elem_size});
5170 }5234 }
51715235
5172 const result = try func.allocStack(ty);5236 const result = try func.allocStack(ty);
5173 const elem_byte_size = @as(u32, @intCast(elem_ty.abiSize(mod)));5237 const elem_byte_size = @as(u32, @intCast(elem_ty.abiSize(pt)));
5174 var index: usize = 0;5238 var index: usize = 0;
5175 var offset: u32 = 0;5239 var offset: u32 = 0;
5176 while (index < vector_len) : (index += 1) {5240 while (index < vector_len) : (index += 1) {
...@@ -5190,7 +5254,8 @@ fn airSelect(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -5190,7 +5254,8 @@ fn airSelect(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
5190}5254}
51915255
5192fn airShuffle(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {5256fn airShuffle(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
5193 const mod = func.bin_file.base.comp.module.?;5257 const pt = func.pt;
5258 const mod = pt.zcu;
5194 const inst_ty = func.typeOfIndex(inst);5259 const inst_ty = func.typeOfIndex(inst);
5195 const ty_pl = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;5260 const ty_pl = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
5196 const extra = func.air.extraData(Air.Shuffle, ty_pl.payload).data;5261 const extra = func.air.extraData(Air.Shuffle, ty_pl.payload).data;
...@@ -5201,14 +5266,14 @@ fn airShuffle(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -5201,14 +5266,14 @@ fn airShuffle(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
5201 const mask_len = extra.mask_len;5266 const mask_len = extra.mask_len;
52025267
5203 const child_ty = inst_ty.childType(mod);5268 const child_ty = inst_ty.childType(mod);
5204 const elem_size = child_ty.abiSize(mod);5269 const elem_size = child_ty.abiSize(pt);
52055270
5206 // TODO: One of them could be by ref; handle in loop5271 // TODO: One of them could be by ref; handle in loop
5207 if (isByRef(func.typeOf(extra.a), mod) or isByRef(inst_ty, mod)) {5272 if (isByRef(func.typeOf(extra.a), pt) or isByRef(inst_ty, pt)) {
5208 const result = try func.allocStack(inst_ty);5273 const result = try func.allocStack(inst_ty);
52095274
5210 for (0..mask_len) |index| {5275 for (0..mask_len) |index| {
5211 const value = (try mask.elemValue(mod, index)).toSignedInt(mod);5276 const value = (try mask.elemValue(pt, index)).toSignedInt(pt);
52125277
5213 try func.emitWValue(result);5278 try func.emitWValue(result);
52145279
...@@ -5228,7 +5293,7 @@ fn airShuffle(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -5228,7 +5293,7 @@ fn airShuffle(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
52285293
5229 var lanes = mem.asBytes(operands[1..]);5294 var lanes = mem.asBytes(operands[1..]);
5230 for (0..@as(usize, @intCast(mask_len))) |index| {5295 for (0..@as(usize, @intCast(mask_len))) |index| {
5231 const mask_elem = (try mask.elemValue(mod, index)).toSignedInt(mod);5296 const mask_elem = (try mask.elemValue(pt, index)).toSignedInt(pt);
5232 const base_index = if (mask_elem >= 0)5297 const base_index = if (mask_elem >= 0)
5233 @as(u8, @intCast(@as(i64, @intCast(elem_size)) * mask_elem))5298 @as(u8, @intCast(@as(i64, @intCast(elem_size)) * mask_elem))
5234 else5299 else
...@@ -5259,7 +5324,8 @@ fn airReduce(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -5259,7 +5324,8 @@ fn airReduce(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
5259}5324}
52605325
5261fn airAggregateInit(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {5326fn airAggregateInit(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
5262 const mod = func.bin_file.base.comp.module.?;5327 const pt = func.pt;
5328 const mod = pt.zcu;
5263 const ip = &mod.intern_pool;5329 const ip = &mod.intern_pool;
5264 const ty_pl = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;5330 const ty_pl = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
5265 const result_ty = func.typeOfIndex(inst);5331 const result_ty = func.typeOfIndex(inst);
...@@ -5271,7 +5337,7 @@ fn airAggregateInit(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -5271,7 +5337,7 @@ fn airAggregateInit(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
5271 .Array => {5337 .Array => {
5272 const result = try func.allocStack(result_ty);5338 const result = try func.allocStack(result_ty);
5273 const elem_ty = result_ty.childType(mod);5339 const elem_ty = result_ty.childType(mod);
5274 const elem_size = @as(u32, @intCast(elem_ty.abiSize(mod)));5340 const elem_size = @as(u32, @intCast(elem_ty.abiSize(pt)));
5275 const sentinel = if (result_ty.sentinel(mod)) |sent| blk: {5341 const sentinel = if (result_ty.sentinel(mod)) |sent| blk: {
5276 break :blk try func.lowerConstant(sent, elem_ty);5342 break :blk try func.lowerConstant(sent, elem_ty);
5277 } else null;5343 } else null;
...@@ -5279,7 +5345,7 @@ fn airAggregateInit(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -5279,7 +5345,7 @@ fn airAggregateInit(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
5279 // When the element type is by reference, we must copy the entire5345 // When the element type is by reference, we must copy the entire
5280 // value. It is therefore safer to move the offset pointer and store5346 // value. It is therefore safer to move the offset pointer and store
5281 // each value individually, instead of using store offsets.5347 // each value individually, instead of using store offsets.
5282 if (isByRef(elem_ty, mod)) {5348 if (isByRef(elem_ty, pt)) {
5283 // copy stack pointer into a temporary local, which is5349 // copy stack pointer into a temporary local, which is
5284 // moved for each element to store each value in the right position.5350 // moved for each element to store each value in the right position.
5285 const offset = try func.buildPointerOffset(result, 0, .new);5351 const offset = try func.buildPointerOffset(result, 0, .new);
...@@ -5309,7 +5375,7 @@ fn airAggregateInit(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -5309,7 +5375,7 @@ fn airAggregateInit(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
5309 },5375 },
5310 .Struct => switch (result_ty.containerLayout(mod)) {5376 .Struct => switch (result_ty.containerLayout(mod)) {
5311 .@"packed" => {5377 .@"packed" => {
5312 if (isByRef(result_ty, mod)) {5378 if (isByRef(result_ty, pt)) {
5313 return func.fail("TODO: airAggregateInit for packed structs larger than 64 bits", .{});5379 return func.fail("TODO: airAggregateInit for packed structs larger than 64 bits", .{});
5314 }5380 }
5315 const packed_struct = mod.typeToPackedStruct(result_ty).?;5381 const packed_struct = mod.typeToPackedStruct(result_ty).?;
...@@ -5318,7 +5384,7 @@ fn airAggregateInit(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -5318,7 +5384,7 @@ fn airAggregateInit(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
53185384
5319 // ensure the result is zero'd5385 // ensure the result is zero'd
5320 const result = try func.allocLocal(backing_type);5386 const result = try func.allocLocal(backing_type);
5321 if (backing_type.bitSize(mod) <= 32)5387 if (backing_type.bitSize(pt) <= 32)
5322 try func.addImm32(0)5388 try func.addImm32(0)
5323 else5389 else
5324 try func.addImm64(0);5390 try func.addImm64(0);
...@@ -5327,16 +5393,16 @@ fn airAggregateInit(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -5327,16 +5393,16 @@ fn airAggregateInit(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
5327 var current_bit: u16 = 0;5393 var current_bit: u16 = 0;
5328 for (elements, 0..) |elem, elem_index| {5394 for (elements, 0..) |elem, elem_index| {
5329 const field_ty = Type.fromInterned(field_types.get(ip)[elem_index]);5395 const field_ty = Type.fromInterned(field_types.get(ip)[elem_index]);
5330 if (!field_ty.hasRuntimeBitsIgnoreComptime(mod)) continue;5396 if (!field_ty.hasRuntimeBitsIgnoreComptime(pt)) continue;
53315397
5332 const shift_val = if (backing_type.bitSize(mod) <= 32)5398 const shift_val = if (backing_type.bitSize(pt) <= 32)
5333 WValue{ .imm32 = current_bit }5399 WValue{ .imm32 = current_bit }
5334 else5400 else
5335 WValue{ .imm64 = current_bit };5401 WValue{ .imm64 = current_bit };
53365402
5337 const value = try func.resolveInst(elem);5403 const value = try func.resolveInst(elem);
5338 const value_bit_size: u16 = @intCast(field_ty.bitSize(mod));5404 const value_bit_size: u16 = @intCast(field_ty.bitSize(pt));
5339 const int_ty = try mod.intType(.unsigned, value_bit_size);5405 const int_ty = try pt.intType(.unsigned, value_bit_size);
53405406
5341 // load our current result on stack so we can perform all transformations5407 // load our current result on stack so we can perform all transformations
5342 // using only stack values. Saving the cost of loads and stores.5408 // using only stack values. Saving the cost of loads and stores.
...@@ -5359,10 +5425,10 @@ fn airAggregateInit(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -5359,10 +5425,10 @@ fn airAggregateInit(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
5359 const offset = try func.buildPointerOffset(result, 0, .new); // pointer to offset5425 const offset = try func.buildPointerOffset(result, 0, .new); // pointer to offset
5360 var prev_field_offset: u64 = 0;5426 var prev_field_offset: u64 = 0;
5361 for (elements, 0..) |elem, elem_index| {5427 for (elements, 0..) |elem, elem_index| {
5362 if ((try result_ty.structFieldValueComptime(mod, elem_index)) != null) continue;5428 if (try result_ty.structFieldValueComptime(pt, elem_index) != null) continue;
53635429
5364 const elem_ty = result_ty.structFieldType(elem_index, mod);5430 const elem_ty = result_ty.structFieldType(elem_index, mod);
5365 const field_offset = result_ty.structFieldOffset(elem_index, mod);5431 const field_offset = result_ty.structFieldOffset(elem_index, pt);
5366 _ = try func.buildPointerOffset(offset, @intCast(field_offset - prev_field_offset), .modify);5432 _ = try func.buildPointerOffset(offset, @intCast(field_offset - prev_field_offset), .modify);
5367 prev_field_offset = field_offset;5433 prev_field_offset = field_offset;
53685434
...@@ -5389,14 +5455,15 @@ fn airAggregateInit(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -5389,14 +5455,15 @@ fn airAggregateInit(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
5389}5455}
53905456
5391fn airUnionInit(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {5457fn airUnionInit(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
5392 const mod = func.bin_file.base.comp.module.?;5458 const pt = func.pt;
5459 const mod = pt.zcu;
5393 const ip = &mod.intern_pool;5460 const ip = &mod.intern_pool;
5394 const ty_pl = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;5461 const ty_pl = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
5395 const extra = func.air.extraData(Air.UnionInit, ty_pl.payload).data;5462 const extra = func.air.extraData(Air.UnionInit, ty_pl.payload).data;
53965463
5397 const result = result: {5464 const result = result: {
5398 const union_ty = func.typeOfIndex(inst);5465 const union_ty = func.typeOfIndex(inst);
5399 const layout = union_ty.unionGetLayout(mod);5466 const layout = union_ty.unionGetLayout(pt);
5400 const union_obj = mod.typeToUnion(union_ty).?;5467 const union_obj = mod.typeToUnion(union_ty).?;
5401 const field_ty = Type.fromInterned(union_obj.field_types.get(ip)[extra.field_index]);5468 const field_ty = Type.fromInterned(union_obj.field_types.get(ip)[extra.field_index]);
5402 const field_name = union_obj.loadTagType(ip).names.get(ip)[extra.field_index];5469 const field_name = union_obj.loadTagType(ip).names.get(ip)[extra.field_index];
...@@ -5404,22 +5471,22 @@ fn airUnionInit(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -5404,22 +5471,22 @@ fn airUnionInit(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
5404 const tag_int = blk: {5471 const tag_int = blk: {
5405 const tag_ty = union_ty.unionTagTypeHypothetical(mod);5472 const tag_ty = union_ty.unionTagTypeHypothetical(mod);
5406 const enum_field_index = tag_ty.enumFieldIndex(field_name, mod).?;5473 const enum_field_index = tag_ty.enumFieldIndex(field_name, mod).?;
5407 const tag_val = try mod.enumValueFieldIndex(tag_ty, enum_field_index);5474 const tag_val = try pt.enumValueFieldIndex(tag_ty, enum_field_index);
5408 break :blk try func.lowerConstant(tag_val, tag_ty);5475 break :blk try func.lowerConstant(tag_val, tag_ty);
5409 };5476 };
5410 if (layout.payload_size == 0) {5477 if (layout.payload_size == 0) {
5411 if (layout.tag_size == 0) {5478 if (layout.tag_size == 0) {
5412 break :result WValue{ .none = {} };5479 break :result WValue{ .none = {} };
5413 }5480 }
5414 assert(!isByRef(union_ty, mod));5481 assert(!isByRef(union_ty, pt));
5415 break :result tag_int;5482 break :result tag_int;
5416 }5483 }
54175484
5418 if (isByRef(union_ty, mod)) {5485 if (isByRef(union_ty, pt)) {
5419 const result_ptr = try func.allocStack(union_ty);5486 const result_ptr = try func.allocStack(union_ty);
5420 const payload = try func.resolveInst(extra.init);5487 const payload = try func.resolveInst(extra.init);
5421 if (layout.tag_align.compare(.gte, layout.payload_align)) {5488 if (layout.tag_align.compare(.gte, layout.payload_align)) {
5422 if (isByRef(field_ty, mod)) {5489 if (isByRef(field_ty, pt)) {
5423 const payload_ptr = try func.buildPointerOffset(result_ptr, layout.tag_size, .new);5490 const payload_ptr = try func.buildPointerOffset(result_ptr, layout.tag_size, .new);
5424 try func.store(payload_ptr, payload, field_ty, 0);5491 try func.store(payload_ptr, payload, field_ty, 0);
5425 } else {5492 } else {
...@@ -5443,14 +5510,14 @@ fn airUnionInit(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -5443,14 +5510,14 @@ fn airUnionInit(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
5443 break :result result_ptr;5510 break :result result_ptr;
5444 } else {5511 } else {
5445 const operand = try func.resolveInst(extra.init);5512 const operand = try func.resolveInst(extra.init);
5446 const union_int_type = try mod.intType(.unsigned, @as(u16, @intCast(union_ty.bitSize(mod))));5513 const union_int_type = try pt.intType(.unsigned, @as(u16, @intCast(union_ty.bitSize(pt))));
5447 if (field_ty.zigTypeTag(mod) == .Float) {5514 if (field_ty.zigTypeTag(mod) == .Float) {
5448 const int_type = try mod.intType(.unsigned, @intCast(field_ty.bitSize(mod)));5515 const int_type = try pt.intType(.unsigned, @intCast(field_ty.bitSize(pt)));
5449 const bitcasted = try func.bitcast(field_ty, int_type, operand);5516 const bitcasted = try func.bitcast(field_ty, int_type, operand);
5450 const casted = try func.trunc(bitcasted, int_type, union_int_type);5517 const casted = try func.trunc(bitcasted, int_type, union_int_type);
5451 break :result try casted.toLocal(func, field_ty);5518 break :result try casted.toLocal(func, field_ty);
5452 } else if (field_ty.isPtrAtRuntime(mod)) {5519 } else if (field_ty.isPtrAtRuntime(mod)) {
5453 const int_type = try mod.intType(.unsigned, @intCast(field_ty.bitSize(mod)));5520 const int_type = try pt.intType(.unsigned, @intCast(field_ty.bitSize(pt)));
5454 const casted = try func.intcast(operand, int_type, union_int_type);5521 const casted = try func.intcast(operand, int_type, union_int_type);
5455 break :result try casted.toLocal(func, field_ty);5522 break :result try casted.toLocal(func, field_ty);
5456 }5523 }
...@@ -5488,8 +5555,9 @@ fn airWasmMemoryGrow(func: *CodeGen, inst: Air.Inst.Index) !void {...@@ -5488,8 +5555,9 @@ fn airWasmMemoryGrow(func: *CodeGen, inst: Air.Inst.Index) !void {
5488}5555}
54895556
5490fn cmpOptionals(func: *CodeGen, lhs: WValue, rhs: WValue, operand_ty: Type, op: std.math.CompareOperator) InnerError!WValue {5557fn cmpOptionals(func: *CodeGen, lhs: WValue, rhs: WValue, operand_ty: Type, op: std.math.CompareOperator) InnerError!WValue {
5491 const mod = func.bin_file.base.comp.module.?;5558 const pt = func.pt;
5492 assert(operand_ty.hasRuntimeBitsIgnoreComptime(mod));5559 const mod = pt.zcu;
5560 assert(operand_ty.hasRuntimeBitsIgnoreComptime(pt));
5493 assert(op == .eq or op == .neq);5561 assert(op == .eq or op == .neq);
5494 const payload_ty = operand_ty.optionalChild(mod);5562 const payload_ty = operand_ty.optionalChild(mod);
54955563
...@@ -5506,7 +5574,7 @@ fn cmpOptionals(func: *CodeGen, lhs: WValue, rhs: WValue, operand_ty: Type, op:...@@ -5506,7 +5574,7 @@ fn cmpOptionals(func: *CodeGen, lhs: WValue, rhs: WValue, operand_ty: Type, op:
55065574
5507 _ = try func.load(lhs, payload_ty, 0);5575 _ = try func.load(lhs, payload_ty, 0);
5508 _ = try func.load(rhs, payload_ty, 0);5576 _ = try func.load(rhs, payload_ty, 0);
5509 const opcode = buildOpcode(.{ .op = .ne, .valtype1 = typeToValtype(payload_ty, mod) });5577 const opcode = buildOpcode(.{ .op = .ne, .valtype1 = typeToValtype(payload_ty, pt) });
5510 try func.addTag(Mir.Inst.Tag.fromOpcode(opcode));5578 try func.addTag(Mir.Inst.Tag.fromOpcode(opcode));
5511 try func.addLabel(.br_if, 0);5579 try func.addLabel(.br_if, 0);
55125580
...@@ -5524,11 +5592,12 @@ fn cmpOptionals(func: *CodeGen, lhs: WValue, rhs: WValue, operand_ty: Type, op:...@@ -5524,11 +5592,12 @@ fn cmpOptionals(func: *CodeGen, lhs: WValue, rhs: WValue, operand_ty: Type, op:
5524/// NOTE: Leaves the result of the comparison on top of the stack.5592/// NOTE: Leaves the result of the comparison on top of the stack.
5525/// TODO: Lower this to compiler_rt call when bitsize > 1285593/// TODO: Lower this to compiler_rt call when bitsize > 128
5526fn cmpBigInt(func: *CodeGen, lhs: WValue, rhs: WValue, operand_ty: Type, op: std.math.CompareOperator) InnerError!WValue {5594fn cmpBigInt(func: *CodeGen, lhs: WValue, rhs: WValue, operand_ty: Type, op: std.math.CompareOperator) InnerError!WValue {
5527 const mod = func.bin_file.base.comp.module.?;5595 const pt = func.pt;
5528 assert(operand_ty.abiSize(mod) >= 16);5596 const mod = pt.zcu;
5597 assert(operand_ty.abiSize(pt) >= 16);
5529 assert(!(lhs != .stack and rhs == .stack));5598 assert(!(lhs != .stack and rhs == .stack));
5530 if (operand_ty.bitSize(mod) > 128) {5599 if (operand_ty.bitSize(pt) > 128) {
5531 return func.fail("TODO: Support cmpBigInt for integer bitsize: '{d}'", .{operand_ty.bitSize(mod)});5600 return func.fail("TODO: Support cmpBigInt for integer bitsize: '{d}'", .{operand_ty.bitSize(pt)});
5532 }5601 }
55335602
5534 var lhs_high_bit = try (try func.load(lhs, Type.u64, 0)).toLocal(func, Type.u64);5603 var lhs_high_bit = try (try func.load(lhs, Type.u64, 0)).toLocal(func, Type.u64);
...@@ -5566,11 +5635,12 @@ fn cmpBigInt(func: *CodeGen, lhs: WValue, rhs: WValue, operand_ty: Type, op: std...@@ -5566,11 +5635,12 @@ fn cmpBigInt(func: *CodeGen, lhs: WValue, rhs: WValue, operand_ty: Type, op: std
5566}5635}
55675636
5568fn airSetUnionTag(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {5637fn airSetUnionTag(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
5569 const mod = func.bin_file.base.comp.module.?;5638 const pt = func.pt;
5639 const mod = pt.zcu;
5570 const bin_op = func.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;5640 const bin_op = func.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
5571 const un_ty = func.typeOf(bin_op.lhs).childType(mod);5641 const un_ty = func.typeOf(bin_op.lhs).childType(mod);
5572 const tag_ty = func.typeOf(bin_op.rhs);5642 const tag_ty = func.typeOf(bin_op.rhs);
5573 const layout = un_ty.unionGetLayout(mod);5643 const layout = un_ty.unionGetLayout(pt);
5574 if (layout.tag_size == 0) return func.finishAir(inst, .none, &.{ bin_op.lhs, bin_op.rhs });5644 if (layout.tag_size == 0) return func.finishAir(inst, .none, &.{ bin_op.lhs, bin_op.rhs });
55755645
5576 const union_ptr = try func.resolveInst(bin_op.lhs);5646 const union_ptr = try func.resolveInst(bin_op.lhs);
...@@ -5590,12 +5660,12 @@ fn airSetUnionTag(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -5590,12 +5660,12 @@ fn airSetUnionTag(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
5590}5660}
55915661
5592fn airGetUnionTag(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {5662fn airGetUnionTag(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
5593 const mod = func.bin_file.base.comp.module.?;5663 const pt = func.pt;
5594 const ty_op = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;5664 const ty_op = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
55955665
5596 const un_ty = func.typeOf(ty_op.operand);5666 const un_ty = func.typeOf(ty_op.operand);
5597 const tag_ty = func.typeOfIndex(inst);5667 const tag_ty = func.typeOfIndex(inst);
5598 const layout = un_ty.unionGetLayout(mod);5668 const layout = un_ty.unionGetLayout(pt);
5599 if (layout.tag_size == 0) return func.finishAir(inst, .none, &.{ty_op.operand});5669 if (layout.tag_size == 0) return func.finishAir(inst, .none, &.{ty_op.operand});
56005670
5601 const operand = try func.resolveInst(ty_op.operand);5671 const operand = try func.resolveInst(ty_op.operand);
...@@ -5695,7 +5765,8 @@ fn fptrunc(func: *CodeGen, operand: WValue, given: Type, wanted: Type) InnerErro...@@ -5695,7 +5765,8 @@ fn fptrunc(func: *CodeGen, operand: WValue, given: Type, wanted: Type) InnerErro
5695}5765}
56965766
5697fn airErrUnionPayloadPtrSet(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {5767fn airErrUnionPayloadPtrSet(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
5698 const mod = func.bin_file.base.comp.module.?;5768 const pt = func.pt;
5769 const mod = pt.zcu;
5699 const ty_op = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;5770 const ty_op = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
57005771
5701 const err_set_ty = func.typeOf(ty_op.operand).childType(mod);5772 const err_set_ty = func.typeOf(ty_op.operand).childType(mod);
...@@ -5707,27 +5778,28 @@ fn airErrUnionPayloadPtrSet(func: *CodeGen, inst: Air.Inst.Index) InnerError!voi...@@ -5707,27 +5778,28 @@ fn airErrUnionPayloadPtrSet(func: *CodeGen, inst: Air.Inst.Index) InnerError!voi
5707 operand,5778 operand,
5708 .{ .imm32 = 0 },5779 .{ .imm32 = 0 },
5709 Type.anyerror,5780 Type.anyerror,
5710 @as(u32, @intCast(errUnionErrorOffset(payload_ty, mod))),5781 @intCast(errUnionErrorOffset(payload_ty, pt)),
5711 );5782 );
57125783
5713 const result = result: {5784 const result = result: {
5714 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) {5785 if (!payload_ty.hasRuntimeBitsIgnoreComptime(pt)) {
5715 break :result func.reuseOperand(ty_op.operand, operand);5786 break :result func.reuseOperand(ty_op.operand, operand);
5716 }5787 }
57175788
5718 break :result try func.buildPointerOffset(operand, @as(u32, @intCast(errUnionPayloadOffset(payload_ty, mod))), .new);5789 break :result try func.buildPointerOffset(operand, @as(u32, @intCast(errUnionPayloadOffset(payload_ty, pt))), .new);
5719 };5790 };
5720 func.finishAir(inst, result, &.{ty_op.operand});5791 func.finishAir(inst, result, &.{ty_op.operand});
5721}5792}
57225793
5723fn airFieldParentPtr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {5794fn airFieldParentPtr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
5724 const mod = func.bin_file.base.comp.module.?;5795 const pt = func.pt;
5796 const mod = pt.zcu;
5725 const ty_pl = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;5797 const ty_pl = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
5726 const extra = func.air.extraData(Air.FieldParentPtr, ty_pl.payload).data;5798 const extra = func.air.extraData(Air.FieldParentPtr, ty_pl.payload).data;
57275799
5728 const field_ptr = try func.resolveInst(extra.field_ptr);5800 const field_ptr = try func.resolveInst(extra.field_ptr);
5729 const parent_ty = ty_pl.ty.toType().childType(mod);5801 const parent_ty = ty_pl.ty.toType().childType(mod);
5730 const field_offset = parent_ty.structFieldOffset(extra.field_index, mod);5802 const field_offset = parent_ty.structFieldOffset(extra.field_index, pt);
57315803
5732 const result = if (field_offset != 0) result: {5804 const result = if (field_offset != 0) result: {
5733 const base = try func.buildPointerOffset(field_ptr, 0, .new);5805 const base = try func.buildPointerOffset(field_ptr, 0, .new);
...@@ -5742,7 +5814,8 @@ fn airFieldParentPtr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -5742,7 +5814,8 @@ fn airFieldParentPtr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
5742}5814}
57435815
5744fn sliceOrArrayPtr(func: *CodeGen, ptr: WValue, ptr_ty: Type) InnerError!WValue {5816fn sliceOrArrayPtr(func: *CodeGen, ptr: WValue, ptr_ty: Type) InnerError!WValue {
5745 const mod = func.bin_file.base.comp.module.?;5817 const pt = func.pt;
5818 const mod = pt.zcu;
5746 if (ptr_ty.isSlice(mod)) {5819 if (ptr_ty.isSlice(mod)) {
5747 return func.slicePtr(ptr);5820 return func.slicePtr(ptr);
5748 } else {5821 } else {
...@@ -5751,7 +5824,8 @@ fn sliceOrArrayPtr(func: *CodeGen, ptr: WValue, ptr_ty: Type) InnerError!WValue...@@ -5751,7 +5824,8 @@ fn sliceOrArrayPtr(func: *CodeGen, ptr: WValue, ptr_ty: Type) InnerError!WValue
5751}5824}
57525825
5753fn airMemcpy(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {5826fn airMemcpy(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
5754 const mod = func.bin_file.base.comp.module.?;5827 const pt = func.pt;
5828 const mod = pt.zcu;
5755 const bin_op = func.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;5829 const bin_op = func.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
5756 const dst = try func.resolveInst(bin_op.lhs);5830 const dst = try func.resolveInst(bin_op.lhs);
5757 const dst_ty = func.typeOf(bin_op.lhs);5831 const dst_ty = func.typeOf(bin_op.lhs);
...@@ -5761,16 +5835,16 @@ fn airMemcpy(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -5761,16 +5835,16 @@ fn airMemcpy(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
5761 const len = switch (dst_ty.ptrSize(mod)) {5835 const len = switch (dst_ty.ptrSize(mod)) {
5762 .Slice => blk: {5836 .Slice => blk: {
5763 const slice_len = try func.sliceLen(dst);5837 const slice_len = try func.sliceLen(dst);
5764 if (ptr_elem_ty.abiSize(mod) != 1) {5838 if (ptr_elem_ty.abiSize(pt) != 1) {
5765 try func.emitWValue(slice_len);5839 try func.emitWValue(slice_len);
5766 try func.emitWValue(.{ .imm32 = @as(u32, @intCast(ptr_elem_ty.abiSize(mod))) });5840 try func.emitWValue(.{ .imm32 = @as(u32, @intCast(ptr_elem_ty.abiSize(pt))) });
5767 try func.addTag(.i32_mul);5841 try func.addTag(.i32_mul);
5768 try func.addLabel(.local_set, slice_len.local.value);5842 try func.addLabel(.local_set, slice_len.local.value);
5769 }5843 }
5770 break :blk slice_len;5844 break :blk slice_len;
5771 },5845 },
5772 .One => @as(WValue, .{5846 .One => @as(WValue, .{
5773 .imm32 = @as(u32, @intCast(ptr_elem_ty.arrayLen(mod) * ptr_elem_ty.childType(mod).abiSize(mod))),5847 .imm32 = @as(u32, @intCast(ptr_elem_ty.arrayLen(mod) * ptr_elem_ty.childType(mod).abiSize(pt))),
5774 }),5848 }),
5775 .C, .Many => unreachable,5849 .C, .Many => unreachable,
5776 };5850 };
...@@ -5791,7 +5865,8 @@ fn airRetAddr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -5791,7 +5865,8 @@ fn airRetAddr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
5791}5865}
57925866
5793fn airPopcount(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {5867fn airPopcount(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
5794 const mod = func.bin_file.base.comp.module.?;5868 const pt = func.pt;
5869 const mod = pt.zcu;
5795 const ty_op = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;5870 const ty_op = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
57965871
5797 const operand = try func.resolveInst(ty_op.operand);5872 const operand = try func.resolveInst(ty_op.operand);
...@@ -5812,14 +5887,14 @@ fn airPopcount(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -5812,14 +5887,14 @@ fn airPopcount(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
5812 32 => {5887 32 => {
5813 try func.emitWValue(operand);5888 try func.emitWValue(operand);
5814 if (op_ty.isSignedInt(mod) and bits != wasm_bits) {5889 if (op_ty.isSignedInt(mod) and bits != wasm_bits) {
5815 _ = try func.wrapOperand(.stack, try mod.intType(.unsigned, bits));5890 _ = try func.wrapOperand(.stack, try pt.intType(.unsigned, bits));
5816 }5891 }
5817 try func.addTag(.i32_popcnt);5892 try func.addTag(.i32_popcnt);
5818 },5893 },
5819 64 => {5894 64 => {
5820 try func.emitWValue(operand);5895 try func.emitWValue(operand);
5821 if (op_ty.isSignedInt(mod) and bits != wasm_bits) {5896 if (op_ty.isSignedInt(mod) and bits != wasm_bits) {
5822 _ = try func.wrapOperand(.stack, try mod.intType(.unsigned, bits));5897 _ = try func.wrapOperand(.stack, try pt.intType(.unsigned, bits));
5823 }5898 }
5824 try func.addTag(.i64_popcnt);5899 try func.addTag(.i64_popcnt);
5825 try func.addTag(.i32_wrap_i64);5900 try func.addTag(.i32_wrap_i64);
...@@ -5830,7 +5905,7 @@ fn airPopcount(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -5830,7 +5905,7 @@ fn airPopcount(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
5830 try func.addTag(.i64_popcnt);5905 try func.addTag(.i64_popcnt);
5831 _ = try func.load(operand, Type.u64, 8);5906 _ = try func.load(operand, Type.u64, 8);
5832 if (op_ty.isSignedInt(mod) and bits != wasm_bits) {5907 if (op_ty.isSignedInt(mod) and bits != wasm_bits) {
5833 _ = try func.wrapOperand(.stack, try mod.intType(.unsigned, bits - 64));5908 _ = try func.wrapOperand(.stack, try pt.intType(.unsigned, bits - 64));
5834 }5909 }
5835 try func.addTag(.i64_popcnt);5910 try func.addTag(.i64_popcnt);
5836 try func.addTag(.i64_add);5911 try func.addTag(.i64_add);
...@@ -5845,7 +5920,8 @@ fn airPopcount(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -5845,7 +5920,8 @@ fn airPopcount(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
5845}5920}
58465921
5847fn airBitReverse(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {5922fn airBitReverse(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
5848 const mod = func.bin_file.base.comp.module.?;5923 const pt = func.pt;
5924 const mod = pt.zcu;
5849 const ty_op = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;5925 const ty_op = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
58505926
5851 const operand = try func.resolveInst(ty_op.operand);5927 const operand = try func.resolveInst(ty_op.operand);
...@@ -5956,10 +6032,10 @@ fn airErrorName(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -5956,10 +6032,10 @@ fn airErrorName(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
5956 //6032 //
5957 // As the names are global and the slice elements are constant, we do not have6033 // As the names are global and the slice elements are constant, we do not have
5958 // to make a copy of the ptr+value but can point towards them directly.6034 // to make a copy of the ptr+value but can point towards them directly.
5959 const error_table_symbol = try func.bin_file.getErrorTableSymbol();6035 const pt = func.pt;
6036 const error_table_symbol = try func.bin_file.getErrorTableSymbol(pt);
5960 const name_ty = Type.slice_const_u8_sentinel_0;6037 const name_ty = Type.slice_const_u8_sentinel_0;
5961 const mod = func.bin_file.base.comp.module.?;6038 const abi_size = name_ty.abiSize(pt);
5962 const abi_size = name_ty.abiSize(mod);
59636039
5964 const error_name_value: WValue = .{ .memory = error_table_symbol }; // emitting this will create a relocation6040 const error_name_value: WValue = .{ .memory = error_table_symbol }; // emitting this will create a relocation
5965 try func.emitWValue(error_name_value);6041 try func.emitWValue(error_name_value);
...@@ -5998,7 +6074,8 @@ fn airAddSubWithOverflow(func: *CodeGen, inst: Air.Inst.Index, op: Op) InnerErro...@@ -5998,7 +6074,8 @@ fn airAddSubWithOverflow(func: *CodeGen, inst: Air.Inst.Index, op: Op) InnerErro
5998 const lhs = try func.resolveInst(extra.lhs);6074 const lhs = try func.resolveInst(extra.lhs);
5999 const rhs = try func.resolveInst(extra.rhs);6075 const rhs = try func.resolveInst(extra.rhs);
6000 const lhs_ty = func.typeOf(extra.lhs);6076 const lhs_ty = func.typeOf(extra.lhs);
6001 const mod = func.bin_file.base.comp.module.?;6077 const pt = func.pt;
6078 const mod = pt.zcu;
60026079
6003 if (lhs_ty.zigTypeTag(mod) == .Vector) {6080 if (lhs_ty.zigTypeTag(mod) == .Vector) {
6004 return func.fail("TODO: Implement overflow arithmetic for vectors", .{});6081 return func.fail("TODO: Implement overflow arithmetic for vectors", .{});
...@@ -6044,14 +6121,15 @@ fn airAddSubWithOverflow(func: *CodeGen, inst: Air.Inst.Index, op: Op) InnerErro...@@ -6044,14 +6121,15 @@ fn airAddSubWithOverflow(func: *CodeGen, inst: Air.Inst.Index, op: Op) InnerErro
60446121
6045 const result_ptr = try func.allocStack(func.typeOfIndex(inst));6122 const result_ptr = try func.allocStack(func.typeOfIndex(inst));
6046 try func.store(result_ptr, result, lhs_ty, 0);6123 try func.store(result_ptr, result, lhs_ty, 0);
6047 const offset = @as(u32, @intCast(lhs_ty.abiSize(mod)));6124 const offset = @as(u32, @intCast(lhs_ty.abiSize(pt)));
6048 try func.store(result_ptr, overflow_local, Type.u1, offset);6125 try func.store(result_ptr, overflow_local, Type.u1, offset);
60496126
6050 func.finishAir(inst, result_ptr, &.{ extra.lhs, extra.rhs });6127 func.finishAir(inst, result_ptr, &.{ extra.lhs, extra.rhs });
6051}6128}
60526129
6053fn addSubWithOverflowBigInt(func: *CodeGen, lhs: WValue, rhs: WValue, ty: Type, result_ty: Type, op: Op) InnerError!WValue {6130fn addSubWithOverflowBigInt(func: *CodeGen, lhs: WValue, rhs: WValue, ty: Type, result_ty: Type, op: Op) InnerError!WValue {
6054 const mod = func.bin_file.base.comp.module.?;6131 const pt = func.pt;
6132 const mod = pt.zcu;
6055 assert(op == .add or op == .sub);6133 assert(op == .add or op == .sub);
6056 const int_info = ty.intInfo(mod);6134 const int_info = ty.intInfo(mod);
6057 const is_signed = int_info.signedness == .signed;6135 const is_signed = int_info.signedness == .signed;
...@@ -6116,7 +6194,8 @@ fn addSubWithOverflowBigInt(func: *CodeGen, lhs: WValue, rhs: WValue, ty: Type,...@@ -6116,7 +6194,8 @@ fn addSubWithOverflowBigInt(func: *CodeGen, lhs: WValue, rhs: WValue, ty: Type,
6116}6194}
61176195
6118fn airShlWithOverflow(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {6196fn airShlWithOverflow(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
6119 const mod = func.bin_file.base.comp.module.?;6197 const pt = func.pt;
6198 const mod = pt.zcu;
6120 const ty_pl = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;6199 const ty_pl = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
6121 const extra = func.air.extraData(Air.Bin, ty_pl.payload).data;6200 const extra = func.air.extraData(Air.Bin, ty_pl.payload).data;
61226201
...@@ -6159,7 +6238,7 @@ fn airShlWithOverflow(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -6159,7 +6238,7 @@ fn airShlWithOverflow(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
61596238
6160 const result_ptr = try func.allocStack(func.typeOfIndex(inst));6239 const result_ptr = try func.allocStack(func.typeOfIndex(inst));
6161 try func.store(result_ptr, result, lhs_ty, 0);6240 try func.store(result_ptr, result, lhs_ty, 0);
6162 const offset = @as(u32, @intCast(lhs_ty.abiSize(mod)));6241 const offset = @as(u32, @intCast(lhs_ty.abiSize(pt)));
6163 try func.store(result_ptr, overflow_local, Type.u1, offset);6242 try func.store(result_ptr, overflow_local, Type.u1, offset);
61646243
6165 func.finishAir(inst, result_ptr, &.{ extra.lhs, extra.rhs });6244 func.finishAir(inst, result_ptr, &.{ extra.lhs, extra.rhs });
...@@ -6172,7 +6251,8 @@ fn airMulWithOverflow(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -6172,7 +6251,8 @@ fn airMulWithOverflow(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
6172 const lhs = try func.resolveInst(extra.lhs);6251 const lhs = try func.resolveInst(extra.lhs);
6173 const rhs = try func.resolveInst(extra.rhs);6252 const rhs = try func.resolveInst(extra.rhs);
6174 const lhs_ty = func.typeOf(extra.lhs);6253 const lhs_ty = func.typeOf(extra.lhs);
6175 const mod = func.bin_file.base.comp.module.?;6254 const pt = func.pt;
6255 const mod = pt.zcu;
61766256
6177 if (lhs_ty.zigTypeTag(mod) == .Vector) {6257 if (lhs_ty.zigTypeTag(mod) == .Vector) {
6178 return func.fail("TODO: Implement overflow arithmetic for vectors", .{});6258 return func.fail("TODO: Implement overflow arithmetic for vectors", .{});
...@@ -6332,7 +6412,7 @@ fn airMulWithOverflow(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -6332,7 +6412,7 @@ fn airMulWithOverflow(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
63326412
6333 const result_ptr = try func.allocStack(func.typeOfIndex(inst));6413 const result_ptr = try func.allocStack(func.typeOfIndex(inst));
6334 try func.store(result_ptr, bin_op_local, lhs_ty, 0);6414 try func.store(result_ptr, bin_op_local, lhs_ty, 0);
6335 const offset = @as(u32, @intCast(lhs_ty.abiSize(mod)));6415 const offset = @as(u32, @intCast(lhs_ty.abiSize(pt)));
6336 try func.store(result_ptr, overflow_bit, Type.u1, offset);6416 try func.store(result_ptr, overflow_bit, Type.u1, offset);
63376417
6338 func.finishAir(inst, result_ptr, &.{ extra.lhs, extra.rhs });6418 func.finishAir(inst, result_ptr, &.{ extra.lhs, extra.rhs });
...@@ -6340,7 +6420,8 @@ fn airMulWithOverflow(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -6340,7 +6420,8 @@ fn airMulWithOverflow(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
63406420
6341fn airMaxMin(func: *CodeGen, inst: Air.Inst.Index, op: Op) InnerError!void {6421fn airMaxMin(func: *CodeGen, inst: Air.Inst.Index, op: Op) InnerError!void {
6342 assert(op == .max or op == .min);6422 assert(op == .max or op == .min);
6343 const mod = func.bin_file.base.comp.module.?;6423 const pt = func.pt;
6424 const mod = pt.zcu;
6344 const target = mod.getTarget();6425 const target = mod.getTarget();
6345 const bin_op = func.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;6426 const bin_op = func.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
63466427
...@@ -6349,7 +6430,7 @@ fn airMaxMin(func: *CodeGen, inst: Air.Inst.Index, op: Op) InnerError!void {...@@ -6349,7 +6430,7 @@ fn airMaxMin(func: *CodeGen, inst: Air.Inst.Index, op: Op) InnerError!void {
6349 return func.fail("TODO: `@maximum` and `@minimum` for vectors", .{});6430 return func.fail("TODO: `@maximum` and `@minimum` for vectors", .{});
6350 }6431 }
63516432
6352 if (ty.abiSize(mod) > 16) {6433 if (ty.abiSize(pt) > 16) {
6353 return func.fail("TODO: `@maximum` and `@minimum` for types larger than 16 bytes", .{});6434 return func.fail("TODO: `@maximum` and `@minimum` for types larger than 16 bytes", .{});
6354 }6435 }
63556436
...@@ -6377,14 +6458,15 @@ fn airMaxMin(func: *CodeGen, inst: Air.Inst.Index, op: Op) InnerError!void {...@@ -6377,14 +6458,15 @@ fn airMaxMin(func: *CodeGen, inst: Air.Inst.Index, op: Op) InnerError!void {
6377 }6458 }
63786459
6379 // store result in local6460 // store result in local
6380 const result_ty = if (isByRef(ty, mod)) Type.u32 else ty;6461 const result_ty = if (isByRef(ty, pt)) Type.u32 else ty;
6381 const result = try func.allocLocal(result_ty);6462 const result = try func.allocLocal(result_ty);
6382 try func.addLabel(.local_set, result.local.value);6463 try func.addLabel(.local_set, result.local.value);
6383 func.finishAir(inst, result, &.{ bin_op.lhs, bin_op.rhs });6464 func.finishAir(inst, result, &.{ bin_op.lhs, bin_op.rhs });
6384}6465}
63856466
6386fn airMulAdd(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {6467fn airMulAdd(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
6387 const mod = func.bin_file.base.comp.module.?;6468 const pt = func.pt;
6469 const mod = pt.zcu;
6388 const pl_op = func.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;6470 const pl_op = func.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;
6389 const bin_op = func.air.extraData(Air.Bin, pl_op.payload).data;6471 const bin_op = func.air.extraData(Air.Bin, pl_op.payload).data;
63906472
...@@ -6418,7 +6500,8 @@ fn airMulAdd(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -6418,7 +6500,8 @@ fn airMulAdd(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
6418}6500}
64196501
6420fn airClz(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {6502fn airClz(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
6421 const mod = func.bin_file.base.comp.module.?;6503 const pt = func.pt;
6504 const mod = pt.zcu;
6422 const ty_op = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;6505 const ty_op = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
64236506
6424 const ty = func.typeOf(ty_op.operand);6507 const ty = func.typeOf(ty_op.operand);
...@@ -6471,7 +6554,8 @@ fn airClz(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -6471,7 +6554,8 @@ fn airClz(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
6471}6554}
64726555
6473fn airCtz(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {6556fn airCtz(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
6474 const mod = func.bin_file.base.comp.module.?;6557 const pt = func.pt;
6558 const mod = pt.zcu;
6475 const ty_op = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;6559 const ty_op = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
64766560
6477 const ty = func.typeOf(ty_op.operand);6561 const ty = func.typeOf(ty_op.operand);
...@@ -6558,7 +6642,8 @@ fn airDbgInlineBlock(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -6558,7 +6642,8 @@ fn airDbgInlineBlock(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
6558fn airDbgVar(func: *CodeGen, inst: Air.Inst.Index, is_ptr: bool) InnerError!void {6642fn airDbgVar(func: *CodeGen, inst: Air.Inst.Index, is_ptr: bool) InnerError!void {
6559 if (func.debug_output != .dwarf) return func.finishAir(inst, .none, &.{});6643 if (func.debug_output != .dwarf) return func.finishAir(inst, .none, &.{});
65606644
6561 const mod = func.bin_file.base.comp.module.?;6645 const pt = func.pt;
6646 const mod = pt.zcu;
6562 const pl_op = func.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;6647 const pl_op = func.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;
6563 const ty = func.typeOf(pl_op.operand);6648 const ty = func.typeOf(pl_op.operand);
6564 const operand = try func.resolveInst(pl_op.operand);6649 const operand = try func.resolveInst(pl_op.operand);
...@@ -6591,7 +6676,8 @@ fn airTry(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -6591,7 +6676,8 @@ fn airTry(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
6591}6676}
65926677
6593fn airTryPtr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {6678fn airTryPtr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
6594 const mod = func.bin_file.base.comp.module.?;6679 const pt = func.pt;
6680 const mod = pt.zcu;
6595 const ty_pl = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;6681 const ty_pl = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
6596 const extra = func.air.extraData(Air.TryPtr, ty_pl.payload);6682 const extra = func.air.extraData(Air.TryPtr, ty_pl.payload);
6597 const err_union_ptr = try func.resolveInst(extra.data.ptr);6683 const err_union_ptr = try func.resolveInst(extra.data.ptr);
...@@ -6609,13 +6695,14 @@ fn lowerTry(...@@ -6609,13 +6695,14 @@ fn lowerTry(
6609 err_union_ty: Type,6695 err_union_ty: Type,
6610 operand_is_ptr: bool,6696 operand_is_ptr: bool,
6611) InnerError!WValue {6697) InnerError!WValue {
6612 const mod = func.bin_file.base.comp.module.?;6698 const pt = func.pt;
6699 const mod = pt.zcu;
6613 if (operand_is_ptr) {6700 if (operand_is_ptr) {
6614 return func.fail("TODO: lowerTry for pointers", .{});6701 return func.fail("TODO: lowerTry for pointers", .{});
6615 }6702 }
66166703
6617 const pl_ty = err_union_ty.errorUnionPayload(mod);6704 const pl_ty = err_union_ty.errorUnionPayload(mod);
6618 const pl_has_bits = pl_ty.hasRuntimeBitsIgnoreComptime(mod);6705 const pl_has_bits = pl_ty.hasRuntimeBitsIgnoreComptime(pt);
66196706
6620 if (!err_union_ty.errorUnionSet(mod).errorSetIsEmpty(mod)) {6707 if (!err_union_ty.errorUnionSet(mod).errorSetIsEmpty(mod)) {
6621 // Block we can jump out of when error is not set6708 // Block we can jump out of when error is not set
...@@ -6624,10 +6711,10 @@ fn lowerTry(...@@ -6624,10 +6711,10 @@ fn lowerTry(
6624 // check if the error tag is set for the error union.6711 // check if the error tag is set for the error union.
6625 try func.emitWValue(err_union);6712 try func.emitWValue(err_union);
6626 if (pl_has_bits) {6713 if (pl_has_bits) {
6627 const err_offset = @as(u32, @intCast(errUnionErrorOffset(pl_ty, mod)));6714 const err_offset: u32 = @intCast(errUnionErrorOffset(pl_ty, pt));
6628 try func.addMemArg(.i32_load16_u, .{6715 try func.addMemArg(.i32_load16_u, .{
6629 .offset = err_union.offset() + err_offset,6716 .offset = err_union.offset() + err_offset,
6630 .alignment = @intCast(Type.anyerror.abiAlignment(mod).toByteUnits().?),6717 .alignment = @intCast(Type.anyerror.abiAlignment(pt).toByteUnits().?),
6631 });6718 });
6632 }6719 }
6633 try func.addTag(.i32_eqz);6720 try func.addTag(.i32_eqz);
...@@ -6649,8 +6736,8 @@ fn lowerTry(...@@ -6649,8 +6736,8 @@ fn lowerTry(
6649 return WValue{ .none = {} };6736 return WValue{ .none = {} };
6650 }6737 }
66516738
6652 const pl_offset = @as(u32, @intCast(errUnionPayloadOffset(pl_ty, mod)));6739 const pl_offset: u32 = @intCast(errUnionPayloadOffset(pl_ty, pt));
6653 if (isByRef(pl_ty, mod)) {6740 if (isByRef(pl_ty, pt)) {
6654 return buildPointerOffset(func, err_union, pl_offset, .new);6741 return buildPointerOffset(func, err_union, pl_offset, .new);
6655 }6742 }
6656 const payload = try func.load(err_union, pl_ty, pl_offset);6743 const payload = try func.load(err_union, pl_ty, pl_offset);
...@@ -6658,7 +6745,8 @@ fn lowerTry(...@@ -6658,7 +6745,8 @@ fn lowerTry(
6658}6745}
66596746
6660fn airByteSwap(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {6747fn airByteSwap(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
6661 const mod = func.bin_file.base.comp.module.?;6748 const pt = func.pt;
6749 const mod = pt.zcu;
6662 const ty_op = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;6750 const ty_op = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
66636751
6664 const ty = func.typeOfIndex(inst);6752 const ty = func.typeOfIndex(inst);
...@@ -6744,7 +6832,8 @@ fn airDivTrunc(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -6744,7 +6832,8 @@ fn airDivTrunc(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
6744fn airDivFloor(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {6832fn airDivFloor(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
6745 const bin_op = func.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;6833 const bin_op = func.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
67466834
6747 const mod = func.bin_file.base.comp.module.?;6835 const pt = func.pt;
6836 const mod = pt.zcu;
6748 const ty = func.typeOfIndex(inst);6837 const ty = func.typeOfIndex(inst);
6749 const lhs = try func.resolveInst(bin_op.lhs);6838 const lhs = try func.resolveInst(bin_op.lhs);
6750 const rhs = try func.resolveInst(bin_op.rhs);6839 const rhs = try func.resolveInst(bin_op.rhs);
...@@ -6864,7 +6953,8 @@ fn airRem(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -6864,7 +6953,8 @@ fn airRem(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
6864fn airMod(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {6953fn airMod(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
6865 const bin_op = func.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;6954 const bin_op = func.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
68666955
6867 const mod = func.bin_file.base.comp.module.?;6956 const pt = func.pt;
6957 const mod = pt.zcu;
6868 const ty = func.typeOfIndex(inst);6958 const ty = func.typeOfIndex(inst);
6869 const lhs = try func.resolveInst(bin_op.lhs);6959 const lhs = try func.resolveInst(bin_op.lhs);
6870 const rhs = try func.resolveInst(bin_op.rhs);6960 const rhs = try func.resolveInst(bin_op.rhs);
...@@ -6901,7 +6991,8 @@ fn airSatBinOp(func: *CodeGen, inst: Air.Inst.Index, op: Op) InnerError!void {...@@ -6901,7 +6991,8 @@ fn airSatBinOp(func: *CodeGen, inst: Air.Inst.Index, op: Op) InnerError!void {
6901 assert(op == .add or op == .sub);6991 assert(op == .add or op == .sub);
6902 const bin_op = func.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;6992 const bin_op = func.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
69036993
6904 const mod = func.bin_file.base.comp.module.?;6994 const pt = func.pt;
6995 const mod = pt.zcu;
6905 const ty = func.typeOfIndex(inst);6996 const ty = func.typeOfIndex(inst);
6906 const lhs = try func.resolveInst(bin_op.lhs);6997 const lhs = try func.resolveInst(bin_op.lhs);
6907 const rhs = try func.resolveInst(bin_op.rhs);6998 const rhs = try func.resolveInst(bin_op.rhs);
...@@ -6949,11 +7040,12 @@ fn airSatBinOp(func: *CodeGen, inst: Air.Inst.Index, op: Op) InnerError!void {...@@ -6949,11 +7040,12 @@ fn airSatBinOp(func: *CodeGen, inst: Air.Inst.Index, op: Op) InnerError!void {
6949}7040}
69507041
6951fn signedSat(func: *CodeGen, lhs: WValue, rhs: WValue, ty: Type, op: Op) InnerError!WValue {7042fn signedSat(func: *CodeGen, lhs: WValue, rhs: WValue, ty: Type, op: Op) InnerError!WValue {
6952 const mod = func.bin_file.base.comp.module.?;7043 const pt = func.pt;
7044 const mod = pt.zcu;
6953 const int_info = ty.intInfo(mod);7045 const int_info = ty.intInfo(mod);
6954 const wasm_bits = toWasmBits(int_info.bits).?;7046 const wasm_bits = toWasmBits(int_info.bits).?;
6955 const is_wasm_bits = wasm_bits == int_info.bits;7047 const is_wasm_bits = wasm_bits == int_info.bits;
6956 const ext_ty = if (!is_wasm_bits) try mod.intType(int_info.signedness, wasm_bits) else ty;7048 const ext_ty = if (!is_wasm_bits) try pt.intType(int_info.signedness, wasm_bits) else ty;
69577049
6958 const max_val: u64 = @as(u64, @intCast((@as(u65, 1) << @as(u7, @intCast(int_info.bits - 1))) - 1));7050 const max_val: u64 = @as(u64, @intCast((@as(u65, 1) << @as(u7, @intCast(int_info.bits - 1))) - 1));
6959 const min_val: i64 = (-@as(i64, @intCast(@as(u63, @intCast(max_val))))) - 1;7051 const min_val: i64 = (-@as(i64, @intCast(@as(u63, @intCast(max_val))))) - 1;
...@@ -7007,7 +7099,8 @@ fn signedSat(func: *CodeGen, lhs: WValue, rhs: WValue, ty: Type, op: Op) InnerEr...@@ -7007,7 +7099,8 @@ fn signedSat(func: *CodeGen, lhs: WValue, rhs: WValue, ty: Type, op: Op) InnerEr
7007fn airShlSat(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {7099fn airShlSat(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
7008 const bin_op = func.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;7100 const bin_op = func.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
70097101
7010 const mod = func.bin_file.base.comp.module.?;7102 const pt = func.pt;
7103 const mod = pt.zcu;
7011 const ty = func.typeOfIndex(inst);7104 const ty = func.typeOfIndex(inst);
7012 const int_info = ty.intInfo(mod);7105 const int_info = ty.intInfo(mod);
7013 const is_signed = int_info.signedness == .signed;7106 const is_signed = int_info.signedness == .signed;
...@@ -7061,7 +7154,7 @@ fn airShlSat(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -7061,7 +7154,7 @@ fn airShlSat(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
7061 64 => WValue{ .imm64 = shift_size },7154 64 => WValue{ .imm64 = shift_size },
7062 else => unreachable,7155 else => unreachable,
7063 };7156 };
7064 const ext_ty = try mod.intType(int_info.signedness, wasm_bits);7157 const ext_ty = try pt.intType(int_info.signedness, wasm_bits);
70657158
7066 var shl_res = try (try func.binOp(lhs, shift_value, ext_ty, .shl)).toLocal(func, ext_ty);7159 var shl_res = try (try func.binOp(lhs, shift_value, ext_ty, .shl)).toLocal(func, ext_ty);
7067 defer shl_res.free(func);7160 defer shl_res.free(func);
...@@ -7128,13 +7221,14 @@ fn callIntrinsic(...@@ -7128,13 +7221,14 @@ fn callIntrinsic(
7128 };7221 };
71297222
7130 // Always pass over C-ABI7223 // Always pass over C-ABI
7131 const mod = func.bin_file.base.comp.module.?;7224 const pt = func.pt;
7132 var func_type = try genFunctype(func.gpa, .C, param_types, return_type, mod);7225 const mod = pt.zcu;
7226 var func_type = try genFunctype(func.gpa, .C, param_types, return_type, pt);
7133 defer func_type.deinit(func.gpa);7227 defer func_type.deinit(func.gpa);
7134 const func_type_index = try func.bin_file.zigObjectPtr().?.putOrGetFuncType(func.gpa, func_type);7228 const func_type_index = try func.bin_file.zigObjectPtr().?.putOrGetFuncType(func.gpa, func_type);
7135 try func.bin_file.addOrUpdateImport(name, symbol_index, null, func_type_index);7229 try func.bin_file.addOrUpdateImport(name, symbol_index, null, func_type_index);
71367230
7137 const want_sret_param = firstParamSRet(.C, return_type, mod);7231 const want_sret_param = firstParamSRet(.C, return_type, pt);
7138 // if we want return as first param, we allocate a pointer to stack,7232 // if we want return as first param, we allocate a pointer to stack,
7139 // and emit it as our first argument7233 // and emit it as our first argument
7140 const sret = if (want_sret_param) blk: {7234 const sret = if (want_sret_param) blk: {
...@@ -7146,14 +7240,14 @@ fn callIntrinsic(...@@ -7146,14 +7240,14 @@ fn callIntrinsic(
7146 // Lower all arguments to the stack before we call our function7240 // Lower all arguments to the stack before we call our function
7147 for (args, 0..) |arg, arg_i| {7241 for (args, 0..) |arg, arg_i| {
7148 assert(!(want_sret_param and arg == .stack));7242 assert(!(want_sret_param and arg == .stack));
7149 assert(Type.fromInterned(param_types[arg_i]).hasRuntimeBitsIgnoreComptime(mod));7243 assert(Type.fromInterned(param_types[arg_i]).hasRuntimeBitsIgnoreComptime(pt));
7150 try func.lowerArg(.C, Type.fromInterned(param_types[arg_i]), arg);7244 try func.lowerArg(.C, Type.fromInterned(param_types[arg_i]), arg);
7151 }7245 }
71527246
7153 // Actually call our intrinsic7247 // Actually call our intrinsic
7154 try func.addLabel(.call, @intFromEnum(symbol_index));7248 try func.addLabel(.call, @intFromEnum(symbol_index));
71557249
7156 if (!return_type.hasRuntimeBitsIgnoreComptime(mod)) {7250 if (!return_type.hasRuntimeBitsIgnoreComptime(pt)) {
7157 return WValue.none;7251 return WValue.none;
7158 } else if (return_type.isNoReturn(mod)) {7252 } else if (return_type.isNoReturn(mod)) {
7159 try func.addTag(.@"unreachable");7253 try func.addTag(.@"unreachable");
...@@ -7181,7 +7275,8 @@ fn airTagName(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -7181,7 +7275,8 @@ fn airTagName(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
7181}7275}
71827276
7183fn getTagNameFunction(func: *CodeGen, enum_ty: Type) InnerError!u32 {7277fn getTagNameFunction(func: *CodeGen, enum_ty: Type) InnerError!u32 {
7184 const mod = func.bin_file.base.comp.module.?;7278 const pt = func.pt;
7279 const mod = pt.zcu;
7185 const ip = &mod.intern_pool;7280 const ip = &mod.intern_pool;
7186 const enum_decl_index = enum_ty.getOwnerDecl(mod);7281 const enum_decl_index = enum_ty.getOwnerDecl(mod);
71877282
...@@ -7189,7 +7284,7 @@ fn getTagNameFunction(func: *CodeGen, enum_ty: Type) InnerError!u32 {...@@ -7189,7 +7284,7 @@ fn getTagNameFunction(func: *CodeGen, enum_ty: Type) InnerError!u32 {
7189 defer arena_allocator.deinit();7284 defer arena_allocator.deinit();
7190 const arena = arena_allocator.allocator();7285 const arena = arena_allocator.allocator();
71917286
7192 const fqn = try mod.declPtr(enum_decl_index).fullyQualifiedName(mod);7287 const fqn = try mod.declPtr(enum_decl_index).fullyQualifiedName(pt);
7193 const func_name = try std.fmt.allocPrintZ(arena, "__zig_tag_name_{}", .{fqn.fmt(ip)});7288 const func_name = try std.fmt.allocPrintZ(arena, "__zig_tag_name_{}", .{fqn.fmt(ip)});
71947289
7195 // check if we already generated code for this.7290 // check if we already generated code for this.
...@@ -7199,7 +7294,7 @@ fn getTagNameFunction(func: *CodeGen, enum_ty: Type) InnerError!u32 {...@@ -7199,7 +7294,7 @@ fn getTagNameFunction(func: *CodeGen, enum_ty: Type) InnerError!u32 {
71997294
7200 const int_tag_ty = enum_ty.intTagType(mod);7295 const int_tag_ty = enum_ty.intTagType(mod);
72017296
7202 if (int_tag_ty.bitSize(mod) > 64) {7297 if (int_tag_ty.bitSize(pt) > 64) {
7203 return func.fail("TODO: Implement @tagName for enums with tag size larger than 64 bits", .{});7298 return func.fail("TODO: Implement @tagName for enums with tag size larger than 64 bits", .{});
7204 }7299 }
72057300
...@@ -7225,16 +7320,17 @@ fn getTagNameFunction(func: *CodeGen, enum_ty: Type) InnerError!u32 {...@@ -7225,16 +7320,17 @@ fn getTagNameFunction(func: *CodeGen, enum_ty: Type) InnerError!u32 {
7225 const tag_name_len = tag_name.length(ip);7320 const tag_name_len = tag_name.length(ip);
7226 // for each tag name, create an unnamed const,7321 // for each tag name, create an unnamed const,
7227 // and then get a pointer to its value.7322 // and then get a pointer to its value.
7228 const name_ty = try mod.arrayType(.{7323 const name_ty = try pt.arrayType(.{
7229 .len = tag_name_len,7324 .len = tag_name_len,
7230 .child = .u8_type,7325 .child = .u8_type,
7231 .sentinel = .zero_u8,7326 .sentinel = .zero_u8,
7232 });7327 });
7233 const name_val = try mod.intern(.{ .aggregate = .{7328 const name_val = try pt.intern(.{ .aggregate = .{
7234 .ty = name_ty.toIntern(),7329 .ty = name_ty.toIntern(),
7235 .storage = .{ .bytes = tag_name.toString() },7330 .storage = .{ .bytes = tag_name.toString() },
7236 } });7331 } });
7237 const tag_sym_index = try func.bin_file.lowerUnnamedConst(7332 const tag_sym_index = try func.bin_file.lowerUnnamedConst(
7333 pt,
7238 Value.fromInterned(name_val),7334 Value.fromInterned(name_val),
7239 enum_decl_index,7335 enum_decl_index,
7240 );7336 );
...@@ -7247,7 +7343,7 @@ fn getTagNameFunction(func: *CodeGen, enum_ty: Type) InnerError!u32 {...@@ -7247,7 +7343,7 @@ fn getTagNameFunction(func: *CodeGen, enum_ty: Type) InnerError!u32 {
7247 try writer.writeByte(std.wasm.opcode(.local_get));7343 try writer.writeByte(std.wasm.opcode(.local_get));
7248 try leb.writeUleb128(writer, @as(u32, 1));7344 try leb.writeUleb128(writer, @as(u32, 1));
72497345
7250 const tag_val = try mod.enumValueFieldIndex(enum_ty, @intCast(tag_index));7346 const tag_val = try pt.enumValueFieldIndex(enum_ty, @intCast(tag_index));
7251 const tag_value = try func.lowerConstant(tag_val, enum_ty);7347 const tag_value = try func.lowerConstant(tag_val, enum_ty);
72527348
7253 switch (tag_value) {7349 switch (tag_value) {
...@@ -7334,13 +7430,14 @@ fn getTagNameFunction(func: *CodeGen, enum_ty: Type) InnerError!u32 {...@@ -7334,13 +7430,14 @@ fn getTagNameFunction(func: *CodeGen, enum_ty: Type) InnerError!u32 {
7334 try writer.writeByte(std.wasm.opcode(.end));7430 try writer.writeByte(std.wasm.opcode(.end));
73357431
7336 const slice_ty = Type.slice_const_u8_sentinel_0;7432 const slice_ty = Type.slice_const_u8_sentinel_0;
7337 const func_type = try genFunctype(arena, .Unspecified, &.{int_tag_ty.ip_index}, slice_ty, mod);7433 const func_type = try genFunctype(arena, .Unspecified, &.{int_tag_ty.ip_index}, slice_ty, pt);
7338 const sym_index = try func.bin_file.createFunction(func_name, func_type, &body_list, &relocs);7434 const sym_index = try func.bin_file.createFunction(func_name, func_type, &body_list, &relocs);
7339 return @intFromEnum(sym_index);7435 return @intFromEnum(sym_index);
7340}7436}
73417437
7342fn airErrorSetHasValue(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {7438fn airErrorSetHasValue(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
7343 const mod = func.bin_file.base.comp.module.?;7439 const pt = func.pt;
7440 const mod = pt.zcu;
7344 const ip = &mod.intern_pool;7441 const ip = &mod.intern_pool;
7345 const ty_op = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;7442 const ty_op = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
73467443
...@@ -7426,7 +7523,8 @@ inline fn useAtomicFeature(func: *const CodeGen) bool {...@@ -7426,7 +7523,8 @@ inline fn useAtomicFeature(func: *const CodeGen) bool {
7426}7523}
74277524
7428fn airCmpxchg(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {7525fn airCmpxchg(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
7429 const mod = func.bin_file.base.comp.module.?;7526 const pt = func.pt;
7527 const mod = pt.zcu;
7430 const ty_pl = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;7528 const ty_pl = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
7431 const extra = func.air.extraData(Air.Cmpxchg, ty_pl.payload).data;7529 const extra = func.air.extraData(Air.Cmpxchg, ty_pl.payload).data;
74327530
...@@ -7445,7 +7543,7 @@ fn airCmpxchg(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -7445,7 +7543,7 @@ fn airCmpxchg(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
7445 try func.emitWValue(ptr_operand);7543 try func.emitWValue(ptr_operand);
7446 try func.lowerToStack(expected_val);7544 try func.lowerToStack(expected_val);
7447 try func.lowerToStack(new_val);7545 try func.lowerToStack(new_val);
7448 try func.addAtomicMemArg(switch (ty.abiSize(mod)) {7546 try func.addAtomicMemArg(switch (ty.abiSize(pt)) {
7449 1 => .i32_atomic_rmw8_cmpxchg_u,7547 1 => .i32_atomic_rmw8_cmpxchg_u,
7450 2 => .i32_atomic_rmw16_cmpxchg_u,7548 2 => .i32_atomic_rmw16_cmpxchg_u,
7451 4 => .i32_atomic_rmw_cmpxchg,7549 4 => .i32_atomic_rmw_cmpxchg,
...@@ -7453,14 +7551,14 @@ fn airCmpxchg(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -7453,14 +7551,14 @@ fn airCmpxchg(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
7453 else => |size| return func.fail("TODO: implement `@cmpxchg` for types with abi size '{d}'", .{size}),7551 else => |size| return func.fail("TODO: implement `@cmpxchg` for types with abi size '{d}'", .{size}),
7454 }, .{7552 }, .{
7455 .offset = ptr_operand.offset(),7553 .offset = ptr_operand.offset(),
7456 .alignment = @intCast(ty.abiAlignment(mod).toByteUnits().?),7554 .alignment = @intCast(ty.abiAlignment(pt).toByteUnits().?),
7457 });7555 });
7458 try func.addLabel(.local_tee, val_local.local.value);7556 try func.addLabel(.local_tee, val_local.local.value);
7459 _ = try func.cmp(.stack, expected_val, ty, .eq);7557 _ = try func.cmp(.stack, expected_val, ty, .eq);
7460 try func.addLabel(.local_set, cmp_result.local.value);7558 try func.addLabel(.local_set, cmp_result.local.value);
7461 break :val val_local;7559 break :val val_local;
7462 } else val: {7560 } else val: {
7463 if (ty.abiSize(mod) > 8) {7561 if (ty.abiSize(pt) > 8) {
7464 return func.fail("TODO: Implement `@cmpxchg` for types larger than abi size of 8 bytes", .{});7562 return func.fail("TODO: Implement `@cmpxchg` for types larger than abi size of 8 bytes", .{});
7465 }7563 }
7466 const ptr_val = try WValue.toLocal(try func.load(ptr_operand, ty, 0), func, ty);7564 const ptr_val = try WValue.toLocal(try func.load(ptr_operand, ty, 0), func, ty);
...@@ -7476,7 +7574,7 @@ fn airCmpxchg(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -7476,7 +7574,7 @@ fn airCmpxchg(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
7476 break :val ptr_val;7574 break :val ptr_val;
7477 };7575 };
74787576
7479 const result_ptr = if (isByRef(result_ty, mod)) val: {7577 const result_ptr = if (isByRef(result_ty, pt)) val: {
7480 try func.emitWValue(cmp_result);7578 try func.emitWValue(cmp_result);
7481 try func.addImm32(~@as(u32, 0));7579 try func.addImm32(~@as(u32, 0));
7482 try func.addTag(.i32_xor);7580 try func.addTag(.i32_xor);
...@@ -7484,7 +7582,7 @@ fn airCmpxchg(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -7484,7 +7582,7 @@ fn airCmpxchg(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
7484 try func.addTag(.i32_and);7582 try func.addTag(.i32_and);
7485 const and_result = try WValue.toLocal(.stack, func, Type.bool);7583 const and_result = try WValue.toLocal(.stack, func, Type.bool);
7486 const result_ptr = try func.allocStack(result_ty);7584 const result_ptr = try func.allocStack(result_ty);
7487 try func.store(result_ptr, and_result, Type.bool, @as(u32, @intCast(ty.abiSize(mod))));7585 try func.store(result_ptr, and_result, Type.bool, @as(u32, @intCast(ty.abiSize(pt))));
7488 try func.store(result_ptr, ptr_val, ty, 0);7586 try func.store(result_ptr, ptr_val, ty, 0);
7489 break :val result_ptr;7587 break :val result_ptr;
7490 } else val: {7588 } else val: {
...@@ -7499,13 +7597,13 @@ fn airCmpxchg(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -7499,13 +7597,13 @@ fn airCmpxchg(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
7499}7597}
75007598
7501fn airAtomicLoad(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {7599fn airAtomicLoad(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
7502 const mod = func.bin_file.base.comp.module.?;7600 const pt = func.pt;
7503 const atomic_load = func.air.instructions.items(.data)[@intFromEnum(inst)].atomic_load;7601 const atomic_load = func.air.instructions.items(.data)[@intFromEnum(inst)].atomic_load;
7504 const ptr = try func.resolveInst(atomic_load.ptr);7602 const ptr = try func.resolveInst(atomic_load.ptr);
7505 const ty = func.typeOfIndex(inst);7603 const ty = func.typeOfIndex(inst);
75067604
7507 if (func.useAtomicFeature()) {7605 if (func.useAtomicFeature()) {
7508 const tag: wasm.AtomicsOpcode = switch (ty.abiSize(mod)) {7606 const tag: wasm.AtomicsOpcode = switch (ty.abiSize(pt)) {
7509 1 => .i32_atomic_load8_u,7607 1 => .i32_atomic_load8_u,
7510 2 => .i32_atomic_load16_u,7608 2 => .i32_atomic_load16_u,
7511 4 => .i32_atomic_load,7609 4 => .i32_atomic_load,
...@@ -7515,7 +7613,7 @@ fn airAtomicLoad(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -7515,7 +7613,7 @@ fn airAtomicLoad(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
7515 try func.emitWValue(ptr);7613 try func.emitWValue(ptr);
7516 try func.addAtomicMemArg(tag, .{7614 try func.addAtomicMemArg(tag, .{
7517 .offset = ptr.offset(),7615 .offset = ptr.offset(),
7518 .alignment = @intCast(ty.abiAlignment(mod).toByteUnits().?),7616 .alignment = @intCast(ty.abiAlignment(pt).toByteUnits().?),
7519 });7617 });
7520 } else {7618 } else {
7521 _ = try func.load(ptr, ty, 0);7619 _ = try func.load(ptr, ty, 0);
...@@ -7526,7 +7624,8 @@ fn airAtomicLoad(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -7526,7 +7624,8 @@ fn airAtomicLoad(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
7526}7624}
75277625
7528fn airAtomicRmw(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {7626fn airAtomicRmw(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
7529 const mod = func.bin_file.base.comp.module.?;7627 const pt = func.pt;
7628 const mod = pt.zcu;
7530 const pl_op = func.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;7629 const pl_op = func.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;
7531 const extra = func.air.extraData(Air.AtomicRmw, pl_op.payload).data;7630 const extra = func.air.extraData(Air.AtomicRmw, pl_op.payload).data;
75327631
...@@ -7550,7 +7649,7 @@ fn airAtomicRmw(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -7550,7 +7649,7 @@ fn airAtomicRmw(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
7550 try func.emitWValue(ptr);7649 try func.emitWValue(ptr);
7551 try func.emitWValue(value);7650 try func.emitWValue(value);
7552 if (op == .Nand) {7651 if (op == .Nand) {
7553 const wasm_bits = toWasmBits(@as(u16, @intCast(ty.bitSize(mod)))).?;7652 const wasm_bits = toWasmBits(@intCast(ty.bitSize(pt))).?;
75547653
7555 const and_res = try func.binOp(value, operand, ty, .@"and");7654 const and_res = try func.binOp(value, operand, ty, .@"and");
7556 if (wasm_bits == 32)7655 if (wasm_bits == 32)
...@@ -7567,7 +7666,7 @@ fn airAtomicRmw(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -7567,7 +7666,7 @@ fn airAtomicRmw(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
7567 try func.addTag(.select);7666 try func.addTag(.select);
7568 }7667 }
7569 try func.addAtomicMemArg(7668 try func.addAtomicMemArg(
7570 switch (ty.abiSize(mod)) {7669 switch (ty.abiSize(pt)) {
7571 1 => .i32_atomic_rmw8_cmpxchg_u,7670 1 => .i32_atomic_rmw8_cmpxchg_u,
7572 2 => .i32_atomic_rmw16_cmpxchg_u,7671 2 => .i32_atomic_rmw16_cmpxchg_u,
7573 4 => .i32_atomic_rmw_cmpxchg,7672 4 => .i32_atomic_rmw_cmpxchg,
...@@ -7576,7 +7675,7 @@ fn airAtomicRmw(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -7576,7 +7675,7 @@ fn airAtomicRmw(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
7576 },7675 },
7577 .{7676 .{
7578 .offset = ptr.offset(),7677 .offset = ptr.offset(),
7579 .alignment = @intCast(ty.abiAlignment(mod).toByteUnits().?),7678 .alignment = @intCast(ty.abiAlignment(pt).toByteUnits().?),
7580 },7679 },
7581 );7680 );
7582 const select_res = try func.allocLocal(ty);7681 const select_res = try func.allocLocal(ty);
...@@ -7595,7 +7694,7 @@ fn airAtomicRmw(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -7595,7 +7694,7 @@ fn airAtomicRmw(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
7595 else => {7694 else => {
7596 try func.emitWValue(ptr);7695 try func.emitWValue(ptr);
7597 try func.emitWValue(operand);7696 try func.emitWValue(operand);
7598 const tag: wasm.AtomicsOpcode = switch (ty.abiSize(mod)) {7697 const tag: wasm.AtomicsOpcode = switch (ty.abiSize(pt)) {
7599 1 => switch (op) {7698 1 => switch (op) {
7600 .Xchg => .i32_atomic_rmw8_xchg_u,7699 .Xchg => .i32_atomic_rmw8_xchg_u,
7601 .Add => .i32_atomic_rmw8_add_u,7700 .Add => .i32_atomic_rmw8_add_u,
...@@ -7636,7 +7735,7 @@ fn airAtomicRmw(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -7636,7 +7735,7 @@ fn airAtomicRmw(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
7636 };7735 };
7637 try func.addAtomicMemArg(tag, .{7736 try func.addAtomicMemArg(tag, .{
7638 .offset = ptr.offset(),7737 .offset = ptr.offset(),
7639 .alignment = @intCast(ty.abiAlignment(mod).toByteUnits().?),7738 .alignment = @intCast(ty.abiAlignment(pt).toByteUnits().?),
7640 });7739 });
7641 const result = try WValue.toLocal(.stack, func, ty);7740 const result = try WValue.toLocal(.stack, func, ty);
7642 return func.finishAir(inst, result, &.{ pl_op.operand, extra.operand });7741 return func.finishAir(inst, result, &.{ pl_op.operand, extra.operand });
...@@ -7681,7 +7780,7 @@ fn airAtomicRmw(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -7681,7 +7780,7 @@ fn airAtomicRmw(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
7681 try func.store(.stack, .stack, ty, ptr.offset());7780 try func.store(.stack, .stack, ty, ptr.offset());
7682 },7781 },
7683 .Nand => {7782 .Nand => {
7684 const wasm_bits = toWasmBits(@as(u16, @intCast(ty.bitSize(mod)))).?;7783 const wasm_bits = toWasmBits(@intCast(ty.bitSize(pt))).?;
76857784
7686 try func.emitWValue(ptr);7785 try func.emitWValue(ptr);
7687 const and_res = try func.binOp(result, operand, ty, .@"and");7786 const and_res = try func.binOp(result, operand, ty, .@"and");
...@@ -7701,7 +7800,8 @@ fn airAtomicRmw(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -7701,7 +7800,8 @@ fn airAtomicRmw(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
7701}7800}
77027801
7703fn airFence(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {7802fn airFence(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
7704 const zcu = func.bin_file.base.comp.module.?;7803 const pt = func.pt;
7804 const zcu = pt.zcu;
7705 // Only when the atomic feature is enabled, and we're not building7805 // Only when the atomic feature is enabled, and we're not building
7706 // for a single-threaded build, can we emit the `fence` instruction.7806 // for a single-threaded build, can we emit the `fence` instruction.
7707 // In all other cases, we emit no instructions for a fence.7807 // In all other cases, we emit no instructions for a fence.
...@@ -7715,7 +7815,8 @@ fn airFence(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -7715,7 +7815,8 @@ fn airFence(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
7715}7815}
77167816
7717fn airAtomicStore(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {7817fn airAtomicStore(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
7718 const mod = func.bin_file.base.comp.module.?;7818 const pt = func.pt;
7819 const mod = pt.zcu;
7719 const bin_op = func.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;7820 const bin_op = func.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
77207821
7721 const ptr = try func.resolveInst(bin_op.lhs);7822 const ptr = try func.resolveInst(bin_op.lhs);
...@@ -7724,7 +7825,7 @@ fn airAtomicStore(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -7724,7 +7825,7 @@ fn airAtomicStore(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
7724 const ty = ptr_ty.childType(mod);7825 const ty = ptr_ty.childType(mod);
77257826
7726 if (func.useAtomicFeature()) {7827 if (func.useAtomicFeature()) {
7727 const tag: wasm.AtomicsOpcode = switch (ty.abiSize(mod)) {7828 const tag: wasm.AtomicsOpcode = switch (ty.abiSize(pt)) {
7728 1 => .i32_atomic_store8,7829 1 => .i32_atomic_store8,
7729 2 => .i32_atomic_store16,7830 2 => .i32_atomic_store16,
7730 4 => .i32_atomic_store,7831 4 => .i32_atomic_store,
...@@ -7735,7 +7836,7 @@ fn airAtomicStore(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -7735,7 +7836,7 @@ fn airAtomicStore(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
7735 try func.lowerToStack(operand);7836 try func.lowerToStack(operand);
7736 try func.addAtomicMemArg(tag, .{7837 try func.addAtomicMemArg(tag, .{
7737 .offset = ptr.offset(),7838 .offset = ptr.offset(),
7738 .alignment = @intCast(ty.abiAlignment(mod).toByteUnits().?),7839 .alignment = @intCast(ty.abiAlignment(pt).toByteUnits().?),
7739 });7840 });
7740 } else {7841 } else {
7741 try func.store(ptr, operand, ty, 0);7842 try func.store(ptr, operand, ty, 0);
...@@ -7754,11 +7855,13 @@ fn airFrameAddress(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -7754,11 +7855,13 @@ fn airFrameAddress(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
7754}7855}
77557856
7756fn typeOf(func: *CodeGen, inst: Air.Inst.Ref) Type {7857fn typeOf(func: *CodeGen, inst: Air.Inst.Ref) Type {
7757 const mod = func.bin_file.base.comp.module.?;7858 const pt = func.pt;
7859 const mod = pt.zcu;
7758 return func.air.typeOf(inst, &mod.intern_pool);7860 return func.air.typeOf(inst, &mod.intern_pool);
7759}7861}
77607862
7761fn typeOfIndex(func: *CodeGen, inst: Air.Inst.Index) Type {7863fn typeOfIndex(func: *CodeGen, inst: Air.Inst.Index) Type {
7762 const mod = func.bin_file.base.comp.module.?;7864 const pt = func.pt;
7865 const mod = pt.zcu;
7763 return func.air.typeOfIndex(inst, &mod.intern_pool);7866 return func.air.typeOfIndex(inst, &mod.intern_pool);
7764}7867}
src/arch/wasm/abi.zig+21-19
...@@ -22,15 +22,16 @@ const direct: [2]Class = .{ .direct, .none };...@@ -22,15 +22,16 @@ const direct: [2]Class = .{ .direct, .none };
22/// Classifies a given Zig type to determine how they must be passed22/// Classifies a given Zig type to determine how they must be passed
23/// or returned as value within a wasm function.23/// or returned as value within a wasm function.
24/// When all elements result in `.none`, no value must be passed in or returned.24/// When all elements result in `.none`, no value must be passed in or returned.
25pub fn classifyType(ty: Type, mod: *Zcu) [2]Class {25pub fn classifyType(ty: Type, pt: Zcu.PerThread) [2]Class {
26 const mod = pt.zcu;
26 const ip = &mod.intern_pool;27 const ip = &mod.intern_pool;
27 const target = mod.getTarget();28 const target = mod.getTarget();
28 if (!ty.hasRuntimeBitsIgnoreComptime(mod)) return none;29 if (!ty.hasRuntimeBitsIgnoreComptime(pt)) return none;
29 switch (ty.zigTypeTag(mod)) {30 switch (ty.zigTypeTag(mod)) {
30 .Struct => {31 .Struct => {
31 const struct_type = mod.typeToStruct(ty).?;32 const struct_type = pt.zcu.typeToStruct(ty).?;
32 if (struct_type.layout == .@"packed") {33 if (struct_type.layout == .@"packed") {
33 if (ty.bitSize(mod) <= 64) return direct;34 if (ty.bitSize(pt) <= 64) return direct;
34 return .{ .direct, .direct };35 return .{ .direct, .direct };
35 }36 }
36 if (struct_type.field_types.len > 1) {37 if (struct_type.field_types.len > 1) {
...@@ -40,13 +41,13 @@ pub fn classifyType(ty: Type, mod: *Zcu) [2]Class {...@@ -40,13 +41,13 @@ pub fn classifyType(ty: Type, mod: *Zcu) [2]Class {
40 const field_ty = Type.fromInterned(struct_type.field_types.get(ip)[0]);41 const field_ty = Type.fromInterned(struct_type.field_types.get(ip)[0]);
41 const explicit_align = struct_type.fieldAlign(ip, 0);42 const explicit_align = struct_type.fieldAlign(ip, 0);
42 if (explicit_align != .none) {43 if (explicit_align != .none) {
43 if (explicit_align.compareStrict(.gt, field_ty.abiAlignment(mod)))44 if (explicit_align.compareStrict(.gt, field_ty.abiAlignment(pt)))
44 return memory;45 return memory;
45 }46 }
46 return classifyType(field_ty, mod);47 return classifyType(field_ty, pt);
47 },48 },
48 .Int, .Enum, .ErrorSet => {49 .Int, .Enum, .ErrorSet => {
49 const int_bits = ty.intInfo(mod).bits;50 const int_bits = ty.intInfo(pt.zcu).bits;
50 if (int_bits <= 64) return direct;51 if (int_bits <= 64) return direct;
51 if (int_bits <= 128) return .{ .direct, .direct };52 if (int_bits <= 128) return .{ .direct, .direct };
52 return memory;53 return memory;
...@@ -61,24 +62,24 @@ pub fn classifyType(ty: Type, mod: *Zcu) [2]Class {...@@ -61,24 +62,24 @@ pub fn classifyType(ty: Type, mod: *Zcu) [2]Class {
61 .Vector => return direct,62 .Vector => return direct,
62 .Array => return memory,63 .Array => return memory,
63 .Optional => {64 .Optional => {
64 assert(ty.isPtrLikeOptional(mod));65 assert(ty.isPtrLikeOptional(pt.zcu));
65 return direct;66 return direct;
66 },67 },
67 .Pointer => {68 .Pointer => {
68 assert(!ty.isSlice(mod));69 assert(!ty.isSlice(pt.zcu));
69 return direct;70 return direct;
70 },71 },
71 .Union => {72 .Union => {
72 const union_obj = mod.typeToUnion(ty).?;73 const union_obj = pt.zcu.typeToUnion(ty).?;
73 if (union_obj.getLayout(ip) == .@"packed") {74 if (union_obj.getLayout(ip) == .@"packed") {
74 if (ty.bitSize(mod) <= 64) return direct;75 if (ty.bitSize(pt) <= 64) return direct;
75 return .{ .direct, .direct };76 return .{ .direct, .direct };
76 }77 }
77 const layout = ty.unionGetLayout(mod);78 const layout = ty.unionGetLayout(pt);
78 assert(layout.tag_size == 0);79 assert(layout.tag_size == 0);
79 if (union_obj.field_types.len > 1) return memory;80 if (union_obj.field_types.len > 1) return memory;
80 const first_field_ty = Type.fromInterned(union_obj.field_types.get(ip)[0]);81 const first_field_ty = Type.fromInterned(union_obj.field_types.get(ip)[0]);
81 return classifyType(first_field_ty, mod);82 return classifyType(first_field_ty, pt);
82 },83 },
83 .ErrorUnion,84 .ErrorUnion,
84 .Frame,85 .Frame,
...@@ -100,28 +101,29 @@ pub fn classifyType(ty: Type, mod: *Zcu) [2]Class {...@@ -100,28 +101,29 @@ pub fn classifyType(ty: Type, mod: *Zcu) [2]Class {
100/// Returns the scalar type a given type can represent.101/// Returns the scalar type a given type can represent.
101/// Asserts given type can be represented as scalar, such as102/// Asserts given type can be represented as scalar, such as
102/// a struct with a single scalar field.103/// a struct with a single scalar field.
103pub fn scalarType(ty: Type, mod: *Zcu) Type {104pub fn scalarType(ty: Type, pt: Zcu.PerThread) Type {
105 const mod = pt.zcu;
104 const ip = &mod.intern_pool;106 const ip = &mod.intern_pool;
105 switch (ty.zigTypeTag(mod)) {107 switch (ty.zigTypeTag(mod)) {
106 .Struct => {108 .Struct => {
107 if (mod.typeToPackedStruct(ty)) |packed_struct| {109 if (mod.typeToPackedStruct(ty)) |packed_struct| {
108 return scalarType(Type.fromInterned(packed_struct.backingIntType(ip).*), mod);110 return scalarType(Type.fromInterned(packed_struct.backingIntType(ip).*), pt);
109 } else {111 } else {
110 assert(ty.structFieldCount(mod) == 1);112 assert(ty.structFieldCount(mod) == 1);
111 return scalarType(ty.structFieldType(0, mod), mod);113 return scalarType(ty.structFieldType(0, mod), pt);
112 }114 }
113 },115 },
114 .Union => {116 .Union => {
115 const union_obj = mod.typeToUnion(ty).?;117 const union_obj = mod.typeToUnion(ty).?;
116 if (union_obj.getLayout(ip) != .@"packed") {118 if (union_obj.getLayout(ip) != .@"packed") {
117 const layout = mod.getUnionLayout(union_obj);119 const layout = pt.getUnionLayout(union_obj);
118 if (layout.payload_size == 0 and layout.tag_size != 0) {120 if (layout.payload_size == 0 and layout.tag_size != 0) {
119 return scalarType(ty.unionTagTypeSafety(mod).?, mod);121 return scalarType(ty.unionTagTypeSafety(mod).?, pt);
120 }122 }
121 assert(union_obj.field_types.len == 1);123 assert(union_obj.field_types.len == 1);
122 }124 }
123 const first_field_ty = Type.fromInterned(union_obj.field_types.get(ip)[0]);125 const first_field_ty = Type.fromInterned(union_obj.field_types.get(ip)[0]);
124 return scalarType(first_field_ty, mod);126 return scalarType(first_field_ty, pt);
125 },127 },
126 else => return ty,128 else => return ty,
127 }129 }
src/arch/x86_64/CodeGen.zig+655-551
...@@ -19,7 +19,7 @@ const CodeGenError = codegen.CodeGenError;...@@ -19,7 +19,7 @@ const CodeGenError = codegen.CodeGenError;
19const Compilation = @import("../../Compilation.zig");19const Compilation = @import("../../Compilation.zig");
20const DebugInfoOutput = codegen.DebugInfoOutput;20const DebugInfoOutput = codegen.DebugInfoOutput;
21const DW = std.dwarf;21const DW = std.dwarf;
22const ErrorMsg = Module.ErrorMsg;22const ErrorMsg = Zcu.ErrorMsg;
23const Result = codegen.Result;23const Result = codegen.Result;
24const Emit = @import("Emit.zig");24const Emit = @import("Emit.zig");
25const Liveness = @import("../../Liveness.zig");25const Liveness = @import("../../Liveness.zig");
...@@ -27,8 +27,6 @@ const Lower = @import("Lower.zig");...@@ -27,8 +27,6 @@ const Lower = @import("Lower.zig");
27const Mir = @import("Mir.zig");27const Mir = @import("Mir.zig");
28const Package = @import("../../Package.zig");28const Package = @import("../../Package.zig");
29const Zcu = @import("../../Zcu.zig");29const Zcu = @import("../../Zcu.zig");
30/// Deprecated.
31const Module = Zcu;
32const InternPool = @import("../../InternPool.zig");30const InternPool = @import("../../InternPool.zig");
33const Alignment = InternPool.Alignment;31const Alignment = InternPool.Alignment;
34const Target = std.Target;32const Target = std.Target;
...@@ -52,6 +50,7 @@ const FrameIndex = bits.FrameIndex;...@@ -52,6 +50,7 @@ const FrameIndex = bits.FrameIndex;
52const InnerError = CodeGenError || error{OutOfRegisters};50const InnerError = CodeGenError || error{OutOfRegisters};
5351
54gpa: Allocator,52gpa: Allocator,
53pt: Zcu.PerThread,
55air: Air,54air: Air,
56liveness: Liveness,55liveness: Liveness,
57bin_file: *link.File,56bin_file: *link.File,
...@@ -74,7 +73,7 @@ va_info: union {...@@ -74,7 +73,7 @@ va_info: union {
74ret_mcv: InstTracking,73ret_mcv: InstTracking,
75fn_type: Type,74fn_type: Type,
76arg_index: u32,75arg_index: u32,
77src_loc: Module.LazySrcLoc,76src_loc: Zcu.LazySrcLoc,
7877
79eflags_inst: ?Air.Inst.Index = null,78eflags_inst: ?Air.Inst.Index = null,
8079
...@@ -120,18 +119,18 @@ const Owner = union(enum) {...@@ -120,18 +119,18 @@ const Owner = union(enum) {
120 func_index: InternPool.Index,119 func_index: InternPool.Index,
121 lazy_sym: link.File.LazySymbol,120 lazy_sym: link.File.LazySymbol,
122121
123 fn getDecl(owner: Owner, mod: *Module) InternPool.DeclIndex {122 fn getDecl(owner: Owner, zcu: *Zcu) InternPool.DeclIndex {
124 return switch (owner) {123 return switch (owner) {
125 .func_index => |func_index| mod.funcOwnerDeclIndex(func_index),124 .func_index => |func_index| zcu.funcOwnerDeclIndex(func_index),
126 .lazy_sym => |lazy_sym| lazy_sym.ty.getOwnerDecl(mod),125 .lazy_sym => |lazy_sym| lazy_sym.ty.getOwnerDecl(zcu),
127 };126 };
128 }127 }
129128
130 fn getSymbolIndex(owner: Owner, ctx: *Self) !u32 {129 fn getSymbolIndex(owner: Owner, ctx: *Self) !u32 {
130 const pt = ctx.pt;
131 switch (owner) {131 switch (owner) {
132 .func_index => |func_index| {132 .func_index => |func_index| {
133 const mod = ctx.bin_file.comp.module.?;133 const decl_index = ctx.pt.zcu.funcOwnerDeclIndex(func_index);
134 const decl_index = mod.funcOwnerDeclIndex(func_index);
135 if (ctx.bin_file.cast(link.File.Elf)) |elf_file| {134 if (ctx.bin_file.cast(link.File.Elf)) |elf_file| {
136 return elf_file.zigObjectPtr().?.getOrCreateMetadataForDecl(elf_file, decl_index);135 return elf_file.zigObjectPtr().?.getOrCreateMetadataForDecl(elf_file, decl_index);
137 } else if (ctx.bin_file.cast(link.File.MachO)) |macho_file| {136 } else if (ctx.bin_file.cast(link.File.MachO)) |macho_file| {
...@@ -145,17 +144,17 @@ const Owner = union(enum) {...@@ -145,17 +144,17 @@ const Owner = union(enum) {
145 },144 },
146 .lazy_sym => |lazy_sym| {145 .lazy_sym => |lazy_sym| {
147 if (ctx.bin_file.cast(link.File.Elf)) |elf_file| {146 if (ctx.bin_file.cast(link.File.Elf)) |elf_file| {
148 return elf_file.zigObjectPtr().?.getOrCreateMetadataForLazySymbol(elf_file, lazy_sym) catch |err|147 return elf_file.zigObjectPtr().?.getOrCreateMetadataForLazySymbol(elf_file, pt, lazy_sym) catch |err|
149 ctx.fail("{s} creating lazy symbol", .{@errorName(err)});148 ctx.fail("{s} creating lazy symbol", .{@errorName(err)});
150 } else if (ctx.bin_file.cast(link.File.MachO)) |macho_file| {149 } else if (ctx.bin_file.cast(link.File.MachO)) |macho_file| {
151 return macho_file.getZigObject().?.getOrCreateMetadataForLazySymbol(macho_file, lazy_sym) catch |err|150 return macho_file.getZigObject().?.getOrCreateMetadataForLazySymbol(macho_file, pt, lazy_sym) catch |err|
152 ctx.fail("{s} creating lazy symbol", .{@errorName(err)});151 ctx.fail("{s} creating lazy symbol", .{@errorName(err)});
153 } else if (ctx.bin_file.cast(link.File.Coff)) |coff_file| {152 } else if (ctx.bin_file.cast(link.File.Coff)) |coff_file| {
154 const atom = coff_file.getOrCreateAtomForLazySymbol(lazy_sym) catch |err|153 const atom = coff_file.getOrCreateAtomForLazySymbol(pt, lazy_sym) catch |err|
155 return ctx.fail("{s} creating lazy symbol", .{@errorName(err)});154 return ctx.fail("{s} creating lazy symbol", .{@errorName(err)});
156 return coff_file.getAtom(atom).getSymbolIndex().?;155 return coff_file.getAtom(atom).getSymbolIndex().?;
157 } else if (ctx.bin_file.cast(link.File.Plan9)) |p9_file| {156 } else if (ctx.bin_file.cast(link.File.Plan9)) |p9_file| {
158 return p9_file.getOrCreateAtomForLazySymbol(lazy_sym) catch |err|157 return p9_file.getOrCreateAtomForLazySymbol(pt, lazy_sym) catch |err|
159 return ctx.fail("{s} creating lazy symbol", .{@errorName(err)});158 return ctx.fail("{s} creating lazy symbol", .{@errorName(err)});
160 } else unreachable;159 } else unreachable;
161 },160 },
...@@ -753,14 +752,14 @@ const FrameAlloc = struct {...@@ -753,14 +752,14 @@ const FrameAlloc = struct {
753 .ref_count = 0,752 .ref_count = 0,
754 };753 };
755 }754 }
756 fn initType(ty: Type, mod: *Module) FrameAlloc {755 fn initType(ty: Type, pt: Zcu.PerThread) FrameAlloc {
757 return init(.{756 return init(.{
758 .size = ty.abiSize(mod),757 .size = ty.abiSize(pt),
759 .alignment = ty.abiAlignment(mod),758 .alignment = ty.abiAlignment(pt),
760 });759 });
761 }760 }
762 fn initSpill(ty: Type, mod: *Module) FrameAlloc {761 fn initSpill(ty: Type, pt: Zcu.PerThread) FrameAlloc {
763 const abi_size = ty.abiSize(mod);762 const abi_size = ty.abiSize(pt);
764 const spill_size = if (abi_size < 8)763 const spill_size = if (abi_size < 8)
765 math.ceilPowerOfTwoAssert(u64, abi_size)764 math.ceilPowerOfTwoAssert(u64, abi_size)
766 else765 else
...@@ -768,7 +767,7 @@ const FrameAlloc = struct {...@@ -768,7 +767,7 @@ const FrameAlloc = struct {
768 return init(.{767 return init(.{
769 .size = spill_size,768 .size = spill_size,
770 .pad = @intCast(spill_size - abi_size),769 .pad = @intCast(spill_size - abi_size),
771 .alignment = ty.abiAlignment(mod).maxStrict(770 .alignment = ty.abiAlignment(pt).maxStrict(
772 Alignment.fromNonzeroByteUnits(@min(spill_size, 8)),771 Alignment.fromNonzeroByteUnits(@min(spill_size, 8)),
773 ),772 ),
774 });773 });
...@@ -777,7 +776,7 @@ const FrameAlloc = struct {...@@ -777,7 +776,7 @@ const FrameAlloc = struct {
777776
778const StackAllocation = struct {777const StackAllocation = struct {
779 inst: ?Air.Inst.Index,778 inst: ?Air.Inst.Index,
780 /// TODO do we need size? should be determined by inst.ty.abiSize(mod)779 /// TODO do we need size? should be determined by inst.ty.abiSize(pt)
781 size: u32,780 size: u32,
782};781};
783782
...@@ -795,16 +794,17 @@ const Self = @This();...@@ -795,16 +794,17 @@ const Self = @This();
795794
796pub fn generate(795pub fn generate(
797 bin_file: *link.File,796 bin_file: *link.File,
798 src_loc: Module.LazySrcLoc,797 pt: Zcu.PerThread,
798 src_loc: Zcu.LazySrcLoc,
799 func_index: InternPool.Index,799 func_index: InternPool.Index,
800 air: Air,800 air: Air,
801 liveness: Liveness,801 liveness: Liveness,
802 code: *std.ArrayList(u8),802 code: *std.ArrayList(u8),
803 debug_output: DebugInfoOutput,803 debug_output: DebugInfoOutput,
804) CodeGenError!Result {804) CodeGenError!Result {
805 const comp = bin_file.comp;805 const zcu = pt.zcu;
806 const gpa = comp.gpa;806 const gpa = zcu.gpa;
807 const zcu = comp.module.?;807 const comp = zcu.comp;
808 const func = zcu.funcInfo(func_index);808 const func = zcu.funcInfo(func_index);
809 const fn_owner_decl = zcu.declPtr(func.owner_decl);809 const fn_owner_decl = zcu.declPtr(func.owner_decl);
810 assert(fn_owner_decl.has_tv);810 assert(fn_owner_decl.has_tv);
...@@ -812,8 +812,9 @@ pub fn generate(...@@ -812,8 +812,9 @@ pub fn generate(
812 const namespace = zcu.namespacePtr(fn_owner_decl.src_namespace);812 const namespace = zcu.namespacePtr(fn_owner_decl.src_namespace);
813 const mod = namespace.fileScope(zcu).mod;813 const mod = namespace.fileScope(zcu).mod;
814814
815 var function = Self{815 var function: Self = .{
816 .gpa = gpa,816 .gpa = gpa,
817 .pt = pt,
817 .air = air,818 .air = air,
818 .liveness = liveness,819 .liveness = liveness,
819 .target = &mod.resolved_target.result,820 .target = &mod.resolved_target.result,
...@@ -882,11 +883,11 @@ pub fn generate(...@@ -882,11 +883,11 @@ pub fn generate(
882 function.args = call_info.args;883 function.args = call_info.args;
883 function.ret_mcv = call_info.return_value;884 function.ret_mcv = call_info.return_value;
884 function.frame_allocs.set(@intFromEnum(FrameIndex.ret_addr), FrameAlloc.init(.{885 function.frame_allocs.set(@intFromEnum(FrameIndex.ret_addr), FrameAlloc.init(.{
885 .size = Type.usize.abiSize(zcu),886 .size = Type.usize.abiSize(pt),
886 .alignment = Type.usize.abiAlignment(zcu).min(call_info.stack_align),887 .alignment = Type.usize.abiAlignment(pt).min(call_info.stack_align),
887 }));888 }));
888 function.frame_allocs.set(@intFromEnum(FrameIndex.base_ptr), FrameAlloc.init(.{889 function.frame_allocs.set(@intFromEnum(FrameIndex.base_ptr), FrameAlloc.init(.{
889 .size = Type.usize.abiSize(zcu),890 .size = Type.usize.abiSize(pt),
890 .alignment = Alignment.min(891 .alignment = Alignment.min(
891 call_info.stack_align,892 call_info.stack_align,
892 Alignment.fromNonzeroByteUnits(function.target.stackAlignment()),893 Alignment.fromNonzeroByteUnits(function.target.stackAlignment()),
...@@ -971,7 +972,8 @@ pub fn generate(...@@ -971,7 +972,8 @@ pub fn generate(
971972
972pub fn generateLazy(973pub fn generateLazy(
973 bin_file: *link.File,974 bin_file: *link.File,
974 src_loc: Module.LazySrcLoc,975 pt: Zcu.PerThread,
976 src_loc: Zcu.LazySrcLoc,
975 lazy_sym: link.File.LazySymbol,977 lazy_sym: link.File.LazySymbol,
976 code: *std.ArrayList(u8),978 code: *std.ArrayList(u8),
977 debug_output: DebugInfoOutput,979 debug_output: DebugInfoOutput,
...@@ -980,8 +982,9 @@ pub fn generateLazy(...@@ -980,8 +982,9 @@ pub fn generateLazy(
980 const gpa = comp.gpa;982 const gpa = comp.gpa;
981 // This function is for generating global code, so we use the root module.983 // This function is for generating global code, so we use the root module.
982 const mod = comp.root_mod;984 const mod = comp.root_mod;
983 var function = Self{985 var function: Self = .{
984 .gpa = gpa,986 .gpa = gpa,
987 .pt = pt,
985 .air = undefined,988 .air = undefined,
986 .liveness = undefined,989 .liveness = undefined,
987 .target = &mod.resolved_target.result,990 .target = &mod.resolved_target.result,
...@@ -1065,7 +1068,7 @@ pub fn generateLazy(...@@ -1065,7 +1068,7 @@ pub fn generateLazy(
1065}1068}
10661069
1067const FormatDeclData = struct {1070const FormatDeclData = struct {
1068 mod: *Module,1071 zcu: *Zcu,
1069 decl_index: InternPool.DeclIndex,1072 decl_index: InternPool.DeclIndex,
1070};1073};
1071fn formatDecl(1074fn formatDecl(
...@@ -1074,11 +1077,11 @@ fn formatDecl(...@@ -1074,11 +1077,11 @@ fn formatDecl(
1074 _: std.fmt.FormatOptions,1077 _: std.fmt.FormatOptions,
1075 writer: anytype,1078 writer: anytype,
1076) @TypeOf(writer).Error!void {1079) @TypeOf(writer).Error!void {
1077 try data.mod.declPtr(data.decl_index).renderFullyQualifiedName(data.mod, writer);1080 try data.zcu.declPtr(data.decl_index).renderFullyQualifiedName(data.zcu, writer);
1078}1081}
1079fn fmtDecl(self: *Self, decl_index: InternPool.DeclIndex) std.fmt.Formatter(formatDecl) {1082fn fmtDecl(self: *Self, decl_index: InternPool.DeclIndex) std.fmt.Formatter(formatDecl) {
1080 return .{ .data = .{1083 return .{ .data = .{
1081 .mod = self.bin_file.comp.module.?,1084 .zcu = self.pt.zcu,
1082 .decl_index = decl_index,1085 .decl_index = decl_index,
1083 } };1086 } };
1084}1087}
...@@ -1095,7 +1098,7 @@ fn formatAir(...@@ -1095,7 +1098,7 @@ fn formatAir(
1095) @TypeOf(writer).Error!void {1098) @TypeOf(writer).Error!void {
1096 @import("../../print_air.zig").dumpInst(1099 @import("../../print_air.zig").dumpInst(
1097 data.inst,1100 data.inst,
1098 data.self.bin_file.comp.module.?,1101 data.self.pt,
1099 data.self.air,1102 data.self.air,
1100 data.self.liveness,1103 data.self.liveness,
1101 );1104 );
...@@ -1746,7 +1749,8 @@ fn asmMemoryRegisterImmediate(...@@ -1746,7 +1749,8 @@ fn asmMemoryRegisterImmediate(
1746}1749}
17471750
1748fn gen(self: *Self) InnerError!void {1751fn gen(self: *Self) InnerError!void {
1749 const mod = self.bin_file.comp.module.?;1752 const pt = self.pt;
1753 const mod = pt.zcu;
1750 const fn_info = mod.typeToFunc(self.fn_type).?;1754 const fn_info = mod.typeToFunc(self.fn_type).?;
1751 const cc = abi.resolveCallingConvention(fn_info.cc, self.target.*);1755 const cc = abi.resolveCallingConvention(fn_info.cc, self.target.*);
1752 if (cc != .Naked) {1756 if (cc != .Naked) {
...@@ -1764,7 +1768,7 @@ fn gen(self: *Self) InnerError!void {...@@ -1764,7 +1768,7 @@ fn gen(self: *Self) InnerError!void {
1764 // The address where to store the return value for the caller is in a1768 // The address where to store the return value for the caller is in a
1765 // register which the callee is free to clobber. Therefore, we purposely1769 // register which the callee is free to clobber. Therefore, we purposely
1766 // spill it to stack immediately.1770 // spill it to stack immediately.
1767 const frame_index = try self.allocFrameIndex(FrameAlloc.initSpill(Type.usize, mod));1771 const frame_index = try self.allocFrameIndex(FrameAlloc.initSpill(Type.usize, pt));
1768 try self.genSetMem(1772 try self.genSetMem(
1769 .{ .frame = frame_index },1773 .{ .frame = frame_index },
1770 0,1774 0,
...@@ -1800,7 +1804,7 @@ fn gen(self: *Self) InnerError!void {...@@ -1800,7 +1804,7 @@ fn gen(self: *Self) InnerError!void {
1800 try self.asmRegisterImmediate(.{ ._, .cmp }, .al, Immediate.u(info.fp_count));1804 try self.asmRegisterImmediate(.{ ._, .cmp }, .al, Immediate.u(info.fp_count));
1801 const skip_sse_reloc = try self.asmJccReloc(.na, undefined);1805 const skip_sse_reloc = try self.asmJccReloc(.na, undefined);
18021806
1803 const vec_2_f64 = try mod.vectorType(.{ .len = 2, .child = .f64_type });1807 const vec_2_f64 = try pt.vectorType(.{ .len = 2, .child = .f64_type });
1804 for (abi.SysV.c_abi_sse_param_regs[info.fp_count..], info.fp_count..) |reg, reg_i|1808 for (abi.SysV.c_abi_sse_param_regs[info.fp_count..], info.fp_count..) |reg, reg_i|
1805 try self.genSetMem(1809 try self.genSetMem(
1806 .{ .frame = reg_save_area_fi },1810 .{ .frame = reg_save_area_fi },
...@@ -1951,7 +1955,8 @@ fn gen(self: *Self) InnerError!void {...@@ -1951,7 +1955,8 @@ fn gen(self: *Self) InnerError!void {
1951}1955}
19521956
1953fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {1957fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {
1954 const mod = self.bin_file.comp.module.?;1958 const pt = self.pt;
1959 const mod = pt.zcu;
1955 const ip = &mod.intern_pool;1960 const ip = &mod.intern_pool;
1956 const air_tags = self.air.instructions.items(.tag);1961 const air_tags = self.air.instructions.items(.tag);
19571962
...@@ -2222,12 +2227,13 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {...@@ -2222,12 +2227,13 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {
2222}2227}
22232228
2224fn genLazy(self: *Self, lazy_sym: link.File.LazySymbol) InnerError!void {2229fn genLazy(self: *Self, lazy_sym: link.File.LazySymbol) InnerError!void {
2225 const mod = self.bin_file.comp.module.?;2230 const pt = self.pt;
2231 const mod = pt.zcu;
2226 const ip = &mod.intern_pool;2232 const ip = &mod.intern_pool;
2227 switch (lazy_sym.ty.zigTypeTag(mod)) {2233 switch (lazy_sym.ty.zigTypeTag(mod)) {
2228 .Enum => {2234 .Enum => {
2229 const enum_ty = lazy_sym.ty;2235 const enum_ty = lazy_sym.ty;
2230 wip_mir_log.debug("{}.@tagName:", .{enum_ty.fmt(mod)});2236 wip_mir_log.debug("{}.@tagName:", .{enum_ty.fmt(pt)});
22312237
2232 const resolved_cc = abi.resolveCallingConvention(.Unspecified, self.target.*);2238 const resolved_cc = abi.resolveCallingConvention(.Unspecified, self.target.*);
2233 const param_regs = abi.getCAbiIntParamRegs(resolved_cc);2239 const param_regs = abi.getCAbiIntParamRegs(resolved_cc);
...@@ -2249,7 +2255,7 @@ fn genLazy(self: *Self, lazy_sym: link.File.LazySymbol) InnerError!void {...@@ -2249,7 +2255,7 @@ fn genLazy(self: *Self, lazy_sym: link.File.LazySymbol) InnerError!void {
2249 const tag_names = enum_ty.enumFields(mod);2255 const tag_names = enum_ty.enumFields(mod);
2250 for (exitlude_jump_relocs, 0..) |*exitlude_jump_reloc, tag_index| {2256 for (exitlude_jump_relocs, 0..) |*exitlude_jump_reloc, tag_index| {
2251 const tag_name_len = tag_names.get(ip)[tag_index].length(ip);2257 const tag_name_len = tag_names.get(ip)[tag_index].length(ip);
2252 const tag_val = try mod.enumValueFieldIndex(enum_ty, @intCast(tag_index));2258 const tag_val = try pt.enumValueFieldIndex(enum_ty, @intCast(tag_index));
2253 const tag_mcv = try self.genTypedValue(tag_val);2259 const tag_mcv = try self.genTypedValue(tag_val);
2254 try self.genBinOpMir(.{ ._, .cmp }, enum_ty, enum_mcv, tag_mcv);2260 try self.genBinOpMir(.{ ._, .cmp }, enum_ty, enum_mcv, tag_mcv);
2255 const skip_reloc = try self.asmJccReloc(.ne, undefined);2261 const skip_reloc = try self.asmJccReloc(.ne, undefined);
...@@ -2282,7 +2288,7 @@ fn genLazy(self: *Self, lazy_sym: link.File.LazySymbol) InnerError!void {...@@ -2282,7 +2288,7 @@ fn genLazy(self: *Self, lazy_sym: link.File.LazySymbol) InnerError!void {
2282 },2288 },
2283 else => return self.fail(2289 else => return self.fail(
2284 "TODO implement {s} for {}",2290 "TODO implement {s} for {}",
2285 .{ @tagName(lazy_sym.kind), lazy_sym.ty.fmt(mod) },2291 .{ @tagName(lazy_sym.kind), lazy_sym.ty.fmt(pt) },
2286 ),2292 ),
2287 }2293 }
2288}2294}
...@@ -2481,14 +2487,15 @@ fn allocFrameIndex(self: *Self, alloc: FrameAlloc) !FrameIndex {...@@ -2481,14 +2487,15 @@ fn allocFrameIndex(self: *Self, alloc: FrameAlloc) !FrameIndex {
24812487
2482/// Use a pointer instruction as the basis for allocating stack memory.2488/// Use a pointer instruction as the basis for allocating stack memory.
2483fn allocMemPtr(self: *Self, inst: Air.Inst.Index) !FrameIndex {2489fn allocMemPtr(self: *Self, inst: Air.Inst.Index) !FrameIndex {
2484 const mod = self.bin_file.comp.module.?;2490 const pt = self.pt;
2491 const mod = pt.zcu;
2485 const ptr_ty = self.typeOfIndex(inst);2492 const ptr_ty = self.typeOfIndex(inst);
2486 const val_ty = ptr_ty.childType(mod);2493 const val_ty = ptr_ty.childType(mod);
2487 return self.allocFrameIndex(FrameAlloc.init(.{2494 return self.allocFrameIndex(FrameAlloc.init(.{
2488 .size = math.cast(u32, val_ty.abiSize(mod)) orelse {2495 .size = math.cast(u32, val_ty.abiSize(pt)) orelse {
2489 return self.fail("type '{}' too big to fit into stack frame", .{val_ty.fmt(mod)});2496 return self.fail("type '{}' too big to fit into stack frame", .{val_ty.fmt(pt)});
2490 },2497 },
2491 .alignment = ptr_ty.ptrAlignment(mod).max(.@"1"),2498 .alignment = ptr_ty.ptrAlignment(pt).max(.@"1"),
2492 }));2499 }));
2493}2500}
24942501
...@@ -2501,9 +2508,10 @@ fn allocTempRegOrMem(self: *Self, elem_ty: Type, reg_ok: bool) !MCValue {...@@ -2501,9 +2508,10 @@ fn allocTempRegOrMem(self: *Self, elem_ty: Type, reg_ok: bool) !MCValue {
2501}2508}
25022509
2503fn allocRegOrMemAdvanced(self: *Self, ty: Type, inst: ?Air.Inst.Index, reg_ok: bool) !MCValue {2510fn allocRegOrMemAdvanced(self: *Self, ty: Type, inst: ?Air.Inst.Index, reg_ok: bool) !MCValue {
2504 const mod = self.bin_file.comp.module.?;2511 const pt = self.pt;
2505 const abi_size = math.cast(u32, ty.abiSize(mod)) orelse {2512 const mod = pt.zcu;
2506 return self.fail("type '{}' too big to fit into stack frame", .{ty.fmt(mod)});2513 const abi_size = math.cast(u32, ty.abiSize(pt)) orelse {
2514 return self.fail("type '{}' too big to fit into stack frame", .{ty.fmt(pt)});
2507 };2515 };
25082516
2509 if (reg_ok) need_mem: {2517 if (reg_ok) need_mem: {
...@@ -2529,12 +2537,13 @@ fn allocRegOrMemAdvanced(self: *Self, ty: Type, inst: ?Air.Inst.Index, reg_ok: b...@@ -2529,12 +2537,13 @@ fn allocRegOrMemAdvanced(self: *Self, ty: Type, inst: ?Air.Inst.Index, reg_ok: b
2529 }2537 }
2530 }2538 }
25312539
2532 const frame_index = try self.allocFrameIndex(FrameAlloc.initSpill(ty, mod));2540 const frame_index = try self.allocFrameIndex(FrameAlloc.initSpill(ty, pt));
2533 return .{ .load_frame = .{ .index = frame_index } };2541 return .{ .load_frame = .{ .index = frame_index } };
2534}2542}
25352543
2536fn regClassForType(self: *Self, ty: Type) RegisterManager.RegisterBitSet {2544fn regClassForType(self: *Self, ty: Type) RegisterManager.RegisterBitSet {
2537 const mod = self.bin_file.comp.module.?;2545 const pt = self.pt;
2546 const mod = pt.zcu;
2538 return switch (ty.zigTypeTag(mod)) {2547 return switch (ty.zigTypeTag(mod)) {
2539 .Float => switch (ty.floatBits(self.target.*)) {2548 .Float => switch (ty.floatBits(self.target.*)) {
2540 80 => abi.RegisterClass.x87,2549 80 => abi.RegisterClass.x87,
...@@ -2849,7 +2858,8 @@ fn airFptrunc(self: *Self, inst: Air.Inst.Index) !void {...@@ -2849,7 +2858,8 @@ fn airFptrunc(self: *Self, inst: Air.Inst.Index) !void {
2849}2858}
28502859
2851fn airFpext(self: *Self, inst: Air.Inst.Index) !void {2860fn airFpext(self: *Self, inst: Air.Inst.Index) !void {
2852 const mod = self.bin_file.comp.module.?;2861 const pt = self.pt;
2862 const mod = pt.zcu;
2853 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;2863 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
2854 const dst_ty = self.typeOfIndex(inst);2864 const dst_ty = self.typeOfIndex(inst);
2855 const dst_scalar_ty = dst_ty.scalarType(mod);2865 const dst_scalar_ty = dst_ty.scalarType(mod);
...@@ -2892,14 +2902,14 @@ fn airFpext(self: *Self, inst: Air.Inst.Index) !void {...@@ -2892,14 +2902,14 @@ fn airFpext(self: *Self, inst: Air.Inst.Index) !void {
2892 } }, &.{src_scalar_ty}, &.{.{ .air_ref = ty_op.operand }});2902 } }, &.{src_scalar_ty}, &.{.{ .air_ref = ty_op.operand }});
2893 }2903 }
28942904
2895 const src_abi_size: u32 = @intCast(src_ty.abiSize(mod));2905 const src_abi_size: u32 = @intCast(src_ty.abiSize(pt));
2896 const src_mcv = try self.resolveInst(ty_op.operand);2906 const src_mcv = try self.resolveInst(ty_op.operand);
2897 const dst_mcv = if (src_mcv.isRegister() and self.reuseOperand(inst, ty_op.operand, 0, src_mcv))2907 const dst_mcv = if (src_mcv.isRegister() and self.reuseOperand(inst, ty_op.operand, 0, src_mcv))
2898 src_mcv2908 src_mcv
2899 else2909 else
2900 try self.copyToRegisterWithInstTracking(inst, dst_ty, src_mcv);2910 try self.copyToRegisterWithInstTracking(inst, dst_ty, src_mcv);
2901 const dst_reg = dst_mcv.getReg().?;2911 const dst_reg = dst_mcv.getReg().?;
2902 const dst_alias = registerAlias(dst_reg, @intCast(@max(dst_ty.abiSize(mod), 16)));2912 const dst_alias = registerAlias(dst_reg, @intCast(@max(dst_ty.abiSize(pt), 16)));
2903 const dst_lock = self.register_manager.lockReg(dst_reg);2913 const dst_lock = self.register_manager.lockReg(dst_reg);
2904 defer if (dst_lock) |lock| self.register_manager.unlockReg(lock);2914 defer if (dst_lock) |lock| self.register_manager.unlockReg(lock);
29052915
...@@ -2978,19 +2988,20 @@ fn airFpext(self: *Self, inst: Air.Inst.Index) !void {...@@ -2978,19 +2988,20 @@ fn airFpext(self: *Self, inst: Air.Inst.Index) !void {
2978 }2988 }
2979 break :result dst_mcv;2989 break :result dst_mcv;
2980 } orelse return self.fail("TODO implement airFpext from {} to {}", .{2990 } orelse return self.fail("TODO implement airFpext from {} to {}", .{
2981 src_ty.fmt(mod), dst_ty.fmt(mod),2991 src_ty.fmt(pt), dst_ty.fmt(pt),
2982 });2992 });
2983 return self.finishAir(inst, result, .{ ty_op.operand, .none, .none });2993 return self.finishAir(inst, result, .{ ty_op.operand, .none, .none });
2984}2994}
29852995
2986fn airIntCast(self: *Self, inst: Air.Inst.Index) !void {2996fn airIntCast(self: *Self, inst: Air.Inst.Index) !void {
2987 const mod = self.bin_file.comp.module.?;2997 const pt = self.pt;
2998 const mod = pt.zcu;
2988 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;2999 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
2989 const src_ty = self.typeOf(ty_op.operand);3000 const src_ty = self.typeOf(ty_op.operand);
2990 const dst_ty = self.typeOfIndex(inst);3001 const dst_ty = self.typeOfIndex(inst);
29913002
2992 const result = @as(?MCValue, result: {3003 const result = @as(?MCValue, result: {
2993 const dst_abi_size: u32 = @intCast(dst_ty.abiSize(mod));3004 const dst_abi_size: u32 = @intCast(dst_ty.abiSize(pt));
29943005
2995 const src_int_info = src_ty.intInfo(mod);3006 const src_int_info = src_ty.intInfo(mod);
2996 const dst_int_info = dst_ty.intInfo(mod);3007 const dst_int_info = dst_ty.intInfo(mod);
...@@ -3001,13 +3012,13 @@ fn airIntCast(self: *Self, inst: Air.Inst.Index) !void {...@@ -3001,13 +3012,13 @@ fn airIntCast(self: *Self, inst: Air.Inst.Index) !void {
30013012
3002 const src_mcv = try self.resolveInst(ty_op.operand);3013 const src_mcv = try self.resolveInst(ty_op.operand);
3003 if (dst_ty.isVector(mod)) {3014 if (dst_ty.isVector(mod)) {
3004 const src_abi_size: u32 = @intCast(src_ty.abiSize(mod));3015 const src_abi_size: u32 = @intCast(src_ty.abiSize(pt));
3005 const max_abi_size = @max(dst_abi_size, src_abi_size);3016 const max_abi_size = @max(dst_abi_size, src_abi_size);
3006 if (max_abi_size > @as(u32, if (self.hasFeature(.avx2)) 32 else 16)) break :result null;3017 if (max_abi_size > @as(u32, if (self.hasFeature(.avx2)) 32 else 16)) break :result null;
3007 const has_avx = self.hasFeature(.avx);3018 const has_avx = self.hasFeature(.avx);
30083019
3009 const dst_elem_abi_size = dst_ty.childType(mod).abiSize(mod);3020 const dst_elem_abi_size = dst_ty.childType(mod).abiSize(pt);
3010 const src_elem_abi_size = src_ty.childType(mod).abiSize(mod);3021 const src_elem_abi_size = src_ty.childType(mod).abiSize(pt);
3011 switch (math.order(dst_elem_abi_size, src_elem_abi_size)) {3022 switch (math.order(dst_elem_abi_size, src_elem_abi_size)) {
3012 .lt => {3023 .lt => {
3013 const mir_tag: Mir.Inst.FixedTag = switch (dst_elem_abi_size) {3024 const mir_tag: Mir.Inst.FixedTag = switch (dst_elem_abi_size) {
...@@ -3236,19 +3247,20 @@ fn airIntCast(self: *Self, inst: Air.Inst.Index) !void {...@@ -3236,19 +3247,20 @@ fn airIntCast(self: *Self, inst: Air.Inst.Index) !void {
32363247
3237 break :result dst_mcv;3248 break :result dst_mcv;
3238 }) orelse return self.fail("TODO implement airIntCast from {} to {}", .{3249 }) orelse return self.fail("TODO implement airIntCast from {} to {}", .{
3239 src_ty.fmt(mod), dst_ty.fmt(mod),3250 src_ty.fmt(pt), dst_ty.fmt(pt),
3240 });3251 });
3241 return self.finishAir(inst, result, .{ ty_op.operand, .none, .none });3252 return self.finishAir(inst, result, .{ ty_op.operand, .none, .none });
3242}3253}
32433254
3244fn airTrunc(self: *Self, inst: Air.Inst.Index) !void {3255fn airTrunc(self: *Self, inst: Air.Inst.Index) !void {
3245 const mod = self.bin_file.comp.module.?;3256 const pt = self.pt;
3257 const mod = pt.zcu;
3246 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;3258 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
32473259
3248 const dst_ty = self.typeOfIndex(inst);3260 const dst_ty = self.typeOfIndex(inst);
3249 const dst_abi_size: u32 = @intCast(dst_ty.abiSize(mod));3261 const dst_abi_size: u32 = @intCast(dst_ty.abiSize(pt));
3250 const src_ty = self.typeOf(ty_op.operand);3262 const src_ty = self.typeOf(ty_op.operand);
3251 const src_abi_size: u32 = @intCast(src_ty.abiSize(mod));3263 const src_abi_size: u32 = @intCast(src_ty.abiSize(pt));
32523264
3253 const result = result: {3265 const result = result: {
3254 const src_mcv = try self.resolveInst(ty_op.operand);3266 const src_mcv = try self.resolveInst(ty_op.operand);
...@@ -3278,9 +3290,9 @@ fn airTrunc(self: *Self, inst: Air.Inst.Index) !void {...@@ -3278,9 +3290,9 @@ fn airTrunc(self: *Self, inst: Air.Inst.Index) !void {
3278 if (dst_ty.zigTypeTag(mod) == .Vector) {3290 if (dst_ty.zigTypeTag(mod) == .Vector) {
3279 assert(src_ty.zigTypeTag(mod) == .Vector and dst_ty.vectorLen(mod) == src_ty.vectorLen(mod));3291 assert(src_ty.zigTypeTag(mod) == .Vector and dst_ty.vectorLen(mod) == src_ty.vectorLen(mod));
3280 const dst_elem_ty = dst_ty.childType(mod);3292 const dst_elem_ty = dst_ty.childType(mod);
3281 const dst_elem_abi_size: u32 = @intCast(dst_elem_ty.abiSize(mod));3293 const dst_elem_abi_size: u32 = @intCast(dst_elem_ty.abiSize(pt));
3282 const src_elem_ty = src_ty.childType(mod);3294 const src_elem_ty = src_ty.childType(mod);
3283 const src_elem_abi_size: u32 = @intCast(src_elem_ty.abiSize(mod));3295 const src_elem_abi_size: u32 = @intCast(src_elem_ty.abiSize(pt));
32843296
3285 const mir_tag = @as(?Mir.Inst.FixedTag, switch (dst_elem_abi_size) {3297 const mir_tag = @as(?Mir.Inst.FixedTag, switch (dst_elem_abi_size) {
3286 1 => switch (src_elem_abi_size) {3298 1 => switch (src_elem_abi_size) {
...@@ -3305,20 +3317,20 @@ fn airTrunc(self: *Self, inst: Air.Inst.Index) !void {...@@ -3305,20 +3317,20 @@ fn airTrunc(self: *Self, inst: Air.Inst.Index) !void {
3305 else => null,3317 else => null,
3306 },3318 },
3307 else => null,3319 else => null,
3308 }) orelse return self.fail("TODO implement airTrunc for {}", .{dst_ty.fmt(mod)});3320 }) orelse return self.fail("TODO implement airTrunc for {}", .{dst_ty.fmt(pt)});
33093321
3310 const dst_info = dst_elem_ty.intInfo(mod);3322 const dst_info = dst_elem_ty.intInfo(mod);
3311 const src_info = src_elem_ty.intInfo(mod);3323 const src_info = src_elem_ty.intInfo(mod);
33123324
3313 const mask_val = try mod.intValue(src_elem_ty, @as(u64, math.maxInt(u64)) >> @intCast(64 - dst_info.bits));3325 const mask_val = try pt.intValue(src_elem_ty, @as(u64, math.maxInt(u64)) >> @intCast(64 - dst_info.bits));
33143326
3315 const splat_ty = try mod.vectorType(.{3327 const splat_ty = try pt.vectorType(.{
3316 .len = @intCast(@divExact(@as(u64, if (src_abi_size > 16) 256 else 128), src_info.bits)),3328 .len = @intCast(@divExact(@as(u64, if (src_abi_size > 16) 256 else 128), src_info.bits)),
3317 .child = src_elem_ty.ip_index,3329 .child = src_elem_ty.ip_index,
3318 });3330 });
3319 const splat_abi_size: u32 = @intCast(splat_ty.abiSize(mod));3331 const splat_abi_size: u32 = @intCast(splat_ty.abiSize(pt));
33203332
3321 const splat_val = try mod.intern(.{ .aggregate = .{3333 const splat_val = try pt.intern(.{ .aggregate = .{
3322 .ty = splat_ty.ip_index,3334 .ty = splat_ty.ip_index,
3323 .storage = .{ .repeated_elem = mask_val.ip_index },3335 .storage = .{ .repeated_elem = mask_val.ip_index },
3324 } });3336 } });
...@@ -3375,7 +3387,7 @@ fn airTrunc(self: *Self, inst: Air.Inst.Index) !void {...@@ -3375,7 +3387,7 @@ fn airTrunc(self: *Self, inst: Air.Inst.Index) !void {
3375 }3387 }
3376 } else if (dst_abi_size <= 16) {3388 } else if (dst_abi_size <= 16) {
3377 const dst_info = dst_ty.intInfo(mod);3389 const dst_info = dst_ty.intInfo(mod);
3378 const high_ty = try mod.intType(dst_info.signedness, dst_info.bits - 64);3390 const high_ty = try pt.intType(dst_info.signedness, dst_info.bits - 64);
3379 if (self.regExtraBits(high_ty) > 0) {3391 if (self.regExtraBits(high_ty) > 0) {
3380 try self.truncateRegister(high_ty, dst_mcv.register_pair[1].to64());3392 try self.truncateRegister(high_ty, dst_mcv.register_pair[1].to64());
3381 }3393 }
...@@ -3400,12 +3412,12 @@ fn airIntFromBool(self: *Self, inst: Air.Inst.Index) !void {...@@ -3400,12 +3412,12 @@ fn airIntFromBool(self: *Self, inst: Air.Inst.Index) !void {
3400}3412}
34013413
3402fn airSlice(self: *Self, inst: Air.Inst.Index) !void {3414fn airSlice(self: *Self, inst: Air.Inst.Index) !void {
3403 const mod = self.bin_file.comp.module.?;3415 const pt = self.pt;
3404 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;3416 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
3405 const bin_op = self.air.extraData(Air.Bin, ty_pl.payload).data;3417 const bin_op = self.air.extraData(Air.Bin, ty_pl.payload).data;
34063418
3407 const slice_ty = self.typeOfIndex(inst);3419 const slice_ty = self.typeOfIndex(inst);
3408 const frame_index = try self.allocFrameIndex(FrameAlloc.initSpill(slice_ty, mod));3420 const frame_index = try self.allocFrameIndex(FrameAlloc.initSpill(slice_ty, pt));
34093421
3410 const ptr_ty = self.typeOf(bin_op.lhs);3422 const ptr_ty = self.typeOf(bin_op.lhs);
3411 try self.genSetMem(.{ .frame = frame_index }, 0, ptr_ty, .{ .air_ref = bin_op.lhs }, .{});3423 try self.genSetMem(.{ .frame = frame_index }, 0, ptr_ty, .{ .air_ref = bin_op.lhs }, .{});
...@@ -3413,7 +3425,7 @@ fn airSlice(self: *Self, inst: Air.Inst.Index) !void {...@@ -3413,7 +3425,7 @@ fn airSlice(self: *Self, inst: Air.Inst.Index) !void {
3413 const len_ty = self.typeOf(bin_op.rhs);3425 const len_ty = self.typeOf(bin_op.rhs);
3414 try self.genSetMem(3426 try self.genSetMem(
3415 .{ .frame = frame_index },3427 .{ .frame = frame_index },
3416 @intCast(ptr_ty.abiSize(mod)),3428 @intCast(ptr_ty.abiSize(pt)),
3417 len_ty,3429 len_ty,
3418 .{ .air_ref = bin_op.rhs },3430 .{ .air_ref = bin_op.rhs },
3419 .{},3431 .{},
...@@ -3430,14 +3442,15 @@ fn airUnOp(self: *Self, inst: Air.Inst.Index, tag: Air.Inst.Tag) !void {...@@ -3430,14 +3442,15 @@ fn airUnOp(self: *Self, inst: Air.Inst.Index, tag: Air.Inst.Tag) !void {
3430}3442}
34313443
3432fn airBinOp(self: *Self, inst: Air.Inst.Index, tag: Air.Inst.Tag) !void {3444fn airBinOp(self: *Self, inst: Air.Inst.Index, tag: Air.Inst.Tag) !void {
3433 const mod = self.bin_file.comp.module.?;3445 const pt = self.pt;
3446 const mod = pt.zcu;
3434 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;3447 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
3435 const dst_mcv = try self.genBinOp(inst, tag, bin_op.lhs, bin_op.rhs);3448 const dst_mcv = try self.genBinOp(inst, tag, bin_op.lhs, bin_op.rhs);
34363449
3437 const dst_ty = self.typeOfIndex(inst);3450 const dst_ty = self.typeOfIndex(inst);
3438 if (dst_ty.isAbiInt(mod)) {3451 if (dst_ty.isAbiInt(mod)) {
3439 const abi_size: u32 = @intCast(dst_ty.abiSize(mod));3452 const abi_size: u32 = @intCast(dst_ty.abiSize(pt));
3440 const bit_size: u32 = @intCast(dst_ty.bitSize(mod));3453 const bit_size: u32 = @intCast(dst_ty.bitSize(pt));
3441 if (abi_size * 8 > bit_size) {3454 if (abi_size * 8 > bit_size) {
3442 const dst_lock = switch (dst_mcv) {3455 const dst_lock = switch (dst_mcv) {
3443 .register => |dst_reg| self.register_manager.lockRegAssumeUnused(dst_reg),3456 .register => |dst_reg| self.register_manager.lockRegAssumeUnused(dst_reg),
...@@ -3452,7 +3465,7 @@ fn airBinOp(self: *Self, inst: Air.Inst.Index, tag: Air.Inst.Tag) !void {...@@ -3452,7 +3465,7 @@ fn airBinOp(self: *Self, inst: Air.Inst.Index, tag: Air.Inst.Tag) !void {
3452 const tmp_lock = self.register_manager.lockRegAssumeUnused(tmp_reg);3465 const tmp_lock = self.register_manager.lockRegAssumeUnused(tmp_reg);
3453 defer self.register_manager.unlockReg(tmp_lock);3466 defer self.register_manager.unlockReg(tmp_lock);
34543467
3455 const hi_ty = try mod.intType(.unsigned, @intCast((dst_ty.bitSize(mod) - 1) % 64 + 1));3468 const hi_ty = try pt.intType(.unsigned, @intCast((dst_ty.bitSize(pt) - 1) % 64 + 1));
3456 const hi_mcv = dst_mcv.address().offset(@intCast(bit_size / 64 * 8)).deref();3469 const hi_mcv = dst_mcv.address().offset(@intCast(bit_size / 64 * 8)).deref();
3457 try self.genSetReg(tmp_reg, hi_ty, hi_mcv, .{});3470 try self.genSetReg(tmp_reg, hi_ty, hi_mcv, .{});
3458 try self.truncateRegister(dst_ty, tmp_reg);3471 try self.truncateRegister(dst_ty, tmp_reg);
...@@ -3471,7 +3484,8 @@ fn airPtrArithmetic(self: *Self, inst: Air.Inst.Index, tag: Air.Inst.Tag) !void...@@ -3471,7 +3484,8 @@ fn airPtrArithmetic(self: *Self, inst: Air.Inst.Index, tag: Air.Inst.Tag) !void
3471}3484}
34723485
3473fn activeIntBits(self: *Self, dst_air: Air.Inst.Ref) u16 {3486fn activeIntBits(self: *Self, dst_air: Air.Inst.Ref) u16 {
3474 const mod = self.bin_file.comp.module.?;3487 const pt = self.pt;
3488 const mod = pt.zcu;
3475 const air_tag = self.air.instructions.items(.tag);3489 const air_tag = self.air.instructions.items(.tag);
3476 const air_data = self.air.instructions.items(.data);3490 const air_data = self.air.instructions.items(.data);
34773491
...@@ -3497,7 +3511,7 @@ fn activeIntBits(self: *Self, dst_air: Air.Inst.Ref) u16 {...@@ -3497,7 +3511,7 @@ fn activeIntBits(self: *Self, dst_air: Air.Inst.Ref) u16 {
3497 }3511 }
3498 } else if (dst_air.toInterned()) |ip_index| {3512 } else if (dst_air.toInterned()) |ip_index| {
3499 var space: Value.BigIntSpace = undefined;3513 var space: Value.BigIntSpace = undefined;
3500 const src_int = Value.fromInterned(ip_index).toBigInt(&space, mod);3514 const src_int = Value.fromInterned(ip_index).toBigInt(&space, pt);
3501 return @as(u16, @intCast(src_int.bitCountTwosComp())) +3515 return @as(u16, @intCast(src_int.bitCountTwosComp())) +
3502 @intFromBool(src_int.positive and dst_info.signedness == .signed);3516 @intFromBool(src_int.positive and dst_info.signedness == .signed);
3503 }3517 }
...@@ -3505,7 +3519,8 @@ fn activeIntBits(self: *Self, dst_air: Air.Inst.Ref) u16 {...@@ -3505,7 +3519,8 @@ fn activeIntBits(self: *Self, dst_air: Air.Inst.Ref) u16 {
3505}3519}
35063520
3507fn airMulDivBinOp(self: *Self, inst: Air.Inst.Index) !void {3521fn airMulDivBinOp(self: *Self, inst: Air.Inst.Index) !void {
3508 const mod = self.bin_file.comp.module.?;3522 const pt = self.pt;
3523 const mod = pt.zcu;
3509 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;3524 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
3510 const result = result: {3525 const result = result: {
3511 const tag = self.air.instructions.items(.tag)[@intFromEnum(inst)];3526 const tag = self.air.instructions.items(.tag)[@intFromEnum(inst)];
...@@ -3514,10 +3529,10 @@ fn airMulDivBinOp(self: *Self, inst: Air.Inst.Index) !void {...@@ -3514,10 +3529,10 @@ fn airMulDivBinOp(self: *Self, inst: Air.Inst.Index) !void {
3514 .Float, .Vector => break :result try self.genBinOp(inst, tag, bin_op.lhs, bin_op.rhs),3529 .Float, .Vector => break :result try self.genBinOp(inst, tag, bin_op.lhs, bin_op.rhs),
3515 else => {},3530 else => {},
3516 }3531 }
3517 const dst_abi_size: u32 = @intCast(dst_ty.abiSize(mod));3532 const dst_abi_size: u32 = @intCast(dst_ty.abiSize(pt));
35183533
3519 const dst_info = dst_ty.intInfo(mod);3534 const dst_info = dst_ty.intInfo(mod);
3520 const src_ty = try mod.intType(dst_info.signedness, switch (tag) {3535 const src_ty = try pt.intType(dst_info.signedness, switch (tag) {
3521 else => unreachable,3536 else => unreachable,
3522 .mul, .mul_wrap => @max(3537 .mul, .mul_wrap => @max(
3523 self.activeIntBits(bin_op.lhs),3538 self.activeIntBits(bin_op.lhs),
...@@ -3526,7 +3541,7 @@ fn airMulDivBinOp(self: *Self, inst: Air.Inst.Index) !void {...@@ -3526,7 +3541,7 @@ fn airMulDivBinOp(self: *Self, inst: Air.Inst.Index) !void {
3526 ),3541 ),
3527 .div_trunc, .div_floor, .div_exact, .rem, .mod => dst_info.bits,3542 .div_trunc, .div_floor, .div_exact, .rem, .mod => dst_info.bits,
3528 });3543 });
3529 const src_abi_size: u32 = @intCast(src_ty.abiSize(mod));3544 const src_abi_size: u32 = @intCast(src_ty.abiSize(pt));
35303545
3531 if (dst_abi_size == 16 and src_abi_size == 16) switch (tag) {3546 if (dst_abi_size == 16 and src_abi_size == 16) switch (tag) {
3532 else => unreachable,3547 else => unreachable,
...@@ -3539,7 +3554,7 @@ fn airMulDivBinOp(self: *Self, inst: Air.Inst.Index) !void {...@@ -3539,7 +3554,7 @@ fn airMulDivBinOp(self: *Self, inst: Air.Inst.Index) !void {
3539 state: State,3554 state: State,
3540 reloc: Mir.Inst.Index,3555 reloc: Mir.Inst.Index,
3541 } = if (signed and tag == .div_floor) state: {3556 } = if (signed and tag == .div_floor) state: {
3542 const frame_index = try self.allocFrameIndex(FrameAlloc.initType(Type.usize, mod));3557 const frame_index = try self.allocFrameIndex(FrameAlloc.initType(Type.usize, pt));
3543 try self.asmMemoryImmediate(3558 try self.asmMemoryImmediate(
3544 .{ ._, .mov },3559 .{ ._, .mov },
3545 .{ .base = .{ .frame = frame_index }, .mod = .{ .rm = .{ .size = .qword } } },3560 .{ .base = .{ .frame = frame_index }, .mod = .{ .rm = .{ .size = .qword } } },
...@@ -3614,7 +3629,7 @@ fn airMulDivBinOp(self: *Self, inst: Air.Inst.Index) !void {...@@ -3614,7 +3629,7 @@ fn airMulDivBinOp(self: *Self, inst: Air.Inst.Index) !void {
3614 .rem, .mod => "mod",3629 .rem, .mod => "mod",
3615 else => unreachable,3630 else => unreachable,
3616 },3631 },
3617 intCompilerRtAbiName(@intCast(dst_ty.bitSize(mod))),3632 intCompilerRtAbiName(@intCast(dst_ty.bitSize(pt))),
3618 }) catch unreachable,3633 }) catch unreachable,
3619 } },3634 } },
3620 &.{ src_ty, src_ty },3635 &.{ src_ty, src_ty },
...@@ -3643,7 +3658,7 @@ fn airMulDivBinOp(self: *Self, inst: Air.Inst.Index) !void {...@@ -3643,7 +3658,7 @@ fn airMulDivBinOp(self: *Self, inst: Air.Inst.Index) !void {
3643 .return_type = dst_ty.toIntern(),3658 .return_type = dst_ty.toIntern(),
3644 .param_types = &.{ src_ty.toIntern(), src_ty.toIntern() },3659 .param_types = &.{ src_ty.toIntern(), src_ty.toIntern() },
3645 .callee = std.fmt.bufPrint(&callee_buf, "__div{c}i3", .{3660 .callee = std.fmt.bufPrint(&callee_buf, "__div{c}i3", .{
3646 intCompilerRtAbiName(@intCast(dst_ty.bitSize(mod))),3661 intCompilerRtAbiName(@intCast(dst_ty.bitSize(pt))),
3647 }) catch unreachable,3662 }) catch unreachable,
3648 } },3663 } },
3649 &.{ src_ty, src_ty },3664 &.{ src_ty, src_ty },
...@@ -3734,12 +3749,13 @@ fn airMulDivBinOp(self: *Self, inst: Air.Inst.Index) !void {...@@ -3734,12 +3749,13 @@ fn airMulDivBinOp(self: *Self, inst: Air.Inst.Index) !void {
3734}3749}
37353750
3736fn airAddSat(self: *Self, inst: Air.Inst.Index) !void {3751fn airAddSat(self: *Self, inst: Air.Inst.Index) !void {
3737 const mod = self.bin_file.comp.module.?;3752 const pt = self.pt;
3753 const mod = pt.zcu;
3738 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;3754 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
3739 const ty = self.typeOf(bin_op.lhs);3755 const ty = self.typeOf(bin_op.lhs);
3740 if (ty.zigTypeTag(mod) == .Vector or ty.abiSize(mod) > 8) return self.fail(3756 if (ty.zigTypeTag(mod) == .Vector or ty.abiSize(pt) > 8) return self.fail(
3741 "TODO implement airAddSat for {}",3757 "TODO implement airAddSat for {}",
3742 .{ty.fmt(mod)},3758 .{ty.fmt(pt)},
3743 );3759 );
37443760
3745 const lhs_mcv = try self.resolveInst(bin_op.lhs);3761 const lhs_mcv = try self.resolveInst(bin_op.lhs);
...@@ -3804,7 +3820,7 @@ fn airAddSat(self: *Self, inst: Air.Inst.Index) !void {...@@ -3804,7 +3820,7 @@ fn airAddSat(self: *Self, inst: Air.Inst.Index) !void {
3804 break :cc .o;3820 break :cc .o;
3805 } else cc: {3821 } else cc: {
3806 try self.genSetReg(limit_reg, ty, .{3822 try self.genSetReg(limit_reg, ty, .{
3807 .immediate = @as(u64, math.maxInt(u64)) >> @intCast(64 - ty.bitSize(mod)),3823 .immediate = @as(u64, math.maxInt(u64)) >> @intCast(64 - ty.bitSize(pt)),
3808 }, .{});3824 }, .{});
38093825
3810 try self.genBinOpMir(.{ ._, .add }, ty, dst_mcv, rhs_mcv);3826 try self.genBinOpMir(.{ ._, .add }, ty, dst_mcv, rhs_mcv);
...@@ -3815,7 +3831,7 @@ fn airAddSat(self: *Self, inst: Air.Inst.Index) !void {...@@ -3815,7 +3831,7 @@ fn airAddSat(self: *Self, inst: Air.Inst.Index) !void {
3815 break :cc .c;3831 break :cc .c;
3816 };3832 };
38173833
3818 const cmov_abi_size = @max(@as(u32, @intCast(ty.abiSize(mod))), 2);3834 const cmov_abi_size = @max(@as(u32, @intCast(ty.abiSize(pt))), 2);
3819 try self.asmCmovccRegisterRegister(3835 try self.asmCmovccRegisterRegister(
3820 cc,3836 cc,
3821 registerAlias(dst_reg, cmov_abi_size),3837 registerAlias(dst_reg, cmov_abi_size),
...@@ -3834,12 +3850,13 @@ fn airAddSat(self: *Self, inst: Air.Inst.Index) !void {...@@ -3834,12 +3850,13 @@ fn airAddSat(self: *Self, inst: Air.Inst.Index) !void {
3834}3850}
38353851
3836fn airSubSat(self: *Self, inst: Air.Inst.Index) !void {3852fn airSubSat(self: *Self, inst: Air.Inst.Index) !void {
3837 const mod = self.bin_file.comp.module.?;3853 const pt = self.pt;
3854 const mod = pt.zcu;
3838 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;3855 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
3839 const ty = self.typeOf(bin_op.lhs);3856 const ty = self.typeOf(bin_op.lhs);
3840 if (ty.zigTypeTag(mod) == .Vector or ty.abiSize(mod) > 8) return self.fail(3857 if (ty.zigTypeTag(mod) == .Vector or ty.abiSize(pt) > 8) return self.fail(
3841 "TODO implement airSubSat for {}",3858 "TODO implement airSubSat for {}",
3842 .{ty.fmt(mod)},3859 .{ty.fmt(pt)},
3843 );3860 );
38443861
3845 const lhs_mcv = try self.resolveInst(bin_op.lhs);3862 const lhs_mcv = try self.resolveInst(bin_op.lhs);
...@@ -3908,7 +3925,7 @@ fn airSubSat(self: *Self, inst: Air.Inst.Index) !void {...@@ -3908,7 +3925,7 @@ fn airSubSat(self: *Self, inst: Air.Inst.Index) !void {
3908 break :cc .c;3925 break :cc .c;
3909 };3926 };
39103927
3911 const cmov_abi_size = @max(@as(u32, @intCast(ty.abiSize(mod))), 2);3928 const cmov_abi_size = @max(@as(u32, @intCast(ty.abiSize(pt))), 2);
3912 try self.asmCmovccRegisterRegister(3929 try self.asmCmovccRegisterRegister(
3913 cc,3930 cc,
3914 registerAlias(dst_reg, cmov_abi_size),3931 registerAlias(dst_reg, cmov_abi_size),
...@@ -3927,13 +3944,14 @@ fn airSubSat(self: *Self, inst: Air.Inst.Index) !void {...@@ -3927,13 +3944,14 @@ fn airSubSat(self: *Self, inst: Air.Inst.Index) !void {
3927}3944}
39283945
3929fn airMulSat(self: *Self, inst: Air.Inst.Index) !void {3946fn airMulSat(self: *Self, inst: Air.Inst.Index) !void {
3930 const mod = self.bin_file.comp.module.?;3947 const pt = self.pt;
3948 const mod = pt.zcu;
3931 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;3949 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
3932 const ty = self.typeOf(bin_op.lhs);3950 const ty = self.typeOf(bin_op.lhs);
39333951
3934 const result = result: {3952 const result = result: {
3935 if (ty.toIntern() == .i128_type) {3953 if (ty.toIntern() == .i128_type) {
3936 const ptr_c_int = try mod.singleMutPtrType(Type.c_int);3954 const ptr_c_int = try pt.singleMutPtrType(Type.c_int);
3937 const overflow = try self.allocTempRegOrMem(Type.c_int, false);3955 const overflow = try self.allocTempRegOrMem(Type.c_int, false);
39383956
3939 const dst_mcv = try self.genCall(.{ .lib = .{3957 const dst_mcv = try self.genCall(.{ .lib = .{
...@@ -4010,9 +4028,9 @@ fn airMulSat(self: *Self, inst: Air.Inst.Index) !void {...@@ -4010,9 +4028,9 @@ fn airMulSat(self: *Self, inst: Air.Inst.Index) !void {
4010 break :result dst_mcv;4028 break :result dst_mcv;
4011 }4029 }
40124030
4013 if (ty.zigTypeTag(mod) == .Vector or ty.abiSize(mod) > 8) return self.fail(4031 if (ty.zigTypeTag(mod) == .Vector or ty.abiSize(pt) > 8) return self.fail(
4014 "TODO implement airMulSat for {}",4032 "TODO implement airMulSat for {}",
4015 .{ty.fmt(mod)},4033 .{ty.fmt(pt)},
4016 );4034 );
40174035
4018 try self.spillRegisters(&.{ .rax, .rcx, .rdx });4036 try self.spillRegisters(&.{ .rax, .rcx, .rdx });
...@@ -4061,7 +4079,7 @@ fn airMulSat(self: *Self, inst: Air.Inst.Index) !void {...@@ -4061,7 +4079,7 @@ fn airMulSat(self: *Self, inst: Air.Inst.Index) !void {
4061 };4079 };
40624080
4063 const dst_mcv = try self.genMulDivBinOp(.mul, inst, ty, ty, lhs_mcv, rhs_mcv);4081 const dst_mcv = try self.genMulDivBinOp(.mul, inst, ty, ty, lhs_mcv, rhs_mcv);
4064 const cmov_abi_size = @max(@as(u32, @intCast(ty.abiSize(mod))), 2);4082 const cmov_abi_size = @max(@as(u32, @intCast(ty.abiSize(pt))), 2);
4065 try self.asmCmovccRegisterRegister(4083 try self.asmCmovccRegisterRegister(
4066 cc,4084 cc,
4067 registerAlias(dst_mcv.register, cmov_abi_size),4085 registerAlias(dst_mcv.register, cmov_abi_size),
...@@ -4073,7 +4091,8 @@ fn airMulSat(self: *Self, inst: Air.Inst.Index) !void {...@@ -4073,7 +4091,8 @@ fn airMulSat(self: *Self, inst: Air.Inst.Index) !void {
4073}4091}
40744092
4075fn airAddSubWithOverflow(self: *Self, inst: Air.Inst.Index) !void {4093fn airAddSubWithOverflow(self: *Self, inst: Air.Inst.Index) !void {
4076 const mod = self.bin_file.comp.module.?;4094 const pt = self.pt;
4095 const mod = pt.zcu;
4077 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;4096 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
4078 const bin_op = self.air.extraData(Air.Bin, ty_pl.payload).data;4097 const bin_op = self.air.extraData(Air.Bin, ty_pl.payload).data;
4079 const result: MCValue = result: {4098 const result: MCValue = result: {
...@@ -4109,17 +4128,17 @@ fn airAddSubWithOverflow(self: *Self, inst: Air.Inst.Index) !void {...@@ -4109,17 +4128,17 @@ fn airAddSubWithOverflow(self: *Self, inst: Air.Inst.Index) !void {
4109 }4128 }
41104129
4111 const frame_index =4130 const frame_index =
4112 try self.allocFrameIndex(FrameAlloc.initSpill(tuple_ty, mod));4131 try self.allocFrameIndex(FrameAlloc.initSpill(tuple_ty, pt));
4113 try self.genSetMem(4132 try self.genSetMem(
4114 .{ .frame = frame_index },4133 .{ .frame = frame_index },
4115 @intCast(tuple_ty.structFieldOffset(1, mod)),4134 @intCast(tuple_ty.structFieldOffset(1, pt)),
4116 Type.u1,4135 Type.u1,
4117 .{ .eflags = cc },4136 .{ .eflags = cc },
4118 .{},4137 .{},
4119 );4138 );
4120 try self.genSetMem(4139 try self.genSetMem(
4121 .{ .frame = frame_index },4140 .{ .frame = frame_index },
4122 @intCast(tuple_ty.structFieldOffset(0, mod)),4141 @intCast(tuple_ty.structFieldOffset(0, pt)),
4123 ty,4142 ty,
4124 partial_mcv,4143 partial_mcv,
4125 .{},4144 .{},
...@@ -4128,7 +4147,7 @@ fn airAddSubWithOverflow(self: *Self, inst: Air.Inst.Index) !void {...@@ -4128,7 +4147,7 @@ fn airAddSubWithOverflow(self: *Self, inst: Air.Inst.Index) !void {
4128 }4147 }
41294148
4130 const frame_index =4149 const frame_index =
4131 try self.allocFrameIndex(FrameAlloc.initSpill(tuple_ty, mod));4150 try self.allocFrameIndex(FrameAlloc.initSpill(tuple_ty, pt));
4132 try self.genSetFrameTruncatedOverflowCompare(tuple_ty, frame_index, partial_mcv, cc);4151 try self.genSetFrameTruncatedOverflowCompare(tuple_ty, frame_index, partial_mcv, cc);
4133 break :result .{ .load_frame = .{ .index = frame_index } };4152 break :result .{ .load_frame = .{ .index = frame_index } };
4134 },4153 },
...@@ -4139,7 +4158,8 @@ fn airAddSubWithOverflow(self: *Self, inst: Air.Inst.Index) !void {...@@ -4139,7 +4158,8 @@ fn airAddSubWithOverflow(self: *Self, inst: Air.Inst.Index) !void {
4139}4158}
41404159
4141fn airShlWithOverflow(self: *Self, inst: Air.Inst.Index) !void {4160fn airShlWithOverflow(self: *Self, inst: Air.Inst.Index) !void {
4142 const mod = self.bin_file.comp.module.?;4161 const pt = self.pt;
4162 const mod = pt.zcu;
4143 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;4163 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
4144 const bin_op = self.air.extraData(Air.Bin, ty_pl.payload).data;4164 const bin_op = self.air.extraData(Air.Bin, ty_pl.payload).data;
4145 const result: MCValue = result: {4165 const result: MCValue = result: {
...@@ -4186,17 +4206,17 @@ fn airShlWithOverflow(self: *Self, inst: Air.Inst.Index) !void {...@@ -4186,17 +4206,17 @@ fn airShlWithOverflow(self: *Self, inst: Air.Inst.Index) !void {
4186 }4206 }
41874207
4188 const frame_index =4208 const frame_index =
4189 try self.allocFrameIndex(FrameAlloc.initSpill(tuple_ty, mod));4209 try self.allocFrameIndex(FrameAlloc.initSpill(tuple_ty, pt));
4190 try self.genSetMem(4210 try self.genSetMem(
4191 .{ .frame = frame_index },4211 .{ .frame = frame_index },
4192 @intCast(tuple_ty.structFieldOffset(1, mod)),4212 @intCast(tuple_ty.structFieldOffset(1, pt)),
4193 tuple_ty.structFieldType(1, mod),4213 tuple_ty.structFieldType(1, mod),
4194 .{ .eflags = cc },4214 .{ .eflags = cc },
4195 .{},4215 .{},
4196 );4216 );
4197 try self.genSetMem(4217 try self.genSetMem(
4198 .{ .frame = frame_index },4218 .{ .frame = frame_index },
4199 @intCast(tuple_ty.structFieldOffset(0, mod)),4219 @intCast(tuple_ty.structFieldOffset(0, pt)),
4200 tuple_ty.structFieldType(0, mod),4220 tuple_ty.structFieldType(0, mod),
4201 partial_mcv,4221 partial_mcv,
4202 .{},4222 .{},
...@@ -4205,7 +4225,7 @@ fn airShlWithOverflow(self: *Self, inst: Air.Inst.Index) !void {...@@ -4205,7 +4225,7 @@ fn airShlWithOverflow(self: *Self, inst: Air.Inst.Index) !void {
4205 }4225 }
42064226
4207 const frame_index =4227 const frame_index =
4208 try self.allocFrameIndex(FrameAlloc.initSpill(tuple_ty, mod));4228 try self.allocFrameIndex(FrameAlloc.initSpill(tuple_ty, pt));
4209 try self.genSetFrameTruncatedOverflowCompare(tuple_ty, frame_index, partial_mcv, cc);4229 try self.genSetFrameTruncatedOverflowCompare(tuple_ty, frame_index, partial_mcv, cc);
4210 break :result .{ .load_frame = .{ .index = frame_index } };4230 break :result .{ .load_frame = .{ .index = frame_index } };
4211 },4231 },
...@@ -4222,7 +4242,8 @@ fn genSetFrameTruncatedOverflowCompare(...@@ -4222,7 +4242,8 @@ fn genSetFrameTruncatedOverflowCompare(
4222 src_mcv: MCValue,4242 src_mcv: MCValue,
4223 overflow_cc: ?Condition,4243 overflow_cc: ?Condition,
4224) !void {4244) !void {
4225 const mod = self.bin_file.comp.module.?;4245 const pt = self.pt;
4246 const mod = pt.zcu;
4226 const src_lock = switch (src_mcv) {4247 const src_lock = switch (src_mcv) {
4227 .register => |reg| self.register_manager.lockReg(reg),4248 .register => |reg| self.register_manager.lockReg(reg),
4228 else => null,4249 else => null,
...@@ -4233,12 +4254,12 @@ fn genSetFrameTruncatedOverflowCompare(...@@ -4233,12 +4254,12 @@ fn genSetFrameTruncatedOverflowCompare(
4233 const int_info = ty.intInfo(mod);4254 const int_info = ty.intInfo(mod);
42344255
4235 const hi_bits = (int_info.bits - 1) % 64 + 1;4256 const hi_bits = (int_info.bits - 1) % 64 + 1;
4236 const hi_ty = try mod.intType(int_info.signedness, hi_bits);4257 const hi_ty = try pt.intType(int_info.signedness, hi_bits);
42374258
4238 const limb_bits: u16 = @intCast(if (int_info.bits <= 64) self.regBitSize(ty) else 64);4259 const limb_bits: u16 = @intCast(if (int_info.bits <= 64) self.regBitSize(ty) else 64);
4239 const limb_ty = try mod.intType(int_info.signedness, limb_bits);4260 const limb_ty = try pt.intType(int_info.signedness, limb_bits);
42404261
4241 const rest_ty = try mod.intType(.unsigned, int_info.bits - hi_bits);4262 const rest_ty = try pt.intType(.unsigned, int_info.bits - hi_bits);
42424263
4243 const temp_regs =4264 const temp_regs =
4244 try self.register_manager.allocRegs(3, .{null} ** 3, abi.RegisterClass.gp);4265 try self.register_manager.allocRegs(3, .{null} ** 3, abi.RegisterClass.gp);
...@@ -4269,7 +4290,7 @@ fn genSetFrameTruncatedOverflowCompare(...@@ -4269,7 +4290,7 @@ fn genSetFrameTruncatedOverflowCompare(
4269 );4290 );
4270 }4291 }
42714292
4272 const payload_off: i32 = @intCast(tuple_ty.structFieldOffset(0, mod));4293 const payload_off: i32 = @intCast(tuple_ty.structFieldOffset(0, pt));
4273 if (hi_limb_off > 0) try self.genSetMem(4294 if (hi_limb_off > 0) try self.genSetMem(
4274 .{ .frame = frame_index },4295 .{ .frame = frame_index },
4275 payload_off,4296 payload_off,
...@@ -4286,7 +4307,7 @@ fn genSetFrameTruncatedOverflowCompare(...@@ -4286,7 +4307,7 @@ fn genSetFrameTruncatedOverflowCompare(
4286 );4307 );
4287 try self.genSetMem(4308 try self.genSetMem(
4288 .{ .frame = frame_index },4309 .{ .frame = frame_index },
4289 @intCast(tuple_ty.structFieldOffset(1, mod)),4310 @intCast(tuple_ty.structFieldOffset(1, pt)),
4290 tuple_ty.structFieldType(1, mod),4311 tuple_ty.structFieldType(1, mod),
4291 if (overflow_cc) |_| .{ .register = overflow_reg.to8() } else .{ .eflags = .ne },4312 if (overflow_cc) |_| .{ .register = overflow_reg.to8() } else .{ .eflags = .ne },
4292 .{},4313 .{},
...@@ -4294,18 +4315,19 @@ fn genSetFrameTruncatedOverflowCompare(...@@ -4294,18 +4315,19 @@ fn genSetFrameTruncatedOverflowCompare(
4294}4315}
42954316
4296fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) !void {4317fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) !void {
4297 const mod = self.bin_file.comp.module.?;4318 const pt = self.pt;
4319 const mod = pt.zcu;
4298 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;4320 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
4299 const bin_op = self.air.extraData(Air.Bin, ty_pl.payload).data;4321 const bin_op = self.air.extraData(Air.Bin, ty_pl.payload).data;
4300 const tuple_ty = self.typeOfIndex(inst);4322 const tuple_ty = self.typeOfIndex(inst);
4301 const dst_ty = self.typeOf(bin_op.lhs);4323 const dst_ty = self.typeOf(bin_op.lhs);
4302 const result: MCValue = switch (dst_ty.zigTypeTag(mod)) {4324 const result: MCValue = switch (dst_ty.zigTypeTag(mod)) {
4303 .Vector => return self.fail("TODO implement airMulWithOverflow for {}", .{dst_ty.fmt(mod)}),4325 .Vector => return self.fail("TODO implement airMulWithOverflow for {}", .{dst_ty.fmt(pt)}),
4304 .Int => result: {4326 .Int => result: {
4305 const dst_info = dst_ty.intInfo(mod);4327 const dst_info = dst_ty.intInfo(mod);
4306 if (dst_info.bits > 128 and dst_info.signedness == .unsigned) {4328 if (dst_info.bits > 128 and dst_info.signedness == .unsigned) {
4307 const slow_inc = self.hasFeature(.slow_incdec);4329 const slow_inc = self.hasFeature(.slow_incdec);
4308 const abi_size: u32 = @intCast(dst_ty.abiSize(mod));4330 const abi_size: u32 = @intCast(dst_ty.abiSize(pt));
4309 const limb_len = math.divCeil(u32, abi_size, 8) catch unreachable;4331 const limb_len = math.divCeil(u32, abi_size, 8) catch unreachable;
43104332
4311 try self.spillRegisters(&.{ .rax, .rcx, .rdx });4333 try self.spillRegisters(&.{ .rax, .rcx, .rdx });
...@@ -4316,7 +4338,7 @@ fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) !void {...@@ -4316,7 +4338,7 @@ fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) !void {
4316 try self.genInlineMemset(4338 try self.genInlineMemset(
4317 dst_mcv.address(),4339 dst_mcv.address(),
4318 .{ .immediate = 0 },4340 .{ .immediate = 0 },
4319 .{ .immediate = tuple_ty.abiSize(mod) },4341 .{ .immediate = tuple_ty.abiSize(pt) },
4320 .{},4342 .{},
4321 );4343 );
4322 const lhs_mcv = try self.resolveInst(bin_op.lhs);4344 const lhs_mcv = try self.resolveInst(bin_op.lhs);
...@@ -4356,7 +4378,7 @@ fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) !void {...@@ -4356,7 +4378,7 @@ fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) !void {
4356 .index = temp_regs[3].to64(),4378 .index = temp_regs[3].to64(),
4357 .scale = .@"8",4379 .scale = .@"8",
4358 .disp = dst_mcv.load_frame.off +4380 .disp = dst_mcv.load_frame.off +
4359 @as(i32, @intCast(tuple_ty.structFieldOffset(0, mod))),4381 @as(i32, @intCast(tuple_ty.structFieldOffset(0, pt))),
4360 } },4382 } },
4361 }, .rdx);4383 }, .rdx);
4362 try self.asmSetccRegister(.c, .cl);4384 try self.asmSetccRegister(.c, .cl);
...@@ -4380,7 +4402,7 @@ fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) !void {...@@ -4380,7 +4402,7 @@ fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) !void {
4380 .index = temp_regs[3].to64(),4402 .index = temp_regs[3].to64(),
4381 .scale = .@"8",4403 .scale = .@"8",
4382 .disp = dst_mcv.load_frame.off +4404 .disp = dst_mcv.load_frame.off +
4383 @as(i32, @intCast(tuple_ty.structFieldOffset(0, mod))),4405 @as(i32, @intCast(tuple_ty.structFieldOffset(0, pt))),
4384 } },4406 } },
4385 }, .rax);4407 }, .rax);
4386 try self.asmSetccRegister(.c, .ch);4408 try self.asmSetccRegister(.c, .ch);
...@@ -4429,7 +4451,7 @@ fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) !void {...@@ -4429,7 +4451,7 @@ fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) !void {
4429 .mod = .{ .rm = .{4451 .mod = .{ .rm = .{
4430 .size = .byte,4452 .size = .byte,
4431 .disp = dst_mcv.load_frame.off +4453 .disp = dst_mcv.load_frame.off +
4432 @as(i32, @intCast(tuple_ty.structFieldOffset(1, mod))),4454 @as(i32, @intCast(tuple_ty.structFieldOffset(1, pt))),
4433 } },4455 } },
4434 }, Immediate.u(1));4456 }, Immediate.u(1));
4435 self.performReloc(no_overflow);4457 self.performReloc(no_overflow);
...@@ -4453,11 +4475,11 @@ fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) !void {...@@ -4453,11 +4475,11 @@ fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) !void {
4453 const lhs_active_bits = self.activeIntBits(bin_op.lhs);4475 const lhs_active_bits = self.activeIntBits(bin_op.lhs);
4454 const rhs_active_bits = self.activeIntBits(bin_op.rhs);4476 const rhs_active_bits = self.activeIntBits(bin_op.rhs);
4455 const src_bits = @max(lhs_active_bits, rhs_active_bits, dst_info.bits / 2);4477 const src_bits = @max(lhs_active_bits, rhs_active_bits, dst_info.bits / 2);
4456 const src_ty = try mod.intType(dst_info.signedness, src_bits);4478 const src_ty = try pt.intType(dst_info.signedness, src_bits);
4457 if (src_bits > 64 and src_bits <= 128 and4479 if (src_bits > 64 and src_bits <= 128 and
4458 dst_info.bits > 64 and dst_info.bits <= 128) switch (dst_info.signedness) {4480 dst_info.bits > 64 and dst_info.bits <= 128) switch (dst_info.signedness) {
4459 .signed => {4481 .signed => {
4460 const ptr_c_int = try mod.singleMutPtrType(Type.c_int);4482 const ptr_c_int = try pt.singleMutPtrType(Type.c_int);
4461 const overflow = try self.allocTempRegOrMem(Type.c_int, false);4483 const overflow = try self.allocTempRegOrMem(Type.c_int, false);
4462 const result = try self.genCall(.{ .lib = .{4484 const result = try self.genCall(.{ .lib = .{
4463 .return_type = .i128_type,4485 .return_type = .i128_type,
...@@ -4472,7 +4494,7 @@ fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) !void {...@@ -4472,7 +4494,7 @@ fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) !void {
4472 const dst_mcv = try self.allocRegOrMem(inst, false);4494 const dst_mcv = try self.allocRegOrMem(inst, false);
4473 try self.genSetMem(4495 try self.genSetMem(
4474 .{ .frame = dst_mcv.load_frame.index },4496 .{ .frame = dst_mcv.load_frame.index },
4475 @intCast(tuple_ty.structFieldOffset(0, mod)),4497 @intCast(tuple_ty.structFieldOffset(0, pt)),
4476 tuple_ty.structFieldType(0, mod),4498 tuple_ty.structFieldType(0, mod),
4477 result,4499 result,
4478 .{},4500 .{},
...@@ -4484,7 +4506,7 @@ fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) !void {...@@ -4484,7 +4506,7 @@ fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) !void {
4484 );4506 );
4485 try self.genSetMem(4507 try self.genSetMem(
4486 .{ .frame = dst_mcv.load_frame.index },4508 .{ .frame = dst_mcv.load_frame.index },
4487 @intCast(tuple_ty.structFieldOffset(1, mod)),4509 @intCast(tuple_ty.structFieldOffset(1, pt)),
4488 tuple_ty.structFieldType(1, mod),4510 tuple_ty.structFieldType(1, mod),
4489 .{ .eflags = .ne },4511 .{ .eflags = .ne },
4490 .{},4512 .{},
...@@ -4596,14 +4618,14 @@ fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) !void {...@@ -4596,14 +4618,14 @@ fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) !void {
4596 const dst_mcv = try self.allocRegOrMem(inst, false);4618 const dst_mcv = try self.allocRegOrMem(inst, false);
4597 try self.genSetMem(4619 try self.genSetMem(
4598 .{ .frame = dst_mcv.load_frame.index },4620 .{ .frame = dst_mcv.load_frame.index },
4599 @intCast(tuple_ty.structFieldOffset(0, mod)),4621 @intCast(tuple_ty.structFieldOffset(0, pt)),
4600 tuple_ty.structFieldType(0, mod),4622 tuple_ty.structFieldType(0, mod),
4601 .{ .register_pair = .{ .rax, .rdx } },4623 .{ .register_pair = .{ .rax, .rdx } },
4602 .{},4624 .{},
4603 );4625 );
4604 try self.genSetMem(4626 try self.genSetMem(
4605 .{ .frame = dst_mcv.load_frame.index },4627 .{ .frame = dst_mcv.load_frame.index },
4606 @intCast(tuple_ty.structFieldOffset(1, mod)),4628 @intCast(tuple_ty.structFieldOffset(1, pt)),
4607 tuple_ty.structFieldType(1, mod),4629 tuple_ty.structFieldType(1, mod),
4608 .{ .register = tmp_regs[1] },4630 .{ .register = tmp_regs[1] },
4609 .{},4631 .{},
...@@ -4636,7 +4658,7 @@ fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) !void {...@@ -4636,7 +4658,7 @@ fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) !void {
4636 self.eflags_inst = inst;4658 self.eflags_inst = inst;
4637 break :result .{ .register_overflow = .{ .reg = reg, .eflags = cc } };4659 break :result .{ .register_overflow = .{ .reg = reg, .eflags = cc } };
4638 } else {4660 } else {
4639 const frame_index = try self.allocFrameIndex(FrameAlloc.initSpill(tuple_ty, mod));4661 const frame_index = try self.allocFrameIndex(FrameAlloc.initSpill(tuple_ty, pt));
4640 try self.genSetFrameTruncatedOverflowCompare(tuple_ty, frame_index, partial_mcv, cc);4662 try self.genSetFrameTruncatedOverflowCompare(tuple_ty, frame_index, partial_mcv, cc);
4641 break :result .{ .load_frame = .{ .index = frame_index } };4663 break :result .{ .load_frame = .{ .index = frame_index } };
4642 },4664 },
...@@ -4644,21 +4666,21 @@ fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) !void {...@@ -4644,21 +4666,21 @@ fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) !void {
4644 // For now, this is the only supported multiply that doesn't fit in a register.4666 // For now, this is the only supported multiply that doesn't fit in a register.
4645 if (dst_info.bits > 128 or src_bits != 64)4667 if (dst_info.bits > 128 or src_bits != 64)
4646 return self.fail("TODO implement airWithOverflow from {} to {}", .{4668 return self.fail("TODO implement airWithOverflow from {} to {}", .{
4647 src_ty.fmt(mod), dst_ty.fmt(mod),4669 src_ty.fmt(pt), dst_ty.fmt(pt),
4648 });4670 });
46494671
4650 const frame_index = try self.allocFrameIndex(FrameAlloc.initSpill(tuple_ty, mod));4672 const frame_index = try self.allocFrameIndex(FrameAlloc.initSpill(tuple_ty, pt));
4651 if (dst_info.bits >= lhs_active_bits + rhs_active_bits) {4673 if (dst_info.bits >= lhs_active_bits + rhs_active_bits) {
4652 try self.genSetMem(4674 try self.genSetMem(
4653 .{ .frame = frame_index },4675 .{ .frame = frame_index },
4654 @intCast(tuple_ty.structFieldOffset(0, mod)),4676 @intCast(tuple_ty.structFieldOffset(0, pt)),
4655 tuple_ty.structFieldType(0, mod),4677 tuple_ty.structFieldType(0, mod),
4656 partial_mcv,4678 partial_mcv,
4657 .{},4679 .{},
4658 );4680 );
4659 try self.genSetMem(4681 try self.genSetMem(
4660 .{ .frame = frame_index },4682 .{ .frame = frame_index },
4661 @intCast(tuple_ty.structFieldOffset(1, mod)),4683 @intCast(tuple_ty.structFieldOffset(1, pt)),
4662 tuple_ty.structFieldType(1, mod),4684 tuple_ty.structFieldType(1, mod),
4663 .{ .immediate = 0 }, // cc being set is impossible4685 .{ .immediate = 0 }, // cc being set is impossible
4664 .{},4686 .{},
...@@ -4682,8 +4704,8 @@ fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) !void {...@@ -4682,8 +4704,8 @@ fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) !void {
4682/// Clobbers .rax and .rdx registers.4704/// Clobbers .rax and .rdx registers.
4683/// Quotient is saved in .rax and remainder in .rdx.4705/// Quotient is saved in .rax and remainder in .rdx.
4684fn genIntMulDivOpMir(self: *Self, tag: Mir.Inst.FixedTag, ty: Type, lhs: MCValue, rhs: MCValue) !void {4706fn genIntMulDivOpMir(self: *Self, tag: Mir.Inst.FixedTag, ty: Type, lhs: MCValue, rhs: MCValue) !void {
4685 const mod = self.bin_file.comp.module.?;4707 const pt = self.pt;
4686 const abi_size: u32 = @intCast(ty.abiSize(mod));4708 const abi_size: u32 = @intCast(ty.abiSize(pt));
4687 const bit_size: u32 = @intCast(self.regBitSize(ty));4709 const bit_size: u32 = @intCast(self.regBitSize(ty));
4688 if (abi_size > 8) {4710 if (abi_size > 8) {
4689 return self.fail("TODO implement genIntMulDivOpMir for ABI size larger than 8", .{});4711 return self.fail("TODO implement genIntMulDivOpMir for ABI size larger than 8", .{});
...@@ -4732,8 +4754,9 @@ fn genIntMulDivOpMir(self: *Self, tag: Mir.Inst.FixedTag, ty: Type, lhs: MCValue...@@ -4732,8 +4754,9 @@ fn genIntMulDivOpMir(self: *Self, tag: Mir.Inst.FixedTag, ty: Type, lhs: MCValue
4732/// Always returns a register.4754/// Always returns a register.
4733/// Clobbers .rax and .rdx registers.4755/// Clobbers .rax and .rdx registers.
4734fn genInlineIntDivFloor(self: *Self, ty: Type, lhs: MCValue, rhs: MCValue) !MCValue {4756fn genInlineIntDivFloor(self: *Self, ty: Type, lhs: MCValue, rhs: MCValue) !MCValue {
4735 const mod = self.bin_file.comp.module.?;4757 const pt = self.pt;
4736 const abi_size: u32 = @intCast(ty.abiSize(mod));4758 const mod = pt.zcu;
4759 const abi_size: u32 = @intCast(ty.abiSize(pt));
4737 const int_info = ty.intInfo(mod);4760 const int_info = ty.intInfo(mod);
4738 const dividend = switch (lhs) {4761 const dividend = switch (lhs) {
4739 .register => |reg| reg,4762 .register => |reg| reg,
...@@ -4784,7 +4807,8 @@ fn genInlineIntDivFloor(self: *Self, ty: Type, lhs: MCValue, rhs: MCValue) !MCVa...@@ -4784,7 +4807,8 @@ fn genInlineIntDivFloor(self: *Self, ty: Type, lhs: MCValue, rhs: MCValue) !MCVa
4784}4807}
47854808
4786fn airShlShrBinOp(self: *Self, inst: Air.Inst.Index) !void {4809fn airShlShrBinOp(self: *Self, inst: Air.Inst.Index) !void {
4787 const mod = self.bin_file.comp.module.?;4810 const pt = self.pt;
4811 const mod = pt.zcu;
4788 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;4812 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
47894813
4790 const air_tags = self.air.instructions.items(.tag);4814 const air_tags = self.air.instructions.items(.tag);
...@@ -4811,7 +4835,7 @@ fn airShlShrBinOp(self: *Self, inst: Air.Inst.Index) !void {...@@ -4811,7 +4835,7 @@ fn airShlShrBinOp(self: *Self, inst: Air.Inst.Index) !void {
4811 const tmp_lock = self.register_manager.lockRegAssumeUnused(tmp_reg);4835 const tmp_lock = self.register_manager.lockRegAssumeUnused(tmp_reg);
4812 defer self.register_manager.unlockReg(tmp_lock);4836 defer self.register_manager.unlockReg(tmp_lock);
48134837
4814 const lhs_bits: u31 = @intCast(lhs_ty.bitSize(mod));4838 const lhs_bits: u31 = @intCast(lhs_ty.bitSize(pt));
4815 const tmp_ty = if (lhs_bits > 64) Type.usize else lhs_ty;4839 const tmp_ty = if (lhs_bits > 64) Type.usize else lhs_ty;
4816 const off = frame_addr.off + (lhs_bits - 1) / 64 * 8;4840 const off = frame_addr.off + (lhs_bits - 1) / 64 * 8;
4817 try self.genSetReg(4841 try self.genSetReg(
...@@ -4922,11 +4946,11 @@ fn airShlShrBinOp(self: *Self, inst: Air.Inst.Index) !void {...@@ -4922,11 +4946,11 @@ fn airShlShrBinOp(self: *Self, inst: Air.Inst.Index) !void {
4922 .shl, .shl_exact => if (self.hasFeature(.avx2)) .{ .vp_q, .sll } else null,4946 .shl, .shl_exact => if (self.hasFeature(.avx2)) .{ .vp_q, .sll } else null,
4923 },4947 },
4924 },4948 },
4925 })) |mir_tag| if (try self.air.value(bin_op.rhs, mod)) |rhs_val| {4949 })) |mir_tag| if (try self.air.value(bin_op.rhs, pt)) |rhs_val| {
4926 switch (mod.intern_pool.indexToKey(rhs_val.toIntern())) {4950 switch (mod.intern_pool.indexToKey(rhs_val.toIntern())) {
4927 .aggregate => |rhs_aggregate| switch (rhs_aggregate.storage) {4951 .aggregate => |rhs_aggregate| switch (rhs_aggregate.storage) {
4928 .repeated_elem => |rhs_elem| {4952 .repeated_elem => |rhs_elem| {
4929 const abi_size: u32 = @intCast(lhs_ty.abiSize(mod));4953 const abi_size: u32 = @intCast(lhs_ty.abiSize(pt));
49304954
4931 const lhs_mcv = try self.resolveInst(bin_op.lhs);4955 const lhs_mcv = try self.resolveInst(bin_op.lhs);
4932 const dst_reg, const lhs_reg = if (lhs_mcv.isRegister() and4956 const dst_reg, const lhs_reg = if (lhs_mcv.isRegister() and
...@@ -4946,7 +4970,7 @@ fn airShlShrBinOp(self: *Self, inst: Air.Inst.Index) !void {...@@ -4946,7 +4970,7 @@ fn airShlShrBinOp(self: *Self, inst: Air.Inst.Index) !void {
4946 self.register_manager.unlockReg(lock);4970 self.register_manager.unlockReg(lock);
49474971
4948 const shift_imm =4972 const shift_imm =
4949 Immediate.u(@intCast(Value.fromInterned(rhs_elem).toUnsignedInt(mod)));4973 Immediate.u(@intCast(Value.fromInterned(rhs_elem).toUnsignedInt(pt)));
4950 if (self.hasFeature(.avx)) try self.asmRegisterRegisterImmediate(4974 if (self.hasFeature(.avx)) try self.asmRegisterRegisterImmediate(
4951 mir_tag,4975 mir_tag,
4952 registerAlias(dst_reg, abi_size),4976 registerAlias(dst_reg, abi_size),
...@@ -4968,7 +4992,7 @@ fn airShlShrBinOp(self: *Self, inst: Air.Inst.Index) !void {...@@ -4968,7 +4992,7 @@ fn airShlShrBinOp(self: *Self, inst: Air.Inst.Index) !void {
4968 }4992 }
4969 } else if (bin_op.rhs.toIndex()) |rhs_inst| switch (air_tags[@intFromEnum(rhs_inst)]) {4993 } else if (bin_op.rhs.toIndex()) |rhs_inst| switch (air_tags[@intFromEnum(rhs_inst)]) {
4970 .splat => {4994 .splat => {
4971 const abi_size: u32 = @intCast(lhs_ty.abiSize(mod));4995 const abi_size: u32 = @intCast(lhs_ty.abiSize(pt));
49724996
4973 const lhs_mcv = try self.resolveInst(bin_op.lhs);4997 const lhs_mcv = try self.resolveInst(bin_op.lhs);
4974 const dst_reg, const lhs_reg = if (lhs_mcv.isRegister() and4998 const dst_reg, const lhs_reg = if (lhs_mcv.isRegister() and
...@@ -4991,13 +5015,13 @@ fn airShlShrBinOp(self: *Self, inst: Air.Inst.Index) !void {...@@ -4991,13 +5015,13 @@ fn airShlShrBinOp(self: *Self, inst: Air.Inst.Index) !void {
4991 const shift_lock = self.register_manager.lockRegAssumeUnused(shift_reg);5015 const shift_lock = self.register_manager.lockRegAssumeUnused(shift_reg);
4992 defer self.register_manager.unlockReg(shift_lock);5016 defer self.register_manager.unlockReg(shift_lock);
49935017
4994 const mask_ty = try mod.vectorType(.{ .len = 16, .child = .u8_type });5018 const mask_ty = try pt.vectorType(.{ .len = 16, .child = .u8_type });
4995 const mask_mcv = try self.genTypedValue(Value.fromInterned(try mod.intern(.{ .aggregate = .{5019 const mask_mcv = try self.genTypedValue(Value.fromInterned(try pt.intern(.{ .aggregate = .{
4996 .ty = mask_ty.toIntern(),5020 .ty = mask_ty.toIntern(),
4997 .storage = .{ .elems = &([1]InternPool.Index{5021 .storage = .{ .elems = &([1]InternPool.Index{
4998 (try rhs_ty.childType(mod).maxIntScalar(mod, Type.u8)).toIntern(),5022 (try rhs_ty.childType(mod).maxIntScalar(pt, Type.u8)).toIntern(),
4999 } ++ [1]InternPool.Index{5023 } ++ [1]InternPool.Index{
5000 (try mod.intValue(Type.u8, 0)).toIntern(),5024 (try pt.intValue(Type.u8, 0)).toIntern(),
5001 } ** 15) },5025 } ** 15) },
5002 } })));5026 } })));
5003 const mask_addr_reg =5027 const mask_addr_reg =
...@@ -5045,7 +5069,7 @@ fn airShlShrBinOp(self: *Self, inst: Air.Inst.Index) !void {...@@ -5045,7 +5069,7 @@ fn airShlShrBinOp(self: *Self, inst: Air.Inst.Index) !void {
5045 },5069 },
5046 else => {},5070 else => {},
5047 }5071 }
5048 return self.fail("TODO implement airShlShrBinOp for {}", .{lhs_ty.fmt(mod)});5072 return self.fail("TODO implement airShlShrBinOp for {}", .{lhs_ty.fmt(pt)});
5049 };5073 };
5050 return self.finishAir(inst, result, .{ bin_op.lhs, bin_op.rhs, .none });5074 return self.finishAir(inst, result, .{ bin_op.lhs, bin_op.rhs, .none });
5051}5075}
...@@ -5058,11 +5082,11 @@ fn airShlSat(self: *Self, inst: Air.Inst.Index) !void {...@@ -5058,11 +5082,11 @@ fn airShlSat(self: *Self, inst: Air.Inst.Index) !void {
5058}5082}
50595083
5060fn airOptionalPayload(self: *Self, inst: Air.Inst.Index) !void {5084fn airOptionalPayload(self: *Self, inst: Air.Inst.Index) !void {
5061 const mod = self.bin_file.comp.module.?;5085 const pt = self.pt;
5062 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;5086 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
5063 const result: MCValue = result: {5087 const result: MCValue = result: {
5064 const pl_ty = self.typeOfIndex(inst);5088 const pl_ty = self.typeOfIndex(inst);
5065 if (!pl_ty.hasRuntimeBitsIgnoreComptime(mod)) break :result .none;5089 if (!pl_ty.hasRuntimeBitsIgnoreComptime(pt)) break :result .none;
50665090
5067 const opt_mcv = try self.resolveInst(ty_op.operand);5091 const opt_mcv = try self.resolveInst(ty_op.operand);
5068 if (self.reuseOperand(inst, ty_op.operand, 0, opt_mcv)) {5092 if (self.reuseOperand(inst, ty_op.operand, 0, opt_mcv)) {
...@@ -5104,7 +5128,8 @@ fn airOptionalPayloadPtr(self: *Self, inst: Air.Inst.Index) !void {...@@ -5104,7 +5128,8 @@ fn airOptionalPayloadPtr(self: *Self, inst: Air.Inst.Index) !void {
5104}5128}
51055129
5106fn airOptionalPayloadPtrSet(self: *Self, inst: Air.Inst.Index) !void {5130fn airOptionalPayloadPtrSet(self: *Self, inst: Air.Inst.Index) !void {
5107 const mod = self.bin_file.comp.module.?;5131 const pt = self.pt;
5132 const mod = pt.zcu;
5108 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;5133 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
5109 const result = result: {5134 const result = result: {
5110 const dst_ty = self.typeOfIndex(inst);5135 const dst_ty = self.typeOfIndex(inst);
...@@ -5130,7 +5155,7 @@ fn airOptionalPayloadPtrSet(self: *Self, inst: Air.Inst.Index) !void {...@@ -5130,7 +5155,7 @@ fn airOptionalPayloadPtrSet(self: *Self, inst: Air.Inst.Index) !void {
5130 try self.copyToRegisterWithInstTracking(inst, dst_ty, src_mcv);5155 try self.copyToRegisterWithInstTracking(inst, dst_ty, src_mcv);
51315156
5132 const pl_ty = dst_ty.childType(mod);5157 const pl_ty = dst_ty.childType(mod);
5133 const pl_abi_size: i32 = @intCast(pl_ty.abiSize(mod));5158 const pl_abi_size: i32 = @intCast(pl_ty.abiSize(pt));
5134 try self.genSetMem(5159 try self.genSetMem(
5135 .{ .reg = dst_mcv.getReg().? },5160 .{ .reg = dst_mcv.getReg().? },
5136 pl_abi_size,5161 pl_abi_size,
...@@ -5144,7 +5169,8 @@ fn airOptionalPayloadPtrSet(self: *Self, inst: Air.Inst.Index) !void {...@@ -5144,7 +5169,8 @@ fn airOptionalPayloadPtrSet(self: *Self, inst: Air.Inst.Index) !void {
5144}5169}
51455170
5146fn airUnwrapErrUnionErr(self: *Self, inst: Air.Inst.Index) !void {5171fn airUnwrapErrUnionErr(self: *Self, inst: Air.Inst.Index) !void {
5147 const mod = self.bin_file.comp.module.?;5172 const pt = self.pt;
5173 const mod = pt.zcu;
5148 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;5174 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
5149 const err_union_ty = self.typeOf(ty_op.operand);5175 const err_union_ty = self.typeOf(ty_op.operand);
5150 const err_ty = err_union_ty.errorUnionSet(mod);5176 const err_ty = err_union_ty.errorUnionSet(mod);
...@@ -5156,11 +5182,11 @@ fn airUnwrapErrUnionErr(self: *Self, inst: Air.Inst.Index) !void {...@@ -5156,11 +5182,11 @@ fn airUnwrapErrUnionErr(self: *Self, inst: Air.Inst.Index) !void {
5156 break :result MCValue{ .immediate = 0 };5182 break :result MCValue{ .immediate = 0 };
5157 }5183 }
51585184
5159 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) {5185 if (!payload_ty.hasRuntimeBitsIgnoreComptime(pt)) {
5160 break :result operand;5186 break :result operand;
5161 }5187 }
51625188
5163 const err_off = errUnionErrorOffset(payload_ty, mod);5189 const err_off = errUnionErrorOffset(payload_ty, pt);
5164 switch (operand) {5190 switch (operand) {
5165 .register => |reg| {5191 .register => |reg| {
5166 // TODO reuse operand5192 // TODO reuse operand
...@@ -5197,7 +5223,8 @@ fn airUnwrapErrUnionPayload(self: *Self, inst: Air.Inst.Index) !void {...@@ -5197,7 +5223,8 @@ fn airUnwrapErrUnionPayload(self: *Self, inst: Air.Inst.Index) !void {
51975223
5198// *(E!T) -> E5224// *(E!T) -> E
5199fn airUnwrapErrUnionErrPtr(self: *Self, inst: Air.Inst.Index) !void {5225fn airUnwrapErrUnionErrPtr(self: *Self, inst: Air.Inst.Index) !void {
5200 const mod = self.bin_file.comp.module.?;5226 const pt = self.pt;
5227 const mod = pt.zcu;
5201 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;5228 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
52025229
5203 const src_ty = self.typeOf(ty_op.operand);5230 const src_ty = self.typeOf(ty_op.operand);
...@@ -5217,8 +5244,8 @@ fn airUnwrapErrUnionErrPtr(self: *Self, inst: Air.Inst.Index) !void {...@@ -5217,8 +5244,8 @@ fn airUnwrapErrUnionErrPtr(self: *Self, inst: Air.Inst.Index) !void {
5217 const eu_ty = src_ty.childType(mod);5244 const eu_ty = src_ty.childType(mod);
5218 const pl_ty = eu_ty.errorUnionPayload(mod);5245 const pl_ty = eu_ty.errorUnionPayload(mod);
5219 const err_ty = eu_ty.errorUnionSet(mod);5246 const err_ty = eu_ty.errorUnionSet(mod);
5220 const err_off: i32 = @intCast(errUnionErrorOffset(pl_ty, mod));5247 const err_off: i32 = @intCast(errUnionErrorOffset(pl_ty, pt));
5221 const err_abi_size: u32 = @intCast(err_ty.abiSize(mod));5248 const err_abi_size: u32 = @intCast(err_ty.abiSize(pt));
5222 try self.asmRegisterMemory(5249 try self.asmRegisterMemory(
5223 .{ ._, .mov },5250 .{ ._, .mov },
5224 registerAlias(dst_reg, err_abi_size),5251 registerAlias(dst_reg, err_abi_size),
...@@ -5244,7 +5271,8 @@ fn airUnwrapErrUnionPayloadPtr(self: *Self, inst: Air.Inst.Index) !void {...@@ -5244,7 +5271,8 @@ fn airUnwrapErrUnionPayloadPtr(self: *Self, inst: Air.Inst.Index) !void {
5244}5271}
52455272
5246fn airErrUnionPayloadPtrSet(self: *Self, inst: Air.Inst.Index) !void {5273fn airErrUnionPayloadPtrSet(self: *Self, inst: Air.Inst.Index) !void {
5247 const mod = self.bin_file.comp.module.?;5274 const pt = self.pt;
5275 const mod = pt.zcu;
5248 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;5276 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
5249 const result: MCValue = result: {5277 const result: MCValue = result: {
5250 const src_ty = self.typeOf(ty_op.operand);5278 const src_ty = self.typeOf(ty_op.operand);
...@@ -5259,8 +5287,8 @@ fn airErrUnionPayloadPtrSet(self: *Self, inst: Air.Inst.Index) !void {...@@ -5259,8 +5287,8 @@ fn airErrUnionPayloadPtrSet(self: *Self, inst: Air.Inst.Index) !void {
5259 const eu_ty = src_ty.childType(mod);5287 const eu_ty = src_ty.childType(mod);
5260 const pl_ty = eu_ty.errorUnionPayload(mod);5288 const pl_ty = eu_ty.errorUnionPayload(mod);
5261 const err_ty = eu_ty.errorUnionSet(mod);5289 const err_ty = eu_ty.errorUnionSet(mod);
5262 const err_off: i32 = @intCast(errUnionErrorOffset(pl_ty, mod));5290 const err_off: i32 = @intCast(errUnionErrorOffset(pl_ty, pt));
5263 const err_abi_size: u32 = @intCast(err_ty.abiSize(mod));5291 const err_abi_size: u32 = @intCast(err_ty.abiSize(pt));
5264 try self.asmMemoryImmediate(5292 try self.asmMemoryImmediate(
5265 .{ ._, .mov },5293 .{ ._, .mov },
5266 .{5294 .{
...@@ -5283,8 +5311,8 @@ fn airErrUnionPayloadPtrSet(self: *Self, inst: Air.Inst.Index) !void {...@@ -5283,8 +5311,8 @@ fn airErrUnionPayloadPtrSet(self: *Self, inst: Air.Inst.Index) !void {
5283 const dst_lock = self.register_manager.lockReg(dst_reg);5311 const dst_lock = self.register_manager.lockReg(dst_reg);
5284 defer if (dst_lock) |lock| self.register_manager.unlockReg(lock);5312 defer if (dst_lock) |lock| self.register_manager.unlockReg(lock);
52855313
5286 const pl_off: i32 = @intCast(errUnionPayloadOffset(pl_ty, mod));5314 const pl_off: i32 = @intCast(errUnionPayloadOffset(pl_ty, pt));
5287 const dst_abi_size: u32 = @intCast(dst_ty.abiSize(mod));5315 const dst_abi_size: u32 = @intCast(dst_ty.abiSize(pt));
5288 try self.asmRegisterMemory(5316 try self.asmRegisterMemory(
5289 .{ ._, .lea },5317 .{ ._, .lea },
5290 registerAlias(dst_reg, dst_abi_size),5318 registerAlias(dst_reg, dst_abi_size),
...@@ -5304,13 +5332,14 @@ fn genUnwrapErrUnionPayloadMir(...@@ -5304,13 +5332,14 @@ fn genUnwrapErrUnionPayloadMir(
5304 err_union_ty: Type,5332 err_union_ty: Type,
5305 err_union: MCValue,5333 err_union: MCValue,
5306) !MCValue {5334) !MCValue {
5307 const mod = self.bin_file.comp.module.?;5335 const pt = self.pt;
5336 const mod = pt.zcu;
5308 const payload_ty = err_union_ty.errorUnionPayload(mod);5337 const payload_ty = err_union_ty.errorUnionPayload(mod);
53095338
5310 const result: MCValue = result: {5339 const result: MCValue = result: {
5311 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) break :result .none;5340 if (!payload_ty.hasRuntimeBitsIgnoreComptime(pt)) break :result .none;
53125341
5313 const payload_off: u31 = @intCast(errUnionPayloadOffset(payload_ty, mod));5342 const payload_off: u31 = @intCast(errUnionPayloadOffset(payload_ty, pt));
5314 switch (err_union) {5343 switch (err_union) {
5315 .load_frame => |frame_addr| break :result .{ .load_frame = .{5344 .load_frame => |frame_addr| break :result .{ .load_frame = .{
5316 .index = frame_addr.index,5345 .index = frame_addr.index,
...@@ -5353,12 +5382,13 @@ fn genUnwrapErrUnionPayloadPtrMir(...@@ -5353,12 +5382,13 @@ fn genUnwrapErrUnionPayloadPtrMir(
5353 ptr_ty: Type,5382 ptr_ty: Type,
5354 ptr_mcv: MCValue,5383 ptr_mcv: MCValue,
5355) !MCValue {5384) !MCValue {
5356 const mod = self.bin_file.comp.module.?;5385 const pt = self.pt;
5386 const mod = pt.zcu;
5357 const err_union_ty = ptr_ty.childType(mod);5387 const err_union_ty = ptr_ty.childType(mod);
5358 const payload_ty = err_union_ty.errorUnionPayload(mod);5388 const payload_ty = err_union_ty.errorUnionPayload(mod);
53595389
5360 const result: MCValue = result: {5390 const result: MCValue = result: {
5361 const payload_off = errUnionPayloadOffset(payload_ty, mod);5391 const payload_off = errUnionPayloadOffset(payload_ty, pt);
5362 const result_mcv: MCValue = if (maybe_inst) |inst|5392 const result_mcv: MCValue = if (maybe_inst) |inst|
5363 try self.copyToRegisterWithInstTracking(inst, ptr_ty, ptr_mcv)5393 try self.copyToRegisterWithInstTracking(inst, ptr_ty, ptr_mcv)
5364 else5394 else
...@@ -5387,11 +5417,12 @@ fn airSaveErrReturnTraceIndex(self: *Self, inst: Air.Inst.Index) !void {...@@ -5387,11 +5417,12 @@ fn airSaveErrReturnTraceIndex(self: *Self, inst: Air.Inst.Index) !void {
5387}5417}
53885418
5389fn airWrapOptional(self: *Self, inst: Air.Inst.Index) !void {5419fn airWrapOptional(self: *Self, inst: Air.Inst.Index) !void {
5390 const mod = self.bin_file.comp.module.?;5420 const pt = self.pt;
5421 const mod = pt.zcu;
5391 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;5422 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
5392 const result: MCValue = result: {5423 const result: MCValue = result: {
5393 const pl_ty = self.typeOf(ty_op.operand);5424 const pl_ty = self.typeOf(ty_op.operand);
5394 if (!pl_ty.hasRuntimeBits(mod)) break :result .{ .immediate = 1 };5425 if (!pl_ty.hasRuntimeBits(pt)) break :result .{ .immediate = 1 };
53955426
5396 const opt_ty = self.typeOfIndex(inst);5427 const opt_ty = self.typeOfIndex(inst);
5397 const pl_mcv = try self.resolveInst(ty_op.operand);5428 const pl_mcv = try self.resolveInst(ty_op.operand);
...@@ -5408,7 +5439,7 @@ fn airWrapOptional(self: *Self, inst: Air.Inst.Index) !void {...@@ -5408,7 +5439,7 @@ fn airWrapOptional(self: *Self, inst: Air.Inst.Index) !void {
5408 try self.genCopy(pl_ty, opt_mcv, pl_mcv, .{});5439 try self.genCopy(pl_ty, opt_mcv, pl_mcv, .{});
54095440
5410 if (!same_repr) {5441 if (!same_repr) {
5411 const pl_abi_size: i32 = @intCast(pl_ty.abiSize(mod));5442 const pl_abi_size: i32 = @intCast(pl_ty.abiSize(pt));
5412 switch (opt_mcv) {5443 switch (opt_mcv) {
5413 else => unreachable,5444 else => unreachable,
54145445
...@@ -5441,7 +5472,8 @@ fn airWrapOptional(self: *Self, inst: Air.Inst.Index) !void {...@@ -5441,7 +5472,8 @@ fn airWrapOptional(self: *Self, inst: Air.Inst.Index) !void {
54415472
5442/// T to E!T5473/// T to E!T
5443fn airWrapErrUnionPayload(self: *Self, inst: Air.Inst.Index) !void {5474fn airWrapErrUnionPayload(self: *Self, inst: Air.Inst.Index) !void {
5444 const mod = self.bin_file.comp.module.?;5475 const pt = self.pt;
5476 const mod = pt.zcu;
5445 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;5477 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
54465478
5447 const eu_ty = ty_op.ty.toType();5479 const eu_ty = ty_op.ty.toType();
...@@ -5450,11 +5482,11 @@ fn airWrapErrUnionPayload(self: *Self, inst: Air.Inst.Index) !void {...@@ -5450,11 +5482,11 @@ fn airWrapErrUnionPayload(self: *Self, inst: Air.Inst.Index) !void {
5450 const operand = try self.resolveInst(ty_op.operand);5482 const operand = try self.resolveInst(ty_op.operand);
54515483
5452 const result: MCValue = result: {5484 const result: MCValue = result: {
5453 if (!pl_ty.hasRuntimeBitsIgnoreComptime(mod)) break :result .{ .immediate = 0 };5485 if (!pl_ty.hasRuntimeBitsIgnoreComptime(pt)) break :result .{ .immediate = 0 };
54545486
5455 const frame_index = try self.allocFrameIndex(FrameAlloc.initSpill(eu_ty, mod));5487 const frame_index = try self.allocFrameIndex(FrameAlloc.initSpill(eu_ty, pt));
5456 const pl_off: i32 = @intCast(errUnionPayloadOffset(pl_ty, mod));5488 const pl_off: i32 = @intCast(errUnionPayloadOffset(pl_ty, pt));
5457 const err_off: i32 = @intCast(errUnionErrorOffset(pl_ty, mod));5489 const err_off: i32 = @intCast(errUnionErrorOffset(pl_ty, pt));
5458 try self.genSetMem(.{ .frame = frame_index }, pl_off, pl_ty, operand, .{});5490 try self.genSetMem(.{ .frame = frame_index }, pl_off, pl_ty, operand, .{});
5459 try self.genSetMem(.{ .frame = frame_index }, err_off, err_ty, .{ .immediate = 0 }, .{});5491 try self.genSetMem(.{ .frame = frame_index }, err_off, err_ty, .{ .immediate = 0 }, .{});
5460 break :result .{ .load_frame = .{ .index = frame_index } };5492 break :result .{ .load_frame = .{ .index = frame_index } };
...@@ -5464,7 +5496,8 @@ fn airWrapErrUnionPayload(self: *Self, inst: Air.Inst.Index) !void {...@@ -5464,7 +5496,8 @@ fn airWrapErrUnionPayload(self: *Self, inst: Air.Inst.Index) !void {
54645496
5465/// E to E!T5497/// E to E!T
5466fn airWrapErrUnionErr(self: *Self, inst: Air.Inst.Index) !void {5498fn airWrapErrUnionErr(self: *Self, inst: Air.Inst.Index) !void {
5467 const mod = self.bin_file.comp.module.?;5499 const pt = self.pt;
5500 const mod = pt.zcu;
5468 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;5501 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
54695502
5470 const eu_ty = ty_op.ty.toType();5503 const eu_ty = ty_op.ty.toType();
...@@ -5472,11 +5505,11 @@ fn airWrapErrUnionErr(self: *Self, inst: Air.Inst.Index) !void {...@@ -5472,11 +5505,11 @@ fn airWrapErrUnionErr(self: *Self, inst: Air.Inst.Index) !void {
5472 const err_ty = eu_ty.errorUnionSet(mod);5505 const err_ty = eu_ty.errorUnionSet(mod);
54735506
5474 const result: MCValue = result: {5507 const result: MCValue = result: {
5475 if (!pl_ty.hasRuntimeBitsIgnoreComptime(mod)) break :result try self.resolveInst(ty_op.operand);5508 if (!pl_ty.hasRuntimeBitsIgnoreComptime(pt)) break :result try self.resolveInst(ty_op.operand);
54765509
5477 const frame_index = try self.allocFrameIndex(FrameAlloc.initSpill(eu_ty, mod));5510 const frame_index = try self.allocFrameIndex(FrameAlloc.initSpill(eu_ty, pt));
5478 const pl_off: i32 = @intCast(errUnionPayloadOffset(pl_ty, mod));5511 const pl_off: i32 = @intCast(errUnionPayloadOffset(pl_ty, pt));
5479 const err_off: i32 = @intCast(errUnionErrorOffset(pl_ty, mod));5512 const err_off: i32 = @intCast(errUnionErrorOffset(pl_ty, pt));
5480 try self.genSetMem(.{ .frame = frame_index }, pl_off, pl_ty, .undef, .{});5513 try self.genSetMem(.{ .frame = frame_index }, pl_off, pl_ty, .undef, .{});
5481 const operand = try self.resolveInst(ty_op.operand);5514 const operand = try self.resolveInst(ty_op.operand);
5482 try self.genSetMem(.{ .frame = frame_index }, err_off, err_ty, operand, .{});5515 try self.genSetMem(.{ .frame = frame_index }, err_off, err_ty, operand, .{});
...@@ -5523,7 +5556,7 @@ fn airSliceLen(self: *Self, inst: Air.Inst.Index) !void {...@@ -5523,7 +5556,7 @@ fn airSliceLen(self: *Self, inst: Air.Inst.Index) !void {
5523}5556}
55245557
5525fn airPtrSliceLenPtr(self: *Self, inst: Air.Inst.Index) !void {5558fn airPtrSliceLenPtr(self: *Self, inst: Air.Inst.Index) !void {
5526 const mod = self.bin_file.comp.module.?;5559 const pt = self.pt;
5527 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;5560 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
55285561
5529 const src_ty = self.typeOf(ty_op.operand);5562 const src_ty = self.typeOf(ty_op.operand);
...@@ -5544,7 +5577,7 @@ fn airPtrSliceLenPtr(self: *Self, inst: Air.Inst.Index) !void {...@@ -5544,7 +5577,7 @@ fn airPtrSliceLenPtr(self: *Self, inst: Air.Inst.Index) !void {
5544 const dst_lock = self.register_manager.lockReg(dst_reg);5577 const dst_lock = self.register_manager.lockReg(dst_reg);
5545 defer if (dst_lock) |lock| self.register_manager.unlockReg(lock);5578 defer if (dst_lock) |lock| self.register_manager.unlockReg(lock);
55465579
5547 const dst_abi_size: u32 = @intCast(dst_ty.abiSize(mod));5580 const dst_abi_size: u32 = @intCast(dst_ty.abiSize(pt));
5548 try self.asmRegisterMemory(5581 try self.asmRegisterMemory(
5549 .{ ._, .lea },5582 .{ ._, .lea },
5550 registerAlias(dst_reg, dst_abi_size),5583 registerAlias(dst_reg, dst_abi_size),
...@@ -5591,7 +5624,8 @@ fn elemOffset(self: *Self, index_ty: Type, index: MCValue, elem_size: u64) !Regi...@@ -5591,7 +5624,8 @@ fn elemOffset(self: *Self, index_ty: Type, index: MCValue, elem_size: u64) !Regi
5591}5624}
55925625
5593fn genSliceElemPtr(self: *Self, lhs: Air.Inst.Ref, rhs: Air.Inst.Ref) !MCValue {5626fn genSliceElemPtr(self: *Self, lhs: Air.Inst.Ref, rhs: Air.Inst.Ref) !MCValue {
5594 const mod = self.bin_file.comp.module.?;5627 const pt = self.pt;
5628 const mod = pt.zcu;
5595 const slice_ty = self.typeOf(lhs);5629 const slice_ty = self.typeOf(lhs);
5596 const slice_mcv = try self.resolveInst(lhs);5630 const slice_mcv = try self.resolveInst(lhs);
5597 const slice_mcv_lock: ?RegisterLock = switch (slice_mcv) {5631 const slice_mcv_lock: ?RegisterLock = switch (slice_mcv) {
...@@ -5601,7 +5635,7 @@ fn genSliceElemPtr(self: *Self, lhs: Air.Inst.Ref, rhs: Air.Inst.Ref) !MCValue {...@@ -5601,7 +5635,7 @@ fn genSliceElemPtr(self: *Self, lhs: Air.Inst.Ref, rhs: Air.Inst.Ref) !MCValue {
5601 defer if (slice_mcv_lock) |lock| self.register_manager.unlockReg(lock);5635 defer if (slice_mcv_lock) |lock| self.register_manager.unlockReg(lock);
56025636
5603 const elem_ty = slice_ty.childType(mod);5637 const elem_ty = slice_ty.childType(mod);
5604 const elem_size = elem_ty.abiSize(mod);5638 const elem_size = elem_ty.abiSize(pt);
5605 const slice_ptr_field_type = slice_ty.slicePtrFieldType(mod);5639 const slice_ptr_field_type = slice_ty.slicePtrFieldType(mod);
56065640
5607 const index_ty = self.typeOf(rhs);5641 const index_ty = self.typeOf(rhs);
...@@ -5627,12 +5661,13 @@ fn genSliceElemPtr(self: *Self, lhs: Air.Inst.Ref, rhs: Air.Inst.Ref) !MCValue {...@@ -5627,12 +5661,13 @@ fn genSliceElemPtr(self: *Self, lhs: Air.Inst.Ref, rhs: Air.Inst.Ref) !MCValue {
5627}5661}
56285662
5629fn airSliceElemVal(self: *Self, inst: Air.Inst.Index) !void {5663fn airSliceElemVal(self: *Self, inst: Air.Inst.Index) !void {
5630 const mod = self.bin_file.comp.module.?;5664 const pt = self.pt;
5665 const mod = pt.zcu;
5631 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;5666 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
56325667
5633 const result: MCValue = result: {5668 const result: MCValue = result: {
5634 const elem_ty = self.typeOfIndex(inst);5669 const elem_ty = self.typeOfIndex(inst);
5635 if (!elem_ty.hasRuntimeBitsIgnoreComptime(mod)) break :result .none;5670 if (!elem_ty.hasRuntimeBitsIgnoreComptime(pt)) break :result .none;
56365671
5637 const slice_ty = self.typeOf(bin_op.lhs);5672 const slice_ty = self.typeOf(bin_op.lhs);
5638 const slice_ptr_field_type = slice_ty.slicePtrFieldType(mod);5673 const slice_ptr_field_type = slice_ty.slicePtrFieldType(mod);
...@@ -5652,7 +5687,8 @@ fn airSliceElemPtr(self: *Self, inst: Air.Inst.Index) !void {...@@ -5652,7 +5687,8 @@ fn airSliceElemPtr(self: *Self, inst: Air.Inst.Index) !void {
5652}5687}
56535688
5654fn airArrayElemVal(self: *Self, inst: Air.Inst.Index) !void {5689fn airArrayElemVal(self: *Self, inst: Air.Inst.Index) !void {
5655 const mod = self.bin_file.comp.module.?;5690 const pt = self.pt;
5691 const mod = pt.zcu;
5656 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;5692 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
56575693
5658 const result: MCValue = result: {5694 const result: MCValue = result: {
...@@ -5675,7 +5711,7 @@ fn airArrayElemVal(self: *Self, inst: Air.Inst.Index) !void {...@@ -5675,7 +5711,7 @@ fn airArrayElemVal(self: *Self, inst: Air.Inst.Index) !void {
5675 defer if (index_lock) |lock| self.register_manager.unlockReg(lock);5711 defer if (index_lock) |lock| self.register_manager.unlockReg(lock);
56765712
5677 try self.spillEflagsIfOccupied();5713 try self.spillEflagsIfOccupied();
5678 if (array_ty.isVector(mod) and elem_ty.bitSize(mod) == 1) {5714 if (array_ty.isVector(mod) and elem_ty.bitSize(pt) == 1) {
5679 const index_reg = switch (index_mcv) {5715 const index_reg = switch (index_mcv) {
5680 .register => |reg| reg,5716 .register => |reg| reg,
5681 else => try self.copyToTmpRegister(index_ty, index_mcv),5717 else => try self.copyToTmpRegister(index_ty, index_mcv),
...@@ -5688,7 +5724,7 @@ fn airArrayElemVal(self: *Self, inst: Air.Inst.Index) !void {...@@ -5688,7 +5724,7 @@ fn airArrayElemVal(self: *Self, inst: Air.Inst.Index) !void {
5688 index_reg.to64(),5724 index_reg.to64(),
5689 ),5725 ),
5690 .sse => {5726 .sse => {
5691 const frame_index = try self.allocFrameIndex(FrameAlloc.initType(array_ty, mod));5727 const frame_index = try self.allocFrameIndex(FrameAlloc.initType(array_ty, pt));
5692 try self.genSetMem(.{ .frame = frame_index }, 0, array_ty, array_mcv, .{});5728 try self.genSetMem(.{ .frame = frame_index }, 0, array_ty, array_mcv, .{});
5693 try self.asmMemoryRegister(5729 try self.asmMemoryRegister(
5694 .{ ._, .bt },5730 .{ ._, .bt },
...@@ -5717,7 +5753,7 @@ fn airArrayElemVal(self: *Self, inst: Air.Inst.Index) !void {...@@ -5717,7 +5753,7 @@ fn airArrayElemVal(self: *Self, inst: Air.Inst.Index) !void {
5717 index_reg.to64(),5753 index_reg.to64(),
5718 ),5754 ),
5719 else => return self.fail("TODO airArrayElemVal for {s} of {}", .{5755 else => return self.fail("TODO airArrayElemVal for {s} of {}", .{
5720 @tagName(array_mcv), array_ty.fmt(mod),5756 @tagName(array_mcv), array_ty.fmt(pt),
5721 }),5757 }),
5722 }5758 }
57235759
...@@ -5726,14 +5762,14 @@ fn airArrayElemVal(self: *Self, inst: Air.Inst.Index) !void {...@@ -5726,14 +5762,14 @@ fn airArrayElemVal(self: *Self, inst: Air.Inst.Index) !void {
5726 break :result .{ .register = dst_reg };5762 break :result .{ .register = dst_reg };
5727 }5763 }
57285764
5729 const elem_abi_size = elem_ty.abiSize(mod);5765 const elem_abi_size = elem_ty.abiSize(pt);
5730 const addr_reg = try self.register_manager.allocReg(null, abi.RegisterClass.gp);5766 const addr_reg = try self.register_manager.allocReg(null, abi.RegisterClass.gp);
5731 const addr_lock = self.register_manager.lockRegAssumeUnused(addr_reg);5767 const addr_lock = self.register_manager.lockRegAssumeUnused(addr_reg);
5732 defer self.register_manager.unlockReg(addr_lock);5768 defer self.register_manager.unlockReg(addr_lock);
57335769
5734 switch (array_mcv) {5770 switch (array_mcv) {
5735 .register => {5771 .register => {
5736 const frame_index = try self.allocFrameIndex(FrameAlloc.initType(array_ty, mod));5772 const frame_index = try self.allocFrameIndex(FrameAlloc.initType(array_ty, pt));
5737 try self.genSetMem(.{ .frame = frame_index }, 0, array_ty, array_mcv, .{});5773 try self.genSetMem(.{ .frame = frame_index }, 0, array_ty, array_mcv, .{});
5738 try self.asmRegisterMemory(5774 try self.asmRegisterMemory(
5739 .{ ._, .lea },5775 .{ ._, .lea },
...@@ -5757,7 +5793,7 @@ fn airArrayElemVal(self: *Self, inst: Air.Inst.Index) !void {...@@ -5757,7 +5793,7 @@ fn airArrayElemVal(self: *Self, inst: Air.Inst.Index) !void {
5757 => try self.genSetReg(addr_reg, Type.usize, array_mcv.address(), .{}),5793 => try self.genSetReg(addr_reg, Type.usize, array_mcv.address(), .{}),
5758 .lea_symbol, .lea_direct, .lea_tlv => unreachable,5794 .lea_symbol, .lea_direct, .lea_tlv => unreachable,
5759 else => return self.fail("TODO airArrayElemVal_val for {s} of {}", .{5795 else => return self.fail("TODO airArrayElemVal_val for {s} of {}", .{
5760 @tagName(array_mcv), array_ty.fmt(mod),5796 @tagName(array_mcv), array_ty.fmt(pt),
5761 }),5797 }),
5762 }5798 }
57635799
...@@ -5781,7 +5817,8 @@ fn airArrayElemVal(self: *Self, inst: Air.Inst.Index) !void {...@@ -5781,7 +5817,8 @@ fn airArrayElemVal(self: *Self, inst: Air.Inst.Index) !void {
5781}5817}
57825818
5783fn airPtrElemVal(self: *Self, inst: Air.Inst.Index) !void {5819fn airPtrElemVal(self: *Self, inst: Air.Inst.Index) !void {
5784 const mod = self.bin_file.comp.module.?;5820 const pt = self.pt;
5821 const mod = pt.zcu;
5785 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;5822 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
5786 const ptr_ty = self.typeOf(bin_op.lhs);5823 const ptr_ty = self.typeOf(bin_op.lhs);
57875824
...@@ -5790,9 +5827,9 @@ fn airPtrElemVal(self: *Self, inst: Air.Inst.Index) !void {...@@ -5790,9 +5827,9 @@ fn airPtrElemVal(self: *Self, inst: Air.Inst.Index) !void {
57905827
5791 const result = result: {5828 const result = result: {
5792 const elem_ty = ptr_ty.elemType2(mod);5829 const elem_ty = ptr_ty.elemType2(mod);
5793 if (!elem_ty.hasRuntimeBitsIgnoreComptime(mod)) break :result .none;5830 if (!elem_ty.hasRuntimeBitsIgnoreComptime(pt)) break :result .none;
57945831
5795 const elem_abi_size: u32 = @intCast(elem_ty.abiSize(mod));5832 const elem_abi_size: u32 = @intCast(elem_ty.abiSize(pt));
5796 const index_ty = self.typeOf(bin_op.rhs);5833 const index_ty = self.typeOf(bin_op.rhs);
5797 const index_mcv = try self.resolveInst(bin_op.rhs);5834 const index_mcv = try self.resolveInst(bin_op.rhs);
5798 const index_lock = switch (index_mcv) {5835 const index_lock = switch (index_mcv) {
...@@ -5831,7 +5868,8 @@ fn airPtrElemVal(self: *Self, inst: Air.Inst.Index) !void {...@@ -5831,7 +5868,8 @@ fn airPtrElemVal(self: *Self, inst: Air.Inst.Index) !void {
5831}5868}
58325869
5833fn airPtrElemPtr(self: *Self, inst: Air.Inst.Index) !void {5870fn airPtrElemPtr(self: *Self, inst: Air.Inst.Index) !void {
5834 const mod = self.bin_file.comp.module.?;5871 const pt = self.pt;
5872 const mod = pt.zcu;
5835 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;5873 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
5836 const extra = self.air.extraData(Air.Bin, ty_pl.payload).data;5874 const extra = self.air.extraData(Air.Bin, ty_pl.payload).data;
58375875
...@@ -5854,7 +5892,7 @@ fn airPtrElemPtr(self: *Self, inst: Air.Inst.Index) !void {...@@ -5854,7 +5892,7 @@ fn airPtrElemPtr(self: *Self, inst: Air.Inst.Index) !void {
5854 }5892 }
58555893
5856 const elem_ty = base_ptr_ty.elemType2(mod);5894 const elem_ty = base_ptr_ty.elemType2(mod);
5857 const elem_abi_size = elem_ty.abiSize(mod);5895 const elem_abi_size = elem_ty.abiSize(pt);
5858 const index_ty = self.typeOf(extra.rhs);5896 const index_ty = self.typeOf(extra.rhs);
5859 const index_mcv = try self.resolveInst(extra.rhs);5897 const index_mcv = try self.resolveInst(extra.rhs);
5860 const index_lock: ?RegisterLock = switch (index_mcv) {5898 const index_lock: ?RegisterLock = switch (index_mcv) {
...@@ -5876,12 +5914,13 @@ fn airPtrElemPtr(self: *Self, inst: Air.Inst.Index) !void {...@@ -5876,12 +5914,13 @@ fn airPtrElemPtr(self: *Self, inst: Air.Inst.Index) !void {
5876}5914}
58775915
5878fn airSetUnionTag(self: *Self, inst: Air.Inst.Index) !void {5916fn airSetUnionTag(self: *Self, inst: Air.Inst.Index) !void {
5879 const mod = self.bin_file.comp.module.?;5917 const pt = self.pt;
5918 const mod = pt.zcu;
5880 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;5919 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
5881 const ptr_union_ty = self.typeOf(bin_op.lhs);5920 const ptr_union_ty = self.typeOf(bin_op.lhs);
5882 const union_ty = ptr_union_ty.childType(mod);5921 const union_ty = ptr_union_ty.childType(mod);
5883 const tag_ty = self.typeOf(bin_op.rhs);5922 const tag_ty = self.typeOf(bin_op.rhs);
5884 const layout = union_ty.unionGetLayout(mod);5923 const layout = union_ty.unionGetLayout(pt);
58855924
5886 if (layout.tag_size == 0) {5925 if (layout.tag_size == 0) {
5887 return self.finishAir(inst, .none, .{ bin_op.lhs, bin_op.rhs, .none });5926 return self.finishAir(inst, .none, .{ bin_op.lhs, bin_op.rhs, .none });
...@@ -5913,19 +5952,19 @@ fn airSetUnionTag(self: *Self, inst: Air.Inst.Index) !void {...@@ -5913,19 +5952,19 @@ fn airSetUnionTag(self: *Self, inst: Air.Inst.Index) !void {
5913 break :blk MCValue{ .register = reg };5952 break :blk MCValue{ .register = reg };
5914 } else ptr;5953 } else ptr;
59155954
5916 const ptr_tag_ty = try mod.adjustPtrTypeChild(ptr_union_ty, tag_ty);5955 const ptr_tag_ty = try pt.adjustPtrTypeChild(ptr_union_ty, tag_ty);
5917 try self.store(ptr_tag_ty, adjusted_ptr, tag, .{});5956 try self.store(ptr_tag_ty, adjusted_ptr, tag, .{});
59185957
5919 return self.finishAir(inst, .none, .{ bin_op.lhs, bin_op.rhs, .none });5958 return self.finishAir(inst, .none, .{ bin_op.lhs, bin_op.rhs, .none });
5920}5959}
59215960
5922fn airGetUnionTag(self: *Self, inst: Air.Inst.Index) !void {5961fn airGetUnionTag(self: *Self, inst: Air.Inst.Index) !void {
5923 const mod = self.bin_file.comp.module.?;5962 const pt = self.pt;
5924 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;5963 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
59255964
5926 const tag_ty = self.typeOfIndex(inst);5965 const tag_ty = self.typeOfIndex(inst);
5927 const union_ty = self.typeOf(ty_op.operand);5966 const union_ty = self.typeOf(ty_op.operand);
5928 const layout = union_ty.unionGetLayout(mod);5967 const layout = union_ty.unionGetLayout(pt);
59295968
5930 if (layout.tag_size == 0) {5969 if (layout.tag_size == 0) {
5931 return self.finishAir(inst, .none, .{ ty_op.operand, .none, .none });5970 return self.finishAir(inst, .none, .{ ty_op.operand, .none, .none });
...@@ -5939,7 +5978,7 @@ fn airGetUnionTag(self: *Self, inst: Air.Inst.Index) !void {...@@ -5939,7 +5978,7 @@ fn airGetUnionTag(self: *Self, inst: Air.Inst.Index) !void {
5939 };5978 };
5940 defer if (operand_lock) |lock| self.register_manager.unlockReg(lock);5979 defer if (operand_lock) |lock| self.register_manager.unlockReg(lock);
59415980
5942 const tag_abi_size = tag_ty.abiSize(mod);5981 const tag_abi_size = tag_ty.abiSize(pt);
5943 const dst_mcv: MCValue = blk: {5982 const dst_mcv: MCValue = blk: {
5944 switch (operand) {5983 switch (operand) {
5945 .load_frame => |frame_addr| {5984 .load_frame => |frame_addr| {
...@@ -5983,7 +6022,8 @@ fn airGetUnionTag(self: *Self, inst: Air.Inst.Index) !void {...@@ -5983,7 +6022,8 @@ fn airGetUnionTag(self: *Self, inst: Air.Inst.Index) !void {
5983}6022}
59846023
5985fn airClz(self: *Self, inst: Air.Inst.Index) !void {6024fn airClz(self: *Self, inst: Air.Inst.Index) !void {
5986 const mod = self.bin_file.comp.module.?;6025 const pt = self.pt;
6026 const mod = pt.zcu;
5987 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;6027 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
5988 const result = result: {6028 const result = result: {
5989 try self.spillEflagsIfOccupied();6029 try self.spillEflagsIfOccupied();
...@@ -5991,7 +6031,7 @@ fn airClz(self: *Self, inst: Air.Inst.Index) !void {...@@ -5991,7 +6031,7 @@ fn airClz(self: *Self, inst: Air.Inst.Index) !void {
5991 const dst_ty = self.typeOfIndex(inst);6031 const dst_ty = self.typeOfIndex(inst);
5992 const src_ty = self.typeOf(ty_op.operand);6032 const src_ty = self.typeOf(ty_op.operand);
5993 if (src_ty.zigTypeTag(mod) == .Vector) return self.fail("TODO implement airClz for {}", .{6033 if (src_ty.zigTypeTag(mod) == .Vector) return self.fail("TODO implement airClz for {}", .{
5994 src_ty.fmt(mod),6034 src_ty.fmt(pt),
5995 });6035 });
59966036
5997 const src_mcv = try self.resolveInst(ty_op.operand);6037 const src_mcv = try self.resolveInst(ty_op.operand);
...@@ -6010,8 +6050,8 @@ fn airClz(self: *Self, inst: Air.Inst.Index) !void {...@@ -6010,8 +6050,8 @@ fn airClz(self: *Self, inst: Air.Inst.Index) !void {
6010 const dst_lock = self.register_manager.lockRegAssumeUnused(dst_reg);6050 const dst_lock = self.register_manager.lockRegAssumeUnused(dst_reg);
6011 defer self.register_manager.unlockReg(dst_lock);6051 defer self.register_manager.unlockReg(dst_lock);
60126052
6013 const abi_size: u31 = @intCast(src_ty.abiSize(mod));6053 const abi_size: u31 = @intCast(src_ty.abiSize(pt));
6014 const src_bits: u31 = @intCast(src_ty.bitSize(mod));6054 const src_bits: u31 = @intCast(src_ty.bitSize(pt));
6015 const has_lzcnt = self.hasFeature(.lzcnt);6055 const has_lzcnt = self.hasFeature(.lzcnt);
6016 if (src_bits > @as(u32, if (has_lzcnt) 128 else 64)) {6056 if (src_bits > @as(u32, if (has_lzcnt) 128 else 64)) {
6017 const limbs_len = math.divCeil(u32, abi_size, 8) catch unreachable;6057 const limbs_len = math.divCeil(u32, abi_size, 8) catch unreachable;
...@@ -6121,7 +6161,7 @@ fn airClz(self: *Self, inst: Air.Inst.Index) !void {...@@ -6121,7 +6161,7 @@ fn airClz(self: *Self, inst: Air.Inst.Index) !void {
6121 }6161 }
61226162
6123 assert(src_bits <= 64);6163 assert(src_bits <= 64);
6124 const cmov_abi_size = @max(@as(u32, @intCast(dst_ty.abiSize(mod))), 2);6164 const cmov_abi_size = @max(@as(u32, @intCast(dst_ty.abiSize(pt))), 2);
6125 if (math.isPowerOfTwo(src_bits)) {6165 if (math.isPowerOfTwo(src_bits)) {
6126 const imm_reg = try self.copyToTmpRegister(dst_ty, .{6166 const imm_reg = try self.copyToTmpRegister(dst_ty, .{
6127 .immediate = src_bits ^ (src_bits - 1),6167 .immediate = src_bits ^ (src_bits - 1),
...@@ -6179,7 +6219,8 @@ fn airClz(self: *Self, inst: Air.Inst.Index) !void {...@@ -6179,7 +6219,8 @@ fn airClz(self: *Self, inst: Air.Inst.Index) !void {
6179}6219}
61806220
6181fn airCtz(self: *Self, inst: Air.Inst.Index) !void {6221fn airCtz(self: *Self, inst: Air.Inst.Index) !void {
6182 const mod = self.bin_file.comp.module.?;6222 const pt = self.pt;
6223 const mod = pt.zcu;
6183 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;6224 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
6184 const result = result: {6225 const result = result: {
6185 try self.spillEflagsIfOccupied();6226 try self.spillEflagsIfOccupied();
...@@ -6187,7 +6228,7 @@ fn airCtz(self: *Self, inst: Air.Inst.Index) !void {...@@ -6187,7 +6228,7 @@ fn airCtz(self: *Self, inst: Air.Inst.Index) !void {
6187 const dst_ty = self.typeOfIndex(inst);6228 const dst_ty = self.typeOfIndex(inst);
6188 const src_ty = self.typeOf(ty_op.operand);6229 const src_ty = self.typeOf(ty_op.operand);
6189 if (src_ty.zigTypeTag(mod) == .Vector) return self.fail("TODO implement airCtz for {}", .{6230 if (src_ty.zigTypeTag(mod) == .Vector) return self.fail("TODO implement airCtz for {}", .{
6190 src_ty.fmt(mod),6231 src_ty.fmt(pt),
6191 });6232 });
61926233
6193 const src_mcv = try self.resolveInst(ty_op.operand);6234 const src_mcv = try self.resolveInst(ty_op.operand);
...@@ -6206,8 +6247,8 @@ fn airCtz(self: *Self, inst: Air.Inst.Index) !void {...@@ -6206,8 +6247,8 @@ fn airCtz(self: *Self, inst: Air.Inst.Index) !void {
6206 const dst_lock = self.register_manager.lockReg(dst_reg);6247 const dst_lock = self.register_manager.lockReg(dst_reg);
6207 defer if (dst_lock) |lock| self.register_manager.unlockReg(lock);6248 defer if (dst_lock) |lock| self.register_manager.unlockReg(lock);
62086249
6209 const abi_size: u31 = @intCast(src_ty.abiSize(mod));6250 const abi_size: u31 = @intCast(src_ty.abiSize(pt));
6210 const src_bits: u31 = @intCast(src_ty.bitSize(mod));6251 const src_bits: u31 = @intCast(src_ty.bitSize(pt));
6211 const has_bmi = self.hasFeature(.bmi);6252 const has_bmi = self.hasFeature(.bmi);
6212 if (src_bits > @as(u32, if (has_bmi) 128 else 64)) {6253 if (src_bits > @as(u32, if (has_bmi) 128 else 64)) {
6213 const limbs_len = math.divCeil(u32, abi_size, 8) catch unreachable;6254 const limbs_len = math.divCeil(u32, abi_size, 8) catch unreachable;
...@@ -6328,7 +6369,7 @@ fn airCtz(self: *Self, inst: Air.Inst.Index) !void {...@@ -6328,7 +6369,7 @@ fn airCtz(self: *Self, inst: Air.Inst.Index) !void {
6328 try self.genBinOpMir(.{ ._, .bsf }, wide_ty, dst_mcv, .{ .register = wide_reg });6369 try self.genBinOpMir(.{ ._, .bsf }, wide_ty, dst_mcv, .{ .register = wide_reg });
6329 } else try self.genBinOpMir(.{ ._, .bsf }, src_ty, dst_mcv, mat_src_mcv);6370 } else try self.genBinOpMir(.{ ._, .bsf }, src_ty, dst_mcv, mat_src_mcv);
63306371
6331 const cmov_abi_size = @max(@as(u32, @intCast(dst_ty.abiSize(mod))), 2);6372 const cmov_abi_size = @max(@as(u32, @intCast(dst_ty.abiSize(pt))), 2);
6332 try self.asmCmovccRegisterRegister(6373 try self.asmCmovccRegisterRegister(
6333 .z,6374 .z,
6334 registerAlias(dst_reg, cmov_abi_size),6375 registerAlias(dst_reg, cmov_abi_size),
...@@ -6340,15 +6381,16 @@ fn airCtz(self: *Self, inst: Air.Inst.Index) !void {...@@ -6340,15 +6381,16 @@ fn airCtz(self: *Self, inst: Air.Inst.Index) !void {
6340}6381}
63416382
6342fn airPopCount(self: *Self, inst: Air.Inst.Index) !void {6383fn airPopCount(self: *Self, inst: Air.Inst.Index) !void {
6343 const mod = self.bin_file.comp.module.?;6384 const pt = self.pt;
6385 const mod = pt.zcu;
6344 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;6386 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
6345 const result: MCValue = result: {6387 const result: MCValue = result: {
6346 try self.spillEflagsIfOccupied();6388 try self.spillEflagsIfOccupied();
63476389
6348 const src_ty = self.typeOf(ty_op.operand);6390 const src_ty = self.typeOf(ty_op.operand);
6349 const src_abi_size: u32 = @intCast(src_ty.abiSize(mod));6391 const src_abi_size: u32 = @intCast(src_ty.abiSize(pt));
6350 if (src_ty.zigTypeTag(mod) == .Vector or src_abi_size > 16)6392 if (src_ty.zigTypeTag(mod) == .Vector or src_abi_size > 16)
6351 return self.fail("TODO implement airPopCount for {}", .{src_ty.fmt(mod)});6393 return self.fail("TODO implement airPopCount for {}", .{src_ty.fmt(pt)});
6352 const src_mcv = try self.resolveInst(ty_op.operand);6394 const src_mcv = try self.resolveInst(ty_op.operand);
63536395
6354 const mat_src_mcv = switch (src_mcv) {6396 const mat_src_mcv = switch (src_mcv) {
...@@ -6385,7 +6427,7 @@ fn airPopCount(self: *Self, inst: Air.Inst.Index) !void {...@@ -6385,7 +6427,7 @@ fn airPopCount(self: *Self, inst: Air.Inst.Index) !void {
6385 else6427 else
6386 .{ .register = mat_src_mcv.register_pair[0] }, false);6428 .{ .register = mat_src_mcv.register_pair[0] }, false);
6387 const src_info = src_ty.intInfo(mod);6429 const src_info = src_ty.intInfo(mod);
6388 const hi_ty = try mod.intType(src_info.signedness, (src_info.bits - 1) % 64 + 1);6430 const hi_ty = try pt.intType(src_info.signedness, (src_info.bits - 1) % 64 + 1);
6389 try self.genPopCount(tmp_regs[1], hi_ty, if (mat_src_mcv.isMemory())6431 try self.genPopCount(tmp_regs[1], hi_ty, if (mat_src_mcv.isMemory())
6390 mat_src_mcv.address().offset(8).deref()6432 mat_src_mcv.address().offset(8).deref()
6391 else6433 else
...@@ -6403,16 +6445,16 @@ fn genPopCount(...@@ -6403,16 +6445,16 @@ fn genPopCount(
6403 src_mcv: MCValue,6445 src_mcv: MCValue,
6404 dst_contains_src: bool,6446 dst_contains_src: bool,
6405) !void {6447) !void {
6406 const mod = self.bin_file.comp.module.?;6448 const pt = self.pt;
64076449
6408 const src_abi_size: u32 = @intCast(src_ty.abiSize(mod));6450 const src_abi_size: u32 = @intCast(src_ty.abiSize(pt));
6409 if (self.hasFeature(.popcnt)) return self.genBinOpMir(6451 if (self.hasFeature(.popcnt)) return self.genBinOpMir(
6410 .{ ._, .popcnt },6452 .{ ._, .popcnt },
6411 if (src_abi_size > 1) src_ty else Type.u32,6453 if (src_abi_size > 1) src_ty else Type.u32,
6412 .{ .register = dst_reg },6454 .{ .register = dst_reg },
6413 if (src_abi_size > 1) src_mcv else src: {6455 if (src_abi_size > 1) src_mcv else src: {
6414 if (!dst_contains_src) try self.genSetReg(dst_reg, src_ty, src_mcv, .{});6456 if (!dst_contains_src) try self.genSetReg(dst_reg, src_ty, src_mcv, .{});
6415 try self.truncateRegister(try src_ty.toUnsigned(mod), dst_reg);6457 try self.truncateRegister(try src_ty.toUnsigned(pt), dst_reg);
6416 break :src .{ .register = dst_reg };6458 break :src .{ .register = dst_reg };
6417 },6459 },
6418 );6460 );
...@@ -6495,13 +6537,14 @@ fn genByteSwap(...@@ -6495,13 +6537,14 @@ fn genByteSwap(
6495 src_mcv: MCValue,6537 src_mcv: MCValue,
6496 mem_ok: bool,6538 mem_ok: bool,
6497) !MCValue {6539) !MCValue {
6498 const mod = self.bin_file.comp.module.?;6540 const pt = self.pt;
6541 const mod = pt.zcu;
6499 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;6542 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
6500 const has_movbe = self.hasFeature(.movbe);6543 const has_movbe = self.hasFeature(.movbe);
65016544
6502 if (src_ty.zigTypeTag(mod) == .Vector) return self.fail(6545 if (src_ty.zigTypeTag(mod) == .Vector) return self.fail(
6503 "TODO implement genByteSwap for {}",6546 "TODO implement genByteSwap for {}",
6504 .{src_ty.fmt(mod)},6547 .{src_ty.fmt(pt)},
6505 );6548 );
65066549
6507 const src_lock = switch (src_mcv) {6550 const src_lock = switch (src_mcv) {
...@@ -6510,7 +6553,7 @@ fn genByteSwap(...@@ -6510,7 +6553,7 @@ fn genByteSwap(
6510 };6553 };
6511 defer if (src_lock) |lock| self.register_manager.unlockReg(lock);6554 defer if (src_lock) |lock| self.register_manager.unlockReg(lock);
65126555
6513 const abi_size: u32 = @intCast(src_ty.abiSize(mod));6556 const abi_size: u32 = @intCast(src_ty.abiSize(pt));
6514 switch (abi_size) {6557 switch (abi_size) {
6515 0 => unreachable,6558 0 => unreachable,
6516 1 => return if ((mem_ok or src_mcv.isRegister()) and6559 1 => return if ((mem_ok or src_mcv.isRegister()) and
...@@ -6658,11 +6701,12 @@ fn genByteSwap(...@@ -6658,11 +6701,12 @@ fn genByteSwap(
6658}6701}
66596702
6660fn airByteSwap(self: *Self, inst: Air.Inst.Index) !void {6703fn airByteSwap(self: *Self, inst: Air.Inst.Index) !void {
6661 const mod = self.bin_file.comp.module.?;6704 const pt = self.pt;
6705 const mod = pt.zcu;
6662 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;6706 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
66636707
6664 const src_ty = self.typeOf(ty_op.operand);6708 const src_ty = self.typeOf(ty_op.operand);
6665 const src_bits: u32 = @intCast(src_ty.bitSize(mod));6709 const src_bits: u32 = @intCast(src_ty.bitSize(pt));
6666 const src_mcv = try self.resolveInst(ty_op.operand);6710 const src_mcv = try self.resolveInst(ty_op.operand);
66676711
6668 const dst_mcv = try self.genByteSwap(inst, src_ty, src_mcv, true);6712 const dst_mcv = try self.genByteSwap(inst, src_ty, src_mcv, true);
...@@ -6674,18 +6718,19 @@ fn airByteSwap(self: *Self, inst: Air.Inst.Index) !void {...@@ -6674,18 +6718,19 @@ fn airByteSwap(self: *Self, inst: Air.Inst.Index) !void {
6674 src_ty,6718 src_ty,
6675 dst_mcv,6719 dst_mcv,
6676 if (src_bits > 256) Type.u16 else Type.u8,6720 if (src_bits > 256) Type.u16 else Type.u8,
6677 .{ .immediate = src_ty.abiSize(mod) * 8 - src_bits },6721 .{ .immediate = src_ty.abiSize(pt) * 8 - src_bits },
6678 );6722 );
6679 return self.finishAir(inst, dst_mcv, .{ ty_op.operand, .none, .none });6723 return self.finishAir(inst, dst_mcv, .{ ty_op.operand, .none, .none });
6680}6724}
66816725
6682fn airBitReverse(self: *Self, inst: Air.Inst.Index) !void {6726fn airBitReverse(self: *Self, inst: Air.Inst.Index) !void {
6683 const mod = self.bin_file.comp.module.?;6727 const pt = self.pt;
6728 const mod = pt.zcu;
6684 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;6729 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
66856730
6686 const src_ty = self.typeOf(ty_op.operand);6731 const src_ty = self.typeOf(ty_op.operand);
6687 const abi_size: u32 = @intCast(src_ty.abiSize(mod));6732 const abi_size: u32 = @intCast(src_ty.abiSize(pt));
6688 const bit_size: u32 = @intCast(src_ty.bitSize(mod));6733 const bit_size: u32 = @intCast(src_ty.bitSize(pt));
6689 const src_mcv = try self.resolveInst(ty_op.operand);6734 const src_mcv = try self.resolveInst(ty_op.operand);
66906735
6691 const dst_mcv = try self.genByteSwap(inst, src_ty, src_mcv, false);6736 const dst_mcv = try self.genByteSwap(inst, src_ty, src_mcv, false);
...@@ -6802,14 +6847,15 @@ fn airBitReverse(self: *Self, inst: Air.Inst.Index) !void {...@@ -6802,14 +6847,15 @@ fn airBitReverse(self: *Self, inst: Air.Inst.Index) !void {
6802}6847}
68036848
6804fn floatSign(self: *Self, inst: Air.Inst.Index, operand: Air.Inst.Ref, ty: Type) !void {6849fn floatSign(self: *Self, inst: Air.Inst.Index, operand: Air.Inst.Ref, ty: Type) !void {
6805 const mod = self.bin_file.comp.module.?;6850 const pt = self.pt;
6851 const mod = pt.zcu;
6806 const tag = self.air.instructions.items(.tag)[@intFromEnum(inst)];6852 const tag = self.air.instructions.items(.tag)[@intFromEnum(inst)];
68076853
6808 const result = result: {6854 const result = result: {
6809 const scalar_bits = ty.scalarType(mod).floatBits(self.target.*);6855 const scalar_bits = ty.scalarType(mod).floatBits(self.target.*);
6810 if (scalar_bits == 80) {6856 if (scalar_bits == 80) {
6811 if (ty.zigTypeTag(mod) != .Float) return self.fail("TODO implement floatSign for {}", .{6857 if (ty.zigTypeTag(mod) != .Float) return self.fail("TODO implement floatSign for {}", .{
6812 ty.fmt(mod),6858 ty.fmt(pt),
6813 });6859 });
68146860
6815 const src_mcv = try self.resolveInst(operand);6861 const src_mcv = try self.resolveInst(operand);
...@@ -6829,11 +6875,11 @@ fn floatSign(self: *Self, inst: Air.Inst.Index, operand: Air.Inst.Ref, ty: Type)...@@ -6829,11 +6875,11 @@ fn floatSign(self: *Self, inst: Air.Inst.Index, operand: Air.Inst.Ref, ty: Type)
6829 break :result dst_mcv;6875 break :result dst_mcv;
6830 }6876 }
68316877
6832 const abi_size: u32 = switch (ty.abiSize(mod)) {6878 const abi_size: u32 = switch (ty.abiSize(pt)) {
6833 1...16 => 16,6879 1...16 => 16,
6834 17...32 => 32,6880 17...32 => 32,
6835 else => return self.fail("TODO implement floatSign for {}", .{6881 else => return self.fail("TODO implement floatSign for {}", .{
6836 ty.fmt(mod),6882 ty.fmt(pt),
6837 }),6883 }),
6838 };6884 };
68396885
...@@ -6852,14 +6898,14 @@ fn floatSign(self: *Self, inst: Air.Inst.Index, operand: Air.Inst.Ref, ty: Type)...@@ -6852,14 +6898,14 @@ fn floatSign(self: *Self, inst: Air.Inst.Index, operand: Air.Inst.Ref, ty: Type)
6852 const dst_lock = self.register_manager.lockReg(dst_reg);6898 const dst_lock = self.register_manager.lockReg(dst_reg);
6853 defer if (dst_lock) |lock| self.register_manager.unlockReg(lock);6899 defer if (dst_lock) |lock| self.register_manager.unlockReg(lock);
68546900
6855 const vec_ty = try mod.vectorType(.{6901 const vec_ty = try pt.vectorType(.{
6856 .len = @divExact(abi_size * 8, scalar_bits),6902 .len = @divExact(abi_size * 8, scalar_bits),
6857 .child = (try mod.intType(.signed, scalar_bits)).ip_index,6903 .child = (try pt.intType(.signed, scalar_bits)).ip_index,
6858 });6904 });
68596905
6860 const sign_mcv = try self.genTypedValue(switch (tag) {6906 const sign_mcv = try self.genTypedValue(switch (tag) {
6861 .neg => try vec_ty.minInt(mod, vec_ty),6907 .neg => try vec_ty.minInt(pt, vec_ty),
6862 .abs => try vec_ty.maxInt(mod, vec_ty),6908 .abs => try vec_ty.maxInt(pt, vec_ty),
6863 else => unreachable,6909 else => unreachable,
6864 });6910 });
6865 const sign_mem: Memory = if (sign_mcv.isMemory())6911 const sign_mem: Memory = if (sign_mcv.isMemory())
...@@ -6891,7 +6937,7 @@ fn floatSign(self: *Self, inst: Air.Inst.Index, operand: Air.Inst.Ref, ty: Type)...@@ -6891,7 +6937,7 @@ fn floatSign(self: *Self, inst: Air.Inst.Index, operand: Air.Inst.Ref, ty: Type)
6891 .abs => .{ .v_pd, .@"and" },6937 .abs => .{ .v_pd, .@"and" },
6892 else => unreachable,6938 else => unreachable,
6893 },6939 },
6894 80 => return self.fail("TODO implement floatSign for {}", .{ty.fmt(mod)}),6940 80 => return self.fail("TODO implement floatSign for {}", .{ty.fmt(pt)}),
6895 else => unreachable,6941 else => unreachable,
6896 },6942 },
6897 registerAlias(dst_reg, abi_size),6943 registerAlias(dst_reg, abi_size),
...@@ -6917,7 +6963,7 @@ fn floatSign(self: *Self, inst: Air.Inst.Index, operand: Air.Inst.Ref, ty: Type)...@@ -6917,7 +6963,7 @@ fn floatSign(self: *Self, inst: Air.Inst.Index, operand: Air.Inst.Ref, ty: Type)
6917 .abs => .{ ._pd, .@"and" },6963 .abs => .{ ._pd, .@"and" },
6918 else => unreachable,6964 else => unreachable,
6919 },6965 },
6920 80 => return self.fail("TODO implement floatSign for {}", .{ty.fmt(mod)}),6966 80 => return self.fail("TODO implement floatSign for {}", .{ty.fmt(pt)}),
6921 else => unreachable,6967 else => unreachable,
6922 },6968 },
6923 registerAlias(dst_reg, abi_size),6969 registerAlias(dst_reg, abi_size),
...@@ -6978,7 +7024,8 @@ fn airRound(self: *Self, inst: Air.Inst.Index, mode: RoundMode) !void {...@@ -6978,7 +7024,8 @@ fn airRound(self: *Self, inst: Air.Inst.Index, mode: RoundMode) !void {
6978}7024}
69797025
6980fn getRoundTag(self: *Self, ty: Type) ?Mir.Inst.FixedTag {7026fn getRoundTag(self: *Self, ty: Type) ?Mir.Inst.FixedTag {
6981 const mod = self.bin_file.comp.module.?;7027 const pt = self.pt;
7028 const mod = pt.zcu;
6982 return if (self.hasFeature(.sse4_1)) switch (ty.zigTypeTag(mod)) {7029 return if (self.hasFeature(.sse4_1)) switch (ty.zigTypeTag(mod)) {
6983 .Float => switch (ty.floatBits(self.target.*)) {7030 .Float => switch (ty.floatBits(self.target.*)) {
6984 32 => if (self.hasFeature(.avx)) .{ .v_ss, .round } else .{ ._ss, .round },7031 32 => if (self.hasFeature(.avx)) .{ .v_ss, .round } else .{ ._ss, .round },
...@@ -7010,11 +7057,12 @@ fn getRoundTag(self: *Self, ty: Type) ?Mir.Inst.FixedTag {...@@ -7010,11 +7057,12 @@ fn getRoundTag(self: *Self, ty: Type) ?Mir.Inst.FixedTag {
7010}7057}
70117058
7012fn genRoundLibcall(self: *Self, ty: Type, src_mcv: MCValue, mode: RoundMode) !MCValue {7059fn genRoundLibcall(self: *Self, ty: Type, src_mcv: MCValue, mode: RoundMode) !MCValue {
7013 const mod = self.bin_file.comp.module.?;7060 const pt = self.pt;
7061 const mod = pt.zcu;
7014 if (self.getRoundTag(ty)) |_| return .none;7062 if (self.getRoundTag(ty)) |_| return .none;
70157063
7016 if (ty.zigTypeTag(mod) != .Float)7064 if (ty.zigTypeTag(mod) != .Float)
7017 return self.fail("TODO implement genRound for {}", .{ty.fmt(mod)});7065 return self.fail("TODO implement genRound for {}", .{ty.fmt(pt)});
70187066
7019 var callee_buf: ["__trunc?".len]u8 = undefined;7067 var callee_buf: ["__trunc?".len]u8 = undefined;
7020 return try self.genCall(.{ .lib = .{7068 return try self.genCall(.{ .lib = .{
...@@ -7034,12 +7082,12 @@ fn genRoundLibcall(self: *Self, ty: Type, src_mcv: MCValue, mode: RoundMode) !MC...@@ -7034,12 +7082,12 @@ fn genRoundLibcall(self: *Self, ty: Type, src_mcv: MCValue, mode: RoundMode) !MC
7034}7082}
70357083
7036fn genRound(self: *Self, ty: Type, dst_reg: Register, src_mcv: MCValue, mode: RoundMode) !void {7084fn genRound(self: *Self, ty: Type, dst_reg: Register, src_mcv: MCValue, mode: RoundMode) !void {
7037 const mod = self.bin_file.comp.module.?;7085 const pt = self.pt;
7038 const mir_tag = self.getRoundTag(ty) orelse {7086 const mir_tag = self.getRoundTag(ty) orelse {
7039 const result = try self.genRoundLibcall(ty, src_mcv, mode);7087 const result = try self.genRoundLibcall(ty, src_mcv, mode);
7040 return self.genSetReg(dst_reg, ty, result, .{});7088 return self.genSetReg(dst_reg, ty, result, .{});
7041 };7089 };
7042 const abi_size: u32 = @intCast(ty.abiSize(mod));7090 const abi_size: u32 = @intCast(ty.abiSize(pt));
7043 const dst_alias = registerAlias(dst_reg, abi_size);7091 const dst_alias = registerAlias(dst_reg, abi_size);
7044 switch (mir_tag[0]) {7092 switch (mir_tag[0]) {
7045 .v_ss, .v_sd => if (src_mcv.isMemory()) try self.asmRegisterRegisterMemoryImmediate(7093 .v_ss, .v_sd => if (src_mcv.isMemory()) try self.asmRegisterRegisterMemoryImmediate(
...@@ -7076,14 +7124,15 @@ fn genRound(self: *Self, ty: Type, dst_reg: Register, src_mcv: MCValue, mode: Ro...@@ -7076,14 +7124,15 @@ fn genRound(self: *Self, ty: Type, dst_reg: Register, src_mcv: MCValue, mode: Ro
7076}7124}
70777125
7078fn airAbs(self: *Self, inst: Air.Inst.Index) !void {7126fn airAbs(self: *Self, inst: Air.Inst.Index) !void {
7079 const mod = self.bin_file.comp.module.?;7127 const pt = self.pt;
7128 const mod = pt.zcu;
7080 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;7129 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
7081 const ty = self.typeOf(ty_op.operand);7130 const ty = self.typeOf(ty_op.operand);
70827131
7083 const result: MCValue = result: {7132 const result: MCValue = result: {
7084 const mir_tag = @as(?Mir.Inst.FixedTag, switch (ty.zigTypeTag(mod)) {7133 const mir_tag = @as(?Mir.Inst.FixedTag, switch (ty.zigTypeTag(mod)) {
7085 else => null,7134 else => null,
7086 .Int => switch (ty.abiSize(mod)) {7135 .Int => switch (ty.abiSize(pt)) {
7087 0 => unreachable,7136 0 => unreachable,
7088 1...8 => {7137 1...8 => {
7089 try self.spillEflagsIfOccupied();7138 try self.spillEflagsIfOccupied();
...@@ -7092,7 +7141,7 @@ fn airAbs(self: *Self, inst: Air.Inst.Index) !void {...@@ -7092,7 +7141,7 @@ fn airAbs(self: *Self, inst: Air.Inst.Index) !void {
70927141
7093 try self.genUnOpMir(.{ ._, .neg }, ty, dst_mcv);7142 try self.genUnOpMir(.{ ._, .neg }, ty, dst_mcv);
70947143
7095 const cmov_abi_size = @max(@as(u32, @intCast(ty.abiSize(mod))), 2);7144 const cmov_abi_size = @max(@as(u32, @intCast(ty.abiSize(pt))), 2);
7096 switch (src_mcv) {7145 switch (src_mcv) {
7097 .register => |val_reg| try self.asmCmovccRegisterRegister(7146 .register => |val_reg| try self.asmCmovccRegisterRegister(
7098 .l,7147 .l,
...@@ -7151,7 +7200,7 @@ fn airAbs(self: *Self, inst: Air.Inst.Index) !void {...@@ -7151,7 +7200,7 @@ fn airAbs(self: *Self, inst: Air.Inst.Index) !void {
7151 break :result dst_mcv;7200 break :result dst_mcv;
7152 },7201 },
7153 else => {7202 else => {
7154 const abi_size: u31 = @intCast(ty.abiSize(mod));7203 const abi_size: u31 = @intCast(ty.abiSize(pt));
7155 const limb_len = math.divCeil(u31, abi_size, 8) catch unreachable;7204 const limb_len = math.divCeil(u31, abi_size, 8) catch unreachable;
71567205
7157 const tmp_regs =7206 const tmp_regs =
...@@ -7249,9 +7298,9 @@ fn airAbs(self: *Self, inst: Air.Inst.Index) !void {...@@ -7249,9 +7298,9 @@ fn airAbs(self: *Self, inst: Air.Inst.Index) !void {
7249 },7298 },
7250 .Float => return self.floatSign(inst, ty_op.operand, ty),7299 .Float => return self.floatSign(inst, ty_op.operand, ty),
7251 },7300 },
7252 }) orelse return self.fail("TODO implement airAbs for {}", .{ty.fmt(mod)});7301 }) orelse return self.fail("TODO implement airAbs for {}", .{ty.fmt(pt)});
72537302
7254 const abi_size: u32 = @intCast(ty.abiSize(mod));7303 const abi_size: u32 = @intCast(ty.abiSize(pt));
7255 const src_mcv = try self.resolveInst(ty_op.operand);7304 const src_mcv = try self.resolveInst(ty_op.operand);
7256 const dst_reg = if (src_mcv.isRegister() and self.reuseOperand(inst, ty_op.operand, 0, src_mcv))7305 const dst_reg = if (src_mcv.isRegister() and self.reuseOperand(inst, ty_op.operand, 0, src_mcv))
7257 src_mcv.getReg().?7306 src_mcv.getReg().?
...@@ -7276,10 +7325,11 @@ fn airAbs(self: *Self, inst: Air.Inst.Index) !void {...@@ -7276,10 +7325,11 @@ fn airAbs(self: *Self, inst: Air.Inst.Index) !void {
7276}7325}
72777326
7278fn airSqrt(self: *Self, inst: Air.Inst.Index) !void {7327fn airSqrt(self: *Self, inst: Air.Inst.Index) !void {
7279 const mod = self.bin_file.comp.module.?;7328 const pt = self.pt;
7329 const mod = pt.zcu;
7280 const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op;7330 const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op;
7281 const ty = self.typeOf(un_op);7331 const ty = self.typeOf(un_op);
7282 const abi_size: u32 = @intCast(ty.abiSize(mod));7332 const abi_size: u32 = @intCast(ty.abiSize(pt));
72837333
7284 const result: MCValue = result: {7334 const result: MCValue = result: {
7285 switch (ty.zigTypeTag(mod)) {7335 switch (ty.zigTypeTag(mod)) {
...@@ -7408,7 +7458,7 @@ fn airSqrt(self: *Self, inst: Air.Inst.Index) !void {...@@ -7408,7 +7458,7 @@ fn airSqrt(self: *Self, inst: Air.Inst.Index) !void {
7408 },7458 },
7409 else => unreachable,7459 else => unreachable,
7410 }) orelse return self.fail("TODO implement airSqrt for {}", .{7460 }) orelse return self.fail("TODO implement airSqrt for {}", .{
7411 ty.fmt(mod),7461 ty.fmt(pt),
7412 });7462 });
7413 switch (mir_tag[0]) {7463 switch (mir_tag[0]) {
7414 .v_ss, .v_sd => if (src_mcv.isMemory()) try self.asmRegisterRegisterMemory(7464 .v_ss, .v_sd => if (src_mcv.isMemory()) try self.asmRegisterRegisterMemory(
...@@ -7521,14 +7571,15 @@ fn reuseOperandAdvanced(...@@ -7521,14 +7571,15 @@ fn reuseOperandAdvanced(
7521}7571}
75227572
7523fn packedLoad(self: *Self, dst_mcv: MCValue, ptr_ty: Type, ptr_mcv: MCValue) InnerError!void {7573fn packedLoad(self: *Self, dst_mcv: MCValue, ptr_ty: Type, ptr_mcv: MCValue) InnerError!void {
7524 const mod = self.bin_file.comp.module.?;7574 const pt = self.pt;
7575 const mod = pt.zcu;
75257576
7526 const ptr_info = ptr_ty.ptrInfo(mod);7577 const ptr_info = ptr_ty.ptrInfo(mod);
7527 const val_ty = Type.fromInterned(ptr_info.child);7578 const val_ty = Type.fromInterned(ptr_info.child);
7528 if (!val_ty.hasRuntimeBitsIgnoreComptime(mod)) return;7579 if (!val_ty.hasRuntimeBitsIgnoreComptime(pt)) return;
7529 const val_abi_size: u32 = @intCast(val_ty.abiSize(mod));7580 const val_abi_size: u32 = @intCast(val_ty.abiSize(pt));
75307581
7531 const val_bit_size: u32 = @intCast(val_ty.bitSize(mod));7582 const val_bit_size: u32 = @intCast(val_ty.bitSize(pt));
7532 const ptr_bit_off = ptr_info.packed_offset.bit_offset + switch (ptr_info.flags.vector_index) {7583 const ptr_bit_off = ptr_info.packed_offset.bit_offset + switch (ptr_info.flags.vector_index) {
7533 .none => 0,7584 .none => 0,
7534 .runtime => unreachable,7585 .runtime => unreachable,
...@@ -7566,7 +7617,7 @@ fn packedLoad(self: *Self, dst_mcv: MCValue, ptr_ty: Type, ptr_mcv: MCValue) Inn...@@ -7566,7 +7617,7 @@ fn packedLoad(self: *Self, dst_mcv: MCValue, ptr_ty: Type, ptr_mcv: MCValue) Inn
7566 return;7617 return;
7567 }7618 }
75687619
7569 if (val_abi_size > 8) return self.fail("TODO implement packed load of {}", .{val_ty.fmt(mod)});7620 if (val_abi_size > 8) return self.fail("TODO implement packed load of {}", .{val_ty.fmt(pt)});
75707621
7571 const limb_abi_size: u31 = @min(val_abi_size, 8);7622 const limb_abi_size: u31 = @min(val_abi_size, 8);
7572 const limb_abi_bits = limb_abi_size * 8;7623 const limb_abi_bits = limb_abi_size * 8;
...@@ -7633,9 +7684,10 @@ fn packedLoad(self: *Self, dst_mcv: MCValue, ptr_ty: Type, ptr_mcv: MCValue) Inn...@@ -7633,9 +7684,10 @@ fn packedLoad(self: *Self, dst_mcv: MCValue, ptr_ty: Type, ptr_mcv: MCValue) Inn
7633}7684}
76347685
7635fn load(self: *Self, dst_mcv: MCValue, ptr_ty: Type, ptr_mcv: MCValue) InnerError!void {7686fn load(self: *Self, dst_mcv: MCValue, ptr_ty: Type, ptr_mcv: MCValue) InnerError!void {
7636 const mod = self.bin_file.comp.module.?;7687 const pt = self.pt;
7688 const mod = pt.zcu;
7637 const dst_ty = ptr_ty.childType(mod);7689 const dst_ty = ptr_ty.childType(mod);
7638 if (!dst_ty.hasRuntimeBitsIgnoreComptime(mod)) return;7690 if (!dst_ty.hasRuntimeBitsIgnoreComptime(pt)) return;
7639 switch (ptr_mcv) {7691 switch (ptr_mcv) {
7640 .none,7692 .none,
7641 .unreach,7693 .unreach,
...@@ -7675,18 +7727,19 @@ fn load(self: *Self, dst_mcv: MCValue, ptr_ty: Type, ptr_mcv: MCValue) InnerErro...@@ -7675,18 +7727,19 @@ fn load(self: *Self, dst_mcv: MCValue, ptr_ty: Type, ptr_mcv: MCValue) InnerErro
7675}7727}
76767728
7677fn airLoad(self: *Self, inst: Air.Inst.Index) !void {7729fn airLoad(self: *Self, inst: Air.Inst.Index) !void {
7678 const mod = self.bin_file.comp.module.?;7730 const pt = self.pt;
7731 const mod = pt.zcu;
7679 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;7732 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
7680 const elem_ty = self.typeOfIndex(inst);7733 const elem_ty = self.typeOfIndex(inst);
7681 const result: MCValue = result: {7734 const result: MCValue = result: {
7682 if (!elem_ty.hasRuntimeBitsIgnoreComptime(mod)) break :result .none;7735 if (!elem_ty.hasRuntimeBitsIgnoreComptime(pt)) break :result .none;
76837736
7684 try self.spillRegisters(&.{ .rdi, .rsi, .rcx });7737 try self.spillRegisters(&.{ .rdi, .rsi, .rcx });
7685 const reg_locks = self.register_manager.lockRegsAssumeUnused(3, .{ .rdi, .rsi, .rcx });7738 const reg_locks = self.register_manager.lockRegsAssumeUnused(3, .{ .rdi, .rsi, .rcx });
7686 defer for (reg_locks) |lock| self.register_manager.unlockReg(lock);7739 defer for (reg_locks) |lock| self.register_manager.unlockReg(lock);
76877740
7688 const ptr_ty = self.typeOf(ty_op.operand);7741 const ptr_ty = self.typeOf(ty_op.operand);
7689 const elem_size = elem_ty.abiSize(mod);7742 const elem_size = elem_ty.abiSize(pt);
76907743
7691 const elem_rc = self.regClassForType(elem_ty);7744 const elem_rc = self.regClassForType(elem_ty);
7692 const ptr_rc = self.regClassForType(ptr_ty);7745 const ptr_rc = self.regClassForType(ptr_ty);
...@@ -7706,7 +7759,7 @@ fn airLoad(self: *Self, inst: Air.Inst.Index) !void {...@@ -7706,7 +7759,7 @@ fn airLoad(self: *Self, inst: Air.Inst.Index) !void {
7706 try self.load(dst_mcv, ptr_ty, ptr_mcv);7759 try self.load(dst_mcv, ptr_ty, ptr_mcv);
7707 }7760 }
77087761
7709 if (elem_ty.isAbiInt(mod) and elem_size * 8 > elem_ty.bitSize(mod)) {7762 if (elem_ty.isAbiInt(mod) and elem_size * 8 > elem_ty.bitSize(pt)) {
7710 const high_mcv: MCValue = switch (dst_mcv) {7763 const high_mcv: MCValue = switch (dst_mcv) {
7711 .register => |dst_reg| .{ .register = dst_reg },7764 .register => |dst_reg| .{ .register = dst_reg },
7712 .register_pair => |dst_regs| .{ .register = dst_regs[1] },7765 .register_pair => |dst_regs| .{ .register = dst_regs[1] },
...@@ -7733,16 +7786,17 @@ fn airLoad(self: *Self, inst: Air.Inst.Index) !void {...@@ -7733,16 +7786,17 @@ fn airLoad(self: *Self, inst: Air.Inst.Index) !void {
7733}7786}
77347787
7735fn packedStore(self: *Self, ptr_ty: Type, ptr_mcv: MCValue, src_mcv: MCValue) InnerError!void {7788fn packedStore(self: *Self, ptr_ty: Type, ptr_mcv: MCValue, src_mcv: MCValue) InnerError!void {
7736 const mod = self.bin_file.comp.module.?;7789 const pt = self.pt;
7790 const mod = pt.zcu;
7737 const ptr_info = ptr_ty.ptrInfo(mod);7791 const ptr_info = ptr_ty.ptrInfo(mod);
7738 const src_ty = Type.fromInterned(ptr_info.child);7792 const src_ty = Type.fromInterned(ptr_info.child);
7739 if (!src_ty.hasRuntimeBitsIgnoreComptime(mod)) return;7793 if (!src_ty.hasRuntimeBitsIgnoreComptime(pt)) return;
77407794
7741 const limb_abi_size: u16 = @min(ptr_info.packed_offset.host_size, 8);7795 const limb_abi_size: u16 = @min(ptr_info.packed_offset.host_size, 8);
7742 const limb_abi_bits = limb_abi_size * 8;7796 const limb_abi_bits = limb_abi_size * 8;
7743 const limb_ty = try mod.intType(.unsigned, limb_abi_bits);7797 const limb_ty = try pt.intType(.unsigned, limb_abi_bits);
77447798
7745 const src_bit_size = src_ty.bitSize(mod);7799 const src_bit_size = src_ty.bitSize(pt);
7746 const ptr_bit_off = ptr_info.packed_offset.bit_offset + switch (ptr_info.flags.vector_index) {7800 const ptr_bit_off = ptr_info.packed_offset.bit_offset + switch (ptr_info.flags.vector_index) {
7747 .none => 0,7801 .none => 0,
7748 .runtime => unreachable,7802 .runtime => unreachable,
...@@ -7827,7 +7881,7 @@ fn packedStore(self: *Self, ptr_ty: Type, ptr_mcv: MCValue, src_mcv: MCValue) In...@@ -7827,7 +7881,7 @@ fn packedStore(self: *Self, ptr_ty: Type, ptr_mcv: MCValue, src_mcv: MCValue) In
7827 limb_mem,7881 limb_mem,
7828 registerAlias(tmp_reg, limb_abi_size),7882 registerAlias(tmp_reg, limb_abi_size),
7829 );7883 );
7830 } else return self.fail("TODO: implement packed store of {}", .{src_ty.fmt(mod)});7884 } else return self.fail("TODO: implement packed store of {}", .{src_ty.fmt(pt)});
7831 }7885 }
7832}7886}
78337887
...@@ -7838,9 +7892,10 @@ fn store(...@@ -7838,9 +7892,10 @@ fn store(
7838 src_mcv: MCValue,7892 src_mcv: MCValue,
7839 opts: CopyOptions,7893 opts: CopyOptions,
7840) InnerError!void {7894) InnerError!void {
7841 const mod = self.bin_file.comp.module.?;7895 const pt = self.pt;
7896 const mod = pt.zcu;
7842 const src_ty = ptr_ty.childType(mod);7897 const src_ty = ptr_ty.childType(mod);
7843 if (!src_ty.hasRuntimeBitsIgnoreComptime(mod)) return;7898 if (!src_ty.hasRuntimeBitsIgnoreComptime(pt)) return;
7844 switch (ptr_mcv) {7899 switch (ptr_mcv) {
7845 .none,7900 .none,
7846 .unreach,7901 .unreach,
...@@ -7880,7 +7935,8 @@ fn store(...@@ -7880,7 +7935,8 @@ fn store(
7880}7935}
78817936
7882fn airStore(self: *Self, inst: Air.Inst.Index, safety: bool) !void {7937fn airStore(self: *Self, inst: Air.Inst.Index, safety: bool) !void {
7883 const mod = self.bin_file.comp.module.?;7938 const pt = self.pt;
7939 const mod = pt.zcu;
7884 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;7940 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
78857941
7886 result: {7942 result: {
...@@ -7918,15 +7974,16 @@ fn airStructFieldPtrIndex(self: *Self, inst: Air.Inst.Index, index: u8) !void {...@@ -7918,15 +7974,16 @@ fn airStructFieldPtrIndex(self: *Self, inst: Air.Inst.Index, index: u8) !void {
7918}7974}
79197975
7920fn fieldPtr(self: *Self, inst: Air.Inst.Index, operand: Air.Inst.Ref, index: u32) !MCValue {7976fn fieldPtr(self: *Self, inst: Air.Inst.Index, operand: Air.Inst.Ref, index: u32) !MCValue {
7921 const mod = self.bin_file.comp.module.?;7977 const pt = self.pt;
7978 const mod = pt.zcu;
7922 const ptr_field_ty = self.typeOfIndex(inst);7979 const ptr_field_ty = self.typeOfIndex(inst);
7923 const ptr_container_ty = self.typeOf(operand);7980 const ptr_container_ty = self.typeOf(operand);
7924 const container_ty = ptr_container_ty.childType(mod);7981 const container_ty = ptr_container_ty.childType(mod);
79257982
7926 const field_off: i32 = switch (container_ty.containerLayout(mod)) {7983 const field_off: i32 = switch (container_ty.containerLayout(mod)) {
7927 .auto, .@"extern" => @intCast(container_ty.structFieldOffset(index, mod)),7984 .auto, .@"extern" => @intCast(container_ty.structFieldOffset(index, pt)),
7928 .@"packed" => @divExact(@as(i32, ptr_container_ty.ptrInfo(mod).packed_offset.bit_offset) +7985 .@"packed" => @divExact(@as(i32, ptr_container_ty.ptrInfo(mod).packed_offset.bit_offset) +
7929 (if (mod.typeToStruct(container_ty)) |struct_obj| mod.structPackedFieldBitOffset(struct_obj, index) else 0) -7986 (if (mod.typeToStruct(container_ty)) |struct_obj| pt.structPackedFieldBitOffset(struct_obj, index) else 0) -
7930 ptr_field_ty.ptrInfo(mod).packed_offset.bit_offset, 8),7987 ptr_field_ty.ptrInfo(mod).packed_offset.bit_offset, 8),
7931 };7988 };
79327989
...@@ -7940,7 +7997,8 @@ fn fieldPtr(self: *Self, inst: Air.Inst.Index, operand: Air.Inst.Ref, index: u32...@@ -7940,7 +7997,8 @@ fn fieldPtr(self: *Self, inst: Air.Inst.Index, operand: Air.Inst.Ref, index: u32
7940}7997}
79417998
7942fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void {7999fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void {
7943 const mod = self.bin_file.comp.module.?;8000 const pt = self.pt;
8001 const mod = pt.zcu;
7944 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;8002 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
7945 const extra = self.air.extraData(Air.StructField, ty_pl.payload).data;8003 const extra = self.air.extraData(Air.StructField, ty_pl.payload).data;
7946 const result: MCValue = result: {8004 const result: MCValue = result: {
...@@ -7950,14 +8008,14 @@ fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void {...@@ -7950,14 +8008,14 @@ fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void {
7950 const container_ty = self.typeOf(operand);8008 const container_ty = self.typeOf(operand);
7951 const container_rc = self.regClassForType(container_ty);8009 const container_rc = self.regClassForType(container_ty);
7952 const field_ty = container_ty.structFieldType(index, mod);8010 const field_ty = container_ty.structFieldType(index, mod);
7953 if (!field_ty.hasRuntimeBitsIgnoreComptime(mod)) break :result .none;8011 if (!field_ty.hasRuntimeBitsIgnoreComptime(pt)) break :result .none;
7954 const field_rc = self.regClassForType(field_ty);8012 const field_rc = self.regClassForType(field_ty);
7955 const field_is_gp = field_rc.supersetOf(abi.RegisterClass.gp);8013 const field_is_gp = field_rc.supersetOf(abi.RegisterClass.gp);
79568014
7957 const src_mcv = try self.resolveInst(operand);8015 const src_mcv = try self.resolveInst(operand);
7958 const field_off: u32 = switch (container_ty.containerLayout(mod)) {8016 const field_off: u32 = switch (container_ty.containerLayout(mod)) {
7959 .auto, .@"extern" => @intCast(container_ty.structFieldOffset(extra.field_index, mod) * 8),8017 .auto, .@"extern" => @intCast(container_ty.structFieldOffset(extra.field_index, pt) * 8),
7960 .@"packed" => if (mod.typeToStruct(container_ty)) |struct_obj| mod.structPackedFieldBitOffset(struct_obj, extra.field_index) else 0,8018 .@"packed" => if (mod.typeToStruct(container_ty)) |struct_obj| pt.structPackedFieldBitOffset(struct_obj, extra.field_index) else 0,
7961 };8019 };
79628020
7963 switch (src_mcv) {8021 switch (src_mcv) {
...@@ -7988,7 +8046,7 @@ fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void {...@@ -7988,7 +8046,7 @@ fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void {
7988 );8046 );
7989 }8047 }
7990 if (abi.RegisterClass.gp.isSet(RegisterManager.indexOfRegIntoTracked(dst_reg).?) and8048 if (abi.RegisterClass.gp.isSet(RegisterManager.indexOfRegIntoTracked(dst_reg).?) and
7991 container_ty.abiSize(mod) * 8 > field_ty.bitSize(mod))8049 container_ty.abiSize(pt) * 8 > field_ty.bitSize(pt))
7992 try self.truncateRegister(field_ty, dst_reg);8050 try self.truncateRegister(field_ty, dst_reg);
79938051
7994 break :result if (field_off == 0 or field_rc.supersetOf(abi.RegisterClass.gp))8052 break :result if (field_off == 0 or field_rc.supersetOf(abi.RegisterClass.gp))
...@@ -8000,7 +8058,7 @@ fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void {...@@ -8000,7 +8058,7 @@ fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void {
8000 const src_regs_lock = self.register_manager.lockRegsAssumeUnused(2, src_regs);8058 const src_regs_lock = self.register_manager.lockRegsAssumeUnused(2, src_regs);
8001 defer for (src_regs_lock) |lock| self.register_manager.unlockReg(lock);8059 defer for (src_regs_lock) |lock| self.register_manager.unlockReg(lock);
80028060
8003 const field_bit_size: u32 = @intCast(field_ty.bitSize(mod));8061 const field_bit_size: u32 = @intCast(field_ty.bitSize(pt));
8004 const src_reg = if (field_off + field_bit_size <= 64)8062 const src_reg = if (field_off + field_bit_size <= 64)
8005 src_regs[0]8063 src_regs[0]
8006 else if (field_off >= 64)8064 else if (field_off >= 64)
...@@ -8044,7 +8102,7 @@ fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void {...@@ -8044,7 +8102,7 @@ fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void {
8044 }8102 }
80458103
8046 if (field_bit_size < 128) try self.truncateRegister(8104 if (field_bit_size < 128) try self.truncateRegister(
8047 try mod.intType(.unsigned, @intCast(field_bit_size - 64)),8105 try pt.intType(.unsigned, @intCast(field_bit_size - 64)),
8048 dst_regs[1],8106 dst_regs[1],
8049 );8107 );
8050 break :result if (field_rc.supersetOf(abi.RegisterClass.gp))8108 break :result if (field_rc.supersetOf(abi.RegisterClass.gp))
...@@ -8099,14 +8157,14 @@ fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void {...@@ -8099,14 +8157,14 @@ fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void {
8099 }8157 }
8100 },8158 },
8101 .load_frame => |frame_addr| {8159 .load_frame => |frame_addr| {
8102 const field_abi_size: u32 = @intCast(field_ty.abiSize(mod));8160 const field_abi_size: u32 = @intCast(field_ty.abiSize(pt));
8103 if (field_off % 8 == 0) {8161 if (field_off % 8 == 0) {
8104 const field_byte_off = @divExact(field_off, 8);8162 const field_byte_off = @divExact(field_off, 8);
8105 const off_mcv = src_mcv.address().offset(@intCast(field_byte_off)).deref();8163 const off_mcv = src_mcv.address().offset(@intCast(field_byte_off)).deref();
8106 const field_bit_size = field_ty.bitSize(mod);8164 const field_bit_size = field_ty.bitSize(pt);
81078165
8108 if (field_abi_size <= 8) {8166 if (field_abi_size <= 8) {
8109 const int_ty = try mod.intType(8167 const int_ty = try pt.intType(
8110 if (field_ty.isAbiInt(mod)) field_ty.intInfo(mod).signedness else .unsigned,8168 if (field_ty.isAbiInt(mod)) field_ty.intInfo(mod).signedness else .unsigned,
8111 @intCast(field_bit_size),8169 @intCast(field_bit_size),
8112 );8170 );
...@@ -8127,7 +8185,7 @@ fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void {...@@ -8127,7 +8185,7 @@ fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void {
8127 try self.copyToRegisterWithInstTracking(inst, field_ty, dst_mcv);8185 try self.copyToRegisterWithInstTracking(inst, field_ty, dst_mcv);
8128 }8186 }
81298187
8130 const container_abi_size: u32 = @intCast(container_ty.abiSize(mod));8188 const container_abi_size: u32 = @intCast(container_ty.abiSize(pt));
8131 const dst_mcv = if (field_byte_off + field_abi_size <= container_abi_size and8189 const dst_mcv = if (field_byte_off + field_abi_size <= container_abi_size and
8132 self.reuseOperand(inst, operand, 0, src_mcv))8190 self.reuseOperand(inst, operand, 0, src_mcv))
8133 off_mcv8191 off_mcv
...@@ -8228,16 +8286,17 @@ fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void {...@@ -8228,16 +8286,17 @@ fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void {
8228}8286}
82298287
8230fn airFieldParentPtr(self: *Self, inst: Air.Inst.Index) !void {8288fn airFieldParentPtr(self: *Self, inst: Air.Inst.Index) !void {
8231 const mod = self.bin_file.comp.module.?;8289 const pt = self.pt;
8290 const mod = pt.zcu;
8232 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;8291 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
8233 const extra = self.air.extraData(Air.FieldParentPtr, ty_pl.payload).data;8292 const extra = self.air.extraData(Air.FieldParentPtr, ty_pl.payload).data;
82348293
8235 const inst_ty = self.typeOfIndex(inst);8294 const inst_ty = self.typeOfIndex(inst);
8236 const parent_ty = inst_ty.childType(mod);8295 const parent_ty = inst_ty.childType(mod);
8237 const field_off: i32 = switch (parent_ty.containerLayout(mod)) {8296 const field_off: i32 = switch (parent_ty.containerLayout(mod)) {
8238 .auto, .@"extern" => @intCast(parent_ty.structFieldOffset(extra.field_index, mod)),8297 .auto, .@"extern" => @intCast(parent_ty.structFieldOffset(extra.field_index, pt)),
8239 .@"packed" => @divExact(@as(i32, inst_ty.ptrInfo(mod).packed_offset.bit_offset) +8298 .@"packed" => @divExact(@as(i32, inst_ty.ptrInfo(mod).packed_offset.bit_offset) +
8240 (if (mod.typeToStruct(parent_ty)) |struct_obj| mod.structPackedFieldBitOffset(struct_obj, extra.field_index) else 0) -8299 (if (mod.typeToStruct(parent_ty)) |struct_obj| pt.structPackedFieldBitOffset(struct_obj, extra.field_index) else 0) -
8241 self.typeOf(extra.field_ptr).ptrInfo(mod).packed_offset.bit_offset, 8),8300 self.typeOf(extra.field_ptr).ptrInfo(mod).packed_offset.bit_offset, 8),
8242 };8301 };
82438302
...@@ -8252,10 +8311,11 @@ fn airFieldParentPtr(self: *Self, inst: Air.Inst.Index) !void {...@@ -8252,10 +8311,11 @@ fn airFieldParentPtr(self: *Self, inst: Air.Inst.Index) !void {
8252}8311}
82538312
8254fn genUnOp(self: *Self, maybe_inst: ?Air.Inst.Index, tag: Air.Inst.Tag, src_air: Air.Inst.Ref) !MCValue {8313fn genUnOp(self: *Self, maybe_inst: ?Air.Inst.Index, tag: Air.Inst.Tag, src_air: Air.Inst.Ref) !MCValue {
8255 const mod = self.bin_file.comp.module.?;8314 const pt = self.pt;
8315 const mod = pt.zcu;
8256 const src_ty = self.typeOf(src_air);8316 const src_ty = self.typeOf(src_air);
8257 if (src_ty.zigTypeTag(mod) == .Vector)8317 if (src_ty.zigTypeTag(mod) == .Vector)
8258 return self.fail("TODO implement genUnOp for {}", .{src_ty.fmt(mod)});8318 return self.fail("TODO implement genUnOp for {}", .{src_ty.fmt(pt)});
82598319
8260 var src_mcv = try self.resolveInst(src_air);8320 var src_mcv = try self.resolveInst(src_air);
8261 switch (src_mcv) {8321 switch (src_mcv) {
...@@ -8290,7 +8350,7 @@ fn genUnOp(self: *Self, maybe_inst: ?Air.Inst.Index, tag: Air.Inst.Tag, src_air:...@@ -8290,7 +8350,7 @@ fn genUnOp(self: *Self, maybe_inst: ?Air.Inst.Index, tag: Air.Inst.Tag, src_air:
8290 };8350 };
8291 defer if (dst_lock) |lock| self.register_manager.unlockReg(lock);8351 defer if (dst_lock) |lock| self.register_manager.unlockReg(lock);
82928352
8293 const abi_size: u16 = @intCast(src_ty.abiSize(mod));8353 const abi_size: u16 = @intCast(src_ty.abiSize(pt));
8294 switch (tag) {8354 switch (tag) {
8295 .not => {8355 .not => {
8296 const limb_abi_size: u16 = @min(abi_size, 8);8356 const limb_abi_size: u16 = @min(abi_size, 8);
...@@ -8304,7 +8364,7 @@ fn genUnOp(self: *Self, maybe_inst: ?Air.Inst.Index, tag: Air.Inst.Tag, src_air:...@@ -8304,7 +8364,7 @@ fn genUnOp(self: *Self, maybe_inst: ?Air.Inst.Index, tag: Air.Inst.Tag, src_air:
8304 .signed => abi_size * 8,8364 .signed => abi_size * 8,
8305 .unsigned => int_info.bits,8365 .unsigned => int_info.bits,
8306 } - byte_off * 8, limb_abi_size * 8));8366 } - byte_off * 8, limb_abi_size * 8));
8307 const limb_ty = try mod.intType(int_info.signedness, limb_bits);8367 const limb_ty = try pt.intType(int_info.signedness, limb_bits);
8308 const limb_mcv = switch (byte_off) {8368 const limb_mcv = switch (byte_off) {
8309 0 => dst_mcv,8369 0 => dst_mcv,
8310 else => dst_mcv.address().offset(byte_off).deref(),8370 else => dst_mcv.address().offset(byte_off).deref(),
...@@ -8340,9 +8400,9 @@ fn genUnOp(self: *Self, maybe_inst: ?Air.Inst.Index, tag: Air.Inst.Tag, src_air:...@@ -8340,9 +8400,9 @@ fn genUnOp(self: *Self, maybe_inst: ?Air.Inst.Index, tag: Air.Inst.Tag, src_air:
8340}8400}
83418401
8342fn genUnOpMir(self: *Self, mir_tag: Mir.Inst.FixedTag, dst_ty: Type, dst_mcv: MCValue) !void {8402fn genUnOpMir(self: *Self, mir_tag: Mir.Inst.FixedTag, dst_ty: Type, dst_mcv: MCValue) !void {
8343 const mod = self.bin_file.comp.module.?;8403 const pt = self.pt;
8344 const abi_size: u32 = @intCast(dst_ty.abiSize(mod));8404 const abi_size: u32 = @intCast(dst_ty.abiSize(pt));
8345 if (abi_size > 8) return self.fail("TODO implement {} for {}", .{ mir_tag, dst_ty.fmt(mod) });8405 if (abi_size > 8) return self.fail("TODO implement {} for {}", .{ mir_tag, dst_ty.fmt(pt) });
8346 switch (dst_mcv) {8406 switch (dst_mcv) {
8347 .none,8407 .none,
8348 .unreach,8408 .unreach,
...@@ -8389,9 +8449,9 @@ fn genShiftBinOpMir(...@@ -8389,9 +8449,9 @@ fn genShiftBinOpMir(
8389 rhs_ty: Type,8449 rhs_ty: Type,
8390 rhs_mcv: MCValue,8450 rhs_mcv: MCValue,
8391) !void {8451) !void {
8392 const mod = self.bin_file.comp.module.?;8452 const pt = self.pt;
8393 const abi_size: u32 = @intCast(lhs_ty.abiSize(mod));8453 const abi_size: u32 = @intCast(lhs_ty.abiSize(pt));
8394 const shift_abi_size: u32 = @intCast(rhs_ty.abiSize(mod));8454 const shift_abi_size: u32 = @intCast(rhs_ty.abiSize(pt));
8395 try self.spillEflagsIfOccupied();8455 try self.spillEflagsIfOccupied();
83968456
8397 if (abi_size > 16) {8457 if (abi_size > 16) {
...@@ -9046,9 +9106,10 @@ fn genShiftBinOp(...@@ -9046,9 +9106,10 @@ fn genShiftBinOp(
9046 lhs_ty: Type,9106 lhs_ty: Type,
9047 rhs_ty: Type,9107 rhs_ty: Type,
9048) !MCValue {9108) !MCValue {
9049 const mod = self.bin_file.comp.module.?;9109 const pt = self.pt;
9110 const mod = pt.zcu;
9050 if (lhs_ty.zigTypeTag(mod) == .Vector) return self.fail("TODO implement genShiftBinOp for {}", .{9111 if (lhs_ty.zigTypeTag(mod) == .Vector) return self.fail("TODO implement genShiftBinOp for {}", .{
9051 lhs_ty.fmt(mod),9112 lhs_ty.fmt(pt),
9052 });9113 });
90539114
9054 try self.register_manager.getKnownReg(.rcx, null);9115 try self.register_manager.getKnownReg(.rcx, null);
...@@ -9104,13 +9165,14 @@ fn genMulDivBinOp(...@@ -9104,13 +9165,14 @@ fn genMulDivBinOp(
9104 lhs_mcv: MCValue,9165 lhs_mcv: MCValue,
9105 rhs_mcv: MCValue,9166 rhs_mcv: MCValue,
9106) !MCValue {9167) !MCValue {
9107 const mod = self.bin_file.comp.module.?;9168 const pt = self.pt;
9169 const mod = pt.zcu;
9108 if (dst_ty.zigTypeTag(mod) == .Vector or dst_ty.zigTypeTag(mod) == .Float) return self.fail(9170 if (dst_ty.zigTypeTag(mod) == .Vector or dst_ty.zigTypeTag(mod) == .Float) return self.fail(
9109 "TODO implement genMulDivBinOp for {s} from {} to {}",9171 "TODO implement genMulDivBinOp for {s} from {} to {}",
9110 .{ @tagName(tag), src_ty.fmt(mod), dst_ty.fmt(mod) },9172 .{ @tagName(tag), src_ty.fmt(pt), dst_ty.fmt(pt) },
9111 );9173 );
9112 const dst_abi_size: u32 = @intCast(dst_ty.abiSize(mod));9174 const dst_abi_size: u32 = @intCast(dst_ty.abiSize(pt));
9113 const src_abi_size: u32 = @intCast(src_ty.abiSize(mod));9175 const src_abi_size: u32 = @intCast(src_ty.abiSize(pt));
91149176
9115 assert(self.register_manager.isRegFree(.rax));9177 assert(self.register_manager.isRegFree(.rax));
9116 assert(self.register_manager.isRegFree(.rcx));9178 assert(self.register_manager.isRegFree(.rcx));
...@@ -9299,13 +9361,13 @@ fn genMulDivBinOp(...@@ -9299,13 +9361,13 @@ fn genMulDivBinOp(
9299 .signed => {},9361 .signed => {},
9300 .unsigned => {9362 .unsigned => {
9301 const dst_mcv = try self.allocRegOrMemAdvanced(dst_ty, maybe_inst, false);9363 const dst_mcv = try self.allocRegOrMemAdvanced(dst_ty, maybe_inst, false);
9302 const manyptr_u32_ty = try mod.ptrType(.{9364 const manyptr_u32_ty = try pt.ptrType(.{
9303 .child = .u32_type,9365 .child = .u32_type,
9304 .flags = .{9366 .flags = .{
9305 .size = .Many,9367 .size = .Many,
9306 },9368 },
9307 });9369 });
9308 const manyptr_const_u32_ty = try mod.ptrType(.{9370 const manyptr_const_u32_ty = try pt.ptrType(.{
9309 .child = .u32_type,9371 .child = .u32_type,
9310 .flags = .{9372 .flags = .{
9311 .size = .Many,9373 .size = .Many,
...@@ -9348,7 +9410,7 @@ fn genMulDivBinOp(...@@ -9348,7 +9410,7 @@ fn genMulDivBinOp(
9348 }9410 }
9349 return self.fail(9411 return self.fail(
9350 "TODO implement genMulDivBinOp for {s} from {} to {}",9412 "TODO implement genMulDivBinOp for {s} from {} to {}",
9351 .{ @tagName(tag), src_ty.fmt(mod), dst_ty.fmt(mod) },9413 .{ @tagName(tag), src_ty.fmt(pt), dst_ty.fmt(pt) },
9352 );9414 );
9353 }9415 }
9354 const ty = if (dst_abi_size <= 8) dst_ty else src_ty;9416 const ty = if (dst_abi_size <= 8) dst_ty else src_ty;
...@@ -9515,10 +9577,11 @@ fn genBinOp(...@@ -9515,10 +9577,11 @@ fn genBinOp(
9515 lhs_air: Air.Inst.Ref,9577 lhs_air: Air.Inst.Ref,
9516 rhs_air: Air.Inst.Ref,9578 rhs_air: Air.Inst.Ref,
9517) !MCValue {9579) !MCValue {
9518 const mod = self.bin_file.comp.module.?;9580 const pt = self.pt;
9581 const mod = pt.zcu;
9519 const lhs_ty = self.typeOf(lhs_air);9582 const lhs_ty = self.typeOf(lhs_air);
9520 const rhs_ty = self.typeOf(rhs_air);9583 const rhs_ty = self.typeOf(rhs_air);
9521 const abi_size: u32 = @intCast(lhs_ty.abiSize(mod));9584 const abi_size: u32 = @intCast(lhs_ty.abiSize(pt));
95229585
9523 if (lhs_ty.isRuntimeFloat()) libcall: {9586 if (lhs_ty.isRuntimeFloat()) libcall: {
9524 const float_bits = lhs_ty.floatBits(self.target.*);9587 const float_bits = lhs_ty.floatBits(self.target.*);
...@@ -9556,7 +9619,7 @@ fn genBinOp(...@@ -9556,7 +9619,7 @@ fn genBinOp(
9556 floatLibcAbiSuffix(lhs_ty),9619 floatLibcAbiSuffix(lhs_ty),
9557 }),9620 }),
9558 else => return self.fail("TODO implement genBinOp for {s} {}", .{9621 else => return self.fail("TODO implement genBinOp for {s} {}", .{
9559 @tagName(air_tag), lhs_ty.fmt(mod),9622 @tagName(air_tag), lhs_ty.fmt(pt),
9560 }),9623 }),
9561 } catch unreachable;9624 } catch unreachable;
9562 const result = try self.genCall(.{ .lib = .{9625 const result = try self.genCall(.{ .lib = .{
...@@ -9668,7 +9731,7 @@ fn genBinOp(...@@ -9668,7 +9731,7 @@ fn genBinOp(
9668 break :adjusted .{ .register = dst_reg };9731 break :adjusted .{ .register = dst_reg };
9669 },9732 },
9670 80, 128 => return self.fail("TODO implement genBinOp for {s} of {}", .{9733 80, 128 => return self.fail("TODO implement genBinOp for {s} of {}", .{
9671 @tagName(air_tag), lhs_ty.fmt(mod),9734 @tagName(air_tag), lhs_ty.fmt(pt),
9672 }),9735 }),
9673 else => unreachable,9736 else => unreachable,
9674 };9737 };
...@@ -9700,8 +9763,8 @@ fn genBinOp(...@@ -9700,8 +9763,8 @@ fn genBinOp(
9700 };9763 };
9701 if (sse_op and ((lhs_ty.scalarType(mod).isRuntimeFloat() and9764 if (sse_op and ((lhs_ty.scalarType(mod).isRuntimeFloat() and
9702 lhs_ty.scalarType(mod).floatBits(self.target.*) == 80) or9765 lhs_ty.scalarType(mod).floatBits(self.target.*) == 80) or
9703 lhs_ty.abiSize(mod) > @as(u6, if (self.hasFeature(.avx)) 32 else 16)))9766 lhs_ty.abiSize(pt) > @as(u6, if (self.hasFeature(.avx)) 32 else 16)))
9704 return self.fail("TODO implement genBinOp for {s} {}", .{ @tagName(air_tag), lhs_ty.fmt(mod) });9767 return self.fail("TODO implement genBinOp for {s} {}", .{ @tagName(air_tag), lhs_ty.fmt(pt) });
97059768
9706 const maybe_mask_reg = switch (air_tag) {9769 const maybe_mask_reg = switch (air_tag) {
9707 else => null,9770 else => null,
...@@ -9857,7 +9920,7 @@ fn genBinOp(...@@ -9857,7 +9920,7 @@ fn genBinOp(
9857 const tmp_lock = self.register_manager.lockRegAssumeUnused(tmp_reg);9920 const tmp_lock = self.register_manager.lockRegAssumeUnused(tmp_reg);
9858 defer self.register_manager.unlockReg(tmp_lock);9921 defer self.register_manager.unlockReg(tmp_lock);
98599922
9860 const elem_size = lhs_ty.elemType2(mod).abiSize(mod);9923 const elem_size = lhs_ty.elemType2(mod).abiSize(pt);
9861 try self.genIntMulComplexOpMir(rhs_ty, tmp_mcv, .{ .immediate = elem_size });9924 try self.genIntMulComplexOpMir(rhs_ty, tmp_mcv, .{ .immediate = elem_size });
9862 try self.genBinOpMir(9925 try self.genBinOpMir(
9863 switch (air_tag) {9926 switch (air_tag) {
...@@ -10003,7 +10066,7 @@ fn genBinOp(...@@ -10003,7 +10066,7 @@ fn genBinOp(
10003 },10066 },
10004 };10067 };
1000510068
10006 const cmov_abi_size = @max(@as(u32, @intCast(lhs_ty.abiSize(mod))), 2);10069 const cmov_abi_size = @max(@as(u32, @intCast(lhs_ty.abiSize(pt))), 2);
10007 const tmp_reg = switch (dst_mcv) {10070 const tmp_reg = switch (dst_mcv) {
10008 .register => |reg| reg,10071 .register => |reg| reg,
10009 else => try self.copyToTmpRegister(lhs_ty, dst_mcv),10072 else => try self.copyToTmpRegister(lhs_ty, dst_mcv),
...@@ -10082,7 +10145,7 @@ fn genBinOp(...@@ -10082,7 +10145,7 @@ fn genBinOp(
10082 },10145 },
1008310146
10084 else => return self.fail("TODO implement genBinOp for {s} {}", .{10147 else => return self.fail("TODO implement genBinOp for {s} {}", .{
10085 @tagName(air_tag), lhs_ty.fmt(mod),10148 @tagName(air_tag), lhs_ty.fmt(pt),
10086 }),10149 }),
10087 }10150 }
10088 return dst_mcv;10151 return dst_mcv;
...@@ -10835,7 +10898,7 @@ fn genBinOp(...@@ -10835,7 +10898,7 @@ fn genBinOp(
10835 },10898 },
10836 },10899 },
10837 }) orelse return self.fail("TODO implement genBinOp for {s} {}", .{10900 }) orelse return self.fail("TODO implement genBinOp for {s} {}", .{
10838 @tagName(air_tag), lhs_ty.fmt(mod),10901 @tagName(air_tag), lhs_ty.fmt(pt),
10839 });10902 });
1084010903
10841 const lhs_copy_reg = if (maybe_mask_reg) |_| registerAlias(10904 const lhs_copy_reg = if (maybe_mask_reg) |_| registerAlias(
...@@ -10978,7 +11041,7 @@ fn genBinOp(...@@ -10978,7 +11041,7 @@ fn genBinOp(
10978 },11041 },
10979 else => unreachable,11042 else => unreachable,
10980 }) orelse return self.fail("TODO implement genBinOp for {s} {}", .{11043 }) orelse return self.fail("TODO implement genBinOp for {s} {}", .{
10981 @tagName(air_tag), lhs_ty.fmt(mod),11044 @tagName(air_tag), lhs_ty.fmt(pt),
10982 }),11045 }),
10983 mask_reg,11046 mask_reg,
10984 rhs_copy_reg,11047 rhs_copy_reg,
...@@ -11010,7 +11073,7 @@ fn genBinOp(...@@ -11010,7 +11073,7 @@ fn genBinOp(
11010 },11073 },
11011 else => unreachable,11074 else => unreachable,
11012 }) orelse return self.fail("TODO implement genBinOp for {s} {}", .{11075 }) orelse return self.fail("TODO implement genBinOp for {s} {}", .{
11013 @tagName(air_tag), lhs_ty.fmt(mod),11076 @tagName(air_tag), lhs_ty.fmt(pt),
11014 }),11077 }),
11015 dst_reg,11078 dst_reg,
11016 dst_reg,11079 dst_reg,
...@@ -11046,7 +11109,7 @@ fn genBinOp(...@@ -11046,7 +11109,7 @@ fn genBinOp(
11046 },11109 },
11047 else => unreachable,11110 else => unreachable,
11048 }) orelse return self.fail("TODO implement genBinOp for {s} {}", .{11111 }) orelse return self.fail("TODO implement genBinOp for {s} {}", .{
11049 @tagName(air_tag), lhs_ty.fmt(mod),11112 @tagName(air_tag), lhs_ty.fmt(pt),
11050 }),11113 }),
11051 mask_reg,11114 mask_reg,
11052 mask_reg,11115 mask_reg,
...@@ -11077,7 +11140,7 @@ fn genBinOp(...@@ -11077,7 +11140,7 @@ fn genBinOp(
11077 },11140 },
11078 else => unreachable,11141 else => unreachable,
11079 }) orelse return self.fail("TODO implement genBinOp for {s} {}", .{11142 }) orelse return self.fail("TODO implement genBinOp for {s} {}", .{
11080 @tagName(air_tag), lhs_ty.fmt(mod),11143 @tagName(air_tag), lhs_ty.fmt(pt),
11081 }),11144 }),
11082 dst_reg,11145 dst_reg,
11083 lhs_copy_reg.?,11146 lhs_copy_reg.?,
...@@ -11107,7 +11170,7 @@ fn genBinOp(...@@ -11107,7 +11170,7 @@ fn genBinOp(
11107 },11170 },
11108 else => unreachable,11171 else => unreachable,
11109 }) orelse return self.fail("TODO implement genBinOp for {s} {}", .{11172 }) orelse return self.fail("TODO implement genBinOp for {s} {}", .{
11110 @tagName(air_tag), lhs_ty.fmt(mod),11173 @tagName(air_tag), lhs_ty.fmt(pt),
11111 });11174 });
11112 try self.asmRegisterRegister(.{ mir_fixes, .@"and" }, dst_reg, mask_reg);11175 try self.asmRegisterRegister(.{ mir_fixes, .@"and" }, dst_reg, mask_reg);
11113 try self.asmRegisterRegister(.{ mir_fixes, .andn }, mask_reg, lhs_copy_reg.?);11176 try self.asmRegisterRegister(.{ mir_fixes, .andn }, mask_reg, lhs_copy_reg.?);
...@@ -11125,8 +11188,8 @@ fn genBinOp(...@@ -11125,8 +11188,8 @@ fn genBinOp(
11125 .cmp_gte,11188 .cmp_gte,
11126 .cmp_neq,11189 .cmp_neq,
11127 => {11190 => {
11128 const unsigned_ty = try lhs_ty.toUnsigned(mod);11191 const unsigned_ty = try lhs_ty.toUnsigned(pt);
11129 const not_mcv = try self.genTypedValue(try unsigned_ty.maxInt(mod, unsigned_ty));11192 const not_mcv = try self.genTypedValue(try unsigned_ty.maxInt(pt, unsigned_ty));
11130 const not_mem: Memory = if (not_mcv.isMemory())11193 const not_mem: Memory = if (not_mcv.isMemory())
11131 try not_mcv.mem(self, Memory.Size.fromSize(abi_size))11194 try not_mcv.mem(self, Memory.Size.fromSize(abi_size))
11132 else11195 else
...@@ -11195,8 +11258,9 @@ fn genBinOpMir(...@@ -11195,8 +11258,9 @@ fn genBinOpMir(
11195 dst_mcv: MCValue,11258 dst_mcv: MCValue,
11196 src_mcv: MCValue,11259 src_mcv: MCValue,
11197) !void {11260) !void {
11198 const mod = self.bin_file.comp.module.?;11261 const pt = self.pt;
11199 const abi_size: u32 = @intCast(ty.abiSize(mod));11262 const mod = pt.zcu;
11263 const abi_size: u32 = @intCast(ty.abiSize(pt));
11200 try self.spillEflagsIfOccupied();11264 try self.spillEflagsIfOccupied();
11201 switch (dst_mcv) {11265 switch (dst_mcv) {
11202 .none,11266 .none,
...@@ -11358,7 +11422,7 @@ fn genBinOpMir(...@@ -11358,7 +11422,7 @@ fn genBinOpMir(
11358 .load_got,11422 .load_got,
11359 .load_tlv,11423 .load_tlv,
11360 => {11424 => {
11361 const ptr_ty = try mod.singleConstPtrType(ty);11425 const ptr_ty = try pt.singleConstPtrType(ty);
11362 const addr_reg = try self.copyToTmpRegister(ptr_ty, src_mcv.address());11426 const addr_reg = try self.copyToTmpRegister(ptr_ty, src_mcv.address());
11363 return self.genBinOpMir(mir_limb_tag, ty, dst_mcv, .{11427 return self.genBinOpMir(mir_limb_tag, ty, dst_mcv, .{
11364 .indirect = .{ .reg = addr_reg, .off = off },11428 .indirect = .{ .reg = addr_reg, .off = off },
...@@ -11619,8 +11683,8 @@ fn genBinOpMir(...@@ -11619,8 +11683,8 @@ fn genBinOpMir(
11619/// Performs multi-operand integer multiplication between dst_mcv and src_mcv, storing the result in dst_mcv.11683/// Performs multi-operand integer multiplication between dst_mcv and src_mcv, storing the result in dst_mcv.
11620/// Does not support byte-size operands.11684/// Does not support byte-size operands.
11621fn genIntMulComplexOpMir(self: *Self, dst_ty: Type, dst_mcv: MCValue, src_mcv: MCValue) InnerError!void {11685fn genIntMulComplexOpMir(self: *Self, dst_ty: Type, dst_mcv: MCValue, src_mcv: MCValue) InnerError!void {
11622 const mod = self.bin_file.comp.module.?;11686 const pt = self.pt;
11623 const abi_size: u32 = @intCast(dst_ty.abiSize(mod));11687 const abi_size: u32 = @intCast(dst_ty.abiSize(pt));
11624 try self.spillEflagsIfOccupied();11688 try self.spillEflagsIfOccupied();
11625 switch (dst_mcv) {11689 switch (dst_mcv) {
11626 .none,11690 .none,
...@@ -11746,7 +11810,8 @@ fn genIntMulComplexOpMir(self: *Self, dst_ty: Type, dst_mcv: MCValue, src_mcv: M...@@ -11746,7 +11810,8 @@ fn genIntMulComplexOpMir(self: *Self, dst_ty: Type, dst_mcv: MCValue, src_mcv: M
11746}11810}
1174711811
11748fn airArg(self: *Self, inst: Air.Inst.Index) !void {11812fn airArg(self: *Self, inst: Air.Inst.Index) !void {
11749 const mod = self.bin_file.comp.module.?;11813 const pt = self.pt;
11814 const mod = pt.zcu;
11750 // skip zero-bit arguments as they don't have a corresponding arg instruction11815 // skip zero-bit arguments as they don't have a corresponding arg instruction
11751 var arg_index = self.arg_index;11816 var arg_index = self.arg_index;
11752 while (self.args[arg_index] == .none) arg_index += 1;11817 while (self.args[arg_index] == .none) arg_index += 1;
...@@ -11808,7 +11873,7 @@ fn airArg(self: *Self, inst: Air.Inst.Index) !void {...@@ -11808,7 +11873,7 @@ fn airArg(self: *Self, inst: Air.Inst.Index) !void {
11808 try self.genInlineMemset(11873 try self.genInlineMemset(
11809 dst_mcv.address().offset(@intFromBool(regs_frame_addr.regs > 0)),11874 dst_mcv.address().offset(@intFromBool(regs_frame_addr.regs > 0)),
11810 .{ .immediate = 0 },11875 .{ .immediate = 0 },
11811 .{ .immediate = arg_ty.abiSize(mod) - @intFromBool(regs_frame_addr.regs > 0) },11876 .{ .immediate = arg_ty.abiSize(pt) - @intFromBool(regs_frame_addr.regs > 0) },
11812 .{},11877 .{},
11813 );11878 );
1181411879
...@@ -11865,7 +11930,8 @@ fn airArg(self: *Self, inst: Air.Inst.Index) !void {...@@ -11865,7 +11930,8 @@ fn airArg(self: *Self, inst: Air.Inst.Index) !void {
11865}11930}
1186611931
11867fn genArgDbgInfo(self: Self, ty: Type, name: [:0]const u8, mcv: MCValue) !void {11932fn genArgDbgInfo(self: Self, ty: Type, name: [:0]const u8, mcv: MCValue) !void {
11868 const mod = self.bin_file.comp.module.?;11933 const pt = self.pt;
11934 const mod = pt.zcu;
11869 switch (self.debug_output) {11935 switch (self.debug_output) {
11870 .dwarf => |dw| {11936 .dwarf => |dw| {
11871 const loc: link.File.Dwarf.DeclState.DbgInfoLoc = switch (mcv) {11937 const loc: link.File.Dwarf.DeclState.DbgInfoLoc = switch (mcv) {
...@@ -11901,7 +11967,8 @@ fn genVarDbgInfo(...@@ -11901,7 +11967,8 @@ fn genVarDbgInfo(
11901 mcv: MCValue,11967 mcv: MCValue,
11902 name: [:0]const u8,11968 name: [:0]const u8,
11903) !void {11969) !void {
11904 const mod = self.bin_file.comp.module.?;11970 const pt = self.pt;
11971 const mod = pt.zcu;
11905 const is_ptr = switch (tag) {11972 const is_ptr = switch (tag) {
11906 .dbg_var_ptr => true,11973 .dbg_var_ptr => true,
11907 .dbg_var_val => false,11974 .dbg_var_val => false,
...@@ -12020,7 +12087,8 @@ fn genCall(self: *Self, info: union(enum) {...@@ -12020,7 +12087,8 @@ fn genCall(self: *Self, info: union(enum) {
12020 callee: []const u8,12087 callee: []const u8,
12021 },12088 },
12022}, arg_types: []const Type, args: []const MCValue) !MCValue {12089}, arg_types: []const Type, args: []const MCValue) !MCValue {
12023 const mod = self.bin_file.comp.module.?;12090 const pt = self.pt;
12091 const mod = pt.zcu;
1202412092
12025 const fn_ty = switch (info) {12093 const fn_ty = switch (info) {
12026 .air => |callee| fn_info: {12094 .air => |callee| fn_info: {
...@@ -12031,7 +12099,7 @@ fn genCall(self: *Self, info: union(enum) {...@@ -12031,7 +12099,7 @@ fn genCall(self: *Self, info: union(enum) {
12031 else => unreachable,12099 else => unreachable,
12032 };12100 };
12033 },12101 },
12034 .lib => |lib| try mod.funcType(.{12102 .lib => |lib| try pt.funcType(.{
12035 .param_types = lib.param_types,12103 .param_types = lib.param_types,
12036 .return_type = lib.return_type,12104 .return_type = lib.return_type,
12037 .cc = .C,12105 .cc = .C,
...@@ -12101,7 +12169,7 @@ fn genCall(self: *Self, info: union(enum) {...@@ -12101,7 +12169,7 @@ fn genCall(self: *Self, info: union(enum) {
12101 try reg_locks.appendSlice(&self.register_manager.lockRegs(2, regs));12169 try reg_locks.appendSlice(&self.register_manager.lockRegs(2, regs));
12102 },12170 },
12103 .indirect => |reg_off| {12171 .indirect => |reg_off| {
12104 frame_index.* = try self.allocFrameIndex(FrameAlloc.initType(arg_ty, mod));12172 frame_index.* = try self.allocFrameIndex(FrameAlloc.initType(arg_ty, pt));
12105 try self.genSetMem(.{ .frame = frame_index.* }, 0, arg_ty, src_arg, .{});12173 try self.genSetMem(.{ .frame = frame_index.* }, 0, arg_ty, src_arg, .{});
12106 try self.register_manager.getReg(reg_off.reg, null);12174 try self.register_manager.getReg(reg_off.reg, null);
12107 try reg_locks.append(self.register_manager.lockReg(reg_off.reg));12175 try reg_locks.append(self.register_manager.lockReg(reg_off.reg));
...@@ -12173,7 +12241,7 @@ fn genCall(self: *Self, info: union(enum) {...@@ -12173,7 +12241,7 @@ fn genCall(self: *Self, info: union(enum) {
12173 .none, .unreach => {},12241 .none, .unreach => {},
12174 .indirect => |reg_off| {12242 .indirect => |reg_off| {
12175 const ret_ty = Type.fromInterned(fn_info.return_type);12243 const ret_ty = Type.fromInterned(fn_info.return_type);
12176 const frame_index = try self.allocFrameIndex(FrameAlloc.initSpill(ret_ty, mod));12244 const frame_index = try self.allocFrameIndex(FrameAlloc.initSpill(ret_ty, pt));
12177 try self.genSetReg(reg_off.reg, Type.usize, .{12245 try self.genSetReg(reg_off.reg, Type.usize, .{
12178 .lea_frame = .{ .index = frame_index, .off = -reg_off.off },12246 .lea_frame = .{ .index = frame_index, .off = -reg_off.off },
12179 }, .{});12247 }, .{});
...@@ -12188,14 +12256,14 @@ fn genCall(self: *Self, info: union(enum) {...@@ -12188,14 +12256,14 @@ fn genCall(self: *Self, info: union(enum) {
12188 .none, .load_frame => {},12256 .none, .load_frame => {},
12189 .register => |dst_reg| switch (fn_info.cc) {12257 .register => |dst_reg| switch (fn_info.cc) {
12190 else => try self.genSetReg(12258 else => try self.genSetReg(
12191 registerAlias(dst_reg, @intCast(arg_ty.abiSize(mod))),12259 registerAlias(dst_reg, @intCast(arg_ty.abiSize(pt))),
12192 arg_ty,12260 arg_ty,
12193 src_arg,12261 src_arg,
12194 .{},12262 .{},
12195 ),12263 ),
12196 .C, .SysV, .Win64 => {12264 .C, .SysV, .Win64 => {
12197 const promoted_ty = self.promoteInt(arg_ty);12265 const promoted_ty = self.promoteInt(arg_ty);
12198 const promoted_abi_size: u32 = @intCast(promoted_ty.abiSize(mod));12266 const promoted_abi_size: u32 = @intCast(promoted_ty.abiSize(pt));
12199 const dst_alias = registerAlias(dst_reg, promoted_abi_size);12267 const dst_alias = registerAlias(dst_reg, promoted_abi_size);
12200 try self.genSetReg(dst_alias, promoted_ty, src_arg, .{});12268 try self.genSetReg(dst_alias, promoted_ty, src_arg, .{});
12201 if (promoted_ty.toIntern() != arg_ty.toIntern())12269 if (promoted_ty.toIntern() != arg_ty.toIntern())
...@@ -12246,7 +12314,7 @@ fn genCall(self: *Self, info: union(enum) {...@@ -12246,7 +12314,7 @@ fn genCall(self: *Self, info: union(enum) {
12246 // Due to incremental compilation, how function calls are generated depends12314 // Due to incremental compilation, how function calls are generated depends
12247 // on linking.12315 // on linking.
12248 switch (info) {12316 switch (info) {
12249 .air => |callee| if (try self.air.value(callee, mod)) |func_value| {12317 .air => |callee| if (try self.air.value(callee, pt)) |func_value| {
12250 const func_key = mod.intern_pool.indexToKey(func_value.ip_index);12318 const func_key = mod.intern_pool.indexToKey(func_value.ip_index);
12251 switch (switch (func_key) {12319 switch (switch (func_key) {
12252 else => func_key,12320 else => func_key,
...@@ -12332,7 +12400,8 @@ fn genCall(self: *Self, info: union(enum) {...@@ -12332,7 +12400,8 @@ fn genCall(self: *Self, info: union(enum) {
12332}12400}
1233312401
12334fn airRet(self: *Self, inst: Air.Inst.Index, safety: bool) !void {12402fn airRet(self: *Self, inst: Air.Inst.Index, safety: bool) !void {
12335 const mod = self.bin_file.comp.module.?;12403 const pt = self.pt;
12404 const mod = pt.zcu;
12336 const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op;12405 const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op;
1233712406
12338 const ret_ty = self.fn_type.fnReturnType(mod);12407 const ret_ty = self.fn_type.fnReturnType(mod);
...@@ -12387,7 +12456,8 @@ fn airRetLoad(self: *Self, inst: Air.Inst.Index) !void {...@@ -12387,7 +12456,8 @@ fn airRetLoad(self: *Self, inst: Air.Inst.Index) !void {
12387}12456}
1238812457
12389fn airCmp(self: *Self, inst: Air.Inst.Index, op: math.CompareOperator) !void {12458fn airCmp(self: *Self, inst: Air.Inst.Index, op: math.CompareOperator) !void {
12390 const mod = self.bin_file.comp.module.?;12459 const pt = self.pt;
12460 const mod = pt.zcu;
12391 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;12461 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
12392 var ty = self.typeOf(bin_op.lhs);12462 var ty = self.typeOf(bin_op.lhs);
12393 var null_compare: ?Mir.Inst.Index = null;12463 var null_compare: ?Mir.Inst.Index = null;
...@@ -12457,9 +12527,9 @@ fn airCmp(self: *Self, inst: Air.Inst.Index, op: math.CompareOperator) !void {...@@ -12457,9 +12527,9 @@ fn airCmp(self: *Self, inst: Air.Inst.Index, op: math.CompareOperator) !void {
12457 },12527 },
12458 .Optional => if (!ty.optionalReprIsPayload(mod)) {12528 .Optional => if (!ty.optionalReprIsPayload(mod)) {
12459 const opt_ty = ty;12529 const opt_ty = ty;
12460 const opt_abi_size: u31 = @intCast(opt_ty.abiSize(mod));12530 const opt_abi_size: u31 = @intCast(opt_ty.abiSize(pt));
12461 ty = opt_ty.optionalChild(mod);12531 ty = opt_ty.optionalChild(mod);
12462 const payload_abi_size: u31 = @intCast(ty.abiSize(mod));12532 const payload_abi_size: u31 = @intCast(ty.abiSize(pt));
1246312533
12464 const temp_lhs_reg = try self.register_manager.allocReg(null, abi.RegisterClass.gp);12534 const temp_lhs_reg = try self.register_manager.allocReg(null, abi.RegisterClass.gp);
12465 const temp_lhs_lock = self.register_manager.lockRegAssumeUnused(temp_lhs_reg);12535 const temp_lhs_lock = self.register_manager.lockRegAssumeUnused(temp_lhs_reg);
...@@ -12518,7 +12588,7 @@ fn airCmp(self: *Self, inst: Air.Inst.Index, op: math.CompareOperator) !void {...@@ -12518,7 +12588,7 @@ fn airCmp(self: *Self, inst: Air.Inst.Index, op: math.CompareOperator) !void {
1251812588
12519 switch (ty.zigTypeTag(mod)) {12589 switch (ty.zigTypeTag(mod)) {
12520 else => {12590 else => {
12521 const abi_size: u16 = @intCast(ty.abiSize(mod));12591 const abi_size: u16 = @intCast(ty.abiSize(pt));
12522 const may_flip: enum {12592 const may_flip: enum {
12523 may_flip,12593 may_flip,
12524 must_flip,12594 must_flip,
...@@ -12845,7 +12915,8 @@ fn airCmpVector(self: *Self, inst: Air.Inst.Index) !void {...@@ -12845,7 +12915,8 @@ fn airCmpVector(self: *Self, inst: Air.Inst.Index) !void {
12845}12915}
1284612916
12847fn airCmpLtErrorsLen(self: *Self, inst: Air.Inst.Index) !void {12917fn airCmpLtErrorsLen(self: *Self, inst: Air.Inst.Index) !void {
12848 const mod = self.bin_file.comp.module.?;12918 const pt = self.pt;
12919 const mod = pt.zcu;
12849 const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op;12920 const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op;
1285012921
12851 const addr_reg = try self.register_manager.allocReg(null, abi.RegisterClass.gp);12922 const addr_reg = try self.register_manager.allocReg(null, abi.RegisterClass.gp);
...@@ -12856,7 +12927,7 @@ fn airCmpLtErrorsLen(self: *Self, inst: Air.Inst.Index) !void {...@@ -12856,7 +12927,7 @@ fn airCmpLtErrorsLen(self: *Self, inst: Air.Inst.Index) !void {
12856 try self.spillEflagsIfOccupied();12927 try self.spillEflagsIfOccupied();
1285712928
12858 const op_ty = self.typeOf(un_op);12929 const op_ty = self.typeOf(un_op);
12859 const op_abi_size: u32 = @intCast(op_ty.abiSize(mod));12930 const op_abi_size: u32 = @intCast(op_ty.abiSize(pt));
12860 const op_mcv = try self.resolveInst(un_op);12931 const op_mcv = try self.resolveInst(un_op);
12861 const dst_reg = switch (op_mcv) {12932 const dst_reg = switch (op_mcv) {
12862 .register => |reg| reg,12933 .register => |reg| reg,
...@@ -12987,8 +13058,8 @@ fn airDbgVar(self: *Self, inst: Air.Inst.Index) !void {...@@ -12987,8 +13058,8 @@ fn airDbgVar(self: *Self, inst: Air.Inst.Index) !void {
12987}13058}
1298813059
12989fn genCondBrMir(self: *Self, ty: Type, mcv: MCValue) !Mir.Inst.Index {13060fn genCondBrMir(self: *Self, ty: Type, mcv: MCValue) !Mir.Inst.Index {
12990 const mod = self.bin_file.comp.module.?;13061 const pt = self.pt;
12991 const abi_size = ty.abiSize(mod);13062 const abi_size = ty.abiSize(pt);
12992 switch (mcv) {13063 switch (mcv) {
12993 .eflags => |cc| {13064 .eflags => |cc| {
12994 // Here we map the opposites since the jump is to the false branch.13065 // Here we map the opposites since the jump is to the false branch.
...@@ -13060,7 +13131,8 @@ fn airCondBr(self: *Self, inst: Air.Inst.Index) !void {...@@ -13060,7 +13131,8 @@ fn airCondBr(self: *Self, inst: Air.Inst.Index) !void {
13060}13131}
1306113132
13062fn isNull(self: *Self, inst: Air.Inst.Index, opt_ty: Type, opt_mcv: MCValue) !MCValue {13133fn isNull(self: *Self, inst: Air.Inst.Index, opt_ty: Type, opt_mcv: MCValue) !MCValue {
13063 const mod = self.bin_file.comp.module.?;13134 const pt = self.pt;
13135 const mod = pt.zcu;
13064 switch (opt_mcv) {13136 switch (opt_mcv) {
13065 .register_overflow => |ro| return .{ .eflags = ro.eflags.negate() },13137 .register_overflow => |ro| return .{ .eflags = ro.eflags.negate() },
13066 else => {},13138 else => {},
...@@ -13073,7 +13145,7 @@ fn isNull(self: *Self, inst: Air.Inst.Index, opt_ty: Type, opt_mcv: MCValue) !MC...@@ -13073,7 +13145,7 @@ fn isNull(self: *Self, inst: Air.Inst.Index, opt_ty: Type, opt_mcv: MCValue) !MC
13073 const some_info: struct { off: i32, ty: Type } = if (opt_ty.optionalReprIsPayload(mod))13145 const some_info: struct { off: i32, ty: Type } = if (opt_ty.optionalReprIsPayload(mod))
13074 .{ .off = 0, .ty = if (pl_ty.isSlice(mod)) pl_ty.slicePtrFieldType(mod) else pl_ty }13146 .{ .off = 0, .ty = if (pl_ty.isSlice(mod)) pl_ty.slicePtrFieldType(mod) else pl_ty }
13075 else13147 else
13076 .{ .off = @intCast(pl_ty.abiSize(mod)), .ty = Type.bool };13148 .{ .off = @intCast(pl_ty.abiSize(pt)), .ty = Type.bool };
1307713149
13078 self.eflags_inst = inst;13150 self.eflags_inst = inst;
13079 switch (opt_mcv) {13151 switch (opt_mcv) {
...@@ -13098,14 +13170,14 @@ fn isNull(self: *Self, inst: Air.Inst.Index, opt_ty: Type, opt_mcv: MCValue) !MC...@@ -13098,14 +13170,14 @@ fn isNull(self: *Self, inst: Air.Inst.Index, opt_ty: Type, opt_mcv: MCValue) !MC
1309813170
13099 .register => |opt_reg| {13171 .register => |opt_reg| {
13100 if (some_info.off == 0) {13172 if (some_info.off == 0) {
13101 const some_abi_size: u32 = @intCast(some_info.ty.abiSize(mod));13173 const some_abi_size: u32 = @intCast(some_info.ty.abiSize(pt));
13102 const alias_reg = registerAlias(opt_reg, some_abi_size);13174 const alias_reg = registerAlias(opt_reg, some_abi_size);
13103 assert(some_abi_size * 8 == alias_reg.bitSize());13175 assert(some_abi_size * 8 == alias_reg.bitSize());
13104 try self.asmRegisterRegister(.{ ._, .@"test" }, alias_reg, alias_reg);13176 try self.asmRegisterRegister(.{ ._, .@"test" }, alias_reg, alias_reg);
13105 return .{ .eflags = .z };13177 return .{ .eflags = .z };
13106 }13178 }
13107 assert(some_info.ty.ip_index == .bool_type);13179 assert(some_info.ty.ip_index == .bool_type);
13108 const opt_abi_size: u32 = @intCast(opt_ty.abiSize(mod));13180 const opt_abi_size: u32 = @intCast(opt_ty.abiSize(pt));
13109 try self.asmRegisterImmediate(13181 try self.asmRegisterImmediate(
13110 .{ ._, .bt },13182 .{ ._, .bt },
13111 registerAlias(opt_reg, opt_abi_size),13183 registerAlias(opt_reg, opt_abi_size),
...@@ -13125,7 +13197,7 @@ fn isNull(self: *Self, inst: Air.Inst.Index, opt_ty: Type, opt_mcv: MCValue) !MC...@@ -13125,7 +13197,7 @@ fn isNull(self: *Self, inst: Air.Inst.Index, opt_ty: Type, opt_mcv: MCValue) !MC
13125 defer self.register_manager.unlockReg(addr_reg_lock);13197 defer self.register_manager.unlockReg(addr_reg_lock);
1312613198
13127 try self.genSetReg(addr_reg, Type.usize, opt_mcv.address(), .{});13199 try self.genSetReg(addr_reg, Type.usize, opt_mcv.address(), .{});
13128 const some_abi_size: u32 = @intCast(some_info.ty.abiSize(mod));13200 const some_abi_size: u32 = @intCast(some_info.ty.abiSize(pt));
13129 try self.asmMemoryImmediate(13201 try self.asmMemoryImmediate(
13130 .{ ._, .cmp },13202 .{ ._, .cmp },
13131 .{13203 .{
...@@ -13141,7 +13213,7 @@ fn isNull(self: *Self, inst: Air.Inst.Index, opt_ty: Type, opt_mcv: MCValue) !MC...@@ -13141,7 +13213,7 @@ fn isNull(self: *Self, inst: Air.Inst.Index, opt_ty: Type, opt_mcv: MCValue) !MC
13141 },13213 },
1314213214
13143 .indirect, .load_frame => {13215 .indirect, .load_frame => {
13144 const some_abi_size: u32 = @intCast(some_info.ty.abiSize(mod));13216 const some_abi_size: u32 = @intCast(some_info.ty.abiSize(pt));
13145 try self.asmMemoryImmediate(13217 try self.asmMemoryImmediate(
13146 .{ ._, .cmp },13218 .{ ._, .cmp },
13147 switch (opt_mcv) {13219 switch (opt_mcv) {
...@@ -13169,7 +13241,8 @@ fn isNull(self: *Self, inst: Air.Inst.Index, opt_ty: Type, opt_mcv: MCValue) !MC...@@ -13169,7 +13241,8 @@ fn isNull(self: *Self, inst: Air.Inst.Index, opt_ty: Type, opt_mcv: MCValue) !MC
13169}13241}
1317013242
13171fn isNullPtr(self: *Self, inst: Air.Inst.Index, ptr_ty: Type, ptr_mcv: MCValue) !MCValue {13243fn isNullPtr(self: *Self, inst: Air.Inst.Index, ptr_ty: Type, ptr_mcv: MCValue) !MCValue {
13172 const mod = self.bin_file.comp.module.?;13244 const pt = self.pt;
13245 const mod = pt.zcu;
13173 const opt_ty = ptr_ty.childType(mod);13246 const opt_ty = ptr_ty.childType(mod);
13174 const pl_ty = opt_ty.optionalChild(mod);13247 const pl_ty = opt_ty.optionalChild(mod);
1317513248
...@@ -13178,7 +13251,7 @@ fn isNullPtr(self: *Self, inst: Air.Inst.Index, ptr_ty: Type, ptr_mcv: MCValue)...@@ -13178,7 +13251,7 @@ fn isNullPtr(self: *Self, inst: Air.Inst.Index, ptr_ty: Type, ptr_mcv: MCValue)
13178 const some_info: struct { off: i32, ty: Type } = if (opt_ty.optionalReprIsPayload(mod))13251 const some_info: struct { off: i32, ty: Type } = if (opt_ty.optionalReprIsPayload(mod))
13179 .{ .off = 0, .ty = if (pl_ty.isSlice(mod)) pl_ty.slicePtrFieldType(mod) else pl_ty }13252 .{ .off = 0, .ty = if (pl_ty.isSlice(mod)) pl_ty.slicePtrFieldType(mod) else pl_ty }
13180 else13253 else
13181 .{ .off = @intCast(pl_ty.abiSize(mod)), .ty = Type.bool };13254 .{ .off = @intCast(pl_ty.abiSize(pt)), .ty = Type.bool };
1318213255
13183 const ptr_reg = switch (ptr_mcv) {13256 const ptr_reg = switch (ptr_mcv) {
13184 .register => |reg| reg,13257 .register => |reg| reg,
...@@ -13187,7 +13260,7 @@ fn isNullPtr(self: *Self, inst: Air.Inst.Index, ptr_ty: Type, ptr_mcv: MCValue)...@@ -13187,7 +13260,7 @@ fn isNullPtr(self: *Self, inst: Air.Inst.Index, ptr_ty: Type, ptr_mcv: MCValue)
13187 const ptr_lock = self.register_manager.lockReg(ptr_reg);13260 const ptr_lock = self.register_manager.lockReg(ptr_reg);
13188 defer if (ptr_lock) |lock| self.register_manager.unlockReg(lock);13261 defer if (ptr_lock) |lock| self.register_manager.unlockReg(lock);
1318913262
13190 const some_abi_size: u32 = @intCast(some_info.ty.abiSize(mod));13263 const some_abi_size: u32 = @intCast(some_info.ty.abiSize(pt));
13191 try self.asmMemoryImmediate(13264 try self.asmMemoryImmediate(
13192 .{ ._, .cmp },13265 .{ ._, .cmp },
13193 .{13266 .{
...@@ -13205,13 +13278,14 @@ fn isNullPtr(self: *Self, inst: Air.Inst.Index, ptr_ty: Type, ptr_mcv: MCValue)...@@ -13205,13 +13278,14 @@ fn isNullPtr(self: *Self, inst: Air.Inst.Index, ptr_ty: Type, ptr_mcv: MCValue)
13205}13278}
1320613279
13207fn isErr(self: *Self, maybe_inst: ?Air.Inst.Index, eu_ty: Type, eu_mcv: MCValue) !MCValue {13280fn isErr(self: *Self, maybe_inst: ?Air.Inst.Index, eu_ty: Type, eu_mcv: MCValue) !MCValue {
13208 const mod = self.bin_file.comp.module.?;13281 const pt = self.pt;
13282 const mod = pt.zcu;
13209 const err_ty = eu_ty.errorUnionSet(mod);13283 const err_ty = eu_ty.errorUnionSet(mod);
13210 if (err_ty.errorSetIsEmpty(mod)) return MCValue{ .immediate = 0 }; // always false13284 if (err_ty.errorSetIsEmpty(mod)) return MCValue{ .immediate = 0 }; // always false
1321113285
13212 try self.spillEflagsIfOccupied();13286 try self.spillEflagsIfOccupied();
1321313287
13214 const err_off: u31 = @intCast(errUnionErrorOffset(eu_ty.errorUnionPayload(mod), mod));13288 const err_off: u31 = @intCast(errUnionErrorOffset(eu_ty.errorUnionPayload(mod), pt));
13215 switch (eu_mcv) {13289 switch (eu_mcv) {
13216 .register => |reg| {13290 .register => |reg| {
13217 const eu_lock = self.register_manager.lockReg(reg);13291 const eu_lock = self.register_manager.lockReg(reg);
...@@ -13253,7 +13327,8 @@ fn isErr(self: *Self, maybe_inst: ?Air.Inst.Index, eu_ty: Type, eu_mcv: MCValue)...@@ -13253,7 +13327,8 @@ fn isErr(self: *Self, maybe_inst: ?Air.Inst.Index, eu_ty: Type, eu_mcv: MCValue)
13253}13327}
1325413328
13255fn isErrPtr(self: *Self, maybe_inst: ?Air.Inst.Index, ptr_ty: Type, ptr_mcv: MCValue) !MCValue {13329fn isErrPtr(self: *Self, maybe_inst: ?Air.Inst.Index, ptr_ty: Type, ptr_mcv: MCValue) !MCValue {
13256 const mod = self.bin_file.comp.module.?;13330 const pt = self.pt;
13331 const mod = pt.zcu;
13257 const eu_ty = ptr_ty.childType(mod);13332 const eu_ty = ptr_ty.childType(mod);
13258 const err_ty = eu_ty.errorUnionSet(mod);13333 const err_ty = eu_ty.errorUnionSet(mod);
13259 if (err_ty.errorSetIsEmpty(mod)) return MCValue{ .immediate = 0 }; // always false13334 if (err_ty.errorSetIsEmpty(mod)) return MCValue{ .immediate = 0 }; // always false
...@@ -13267,7 +13342,7 @@ fn isErrPtr(self: *Self, maybe_inst: ?Air.Inst.Index, ptr_ty: Type, ptr_mcv: MCV...@@ -13267,7 +13342,7 @@ fn isErrPtr(self: *Self, maybe_inst: ?Air.Inst.Index, ptr_ty: Type, ptr_mcv: MCV
13267 const ptr_lock = self.register_manager.lockReg(ptr_reg);13342 const ptr_lock = self.register_manager.lockReg(ptr_reg);
13268 defer if (ptr_lock) |lock| self.register_manager.unlockReg(lock);13343 defer if (ptr_lock) |lock| self.register_manager.unlockReg(lock);
1326913344
13270 const err_off: u31 = @intCast(errUnionErrorOffset(eu_ty.errorUnionPayload(mod), mod));13345 const err_off: u31 = @intCast(errUnionErrorOffset(eu_ty.errorUnionPayload(mod), pt));
13271 try self.asmMemoryImmediate(13346 try self.asmMemoryImmediate(
13272 .{ ._, .cmp },13347 .{ ._, .cmp },
13273 .{13348 .{
...@@ -13539,12 +13614,12 @@ fn performReloc(self: *Self, reloc: Mir.Inst.Index) void {...@@ -13539,12 +13614,12 @@ fn performReloc(self: *Self, reloc: Mir.Inst.Index) void {
13539}13614}
1354013615
13541fn airBr(self: *Self, inst: Air.Inst.Index) !void {13616fn airBr(self: *Self, inst: Air.Inst.Index) !void {
13542 const mod = self.bin_file.comp.module.?;13617 const pt = self.pt;
13543 const br = self.air.instructions.items(.data)[@intFromEnum(inst)].br;13618 const br = self.air.instructions.items(.data)[@intFromEnum(inst)].br;
1354413619
13545 const block_ty = self.typeOfIndex(br.block_inst);13620 const block_ty = self.typeOfIndex(br.block_inst);
13546 const block_unused =13621 const block_unused =
13547 !block_ty.hasRuntimeBitsIgnoreComptime(mod) or self.liveness.isUnused(br.block_inst);13622 !block_ty.hasRuntimeBitsIgnoreComptime(pt) or self.liveness.isUnused(br.block_inst);
13548 const block_tracking = self.inst_tracking.getPtr(br.block_inst).?;13623 const block_tracking = self.inst_tracking.getPtr(br.block_inst).?;
13549 const block_data = self.blocks.getPtr(br.block_inst).?;13624 const block_data = self.blocks.getPtr(br.block_inst).?;
13550 const first_br = block_data.relocs.items.len == 0;13625 const first_br = block_data.relocs.items.len == 0;
...@@ -13600,7 +13675,8 @@ fn airBr(self: *Self, inst: Air.Inst.Index) !void {...@@ -13600,7 +13675,8 @@ fn airBr(self: *Self, inst: Air.Inst.Index) !void {
13600}13675}
1360113676
13602fn airAsm(self: *Self, inst: Air.Inst.Index) !void {13677fn airAsm(self: *Self, inst: Air.Inst.Index) !void {
13603 const mod = self.bin_file.comp.module.?;13678 const pt = self.pt;
13679 const mod = pt.zcu;
13604 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;13680 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
13605 const extra = self.air.extraData(Air.Asm, ty_pl.payload);13681 const extra = self.air.extraData(Air.Asm, ty_pl.payload);
13606 const clobbers_len: u31 = @truncate(extra.data.flags);13682 const clobbers_len: u31 = @truncate(extra.data.flags);
...@@ -13664,7 +13740,7 @@ fn airAsm(self: *Self, inst: Air.Inst.Index) !void {...@@ -13664,7 +13740,7 @@ fn airAsm(self: *Self, inst: Air.Inst.Index) !void {
13664 'x' => abi.RegisterClass.sse,13740 'x' => abi.RegisterClass.sse,
13665 else => unreachable,13741 else => unreachable,
13666 }) orelse return self.fail("ran out of registers lowering inline asm", .{}),13742 }) orelse return self.fail("ran out of registers lowering inline asm", .{}),
13667 @intCast(ty.abiSize(mod)),13743 @intCast(ty.abiSize(pt)),
13668 )13744 )
13669 else if (mem.eql(u8, rest, "m"))13745 else if (mem.eql(u8, rest, "m"))
13670 if (output != .none) null else return self.fail(13746 if (output != .none) null else return self.fail(
...@@ -13734,7 +13810,7 @@ fn airAsm(self: *Self, inst: Air.Inst.Index) !void {...@@ -13734,7 +13810,7 @@ fn airAsm(self: *Self, inst: Air.Inst.Index) !void {
13734 break :arg input_mcv;13810 break :arg input_mcv;
13735 const reg = try self.register_manager.allocReg(null, rc);13811 const reg = try self.register_manager.allocReg(null, rc);
13736 try self.genSetReg(reg, ty, input_mcv, .{});13812 try self.genSetReg(reg, ty, input_mcv, .{});
13737 break :arg .{ .register = registerAlias(reg, @intCast(ty.abiSize(mod))) };13813 break :arg .{ .register = registerAlias(reg, @intCast(ty.abiSize(pt))) };
13738 } else if (mem.eql(u8, constraint, "i") or mem.eql(u8, constraint, "n"))13814 } else if (mem.eql(u8, constraint, "i") or mem.eql(u8, constraint, "n"))
13739 switch (input_mcv) {13815 switch (input_mcv) {
13740 .immediate => |imm| .{ .immediate = imm },13816 .immediate => |imm| .{ .immediate = imm },
...@@ -14310,18 +14386,19 @@ const MoveStrategy = union(enum) {...@@ -14310,18 +14386,19 @@ const MoveStrategy = union(enum) {
14310 }14386 }
14311};14387};
14312fn moveStrategy(self: *Self, ty: Type, class: Register.Class, aligned: bool) !MoveStrategy {14388fn moveStrategy(self: *Self, ty: Type, class: Register.Class, aligned: bool) !MoveStrategy {
14313 const mod = self.bin_file.comp.module.?;14389 const pt = self.pt;
14390 const mod = pt.zcu;
14314 switch (class) {14391 switch (class) {
14315 .general_purpose, .segment => return .{ .move = .{ ._, .mov } },14392 .general_purpose, .segment => return .{ .move = .{ ._, .mov } },
14316 .x87 => return .x87_load_store,14393 .x87 => return .x87_load_store,
14317 .mmx => {},14394 .mmx => {},
14318 .sse => switch (ty.zigTypeTag(mod)) {14395 .sse => switch (ty.zigTypeTag(mod)) {
14319 else => {14396 else => {
14320 const classes = mem.sliceTo(&abi.classifySystemV(ty, mod, self.target.*, .other), .none);14397 const classes = mem.sliceTo(&abi.classifySystemV(ty, pt, self.target.*, .other), .none);
14321 assert(std.mem.indexOfNone(abi.Class, classes, &.{14398 assert(std.mem.indexOfNone(abi.Class, classes, &.{
14322 .integer, .sse, .sseup, .memory, .float, .float_combine,14399 .integer, .sse, .sseup, .memory, .float, .float_combine,
14323 }) == null);14400 }) == null);
14324 const abi_size = ty.abiSize(mod);14401 const abi_size = ty.abiSize(pt);
14325 if (abi_size < 4 or14402 if (abi_size < 4 or
14326 std.mem.indexOfScalar(abi.Class, classes, .integer) != null) switch (abi_size) {14403 std.mem.indexOfScalar(abi.Class, classes, .integer) != null) switch (abi_size) {
14327 1 => if (self.hasFeature(.avx)) return .{ .vex_insert_extract = .{14404 1 => if (self.hasFeature(.avx)) return .{ .vex_insert_extract = .{
...@@ -14532,7 +14609,7 @@ fn moveStrategy(self: *Self, ty: Type, class: Register.Class, aligned: bool) !Mo...@@ -14532,7 +14609,7 @@ fn moveStrategy(self: *Self, ty: Type, class: Register.Class, aligned: bool) !Mo
14532 },14609 },
14533 .ip => {},14610 .ip => {},
14534 }14611 }
14535 return self.fail("TODO moveStrategy for {}", .{ty.fmt(mod)});14612 return self.fail("TODO moveStrategy for {}", .{ty.fmt(pt)});
14536}14613}
1453714614
14538const CopyOptions = struct {14615const CopyOptions = struct {
...@@ -14540,7 +14617,7 @@ const CopyOptions = struct {...@@ -14540,7 +14617,7 @@ const CopyOptions = struct {
14540};14617};
1454114618
14542fn genCopy(self: *Self, ty: Type, dst_mcv: MCValue, src_mcv: MCValue, opts: CopyOptions) InnerError!void {14619fn genCopy(self: *Self, ty: Type, dst_mcv: MCValue, src_mcv: MCValue, opts: CopyOptions) InnerError!void {
14543 const mod = self.bin_file.comp.module.?;14620 const pt = self.pt;
1454414621
14545 const src_lock = if (src_mcv.getReg()) |reg| self.register_manager.lockReg(reg) else null;14622 const src_lock = if (src_mcv.getReg()) |reg| self.register_manager.lockReg(reg) else null;
14546 defer if (src_lock) |lock| self.register_manager.unlockReg(lock);14623 defer if (src_lock) |lock| self.register_manager.unlockReg(lock);
...@@ -14601,7 +14678,7 @@ fn genCopy(self: *Self, ty: Type, dst_mcv: MCValue, src_mcv: MCValue, opts: Copy...@@ -14601,7 +14678,7 @@ fn genCopy(self: *Self, ty: Type, dst_mcv: MCValue, src_mcv: MCValue, opts: Copy
14601 opts,14678 opts,
14602 ),14679 ),
14603 else => return self.fail("TODO implement genCopy for {s} of {}", .{14680 else => return self.fail("TODO implement genCopy for {s} of {}", .{
14604 @tagName(src_mcv), ty.fmt(mod),14681 @tagName(src_mcv), ty.fmt(pt),
14605 }),14682 }),
14606 };14683 };
14607 defer if (src_info) |info| self.register_manager.unlockReg(info.addr_lock);14684 defer if (src_info) |info| self.register_manager.unlockReg(info.addr_lock);
...@@ -14617,7 +14694,7 @@ fn genCopy(self: *Self, ty: Type, dst_mcv: MCValue, src_mcv: MCValue, opts: Copy...@@ -14617,7 +14694,7 @@ fn genCopy(self: *Self, ty: Type, dst_mcv: MCValue, src_mcv: MCValue, opts: Copy
14617 } },14694 } },
14618 else => unreachable,14695 else => unreachable,
14619 }, opts);14696 }, opts);
14620 part_disp += @intCast(dst_ty.abiSize(mod));14697 part_disp += @intCast(dst_ty.abiSize(pt));
14621 }14698 }
14622 },14699 },
14623 .indirect => |reg_off| try self.genSetMem(14700 .indirect => |reg_off| try self.genSetMem(
...@@ -14658,9 +14735,10 @@ fn genSetReg(...@@ -14658,9 +14735,10 @@ fn genSetReg(
14658 src_mcv: MCValue,14735 src_mcv: MCValue,
14659 opts: CopyOptions,14736 opts: CopyOptions,
14660) InnerError!void {14737) InnerError!void {
14661 const mod = self.bin_file.comp.module.?;14738 const pt = self.pt;
14662 const abi_size: u32 = @intCast(ty.abiSize(mod));14739 const mod = pt.zcu;
14663 if (ty.bitSize(mod) > dst_reg.bitSize())14740 const abi_size: u32 = @intCast(ty.abiSize(pt));
14741 if (ty.bitSize(pt) > dst_reg.bitSize())
14664 return self.fail("genSetReg called with a value larger than dst_reg", .{});14742 return self.fail("genSetReg called with a value larger than dst_reg", .{});
14665 switch (src_mcv) {14743 switch (src_mcv) {
14666 .none,14744 .none,
...@@ -14686,7 +14764,7 @@ fn genSetReg(...@@ -14686,7 +14764,7 @@ fn genSetReg(
14686 ),14764 ),
14687 else => unreachable,14765 else => unreachable,
14688 },14766 },
14689 .segment, .x87, .mmx, .sse => try self.genSetReg(dst_reg, ty, try self.genTypedValue(try mod.undefValue(ty)), opts),14767 .segment, .x87, .mmx, .sse => try self.genSetReg(dst_reg, ty, try self.genTypedValue(try pt.undefValue(ty)), opts),
14690 .ip => unreachable,14768 .ip => unreachable,
14691 },14769 },
14692 .eflags => |cc| try self.asmSetccRegister(cc, dst_reg.to8()),14770 .eflags => |cc| try self.asmSetccRegister(cc, dst_reg.to8()),
...@@ -14797,7 +14875,7 @@ fn genSetReg(...@@ -14797,7 +14875,7 @@ fn genSetReg(
14797 80 => null,14875 80 => null,
14798 else => unreachable,14876 else => unreachable,
14799 },14877 },
14800 }) orelse return self.fail("TODO implement genSetReg for {}", .{ty.fmt(mod)}),14878 }) orelse return self.fail("TODO implement genSetReg for {}", .{ty.fmt(pt)}),
14801 registerAlias(dst_reg, abi_size),14879 registerAlias(dst_reg, abi_size),
14802 registerAlias(src_reg, abi_size),14880 registerAlias(src_reg, abi_size),
14803 ),14881 ),
...@@ -14847,7 +14925,7 @@ fn genSetReg(...@@ -14847,7 +14925,7 @@ fn genSetReg(
14847 return (try self.moveStrategy(14925 return (try self.moveStrategy(
14848 ty,14926 ty,
14849 dst_reg.class(),14927 dst_reg.class(),
14850 ty.abiAlignment(mod).check(@as(u32, @bitCast(small_addr))),14928 ty.abiAlignment(pt).check(@as(u32, @bitCast(small_addr))),
14851 )).read(self, registerAlias(dst_reg, abi_size), .{14929 )).read(self, registerAlias(dst_reg, abi_size), .{
14852 .base = .{ .reg = .ds },14930 .base = .{ .reg = .ds },
14853 .mod = .{ .rm = .{14931 .mod = .{ .rm = .{
...@@ -14967,8 +15045,9 @@ fn genSetMem(...@@ -14967,8 +15045,9 @@ fn genSetMem(
14967 src_mcv: MCValue,15045 src_mcv: MCValue,
14968 opts: CopyOptions,15046 opts: CopyOptions,
14969) InnerError!void {15047) InnerError!void {
14970 const mod = self.bin_file.comp.module.?;15048 const pt = self.pt;
14971 const abi_size: u32 = @intCast(ty.abiSize(mod));15049 const mod = pt.zcu;
15050 const abi_size: u32 = @intCast(ty.abiSize(pt));
14972 const dst_ptr_mcv: MCValue = switch (base) {15051 const dst_ptr_mcv: MCValue = switch (base) {
14973 .none => .{ .immediate = @bitCast(@as(i64, disp)) },15052 .none => .{ .immediate = @bitCast(@as(i64, disp)) },
14974 .reg => |base_reg| .{ .register_offset = .{ .reg = base_reg, .off = disp } },15053 .reg => |base_reg| .{ .register_offset = .{ .reg = base_reg, .off = disp } },
...@@ -15094,21 +15173,21 @@ fn genSetMem(...@@ -15094,21 +15173,21 @@ fn genSetMem(
15094 var part_disp: i32 = disp;15173 var part_disp: i32 = disp;
15095 for (try self.splitType(ty), src_regs) |src_ty, src_reg| {15174 for (try self.splitType(ty), src_regs) |src_ty, src_reg| {
15096 try self.genSetMem(base, part_disp, src_ty, .{ .register = src_reg }, opts);15175 try self.genSetMem(base, part_disp, src_ty, .{ .register = src_reg }, opts);
15097 part_disp += @intCast(src_ty.abiSize(mod));15176 part_disp += @intCast(src_ty.abiSize(pt));
15098 }15177 }
15099 },15178 },
15100 .register_overflow => |ro| switch (ty.zigTypeTag(mod)) {15179 .register_overflow => |ro| switch (ty.zigTypeTag(mod)) {
15101 .Struct => {15180 .Struct => {
15102 try self.genSetMem(15181 try self.genSetMem(
15103 base,15182 base,
15104 disp + @as(i32, @intCast(ty.structFieldOffset(0, mod))),15183 disp + @as(i32, @intCast(ty.structFieldOffset(0, pt))),
15105 ty.structFieldType(0, mod),15184 ty.structFieldType(0, mod),
15106 .{ .register = ro.reg },15185 .{ .register = ro.reg },
15107 opts,15186 opts,
15108 );15187 );
15109 try self.genSetMem(15188 try self.genSetMem(
15110 base,15189 base,
15111 disp + @as(i32, @intCast(ty.structFieldOffset(1, mod))),15190 disp + @as(i32, @intCast(ty.structFieldOffset(1, pt))),
15112 ty.structFieldType(1, mod),15191 ty.structFieldType(1, mod),
15113 .{ .eflags = ro.eflags },15192 .{ .eflags = ro.eflags },
15114 opts,15193 opts,
...@@ -15120,14 +15199,14 @@ fn genSetMem(...@@ -15120,14 +15199,14 @@ fn genSetMem(
15120 try self.genSetMem(base, disp, child_ty, .{ .register = ro.reg }, opts);15199 try self.genSetMem(base, disp, child_ty, .{ .register = ro.reg }, opts);
15121 try self.genSetMem(15200 try self.genSetMem(
15122 base,15201 base,
15123 disp + @as(i32, @intCast(child_ty.abiSize(mod))),15202 disp + @as(i32, @intCast(child_ty.abiSize(pt))),
15124 Type.bool,15203 Type.bool,
15125 .{ .eflags = ro.eflags },15204 .{ .eflags = ro.eflags },
15126 opts,15205 opts,
15127 );15206 );
15128 },15207 },
15129 else => return self.fail("TODO implement genSetMem for {s} of {}", .{15208 else => return self.fail("TODO implement genSetMem for {s} of {}", .{
15130 @tagName(src_mcv), ty.fmt(mod),15209 @tagName(src_mcv), ty.fmt(pt),
15131 }),15210 }),
15132 },15211 },
15133 .register_offset,15212 .register_offset,
...@@ -15236,8 +15315,9 @@ fn genLazySymbolRef(...@@ -15236,8 +15315,9 @@ fn genLazySymbolRef(
15236 reg: Register,15315 reg: Register,
15237 lazy_sym: link.File.LazySymbol,15316 lazy_sym: link.File.LazySymbol,
15238) InnerError!void {15317) InnerError!void {
15318 const pt = self.pt;
15239 if (self.bin_file.cast(link.File.Elf)) |elf_file| {15319 if (self.bin_file.cast(link.File.Elf)) |elf_file| {
15240 const sym_index = elf_file.zigObjectPtr().?.getOrCreateMetadataForLazySymbol(elf_file, lazy_sym) catch |err|15320 const sym_index = elf_file.zigObjectPtr().?.getOrCreateMetadataForLazySymbol(elf_file, pt, lazy_sym) catch |err|
15241 return self.fail("{s} creating lazy symbol", .{@errorName(err)});15321 return self.fail("{s} creating lazy symbol", .{@errorName(err)});
15242 const sym = elf_file.symbol(sym_index);15322 const sym = elf_file.symbol(sym_index);
15243 if (self.mod.pic) {15323 if (self.mod.pic) {
...@@ -15273,7 +15353,7 @@ fn genLazySymbolRef(...@@ -15273,7 +15353,7 @@ fn genLazySymbolRef(
15273 }15353 }
15274 }15354 }
15275 } else if (self.bin_file.cast(link.File.Plan9)) |p9_file| {15355 } else if (self.bin_file.cast(link.File.Plan9)) |p9_file| {
15276 const atom_index = p9_file.getOrCreateAtomForLazySymbol(lazy_sym) catch |err|15356 const atom_index = p9_file.getOrCreateAtomForLazySymbol(pt, lazy_sym) catch |err|
15277 return self.fail("{s} creating lazy symbol", .{@errorName(err)});15357 return self.fail("{s} creating lazy symbol", .{@errorName(err)});
15278 var atom = p9_file.getAtom(atom_index);15358 var atom = p9_file.getAtom(atom_index);
15279 _ = atom.getOrCreateOffsetTableEntry(p9_file);15359 _ = atom.getOrCreateOffsetTableEntry(p9_file);
...@@ -15300,7 +15380,7 @@ fn genLazySymbolRef(...@@ -15300,7 +15380,7 @@ fn genLazySymbolRef(
15300 else => unreachable,15380 else => unreachable,
15301 }15381 }
15302 } else if (self.bin_file.cast(link.File.Coff)) |coff_file| {15382 } else if (self.bin_file.cast(link.File.Coff)) |coff_file| {
15303 const atom_index = coff_file.getOrCreateAtomForLazySymbol(lazy_sym) catch |err|15383 const atom_index = coff_file.getOrCreateAtomForLazySymbol(pt, lazy_sym) catch |err|
15304 return self.fail("{s} creating lazy symbol", .{@errorName(err)});15384 return self.fail("{s} creating lazy symbol", .{@errorName(err)});
15305 const sym_index = coff_file.getAtom(atom_index).getSymbolIndex().?;15385 const sym_index = coff_file.getAtom(atom_index).getSymbolIndex().?;
15306 switch (tag) {15386 switch (tag) {
...@@ -15314,7 +15394,7 @@ fn genLazySymbolRef(...@@ -15314,7 +15394,7 @@ fn genLazySymbolRef(
15314 else => unreachable,15394 else => unreachable,
15315 }15395 }
15316 } else if (self.bin_file.cast(link.File.MachO)) |macho_file| {15396 } else if (self.bin_file.cast(link.File.MachO)) |macho_file| {
15317 const sym_index = macho_file.getZigObject().?.getOrCreateMetadataForLazySymbol(macho_file, lazy_sym) catch |err|15397 const sym_index = macho_file.getZigObject().?.getOrCreateMetadataForLazySymbol(macho_file, pt, lazy_sym) catch |err|
15318 return self.fail("{s} creating lazy symbol", .{@errorName(err)});15398 return self.fail("{s} creating lazy symbol", .{@errorName(err)});
15319 const sym = macho_file.getSymbol(sym_index);15399 const sym = macho_file.getSymbol(sym_index);
15320 switch (tag) {15400 switch (tag) {
...@@ -15353,7 +15433,8 @@ fn airIntFromPtr(self: *Self, inst: Air.Inst.Index) !void {...@@ -15353,7 +15433,8 @@ fn airIntFromPtr(self: *Self, inst: Air.Inst.Index) !void {
15353}15433}
1535415434
15355fn airBitCast(self: *Self, inst: Air.Inst.Index) !void {15435fn airBitCast(self: *Self, inst: Air.Inst.Index) !void {
15356 const mod = self.bin_file.comp.module.?;15436 const pt = self.pt;
15437 const mod = pt.zcu;
15357 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;15438 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
15358 const dst_ty = self.typeOfIndex(inst);15439 const dst_ty = self.typeOfIndex(inst);
15359 const src_ty = self.typeOf(ty_op.operand);15440 const src_ty = self.typeOf(ty_op.operand);
...@@ -15366,10 +15447,10 @@ fn airBitCast(self: *Self, inst: Air.Inst.Index) !void {...@@ -15366,10 +15447,10 @@ fn airBitCast(self: *Self, inst: Air.Inst.Index) !void {
15366 const src_lock = if (src_mcv.getReg()) |reg| self.register_manager.lockReg(reg) else null;15447 const src_lock = if (src_mcv.getReg()) |reg| self.register_manager.lockReg(reg) else null;
15367 defer if (src_lock) |lock| self.register_manager.unlockReg(lock);15448 defer if (src_lock) |lock| self.register_manager.unlockReg(lock);
1536815449
15369 const dst_mcv = if (dst_rc.supersetOf(src_rc) and dst_ty.abiSize(mod) <= src_ty.abiSize(mod) and15450 const dst_mcv = if (dst_rc.supersetOf(src_rc) and dst_ty.abiSize(pt) <= src_ty.abiSize(pt) and
15370 self.reuseOperand(inst, ty_op.operand, 0, src_mcv)) src_mcv else dst: {15451 self.reuseOperand(inst, ty_op.operand, 0, src_mcv)) src_mcv else dst: {
15371 const dst_mcv = try self.allocRegOrMem(inst, true);15452 const dst_mcv = try self.allocRegOrMem(inst, true);
15372 try self.genCopy(switch (math.order(dst_ty.abiSize(mod), src_ty.abiSize(mod))) {15453 try self.genCopy(switch (math.order(dst_ty.abiSize(pt), src_ty.abiSize(pt))) {
15373 .lt => dst_ty,15454 .lt => dst_ty,
15374 .eq => if (!dst_mcv.isMemory() or src_mcv.isMemory()) dst_ty else src_ty,15455 .eq => if (!dst_mcv.isMemory() or src_mcv.isMemory()) dst_ty else src_ty,
15375 .gt => src_ty,15456 .gt => src_ty,
...@@ -15382,8 +15463,8 @@ fn airBitCast(self: *Self, inst: Air.Inst.Index) !void {...@@ -15382,8 +15463,8 @@ fn airBitCast(self: *Self, inst: Air.Inst.Index) !void {
15382 if (dst_ty.isAbiInt(mod) and src_ty.isAbiInt(mod) and15463 if (dst_ty.isAbiInt(mod) and src_ty.isAbiInt(mod) and
15383 dst_ty.intInfo(mod).signedness == src_ty.intInfo(mod).signedness) break :result dst_mcv;15464 dst_ty.intInfo(mod).signedness == src_ty.intInfo(mod).signedness) break :result dst_mcv;
1538415465
15385 const abi_size = dst_ty.abiSize(mod);15466 const abi_size = dst_ty.abiSize(pt);
15386 const bit_size = dst_ty.bitSize(mod);15467 const bit_size = dst_ty.bitSize(pt);
15387 if (abi_size * 8 <= bit_size or dst_ty.isVector(mod)) break :result dst_mcv;15468 if (abi_size * 8 <= bit_size or dst_ty.isVector(mod)) break :result dst_mcv;
1538815469
15389 const dst_limbs_len = math.divCeil(i32, @intCast(bit_size), 64) catch unreachable;15470 const dst_limbs_len = math.divCeil(i32, @intCast(bit_size), 64) catch unreachable;
...@@ -15412,7 +15493,8 @@ fn airBitCast(self: *Self, inst: Air.Inst.Index) !void {...@@ -15412,7 +15493,8 @@ fn airBitCast(self: *Self, inst: Air.Inst.Index) !void {
15412}15493}
1541315494
15414fn airArrayToSlice(self: *Self, inst: Air.Inst.Index) !void {15495fn airArrayToSlice(self: *Self, inst: Air.Inst.Index) !void {
15415 const mod = self.bin_file.comp.module.?;15496 const pt = self.pt;
15497 const mod = pt.zcu;
15416 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;15498 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
1541715499
15418 const slice_ty = self.typeOfIndex(inst);15500 const slice_ty = self.typeOfIndex(inst);
...@@ -15421,11 +15503,11 @@ fn airArrayToSlice(self: *Self, inst: Air.Inst.Index) !void {...@@ -15421,11 +15503,11 @@ fn airArrayToSlice(self: *Self, inst: Air.Inst.Index) !void {
15421 const array_ty = ptr_ty.childType(mod);15503 const array_ty = ptr_ty.childType(mod);
15422 const array_len = array_ty.arrayLen(mod);15504 const array_len = array_ty.arrayLen(mod);
1542315505
15424 const frame_index = try self.allocFrameIndex(FrameAlloc.initSpill(slice_ty, mod));15506 const frame_index = try self.allocFrameIndex(FrameAlloc.initSpill(slice_ty, pt));
15425 try self.genSetMem(.{ .frame = frame_index }, 0, ptr_ty, ptr, .{});15507 try self.genSetMem(.{ .frame = frame_index }, 0, ptr_ty, ptr, .{});
15426 try self.genSetMem(15508 try self.genSetMem(
15427 .{ .frame = frame_index },15509 .{ .frame = frame_index },
15428 @intCast(ptr_ty.abiSize(mod)),15510 @intCast(ptr_ty.abiSize(pt)),
15429 Type.usize,15511 Type.usize,
15430 .{ .immediate = array_len },15512 .{ .immediate = array_len },
15431 .{},15513 .{},
...@@ -15436,14 +15518,15 @@ fn airArrayToSlice(self: *Self, inst: Air.Inst.Index) !void {...@@ -15436,14 +15518,15 @@ fn airArrayToSlice(self: *Self, inst: Air.Inst.Index) !void {
15436}15518}
1543715519
15438fn airFloatFromInt(self: *Self, inst: Air.Inst.Index) !void {15520fn airFloatFromInt(self: *Self, inst: Air.Inst.Index) !void {
15439 const mod = self.bin_file.comp.module.?;15521 const pt = self.pt;
15522 const mod = pt.zcu;
15440 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;15523 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
1544115524
15442 const dst_ty = self.typeOfIndex(inst);15525 const dst_ty = self.typeOfIndex(inst);
15443 const dst_bits = dst_ty.floatBits(self.target.*);15526 const dst_bits = dst_ty.floatBits(self.target.*);
1544415527
15445 const src_ty = self.typeOf(ty_op.operand);15528 const src_ty = self.typeOf(ty_op.operand);
15446 const src_bits: u32 = @intCast(src_ty.bitSize(mod));15529 const src_bits: u32 = @intCast(src_ty.bitSize(pt));
15447 const src_signedness =15530 const src_signedness =
15448 if (src_ty.isAbiInt(mod)) src_ty.intInfo(mod).signedness else .unsigned;15531 if (src_ty.isAbiInt(mod)) src_ty.intInfo(mod).signedness else .unsigned;
15449 const src_size = math.divCeil(u32, @max(switch (src_signedness) {15532 const src_size = math.divCeil(u32, @max(switch (src_signedness) {
...@@ -15458,7 +15541,7 @@ fn airFloatFromInt(self: *Self, inst: Air.Inst.Index) !void {...@@ -15458,7 +15541,7 @@ fn airFloatFromInt(self: *Self, inst: Air.Inst.Index) !void {
15458 else => unreachable,15541 else => unreachable,
15459 }) {15542 }) {
15460 if (src_bits > 128) return self.fail("TODO implement airFloatFromInt from {} to {}", .{15543 if (src_bits > 128) return self.fail("TODO implement airFloatFromInt from {} to {}", .{
15461 src_ty.fmt(mod), dst_ty.fmt(mod),15544 src_ty.fmt(pt), dst_ty.fmt(pt),
15462 });15545 });
1546315546
15464 var callee_buf: ["__floatun?i?f".len]u8 = undefined;15547 var callee_buf: ["__floatun?i?f".len]u8 = undefined;
...@@ -15500,7 +15583,7 @@ fn airFloatFromInt(self: *Self, inst: Air.Inst.Index) !void {...@@ -15500,7 +15583,7 @@ fn airFloatFromInt(self: *Self, inst: Air.Inst.Index) !void {
15500 },15583 },
15501 else => null,15584 else => null,
15502 }) orelse return self.fail("TODO implement airFloatFromInt from {} to {}", .{15585 }) orelse return self.fail("TODO implement airFloatFromInt from {} to {}", .{
15503 src_ty.fmt(mod), dst_ty.fmt(mod),15586 src_ty.fmt(pt), dst_ty.fmt(pt),
15504 });15587 });
15505 const dst_alias = dst_reg.to128();15588 const dst_alias = dst_reg.to128();
15506 const src_alias = registerAlias(src_reg, src_size);15589 const src_alias = registerAlias(src_reg, src_size);
...@@ -15515,11 +15598,12 @@ fn airFloatFromInt(self: *Self, inst: Air.Inst.Index) !void {...@@ -15515,11 +15598,12 @@ fn airFloatFromInt(self: *Self, inst: Air.Inst.Index) !void {
15515}15598}
1551615599
15517fn airIntFromFloat(self: *Self, inst: Air.Inst.Index) !void {15600fn airIntFromFloat(self: *Self, inst: Air.Inst.Index) !void {
15518 const mod = self.bin_file.comp.module.?;15601 const pt = self.pt;
15602 const mod = pt.zcu;
15519 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;15603 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
1552015604
15521 const dst_ty = self.typeOfIndex(inst);15605 const dst_ty = self.typeOfIndex(inst);
15522 const dst_bits: u32 = @intCast(dst_ty.bitSize(mod));15606 const dst_bits: u32 = @intCast(dst_ty.bitSize(pt));
15523 const dst_signedness =15607 const dst_signedness =
15524 if (dst_ty.isAbiInt(mod)) dst_ty.intInfo(mod).signedness else .unsigned;15608 if (dst_ty.isAbiInt(mod)) dst_ty.intInfo(mod).signedness else .unsigned;
15525 const dst_size = math.divCeil(u32, @max(switch (dst_signedness) {15609 const dst_size = math.divCeil(u32, @max(switch (dst_signedness) {
...@@ -15537,7 +15621,7 @@ fn airIntFromFloat(self: *Self, inst: Air.Inst.Index) !void {...@@ -15537,7 +15621,7 @@ fn airIntFromFloat(self: *Self, inst: Air.Inst.Index) !void {
15537 else => unreachable,15621 else => unreachable,
15538 }) {15622 }) {
15539 if (dst_bits > 128) return self.fail("TODO implement airIntFromFloat from {} to {}", .{15623 if (dst_bits > 128) return self.fail("TODO implement airIntFromFloat from {} to {}", .{
15540 src_ty.fmt(mod), dst_ty.fmt(mod),15624 src_ty.fmt(pt), dst_ty.fmt(pt),
15541 });15625 });
1554215626
15543 var callee_buf: ["__fixuns?f?i".len]u8 = undefined;15627 var callee_buf: ["__fixuns?f?i".len]u8 = undefined;
...@@ -15586,13 +15670,13 @@ fn airIntFromFloat(self: *Self, inst: Air.Inst.Index) !void {...@@ -15586,13 +15670,13 @@ fn airIntFromFloat(self: *Self, inst: Air.Inst.Index) !void {
15586}15670}
1558715671
15588fn airCmpxchg(self: *Self, inst: Air.Inst.Index) !void {15672fn airCmpxchg(self: *Self, inst: Air.Inst.Index) !void {
15589 const mod = self.bin_file.comp.module.?;15673 const pt = self.pt;
15590 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;15674 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
15591 const extra = self.air.extraData(Air.Cmpxchg, ty_pl.payload).data;15675 const extra = self.air.extraData(Air.Cmpxchg, ty_pl.payload).data;
1559215676
15593 const ptr_ty = self.typeOf(extra.ptr);15677 const ptr_ty = self.typeOf(extra.ptr);
15594 const val_ty = self.typeOf(extra.expected_value);15678 const val_ty = self.typeOf(extra.expected_value);
15595 const val_abi_size: u32 = @intCast(val_ty.abiSize(mod));15679 const val_abi_size: u32 = @intCast(val_ty.abiSize(pt));
1559615680
15597 try self.spillRegisters(&.{ .rax, .rdx, .rbx, .rcx });15681 try self.spillRegisters(&.{ .rax, .rdx, .rbx, .rcx });
15598 const regs_lock = self.register_manager.lockRegsAssumeUnused(4, .{ .rax, .rdx, .rbx, .rcx });15682 const regs_lock = self.register_manager.lockRegsAssumeUnused(4, .{ .rax, .rdx, .rbx, .rcx });
...@@ -15682,7 +15766,8 @@ fn atomicOp(...@@ -15682,7 +15766,8 @@ fn atomicOp(
15682 rmw_op: ?std.builtin.AtomicRmwOp,15766 rmw_op: ?std.builtin.AtomicRmwOp,
15683 order: std.builtin.AtomicOrder,15767 order: std.builtin.AtomicOrder,
15684) InnerError!MCValue {15768) InnerError!MCValue {
15685 const mod = self.bin_file.comp.module.?;15769 const pt = self.pt;
15770 const mod = pt.zcu;
15686 const ptr_lock = switch (ptr_mcv) {15771 const ptr_lock = switch (ptr_mcv) {
15687 .register => |reg| self.register_manager.lockReg(reg),15772 .register => |reg| self.register_manager.lockReg(reg),
15688 else => null,15773 else => null,
...@@ -15695,7 +15780,7 @@ fn atomicOp(...@@ -15695,7 +15780,7 @@ fn atomicOp(
15695 };15780 };
15696 defer if (val_lock) |lock| self.register_manager.unlockReg(lock);15781 defer if (val_lock) |lock| self.register_manager.unlockReg(lock);
1569715782
15698 const val_abi_size: u32 = @intCast(val_ty.abiSize(mod));15783 const val_abi_size: u32 = @intCast(val_ty.abiSize(pt));
15699 const mem_size = Memory.Size.fromSize(val_abi_size);15784 const mem_size = Memory.Size.fromSize(val_abi_size);
15700 const ptr_mem: Memory = switch (ptr_mcv) {15785 const ptr_mem: Memory = switch (ptr_mcv) {
15701 .immediate, .register, .register_offset, .lea_frame => try ptr_mcv.deref().mem(self, mem_size),15786 .immediate, .register, .register_offset, .lea_frame => try ptr_mcv.deref().mem(self, mem_size),
...@@ -15809,7 +15894,7 @@ fn atomicOp(...@@ -15809,7 +15894,7 @@ fn atomicOp(
15809 },15894 },
15810 else => unreachable,15895 else => unreachable,
15811 }) orelse return self.fail("TODO implement atomicOp of {s} for {}", .{15896 }) orelse return self.fail("TODO implement atomicOp of {s} for {}", .{
15812 @tagName(op), val_ty.fmt(mod),15897 @tagName(op), val_ty.fmt(pt),
15813 });15898 });
15814 try self.genSetReg(sse_reg, val_ty, .{ .register = .rax }, .{});15899 try self.genSetReg(sse_reg, val_ty, .{ .register = .rax }, .{});
15815 switch (mir_tag[0]) {15900 switch (mir_tag[0]) {
...@@ -16086,7 +16171,8 @@ fn airAtomicStore(self: *Self, inst: Air.Inst.Index, order: std.builtin.AtomicOr...@@ -16086,7 +16171,8 @@ fn airAtomicStore(self: *Self, inst: Air.Inst.Index, order: std.builtin.AtomicOr
16086}16171}
1608716172
16088fn airMemset(self: *Self, inst: Air.Inst.Index, safety: bool) !void {16173fn airMemset(self: *Self, inst: Air.Inst.Index, safety: bool) !void {
16089 const mod = self.bin_file.comp.module.?;16174 const pt = self.pt;
16175 const mod = pt.zcu;
16090 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;16176 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
1609116177
16092 result: {16178 result: {
...@@ -16112,7 +16198,7 @@ fn airMemset(self: *Self, inst: Air.Inst.Index, safety: bool) !void {...@@ -16112,7 +16198,7 @@ fn airMemset(self: *Self, inst: Air.Inst.Index, safety: bool) !void {
16112 };16198 };
16113 defer if (src_val_lock) |lock| self.register_manager.unlockReg(lock);16199 defer if (src_val_lock) |lock| self.register_manager.unlockReg(lock);
1611416200
16115 const elem_abi_size: u31 = @intCast(elem_ty.abiSize(mod));16201 const elem_abi_size: u31 = @intCast(elem_ty.abiSize(pt));
1611616202
16117 if (elem_abi_size == 1) {16203 if (elem_abi_size == 1) {
16118 const ptr: MCValue = switch (dst_ptr_ty.ptrSize(mod)) {16204 const ptr: MCValue = switch (dst_ptr_ty.ptrSize(mod)) {
...@@ -16185,7 +16271,7 @@ fn airMemset(self: *Self, inst: Air.Inst.Index, safety: bool) !void {...@@ -16185,7 +16271,7 @@ fn airMemset(self: *Self, inst: Air.Inst.Index, safety: bool) !void {
16185 self.performReloc(skip_reloc);16271 self.performReloc(skip_reloc);
16186 },16272 },
16187 .One => {16273 .One => {
16188 const elem_ptr_ty = try mod.singleMutPtrType(elem_ty);16274 const elem_ptr_ty = try pt.singleMutPtrType(elem_ty);
1618916275
16190 const len = dst_ptr_ty.childType(mod).arrayLen(mod);16276 const len = dst_ptr_ty.childType(mod).arrayLen(mod);
1619116277
...@@ -16214,7 +16300,8 @@ fn airMemset(self: *Self, inst: Air.Inst.Index, safety: bool) !void {...@@ -16214,7 +16300,8 @@ fn airMemset(self: *Self, inst: Air.Inst.Index, safety: bool) !void {
16214}16300}
1621516301
16216fn airMemcpy(self: *Self, inst: Air.Inst.Index) !void {16302fn airMemcpy(self: *Self, inst: Air.Inst.Index) !void {
16217 const mod = self.bin_file.comp.module.?;16303 const pt = self.pt;
16304 const mod = pt.zcu;
16218 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;16305 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
1621916306
16220 try self.spillRegisters(&.{ .rdi, .rsi, .rcx });16307 try self.spillRegisters(&.{ .rdi, .rsi, .rcx });
...@@ -16246,13 +16333,13 @@ fn airMemcpy(self: *Self, inst: Air.Inst.Index) !void {...@@ -16246,13 +16333,13 @@ fn airMemcpy(self: *Self, inst: Air.Inst.Index) !void {
16246 .{ .i_, .mul },16333 .{ .i_, .mul },
16247 len_reg,16334 len_reg,
16248 try dst_ptr.address().offset(8).deref().mem(self, .qword),16335 try dst_ptr.address().offset(8).deref().mem(self, .qword),
16249 Immediate.s(@intCast(dst_ptr_ty.childType(mod).abiSize(mod))),16336 Immediate.s(@intCast(dst_ptr_ty.childType(mod).abiSize(pt))),
16250 );16337 );
16251 break :len .{ .register = len_reg };16338 break :len .{ .register = len_reg };
16252 },16339 },
16253 .One => len: {16340 .One => len: {
16254 const array_ty = dst_ptr_ty.childType(mod);16341 const array_ty = dst_ptr_ty.childType(mod);
16255 break :len .{ .immediate = array_ty.arrayLen(mod) * array_ty.childType(mod).abiSize(mod) };16342 break :len .{ .immediate = array_ty.arrayLen(mod) * array_ty.childType(mod).abiSize(pt) };
16256 },16343 },
16257 .C, .Many => unreachable,16344 .C, .Many => unreachable,
16258 };16345 };
...@@ -16269,7 +16356,8 @@ fn airMemcpy(self: *Self, inst: Air.Inst.Index) !void {...@@ -16269,7 +16356,8 @@ fn airMemcpy(self: *Self, inst: Air.Inst.Index) !void {
16269}16356}
1627016357
16271fn airTagName(self: *Self, inst: Air.Inst.Index) !void {16358fn airTagName(self: *Self, inst: Air.Inst.Index) !void {
16272 const mod = self.bin_file.comp.module.?;16359 const pt = self.pt;
16360 const mod = pt.zcu;
16273 const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op;16361 const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op;
16274 const inst_ty = self.typeOfIndex(inst);16362 const inst_ty = self.typeOfIndex(inst);
16275 const enum_ty = self.typeOf(un_op);16363 const enum_ty = self.typeOf(un_op);
...@@ -16278,8 +16366,8 @@ fn airTagName(self: *Self, inst: Air.Inst.Index) !void {...@@ -16278,8 +16366,8 @@ fn airTagName(self: *Self, inst: Air.Inst.Index) !void {
16278 // We need a properly aligned and sized call frame to be able to call this function.16366 // We need a properly aligned and sized call frame to be able to call this function.
16279 {16367 {
16280 const needed_call_frame = FrameAlloc.init(.{16368 const needed_call_frame = FrameAlloc.init(.{
16281 .size = inst_ty.abiSize(mod),16369 .size = inst_ty.abiSize(pt),
16282 .alignment = inst_ty.abiAlignment(mod),16370 .alignment = inst_ty.abiAlignment(pt),
16283 });16371 });
16284 const frame_allocs_slice = self.frame_allocs.slice();16372 const frame_allocs_slice = self.frame_allocs.slice();
16285 const stack_frame_size =16373 const stack_frame_size =
...@@ -16311,7 +16399,8 @@ fn airTagName(self: *Self, inst: Air.Inst.Index) !void {...@@ -16311,7 +16399,8 @@ fn airTagName(self: *Self, inst: Air.Inst.Index) !void {
16311}16399}
1631216400
16313fn airErrorName(self: *Self, inst: Air.Inst.Index) !void {16401fn airErrorName(self: *Self, inst: Air.Inst.Index) !void {
16314 const mod = self.bin_file.comp.module.?;16402 const pt = self.pt;
16403 const mod = pt.zcu;
16315 const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op;16404 const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op;
1631616405
16317 const err_ty = self.typeOf(un_op);16406 const err_ty = self.typeOf(un_op);
...@@ -16413,7 +16502,8 @@ fn airErrorName(self: *Self, inst: Air.Inst.Index) !void {...@@ -16413,7 +16502,8 @@ fn airErrorName(self: *Self, inst: Air.Inst.Index) !void {
16413}16502}
1641416503
16415fn airSplat(self: *Self, inst: Air.Inst.Index) !void {16504fn airSplat(self: *Self, inst: Air.Inst.Index) !void {
16416 const mod = self.bin_file.comp.module.?;16505 const pt = self.pt;
16506 const mod = pt.zcu;
16417 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;16507 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
16418 const vector_ty = self.typeOfIndex(inst);16508 const vector_ty = self.typeOfIndex(inst);
16419 const vector_len = vector_ty.vectorLen(mod);16509 const vector_len = vector_ty.vectorLen(mod);
...@@ -16495,15 +16585,15 @@ fn airSplat(self: *Self, inst: Air.Inst.Index) !void {...@@ -16495,15 +16585,15 @@ fn airSplat(self: *Self, inst: Air.Inst.Index) !void {
16495 const src_mcv = try self.resolveInst(ty_op.operand);16585 const src_mcv = try self.resolveInst(ty_op.operand);
16496 if (src_mcv.isMemory()) try self.asmRegisterMemory(16586 if (src_mcv.isMemory()) try self.asmRegisterMemory(
16497 mir_tag,16587 mir_tag,
16498 registerAlias(dst_reg, @intCast(vector_ty.abiSize(mod))),16588 registerAlias(dst_reg, @intCast(vector_ty.abiSize(pt))),
16499 try src_mcv.mem(self, self.memSize(scalar_ty)),16589 try src_mcv.mem(self, self.memSize(scalar_ty)),
16500 ) else {16590 ) else {
16501 if (mir_tag[0] == .v_i128) break :avx2;16591 if (mir_tag[0] == .v_i128) break :avx2;
16502 try self.genSetReg(dst_reg, scalar_ty, src_mcv, .{});16592 try self.genSetReg(dst_reg, scalar_ty, src_mcv, .{});
16503 try self.asmRegisterRegister(16593 try self.asmRegisterRegister(
16504 mir_tag,16594 mir_tag,
16505 registerAlias(dst_reg, @intCast(vector_ty.abiSize(mod))),16595 registerAlias(dst_reg, @intCast(vector_ty.abiSize(pt))),
16506 registerAlias(dst_reg, @intCast(scalar_ty.abiSize(mod))),16596 registerAlias(dst_reg, @intCast(scalar_ty.abiSize(pt))),
16507 );16597 );
16508 }16598 }
16509 break :result .{ .register = dst_reg };16599 break :result .{ .register = dst_reg };
...@@ -16515,7 +16605,7 @@ fn airSplat(self: *Self, inst: Air.Inst.Index) !void {...@@ -16515,7 +16605,7 @@ fn airSplat(self: *Self, inst: Air.Inst.Index) !void {
16515 try self.genSetReg(dst_reg, scalar_ty, .{ .air_ref = ty_op.operand }, .{});16605 try self.genSetReg(dst_reg, scalar_ty, .{ .air_ref = ty_op.operand }, .{});
16516 if (vector_len == 1) break :result .{ .register = dst_reg };16606 if (vector_len == 1) break :result .{ .register = dst_reg };
1651716607
16518 const dst_alias = registerAlias(dst_reg, @intCast(vector_ty.abiSize(mod)));16608 const dst_alias = registerAlias(dst_reg, @intCast(vector_ty.abiSize(pt)));
16519 const scalar_bits = scalar_ty.intInfo(mod).bits;16609 const scalar_bits = scalar_ty.intInfo(mod).bits;
16520 if (switch (scalar_bits) {16610 if (switch (scalar_bits) {
16521 1...8 => true,16611 1...8 => true,
...@@ -16745,20 +16835,21 @@ fn airSplat(self: *Self, inst: Air.Inst.Index) !void {...@@ -16745,20 +16835,21 @@ fn airSplat(self: *Self, inst: Air.Inst.Index) !void {
16745 else => unreachable,16835 else => unreachable,
16746 },16836 },
16747 }16837 }
16748 return self.fail("TODO implement airSplat for {}", .{vector_ty.fmt(mod)});16838 return self.fail("TODO implement airSplat for {}", .{vector_ty.fmt(pt)});
16749 };16839 };
16750 return self.finishAir(inst, result, .{ ty_op.operand, .none, .none });16840 return self.finishAir(inst, result, .{ ty_op.operand, .none, .none });
16751}16841}
1675216842
16753fn airSelect(self: *Self, inst: Air.Inst.Index) !void {16843fn airSelect(self: *Self, inst: Air.Inst.Index) !void {
16754 const mod = self.bin_file.comp.module.?;16844 const pt = self.pt;
16845 const mod = pt.zcu;
16755 const pl_op = self.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;16846 const pl_op = self.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;
16756 const extra = self.air.extraData(Air.Bin, pl_op.payload).data;16847 const extra = self.air.extraData(Air.Bin, pl_op.payload).data;
16757 const ty = self.typeOfIndex(inst);16848 const ty = self.typeOfIndex(inst);
16758 const vec_len = ty.vectorLen(mod);16849 const vec_len = ty.vectorLen(mod);
16759 const elem_ty = ty.childType(mod);16850 const elem_ty = ty.childType(mod);
16760 const elem_abi_size: u32 = @intCast(elem_ty.abiSize(mod));16851 const elem_abi_size: u32 = @intCast(elem_ty.abiSize(pt));
16761 const abi_size: u32 = @intCast(ty.abiSize(mod));16852 const abi_size: u32 = @intCast(ty.abiSize(pt));
16762 const pred_ty = self.typeOf(pl_op.operand);16853 const pred_ty = self.typeOf(pl_op.operand);
1676316854
16764 const result = result: {16855 const result = result: {
...@@ -16878,17 +16969,17 @@ fn airSelect(self: *Self, inst: Air.Inst.Index) !void {...@@ -16878,17 +16969,17 @@ fn airSelect(self: *Self, inst: Air.Inst.Index) !void {
16878 else => unreachable,16969 else => unreachable,
16879 }),16970 }),
16880 );16971 );
16881 } else return self.fail("TODO implement airSelect for {}", .{ty.fmt(mod)});16972 } else return self.fail("TODO implement airSelect for {}", .{ty.fmt(pt)});
16882 const elem_bits: u16 = @intCast(elem_abi_size * 8);16973 const elem_bits: u16 = @intCast(elem_abi_size * 8);
16883 const mask_elem_ty = try mod.intType(.unsigned, elem_bits);16974 const mask_elem_ty = try pt.intType(.unsigned, elem_bits);
16884 const mask_ty = try mod.vectorType(.{ .len = vec_len, .child = mask_elem_ty.toIntern() });16975 const mask_ty = try pt.vectorType(.{ .len = vec_len, .child = mask_elem_ty.toIntern() });
16885 if (!pred_fits_in_elem) if (self.hasFeature(.ssse3)) {16976 if (!pred_fits_in_elem) if (self.hasFeature(.ssse3)) {
16886 var mask_elems: [32]InternPool.Index = undefined;16977 var mask_elems: [32]InternPool.Index = undefined;
16887 for (mask_elems[0..vec_len], 0..) |*elem, bit| elem.* = try mod.intern(.{ .int = .{16978 for (mask_elems[0..vec_len], 0..) |*elem, bit| elem.* = try pt.intern(.{ .int = .{
16888 .ty = mask_elem_ty.toIntern(),16979 .ty = mask_elem_ty.toIntern(),
16889 .storage = .{ .u64 = bit / elem_bits },16980 .storage = .{ .u64 = bit / elem_bits },
16890 } });16981 } });
16891 const mask_mcv = try self.genTypedValue(Value.fromInterned(try mod.intern(.{ .aggregate = .{16982 const mask_mcv = try self.genTypedValue(Value.fromInterned(try pt.intern(.{ .aggregate = .{
16892 .ty = mask_ty.toIntern(),16983 .ty = mask_ty.toIntern(),
16893 .storage = .{ .elems = mask_elems[0..vec_len] },16984 .storage = .{ .elems = mask_elems[0..vec_len] },
16894 } })));16985 } })));
...@@ -16906,14 +16997,14 @@ fn airSelect(self: *Self, inst: Air.Inst.Index) !void {...@@ -16906,14 +16997,14 @@ fn airSelect(self: *Self, inst: Air.Inst.Index) !void {
16906 mask_alias,16997 mask_alias,
16907 mask_mem,16998 mask_mem,
16908 );16999 );
16909 } else return self.fail("TODO implement airSelect for {}", .{ty.fmt(mod)});17000 } else return self.fail("TODO implement airSelect for {}", .{ty.fmt(pt)});
16910 {17001 {
16911 var mask_elems: [32]InternPool.Index = undefined;17002 var mask_elems: [32]InternPool.Index = undefined;
16912 for (mask_elems[0..vec_len], 0..) |*elem, bit| elem.* = try mod.intern(.{ .int = .{17003 for (mask_elems[0..vec_len], 0..) |*elem, bit| elem.* = try pt.intern(.{ .int = .{
16913 .ty = mask_elem_ty.toIntern(),17004 .ty = mask_elem_ty.toIntern(),
16914 .storage = .{ .u64 = @as(u32, 1) << @intCast(bit & (elem_bits - 1)) },17005 .storage = .{ .u64 = @as(u32, 1) << @intCast(bit & (elem_bits - 1)) },
16915 } });17006 } });
16916 const mask_mcv = try self.genTypedValue(Value.fromInterned(try mod.intern(.{ .aggregate = .{17007 const mask_mcv = try self.genTypedValue(Value.fromInterned(try pt.intern(.{ .aggregate = .{
16917 .ty = mask_ty.toIntern(),17008 .ty = mask_ty.toIntern(),
16918 .storage = .{ .elems = mask_elems[0..vec_len] },17009 .storage = .{ .elems = mask_elems[0..vec_len] },
16919 } })));17010 } })));
...@@ -17014,7 +17105,7 @@ fn airSelect(self: *Self, inst: Air.Inst.Index) !void {...@@ -17014,7 +17105,7 @@ fn airSelect(self: *Self, inst: Air.Inst.Index) !void {
17014 else => null,17105 else => null,
17015 },17106 },
17016 },17107 },
17017 }) orelse return self.fail("TODO implement airSelect for {}", .{ty.fmt(mod)});17108 }) orelse return self.fail("TODO implement airSelect for {}", .{ty.fmt(pt)});
17018 if (has_avx) {17109 if (has_avx) {
17019 const rhs_alias = if (rhs_mcv.isRegister())17110 const rhs_alias = if (rhs_mcv.isRegister())
17020 registerAlias(rhs_mcv.getReg().?, abi_size)17111 registerAlias(rhs_mcv.getReg().?, abi_size)
...@@ -17061,7 +17152,7 @@ fn airSelect(self: *Self, inst: Air.Inst.Index) !void {...@@ -17061,7 +17152,7 @@ fn airSelect(self: *Self, inst: Air.Inst.Index) !void {
17061 16, 80, 128 => null,17152 16, 80, 128 => null,
17062 else => unreachable,17153 else => unreachable,
17063 },17154 },
17064 }) orelse return self.fail("TODO implement airSelect for {}", .{ty.fmt(mod)});17155 }) orelse return self.fail("TODO implement airSelect for {}", .{ty.fmt(pt)});
17065 try self.asmRegisterRegister(.{ mir_fixes, .@"and" }, dst_alias, mask_alias);17156 try self.asmRegisterRegister(.{ mir_fixes, .@"and" }, dst_alias, mask_alias);
17066 if (rhs_mcv.isMemory()) try self.asmRegisterMemory(17157 if (rhs_mcv.isMemory()) try self.asmRegisterMemory(
17067 .{ mir_fixes, .andn },17158 .{ mir_fixes, .andn },
...@@ -17083,18 +17174,19 @@ fn airSelect(self: *Self, inst: Air.Inst.Index) !void {...@@ -17083,18 +17174,19 @@ fn airSelect(self: *Self, inst: Air.Inst.Index) !void {
17083}17174}
1708417175
17085fn airShuffle(self: *Self, inst: Air.Inst.Index) !void {17176fn airShuffle(self: *Self, inst: Air.Inst.Index) !void {
17086 const mod = self.bin_file.comp.module.?;17177 const pt = self.pt;
17178 const mod = pt.zcu;
17087 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;17179 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
17088 const extra = self.air.extraData(Air.Shuffle, ty_pl.payload).data;17180 const extra = self.air.extraData(Air.Shuffle, ty_pl.payload).data;
1708917181
17090 const dst_ty = self.typeOfIndex(inst);17182 const dst_ty = self.typeOfIndex(inst);
17091 const elem_ty = dst_ty.childType(mod);17183 const elem_ty = dst_ty.childType(mod);
17092 const elem_abi_size: u16 = @intCast(elem_ty.abiSize(mod));17184 const elem_abi_size: u16 = @intCast(elem_ty.abiSize(pt));
17093 const dst_abi_size: u32 = @intCast(dst_ty.abiSize(mod));17185 const dst_abi_size: u32 = @intCast(dst_ty.abiSize(pt));
17094 const lhs_ty = self.typeOf(extra.a);17186 const lhs_ty = self.typeOf(extra.a);
17095 const lhs_abi_size: u32 = @intCast(lhs_ty.abiSize(mod));17187 const lhs_abi_size: u32 = @intCast(lhs_ty.abiSize(pt));
17096 const rhs_ty = self.typeOf(extra.b);17188 const rhs_ty = self.typeOf(extra.b);
17097 const rhs_abi_size: u32 = @intCast(rhs_ty.abiSize(mod));17189 const rhs_abi_size: u32 = @intCast(rhs_ty.abiSize(pt));
17098 const max_abi_size = @max(dst_abi_size, lhs_abi_size, rhs_abi_size);17190 const max_abi_size = @max(dst_abi_size, lhs_abi_size, rhs_abi_size);
1709917191
17100 const ExpectedContents = [32]?i32;17192 const ExpectedContents = [32]?i32;
...@@ -17106,11 +17198,11 @@ fn airShuffle(self: *Self, inst: Air.Inst.Index) !void {...@@ -17106,11 +17198,11 @@ fn airShuffle(self: *Self, inst: Air.Inst.Index) !void {
17106 defer allocator.free(mask_elems);17198 defer allocator.free(mask_elems);
17107 for (mask_elems, 0..) |*mask_elem, elem_index| {17199 for (mask_elems, 0..) |*mask_elem, elem_index| {
17108 const mask_elem_val =17200 const mask_elem_val =
17109 Value.fromInterned(extra.mask).elemValue(mod, elem_index) catch unreachable;17201 Value.fromInterned(extra.mask).elemValue(pt, elem_index) catch unreachable;
17110 mask_elem.* = if (mask_elem_val.isUndef(mod))17202 mask_elem.* = if (mask_elem_val.isUndef(mod))
17111 null17203 null
17112 else17204 else
17113 @intCast(mask_elem_val.toSignedInt(mod));17205 @intCast(mask_elem_val.toSignedInt(pt));
17114 }17206 }
1711517207
17116 const has_avx = self.hasFeature(.avx);17208 const has_avx = self.hasFeature(.avx);
...@@ -17626,8 +17718,8 @@ fn airShuffle(self: *Self, inst: Air.Inst.Index) !void {...@@ -17626,8 +17718,8 @@ fn airShuffle(self: *Self, inst: Air.Inst.Index) !void {
17626 else17718 else
17627 self.hasFeature(.avx2)) 32 else 16)) break :blendv;17719 self.hasFeature(.avx2)) 32 else 16)) break :blendv;
1762817720
17629 const select_mask_elem_ty = try mod.intType(.unsigned, elem_abi_size * 8);17721 const select_mask_elem_ty = try pt.intType(.unsigned, elem_abi_size * 8);
17630 const select_mask_ty = try mod.vectorType(.{17722 const select_mask_ty = try pt.vectorType(.{
17631 .len = @intCast(mask_elems.len),17723 .len = @intCast(mask_elems.len),
17632 .child = select_mask_elem_ty.toIntern(),17724 .child = select_mask_elem_ty.toIntern(),
17633 });17725 });
...@@ -17643,11 +17735,11 @@ fn airShuffle(self: *Self, inst: Air.Inst.Index) !void {...@@ -17643,11 +17735,11 @@ fn airShuffle(self: *Self, inst: Air.Inst.Index) !void {
17643 if (mask_elem_index != elem_index) break :blendv;17735 if (mask_elem_index != elem_index) break :blendv;
1764417736
17645 select_mask_elem.* = (if (mask_elem < 0)17737 select_mask_elem.* = (if (mask_elem < 0)
17646 try select_mask_elem_ty.maxIntScalar(mod, select_mask_elem_ty)17738 try select_mask_elem_ty.maxIntScalar(pt, select_mask_elem_ty)
17647 else17739 else
17648 try select_mask_elem_ty.minIntScalar(mod, select_mask_elem_ty)).toIntern();17740 try select_mask_elem_ty.minIntScalar(pt, select_mask_elem_ty)).toIntern();
17649 }17741 }
17650 const select_mask_mcv = try self.genTypedValue(Value.fromInterned(try mod.intern(.{ .aggregate = .{17742 const select_mask_mcv = try self.genTypedValue(Value.fromInterned(try pt.intern(.{ .aggregate = .{
17651 .ty = select_mask_ty.toIntern(),17743 .ty = select_mask_ty.toIntern(),
17652 .storage = .{ .elems = select_mask_elems[0..mask_elems.len] },17744 .storage = .{ .elems = select_mask_elems[0..mask_elems.len] },
17653 } })));17745 } })));
...@@ -17783,7 +17875,7 @@ fn airShuffle(self: *Self, inst: Air.Inst.Index) !void {...@@ -17783,7 +17875,7 @@ fn airShuffle(self: *Self, inst: Air.Inst.Index) !void {
17783 var lhs_mask_elems: [16]InternPool.Index = undefined;17875 var lhs_mask_elems: [16]InternPool.Index = undefined;
17784 for (lhs_mask_elems[0..max_abi_size], 0..) |*lhs_mask_elem, byte_index| {17876 for (lhs_mask_elems[0..max_abi_size], 0..) |*lhs_mask_elem, byte_index| {
17785 const elem_index = byte_index / elem_abi_size;17877 const elem_index = byte_index / elem_abi_size;
17786 lhs_mask_elem.* = try mod.intern(.{ .int = .{17878 lhs_mask_elem.* = try pt.intern(.{ .int = .{
17787 .ty = .u8_type,17879 .ty = .u8_type,
17788 .storage = .{ .u64 = if (elem_index >= mask_elems.len) 0b1_00_00000 else elem: {17880 .storage = .{ .u64 = if (elem_index >= mask_elems.len) 0b1_00_00000 else elem: {
17789 const mask_elem = mask_elems[elem_index] orelse break :elem 0b1_00_00000;17881 const mask_elem = mask_elems[elem_index] orelse break :elem 0b1_00_00000;
...@@ -17794,8 +17886,8 @@ fn airShuffle(self: *Self, inst: Air.Inst.Index) !void {...@@ -17794,8 +17886,8 @@ fn airShuffle(self: *Self, inst: Air.Inst.Index) !void {
17794 } },17886 } },
17795 } });17887 } });
17796 }17888 }
17797 const lhs_mask_ty = try mod.vectorType(.{ .len = max_abi_size, .child = .u8_type });17889 const lhs_mask_ty = try pt.vectorType(.{ .len = max_abi_size, .child = .u8_type });
17798 const lhs_mask_mcv = try self.genTypedValue(Value.fromInterned(try mod.intern(.{ .aggregate = .{17890 const lhs_mask_mcv = try self.genTypedValue(Value.fromInterned(try pt.intern(.{ .aggregate = .{
17799 .ty = lhs_mask_ty.toIntern(),17891 .ty = lhs_mask_ty.toIntern(),
17800 .storage = .{ .elems = lhs_mask_elems[0..max_abi_size] },17892 .storage = .{ .elems = lhs_mask_elems[0..max_abi_size] },
17801 } })));17893 } })));
...@@ -17817,7 +17909,7 @@ fn airShuffle(self: *Self, inst: Air.Inst.Index) !void {...@@ -17817,7 +17909,7 @@ fn airShuffle(self: *Self, inst: Air.Inst.Index) !void {
17817 var rhs_mask_elems: [16]InternPool.Index = undefined;17909 var rhs_mask_elems: [16]InternPool.Index = undefined;
17818 for (rhs_mask_elems[0..max_abi_size], 0..) |*rhs_mask_elem, byte_index| {17910 for (rhs_mask_elems[0..max_abi_size], 0..) |*rhs_mask_elem, byte_index| {
17819 const elem_index = byte_index / elem_abi_size;17911 const elem_index = byte_index / elem_abi_size;
17820 rhs_mask_elem.* = try mod.intern(.{ .int = .{17912 rhs_mask_elem.* = try pt.intern(.{ .int = .{
17821 .ty = .u8_type,17913 .ty = .u8_type,
17822 .storage = .{ .u64 = if (elem_index >= mask_elems.len) 0b1_00_00000 else elem: {17914 .storage = .{ .u64 = if (elem_index >= mask_elems.len) 0b1_00_00000 else elem: {
17823 const mask_elem = mask_elems[elem_index] orelse break :elem 0b1_00_00000;17915 const mask_elem = mask_elems[elem_index] orelse break :elem 0b1_00_00000;
...@@ -17828,8 +17920,8 @@ fn airShuffle(self: *Self, inst: Air.Inst.Index) !void {...@@ -17828,8 +17920,8 @@ fn airShuffle(self: *Self, inst: Air.Inst.Index) !void {
17828 } },17920 } },
17829 } });17921 } });
17830 }17922 }
17831 const rhs_mask_ty = try mod.vectorType(.{ .len = max_abi_size, .child = .u8_type });17923 const rhs_mask_ty = try pt.vectorType(.{ .len = max_abi_size, .child = .u8_type });
17832 const rhs_mask_mcv = try self.genTypedValue(Value.fromInterned(try mod.intern(.{ .aggregate = .{17924 const rhs_mask_mcv = try self.genTypedValue(Value.fromInterned(try pt.intern(.{ .aggregate = .{
17833 .ty = rhs_mask_ty.toIntern(),17925 .ty = rhs_mask_ty.toIntern(),
17834 .storage = .{ .elems = rhs_mask_elems[0..max_abi_size] },17926 .storage = .{ .elems = rhs_mask_elems[0..max_abi_size] },
17835 } })));17927 } })));
...@@ -17881,14 +17973,15 @@ fn airShuffle(self: *Self, inst: Air.Inst.Index) !void {...@@ -17881,14 +17973,15 @@ fn airShuffle(self: *Self, inst: Air.Inst.Index) !void {
1788117973
17882 break :result null;17974 break :result null;
17883 }) orelse return self.fail("TODO implement airShuffle from {} and {} to {} with {}", .{17975 }) orelse return self.fail("TODO implement airShuffle from {} and {} to {} with {}", .{
17884 lhs_ty.fmt(mod), rhs_ty.fmt(mod), dst_ty.fmt(mod),17976 lhs_ty.fmt(pt), rhs_ty.fmt(pt), dst_ty.fmt(pt),
17885 Value.fromInterned(extra.mask).fmtValue(mod, null),17977 Value.fromInterned(extra.mask).fmtValue(pt, null),
17886 });17978 });
17887 return self.finishAir(inst, result, .{ extra.a, extra.b, .none });17979 return self.finishAir(inst, result, .{ extra.a, extra.b, .none });
17888}17980}
1788917981
17890fn airReduce(self: *Self, inst: Air.Inst.Index) !void {17982fn airReduce(self: *Self, inst: Air.Inst.Index) !void {
17891 const mod = self.bin_file.comp.module.?;17983 const pt = self.pt;
17984 const mod = pt.zcu;
17892 const reduce = self.air.instructions.items(.data)[@intFromEnum(inst)].reduce;17985 const reduce = self.air.instructions.items(.data)[@intFromEnum(inst)].reduce;
1789317986
17894 const result: MCValue = result: {17987 const result: MCValue = result: {
...@@ -17898,9 +17991,9 @@ fn airReduce(self: *Self, inst: Air.Inst.Index) !void {...@@ -17898,9 +17991,9 @@ fn airReduce(self: *Self, inst: Air.Inst.Index) !void {
1789817991
17899 const operand_mcv = try self.resolveInst(reduce.operand);17992 const operand_mcv = try self.resolveInst(reduce.operand);
17900 const mask_len = (math.cast(u6, operand_ty.vectorLen(mod)) orelse17993 const mask_len = (math.cast(u6, operand_ty.vectorLen(mod)) orelse
17901 return self.fail("TODO implement airReduce for {}", .{operand_ty.fmt(mod)}));17994 return self.fail("TODO implement airReduce for {}", .{operand_ty.fmt(pt)}));
17902 const mask = (@as(u64, 1) << mask_len) - 1;17995 const mask = (@as(u64, 1) << mask_len) - 1;
17903 const abi_size: u32 = @intCast(operand_ty.abiSize(mod));17996 const abi_size: u32 = @intCast(operand_ty.abiSize(pt));
17904 switch (reduce.operation) {17997 switch (reduce.operation) {
17905 .Or => {17998 .Or => {
17906 if (operand_mcv.isMemory()) try self.asmMemoryImmediate(17999 if (operand_mcv.isMemory()) try self.asmMemoryImmediate(
...@@ -17936,16 +18029,17 @@ fn airReduce(self: *Self, inst: Air.Inst.Index) !void {...@@ -17936,16 +18029,17 @@ fn airReduce(self: *Self, inst: Air.Inst.Index) !void {
17936 try self.asmRegisterRegister(.{ ._, .@"test" }, tmp_reg, tmp_reg);18029 try self.asmRegisterRegister(.{ ._, .@"test" }, tmp_reg, tmp_reg);
17937 break :result .{ .eflags = .z };18030 break :result .{ .eflags = .z };
17938 },18031 },
17939 else => return self.fail("TODO implement airReduce for {}", .{operand_ty.fmt(mod)}),18032 else => return self.fail("TODO implement airReduce for {}", .{operand_ty.fmt(pt)}),
17940 }18033 }
17941 }18034 }
17942 return self.fail("TODO implement airReduce for {}", .{operand_ty.fmt(mod)});18035 return self.fail("TODO implement airReduce for {}", .{operand_ty.fmt(pt)});
17943 };18036 };
17944 return self.finishAir(inst, result, .{ reduce.operand, .none, .none });18037 return self.finishAir(inst, result, .{ reduce.operand, .none, .none });
17945}18038}
1794618039
17947fn airAggregateInit(self: *Self, inst: Air.Inst.Index) !void {18040fn airAggregateInit(self: *Self, inst: Air.Inst.Index) !void {
17948 const mod = self.bin_file.comp.module.?;18041 const pt = self.pt;
18042 const mod = pt.zcu;
17949 const result_ty = self.typeOfIndex(inst);18043 const result_ty = self.typeOfIndex(inst);
17950 const len: usize = @intCast(result_ty.arrayLen(mod));18044 const len: usize = @intCast(result_ty.arrayLen(mod));
17951 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;18045 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
...@@ -17953,30 +18047,30 @@ fn airAggregateInit(self: *Self, inst: Air.Inst.Index) !void {...@@ -17953,30 +18047,30 @@ fn airAggregateInit(self: *Self, inst: Air.Inst.Index) !void {
17953 const result: MCValue = result: {18047 const result: MCValue = result: {
17954 switch (result_ty.zigTypeTag(mod)) {18048 switch (result_ty.zigTypeTag(mod)) {
17955 .Struct => {18049 .Struct => {
17956 const frame_index = try self.allocFrameIndex(FrameAlloc.initSpill(result_ty, mod));18050 const frame_index = try self.allocFrameIndex(FrameAlloc.initSpill(result_ty, pt));
17957 if (result_ty.containerLayout(mod) == .@"packed") {18051 if (result_ty.containerLayout(mod) == .@"packed") {
17958 const struct_obj = mod.typeToStruct(result_ty).?;18052 const struct_obj = mod.typeToStruct(result_ty).?;
17959 try self.genInlineMemset(18053 try self.genInlineMemset(
17960 .{ .lea_frame = .{ .index = frame_index } },18054 .{ .lea_frame = .{ .index = frame_index } },
17961 .{ .immediate = 0 },18055 .{ .immediate = 0 },
17962 .{ .immediate = result_ty.abiSize(mod) },18056 .{ .immediate = result_ty.abiSize(pt) },
17963 .{},18057 .{},
17964 );18058 );
17965 for (elements, 0..) |elem, elem_i_usize| {18059 for (elements, 0..) |elem, elem_i_usize| {
17966 const elem_i: u32 = @intCast(elem_i_usize);18060 const elem_i: u32 = @intCast(elem_i_usize);
17967 if ((try result_ty.structFieldValueComptime(mod, elem_i)) != null) continue;18061 if ((try result_ty.structFieldValueComptime(pt, elem_i)) != null) continue;
1796818062
17969 const elem_ty = result_ty.structFieldType(elem_i, mod);18063 const elem_ty = result_ty.structFieldType(elem_i, mod);
17970 const elem_bit_size: u32 = @intCast(elem_ty.bitSize(mod));18064 const elem_bit_size: u32 = @intCast(elem_ty.bitSize(pt));
17971 if (elem_bit_size > 64) {18065 if (elem_bit_size > 64) {
17972 return self.fail(18066 return self.fail(
17973 "TODO airAggregateInit implement packed structs with large fields",18067 "TODO airAggregateInit implement packed structs with large fields",
17974 .{},18068 .{},
17975 );18069 );
17976 }18070 }
17977 const elem_abi_size: u32 = @intCast(elem_ty.abiSize(mod));18071 const elem_abi_size: u32 = @intCast(elem_ty.abiSize(pt));
17978 const elem_abi_bits = elem_abi_size * 8;18072 const elem_abi_bits = elem_abi_size * 8;
17979 const elem_off = mod.structPackedFieldBitOffset(struct_obj, elem_i);18073 const elem_off = pt.structPackedFieldBitOffset(struct_obj, elem_i);
17980 const elem_byte_off: i32 = @intCast(elem_off / elem_abi_bits * elem_abi_size);18074 const elem_byte_off: i32 = @intCast(elem_off / elem_abi_bits * elem_abi_size);
17981 const elem_bit_off = elem_off % elem_abi_bits;18075 const elem_bit_off = elem_off % elem_abi_bits;
17982 const elem_mcv = try self.resolveInst(elem);18076 const elem_mcv = try self.resolveInst(elem);
...@@ -18046,10 +18140,10 @@ fn airAggregateInit(self: *Self, inst: Air.Inst.Index) !void {...@@ -18046,10 +18140,10 @@ fn airAggregateInit(self: *Self, inst: Air.Inst.Index) !void {
18046 }18140 }
18047 }18141 }
18048 } else for (elements, 0..) |elem, elem_i| {18142 } else for (elements, 0..) |elem, elem_i| {
18049 if ((try result_ty.structFieldValueComptime(mod, elem_i)) != null) continue;18143 if ((try result_ty.structFieldValueComptime(pt, elem_i)) != null) continue;
1805018144
18051 const elem_ty = result_ty.structFieldType(elem_i, mod);18145 const elem_ty = result_ty.structFieldType(elem_i, mod);
18052 const elem_off: i32 = @intCast(result_ty.structFieldOffset(elem_i, mod));18146 const elem_off: i32 = @intCast(result_ty.structFieldOffset(elem_i, pt));
18053 const elem_mcv = try self.resolveInst(elem);18147 const elem_mcv = try self.resolveInst(elem);
18054 const mat_elem_mcv = switch (elem_mcv) {18148 const mat_elem_mcv = switch (elem_mcv) {
18055 .load_tlv => |sym_index| MCValue{ .lea_tlv = sym_index },18149 .load_tlv => |sym_index| MCValue{ .lea_tlv = sym_index },
...@@ -18062,7 +18156,7 @@ fn airAggregateInit(self: *Self, inst: Air.Inst.Index) !void {...@@ -18062,7 +18156,7 @@ fn airAggregateInit(self: *Self, inst: Air.Inst.Index) !void {
18062 .Array, .Vector => {18156 .Array, .Vector => {
18063 const elem_ty = result_ty.childType(mod);18157 const elem_ty = result_ty.childType(mod);
18064 if (result_ty.isVector(mod) and elem_ty.toIntern() == .bool_type) {18158 if (result_ty.isVector(mod) and elem_ty.toIntern() == .bool_type) {
18065 const result_size: u32 = @intCast(result_ty.abiSize(mod));18159 const result_size: u32 = @intCast(result_ty.abiSize(pt));
18066 const dst_reg = try self.register_manager.allocReg(inst, abi.RegisterClass.gp);18160 const dst_reg = try self.register_manager.allocReg(inst, abi.RegisterClass.gp);
18067 try self.asmRegisterRegister(18161 try self.asmRegisterRegister(
18068 .{ ._, .xor },18162 .{ ._, .xor },
...@@ -18093,8 +18187,8 @@ fn airAggregateInit(self: *Self, inst: Air.Inst.Index) !void {...@@ -18093,8 +18187,8 @@ fn airAggregateInit(self: *Self, inst: Air.Inst.Index) !void {
18093 }18187 }
18094 break :result .{ .register = dst_reg };18188 break :result .{ .register = dst_reg };
18095 } else {18189 } else {
18096 const frame_index = try self.allocFrameIndex(FrameAlloc.initSpill(result_ty, mod));18190 const frame_index = try self.allocFrameIndex(FrameAlloc.initSpill(result_ty, pt));
18097 const elem_size: u32 = @intCast(elem_ty.abiSize(mod));18191 const elem_size: u32 = @intCast(elem_ty.abiSize(pt));
1809818192
18099 for (elements, 0..) |elem, elem_i| {18193 for (elements, 0..) |elem, elem_i| {
18100 const elem_mcv = try self.resolveInst(elem);18194 const elem_mcv = try self.resolveInst(elem);
...@@ -18136,18 +18230,19 @@ fn airAggregateInit(self: *Self, inst: Air.Inst.Index) !void {...@@ -18136,18 +18230,19 @@ fn airAggregateInit(self: *Self, inst: Air.Inst.Index) !void {
18136}18230}
1813718231
18138fn airUnionInit(self: *Self, inst: Air.Inst.Index) !void {18232fn airUnionInit(self: *Self, inst: Air.Inst.Index) !void {
18139 const mod = self.bin_file.comp.module.?;18233 const pt = self.pt;
18234 const mod = pt.zcu;
18140 const ip = &mod.intern_pool;18235 const ip = &mod.intern_pool;
18141 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;18236 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
18142 const extra = self.air.extraData(Air.UnionInit, ty_pl.payload).data;18237 const extra = self.air.extraData(Air.UnionInit, ty_pl.payload).data;
18143 const result: MCValue = result: {18238 const result: MCValue = result: {
18144 const union_ty = self.typeOfIndex(inst);18239 const union_ty = self.typeOfIndex(inst);
18145 const layout = union_ty.unionGetLayout(mod);18240 const layout = union_ty.unionGetLayout(pt);
1814618241
18147 const src_ty = self.typeOf(extra.init);18242 const src_ty = self.typeOf(extra.init);
18148 const src_mcv = try self.resolveInst(extra.init);18243 const src_mcv = try self.resolveInst(extra.init);
18149 if (layout.tag_size == 0) {18244 if (layout.tag_size == 0) {
18150 if (layout.abi_size <= src_ty.abiSize(mod) and18245 if (layout.abi_size <= src_ty.abiSize(pt) and
18151 self.reuseOperand(inst, extra.init, 0, src_mcv)) break :result src_mcv;18246 self.reuseOperand(inst, extra.init, 0, src_mcv)) break :result src_mcv;
1815218247
18153 const dst_mcv = try self.allocRegOrMem(inst, true);18248 const dst_mcv = try self.allocRegOrMem(inst, true);
...@@ -18161,9 +18256,9 @@ fn airUnionInit(self: *Self, inst: Air.Inst.Index) !void {...@@ -18161,9 +18256,9 @@ fn airUnionInit(self: *Self, inst: Air.Inst.Index) !void {
18161 const field_name = union_obj.loadTagType(ip).names.get(ip)[extra.field_index];18256 const field_name = union_obj.loadTagType(ip).names.get(ip)[extra.field_index];
18162 const tag_ty = Type.fromInterned(union_obj.enum_tag_ty);18257 const tag_ty = Type.fromInterned(union_obj.enum_tag_ty);
18163 const field_index = tag_ty.enumFieldIndex(field_name, mod).?;18258 const field_index = tag_ty.enumFieldIndex(field_name, mod).?;
18164 const tag_val = try mod.enumValueFieldIndex(tag_ty, field_index);18259 const tag_val = try pt.enumValueFieldIndex(tag_ty, field_index);
18165 const tag_int_val = try tag_val.intFromEnum(tag_ty, mod);18260 const tag_int_val = try tag_val.intFromEnum(tag_ty, pt);
18166 const tag_int = tag_int_val.toUnsignedInt(mod);18261 const tag_int = tag_int_val.toUnsignedInt(pt);
18167 const tag_off: i32 = if (layout.tag_align.compare(.lt, layout.payload_align))18262 const tag_off: i32 = if (layout.tag_align.compare(.lt, layout.payload_align))
18168 @intCast(layout.payload_size)18263 @intCast(layout.payload_size)
18169 else18264 else
...@@ -18192,7 +18287,8 @@ fn airPrefetch(self: *Self, inst: Air.Inst.Index) !void {...@@ -18192,7 +18287,8 @@ fn airPrefetch(self: *Self, inst: Air.Inst.Index) !void {
18192}18287}
1819318288
18194fn airMulAdd(self: *Self, inst: Air.Inst.Index) !void {18289fn airMulAdd(self: *Self, inst: Air.Inst.Index) !void {
18195 const mod = self.bin_file.comp.module.?;18290 const pt = self.pt;
18291 const mod = pt.zcu;
18196 const pl_op = self.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;18292 const pl_op = self.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;
18197 const extra = self.air.extraData(Air.Bin, pl_op.payload).data;18293 const extra = self.air.extraData(Air.Bin, pl_op.payload).data;
18198 const ty = self.typeOfIndex(inst);18294 const ty = self.typeOfIndex(inst);
...@@ -18205,7 +18301,7 @@ fn airMulAdd(self: *Self, inst: Air.Inst.Index) !void {...@@ -18205,7 +18301,7 @@ fn airMulAdd(self: *Self, inst: Air.Inst.Index) !void {
18205 else => unreachable,18301 else => unreachable,
18206 }) {18302 }) {
18207 if (ty.zigTypeTag(mod) != .Float) return self.fail("TODO implement airMulAdd for {}", .{18303 if (ty.zigTypeTag(mod) != .Float) return self.fail("TODO implement airMulAdd for {}", .{
18208 ty.fmt(mod),18304 ty.fmt(pt),
18209 });18305 });
1821018306
18211 var callee_buf: ["__fma?".len]u8 = undefined;18307 var callee_buf: ["__fma?".len]u8 = undefined;
...@@ -18334,12 +18430,12 @@ fn airMulAdd(self: *Self, inst: Air.Inst.Index) !void {...@@ -18334,12 +18430,12 @@ fn airMulAdd(self: *Self, inst: Air.Inst.Index) !void {
18334 else => unreachable,18430 else => unreachable,
18335 }18431 }
18336 else18432 else
18337 unreachable) orelse return self.fail("TODO implement airMulAdd for {}", .{ty.fmt(mod)});18433 unreachable) orelse return self.fail("TODO implement airMulAdd for {}", .{ty.fmt(pt)});
1833818434
18339 var mops: [3]MCValue = undefined;18435 var mops: [3]MCValue = undefined;
18340 for (order, mcvs) |mop_index, mcv| mops[mop_index - 1] = mcv;18436 for (order, mcvs) |mop_index, mcv| mops[mop_index - 1] = mcv;
1834118437
18342 const abi_size: u32 = @intCast(ty.abiSize(mod));18438 const abi_size: u32 = @intCast(ty.abiSize(pt));
18343 const mop1_reg = registerAlias(mops[0].getReg().?, abi_size);18439 const mop1_reg = registerAlias(mops[0].getReg().?, abi_size);
18344 const mop2_reg = registerAlias(mops[1].getReg().?, abi_size);18440 const mop2_reg = registerAlias(mops[1].getReg().?, abi_size);
18345 if (mops[2].isRegister()) try self.asmRegisterRegisterRegister(18441 if (mops[2].isRegister()) try self.asmRegisterRegisterRegister(
...@@ -18359,9 +18455,10 @@ fn airMulAdd(self: *Self, inst: Air.Inst.Index) !void {...@@ -18359,9 +18455,10 @@ fn airMulAdd(self: *Self, inst: Air.Inst.Index) !void {
18359}18455}
1836018456
18361fn airVaStart(self: *Self, inst: Air.Inst.Index) !void {18457fn airVaStart(self: *Self, inst: Air.Inst.Index) !void {
18362 const mod = self.bin_file.comp.module.?;18458 const pt = self.pt;
18459 const mod = pt.zcu;
18363 const va_list_ty = self.air.instructions.items(.data)[@intFromEnum(inst)].ty;18460 const va_list_ty = self.air.instructions.items(.data)[@intFromEnum(inst)].ty;
18364 const ptr_anyopaque_ty = try mod.singleMutPtrType(Type.anyopaque);18461 const ptr_anyopaque_ty = try pt.singleMutPtrType(Type.anyopaque);
1836518462
18366 const result: MCValue = switch (abi.resolveCallingConvention(18463 const result: MCValue = switch (abi.resolveCallingConvention(
18367 self.fn_type.fnCallingConvention(mod),18464 self.fn_type.fnCallingConvention(mod),
...@@ -18369,7 +18466,7 @@ fn airVaStart(self: *Self, inst: Air.Inst.Index) !void {...@@ -18369,7 +18466,7 @@ fn airVaStart(self: *Self, inst: Air.Inst.Index) !void {
18369 )) {18466 )) {
18370 .SysV => result: {18467 .SysV => result: {
18371 const info = self.va_info.sysv;18468 const info = self.va_info.sysv;
18372 const dst_fi = try self.allocFrameIndex(FrameAlloc.initSpill(va_list_ty, mod));18469 const dst_fi = try self.allocFrameIndex(FrameAlloc.initSpill(va_list_ty, pt));
18373 var field_off: u31 = 0;18470 var field_off: u31 = 0;
18374 // gp_offset: c_uint,18471 // gp_offset: c_uint,
18375 try self.genSetMem(18472 try self.genSetMem(
...@@ -18379,7 +18476,7 @@ fn airVaStart(self: *Self, inst: Air.Inst.Index) !void {...@@ -18379,7 +18476,7 @@ fn airVaStart(self: *Self, inst: Air.Inst.Index) !void {
18379 .{ .immediate = info.gp_count * 8 },18476 .{ .immediate = info.gp_count * 8 },
18380 .{},18477 .{},
18381 );18478 );
18382 field_off += @intCast(Type.c_uint.abiSize(mod));18479 field_off += @intCast(Type.c_uint.abiSize(pt));
18383 // fp_offset: c_uint,18480 // fp_offset: c_uint,
18384 try self.genSetMem(18481 try self.genSetMem(
18385 .{ .frame = dst_fi },18482 .{ .frame = dst_fi },
...@@ -18388,7 +18485,7 @@ fn airVaStart(self: *Self, inst: Air.Inst.Index) !void {...@@ -18388,7 +18485,7 @@ fn airVaStart(self: *Self, inst: Air.Inst.Index) !void {
18388 .{ .immediate = abi.SysV.c_abi_int_param_regs.len * 8 + info.fp_count * 16 },18485 .{ .immediate = abi.SysV.c_abi_int_param_regs.len * 8 + info.fp_count * 16 },
18389 .{},18486 .{},
18390 );18487 );
18391 field_off += @intCast(Type.c_uint.abiSize(mod));18488 field_off += @intCast(Type.c_uint.abiSize(pt));
18392 // overflow_arg_area: *anyopaque,18489 // overflow_arg_area: *anyopaque,
18393 try self.genSetMem(18490 try self.genSetMem(
18394 .{ .frame = dst_fi },18491 .{ .frame = dst_fi },
...@@ -18397,7 +18494,7 @@ fn airVaStart(self: *Self, inst: Air.Inst.Index) !void {...@@ -18397,7 +18494,7 @@ fn airVaStart(self: *Self, inst: Air.Inst.Index) !void {
18397 .{ .lea_frame = info.overflow_arg_area },18494 .{ .lea_frame = info.overflow_arg_area },
18398 .{},18495 .{},
18399 );18496 );
18400 field_off += @intCast(ptr_anyopaque_ty.abiSize(mod));18497 field_off += @intCast(ptr_anyopaque_ty.abiSize(pt));
18401 // reg_save_area: *anyopaque,18498 // reg_save_area: *anyopaque,
18402 try self.genSetMem(18499 try self.genSetMem(
18403 .{ .frame = dst_fi },18500 .{ .frame = dst_fi },
...@@ -18406,7 +18503,7 @@ fn airVaStart(self: *Self, inst: Air.Inst.Index) !void {...@@ -18406,7 +18503,7 @@ fn airVaStart(self: *Self, inst: Air.Inst.Index) !void {
18406 .{ .lea_frame = info.reg_save_area },18503 .{ .lea_frame = info.reg_save_area },
18407 .{},18504 .{},
18408 );18505 );
18409 field_off += @intCast(ptr_anyopaque_ty.abiSize(mod));18506 field_off += @intCast(ptr_anyopaque_ty.abiSize(pt));
18410 break :result .{ .load_frame = .{ .index = dst_fi } };18507 break :result .{ .load_frame = .{ .index = dst_fi } };
18411 },18508 },
18412 .Win64 => return self.fail("TODO implement c_va_start for Win64", .{}),18509 .Win64 => return self.fail("TODO implement c_va_start for Win64", .{}),
...@@ -18416,11 +18513,12 @@ fn airVaStart(self: *Self, inst: Air.Inst.Index) !void {...@@ -18416,11 +18513,12 @@ fn airVaStart(self: *Self, inst: Air.Inst.Index) !void {
18416}18513}
1841718514
18418fn airVaArg(self: *Self, inst: Air.Inst.Index) !void {18515fn airVaArg(self: *Self, inst: Air.Inst.Index) !void {
18419 const mod = self.bin_file.comp.module.?;18516 const pt = self.pt;
18517 const mod = pt.zcu;
18420 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;18518 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
18421 const ty = self.typeOfIndex(inst);18519 const ty = self.typeOfIndex(inst);
18422 const promote_ty = self.promoteVarArg(ty);18520 const promote_ty = self.promoteVarArg(ty);
18423 const ptr_anyopaque_ty = try mod.singleMutPtrType(Type.anyopaque);18521 const ptr_anyopaque_ty = try pt.singleMutPtrType(Type.anyopaque);
18424 const unused = self.liveness.isUnused(inst);18522 const unused = self.liveness.isUnused(inst);
1842518523
18426 const result: MCValue = switch (abi.resolveCallingConvention(18524 const result: MCValue = switch (abi.resolveCallingConvention(
...@@ -18454,7 +18552,7 @@ fn airVaArg(self: *Self, inst: Air.Inst.Index) !void {...@@ -18454,7 +18552,7 @@ fn airVaArg(self: *Self, inst: Air.Inst.Index) !void {
18454 const overflow_arg_area: MCValue = .{ .indirect = .{ .reg = ptr_arg_list_reg, .off = 8 } };18552 const overflow_arg_area: MCValue = .{ .indirect = .{ .reg = ptr_arg_list_reg, .off = 8 } };
18455 const reg_save_area: MCValue = .{ .indirect = .{ .reg = ptr_arg_list_reg, .off = 16 } };18553 const reg_save_area: MCValue = .{ .indirect = .{ .reg = ptr_arg_list_reg, .off = 16 } };
1845618554
18457 const classes = mem.sliceTo(&abi.classifySystemV(promote_ty, mod, self.target.*, .arg), .none);18555 const classes = mem.sliceTo(&abi.classifySystemV(promote_ty, pt, self.target.*, .arg), .none);
18458 switch (classes[0]) {18556 switch (classes[0]) {
18459 .integer => {18557 .integer => {
18460 assert(classes.len == 1);18558 assert(classes.len == 1);
...@@ -18489,7 +18587,7 @@ fn airVaArg(self: *Self, inst: Air.Inst.Index) !void {...@@ -18489,7 +18587,7 @@ fn airVaArg(self: *Self, inst: Air.Inst.Index) !void {
18489 .base = .{ .reg = addr_reg },18587 .base = .{ .reg = addr_reg },
18490 .mod = .{ .rm = .{18588 .mod = .{ .rm = .{
18491 .size = .qword,18589 .size = .qword,
18492 .disp = @intCast(@max(promote_ty.abiSize(mod), 8)),18590 .disp = @intCast(@max(promote_ty.abiSize(pt), 8)),
18493 } },18591 } },
18494 });18592 });
18495 try self.genCopy(18593 try self.genCopy(
...@@ -18537,7 +18635,7 @@ fn airVaArg(self: *Self, inst: Air.Inst.Index) !void {...@@ -18537,7 +18635,7 @@ fn airVaArg(self: *Self, inst: Air.Inst.Index) !void {
18537 .base = .{ .reg = addr_reg },18635 .base = .{ .reg = addr_reg },
18538 .mod = .{ .rm = .{18636 .mod = .{ .rm = .{
18539 .size = .qword,18637 .size = .qword,
18540 .disp = @intCast(@max(promote_ty.abiSize(mod), 8)),18638 .disp = @intCast(@max(promote_ty.abiSize(pt), 8)),
18541 } },18639 } },
18542 });18640 });
18543 try self.genCopy(18641 try self.genCopy(
...@@ -18557,7 +18655,7 @@ fn airVaArg(self: *Self, inst: Air.Inst.Index) !void {...@@ -18557,7 +18655,7 @@ fn airVaArg(self: *Self, inst: Air.Inst.Index) !void {
18557 unreachable;18655 unreachable;
18558 },18656 },
18559 else => return self.fail("TODO implement c_va_arg for {} on SysV", .{18657 else => return self.fail("TODO implement c_va_arg for {} on SysV", .{
18560 promote_ty.fmt(mod),18658 promote_ty.fmt(pt),
18561 }),18659 }),
18562 }18660 }
1856318661
...@@ -18627,11 +18725,11 @@ fn airVaEnd(self: *Self, inst: Air.Inst.Index) !void {...@@ -18627,11 +18725,11 @@ fn airVaEnd(self: *Self, inst: Air.Inst.Index) !void {
18627}18725}
1862818726
18629fn resolveInst(self: *Self, ref: Air.Inst.Ref) InnerError!MCValue {18727fn resolveInst(self: *Self, ref: Air.Inst.Ref) InnerError!MCValue {
18630 const mod = self.bin_file.comp.module.?;18728 const pt = self.pt;
18631 const ty = self.typeOf(ref);18729 const ty = self.typeOf(ref);
1863218730
18633 // If the type has no codegen bits, no need to store it.18731 // If the type has no codegen bits, no need to store it.
18634 if (!ty.hasRuntimeBitsIgnoreComptime(mod)) return .none;18732 if (!ty.hasRuntimeBitsIgnoreComptime(pt)) return .none;
1863518733
18636 const mcv = if (ref.toIndex()) |inst| mcv: {18734 const mcv = if (ref.toIndex()) |inst| mcv: {
18637 break :mcv self.inst_tracking.getPtr(inst).?.short;18735 break :mcv self.inst_tracking.getPtr(inst).?.short;
...@@ -18705,8 +18803,8 @@ fn limitImmediateType(self: *Self, operand: Air.Inst.Ref, comptime T: type) !MCV...@@ -18705,8 +18803,8 @@ fn limitImmediateType(self: *Self, operand: Air.Inst.Ref, comptime T: type) !MCV
18705}18803}
1870618804
18707fn genTypedValue(self: *Self, val: Value) InnerError!MCValue {18805fn genTypedValue(self: *Self, val: Value) InnerError!MCValue {
18708 const mod = self.bin_file.comp.module.?;18806 const pt = self.pt;
18709 return switch (try codegen.genTypedValue(self.bin_file, self.src_loc, val, self.owner.getDecl(mod))) {18807 return switch (try codegen.genTypedValue(self.bin_file, pt, self.src_loc, val, self.owner.getDecl(pt.zcu))) {
18710 .mcv => |mcv| switch (mcv) {18808 .mcv => |mcv| switch (mcv) {
18711 .none => .none,18809 .none => .none,
18712 .undef => .undef,18810 .undef => .undef,
...@@ -18745,7 +18843,8 @@ fn resolveCallingConventionValues(...@@ -18745,7 +18843,8 @@ fn resolveCallingConventionValues(
18745 var_args: []const Type,18843 var_args: []const Type,
18746 stack_frame_base: FrameIndex,18844 stack_frame_base: FrameIndex,
18747) !CallMCValues {18845) !CallMCValues {
18748 const mod = self.bin_file.comp.module.?;18846 const pt = self.pt;
18847 const mod = pt.zcu;
18749 const ip = &mod.intern_pool;18848 const ip = &mod.intern_pool;
18750 const cc = fn_info.cc;18849 const cc = fn_info.cc;
18751 const param_types = try self.gpa.alloc(Type, fn_info.param_types.len + var_args.len);18850 const param_types = try self.gpa.alloc(Type, fn_info.param_types.len + var_args.len);
...@@ -18788,7 +18887,7 @@ fn resolveCallingConventionValues(...@@ -18788,7 +18887,7 @@ fn resolveCallingConventionValues(
18788 .SysV => {},18887 .SysV => {},
18789 .Win64 => {18888 .Win64 => {
18790 // Align the stack to 16bytes before allocating shadow stack space (if any).18889 // Align the stack to 16bytes before allocating shadow stack space (if any).
18791 result.stack_byte_count += @intCast(4 * Type.usize.abiSize(mod));18890 result.stack_byte_count += @intCast(4 * Type.usize.abiSize(pt));
18792 },18891 },
18793 else => unreachable,18892 else => unreachable,
18794 }18893 }
...@@ -18796,7 +18895,7 @@ fn resolveCallingConventionValues(...@@ -18796,7 +18895,7 @@ fn resolveCallingConventionValues(
18796 // Return values18895 // Return values
18797 if (ret_ty.zigTypeTag(mod) == .NoReturn) {18896 if (ret_ty.zigTypeTag(mod) == .NoReturn) {
18798 result.return_value = InstTracking.init(.unreach);18897 result.return_value = InstTracking.init(.unreach);
18799 } else if (!ret_ty.hasRuntimeBitsIgnoreComptime(mod)) {18898 } else if (!ret_ty.hasRuntimeBitsIgnoreComptime(pt)) {
18800 // TODO: is this even possible for C calling convention?18899 // TODO: is this even possible for C calling convention?
18801 result.return_value = InstTracking.init(.none);18900 result.return_value = InstTracking.init(.none);
18802 } else {18901 } else {
...@@ -18804,15 +18903,15 @@ fn resolveCallingConventionValues(...@@ -18804,15 +18903,15 @@ fn resolveCallingConventionValues(
18804 var ret_tracking_i: usize = 0;18903 var ret_tracking_i: usize = 0;
1880518904
18806 const classes = switch (resolved_cc) {18905 const classes = switch (resolved_cc) {
18807 .SysV => mem.sliceTo(&abi.classifySystemV(ret_ty, mod, self.target.*, .ret), .none),18906 .SysV => mem.sliceTo(&abi.classifySystemV(ret_ty, pt, self.target.*, .ret), .none),
18808 .Win64 => &.{abi.classifyWindows(ret_ty, mod)},18907 .Win64 => &.{abi.classifyWindows(ret_ty, pt)},
18809 else => unreachable,18908 else => unreachable,
18810 };18909 };
18811 for (classes) |class| switch (class) {18910 for (classes) |class| switch (class) {
18812 .integer => {18911 .integer => {
18813 const ret_int_reg = registerAlias(18912 const ret_int_reg = registerAlias(
18814 abi.getCAbiIntReturnRegs(resolved_cc)[ret_int_reg_i],18913 abi.getCAbiIntReturnRegs(resolved_cc)[ret_int_reg_i],
18815 @intCast(@min(ret_ty.abiSize(mod), 8)),18914 @intCast(@min(ret_ty.abiSize(pt), 8)),
18816 );18915 );
18817 ret_int_reg_i += 1;18916 ret_int_reg_i += 1;
1881818917
...@@ -18822,7 +18921,7 @@ fn resolveCallingConventionValues(...@@ -18822,7 +18921,7 @@ fn resolveCallingConventionValues(
18822 .sse, .float, .float_combine, .win_i128 => {18921 .sse, .float, .float_combine, .win_i128 => {
18823 const ret_sse_reg = registerAlias(18922 const ret_sse_reg = registerAlias(
18824 abi.getCAbiSseReturnRegs(resolved_cc)[ret_sse_reg_i],18923 abi.getCAbiSseReturnRegs(resolved_cc)[ret_sse_reg_i],
18825 @intCast(ret_ty.abiSize(mod)),18924 @intCast(ret_ty.abiSize(pt)),
18826 );18925 );
18827 ret_sse_reg_i += 1;18926 ret_sse_reg_i += 1;
1882818927
...@@ -18865,7 +18964,7 @@ fn resolveCallingConventionValues(...@@ -18865,7 +18964,7 @@ fn resolveCallingConventionValues(
1886518964
18866 // Input params18965 // Input params
18867 for (param_types, result.args) |ty, *arg| {18966 for (param_types, result.args) |ty, *arg| {
18868 assert(ty.hasRuntimeBitsIgnoreComptime(mod));18967 assert(ty.hasRuntimeBitsIgnoreComptime(pt));
18869 switch (resolved_cc) {18968 switch (resolved_cc) {
18870 .SysV => {},18969 .SysV => {},
18871 .Win64 => {18970 .Win64 => {
...@@ -18879,8 +18978,8 @@ fn resolveCallingConventionValues(...@@ -18879,8 +18978,8 @@ fn resolveCallingConventionValues(
18879 var arg_mcv_i: usize = 0;18978 var arg_mcv_i: usize = 0;
1888018979
18881 const classes = switch (resolved_cc) {18980 const classes = switch (resolved_cc) {
18882 .SysV => mem.sliceTo(&abi.classifySystemV(ty, mod, self.target.*, .arg), .none),18981 .SysV => mem.sliceTo(&abi.classifySystemV(ty, pt, self.target.*, .arg), .none),
18883 .Win64 => &.{abi.classifyWindows(ty, mod)},18982 .Win64 => &.{abi.classifyWindows(ty, pt)},
18884 else => unreachable,18983 else => unreachable,
18885 };18984 };
18886 for (classes) |class| switch (class) {18985 for (classes) |class| switch (class) {
...@@ -18890,7 +18989,7 @@ fn resolveCallingConventionValues(...@@ -18890,7 +18989,7 @@ fn resolveCallingConventionValues(
1889018989
18891 const param_int_reg = registerAlias(18990 const param_int_reg = registerAlias(
18892 abi.getCAbiIntParamRegs(resolved_cc)[param_int_reg_i],18991 abi.getCAbiIntParamRegs(resolved_cc)[param_int_reg_i],
18893 @intCast(@min(ty.abiSize(mod), 8)),18992 @intCast(@min(ty.abiSize(pt), 8)),
18894 );18993 );
18895 param_int_reg_i += 1;18994 param_int_reg_i += 1;
1889618995
...@@ -18903,7 +19002,7 @@ fn resolveCallingConventionValues(...@@ -18903,7 +19002,7 @@ fn resolveCallingConventionValues(
1890319002
18904 const param_sse_reg = registerAlias(19003 const param_sse_reg = registerAlias(
18905 abi.getCAbiSseParamRegs(resolved_cc)[param_sse_reg_i],19004 abi.getCAbiSseParamRegs(resolved_cc)[param_sse_reg_i],
18906 @intCast(ty.abiSize(mod)),19005 @intCast(ty.abiSize(pt)),
18907 );19006 );
18908 param_sse_reg_i += 1;19007 param_sse_reg_i += 1;
1890919008
...@@ -18916,7 +19015,7 @@ fn resolveCallingConventionValues(...@@ -18916,7 +19015,7 @@ fn resolveCallingConventionValues(
18916 .x87, .x87up, .complex_x87, .memory => break,19015 .x87, .x87up, .complex_x87, .memory => break,
18917 else => unreachable,19016 else => unreachable,
18918 },19017 },
18919 .Win64 => if (ty.abiSize(mod) > 8) {19018 .Win64 => if (ty.abiSize(pt) > 8) {
18920 const param_int_reg =19019 const param_int_reg =
18921 abi.getCAbiIntParamRegs(resolved_cc)[param_int_reg_i].to64();19020 abi.getCAbiIntParamRegs(resolved_cc)[param_int_reg_i].to64();
18922 param_int_reg_i += 1;19021 param_int_reg_i += 1;
...@@ -18938,7 +19037,7 @@ fn resolveCallingConventionValues(...@@ -18938,7 +19037,7 @@ fn resolveCallingConventionValues(
18938 const frame_elems_len = ty.vectorLen(mod) - remaining_param_int_regs;19037 const frame_elems_len = ty.vectorLen(mod) - remaining_param_int_regs;
18939 const frame_elem_size = mem.alignForward(19038 const frame_elem_size = mem.alignForward(
18940 u64,19039 u64,
18941 ty.childType(mod).abiSize(mod),19040 ty.childType(mod).abiSize(pt),
18942 frame_elem_align,19041 frame_elem_align,
18943 );19042 );
18944 const frame_size: u31 = @intCast(frame_elems_len * frame_elem_size);19043 const frame_size: u31 = @intCast(frame_elems_len * frame_elem_size);
...@@ -18962,9 +19061,9 @@ fn resolveCallingConventionValues(...@@ -18962,9 +19061,9 @@ fn resolveCallingConventionValues(
18962 continue;19061 continue;
18963 }19062 }
1896419063
18965 const param_size: u31 = @intCast(ty.abiSize(mod));19064 const param_size: u31 = @intCast(ty.abiSize(pt));
18966 const param_align: u31 =19065 const param_align: u31 =
18967 @intCast(@max(ty.abiAlignment(mod).toByteUnits().?, 8));19066 @intCast(@max(ty.abiAlignment(pt).toByteUnits().?, 8));
18968 result.stack_byte_count =19067 result.stack_byte_count =
18969 mem.alignForward(u31, result.stack_byte_count, param_align);19068 mem.alignForward(u31, result.stack_byte_count, param_align);
18970 arg.* = .{ .load_frame = .{19069 arg.* = .{ .load_frame = .{
...@@ -18984,11 +19083,11 @@ fn resolveCallingConventionValues(...@@ -18984,11 +19083,11 @@ fn resolveCallingConventionValues(
18984 // Return values19083 // Return values
18985 if (ret_ty.zigTypeTag(mod) == .NoReturn) {19084 if (ret_ty.zigTypeTag(mod) == .NoReturn) {
18986 result.return_value = InstTracking.init(.unreach);19085 result.return_value = InstTracking.init(.unreach);
18987 } else if (!ret_ty.hasRuntimeBitsIgnoreComptime(mod)) {19086 } else if (!ret_ty.hasRuntimeBitsIgnoreComptime(pt)) {
18988 result.return_value = InstTracking.init(.none);19087 result.return_value = InstTracking.init(.none);
18989 } else {19088 } else {
18990 const ret_reg = abi.getCAbiIntReturnRegs(resolved_cc)[0];19089 const ret_reg = abi.getCAbiIntReturnRegs(resolved_cc)[0];
18991 const ret_ty_size: u31 = @intCast(ret_ty.abiSize(mod));19090 const ret_ty_size: u31 = @intCast(ret_ty.abiSize(pt));
18992 if (ret_ty_size <= 8 and !ret_ty.isRuntimeFloat()) {19091 if (ret_ty_size <= 8 and !ret_ty.isRuntimeFloat()) {
18993 const aliased_reg = registerAlias(ret_reg, ret_ty_size);19092 const aliased_reg = registerAlias(ret_reg, ret_ty_size);
18994 result.return_value = .{ .short = .{ .register = aliased_reg }, .long = .none };19093 result.return_value = .{ .short = .{ .register = aliased_reg }, .long = .none };
...@@ -19003,12 +19102,12 @@ fn resolveCallingConventionValues(...@@ -19003,12 +19102,12 @@ fn resolveCallingConventionValues(
1900319102
19004 // Input params19103 // Input params
19005 for (param_types, result.args) |ty, *arg| {19104 for (param_types, result.args) |ty, *arg| {
19006 if (!ty.hasRuntimeBitsIgnoreComptime(mod)) {19105 if (!ty.hasRuntimeBitsIgnoreComptime(pt)) {
19007 arg.* = .none;19106 arg.* = .none;
19008 continue;19107 continue;
19009 }19108 }
19010 const param_size: u31 = @intCast(ty.abiSize(mod));19109 const param_size: u31 = @intCast(ty.abiSize(pt));
19011 const param_align: u31 = @intCast(ty.abiAlignment(mod).toByteUnits().?);19110 const param_align: u31 = @intCast(ty.abiAlignment(pt).toByteUnits().?);
19012 result.stack_byte_count =19111 result.stack_byte_count =
19013 mem.alignForward(u31, result.stack_byte_count, param_align);19112 mem.alignForward(u31, result.stack_byte_count, param_align);
19014 arg.* = .{ .load_frame = .{19113 arg.* = .{ .load_frame = .{
...@@ -19093,47 +19192,49 @@ fn registerAlias(reg: Register, size_bytes: u32) Register {...@@ -19093,47 +19192,49 @@ fn registerAlias(reg: Register, size_bytes: u32) Register {
19093}19192}
1909419193
19095fn memSize(self: *Self, ty: Type) Memory.Size {19194fn memSize(self: *Self, ty: Type) Memory.Size {
19096 const mod = self.bin_file.comp.module.?;19195 const pt = self.pt;
19196 const mod = pt.zcu;
19097 return switch (ty.zigTypeTag(mod)) {19197 return switch (ty.zigTypeTag(mod)) {
19098 .Float => Memory.Size.fromBitSize(ty.floatBits(self.target.*)),19198 .Float => Memory.Size.fromBitSize(ty.floatBits(self.target.*)),
19099 else => Memory.Size.fromSize(@intCast(ty.abiSize(mod))),19199 else => Memory.Size.fromSize(@intCast(ty.abiSize(pt))),
19100 };19200 };
19101}19201}
1910219202
19103fn splitType(self: *Self, ty: Type) ![2]Type {19203fn splitType(self: *Self, ty: Type) ![2]Type {
19104 const mod = self.bin_file.comp.module.?;19204 const pt = self.pt;
19105 const classes = mem.sliceTo(&abi.classifySystemV(ty, mod, self.target.*, .other), .none);19205 const classes = mem.sliceTo(&abi.classifySystemV(ty, pt, self.target.*, .other), .none);
19106 var parts: [2]Type = undefined;19206 var parts: [2]Type = undefined;
19107 if (classes.len == 2) for (&parts, classes, 0..) |*part, class, part_i| {19207 if (classes.len == 2) for (&parts, classes, 0..) |*part, class, part_i| {
19108 part.* = switch (class) {19208 part.* = switch (class) {
19109 .integer => switch (part_i) {19209 .integer => switch (part_i) {
19110 0 => Type.u64,19210 0 => Type.u64,
19111 1 => part: {19211 1 => part: {
19112 const elem_size = ty.abiAlignment(mod).minStrict(.@"8").toByteUnits().?;19212 const elem_size = ty.abiAlignment(pt).minStrict(.@"8").toByteUnits().?;
19113 const elem_ty = try mod.intType(.unsigned, @intCast(elem_size * 8));19213 const elem_ty = try pt.intType(.unsigned, @intCast(elem_size * 8));
19114 break :part switch (@divExact(ty.abiSize(mod) - 8, elem_size)) {19214 break :part switch (@divExact(ty.abiSize(pt) - 8, elem_size)) {
19115 1 => elem_ty,19215 1 => elem_ty,
19116 else => |len| try mod.arrayType(.{ .len = len, .child = elem_ty.toIntern() }),19216 else => |len| try pt.arrayType(.{ .len = len, .child = elem_ty.toIntern() }),
19117 };19217 };
19118 },19218 },
19119 else => unreachable,19219 else => unreachable,
19120 },19220 },
19121 .float => Type.f32,19221 .float => Type.f32,
19122 .float_combine => try mod.arrayType(.{ .len = 2, .child = .f32_type }),19222 .float_combine => try pt.arrayType(.{ .len = 2, .child = .f32_type }),
19123 .sse => Type.f64,19223 .sse => Type.f64,
19124 else => break,19224 else => break,
19125 };19225 };
19126 } else if (parts[0].abiSize(mod) + parts[1].abiSize(mod) == ty.abiSize(mod)) return parts;19226 } else if (parts[0].abiSize(pt) + parts[1].abiSize(pt) == ty.abiSize(pt)) return parts;
19127 return self.fail("TODO implement splitType for {}", .{ty.fmt(mod)});19227 return self.fail("TODO implement splitType for {}", .{ty.fmt(pt)});
19128}19228}
1912919229
19130/// Truncates the value in the register in place.19230/// Truncates the value in the register in place.
19131/// Clobbers any remaining bits.19231/// Clobbers any remaining bits.
19132fn truncateRegister(self: *Self, ty: Type, reg: Register) !void {19232fn truncateRegister(self: *Self, ty: Type, reg: Register) !void {
19133 const mod = self.bin_file.comp.module.?;19233 const pt = self.pt;
19234 const mod = pt.zcu;
19134 const int_info = if (ty.isAbiInt(mod)) ty.intInfo(mod) else std.builtin.Type.Int{19235 const int_info = if (ty.isAbiInt(mod)) ty.intInfo(mod) else std.builtin.Type.Int{
19135 .signedness = .unsigned,19236 .signedness = .unsigned,
19136 .bits = @intCast(ty.bitSize(mod)),19237 .bits = @intCast(ty.bitSize(pt)),
19137 };19238 };
19138 const shift = math.cast(u6, 64 - int_info.bits % 64) orelse return;19239 const shift = math.cast(u6, 64 - int_info.bits % 64) orelse return;
19139 try self.spillEflagsIfOccupied();19240 try self.spillEflagsIfOccupied();
...@@ -19177,8 +19278,9 @@ fn truncateRegister(self: *Self, ty: Type, reg: Register) !void {...@@ -19177,8 +19278,9 @@ fn truncateRegister(self: *Self, ty: Type, reg: Register) !void {
19177}19278}
1917819279
19179fn regBitSize(self: *Self, ty: Type) u64 {19280fn regBitSize(self: *Self, ty: Type) u64 {
19180 const mod = self.bin_file.comp.module.?;19281 const pt = self.pt;
19181 const abi_size = ty.abiSize(mod);19282 const mod = pt.zcu;
19283 const abi_size = ty.abiSize(pt);
19182 return switch (ty.zigTypeTag(mod)) {19284 return switch (ty.zigTypeTag(mod)) {
19183 else => switch (abi_size) {19285 else => switch (abi_size) {
19184 1 => 8,19286 1 => 8,
...@@ -19196,8 +19298,7 @@ fn regBitSize(self: *Self, ty: Type) u64 {...@@ -19196,8 +19298,7 @@ fn regBitSize(self: *Self, ty: Type) u64 {
19196}19298}
1919719299
19198fn regExtraBits(self: *Self, ty: Type) u64 {19300fn regExtraBits(self: *Self, ty: Type) u64 {
19199 const mod = self.bin_file.comp.module.?;19301 return self.regBitSize(ty) - ty.bitSize(self.pt);
19200 return self.regBitSize(ty) - ty.bitSize(mod);
19201}19302}
1920219303
19203fn hasFeature(self: *Self, feature: Target.x86.Feature) bool {19304fn hasFeature(self: *Self, feature: Target.x86.Feature) bool {
...@@ -19211,12 +19312,14 @@ fn hasAllFeatures(self: *Self, features: anytype) bool {...@@ -19211,12 +19312,14 @@ fn hasAllFeatures(self: *Self, features: anytype) bool {
19211}19312}
1921219313
19213fn typeOf(self: *Self, inst: Air.Inst.Ref) Type {19314fn typeOf(self: *Self, inst: Air.Inst.Ref) Type {
19214 const mod = self.bin_file.comp.module.?;19315 const pt = self.pt;
19316 const mod = pt.zcu;
19215 return self.air.typeOf(inst, &mod.intern_pool);19317 return self.air.typeOf(inst, &mod.intern_pool);
19216}19318}
1921719319
19218fn typeOfIndex(self: *Self, inst: Air.Inst.Index) Type {19320fn typeOfIndex(self: *Self, inst: Air.Inst.Index) Type {
19219 const mod = self.bin_file.comp.module.?;19321 const pt = self.pt;
19322 const mod = pt.zcu;
19220 return self.air.typeOfIndex(inst, &mod.intern_pool);19323 return self.air.typeOfIndex(inst, &mod.intern_pool);
19221}19324}
1922219325
...@@ -19268,7 +19371,8 @@ fn floatLibcAbiSuffix(ty: Type) []const u8 {...@@ -19268,7 +19371,8 @@ fn floatLibcAbiSuffix(ty: Type) []const u8 {
19268}19371}
1926919372
19270fn promoteInt(self: *Self, ty: Type) Type {19373fn promoteInt(self: *Self, ty: Type) Type {
19271 const mod = self.bin_file.comp.module.?;19374 const pt = self.pt;
19375 const mod = pt.zcu;
19272 const int_info: InternPool.Key.IntType = switch (ty.toIntern()) {19376 const int_info: InternPool.Key.IntType = switch (ty.toIntern()) {
19273 .bool_type => .{ .signedness = .unsigned, .bits = 1 },19377 .bool_type => .{ .signedness = .unsigned, .bits = 1 },
19274 else => if (ty.isAbiInt(mod)) ty.intInfo(mod) else return ty,19378 else => if (ty.isAbiInt(mod)) ty.intInfo(mod) else return ty,
src/arch/x86_64/Lower.zig+2-4
...@@ -8,7 +8,7 @@ allocator: Allocator,...@@ -8,7 +8,7 @@ allocator: Allocator,
8mir: Mir,8mir: Mir,
9cc: std.builtin.CallingConvention,9cc: std.builtin.CallingConvention,
10err_msg: ?*ErrorMsg = null,10err_msg: ?*ErrorMsg = null,
11src_loc: Module.LazySrcLoc,11src_loc: Zcu.LazySrcLoc,
12result_insts_len: u8 = undefined,12result_insts_len: u8 = undefined,
13result_relocs_len: u8 = undefined,13result_relocs_len: u8 = undefined,
14result_insts: [14result_insts: [
...@@ -657,7 +657,7 @@ const std = @import("std");...@@ -657,7 +657,7 @@ const std = @import("std");
657657
658const Air = @import("../../Air.zig");658const Air = @import("../../Air.zig");
659const Allocator = std.mem.Allocator;659const Allocator = std.mem.Allocator;
660const ErrorMsg = Module.ErrorMsg;660const ErrorMsg = Zcu.ErrorMsg;
661const Immediate = bits.Immediate;661const Immediate = bits.Immediate;
662const Instruction = encoder.Instruction;662const Instruction = encoder.Instruction;
663const Lower = @This();663const Lower = @This();
...@@ -665,8 +665,6 @@ const Memory = Instruction.Memory;...@@ -665,8 +665,6 @@ const Memory = Instruction.Memory;
665const Mir = @import("Mir.zig");665const Mir = @import("Mir.zig");
666const Mnemonic = Instruction.Mnemonic;666const Mnemonic = Instruction.Mnemonic;
667const Zcu = @import("../../Zcu.zig");667const Zcu = @import("../../Zcu.zig");
668/// Deprecated.
669const Module = Zcu;
670const Operand = Instruction.Operand;668const Operand = Instruction.Operand;
671const Prefix = Instruction.Prefix;669const Prefix = Instruction.Prefix;
672const Register = bits.Register;670const Register = bits.Register;
src/arch/x86_64/abi.zig+35-35
...@@ -44,7 +44,7 @@ pub const Class = enum {...@@ -44,7 +44,7 @@ pub const Class = enum {
44 }44 }
45};45};
4646
47pub fn classifyWindows(ty: Type, zcu: *Zcu) Class {47pub fn classifyWindows(ty: Type, pt: Zcu.PerThread) Class {
48 // https://docs.microsoft.com/en-gb/cpp/build/x64-calling-convention?view=vs-201748 // https://docs.microsoft.com/en-gb/cpp/build/x64-calling-convention?view=vs-2017
49 // "There's a strict one-to-one correspondence between a function call's arguments49 // "There's a strict one-to-one correspondence between a function call's arguments
50 // and the registers used for those arguments. Any argument that doesn't fit in 850 // and the registers used for those arguments. Any argument that doesn't fit in 8
...@@ -53,7 +53,7 @@ pub fn classifyWindows(ty: Type, zcu: *Zcu) Class {...@@ -53,7 +53,7 @@ pub fn classifyWindows(ty: Type, zcu: *Zcu) Class {
53 // "All floating point operations are done using the 16 XMM registers."53 // "All floating point operations are done using the 16 XMM registers."
54 // "Structs and unions of size 8, 16, 32, or 64 bits, and __m64 types, are passed54 // "Structs and unions of size 8, 16, 32, or 64 bits, and __m64 types, are passed
55 // as if they were integers of the same size."55 // as if they were integers of the same size."
56 switch (ty.zigTypeTag(zcu)) {56 switch (ty.zigTypeTag(pt.zcu)) {
57 .Pointer,57 .Pointer,
58 .Int,58 .Int,
59 .Bool,59 .Bool,
...@@ -68,12 +68,12 @@ pub fn classifyWindows(ty: Type, zcu: *Zcu) Class {...@@ -68,12 +68,12 @@ pub fn classifyWindows(ty: Type, zcu: *Zcu) Class {
68 .ErrorUnion,68 .ErrorUnion,
69 .AnyFrame,69 .AnyFrame,
70 .Frame,70 .Frame,
71 => switch (ty.abiSize(zcu)) {71 => switch (ty.abiSize(pt)) {
72 0 => unreachable,72 0 => unreachable,
73 1, 2, 4, 8 => return .integer,73 1, 2, 4, 8 => return .integer,
74 else => switch (ty.zigTypeTag(zcu)) {74 else => switch (ty.zigTypeTag(pt.zcu)) {
75 .Int => return .win_i128,75 .Int => return .win_i128,
76 .Struct, .Union => if (ty.containerLayout(zcu) == .@"packed") {76 .Struct, .Union => if (ty.containerLayout(pt.zcu) == .@"packed") {
77 return .win_i128;77 return .win_i128;
78 } else {78 } else {
79 return .memory;79 return .memory;
...@@ -100,14 +100,14 @@ pub const Context = enum { ret, arg, field, other };...@@ -100,14 +100,14 @@ pub const Context = enum { ret, arg, field, other };
100100
101/// There are a maximum of 8 possible return slots. Returned values are in101/// There are a maximum of 8 possible return slots. Returned values are in
102/// the beginning of the array; unused slots are filled with .none.102/// the beginning of the array; unused slots are filled with .none.
103pub fn classifySystemV(ty: Type, zcu: *Zcu, target: std.Target, ctx: Context) [8]Class {103pub fn classifySystemV(ty: Type, pt: Zcu.PerThread, target: std.Target, ctx: Context) [8]Class {
104 const memory_class = [_]Class{104 const memory_class = [_]Class{
105 .memory, .none, .none, .none,105 .memory, .none, .none, .none,
106 .none, .none, .none, .none,106 .none, .none, .none, .none,
107 };107 };
108 var result = [1]Class{.none} ** 8;108 var result = [1]Class{.none} ** 8;
109 switch (ty.zigTypeTag(zcu)) {109 switch (ty.zigTypeTag(pt.zcu)) {
110 .Pointer => switch (ty.ptrSize(zcu)) {110 .Pointer => switch (ty.ptrSize(pt.zcu)) {
111 .Slice => {111 .Slice => {
112 result[0] = .integer;112 result[0] = .integer;
113 result[1] = .integer;113 result[1] = .integer;
...@@ -119,7 +119,7 @@ pub fn classifySystemV(ty: Type, zcu: *Zcu, target: std.Target, ctx: Context) [8...@@ -119,7 +119,7 @@ pub fn classifySystemV(ty: Type, zcu: *Zcu, target: std.Target, ctx: Context) [8
119 },119 },
120 },120 },
121 .Int, .Enum, .ErrorSet => {121 .Int, .Enum, .ErrorSet => {
122 const bits = ty.intInfo(zcu).bits;122 const bits = ty.intInfo(pt.zcu).bits;
123 if (bits <= 64) {123 if (bits <= 64) {
124 result[0] = .integer;124 result[0] = .integer;
125 return result;125 return result;
...@@ -185,8 +185,8 @@ pub fn classifySystemV(ty: Type, zcu: *Zcu, target: std.Target, ctx: Context) [8...@@ -185,8 +185,8 @@ pub fn classifySystemV(ty: Type, zcu: *Zcu, target: std.Target, ctx: Context) [8
185 else => unreachable,185 else => unreachable,
186 },186 },
187 .Vector => {187 .Vector => {
188 const elem_ty = ty.childType(zcu);188 const elem_ty = ty.childType(pt.zcu);
189 const bits = elem_ty.bitSize(zcu) * ty.arrayLen(zcu);189 const bits = elem_ty.bitSize(pt) * ty.arrayLen(pt.zcu);
190 if (elem_ty.toIntern() == .bool_type) {190 if (elem_ty.toIntern() == .bool_type) {
191 if (bits <= 32) return .{191 if (bits <= 32) return .{
192 .integer, .none, .none, .none,192 .integer, .none, .none, .none,
...@@ -250,7 +250,7 @@ pub fn classifySystemV(ty: Type, zcu: *Zcu, target: std.Target, ctx: Context) [8...@@ -250,7 +250,7 @@ pub fn classifySystemV(ty: Type, zcu: *Zcu, target: std.Target, ctx: Context) [8
250 return memory_class;250 return memory_class;
251 },251 },
252 .Optional => {252 .Optional => {
253 if (ty.isPtrLikeOptional(zcu)) {253 if (ty.isPtrLikeOptional(pt.zcu)) {
254 result[0] = .integer;254 result[0] = .integer;
255 return result;255 return result;
256 }256 }
...@@ -261,8 +261,8 @@ pub fn classifySystemV(ty: Type, zcu: *Zcu, target: std.Target, ctx: Context) [8...@@ -261,8 +261,8 @@ pub fn classifySystemV(ty: Type, zcu: *Zcu, target: std.Target, ctx: Context) [8
261 // it contains unaligned fields, it has class MEMORY"261 // it contains unaligned fields, it has class MEMORY"
262 // "If the size of the aggregate exceeds a single eightbyte, each is classified262 // "If the size of the aggregate exceeds a single eightbyte, each is classified
263 // separately.".263 // separately.".
264 const ty_size = ty.abiSize(zcu);264 const ty_size = ty.abiSize(pt);
265 switch (ty.containerLayout(zcu)) {265 switch (ty.containerLayout(pt.zcu)) {
266 .auto, .@"extern" => {},266 .auto, .@"extern" => {},
267 .@"packed" => {267 .@"packed" => {
268 assert(ty_size <= 16);268 assert(ty_size <= 16);
...@@ -274,10 +274,10 @@ pub fn classifySystemV(ty: Type, zcu: *Zcu, target: std.Target, ctx: Context) [8...@@ -274,10 +274,10 @@ pub fn classifySystemV(ty: Type, zcu: *Zcu, target: std.Target, ctx: Context) [8
274 if (ty_size > 64)274 if (ty_size > 64)
275 return memory_class;275 return memory_class;
276276
277 _ = if (zcu.typeToStruct(ty)) |loaded_struct|277 _ = if (pt.zcu.typeToStruct(ty)) |loaded_struct|
278 classifySystemVStruct(&result, 0, loaded_struct, zcu, target)278 classifySystemVStruct(&result, 0, loaded_struct, pt, target)
279 else if (zcu.typeToUnion(ty)) |loaded_union|279 else if (pt.zcu.typeToUnion(ty)) |loaded_union|
280 classifySystemVUnion(&result, 0, loaded_union, zcu, target)280 classifySystemVUnion(&result, 0, loaded_union, pt, target)
281 else281 else
282 unreachable;282 unreachable;
283283
...@@ -306,7 +306,7 @@ pub fn classifySystemV(ty: Type, zcu: *Zcu, target: std.Target, ctx: Context) [8...@@ -306,7 +306,7 @@ pub fn classifySystemV(ty: Type, zcu: *Zcu, target: std.Target, ctx: Context) [8
306 return result;306 return result;
307 },307 },
308 .Array => {308 .Array => {
309 const ty_size = ty.abiSize(zcu);309 const ty_size = ty.abiSize(pt);
310 if (ty_size <= 8) {310 if (ty_size <= 8) {
311 result[0] = .integer;311 result[0] = .integer;
312 return result;312 return result;
...@@ -326,10 +326,10 @@ fn classifySystemVStruct(...@@ -326,10 +326,10 @@ fn classifySystemVStruct(
326 result: *[8]Class,326 result: *[8]Class,
327 starting_byte_offset: u64,327 starting_byte_offset: u64,
328 loaded_struct: InternPool.LoadedStructType,328 loaded_struct: InternPool.LoadedStructType,
329 zcu: *Zcu,329 pt: Zcu.PerThread,
330 target: std.Target,330 target: std.Target,
331) u64 {331) u64 {
332 const ip = &zcu.intern_pool;332 const ip = &pt.zcu.intern_pool;
333 var byte_offset = starting_byte_offset;333 var byte_offset = starting_byte_offset;
334 var field_it = loaded_struct.iterateRuntimeOrder(ip);334 var field_it = loaded_struct.iterateRuntimeOrder(ip);
335 while (field_it.next()) |field_index| {335 while (field_it.next()) |field_index| {
...@@ -338,29 +338,29 @@ fn classifySystemVStruct(...@@ -338,29 +338,29 @@ fn classifySystemVStruct(
338 byte_offset = std.mem.alignForward(338 byte_offset = std.mem.alignForward(
339 u64,339 u64,
340 byte_offset,340 byte_offset,
341 field_align.toByteUnits() orelse field_ty.abiAlignment(zcu).toByteUnits().?,341 field_align.toByteUnits() orelse field_ty.abiAlignment(pt).toByteUnits().?,
342 );342 );
343 if (zcu.typeToStruct(field_ty)) |field_loaded_struct| {343 if (pt.zcu.typeToStruct(field_ty)) |field_loaded_struct| {
344 switch (field_loaded_struct.layout) {344 switch (field_loaded_struct.layout) {
345 .auto, .@"extern" => {345 .auto, .@"extern" => {
346 byte_offset = classifySystemVStruct(result, byte_offset, field_loaded_struct, zcu, target);346 byte_offset = classifySystemVStruct(result, byte_offset, field_loaded_struct, pt, target);
347 continue;347 continue;
348 },348 },
349 .@"packed" => {},349 .@"packed" => {},
350 }350 }
351 } else if (zcu.typeToUnion(field_ty)) |field_loaded_union| {351 } else if (pt.zcu.typeToUnion(field_ty)) |field_loaded_union| {
352 switch (field_loaded_union.getLayout(ip)) {352 switch (field_loaded_union.getLayout(ip)) {
353 .auto, .@"extern" => {353 .auto, .@"extern" => {
354 byte_offset = classifySystemVUnion(result, byte_offset, field_loaded_union, zcu, target);354 byte_offset = classifySystemVUnion(result, byte_offset, field_loaded_union, pt, target);
355 continue;355 continue;
356 },356 },
357 .@"packed" => {},357 .@"packed" => {},
358 }358 }
359 }359 }
360 const field_classes = std.mem.sliceTo(&classifySystemV(field_ty, zcu, target, .field), .none);360 const field_classes = std.mem.sliceTo(&classifySystemV(field_ty, pt, target, .field), .none);
361 for (result[@intCast(byte_offset / 8)..][0..field_classes.len], field_classes) |*result_class, field_class|361 for (result[@intCast(byte_offset / 8)..][0..field_classes.len], field_classes) |*result_class, field_class|
362 result_class.* = result_class.combineSystemV(field_class);362 result_class.* = result_class.combineSystemV(field_class);
363 byte_offset += field_ty.abiSize(zcu);363 byte_offset += field_ty.abiSize(pt);
364 }364 }
365 const final_byte_offset = starting_byte_offset + loaded_struct.size(ip).*;365 const final_byte_offset = starting_byte_offset + loaded_struct.size(ip).*;
366 std.debug.assert(final_byte_offset == std.mem.alignForward(366 std.debug.assert(final_byte_offset == std.mem.alignForward(
...@@ -375,30 +375,30 @@ fn classifySystemVUnion(...@@ -375,30 +375,30 @@ fn classifySystemVUnion(
375 result: *[8]Class,375 result: *[8]Class,
376 starting_byte_offset: u64,376 starting_byte_offset: u64,
377 loaded_union: InternPool.LoadedUnionType,377 loaded_union: InternPool.LoadedUnionType,
378 zcu: *Zcu,378 pt: Zcu.PerThread,
379 target: std.Target,379 target: std.Target,
380) u64 {380) u64 {
381 const ip = &zcu.intern_pool;381 const ip = &pt.zcu.intern_pool;
382 for (0..loaded_union.field_types.len) |field_index| {382 for (0..loaded_union.field_types.len) |field_index| {
383 const field_ty = Type.fromInterned(loaded_union.field_types.get(ip)[field_index]);383 const field_ty = Type.fromInterned(loaded_union.field_types.get(ip)[field_index]);
384 if (zcu.typeToStruct(field_ty)) |field_loaded_struct| {384 if (pt.zcu.typeToStruct(field_ty)) |field_loaded_struct| {
385 switch (field_loaded_struct.layout) {385 switch (field_loaded_struct.layout) {
386 .auto, .@"extern" => {386 .auto, .@"extern" => {
387 _ = classifySystemVStruct(result, starting_byte_offset, field_loaded_struct, zcu, target);387 _ = classifySystemVStruct(result, starting_byte_offset, field_loaded_struct, pt, target);
388 continue;388 continue;
389 },389 },
390 .@"packed" => {},390 .@"packed" => {},
391 }391 }
392 } else if (zcu.typeToUnion(field_ty)) |field_loaded_union| {392 } else if (pt.zcu.typeToUnion(field_ty)) |field_loaded_union| {
393 switch (field_loaded_union.getLayout(ip)) {393 switch (field_loaded_union.getLayout(ip)) {
394 .auto, .@"extern" => {394 .auto, .@"extern" => {
395 _ = classifySystemVUnion(result, starting_byte_offset, field_loaded_union, zcu, target);395 _ = classifySystemVUnion(result, starting_byte_offset, field_loaded_union, pt, target);
396 continue;396 continue;
397 },397 },
398 .@"packed" => {},398 .@"packed" => {},
399 }399 }
400 }400 }
401 const field_classes = std.mem.sliceTo(&classifySystemV(field_ty, zcu, target, .field), .none);401 const field_classes = std.mem.sliceTo(&classifySystemV(field_ty, pt, target, .field), .none);
402 for (result[@intCast(starting_byte_offset / 8)..][0..field_classes.len], field_classes) |*result_class, field_class|402 for (result[@intCast(starting_byte_offset / 8)..][0..field_classes.len], field_classes) |*result_class, field_class|
403 result_class.* = result_class.combineSystemV(field_class);403 result_class.* = result_class.combineSystemV(field_class);
404 }404 }
src/codegen.zig+141-130
...@@ -13,12 +13,10 @@ const trace = @import("tracy.zig").trace;...@@ -13,12 +13,10 @@ const trace = @import("tracy.zig").trace;
13const Air = @import("Air.zig");13const Air = @import("Air.zig");
14const Allocator = mem.Allocator;14const Allocator = mem.Allocator;
15const Compilation = @import("Compilation.zig");15const Compilation = @import("Compilation.zig");
16const ErrorMsg = Module.ErrorMsg;16const ErrorMsg = Zcu.ErrorMsg;
17const InternPool = @import("InternPool.zig");17const InternPool = @import("InternPool.zig");
18const Liveness = @import("Liveness.zig");18const Liveness = @import("Liveness.zig");
19const Zcu = @import("Zcu.zig");19const Zcu = @import("Zcu.zig");
20/// Deprecated.
21const Module = Zcu;
22const Target = std.Target;20const Target = std.Target;
23const Type = @import("Type.zig");21const Type = @import("Type.zig");
24const Value = @import("Value.zig");22const Value = @import("Value.zig");
...@@ -47,14 +45,15 @@ pub const DebugInfoOutput = union(enum) {...@@ -47,14 +45,15 @@ pub const DebugInfoOutput = union(enum) {
4745
48pub fn generateFunction(46pub fn generateFunction(
49 lf: *link.File,47 lf: *link.File,
50 src_loc: Module.LazySrcLoc,48 pt: Zcu.PerThread,
49 src_loc: Zcu.LazySrcLoc,
51 func_index: InternPool.Index,50 func_index: InternPool.Index,
52 air: Air,51 air: Air,
53 liveness: Liveness,52 liveness: Liveness,
54 code: *std.ArrayList(u8),53 code: *std.ArrayList(u8),
55 debug_output: DebugInfoOutput,54 debug_output: DebugInfoOutput,
56) CodeGenError!Result {55) CodeGenError!Result {
57 const zcu = lf.comp.module.?;56 const zcu = pt.zcu;
58 const func = zcu.funcInfo(func_index);57 const func = zcu.funcInfo(func_index);
59 const decl = zcu.declPtr(func.owner_decl);58 const decl = zcu.declPtr(func.owner_decl);
60 const namespace = zcu.namespacePtr(decl.src_namespace);59 const namespace = zcu.namespacePtr(decl.src_namespace);
...@@ -62,35 +61,36 @@ pub fn generateFunction(...@@ -62,35 +61,36 @@ pub fn generateFunction(
62 switch (target.cpu.arch) {61 switch (target.cpu.arch) {
63 .arm,62 .arm,
64 .armeb,63 .armeb,
65 => return @import("arch/arm/CodeGen.zig").generate(lf, src_loc, func_index, air, liveness, code, debug_output),64 => return @import("arch/arm/CodeGen.zig").generate(lf, pt, src_loc, func_index, air, liveness, code, debug_output),
66 .aarch64,65 .aarch64,
67 .aarch64_be,66 .aarch64_be,
68 .aarch64_32,67 .aarch64_32,
69 => return @import("arch/aarch64/CodeGen.zig").generate(lf, src_loc, func_index, air, liveness, code, debug_output),68 => return @import("arch/aarch64/CodeGen.zig").generate(lf, pt, src_loc, func_index, air, liveness, code, debug_output),
70 .riscv64 => return @import("arch/riscv64/CodeGen.zig").generate(lf, src_loc, func_index, air, liveness, code, debug_output),69 .riscv64 => return @import("arch/riscv64/CodeGen.zig").generate(lf, pt, src_loc, func_index, air, liveness, code, debug_output),
71 .sparc64 => return @import("arch/sparc64/CodeGen.zig").generate(lf, src_loc, func_index, air, liveness, code, debug_output),70 .sparc64 => return @import("arch/sparc64/CodeGen.zig").generate(lf, pt, src_loc, func_index, air, liveness, code, debug_output),
72 .x86_64 => return @import("arch/x86_64/CodeGen.zig").generate(lf, src_loc, func_index, air, liveness, code, debug_output),71 .x86_64 => return @import("arch/x86_64/CodeGen.zig").generate(lf, pt, src_loc, func_index, air, liveness, code, debug_output),
73 .wasm32,72 .wasm32,
74 .wasm64,73 .wasm64,
75 => return @import("arch/wasm/CodeGen.zig").generate(lf, src_loc, func_index, air, liveness, code, debug_output),74 => return @import("arch/wasm/CodeGen.zig").generate(lf, pt, src_loc, func_index, air, liveness, code, debug_output),
76 else => unreachable,75 else => unreachable,
77 }76 }
78}77}
7978
80pub fn generateLazyFunction(79pub fn generateLazyFunction(
81 lf: *link.File,80 lf: *link.File,
82 src_loc: Module.LazySrcLoc,81 pt: Zcu.PerThread,
82 src_loc: Zcu.LazySrcLoc,
83 lazy_sym: link.File.LazySymbol,83 lazy_sym: link.File.LazySymbol,
84 code: *std.ArrayList(u8),84 code: *std.ArrayList(u8),
85 debug_output: DebugInfoOutput,85 debug_output: DebugInfoOutput,
86) CodeGenError!Result {86) CodeGenError!Result {
87 const zcu = lf.comp.module.?;87 const zcu = pt.zcu;
88 const decl_index = lazy_sym.ty.getOwnerDecl(zcu);88 const decl_index = lazy_sym.ty.getOwnerDecl(zcu);
89 const decl = zcu.declPtr(decl_index);89 const decl = zcu.declPtr(decl_index);
90 const namespace = zcu.namespacePtr(decl.src_namespace);90 const namespace = zcu.namespacePtr(decl.src_namespace);
91 const target = namespace.fileScope(zcu).mod.resolved_target.result;91 const target = namespace.fileScope(zcu).mod.resolved_target.result;
92 switch (target.cpu.arch) {92 switch (target.cpu.arch) {
93 .x86_64 => return @import("arch/x86_64/CodeGen.zig").generateLazy(lf, src_loc, lazy_sym, code, debug_output),93 .x86_64 => return @import("arch/x86_64/CodeGen.zig").generateLazy(lf, pt, src_loc, lazy_sym, code, debug_output),
94 else => unreachable,94 else => unreachable,
95 }95 }
96}96}
...@@ -105,7 +105,8 @@ fn writeFloat(comptime F: type, f: F, target: Target, endian: std.builtin.Endian...@@ -105,7 +105,8 @@ fn writeFloat(comptime F: type, f: F, target: Target, endian: std.builtin.Endian
105105
106pub fn generateLazySymbol(106pub fn generateLazySymbol(
107 bin_file: *link.File,107 bin_file: *link.File,
108 src_loc: Module.LazySrcLoc,108 pt: Zcu.PerThread,
109 src_loc: Zcu.LazySrcLoc,
109 lazy_sym: link.File.LazySymbol,110 lazy_sym: link.File.LazySymbol,
110 // TODO don't use an "out" parameter like this; put it in the result instead111 // TODO don't use an "out" parameter like this; put it in the result instead
111 alignment: *Alignment,112 alignment: *Alignment,
...@@ -119,25 +120,24 @@ pub fn generateLazySymbol(...@@ -119,25 +120,24 @@ pub fn generateLazySymbol(
119 defer tracy.end();120 defer tracy.end();
120121
121 const comp = bin_file.comp;122 const comp = bin_file.comp;
122 const zcu = comp.module.?;123 const ip = &pt.zcu.intern_pool;
123 const ip = &zcu.intern_pool;
124 const target = comp.root_mod.resolved_target.result;124 const target = comp.root_mod.resolved_target.result;
125 const endian = target.cpu.arch.endian();125 const endian = target.cpu.arch.endian();
126 const gpa = comp.gpa;126 const gpa = comp.gpa;
127127
128 log.debug("generateLazySymbol: kind = {s}, ty = {}", .{128 log.debug("generateLazySymbol: kind = {s}, ty = {}", .{
129 @tagName(lazy_sym.kind),129 @tagName(lazy_sym.kind),
130 lazy_sym.ty.fmt(zcu),130 lazy_sym.ty.fmt(pt),
131 });131 });
132132
133 if (lazy_sym.kind == .code) {133 if (lazy_sym.kind == .code) {
134 alignment.* = target_util.defaultFunctionAlignment(target);134 alignment.* = target_util.defaultFunctionAlignment(target);
135 return generateLazyFunction(bin_file, src_loc, lazy_sym, code, debug_output);135 return generateLazyFunction(bin_file, pt, src_loc, lazy_sym, code, debug_output);
136 }136 }
137137
138 if (lazy_sym.ty.isAnyError(zcu)) {138 if (lazy_sym.ty.isAnyError(pt.zcu)) {
139 alignment.* = .@"4";139 alignment.* = .@"4";
140 const err_names = zcu.global_error_set.keys();140 const err_names = pt.zcu.global_error_set.keys();
141 mem.writeInt(u32, try code.addManyAsArray(4), @intCast(err_names.len), endian);141 mem.writeInt(u32, try code.addManyAsArray(4), @intCast(err_names.len), endian);
142 var offset = code.items.len;142 var offset = code.items.len;
143 try code.resize((1 + err_names.len + 1) * 4);143 try code.resize((1 + err_names.len + 1) * 4);
...@@ -151,9 +151,9 @@ pub fn generateLazySymbol(...@@ -151,9 +151,9 @@ pub fn generateLazySymbol(
151 }151 }
152 mem.writeInt(u32, code.items[offset..][0..4], @intCast(code.items.len), endian);152 mem.writeInt(u32, code.items[offset..][0..4], @intCast(code.items.len), endian);
153 return Result.ok;153 return Result.ok;
154 } else if (lazy_sym.ty.zigTypeTag(zcu) == .Enum) {154 } else if (lazy_sym.ty.zigTypeTag(pt.zcu) == .Enum) {
155 alignment.* = .@"1";155 alignment.* = .@"1";
156 const tag_names = lazy_sym.ty.enumFields(zcu);156 const tag_names = lazy_sym.ty.enumFields(pt.zcu);
157 for (0..tag_names.len) |tag_index| {157 for (0..tag_names.len) |tag_index| {
158 const tag_name = tag_names.get(ip)[tag_index].toSlice(ip);158 const tag_name = tag_names.get(ip)[tag_index].toSlice(ip);
159 try code.ensureUnusedCapacity(tag_name.len + 1);159 try code.ensureUnusedCapacity(tag_name.len + 1);
...@@ -165,13 +165,14 @@ pub fn generateLazySymbol(...@@ -165,13 +165,14 @@ pub fn generateLazySymbol(
165 gpa,165 gpa,
166 src_loc,166 src_loc,
167 "TODO implement generateLazySymbol for {s} {}",167 "TODO implement generateLazySymbol for {s} {}",
168 .{ @tagName(lazy_sym.kind), lazy_sym.ty.fmt(zcu) },168 .{ @tagName(lazy_sym.kind), lazy_sym.ty.fmt(pt) },
169 ) };169 ) };
170}170}
171171
172pub fn generateSymbol(172pub fn generateSymbol(
173 bin_file: *link.File,173 bin_file: *link.File,
174 src_loc: Module.LazySrcLoc,174 pt: Zcu.PerThread,
175 src_loc: Zcu.LazySrcLoc,
175 val: Value,176 val: Value,
176 code: *std.ArrayList(u8),177 code: *std.ArrayList(u8),
177 debug_output: DebugInfoOutput,178 debug_output: DebugInfoOutput,
...@@ -180,17 +181,17 @@ pub fn generateSymbol(...@@ -180,17 +181,17 @@ pub fn generateSymbol(
180 const tracy = trace(@src());181 const tracy = trace(@src());
181 defer tracy.end();182 defer tracy.end();
182183
183 const mod = bin_file.comp.module.?;184 const mod = pt.zcu;
184 const ip = &mod.intern_pool;185 const ip = &mod.intern_pool;
185 const ty = val.typeOf(mod);186 const ty = val.typeOf(mod);
186187
187 const target = mod.getTarget();188 const target = mod.getTarget();
188 const endian = target.cpu.arch.endian();189 const endian = target.cpu.arch.endian();
189190
190 log.debug("generateSymbol: val = {}", .{val.fmtValue(mod, null)});191 log.debug("generateSymbol: val = {}", .{val.fmtValue(pt, null)});
191192
192 if (val.isUndefDeep(mod)) {193 if (val.isUndefDeep(mod)) {
193 const abi_size = math.cast(usize, ty.abiSize(mod)) orelse return error.Overflow;194 const abi_size = math.cast(usize, ty.abiSize(pt)) orelse return error.Overflow;
194 try code.appendNTimes(0xaa, abi_size);195 try code.appendNTimes(0xaa, abi_size);
195 return .ok;196 return .ok;
196 }197 }
...@@ -236,9 +237,9 @@ pub fn generateSymbol(...@@ -236,9 +237,9 @@ pub fn generateSymbol(
236 .empty_enum_value,237 .empty_enum_value,
237 => unreachable, // non-runtime values238 => unreachable, // non-runtime values
238 .int => {239 .int => {
239 const abi_size = math.cast(usize, ty.abiSize(mod)) orelse return error.Overflow;240 const abi_size = math.cast(usize, ty.abiSize(pt)) orelse return error.Overflow;
240 var space: Value.BigIntSpace = undefined;241 var space: Value.BigIntSpace = undefined;
241 const int_val = val.toBigInt(&space, mod);242 const int_val = val.toBigInt(&space, pt);
242 int_val.writeTwosComplement(try code.addManyAsSlice(abi_size), endian);243 int_val.writeTwosComplement(try code.addManyAsSlice(abi_size), endian);
243 },244 },
244 .err => |err| {245 .err => |err| {
...@@ -252,14 +253,14 @@ pub fn generateSymbol(...@@ -252,14 +253,14 @@ pub fn generateSymbol(
252 .payload => 0,253 .payload => 0,
253 };254 };
254255
255 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) {256 if (!payload_ty.hasRuntimeBitsIgnoreComptime(pt)) {
256 try code.writer().writeInt(u16, err_val, endian);257 try code.writer().writeInt(u16, err_val, endian);
257 return .ok;258 return .ok;
258 }259 }
259260
260 const payload_align = payload_ty.abiAlignment(mod);261 const payload_align = payload_ty.abiAlignment(pt);
261 const error_align = Type.anyerror.abiAlignment(mod);262 const error_align = Type.anyerror.abiAlignment(pt);
262 const abi_align = ty.abiAlignment(mod);263 const abi_align = ty.abiAlignment(pt);
263264
264 // error value first when its type is larger than the error union's payload265 // error value first when its type is larger than the error union's payload
265 if (error_align.order(payload_align) == .gt) {266 if (error_align.order(payload_align) == .gt) {
...@@ -269,8 +270,8 @@ pub fn generateSymbol(...@@ -269,8 +270,8 @@ pub fn generateSymbol(
269 // emit payload part of the error union270 // emit payload part of the error union
270 {271 {
271 const begin = code.items.len;272 const begin = code.items.len;
272 switch (try generateSymbol(bin_file, src_loc, Value.fromInterned(switch (error_union.val) {273 switch (try generateSymbol(bin_file, pt, src_loc, Value.fromInterned(switch (error_union.val) {
273 .err_name => try mod.intern(.{ .undef = payload_ty.toIntern() }),274 .err_name => try pt.intern(.{ .undef = payload_ty.toIntern() }),
274 .payload => |payload| payload,275 .payload => |payload| payload,
275 }), code, debug_output, reloc_info)) {276 }), code, debug_output, reloc_info)) {
276 .ok => {},277 .ok => {},
...@@ -300,7 +301,7 @@ pub fn generateSymbol(...@@ -300,7 +301,7 @@ pub fn generateSymbol(
300 },301 },
301 .enum_tag => |enum_tag| {302 .enum_tag => |enum_tag| {
302 const int_tag_ty = ty.intTagType(mod);303 const int_tag_ty = ty.intTagType(mod);
303 switch (try generateSymbol(bin_file, src_loc, try mod.getCoerced(Value.fromInterned(enum_tag.int), int_tag_ty), code, debug_output, reloc_info)) {304 switch (try generateSymbol(bin_file, pt, src_loc, try pt.getCoerced(Value.fromInterned(enum_tag.int), int_tag_ty), code, debug_output, reloc_info)) {
304 .ok => {},305 .ok => {},
305 .fail => |em| return .{ .fail = em },306 .fail => |em| return .{ .fail = em },
306 }307 }
...@@ -311,21 +312,21 @@ pub fn generateSymbol(...@@ -311,21 +312,21 @@ pub fn generateSymbol(
311 .f64 => |f64_val| writeFloat(f64, f64_val, target, endian, try code.addManyAsArray(8)),312 .f64 => |f64_val| writeFloat(f64, f64_val, target, endian, try code.addManyAsArray(8)),
312 .f80 => |f80_val| {313 .f80 => |f80_val| {
313 writeFloat(f80, f80_val, target, endian, try code.addManyAsArray(10));314 writeFloat(f80, f80_val, target, endian, try code.addManyAsArray(10));
314 const abi_size = math.cast(usize, ty.abiSize(mod)) orelse return error.Overflow;315 const abi_size = math.cast(usize, ty.abiSize(pt)) orelse return error.Overflow;
315 try code.appendNTimes(0, abi_size - 10);316 try code.appendNTimes(0, abi_size - 10);
316 },317 },
317 .f128 => |f128_val| writeFloat(f128, f128_val, target, endian, try code.addManyAsArray(16)),318 .f128 => |f128_val| writeFloat(f128, f128_val, target, endian, try code.addManyAsArray(16)),
318 },319 },
319 .ptr => switch (try lowerPtr(bin_file, src_loc, val.toIntern(), code, debug_output, reloc_info, 0)) {320 .ptr => switch (try lowerPtr(bin_file, pt, src_loc, val.toIntern(), code, debug_output, reloc_info, 0)) {
320 .ok => {},321 .ok => {},
321 .fail => |em| return .{ .fail = em },322 .fail => |em| return .{ .fail = em },
322 },323 },
323 .slice => |slice| {324 .slice => |slice| {
324 switch (try generateSymbol(bin_file, src_loc, Value.fromInterned(slice.ptr), code, debug_output, reloc_info)) {325 switch (try generateSymbol(bin_file, pt, src_loc, Value.fromInterned(slice.ptr), code, debug_output, reloc_info)) {
325 .ok => {},326 .ok => {},
326 .fail => |em| return .{ .fail = em },327 .fail => |em| return .{ .fail = em },
327 }328 }
328 switch (try generateSymbol(bin_file, src_loc, Value.fromInterned(slice.len), code, debug_output, reloc_info)) {329 switch (try generateSymbol(bin_file, pt, src_loc, Value.fromInterned(slice.len), code, debug_output, reloc_info)) {
329 .ok => {},330 .ok => {},
330 .fail => |em| return .{ .fail = em },331 .fail => |em| return .{ .fail = em },
331 }332 }
...@@ -333,11 +334,11 @@ pub fn generateSymbol(...@@ -333,11 +334,11 @@ pub fn generateSymbol(
333 .opt => {334 .opt => {
334 const payload_type = ty.optionalChild(mod);335 const payload_type = ty.optionalChild(mod);
335 const payload_val = val.optionalValue(mod);336 const payload_val = val.optionalValue(mod);
336 const abi_size = math.cast(usize, ty.abiSize(mod)) orelse return error.Overflow;337 const abi_size = math.cast(usize, ty.abiSize(pt)) orelse return error.Overflow;
337338
338 if (ty.optionalReprIsPayload(mod)) {339 if (ty.optionalReprIsPayload(mod)) {
339 if (payload_val) |value| {340 if (payload_val) |value| {
340 switch (try generateSymbol(bin_file, src_loc, value, code, debug_output, reloc_info)) {341 switch (try generateSymbol(bin_file, pt, src_loc, value, code, debug_output, reloc_info)) {
341 .ok => {},342 .ok => {},
342 .fail => |em| return Result{ .fail = em },343 .fail => |em| return Result{ .fail = em },
343 }344 }
...@@ -345,10 +346,12 @@ pub fn generateSymbol(...@@ -345,10 +346,12 @@ pub fn generateSymbol(
345 try code.appendNTimes(0, abi_size);346 try code.appendNTimes(0, abi_size);
346 }347 }
347 } else {348 } else {
348 const padding = abi_size - (math.cast(usize, payload_type.abiSize(mod)) orelse return error.Overflow) - 1;349 const padding = abi_size - (math.cast(usize, payload_type.abiSize(pt)) orelse return error.Overflow) - 1;
349 if (payload_type.hasRuntimeBits(mod)) {350 if (payload_type.hasRuntimeBits(pt)) {
350 const value = payload_val orelse Value.fromInterned((try mod.intern(.{ .undef = payload_type.toIntern() })));351 const value = payload_val orelse Value.fromInterned(try pt.intern(.{
351 switch (try generateSymbol(bin_file, src_loc, value, code, debug_output, reloc_info)) {352 .undef = payload_type.toIntern(),
353 }));
354 switch (try generateSymbol(bin_file, pt, src_loc, value, code, debug_output, reloc_info)) {
352 .ok => {},355 .ok => {},
353 .fail => |em| return Result{ .fail = em },356 .fail => |em| return Result{ .fail = em },
354 }357 }
...@@ -363,7 +366,7 @@ pub fn generateSymbol(...@@ -363,7 +366,7 @@ pub fn generateSymbol(
363 .elems, .repeated_elem => {366 .elems, .repeated_elem => {
364 var index: u64 = 0;367 var index: u64 = 0;
365 while (index < array_type.lenIncludingSentinel()) : (index += 1) {368 while (index < array_type.lenIncludingSentinel()) : (index += 1) {
366 switch (try generateSymbol(bin_file, src_loc, Value.fromInterned(switch (aggregate.storage) {369 switch (try generateSymbol(bin_file, pt, src_loc, Value.fromInterned(switch (aggregate.storage) {
367 .bytes => unreachable,370 .bytes => unreachable,
368 .elems => |elems| elems[@intCast(index)],371 .elems => |elems| elems[@intCast(index)],
369 .repeated_elem => |elem| if (index < array_type.len)372 .repeated_elem => |elem| if (index < array_type.len)
...@@ -378,8 +381,7 @@ pub fn generateSymbol(...@@ -378,8 +381,7 @@ pub fn generateSymbol(
378 },381 },
379 },382 },
380 .vector_type => |vector_type| {383 .vector_type => |vector_type| {
381 const abi_size = math.cast(usize, ty.abiSize(mod)) orelse384 const abi_size = math.cast(usize, ty.abiSize(pt)) orelse return error.Overflow;
382 return error.Overflow;
383 if (vector_type.child == .bool_type) {385 if (vector_type.child == .bool_type) {
384 const bytes = try code.addManyAsSlice(abi_size);386 const bytes = try code.addManyAsSlice(abi_size);
385 @memset(bytes, 0xaa);387 @memset(bytes, 0xaa);
...@@ -424,7 +426,7 @@ pub fn generateSymbol(...@@ -424,7 +426,7 @@ pub fn generateSymbol(
424 .elems, .repeated_elem => {426 .elems, .repeated_elem => {
425 var index: u64 = 0;427 var index: u64 = 0;
426 while (index < vector_type.len) : (index += 1) {428 while (index < vector_type.len) : (index += 1) {
427 switch (try generateSymbol(bin_file, src_loc, Value.fromInterned(switch (aggregate.storage) {429 switch (try generateSymbol(bin_file, pt, src_loc, Value.fromInterned(switch (aggregate.storage) {
428 .bytes => unreachable,430 .bytes => unreachable,
429 .elems => |elems| elems[431 .elems => |elems| elems[
430 math.cast(usize, index) orelse return error.Overflow432 math.cast(usize, index) orelse return error.Overflow
...@@ -439,7 +441,7 @@ pub fn generateSymbol(...@@ -439,7 +441,7 @@ pub fn generateSymbol(
439 }441 }
440442
441 const padding = abi_size -443 const padding = abi_size -
442 (math.cast(usize, Type.fromInterned(vector_type.child).abiSize(mod) * vector_type.len) orelse444 (math.cast(usize, Type.fromInterned(vector_type.child).abiSize(pt) * vector_type.len) orelse
443 return error.Overflow);445 return error.Overflow);
444 if (padding > 0) try code.appendNTimes(0, padding);446 if (padding > 0) try code.appendNTimes(0, padding);
445 }447 }
...@@ -452,10 +454,10 @@ pub fn generateSymbol(...@@ -452,10 +454,10 @@ pub fn generateSymbol(
452 0..,454 0..,
453 ) |field_ty, comptime_val, index| {455 ) |field_ty, comptime_val, index| {
454 if (comptime_val != .none) continue;456 if (comptime_val != .none) continue;
455 if (!Type.fromInterned(field_ty).hasRuntimeBits(mod)) continue;457 if (!Type.fromInterned(field_ty).hasRuntimeBits(pt)) continue;
456458
457 const field_val = switch (aggregate.storage) {459 const field_val = switch (aggregate.storage) {
458 .bytes => |bytes| try ip.get(mod.gpa, .{ .int = .{460 .bytes => |bytes| try pt.intern(.{ .int = .{
459 .ty = field_ty,461 .ty = field_ty,
460 .storage = .{ .u64 = bytes.at(index, ip) },462 .storage = .{ .u64 = bytes.at(index, ip) },
461 } }),463 } }),
...@@ -463,14 +465,14 @@ pub fn generateSymbol(...@@ -463,14 +465,14 @@ pub fn generateSymbol(
463 .repeated_elem => |elem| elem,465 .repeated_elem => |elem| elem,
464 };466 };
465467
466 switch (try generateSymbol(bin_file, src_loc, Value.fromInterned(field_val), code, debug_output, reloc_info)) {468 switch (try generateSymbol(bin_file, pt, src_loc, Value.fromInterned(field_val), code, debug_output, reloc_info)) {
467 .ok => {},469 .ok => {},
468 .fail => |em| return Result{ .fail = em },470 .fail => |em| return Result{ .fail = em },
469 }471 }
470 const unpadded_field_end = code.items.len - struct_begin;472 const unpadded_field_end = code.items.len - struct_begin;
471473
472 // Pad struct members if required474 // Pad struct members if required
473 const padded_field_end = ty.structFieldOffset(index + 1, mod);475 const padded_field_end = ty.structFieldOffset(index + 1, pt);
474 const padding = math.cast(usize, padded_field_end - unpadded_field_end) orelse476 const padding = math.cast(usize, padded_field_end - unpadded_field_end) orelse
475 return error.Overflow;477 return error.Overflow;
476478
...@@ -483,15 +485,14 @@ pub fn generateSymbol(...@@ -483,15 +485,14 @@ pub fn generateSymbol(
483 const struct_type = ip.loadStructType(ty.toIntern());485 const struct_type = ip.loadStructType(ty.toIntern());
484 switch (struct_type.layout) {486 switch (struct_type.layout) {
485 .@"packed" => {487 .@"packed" => {
486 const abi_size = math.cast(usize, ty.abiSize(mod)) orelse488 const abi_size = math.cast(usize, ty.abiSize(pt)) orelse return error.Overflow;
487 return error.Overflow;
488 const current_pos = code.items.len;489 const current_pos = code.items.len;
489 try code.appendNTimes(0, abi_size);490 try code.appendNTimes(0, abi_size);
490 var bits: u16 = 0;491 var bits: u16 = 0;
491492
492 for (struct_type.field_types.get(ip), 0..) |field_ty, index| {493 for (struct_type.field_types.get(ip), 0..) |field_ty, index| {
493 const field_val = switch (aggregate.storage) {494 const field_val = switch (aggregate.storage) {
494 .bytes => |bytes| try ip.get(mod.gpa, .{ .int = .{495 .bytes => |bytes| try pt.intern(.{ .int = .{
495 .ty = field_ty,496 .ty = field_ty,
496 .storage = .{ .u64 = bytes.at(index, ip) },497 .storage = .{ .u64 = bytes.at(index, ip) },
497 } }),498 } }),
...@@ -502,18 +503,18 @@ pub fn generateSymbol(...@@ -502,18 +503,18 @@ pub fn generateSymbol(
502 // pointer may point to a decl which must be marked used503 // pointer may point to a decl which must be marked used
503 // but can also result in a relocation. Therefore we handle those separately.504 // but can also result in a relocation. Therefore we handle those separately.
504 if (Type.fromInterned(field_ty).zigTypeTag(mod) == .Pointer) {505 if (Type.fromInterned(field_ty).zigTypeTag(mod) == .Pointer) {
505 const field_size = math.cast(usize, Type.fromInterned(field_ty).abiSize(mod)) orelse506 const field_size = math.cast(usize, Type.fromInterned(field_ty).abiSize(pt)) orelse
506 return error.Overflow;507 return error.Overflow;
507 var tmp_list = try std.ArrayList(u8).initCapacity(code.allocator, field_size);508 var tmp_list = try std.ArrayList(u8).initCapacity(code.allocator, field_size);
508 defer tmp_list.deinit();509 defer tmp_list.deinit();
509 switch (try generateSymbol(bin_file, src_loc, Value.fromInterned(field_val), &tmp_list, debug_output, reloc_info)) {510 switch (try generateSymbol(bin_file, pt, src_loc, Value.fromInterned(field_val), &tmp_list, debug_output, reloc_info)) {
510 .ok => @memcpy(code.items[current_pos..][0..tmp_list.items.len], tmp_list.items),511 .ok => @memcpy(code.items[current_pos..][0..tmp_list.items.len], tmp_list.items),
511 .fail => |em| return Result{ .fail = em },512 .fail => |em| return Result{ .fail = em },
512 }513 }
513 } else {514 } else {
514 Value.fromInterned(field_val).writeToPackedMemory(Type.fromInterned(field_ty), mod, code.items[current_pos..], bits) catch unreachable;515 Value.fromInterned(field_val).writeToPackedMemory(Type.fromInterned(field_ty), pt, code.items[current_pos..], bits) catch unreachable;
515 }516 }
516 bits += @intCast(Type.fromInterned(field_ty).bitSize(mod));517 bits += @intCast(Type.fromInterned(field_ty).bitSize(pt));
517 }518 }
518 },519 },
519 .auto, .@"extern" => {520 .auto, .@"extern" => {
...@@ -524,10 +525,10 @@ pub fn generateSymbol(...@@ -524,10 +525,10 @@ pub fn generateSymbol(
524 var it = struct_type.iterateRuntimeOrder(ip);525 var it = struct_type.iterateRuntimeOrder(ip);
525 while (it.next()) |field_index| {526 while (it.next()) |field_index| {
526 const field_ty = field_types[field_index];527 const field_ty = field_types[field_index];
527 if (!Type.fromInterned(field_ty).hasRuntimeBits(mod)) continue;528 if (!Type.fromInterned(field_ty).hasRuntimeBits(pt)) continue;
528529
529 const field_val = switch (ip.indexToKey(val.toIntern()).aggregate.storage) {530 const field_val = switch (ip.indexToKey(val.toIntern()).aggregate.storage) {
530 .bytes => |bytes| try ip.get(mod.gpa, .{ .int = .{531 .bytes => |bytes| try pt.intern(.{ .int = .{
531 .ty = field_ty,532 .ty = field_ty,
532 .storage = .{ .u64 = bytes.at(field_index, ip) },533 .storage = .{ .u64 = bytes.at(field_index, ip) },
533 } }),534 } }),
...@@ -541,7 +542,7 @@ pub fn generateSymbol(...@@ -541,7 +542,7 @@ pub fn generateSymbol(
541 ) orelse return error.Overflow;542 ) orelse return error.Overflow;
542 if (padding > 0) try code.appendNTimes(0, padding);543 if (padding > 0) try code.appendNTimes(0, padding);
543544
544 switch (try generateSymbol(bin_file, src_loc, Value.fromInterned(field_val), code, debug_output, reloc_info)) {545 switch (try generateSymbol(bin_file, pt, src_loc, Value.fromInterned(field_val), code, debug_output, reloc_info)) {
545 .ok => {},546 .ok => {},
546 .fail => |em| return Result{ .fail = em },547 .fail => |em| return Result{ .fail = em },
547 }548 }
...@@ -562,15 +563,15 @@ pub fn generateSymbol(...@@ -562,15 +563,15 @@ pub fn generateSymbol(
562 else => unreachable,563 else => unreachable,
563 },564 },
564 .un => |un| {565 .un => |un| {
565 const layout = ty.unionGetLayout(mod);566 const layout = ty.unionGetLayout(pt);
566567
567 if (layout.payload_size == 0) {568 if (layout.payload_size == 0) {
568 return generateSymbol(bin_file, src_loc, Value.fromInterned(un.tag), code, debug_output, reloc_info);569 return generateSymbol(bin_file, pt, src_loc, Value.fromInterned(un.tag), code, debug_output, reloc_info);
569 }570 }
570571
571 // Check if we should store the tag first.572 // Check if we should store the tag first.
572 if (layout.tag_size > 0 and layout.tag_align.compare(.gte, layout.payload_align)) {573 if (layout.tag_size > 0 and layout.tag_align.compare(.gte, layout.payload_align)) {
573 switch (try generateSymbol(bin_file, src_loc, Value.fromInterned(un.tag), code, debug_output, reloc_info)) {574 switch (try generateSymbol(bin_file, pt, src_loc, Value.fromInterned(un.tag), code, debug_output, reloc_info)) {
574 .ok => {},575 .ok => {},
575 .fail => |em| return Result{ .fail = em },576 .fail => |em| return Result{ .fail = em },
576 }577 }
...@@ -580,28 +581,28 @@ pub fn generateSymbol(...@@ -580,28 +581,28 @@ pub fn generateSymbol(
580 if (un.tag != .none) {581 if (un.tag != .none) {
581 const field_index = ty.unionTagFieldIndex(Value.fromInterned(un.tag), mod).?;582 const field_index = ty.unionTagFieldIndex(Value.fromInterned(un.tag), mod).?;
582 const field_ty = Type.fromInterned(union_obj.field_types.get(ip)[field_index]);583 const field_ty = Type.fromInterned(union_obj.field_types.get(ip)[field_index]);
583 if (!field_ty.hasRuntimeBits(mod)) {584 if (!field_ty.hasRuntimeBits(pt)) {
584 try code.appendNTimes(0xaa, math.cast(usize, layout.payload_size) orelse return error.Overflow);585 try code.appendNTimes(0xaa, math.cast(usize, layout.payload_size) orelse return error.Overflow);
585 } else {586 } else {
586 switch (try generateSymbol(bin_file, src_loc, Value.fromInterned(un.val), code, debug_output, reloc_info)) {587 switch (try generateSymbol(bin_file, pt, src_loc, Value.fromInterned(un.val), code, debug_output, reloc_info)) {
587 .ok => {},588 .ok => {},
588 .fail => |em| return Result{ .fail = em },589 .fail => |em| return Result{ .fail = em },
589 }590 }
590591
591 const padding = math.cast(usize, layout.payload_size - field_ty.abiSize(mod)) orelse return error.Overflow;592 const padding = math.cast(usize, layout.payload_size - field_ty.abiSize(pt)) orelse return error.Overflow;
592 if (padding > 0) {593 if (padding > 0) {
593 try code.appendNTimes(0, padding);594 try code.appendNTimes(0, padding);
594 }595 }
595 }596 }
596 } else {597 } else {
597 switch (try generateSymbol(bin_file, src_loc, Value.fromInterned(un.val), code, debug_output, reloc_info)) {598 switch (try generateSymbol(bin_file, pt, src_loc, Value.fromInterned(un.val), code, debug_output, reloc_info)) {
598 .ok => {},599 .ok => {},
599 .fail => |em| return Result{ .fail = em },600 .fail => |em| return Result{ .fail = em },
600 }601 }
601 }602 }
602603
603 if (layout.tag_size > 0 and layout.tag_align.compare(.lt, layout.payload_align)) {604 if (layout.tag_size > 0 and layout.tag_align.compare(.lt, layout.payload_align)) {
604 switch (try generateSymbol(bin_file, src_loc, Value.fromInterned(un.tag), code, debug_output, reloc_info)) {605 switch (try generateSymbol(bin_file, pt, src_loc, Value.fromInterned(un.tag), code, debug_output, reloc_info)) {
605 .ok => {},606 .ok => {},
606 .fail => |em| return Result{ .fail = em },607 .fail => |em| return Result{ .fail = em },
607 }608 }
...@@ -618,22 +619,24 @@ pub fn generateSymbol(...@@ -618,22 +619,24 @@ pub fn generateSymbol(
618619
619fn lowerPtr(620fn lowerPtr(
620 bin_file: *link.File,621 bin_file: *link.File,
621 src_loc: Module.LazySrcLoc,622 pt: Zcu.PerThread,
623 src_loc: Zcu.LazySrcLoc,
622 ptr_val: InternPool.Index,624 ptr_val: InternPool.Index,
623 code: *std.ArrayList(u8),625 code: *std.ArrayList(u8),
624 debug_output: DebugInfoOutput,626 debug_output: DebugInfoOutput,
625 reloc_info: RelocInfo,627 reloc_info: RelocInfo,
626 prev_offset: u64,628 prev_offset: u64,
627) CodeGenError!Result {629) CodeGenError!Result {
628 const zcu = bin_file.comp.module.?;630 const zcu = pt.zcu;
629 const ptr = zcu.intern_pool.indexToKey(ptr_val).ptr;631 const ptr = zcu.intern_pool.indexToKey(ptr_val).ptr;
630 const offset: u64 = prev_offset + ptr.byte_offset;632 const offset: u64 = prev_offset + ptr.byte_offset;
631 return switch (ptr.base_addr) {633 return switch (ptr.base_addr) {
632 .decl => |decl| try lowerDeclRef(bin_file, src_loc, decl, code, debug_output, reloc_info, offset),634 .decl => |decl| try lowerDeclRef(bin_file, pt, src_loc, decl, code, debug_output, reloc_info, offset),
633 .anon_decl => |ad| try lowerAnonDeclRef(bin_file, src_loc, ad, code, debug_output, reloc_info, offset),635 .anon_decl => |ad| try lowerAnonDeclRef(bin_file, pt, src_loc, ad, code, debug_output, reloc_info, offset),
634 .int => try generateSymbol(bin_file, src_loc, try zcu.intValue(Type.usize, offset), code, debug_output, reloc_info),636 .int => try generateSymbol(bin_file, pt, src_loc, try pt.intValue(Type.usize, offset), code, debug_output, reloc_info),
635 .eu_payload => |eu_ptr| try lowerPtr(637 .eu_payload => |eu_ptr| try lowerPtr(
636 bin_file,638 bin_file,
639 pt,
637 src_loc,640 src_loc,
638 eu_ptr,641 eu_ptr,
639 code,642 code,
...@@ -641,11 +644,12 @@ fn lowerPtr(...@@ -641,11 +644,12 @@ fn lowerPtr(
641 reloc_info,644 reloc_info,
642 offset + errUnionPayloadOffset(645 offset + errUnionPayloadOffset(
643 Value.fromInterned(eu_ptr).typeOf(zcu).childType(zcu).errorUnionPayload(zcu),646 Value.fromInterned(eu_ptr).typeOf(zcu).childType(zcu).errorUnionPayload(zcu),
644 zcu,647 pt,
645 ),648 ),
646 ),649 ),
647 .opt_payload => |opt_ptr| try lowerPtr(650 .opt_payload => |opt_ptr| try lowerPtr(
648 bin_file,651 bin_file,
652 pt,
649 src_loc,653 src_loc,
650 opt_ptr,654 opt_ptr,
651 code,655 code,
...@@ -666,12 +670,12 @@ fn lowerPtr(...@@ -666,12 +670,12 @@ fn lowerPtr(
666 };670 };
667 },671 },
668 .Struct, .Union => switch (base_ty.containerLayout(zcu)) {672 .Struct, .Union => switch (base_ty.containerLayout(zcu)) {
669 .auto => base_ty.structFieldOffset(@intCast(field.index), zcu),673 .auto => base_ty.structFieldOffset(@intCast(field.index), pt),
670 .@"extern", .@"packed" => unreachable,674 .@"extern", .@"packed" => unreachable,
671 },675 },
672 else => unreachable,676 else => unreachable,
673 };677 };
674 return lowerPtr(bin_file, src_loc, field.base, code, debug_output, reloc_info, offset + field_off);678 return lowerPtr(bin_file, pt, src_loc, field.base, code, debug_output, reloc_info, offset + field_off);
675 },679 },
676 .arr_elem, .comptime_field, .comptime_alloc => unreachable,680 .arr_elem, .comptime_field, .comptime_alloc => unreachable,
677 };681 };
...@@ -683,7 +687,8 @@ const RelocInfo = struct {...@@ -683,7 +687,8 @@ const RelocInfo = struct {
683687
684fn lowerAnonDeclRef(688fn lowerAnonDeclRef(
685 lf: *link.File,689 lf: *link.File,
686 src_loc: Module.LazySrcLoc,690 pt: Zcu.PerThread,
691 src_loc: Zcu.LazySrcLoc,
687 anon_decl: InternPool.Key.Ptr.BaseAddr.AnonDecl,692 anon_decl: InternPool.Key.Ptr.BaseAddr.AnonDecl,
688 code: *std.ArrayList(u8),693 code: *std.ArrayList(u8),
689 debug_output: DebugInfoOutput,694 debug_output: DebugInfoOutput,
...@@ -691,22 +696,21 @@ fn lowerAnonDeclRef(...@@ -691,22 +696,21 @@ fn lowerAnonDeclRef(
691 offset: u64,696 offset: u64,
692) CodeGenError!Result {697) CodeGenError!Result {
693 _ = debug_output;698 _ = debug_output;
694 const zcu = lf.comp.module.?;699 const ip = &pt.zcu.intern_pool;
695 const ip = &zcu.intern_pool;
696 const target = lf.comp.root_mod.resolved_target.result;700 const target = lf.comp.root_mod.resolved_target.result;
697701
698 const ptr_width_bytes = @divExact(target.ptrBitWidth(), 8);702 const ptr_width_bytes = @divExact(target.ptrBitWidth(), 8);
699 const decl_val = anon_decl.val;703 const decl_val = anon_decl.val;
700 const decl_ty = Type.fromInterned(ip.typeOf(decl_val));704 const decl_ty = Type.fromInterned(ip.typeOf(decl_val));
701 log.debug("lowerAnonDecl: ty = {}", .{decl_ty.fmt(zcu)});705 log.debug("lowerAnonDecl: ty = {}", .{decl_ty.fmt(pt)});
702 const is_fn_body = decl_ty.zigTypeTag(zcu) == .Fn;706 const is_fn_body = decl_ty.zigTypeTag(pt.zcu) == .Fn;
703 if (!is_fn_body and !decl_ty.hasRuntimeBits(zcu)) {707 if (!is_fn_body and !decl_ty.hasRuntimeBits(pt)) {
704 try code.appendNTimes(0xaa, ptr_width_bytes);708 try code.appendNTimes(0xaa, ptr_width_bytes);
705 return Result.ok;709 return Result.ok;
706 }710 }
707711
708 const decl_align = ip.indexToKey(anon_decl.orig_ty).ptr_type.flags.alignment;712 const decl_align = ip.indexToKey(anon_decl.orig_ty).ptr_type.flags.alignment;
709 const res = try lf.lowerAnonDecl(decl_val, decl_align, src_loc);713 const res = try lf.lowerAnonDecl(pt, decl_val, decl_align, src_loc);
710 switch (res) {714 switch (res) {
711 .ok => {},715 .ok => {},
712 .fail => |em| return .{ .fail = em },716 .fail => |em| return .{ .fail = em },
...@@ -730,7 +734,8 @@ fn lowerAnonDeclRef(...@@ -730,7 +734,8 @@ fn lowerAnonDeclRef(
730734
731fn lowerDeclRef(735fn lowerDeclRef(
732 lf: *link.File,736 lf: *link.File,
733 src_loc: Module.LazySrcLoc,737 pt: Zcu.PerThread,
738 src_loc: Zcu.LazySrcLoc,
734 decl_index: InternPool.DeclIndex,739 decl_index: InternPool.DeclIndex,
735 code: *std.ArrayList(u8),740 code: *std.ArrayList(u8),
736 debug_output: DebugInfoOutput,741 debug_output: DebugInfoOutput,
...@@ -739,19 +744,19 @@ fn lowerDeclRef(...@@ -739,19 +744,19 @@ fn lowerDeclRef(
739) CodeGenError!Result {744) CodeGenError!Result {
740 _ = src_loc;745 _ = src_loc;
741 _ = debug_output;746 _ = debug_output;
742 const zcu = lf.comp.module.?;747 const zcu = pt.zcu;
743 const decl = zcu.declPtr(decl_index);748 const decl = zcu.declPtr(decl_index);
744 const namespace = zcu.namespacePtr(decl.src_namespace);749 const namespace = zcu.namespacePtr(decl.src_namespace);
745 const target = namespace.fileScope(zcu).mod.resolved_target.result;750 const target = namespace.fileScope(zcu).mod.resolved_target.result;
746751
747 const ptr_width = target.ptrBitWidth();752 const ptr_width = target.ptrBitWidth();
748 const is_fn_body = decl.typeOf(zcu).zigTypeTag(zcu) == .Fn;753 const is_fn_body = decl.typeOf(zcu).zigTypeTag(zcu) == .Fn;
749 if (!is_fn_body and !decl.typeOf(zcu).hasRuntimeBits(zcu)) {754 if (!is_fn_body and !decl.typeOf(zcu).hasRuntimeBits(pt)) {
750 try code.appendNTimes(0xaa, @divExact(ptr_width, 8));755 try code.appendNTimes(0xaa, @divExact(ptr_width, 8));
751 return Result.ok;756 return Result.ok;
752 }757 }
753758
754 const vaddr = try lf.getDeclVAddr(decl_index, .{759 const vaddr = try lf.getDeclVAddr(pt, decl_index, .{
755 .parent_atom_index = reloc_info.parent_atom_index,760 .parent_atom_index = reloc_info.parent_atom_index,
756 .offset = code.items.len,761 .offset = code.items.len,
757 .addend = @intCast(offset),762 .addend = @intCast(offset),
...@@ -814,7 +819,7 @@ pub const GenResult = union(enum) {...@@ -814,7 +819,7 @@ pub const GenResult = union(enum) {
814819
815 fn fail(820 fn fail(
816 gpa: Allocator,821 gpa: Allocator,
817 src_loc: Module.LazySrcLoc,822 src_loc: Zcu.LazySrcLoc,
818 comptime format: []const u8,823 comptime format: []const u8,
819 args: anytype,824 args: anytype,
820 ) Allocator.Error!GenResult {825 ) Allocator.Error!GenResult {
...@@ -825,14 +830,15 @@ pub const GenResult = union(enum) {...@@ -825,14 +830,15 @@ pub const GenResult = union(enum) {
825830
826fn genDeclRef(831fn genDeclRef(
827 lf: *link.File,832 lf: *link.File,
828 src_loc: Module.LazySrcLoc,833 pt: Zcu.PerThread,
834 src_loc: Zcu.LazySrcLoc,
829 val: Value,835 val: Value,
830 ptr_decl_index: InternPool.DeclIndex,836 ptr_decl_index: InternPool.DeclIndex,
831) CodeGenError!GenResult {837) CodeGenError!GenResult {
832 const zcu = lf.comp.module.?;838 const zcu = pt.zcu;
833 const ip = &zcu.intern_pool;839 const ip = &zcu.intern_pool;
834 const ty = val.typeOf(zcu);840 const ty = val.typeOf(zcu);
835 log.debug("genDeclRef: val = {}", .{val.fmtValue(zcu, null)});841 log.debug("genDeclRef: val = {}", .{val.fmtValue(pt, null)});
836842
837 const ptr_decl = zcu.declPtr(ptr_decl_index);843 const ptr_decl = zcu.declPtr(ptr_decl_index);
838 const namespace = zcu.namespacePtr(ptr_decl.src_namespace);844 const namespace = zcu.namespacePtr(ptr_decl.src_namespace);
...@@ -848,7 +854,7 @@ fn genDeclRef(...@@ -848,7 +854,7 @@ fn genDeclRef(
848 };854 };
849 const decl = zcu.declPtr(decl_index);855 const decl = zcu.declPtr(decl_index);
850856
851 if (!decl.typeOf(zcu).isFnOrHasRuntimeBitsIgnoreComptime(zcu)) {857 if (!decl.typeOf(zcu).isFnOrHasRuntimeBitsIgnoreComptime(pt)) {
852 const imm: u64 = switch (ptr_bytes) {858 const imm: u64 = switch (ptr_bytes) {
853 1 => 0xaa,859 1 => 0xaa,
854 2 => 0xaaaa,860 2 => 0xaaaa,
...@@ -865,12 +871,12 @@ fn genDeclRef(...@@ -865,12 +871,12 @@ fn genDeclRef(
865 // TODO this feels clunky. Perhaps we should check for it in `genTypedValue`?871 // TODO this feels clunky. Perhaps we should check for it in `genTypedValue`?
866 if (ty.castPtrToFn(zcu)) |fn_ty| {872 if (ty.castPtrToFn(zcu)) |fn_ty| {
867 if (zcu.typeToFunc(fn_ty).?.is_generic) {873 if (zcu.typeToFunc(fn_ty).?.is_generic) {
868 return GenResult.mcv(.{ .immediate = fn_ty.abiAlignment(zcu).toByteUnits().? });874 return GenResult.mcv(.{ .immediate = fn_ty.abiAlignment(pt).toByteUnits().? });
869 }875 }
870 } else if (ty.zigTypeTag(zcu) == .Pointer) {876 } else if (ty.zigTypeTag(zcu) == .Pointer) {
871 const elem_ty = ty.elemType2(zcu);877 const elem_ty = ty.elemType2(zcu);
872 if (!elem_ty.hasRuntimeBits(zcu)) {878 if (!elem_ty.hasRuntimeBits(pt)) {
873 return GenResult.mcv(.{ .immediate = elem_ty.abiAlignment(zcu).toByteUnits().? });879 return GenResult.mcv(.{ .immediate = elem_ty.abiAlignment(pt).toByteUnits().? });
874 }880 }
875 }881 }
876882
...@@ -931,15 +937,15 @@ fn genDeclRef(...@@ -931,15 +937,15 @@ fn genDeclRef(
931937
932fn genUnnamedConst(938fn genUnnamedConst(
933 lf: *link.File,939 lf: *link.File,
934 src_loc: Module.LazySrcLoc,940 pt: Zcu.PerThread,
941 src_loc: Zcu.LazySrcLoc,
935 val: Value,942 val: Value,
936 owner_decl_index: InternPool.DeclIndex,943 owner_decl_index: InternPool.DeclIndex,
937) CodeGenError!GenResult {944) CodeGenError!GenResult {
938 const zcu = lf.comp.module.?;
939 const gpa = lf.comp.gpa;945 const gpa = lf.comp.gpa;
940 log.debug("genUnnamedConst: val = {}", .{val.fmtValue(zcu, null)});946 log.debug("genUnnamedConst: val = {}", .{val.fmtValue(pt, null)});
941947
942 const local_sym_index = lf.lowerUnnamedConst(val, owner_decl_index) catch |err| {948 const local_sym_index = lf.lowerUnnamedConst(pt, val, owner_decl_index) catch |err| {
943 return GenResult.fail(gpa, src_loc, "lowering unnamed constant failed: {s}", .{@errorName(err)});949 return GenResult.fail(gpa, src_loc, "lowering unnamed constant failed: {s}", .{@errorName(err)});
944 };950 };
945 switch (lf.tag) {951 switch (lf.tag) {
...@@ -970,15 +976,16 @@ fn genUnnamedConst(...@@ -970,15 +976,16 @@ fn genUnnamedConst(
970976
971pub fn genTypedValue(977pub fn genTypedValue(
972 lf: *link.File,978 lf: *link.File,
973 src_loc: Module.LazySrcLoc,979 pt: Zcu.PerThread,
980 src_loc: Zcu.LazySrcLoc,
974 val: Value,981 val: Value,
975 owner_decl_index: InternPool.DeclIndex,982 owner_decl_index: InternPool.DeclIndex,
976) CodeGenError!GenResult {983) CodeGenError!GenResult {
977 const zcu = lf.comp.module.?;984 const zcu = pt.zcu;
978 const ip = &zcu.intern_pool;985 const ip = &zcu.intern_pool;
979 const ty = val.typeOf(zcu);986 const ty = val.typeOf(zcu);
980987
981 log.debug("genTypedValue: val = {}", .{val.fmtValue(zcu, null)});988 log.debug("genTypedValue: val = {}", .{val.fmtValue(pt, null)});
982989
983 if (val.isUndef(zcu))990 if (val.isUndef(zcu))
984 return GenResult.mcv(.undef);991 return GenResult.mcv(.undef);
...@@ -990,7 +997,7 @@ pub fn genTypedValue(...@@ -990,7 +997,7 @@ pub fn genTypedValue(
990997
991 if (!ty.isSlice(zcu)) switch (ip.indexToKey(val.toIntern())) {998 if (!ty.isSlice(zcu)) switch (ip.indexToKey(val.toIntern())) {
992 .ptr => |ptr| if (ptr.byte_offset == 0) switch (ptr.base_addr) {999 .ptr => |ptr| if (ptr.byte_offset == 0) switch (ptr.base_addr) {
993 .decl => |decl| return genDeclRef(lf, src_loc, val, decl),1000 .decl => |decl| return genDeclRef(lf, pt, src_loc, val, decl),
994 else => {},1001 else => {},
995 },1002 },
996 else => {},1003 else => {},
...@@ -1007,7 +1014,7 @@ pub fn genTypedValue(...@@ -1007,7 +1014,7 @@ pub fn genTypedValue(
1007 .none => {},1014 .none => {},
1008 else => switch (ip.indexToKey(val.toIntern())) {1015 else => switch (ip.indexToKey(val.toIntern())) {
1009 .int => {1016 .int => {
1010 return GenResult.mcv(.{ .immediate = val.toUnsignedInt(zcu) });1017 return GenResult.mcv(.{ .immediate = val.toUnsignedInt(pt) });
1011 },1018 },
1012 else => {},1019 else => {},
1013 },1020 },
...@@ -1017,8 +1024,8 @@ pub fn genTypedValue(...@@ -1017,8 +1024,8 @@ pub fn genTypedValue(
1017 const info = ty.intInfo(zcu);1024 const info = ty.intInfo(zcu);
1018 if (info.bits <= ptr_bits) {1025 if (info.bits <= ptr_bits) {
1019 const unsigned: u64 = switch (info.signedness) {1026 const unsigned: u64 = switch (info.signedness) {
1020 .signed => @bitCast(val.toSignedInt(zcu)),1027 .signed => @bitCast(val.toSignedInt(pt)),
1021 .unsigned => val.toUnsignedInt(zcu),1028 .unsigned => val.toUnsignedInt(pt),
1022 };1029 };
1023 return GenResult.mcv(.{ .immediate = unsigned });1030 return GenResult.mcv(.{ .immediate = unsigned });
1024 }1031 }
...@@ -1030,11 +1037,12 @@ pub fn genTypedValue(...@@ -1030,11 +1037,12 @@ pub fn genTypedValue(
1030 if (ty.isPtrLikeOptional(zcu)) {1037 if (ty.isPtrLikeOptional(zcu)) {
1031 return genTypedValue(1038 return genTypedValue(
1032 lf,1039 lf,
1040 pt,
1033 src_loc,1041 src_loc,
1034 val.optionalValue(zcu) orelse return GenResult.mcv(.{ .immediate = 0 }),1042 val.optionalValue(zcu) orelse return GenResult.mcv(.{ .immediate = 0 }),
1035 owner_decl_index,1043 owner_decl_index,
1036 );1044 );
1037 } else if (ty.abiSize(zcu) == 1) {1045 } else if (ty.abiSize(pt) == 1) {
1038 return GenResult.mcv(.{ .immediate = @intFromBool(!val.isNull(zcu)) });1046 return GenResult.mcv(.{ .immediate = @intFromBool(!val.isNull(zcu)) });
1039 }1047 }
1040 },1048 },
...@@ -1042,6 +1050,7 @@ pub fn genTypedValue(...@@ -1042,6 +1050,7 @@ pub fn genTypedValue(
1042 const enum_tag = ip.indexToKey(val.toIntern()).enum_tag;1050 const enum_tag = ip.indexToKey(val.toIntern()).enum_tag;
1043 return genTypedValue(1051 return genTypedValue(
1044 lf,1052 lf,
1053 pt,
1045 src_loc,1054 src_loc,
1046 Value.fromInterned(enum_tag.int),1055 Value.fromInterned(enum_tag.int),
1047 owner_decl_index,1056 owner_decl_index,
...@@ -1055,14 +1064,15 @@ pub fn genTypedValue(...@@ -1055,14 +1064,15 @@ pub fn genTypedValue(
1055 .ErrorUnion => {1064 .ErrorUnion => {
1056 const err_type = ty.errorUnionSet(zcu);1065 const err_type = ty.errorUnionSet(zcu);
1057 const payload_type = ty.errorUnionPayload(zcu);1066 const payload_type = ty.errorUnionPayload(zcu);
1058 if (!payload_type.hasRuntimeBitsIgnoreComptime(zcu)) {1067 if (!payload_type.hasRuntimeBitsIgnoreComptime(pt)) {
1059 // We use the error type directly as the type.1068 // We use the error type directly as the type.
1060 const err_int_ty = try zcu.errorIntType();1069 const err_int_ty = try pt.errorIntType();
1061 switch (ip.indexToKey(val.toIntern()).error_union.val) {1070 switch (ip.indexToKey(val.toIntern()).error_union.val) {
1062 .err_name => |err_name| return genTypedValue(1071 .err_name => |err_name| return genTypedValue(
1063 lf,1072 lf,
1073 pt,
1064 src_loc,1074 src_loc,
1065 Value.fromInterned(try zcu.intern(.{ .err = .{1075 Value.fromInterned(try pt.intern(.{ .err = .{
1066 .ty = err_type.toIntern(),1076 .ty = err_type.toIntern(),
1067 .name = err_name,1077 .name = err_name,
1068 } })),1078 } })),
...@@ -1070,8 +1080,9 @@ pub fn genTypedValue(...@@ -1070,8 +1080,9 @@ pub fn genTypedValue(
1070 ),1080 ),
1071 .payload => return genTypedValue(1081 .payload => return genTypedValue(
1072 lf,1082 lf,
1083 pt,
1073 src_loc,1084 src_loc,
1074 try zcu.intValue(err_int_ty, 0),1085 try pt.intValue(err_int_ty, 0),
1075 owner_decl_index,1086 owner_decl_index,
1076 ),1087 ),
1077 }1088 }
...@@ -1090,26 +1101,26 @@ pub fn genTypedValue(...@@ -1090,26 +1101,26 @@ pub fn genTypedValue(
1090 else => {},1101 else => {},
1091 }1102 }
10921103
1093 return genUnnamedConst(lf, src_loc, val, owner_decl_index);1104 return genUnnamedConst(lf, pt, src_loc, val, owner_decl_index);
1094}1105}
10951106
1096pub fn errUnionPayloadOffset(payload_ty: Type, mod: *Module) u64 {1107pub fn errUnionPayloadOffset(payload_ty: Type, pt: Zcu.PerThread) u64 {
1097 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) return 0;1108 if (!payload_ty.hasRuntimeBitsIgnoreComptime(pt)) return 0;
1098 const payload_align = payload_ty.abiAlignment(mod);1109 const payload_align = payload_ty.abiAlignment(pt);
1099 const error_align = Type.anyerror.abiAlignment(mod);1110 const error_align = Type.anyerror.abiAlignment(pt);
1100 if (payload_align.compare(.gte, error_align) or !payload_ty.hasRuntimeBitsIgnoreComptime(mod)) {1111 if (payload_align.compare(.gte, error_align) or !payload_ty.hasRuntimeBitsIgnoreComptime(pt)) {
1101 return 0;1112 return 0;
1102 } else {1113 } else {
1103 return payload_align.forward(Type.anyerror.abiSize(mod));1114 return payload_align.forward(Type.anyerror.abiSize(pt));
1104 }1115 }
1105}1116}
11061117
1107pub fn errUnionErrorOffset(payload_ty: Type, mod: *Module) u64 {1118pub fn errUnionErrorOffset(payload_ty: Type, pt: Zcu.PerThread) u64 {
1108 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) return 0;1119 if (!payload_ty.hasRuntimeBitsIgnoreComptime(pt)) return 0;
1109 const payload_align = payload_ty.abiAlignment(mod);1120 const payload_align = payload_ty.abiAlignment(pt);
1110 const error_align = Type.anyerror.abiAlignment(mod);1121 const error_align = Type.anyerror.abiAlignment(pt);
1111 if (payload_align.compare(.gte, error_align) and payload_ty.hasRuntimeBitsIgnoreComptime(mod)) {1122 if (payload_align.compare(.gte, error_align) and payload_ty.hasRuntimeBitsIgnoreComptime(pt)) {
1112 return error_align.forward(payload_ty.abiSize(mod));1123 return error_align.forward(payload_ty.abiSize(pt));
1113 } else {1124 } else {
1114 return 0;1125 return 0;
1115 }1126 }
src/codegen/c.zig+408-337
...@@ -333,15 +333,15 @@ pub const Function = struct {...@@ -333,15 +333,15 @@ pub const Function = struct {
333 const gop = try f.value_map.getOrPut(ref);333 const gop = try f.value_map.getOrPut(ref);
334 if (gop.found_existing) return gop.value_ptr.*;334 if (gop.found_existing) return gop.value_ptr.*;
335335
336 const zcu = f.object.dg.zcu;336 const pt = f.object.dg.pt;
337 const val = (try f.air.value(ref, zcu)).?;337 const val = (try f.air.value(ref, pt)).?;
338 const ty = f.typeOf(ref);338 const ty = f.typeOf(ref);
339339
340 const result: CValue = if (lowersToArray(ty, zcu)) result: {340 const result: CValue = if (lowersToArray(ty, pt)) result: {
341 const writer = f.object.codeHeaderWriter();341 const writer = f.object.codeHeaderWriter();
342 const decl_c_value = try f.allocLocalValue(.{342 const decl_c_value = try f.allocLocalValue(.{
343 .ctype = try f.ctypeFromType(ty, .complete),343 .ctype = try f.ctypeFromType(ty, .complete),
344 .alignas = CType.AlignAs.fromAbiAlignment(ty.abiAlignment(zcu)),344 .alignas = CType.AlignAs.fromAbiAlignment(ty.abiAlignment(pt)),
345 });345 });
346 const gpa = f.object.dg.gpa;346 const gpa = f.object.dg.gpa;
347 try f.allocs.put(gpa, decl_c_value.new_local, false);347 try f.allocs.put(gpa, decl_c_value.new_local, false);
...@@ -358,7 +358,7 @@ pub const Function = struct {...@@ -358,7 +358,7 @@ pub const Function = struct {
358 }358 }
359359
360 fn wantSafety(f: *Function) bool {360 fn wantSafety(f: *Function) bool {
361 return switch (f.object.dg.zcu.optimizeMode()) {361 return switch (f.object.dg.pt.zcu.optimizeMode()) {
362 .Debug, .ReleaseSafe => true,362 .Debug, .ReleaseSafe => true,
363 .ReleaseFast, .ReleaseSmall => false,363 .ReleaseFast, .ReleaseSmall => false,
364 };364 };
...@@ -379,7 +379,7 @@ pub const Function = struct {...@@ -379,7 +379,7 @@ pub const Function = struct {
379 fn allocLocal(f: *Function, inst: ?Air.Inst.Index, ty: Type) !CValue {379 fn allocLocal(f: *Function, inst: ?Air.Inst.Index, ty: Type) !CValue {
380 return f.allocAlignedLocal(inst, .{380 return f.allocAlignedLocal(inst, .{
381 .ctype = try f.ctypeFromType(ty, .complete),381 .ctype = try f.ctypeFromType(ty, .complete),
382 .alignas = CType.AlignAs.fromAbiAlignment(ty.abiAlignment(f.object.dg.zcu)),382 .alignas = CType.AlignAs.fromAbiAlignment(ty.abiAlignment(f.object.dg.pt)),
383 });383 });
384 }384 }
385385
...@@ -500,7 +500,8 @@ pub const Function = struct {...@@ -500,7 +500,8 @@ pub const Function = struct {
500500
501 fn getLazyFnName(f: *Function, key: LazyFnKey, data: LazyFnValue.Data) ![]const u8 {501 fn getLazyFnName(f: *Function, key: LazyFnKey, data: LazyFnValue.Data) ![]const u8 {
502 const gpa = f.object.dg.gpa;502 const gpa = f.object.dg.gpa;
503 const zcu = f.object.dg.zcu;503 const pt = f.object.dg.pt;
504 const zcu = pt.zcu;
504 const ctype_pool = &f.object.dg.ctype_pool;505 const ctype_pool = &f.object.dg.ctype_pool;
505506
506 const gop = try f.lazy_fns.getOrPut(gpa, key);507 const gop = try f.lazy_fns.getOrPut(gpa, key);
...@@ -539,13 +540,11 @@ pub const Function = struct {...@@ -539,13 +540,11 @@ pub const Function = struct {
539 }540 }
540541
541 fn typeOf(f: *Function, inst: Air.Inst.Ref) Type {542 fn typeOf(f: *Function, inst: Air.Inst.Ref) Type {
542 const zcu = f.object.dg.zcu;543 return f.air.typeOf(inst, &f.object.dg.pt.zcu.intern_pool);
543 return f.air.typeOf(inst, &zcu.intern_pool);
544 }544 }
545545
546 fn typeOfIndex(f: *Function, inst: Air.Inst.Index) Type {546 fn typeOfIndex(f: *Function, inst: Air.Inst.Index) Type {
547 const zcu = f.object.dg.zcu;547 return f.air.typeOfIndex(inst, &f.object.dg.pt.zcu.intern_pool);
548 return f.air.typeOfIndex(inst, &zcu.intern_pool);
549 }548 }
550549
551 fn copyCValue(f: *Function, ctype: CType, dst: CValue, src: CValue) !void {550 fn copyCValue(f: *Function, ctype: CType, dst: CValue, src: CValue) !void {
...@@ -608,7 +607,7 @@ pub const Object = struct {...@@ -608,7 +607,7 @@ pub const Object = struct {
608/// This data is available both when outputting .c code and when outputting an .h file.607/// This data is available both when outputting .c code and when outputting an .h file.
609pub const DeclGen = struct {608pub const DeclGen = struct {
610 gpa: mem.Allocator,609 gpa: mem.Allocator,
611 zcu: *Zcu,610 pt: Zcu.PerThread,
612 mod: *Module,611 mod: *Module,
613 pass: Pass,612 pass: Pass,
614 is_naked_fn: bool,613 is_naked_fn: bool,
...@@ -634,7 +633,7 @@ pub const DeclGen = struct {...@@ -634,7 +633,7 @@ pub const DeclGen = struct {
634633
635 fn fail(dg: *DeclGen, comptime format: []const u8, args: anytype) error{ AnalysisFail, OutOfMemory } {634 fn fail(dg: *DeclGen, comptime format: []const u8, args: anytype) error{ AnalysisFail, OutOfMemory } {
636 @setCold(true);635 @setCold(true);
637 const zcu = dg.zcu;636 const zcu = dg.pt.zcu;
638 const decl_index = dg.pass.decl;637 const decl_index = dg.pass.decl;
639 const decl = zcu.declPtr(decl_index);638 const decl = zcu.declPtr(decl_index);
640 const src_loc = decl.navSrcLoc(zcu);639 const src_loc = decl.navSrcLoc(zcu);
...@@ -648,7 +647,8 @@ pub const DeclGen = struct {...@@ -648,7 +647,8 @@ pub const DeclGen = struct {
648 anon_decl: InternPool.Key.Ptr.BaseAddr.AnonDecl,647 anon_decl: InternPool.Key.Ptr.BaseAddr.AnonDecl,
649 location: ValueRenderLocation,648 location: ValueRenderLocation,
650 ) error{ OutOfMemory, AnalysisFail }!void {649 ) error{ OutOfMemory, AnalysisFail }!void {
651 const zcu = dg.zcu;650 const pt = dg.pt;
651 const zcu = pt.zcu;
652 const ip = &zcu.intern_pool;652 const ip = &zcu.intern_pool;
653 const ctype_pool = &dg.ctype_pool;653 const ctype_pool = &dg.ctype_pool;
654 const decl_val = Value.fromInterned(anon_decl.val);654 const decl_val = Value.fromInterned(anon_decl.val);
...@@ -656,7 +656,7 @@ pub const DeclGen = struct {...@@ -656,7 +656,7 @@ pub const DeclGen = struct {
656656
657 // Render an undefined pointer if we have a pointer to a zero-bit or comptime type.657 // Render an undefined pointer if we have a pointer to a zero-bit or comptime type.
658 const ptr_ty = Type.fromInterned(anon_decl.orig_ty);658 const ptr_ty = Type.fromInterned(anon_decl.orig_ty);
659 if (ptr_ty.isPtrAtRuntime(zcu) and !decl_ty.isFnOrHasRuntimeBits(zcu)) {659 if (ptr_ty.isPtrAtRuntime(zcu) and !decl_ty.isFnOrHasRuntimeBits(pt)) {
660 return dg.writeCValue(writer, .{ .undef = ptr_ty });660 return dg.writeCValue(writer, .{ .undef = ptr_ty });
661 }661 }
662662
...@@ -696,7 +696,7 @@ pub const DeclGen = struct {...@@ -696,7 +696,7 @@ pub const DeclGen = struct {
696 // alignment. If there is already an entry, keep the greater alignment.696 // alignment. If there is already an entry, keep the greater alignment.
697 const explicit_alignment = ptr_type.flags.alignment;697 const explicit_alignment = ptr_type.flags.alignment;
698 if (explicit_alignment != .none) {698 if (explicit_alignment != .none) {
699 const abi_alignment = Type.fromInterned(ptr_type.child).abiAlignment(zcu);699 const abi_alignment = Type.fromInterned(ptr_type.child).abiAlignment(pt);
700 if (explicit_alignment.order(abi_alignment).compare(.gt)) {700 if (explicit_alignment.order(abi_alignment).compare(.gt)) {
701 const aligned_gop = try dg.aligned_anon_decls.getOrPut(dg.gpa, anon_decl.val);701 const aligned_gop = try dg.aligned_anon_decls.getOrPut(dg.gpa, anon_decl.val);
702 aligned_gop.value_ptr.* = if (aligned_gop.found_existing)702 aligned_gop.value_ptr.* = if (aligned_gop.found_existing)
...@@ -713,15 +713,16 @@ pub const DeclGen = struct {...@@ -713,15 +713,16 @@ pub const DeclGen = struct {
713 decl_index: InternPool.DeclIndex,713 decl_index: InternPool.DeclIndex,
714 location: ValueRenderLocation,714 location: ValueRenderLocation,
715 ) error{ OutOfMemory, AnalysisFail }!void {715 ) error{ OutOfMemory, AnalysisFail }!void {
716 const zcu = dg.zcu;716 const pt = dg.pt;
717 const zcu = pt.zcu;
717 const ctype_pool = &dg.ctype_pool;718 const ctype_pool = &dg.ctype_pool;
718 const decl = zcu.declPtr(decl_index);719 const decl = zcu.declPtr(decl_index);
719 assert(decl.has_tv);720 assert(decl.has_tv);
720721
721 // Render an undefined pointer if we have a pointer to a zero-bit or comptime type.722 // Render an undefined pointer if we have a pointer to a zero-bit or comptime type.
722 const decl_ty = decl.typeOf(zcu);723 const decl_ty = decl.typeOf(zcu);
723 const ptr_ty = try decl.declPtrType(zcu);724 const ptr_ty = try decl.declPtrType(pt);
724 if (!decl_ty.isFnOrHasRuntimeBits(zcu)) {725 if (!decl_ty.isFnOrHasRuntimeBits(pt)) {
725 return dg.writeCValue(writer, .{ .undef = ptr_ty });726 return dg.writeCValue(writer, .{ .undef = ptr_ty });
726 }727 }
727728
...@@ -756,12 +757,13 @@ pub const DeclGen = struct {...@@ -756,12 +757,13 @@ pub const DeclGen = struct {
756 derivation: Value.PointerDeriveStep,757 derivation: Value.PointerDeriveStep,
757 location: ValueRenderLocation,758 location: ValueRenderLocation,
758 ) error{ OutOfMemory, AnalysisFail }!void {759 ) error{ OutOfMemory, AnalysisFail }!void {
759 const zcu = dg.zcu;760 const pt = dg.pt;
761 const zcu = pt.zcu;
760 switch (derivation) {762 switch (derivation) {
761 .comptime_alloc_ptr, .comptime_field_ptr => unreachable,763 .comptime_alloc_ptr, .comptime_field_ptr => unreachable,
762 .int => |int| {764 .int => |int| {
763 const ptr_ctype = try dg.ctypeFromType(int.ptr_ty, .complete);765 const ptr_ctype = try dg.ctypeFromType(int.ptr_ty, .complete);
764 const addr_val = try zcu.intValue(Type.usize, int.addr);766 const addr_val = try pt.intValue(Type.usize, int.addr);
765 try writer.writeByte('(');767 try writer.writeByte('(');
766 try dg.renderCType(writer, ptr_ctype);768 try dg.renderCType(writer, ptr_ctype);
767 try writer.print("){x}", .{try dg.fmtIntLiteral(addr_val, .Other)});769 try writer.print("){x}", .{try dg.fmtIntLiteral(addr_val, .Other)});
...@@ -777,12 +779,12 @@ pub const DeclGen = struct {...@@ -777,12 +779,12 @@ pub const DeclGen = struct {
777 },779 },
778780
779 .field_ptr => |field| {781 .field_ptr => |field| {
780 const parent_ptr_ty = try field.parent.ptrType(zcu);782 const parent_ptr_ty = try field.parent.ptrType(pt);
781783
782 // Ensure complete type definition is available before accessing fields.784 // Ensure complete type definition is available before accessing fields.
783 _ = try dg.ctypeFromType(parent_ptr_ty.childType(zcu), .complete);785 _ = try dg.ctypeFromType(parent_ptr_ty.childType(zcu), .complete);
784786
785 switch (fieldLocation(parent_ptr_ty, field.result_ptr_ty, field.field_idx, zcu)) {787 switch (fieldLocation(parent_ptr_ty, field.result_ptr_ty, field.field_idx, pt)) {
786 .begin => {788 .begin => {
787 const ptr_ctype = try dg.ctypeFromType(field.result_ptr_ty, .complete);789 const ptr_ctype = try dg.ctypeFromType(field.result_ptr_ty, .complete);
788 try writer.writeByte('(');790 try writer.writeByte('(');
...@@ -801,7 +803,7 @@ pub const DeclGen = struct {...@@ -801,7 +803,7 @@ pub const DeclGen = struct {
801 try writer.writeByte('(');803 try writer.writeByte('(');
802 try dg.renderCType(writer, ptr_ctype);804 try dg.renderCType(writer, ptr_ctype);
803 try writer.writeByte(')');805 try writer.writeByte(')');
804 const offset_val = try zcu.intValue(Type.usize, byte_offset);806 const offset_val = try pt.intValue(Type.usize, byte_offset);
805 try writer.writeAll("((char *)");807 try writer.writeAll("((char *)");
806 try dg.renderPointer(writer, field.parent.*, location);808 try dg.renderPointer(writer, field.parent.*, location);
807 try writer.print(" + {})", .{try dg.fmtIntLiteral(offset_val, .Other)});809 try writer.print(" + {})", .{try dg.fmtIntLiteral(offset_val, .Other)});
...@@ -809,7 +811,7 @@ pub const DeclGen = struct {...@@ -809,7 +811,7 @@ pub const DeclGen = struct {
809 }811 }
810 },812 },
811813
812 .elem_ptr => |elem| if (!(try elem.parent.ptrType(zcu)).childType(zcu).hasRuntimeBits(zcu)) {814 .elem_ptr => |elem| if (!(try elem.parent.ptrType(pt)).childType(zcu).hasRuntimeBits(pt)) {
813 // Element type is zero-bit, so lowers to `void`. The index is irrelevant; just cast the pointer.815 // Element type is zero-bit, so lowers to `void`. The index is irrelevant; just cast the pointer.
814 const ptr_ctype = try dg.ctypeFromType(elem.result_ptr_ty, .complete);816 const ptr_ctype = try dg.ctypeFromType(elem.result_ptr_ty, .complete);
815 try writer.writeByte('(');817 try writer.writeByte('(');
...@@ -817,11 +819,11 @@ pub const DeclGen = struct {...@@ -817,11 +819,11 @@ pub const DeclGen = struct {
817 try writer.writeByte(')');819 try writer.writeByte(')');
818 try dg.renderPointer(writer, elem.parent.*, location);820 try dg.renderPointer(writer, elem.parent.*, location);
819 } else {821 } else {
820 const index_val = try zcu.intValue(Type.usize, elem.elem_idx);822 const index_val = try pt.intValue(Type.usize, elem.elem_idx);
821 // We want to do pointer arithmetic on a pointer to the element type.823 // We want to do pointer arithmetic on a pointer to the element type.
822 // We might have a pointer-to-array. In this case, we must cast first.824 // We might have a pointer-to-array. In this case, we must cast first.
823 const result_ctype = try dg.ctypeFromType(elem.result_ptr_ty, .complete);825 const result_ctype = try dg.ctypeFromType(elem.result_ptr_ty, .complete);
824 const parent_ctype = try dg.ctypeFromType(try elem.parent.ptrType(zcu), .complete);826 const parent_ctype = try dg.ctypeFromType(try elem.parent.ptrType(pt), .complete);
825 if (result_ctype.eql(parent_ctype)) {827 if (result_ctype.eql(parent_ctype)) {
826 // The pointer already has an appropriate type - just do the arithmetic.828 // The pointer already has an appropriate type - just do the arithmetic.
827 try writer.writeByte('(');829 try writer.writeByte('(');
...@@ -846,7 +848,7 @@ pub const DeclGen = struct {...@@ -846,7 +848,7 @@ pub const DeclGen = struct {
846 if (oac.byte_offset == 0) {848 if (oac.byte_offset == 0) {
847 try dg.renderPointer(writer, oac.parent.*, location);849 try dg.renderPointer(writer, oac.parent.*, location);
848 } else {850 } else {
849 const offset_val = try zcu.intValue(Type.usize, oac.byte_offset);851 const offset_val = try pt.intValue(Type.usize, oac.byte_offset);
850 try writer.writeAll("((char *)");852 try writer.writeAll("((char *)");
851 try dg.renderPointer(writer, oac.parent.*, location);853 try dg.renderPointer(writer, oac.parent.*, location);
852 try writer.print(" + {})", .{try dg.fmtIntLiteral(offset_val, .Other)});854 try writer.print(" + {})", .{try dg.fmtIntLiteral(offset_val, .Other)});
...@@ -856,8 +858,7 @@ pub const DeclGen = struct {...@@ -856,8 +858,7 @@ pub const DeclGen = struct {
856 }858 }
857859
858 fn renderErrorName(dg: *DeclGen, writer: anytype, err_name: InternPool.NullTerminatedString) !void {860 fn renderErrorName(dg: *DeclGen, writer: anytype, err_name: InternPool.NullTerminatedString) !void {
859 const zcu = dg.zcu;861 const ip = &dg.pt.zcu.intern_pool;
860 const ip = &zcu.intern_pool;
861 try writer.print("zig_error_{}", .{fmtIdent(err_name.toSlice(ip))});862 try writer.print("zig_error_{}", .{fmtIdent(err_name.toSlice(ip))});
862 }863 }
863864
...@@ -867,7 +868,8 @@ pub const DeclGen = struct {...@@ -867,7 +868,8 @@ pub const DeclGen = struct {
867 val: Value,868 val: Value,
868 location: ValueRenderLocation,869 location: ValueRenderLocation,
869 ) error{ OutOfMemory, AnalysisFail }!void {870 ) error{ OutOfMemory, AnalysisFail }!void {
870 const zcu = dg.zcu;871 const pt = dg.pt;
872 const zcu = pt.zcu;
871 const ip = &zcu.intern_pool;873 const ip = &zcu.intern_pool;
872 const target = &dg.mod.resolved_target.result;874 const target = &dg.mod.resolved_target.result;
873 const ctype_pool = &dg.ctype_pool;875 const ctype_pool = &dg.ctype_pool;
...@@ -927,7 +929,7 @@ pub const DeclGen = struct {...@@ -927,7 +929,7 @@ pub const DeclGen = struct {
927 try writer.writeAll("((");929 try writer.writeAll("((");
928 try dg.renderCType(writer, ctype);930 try dg.renderCType(writer, ctype);
929 try writer.print("){x})", .{try dg.fmtIntLiteral(931 try writer.print("){x})", .{try dg.fmtIntLiteral(
930 try zcu.intValue(Type.usize, val.toUnsignedInt(zcu)),932 try pt.intValue(Type.usize, val.toUnsignedInt(pt)),
931 .Other,933 .Other,
932 )});934 )});
933 },935 },
...@@ -974,10 +976,10 @@ pub const DeclGen = struct {...@@ -974,10 +976,10 @@ pub const DeclGen = struct {
974 .enum_tag => |enum_tag| try dg.renderValue(writer, Value.fromInterned(enum_tag.int), location),976 .enum_tag => |enum_tag| try dg.renderValue(writer, Value.fromInterned(enum_tag.int), location),
975 .float => {977 .float => {
976 const bits = ty.floatBits(target.*);978 const bits = ty.floatBits(target.*);
977 const f128_val = val.toFloat(f128, zcu);979 const f128_val = val.toFloat(f128, pt);
978980
979 // All unsigned ints matching float types are pre-allocated.981 // All unsigned ints matching float types are pre-allocated.
980 const repr_ty = zcu.intType(.unsigned, bits) catch unreachable;982 const repr_ty = pt.intType(.unsigned, bits) catch unreachable;
981983
982 assert(bits <= 128);984 assert(bits <= 128);
983 var repr_val_limbs: [BigInt.calcTwosCompLimbCount(128)]BigIntLimb = undefined;985 var repr_val_limbs: [BigInt.calcTwosCompLimbCount(128)]BigIntLimb = undefined;
...@@ -988,10 +990,10 @@ pub const DeclGen = struct {...@@ -988,10 +990,10 @@ pub const DeclGen = struct {
988 };990 };
989991
990 switch (bits) {992 switch (bits) {
991 16 => repr_val_big.set(@as(u16, @bitCast(val.toFloat(f16, zcu)))),993 16 => repr_val_big.set(@as(u16, @bitCast(val.toFloat(f16, pt)))),
992 32 => repr_val_big.set(@as(u32, @bitCast(val.toFloat(f32, zcu)))),994 32 => repr_val_big.set(@as(u32, @bitCast(val.toFloat(f32, pt)))),
993 64 => repr_val_big.set(@as(u64, @bitCast(val.toFloat(f64, zcu)))),995 64 => repr_val_big.set(@as(u64, @bitCast(val.toFloat(f64, pt)))),
994 80 => repr_val_big.set(@as(u80, @bitCast(val.toFloat(f80, zcu)))),996 80 => repr_val_big.set(@as(u80, @bitCast(val.toFloat(f80, pt)))),
995 128 => repr_val_big.set(@as(u128, @bitCast(f128_val))),997 128 => repr_val_big.set(@as(u128, @bitCast(f128_val))),
996 else => unreachable,998 else => unreachable,
997 }999 }
...@@ -1002,10 +1004,10 @@ pub const DeclGen = struct {...@@ -1002,10 +1004,10 @@ pub const DeclGen = struct {
1002 try dg.renderTypeForBuiltinFnName(writer, ty);1004 try dg.renderTypeForBuiltinFnName(writer, ty);
1003 try writer.writeByte('(');1005 try writer.writeByte('(');
1004 switch (bits) {1006 switch (bits) {
1005 16 => try writer.print("{x}", .{val.toFloat(f16, zcu)}),1007 16 => try writer.print("{x}", .{val.toFloat(f16, pt)}),
1006 32 => try writer.print("{x}", .{val.toFloat(f32, zcu)}),1008 32 => try writer.print("{x}", .{val.toFloat(f32, pt)}),
1007 64 => try writer.print("{x}", .{val.toFloat(f64, zcu)}),1009 64 => try writer.print("{x}", .{val.toFloat(f64, pt)}),
1008 80 => try writer.print("{x}", .{val.toFloat(f80, zcu)}),1010 80 => try writer.print("{x}", .{val.toFloat(f80, pt)}),
1009 128 => try writer.print("{x}", .{f128_val}),1011 128 => try writer.print("{x}", .{f128_val}),
1010 else => unreachable,1012 else => unreachable,
1011 }1013 }
...@@ -1045,10 +1047,10 @@ pub const DeclGen = struct {...@@ -1045,10 +1047,10 @@ pub const DeclGen = struct {
1045 if (std.math.isNan(f128_val)) switch (bits) {1047 if (std.math.isNan(f128_val)) switch (bits) {
1046 // We only actually need to pass the significand, but it will get1048 // We only actually need to pass the significand, but it will get
1047 // properly masked anyway, so just pass the whole value.1049 // properly masked anyway, so just pass the whole value.
1048 16 => try writer.print("\"0x{x}\"", .{@as(u16, @bitCast(val.toFloat(f16, zcu)))}),1050 16 => try writer.print("\"0x{x}\"", .{@as(u16, @bitCast(val.toFloat(f16, pt)))}),
1049 32 => try writer.print("\"0x{x}\"", .{@as(u32, @bitCast(val.toFloat(f32, zcu)))}),1051 32 => try writer.print("\"0x{x}\"", .{@as(u32, @bitCast(val.toFloat(f32, pt)))}),
1050 64 => try writer.print("\"0x{x}\"", .{@as(u64, @bitCast(val.toFloat(f64, zcu)))}),1052 64 => try writer.print("\"0x{x}\"", .{@as(u64, @bitCast(val.toFloat(f64, pt)))}),
1051 80 => try writer.print("\"0x{x}\"", .{@as(u80, @bitCast(val.toFloat(f80, zcu)))}),1053 80 => try writer.print("\"0x{x}\"", .{@as(u80, @bitCast(val.toFloat(f80, pt)))}),
1052 128 => try writer.print("\"0x{x}\"", .{@as(u128, @bitCast(f128_val))}),1054 128 => try writer.print("\"0x{x}\"", .{@as(u128, @bitCast(f128_val))}),
1053 else => unreachable,1055 else => unreachable,
1054 };1056 };
...@@ -1056,7 +1058,7 @@ pub const DeclGen = struct {...@@ -1056,7 +1058,7 @@ pub const DeclGen = struct {
1056 empty = false;1058 empty = false;
1057 }1059 }
1058 try writer.print("{x}", .{try dg.fmtIntLiteral(1060 try writer.print("{x}", .{try dg.fmtIntLiteral(
1059 try zcu.intValue_big(repr_ty, repr_val_big.toConst()),1061 try pt.intValue_big(repr_ty, repr_val_big.toConst()),
1060 location,1062 location,
1061 )});1063 )});
1062 if (!empty) try writer.writeByte(')');1064 if (!empty) try writer.writeByte(')');
...@@ -1084,7 +1086,7 @@ pub const DeclGen = struct {...@@ -1084,7 +1086,7 @@ pub const DeclGen = struct {
1084 .ptr => {1086 .ptr => {
1085 var arena = std.heap.ArenaAllocator.init(zcu.gpa);1087 var arena = std.heap.ArenaAllocator.init(zcu.gpa);
1086 defer arena.deinit();1088 defer arena.deinit();
1087 const derivation = try val.pointerDerivation(arena.allocator(), zcu);1089 const derivation = try val.pointerDerivation(arena.allocator(), pt);
1088 try dg.renderPointer(writer, derivation, location);1090 try dg.renderPointer(writer, derivation, location);
1089 },1091 },
1090 .opt => |opt| switch (ctype.info(ctype_pool)) {1092 .opt => |opt| switch (ctype.info(ctype_pool)) {
...@@ -1167,15 +1169,15 @@ pub const DeclGen = struct {...@@ -1167,15 +1169,15 @@ pub const DeclGen = struct {
1167 try literal.start();1169 try literal.start();
1168 var index: usize = 0;1170 var index: usize = 0;
1169 while (index < ai.len) : (index += 1) {1171 while (index < ai.len) : (index += 1) {
1170 const elem_val = try val.elemValue(zcu, index);1172 const elem_val = try val.elemValue(pt, index);
1171 const elem_val_u8: u8 = if (elem_val.isUndef(zcu))1173 const elem_val_u8: u8 = if (elem_val.isUndef(zcu))
1172 undefPattern(u8)1174 undefPattern(u8)
1173 else1175 else
1174 @intCast(elem_val.toUnsignedInt(zcu));1176 @intCast(elem_val.toUnsignedInt(pt));
1175 try literal.writeChar(elem_val_u8);1177 try literal.writeChar(elem_val_u8);
1176 }1178 }
1177 if (ai.sentinel) |s| {1179 if (ai.sentinel) |s| {
1178 const s_u8: u8 = @intCast(s.toUnsignedInt(zcu));1180 const s_u8: u8 = @intCast(s.toUnsignedInt(pt));
1179 if (s_u8 != 0) try literal.writeChar(s_u8);1181 if (s_u8 != 0) try literal.writeChar(s_u8);
1180 }1182 }
1181 try literal.end();1183 try literal.end();
...@@ -1184,7 +1186,7 @@ pub const DeclGen = struct {...@@ -1184,7 +1186,7 @@ pub const DeclGen = struct {
1184 var index: usize = 0;1186 var index: usize = 0;
1185 while (index < ai.len) : (index += 1) {1187 while (index < ai.len) : (index += 1) {
1186 if (index != 0) try writer.writeByte(',');1188 if (index != 0) try writer.writeByte(',');
1187 const elem_val = try val.elemValue(zcu, index);1189 const elem_val = try val.elemValue(pt, index);
1188 try dg.renderValue(writer, elem_val, initializer_type);1190 try dg.renderValue(writer, elem_val, initializer_type);
1189 }1191 }
1190 if (ai.sentinel) |s| {1192 if (ai.sentinel) |s| {
...@@ -1207,13 +1209,13 @@ pub const DeclGen = struct {...@@ -1207,13 +1209,13 @@ pub const DeclGen = struct {
1207 const comptime_val = tuple.values.get(ip)[field_index];1209 const comptime_val = tuple.values.get(ip)[field_index];
1208 if (comptime_val != .none) continue;1210 if (comptime_val != .none) continue;
1209 const field_ty = Type.fromInterned(tuple.types.get(ip)[field_index]);1211 const field_ty = Type.fromInterned(tuple.types.get(ip)[field_index]);
1210 if (!field_ty.hasRuntimeBitsIgnoreComptime(zcu)) continue;1212 if (!field_ty.hasRuntimeBitsIgnoreComptime(pt)) continue;
12111213
1212 if (!empty) try writer.writeByte(',');1214 if (!empty) try writer.writeByte(',');
12131215
1214 const field_val = Value.fromInterned(1216 const field_val = Value.fromInterned(
1215 switch (ip.indexToKey(val.toIntern()).aggregate.storage) {1217 switch (ip.indexToKey(val.toIntern()).aggregate.storage) {
1216 .bytes => |bytes| try ip.get(zcu.gpa, .{ .int = .{1218 .bytes => |bytes| try pt.intern(.{ .int = .{
1217 .ty = field_ty.toIntern(),1219 .ty = field_ty.toIntern(),
1218 .storage = .{ .u64 = bytes.at(field_index, ip) },1220 .storage = .{ .u64 = bytes.at(field_index, ip) },
1219 } }),1221 } }),
...@@ -1242,12 +1244,12 @@ pub const DeclGen = struct {...@@ -1242,12 +1244,12 @@ pub const DeclGen = struct {
1242 var need_comma = false;1244 var need_comma = false;
1243 while (field_it.next()) |field_index| {1245 while (field_it.next()) |field_index| {
1244 const field_ty = Type.fromInterned(loaded_struct.field_types.get(ip)[field_index]);1246 const field_ty = Type.fromInterned(loaded_struct.field_types.get(ip)[field_index]);
1245 if (!field_ty.hasRuntimeBitsIgnoreComptime(zcu)) continue;1247 if (!field_ty.hasRuntimeBitsIgnoreComptime(pt)) continue;
12461248
1247 if (need_comma) try writer.writeByte(',');1249 if (need_comma) try writer.writeByte(',');
1248 need_comma = true;1250 need_comma = true;
1249 const field_val = switch (ip.indexToKey(val.toIntern()).aggregate.storage) {1251 const field_val = switch (ip.indexToKey(val.toIntern()).aggregate.storage) {
1250 .bytes => |bytes| try ip.get(zcu.gpa, .{ .int = .{1252 .bytes => |bytes| try pt.intern(.{ .int = .{
1251 .ty = field_ty.toIntern(),1253 .ty = field_ty.toIntern(),
1252 .storage = .{ .u64 = bytes.at(field_index, ip) },1254 .storage = .{ .u64 = bytes.at(field_index, ip) },
1253 } }),1255 } }),
...@@ -1262,14 +1264,14 @@ pub const DeclGen = struct {...@@ -1262,14 +1264,14 @@ pub const DeclGen = struct {
1262 const int_info = ty.intInfo(zcu);1264 const int_info = ty.intInfo(zcu);
12631265
1264 const bits = Type.smallestUnsignedBits(int_info.bits - 1);1266 const bits = Type.smallestUnsignedBits(int_info.bits - 1);
1265 const bit_offset_ty = try zcu.intType(.unsigned, bits);1267 const bit_offset_ty = try pt.intType(.unsigned, bits);
12661268
1267 var bit_offset: u64 = 0;1269 var bit_offset: u64 = 0;
1268 var eff_num_fields: usize = 0;1270 var eff_num_fields: usize = 0;
12691271
1270 for (0..loaded_struct.field_types.len) |field_index| {1272 for (0..loaded_struct.field_types.len) |field_index| {
1271 const field_ty = Type.fromInterned(loaded_struct.field_types.get(ip)[field_index]);1273 const field_ty = Type.fromInterned(loaded_struct.field_types.get(ip)[field_index]);
1272 if (!field_ty.hasRuntimeBitsIgnoreComptime(zcu)) continue;1274 if (!field_ty.hasRuntimeBitsIgnoreComptime(pt)) continue;
1273 eff_num_fields += 1;1275 eff_num_fields += 1;
1274 }1276 }
12751277
...@@ -1277,7 +1279,7 @@ pub const DeclGen = struct {...@@ -1277,7 +1279,7 @@ pub const DeclGen = struct {
1277 try writer.writeByte('(');1279 try writer.writeByte('(');
1278 try dg.renderUndefValue(writer, ty, location);1280 try dg.renderUndefValue(writer, ty, location);
1279 try writer.writeByte(')');1281 try writer.writeByte(')');
1280 } else if (ty.bitSize(zcu) > 64) {1282 } else if (ty.bitSize(pt) > 64) {
1281 // zig_or_u128(zig_or_u128(zig_shl_u128(a, a_off), zig_shl_u128(b, b_off)), zig_shl_u128(c, c_off))1283 // zig_or_u128(zig_or_u128(zig_shl_u128(a, a_off), zig_shl_u128(b, b_off)), zig_shl_u128(c, c_off))
1282 var num_or = eff_num_fields - 1;1284 var num_or = eff_num_fields - 1;
1283 while (num_or > 0) : (num_or -= 1) {1285 while (num_or > 0) : (num_or -= 1) {
...@@ -1290,10 +1292,10 @@ pub const DeclGen = struct {...@@ -1290,10 +1292,10 @@ pub const DeclGen = struct {
1290 var needs_closing_paren = false;1292 var needs_closing_paren = false;
1291 for (0..loaded_struct.field_types.len) |field_index| {1293 for (0..loaded_struct.field_types.len) |field_index| {
1292 const field_ty = Type.fromInterned(loaded_struct.field_types.get(ip)[field_index]);1294 const field_ty = Type.fromInterned(loaded_struct.field_types.get(ip)[field_index]);
1293 if (!field_ty.hasRuntimeBitsIgnoreComptime(zcu)) continue;1295 if (!field_ty.hasRuntimeBitsIgnoreComptime(pt)) continue;
12941296
1295 const field_val = switch (ip.indexToKey(val.toIntern()).aggregate.storage) {1297 const field_val = switch (ip.indexToKey(val.toIntern()).aggregate.storage) {
1296 .bytes => |bytes| try ip.get(zcu.gpa, .{ .int = .{1298 .bytes => |bytes| try pt.intern(.{ .int = .{
1297 .ty = field_ty.toIntern(),1299 .ty = field_ty.toIntern(),
1298 .storage = .{ .u64 = bytes.at(field_index, ip) },1300 .storage = .{ .u64 = bytes.at(field_index, ip) },
1299 } }),1301 } }),
...@@ -1307,7 +1309,7 @@ pub const DeclGen = struct {...@@ -1307,7 +1309,7 @@ pub const DeclGen = struct {
1307 try writer.writeByte('(');1309 try writer.writeByte('(');
1308 try dg.renderIntCast(writer, ty, cast_context, field_ty, .FunctionArgument);1310 try dg.renderIntCast(writer, ty, cast_context, field_ty, .FunctionArgument);
1309 try writer.writeAll(", ");1311 try writer.writeAll(", ");
1310 try dg.renderValue(writer, try zcu.intValue(bit_offset_ty, bit_offset), .FunctionArgument);1312 try dg.renderValue(writer, try pt.intValue(bit_offset_ty, bit_offset), .FunctionArgument);
1311 try writer.writeByte(')');1313 try writer.writeByte(')');
1312 } else {1314 } else {
1313 try dg.renderIntCast(writer, ty, cast_context, field_ty, .FunctionArgument);1315 try dg.renderIntCast(writer, ty, cast_context, field_ty, .FunctionArgument);
...@@ -1316,7 +1318,7 @@ pub const DeclGen = struct {...@@ -1316,7 +1318,7 @@ pub const DeclGen = struct {
1316 if (needs_closing_paren) try writer.writeByte(')');1318 if (needs_closing_paren) try writer.writeByte(')');
1317 if (eff_index != eff_num_fields - 1) try writer.writeAll(", ");1319 if (eff_index != eff_num_fields - 1) try writer.writeAll(", ");
13181320
1319 bit_offset += field_ty.bitSize(zcu);1321 bit_offset += field_ty.bitSize(pt);
1320 needs_closing_paren = true;1322 needs_closing_paren = true;
1321 eff_index += 1;1323 eff_index += 1;
1322 }1324 }
...@@ -1326,7 +1328,7 @@ pub const DeclGen = struct {...@@ -1326,7 +1328,7 @@ pub const DeclGen = struct {
1326 var empty = true;1328 var empty = true;
1327 for (0..loaded_struct.field_types.len) |field_index| {1329 for (0..loaded_struct.field_types.len) |field_index| {
1328 const field_ty = Type.fromInterned(loaded_struct.field_types.get(ip)[field_index]);1330 const field_ty = Type.fromInterned(loaded_struct.field_types.get(ip)[field_index]);
1329 if (!field_ty.hasRuntimeBitsIgnoreComptime(zcu)) continue;1331 if (!field_ty.hasRuntimeBitsIgnoreComptime(pt)) continue;
13301332
1331 if (!empty) try writer.writeAll(" | ");1333 if (!empty) try writer.writeAll(" | ");
1332 try writer.writeByte('(');1334 try writer.writeByte('(');
...@@ -1334,7 +1336,7 @@ pub const DeclGen = struct {...@@ -1334,7 +1336,7 @@ pub const DeclGen = struct {
1334 try writer.writeByte(')');1336 try writer.writeByte(')');
13351337
1336 const field_val = switch (ip.indexToKey(val.toIntern()).aggregate.storage) {1338 const field_val = switch (ip.indexToKey(val.toIntern()).aggregate.storage) {
1337 .bytes => |bytes| try ip.get(zcu.gpa, .{ .int = .{1339 .bytes => |bytes| try pt.intern(.{ .int = .{
1338 .ty = field_ty.toIntern(),1340 .ty = field_ty.toIntern(),
1339 .storage = .{ .u64 = bytes.at(field_index, ip) },1341 .storage = .{ .u64 = bytes.at(field_index, ip) },
1340 } }),1342 } }),
...@@ -1345,12 +1347,12 @@ pub const DeclGen = struct {...@@ -1345,12 +1347,12 @@ pub const DeclGen = struct {
1345 if (bit_offset != 0) {1347 if (bit_offset != 0) {
1346 try dg.renderValue(writer, Value.fromInterned(field_val), .Other);1348 try dg.renderValue(writer, Value.fromInterned(field_val), .Other);
1347 try writer.writeAll(" << ");1349 try writer.writeAll(" << ");
1348 try dg.renderValue(writer, try zcu.intValue(bit_offset_ty, bit_offset), .FunctionArgument);1350 try dg.renderValue(writer, try pt.intValue(bit_offset_ty, bit_offset), .FunctionArgument);
1349 } else {1351 } else {
1350 try dg.renderValue(writer, Value.fromInterned(field_val), .Other);1352 try dg.renderValue(writer, Value.fromInterned(field_val), .Other);
1351 }1353 }
13521354
1353 bit_offset += field_ty.bitSize(zcu);1355 bit_offset += field_ty.bitSize(pt);
1354 empty = false;1356 empty = false;
1355 }1357 }
1356 try writer.writeByte(')');1358 try writer.writeByte(')');
...@@ -1363,7 +1365,7 @@ pub const DeclGen = struct {...@@ -1363,7 +1365,7 @@ pub const DeclGen = struct {
1363 .un => |un| {1365 .un => |un| {
1364 const loaded_union = ip.loadUnionType(ty.toIntern());1366 const loaded_union = ip.loadUnionType(ty.toIntern());
1365 if (un.tag == .none) {1367 if (un.tag == .none) {
1366 const backing_ty = try ty.unionBackingType(zcu);1368 const backing_ty = try ty.unionBackingType(pt);
1367 switch (loaded_union.getLayout(ip)) {1369 switch (loaded_union.getLayout(ip)) {
1368 .@"packed" => {1370 .@"packed" => {
1369 if (!location.isInitializer()) {1371 if (!location.isInitializer()) {
...@@ -1378,7 +1380,7 @@ pub const DeclGen = struct {...@@ -1378,7 +1380,7 @@ pub const DeclGen = struct {
1378 return dg.fail("TODO: C backend: implement extern union backing type rendering in static initializers", .{});1380 return dg.fail("TODO: C backend: implement extern union backing type rendering in static initializers", .{});
1379 }1381 }
13801382
1381 const ptr_ty = try zcu.singleConstPtrType(ty);1383 const ptr_ty = try pt.singleConstPtrType(ty);
1382 try writer.writeAll("*((");1384 try writer.writeAll("*((");
1383 try dg.renderType(writer, ptr_ty);1385 try dg.renderType(writer, ptr_ty);
1384 try writer.writeAll(")(");1386 try writer.writeAll(")(");
...@@ -1400,7 +1402,7 @@ pub const DeclGen = struct {...@@ -1400,7 +1402,7 @@ pub const DeclGen = struct {
1400 const field_ty = Type.fromInterned(loaded_union.field_types.get(ip)[field_index]);1402 const field_ty = Type.fromInterned(loaded_union.field_types.get(ip)[field_index]);
1401 const field_name = loaded_union.loadTagType(ip).names.get(ip)[field_index];1403 const field_name = loaded_union.loadTagType(ip).names.get(ip)[field_index];
1402 if (loaded_union.getLayout(ip) == .@"packed") {1404 if (loaded_union.getLayout(ip) == .@"packed") {
1403 if (field_ty.hasRuntimeBits(zcu)) {1405 if (field_ty.hasRuntimeBits(pt)) {
1404 if (field_ty.isPtrAtRuntime(zcu)) {1406 if (field_ty.isPtrAtRuntime(zcu)) {
1405 try writer.writeByte('(');1407 try writer.writeByte('(');
1406 try dg.renderCType(writer, ctype);1408 try dg.renderCType(writer, ctype);
...@@ -1431,7 +1433,7 @@ pub const DeclGen = struct {...@@ -1431,7 +1433,7 @@ pub const DeclGen = struct {
1431 ),1433 ),
1432 .payload => {1434 .payload => {
1433 try writer.writeByte('{');1435 try writer.writeByte('{');
1434 if (field_ty.hasRuntimeBits(zcu)) {1436 if (field_ty.hasRuntimeBits(pt)) {
1435 try writer.print(" .{ } = ", .{fmtIdent(field_name.toSlice(ip))});1437 try writer.print(" .{ } = ", .{fmtIdent(field_name.toSlice(ip))});
1436 try dg.renderValue(1438 try dg.renderValue(
1437 writer,1439 writer,
...@@ -1443,7 +1445,7 @@ pub const DeclGen = struct {...@@ -1443,7 +1445,7 @@ pub const DeclGen = struct {
1443 const inner_field_ty = Type.fromInterned(1445 const inner_field_ty = Type.fromInterned(
1444 loaded_union.field_types.get(ip)[inner_field_index],1446 loaded_union.field_types.get(ip)[inner_field_index],
1445 );1447 );
1446 if (!inner_field_ty.hasRuntimeBits(zcu)) continue;1448 if (!inner_field_ty.hasRuntimeBits(pt)) continue;
1447 try dg.renderUndefValue(writer, inner_field_ty, initializer_type);1449 try dg.renderUndefValue(writer, inner_field_ty, initializer_type);
1448 break;1450 break;
1449 }1451 }
...@@ -1464,7 +1466,8 @@ pub const DeclGen = struct {...@@ -1464,7 +1466,8 @@ pub const DeclGen = struct {
1464 ty: Type,1466 ty: Type,
1465 location: ValueRenderLocation,1467 location: ValueRenderLocation,
1466 ) error{ OutOfMemory, AnalysisFail }!void {1468 ) error{ OutOfMemory, AnalysisFail }!void {
1467 const zcu = dg.zcu;1469 const pt = dg.pt;
1470 const zcu = pt.zcu;
1468 const ip = &zcu.intern_pool;1471 const ip = &zcu.intern_pool;
1469 const target = &dg.mod.resolved_target.result;1472 const target = &dg.mod.resolved_target.result;
1470 const ctype_pool = &dg.ctype_pool;1473 const ctype_pool = &dg.ctype_pool;
...@@ -1490,7 +1493,7 @@ pub const DeclGen = struct {...@@ -1490,7 +1493,7 @@ pub const DeclGen = struct {
1490 => {1493 => {
1491 const bits = ty.floatBits(target.*);1494 const bits = ty.floatBits(target.*);
1492 // All unsigned ints matching float types are pre-allocated.1495 // All unsigned ints matching float types are pre-allocated.
1493 const repr_ty = zcu.intType(.unsigned, bits) catch unreachable;1496 const repr_ty = dg.pt.intType(.unsigned, bits) catch unreachable;
14941497
1495 try writer.writeAll("zig_make_");1498 try writer.writeAll("zig_make_");
1496 try dg.renderTypeForBuiltinFnName(writer, ty);1499 try dg.renderTypeForBuiltinFnName(writer, ty);
...@@ -1515,14 +1518,14 @@ pub const DeclGen = struct {...@@ -1515,14 +1518,14 @@ pub const DeclGen = struct {
1515 .error_set_type,1518 .error_set_type,
1516 .inferred_error_set_type,1519 .inferred_error_set_type,
1517 => return writer.print("{x}", .{1520 => return writer.print("{x}", .{
1518 try dg.fmtIntLiteral(try zcu.undefValue(ty), location),1521 try dg.fmtIntLiteral(try pt.undefValue(ty), location),
1519 }),1522 }),
1520 .ptr_type => |ptr_type| switch (ptr_type.flags.size) {1523 .ptr_type => |ptr_type| switch (ptr_type.flags.size) {
1521 .One, .Many, .C => {1524 .One, .Many, .C => {
1522 try writer.writeAll("((");1525 try writer.writeAll("((");
1523 try dg.renderCType(writer, ctype);1526 try dg.renderCType(writer, ctype);
1524 return writer.print("){x})", .{1527 return writer.print("){x})", .{
1525 try dg.fmtIntLiteral(try zcu.undefValue(Type.usize), .Other),1528 try dg.fmtIntLiteral(try pt.undefValue(Type.usize), .Other),
1526 });1529 });
1527 },1530 },
1528 .Slice => {1531 .Slice => {
...@@ -1536,7 +1539,7 @@ pub const DeclGen = struct {...@@ -1536,7 +1539,7 @@ pub const DeclGen = struct {
1536 const ptr_ty = ty.slicePtrFieldType(zcu);1539 const ptr_ty = ty.slicePtrFieldType(zcu);
1537 try dg.renderType(writer, ptr_ty);1540 try dg.renderType(writer, ptr_ty);
1538 return writer.print("){x}, {0x}}}", .{1541 return writer.print("){x}, {0x}}}", .{
1539 try dg.fmtIntLiteral(try zcu.undefValue(Type.usize), .Other),1542 try dg.fmtIntLiteral(try dg.pt.undefValue(Type.usize), .Other),
1540 });1543 });
1541 },1544 },
1542 },1545 },
...@@ -1591,7 +1594,7 @@ pub const DeclGen = struct {...@@ -1591,7 +1594,7 @@ pub const DeclGen = struct {
1591 var need_comma = false;1594 var need_comma = false;
1592 while (field_it.next()) |field_index| {1595 while (field_it.next()) |field_index| {
1593 const field_ty = Type.fromInterned(loaded_struct.field_types.get(ip)[field_index]);1596 const field_ty = Type.fromInterned(loaded_struct.field_types.get(ip)[field_index]);
1594 if (!field_ty.hasRuntimeBitsIgnoreComptime(zcu)) continue;1597 if (!field_ty.hasRuntimeBitsIgnoreComptime(pt)) continue;
15951598
1596 if (need_comma) try writer.writeByte(',');1599 if (need_comma) try writer.writeByte(',');
1597 need_comma = true;1600 need_comma = true;
...@@ -1600,7 +1603,7 @@ pub const DeclGen = struct {...@@ -1600,7 +1603,7 @@ pub const DeclGen = struct {
1600 return writer.writeByte('}');1603 return writer.writeByte('}');
1601 },1604 },
1602 .@"packed" => return writer.print("{x}", .{1605 .@"packed" => return writer.print("{x}", .{
1603 try dg.fmtIntLiteral(try zcu.undefValue(ty), .Other),1606 try dg.fmtIntLiteral(try pt.undefValue(ty), .Other),
1604 }),1607 }),
1605 }1608 }
1606 },1609 },
...@@ -1616,7 +1619,7 @@ pub const DeclGen = struct {...@@ -1616,7 +1619,7 @@ pub const DeclGen = struct {
1616 for (0..anon_struct_info.types.len) |field_index| {1619 for (0..anon_struct_info.types.len) |field_index| {
1617 if (anon_struct_info.values.get(ip)[field_index] != .none) continue;1620 if (anon_struct_info.values.get(ip)[field_index] != .none) continue;
1618 const field_ty = Type.fromInterned(anon_struct_info.types.get(ip)[field_index]);1621 const field_ty = Type.fromInterned(anon_struct_info.types.get(ip)[field_index]);
1619 if (!field_ty.hasRuntimeBitsIgnoreComptime(zcu)) continue;1622 if (!field_ty.hasRuntimeBitsIgnoreComptime(pt)) continue;
16201623
1621 if (need_comma) try writer.writeByte(',');1624 if (need_comma) try writer.writeByte(',');
1622 need_comma = true;1625 need_comma = true;
...@@ -1654,7 +1657,7 @@ pub const DeclGen = struct {...@@ -1654,7 +1657,7 @@ pub const DeclGen = struct {
1654 const inner_field_ty = Type.fromInterned(1657 const inner_field_ty = Type.fromInterned(
1655 loaded_union.field_types.get(ip)[inner_field_index],1658 loaded_union.field_types.get(ip)[inner_field_index],
1656 );1659 );
1657 if (!inner_field_ty.hasRuntimeBits(zcu)) continue;1660 if (!inner_field_ty.hasRuntimeBits(pt)) continue;
1658 try dg.renderUndefValue(1661 try dg.renderUndefValue(
1659 writer,1662 writer,
1660 inner_field_ty,1663 inner_field_ty,
...@@ -1670,7 +1673,7 @@ pub const DeclGen = struct {...@@ -1670,7 +1673,7 @@ pub const DeclGen = struct {
1670 if (has_tag) try writer.writeByte('}');1673 if (has_tag) try writer.writeByte('}');
1671 },1674 },
1672 .@"packed" => return writer.print("{x}", .{1675 .@"packed" => return writer.print("{x}", .{
1673 try dg.fmtIntLiteral(try zcu.undefValue(ty), .Other),1676 try dg.fmtIntLiteral(try pt.undefValue(ty), .Other),
1674 }),1677 }),
1675 }1678 }
1676 },1679 },
...@@ -1775,7 +1778,7 @@ pub const DeclGen = struct {...@@ -1775,7 +1778,7 @@ pub const DeclGen = struct {
1775 },1778 },
1776 },1779 },
1777 ) !void {1780 ) !void {
1778 const zcu = dg.zcu;1781 const zcu = dg.pt.zcu;
1779 const ip = &zcu.intern_pool;1782 const ip = &zcu.intern_pool;
17801783
1781 const fn_ty = fn_val.typeOf(zcu);1784 const fn_ty = fn_val.typeOf(zcu);
...@@ -1856,7 +1859,7 @@ pub const DeclGen = struct {...@@ -1856,7 +1859,7 @@ pub const DeclGen = struct {
18561859
1857 fn ctypeFromType(dg: *DeclGen, ty: Type, kind: CType.Kind) !CType {1860 fn ctypeFromType(dg: *DeclGen, ty: Type, kind: CType.Kind) !CType {
1858 defer std.debug.assert(dg.scratch.items.len == 0);1861 defer std.debug.assert(dg.scratch.items.len == 0);
1859 return dg.ctype_pool.fromType(dg.gpa, &dg.scratch, ty, dg.zcu, dg.mod, kind);1862 return dg.ctype_pool.fromType(dg.gpa, &dg.scratch, ty, dg.pt, dg.mod, kind);
1860 }1863 }
18611864
1862 fn byteSize(dg: *DeclGen, ctype: CType) u64 {1865 fn byteSize(dg: *DeclGen, ctype: CType) u64 {
...@@ -1879,8 +1882,8 @@ pub const DeclGen = struct {...@@ -1879,8 +1882,8 @@ pub const DeclGen = struct {
1879 }1882 }
18801883
1881 fn renderCType(dg: *DeclGen, w: anytype, ctype: CType) error{OutOfMemory}!void {1884 fn renderCType(dg: *DeclGen, w: anytype, ctype: CType) error{OutOfMemory}!void {
1882 _ = try renderTypePrefix(dg.pass, &dg.ctype_pool, dg.zcu, w, ctype, .suffix, .{});1885 _ = try renderTypePrefix(dg.pass, &dg.ctype_pool, dg.pt.zcu, w, ctype, .suffix, .{});
1883 try renderTypeSuffix(dg.pass, &dg.ctype_pool, dg.zcu, w, ctype, .suffix, .{});1886 try renderTypeSuffix(dg.pass, &dg.ctype_pool, dg.pt.zcu, w, ctype, .suffix, .{});
1884 }1887 }
18851888
1886 const IntCastContext = union(enum) {1889 const IntCastContext = union(enum) {
...@@ -1904,18 +1907,18 @@ pub const DeclGen = struct {...@@ -1904,18 +1907,18 @@ pub const DeclGen = struct {
1904 }1907 }
1905 };1908 };
1906 fn intCastIsNoop(dg: *DeclGen, dest_ty: Type, src_ty: Type) bool {1909 fn intCastIsNoop(dg: *DeclGen, dest_ty: Type, src_ty: Type) bool {
1907 const zcu = dg.zcu;1910 const pt = dg.pt;
1908 const dest_bits = dest_ty.bitSize(zcu);1911 const dest_bits = dest_ty.bitSize(pt);
1909 const dest_int_info = dest_ty.intInfo(zcu);1912 const dest_int_info = dest_ty.intInfo(pt.zcu);
19101913
1911 const src_is_ptr = src_ty.isPtrAtRuntime(zcu);1914 const src_is_ptr = src_ty.isPtrAtRuntime(pt.zcu);
1912 const src_eff_ty: Type = if (src_is_ptr) switch (dest_int_info.signedness) {1915 const src_eff_ty: Type = if (src_is_ptr) switch (dest_int_info.signedness) {
1913 .unsigned => Type.usize,1916 .unsigned => Type.usize,
1914 .signed => Type.isize,1917 .signed => Type.isize,
1915 } else src_ty;1918 } else src_ty;
19161919
1917 const src_bits = src_eff_ty.bitSize(zcu);1920 const src_bits = src_eff_ty.bitSize(pt);
1918 const src_int_info = if (src_eff_ty.isAbiInt(zcu)) src_eff_ty.intInfo(zcu) else null;1921 const src_int_info = if (src_eff_ty.isAbiInt(pt.zcu)) src_eff_ty.intInfo(pt.zcu) else null;
1919 if (dest_bits <= 64 and src_bits <= 64) {1922 if (dest_bits <= 64 and src_bits <= 64) {
1920 const needs_cast = src_int_info == null or1923 const needs_cast = src_int_info == null or
1921 (toCIntBits(dest_int_info.bits) != toCIntBits(src_int_info.?.bits) or1924 (toCIntBits(dest_int_info.bits) != toCIntBits(src_int_info.?.bits) or
...@@ -1944,8 +1947,9 @@ pub const DeclGen = struct {...@@ -1944,8 +1947,9 @@ pub const DeclGen = struct {
1944 src_ty: Type,1947 src_ty: Type,
1945 location: ValueRenderLocation,1948 location: ValueRenderLocation,
1946 ) !void {1949 ) !void {
1947 const zcu = dg.zcu;1950 const pt = dg.pt;
1948 const dest_bits = dest_ty.bitSize(zcu);1951 const zcu = pt.zcu;
1952 const dest_bits = dest_ty.bitSize(pt);
1949 const dest_int_info = dest_ty.intInfo(zcu);1953 const dest_int_info = dest_ty.intInfo(zcu);
19501954
1951 const src_is_ptr = src_ty.isPtrAtRuntime(zcu);1955 const src_is_ptr = src_ty.isPtrAtRuntime(zcu);
...@@ -1954,7 +1958,7 @@ pub const DeclGen = struct {...@@ -1954,7 +1958,7 @@ pub const DeclGen = struct {
1954 .signed => Type.isize,1958 .signed => Type.isize,
1955 } else src_ty;1959 } else src_ty;
19561960
1957 const src_bits = src_eff_ty.bitSize(zcu);1961 const src_bits = src_eff_ty.bitSize(pt);
1958 const src_int_info = if (src_eff_ty.isAbiInt(zcu)) src_eff_ty.intInfo(zcu) else null;1962 const src_int_info = if (src_eff_ty.isAbiInt(zcu)) src_eff_ty.intInfo(zcu) else null;
1959 if (dest_bits <= 64 and src_bits <= 64) {1963 if (dest_bits <= 64 and src_bits <= 64) {
1960 const needs_cast = src_int_info == null or1964 const needs_cast = src_int_info == null or
...@@ -2035,7 +2039,7 @@ pub const DeclGen = struct {...@@ -2035,7 +2039,7 @@ pub const DeclGen = struct {
2035 qualifiers,2039 qualifiers,
2036 CType.AlignAs.fromAlignment(.{2040 CType.AlignAs.fromAlignment(.{
2037 .@"align" = alignment,2041 .@"align" = alignment,
2038 .abi = ty.abiAlignment(dg.zcu),2042 .abi = ty.abiAlignment(dg.pt),
2039 }),2043 }),
2040 );2044 );
2041 }2045 }
...@@ -2048,6 +2052,7 @@ pub const DeclGen = struct {...@@ -2048,6 +2052,7 @@ pub const DeclGen = struct {
2048 qualifiers: CQualifiers,2052 qualifiers: CQualifiers,
2049 alignas: CType.AlignAs,2053 alignas: CType.AlignAs,
2050 ) error{ OutOfMemory, AnalysisFail }!void {2054 ) error{ OutOfMemory, AnalysisFail }!void {
2055 const zcu = dg.pt.zcu;
2051 switch (alignas.abiOrder()) {2056 switch (alignas.abiOrder()) {
2052 .lt => try w.print("zig_under_align({}) ", .{alignas.toByteUnits()}),2057 .lt => try w.print("zig_under_align({}) ", .{alignas.toByteUnits()}),
2053 .eq => {},2058 .eq => {},
...@@ -2055,10 +2060,10 @@ pub const DeclGen = struct {...@@ -2055,10 +2060,10 @@ pub const DeclGen = struct {
2055 }2060 }
20562061
2057 try w.print("{}", .{2062 try w.print("{}", .{
2058 try renderTypePrefix(dg.pass, &dg.ctype_pool, dg.zcu, w, ctype, .suffix, qualifiers),2063 try renderTypePrefix(dg.pass, &dg.ctype_pool, zcu, w, ctype, .suffix, qualifiers),
2059 });2064 });
2060 try dg.writeName(w, name);2065 try dg.writeName(w, name);
2061 try renderTypeSuffix(dg.pass, &dg.ctype_pool, dg.zcu, w, ctype, .suffix, .{});2066 try renderTypeSuffix(dg.pass, &dg.ctype_pool, zcu, w, ctype, .suffix, .{});
2062 }2067 }
20632068
2064 fn writeName(dg: *DeclGen, w: anytype, c_value: CValue) !void {2069 fn writeName(dg: *DeclGen, w: anytype, c_value: CValue) !void {
...@@ -2162,7 +2167,7 @@ pub const DeclGen = struct {...@@ -2162,7 +2167,7 @@ pub const DeclGen = struct {
2162 decl_index: InternPool.DeclIndex,2167 decl_index: InternPool.DeclIndex,
2163 variable: InternPool.Key.Variable,2168 variable: InternPool.Key.Variable,
2164 ) !void {2169 ) !void {
2165 const zcu = dg.zcu;2170 const zcu = dg.pt.zcu;
2166 const decl = zcu.declPtr(decl_index);2171 const decl = zcu.declPtr(decl_index);
2167 const fwd = dg.fwdDeclWriter();2172 const fwd = dg.fwdDeclWriter();
2168 try fwd.writeAll(if (variable.is_extern) "zig_extern " else "static ");2173 try fwd.writeAll(if (variable.is_extern) "zig_extern " else "static ");
...@@ -2180,7 +2185,7 @@ pub const DeclGen = struct {...@@ -2180,7 +2185,7 @@ pub const DeclGen = struct {
2180 }2185 }
21812186
2182 fn renderDeclName(dg: *DeclGen, writer: anytype, decl_index: InternPool.DeclIndex) !void {2187 fn renderDeclName(dg: *DeclGen, writer: anytype, decl_index: InternPool.DeclIndex) !void {
2183 const zcu = dg.zcu;2188 const zcu = dg.pt.zcu;
2184 const ip = &zcu.intern_pool;2189 const ip = &zcu.intern_pool;
2185 const decl = zcu.declPtr(decl_index);2190 const decl = zcu.declPtr(decl_index);
21862191
...@@ -2236,15 +2241,15 @@ pub const DeclGen = struct {...@@ -2236,15 +2241,15 @@ pub const DeclGen = struct {
2236 .bits => {},2241 .bits => {},
2237 }2242 }
22382243
2239 const zcu = dg.zcu;2244 const pt = dg.pt;
2240 const int_info = if (ty.isAbiInt(zcu)) ty.intInfo(zcu) else std.builtin.Type.Int{2245 const int_info = if (ty.isAbiInt(pt.zcu)) ty.intInfo(pt.zcu) else std.builtin.Type.Int{
2241 .signedness = .unsigned,2246 .signedness = .unsigned,
2242 .bits = @as(u16, @intCast(ty.bitSize(zcu))),2247 .bits = @as(u16, @intCast(ty.bitSize(pt))),
2243 };2248 };
22442249
2245 if (is_big) try writer.print(", {}", .{int_info.signedness == .signed});2250 if (is_big) try writer.print(", {}", .{int_info.signedness == .signed});
2246 try writer.print(", {}", .{try dg.fmtIntLiteral(2251 try writer.print(", {}", .{try dg.fmtIntLiteral(
2247 try zcu.intValue(if (is_big) Type.u16 else Type.u8, int_info.bits),2252 try pt.intValue(if (is_big) Type.u16 else Type.u8, int_info.bits),
2248 .FunctionArgument,2253 .FunctionArgument,
2249 )});2254 )});
2250 }2255 }
...@@ -2254,7 +2259,7 @@ pub const DeclGen = struct {...@@ -2254,7 +2259,7 @@ pub const DeclGen = struct {
2254 val: Value,2259 val: Value,
2255 loc: ValueRenderLocation,2260 loc: ValueRenderLocation,
2256 ) !std.fmt.Formatter(formatIntLiteral) {2261 ) !std.fmt.Formatter(formatIntLiteral) {
2257 const zcu = dg.zcu;2262 const zcu = dg.pt.zcu;
2258 const kind = loc.toCTypeKind();2263 const kind = loc.toCTypeKind();
2259 const ty = val.typeOf(zcu);2264 const ty = val.typeOf(zcu);
2260 return std.fmt.Formatter(formatIntLiteral){ .data = .{2265 return std.fmt.Formatter(formatIntLiteral){ .data = .{
...@@ -2616,7 +2621,8 @@ pub fn genGlobalAsm(zcu: *Zcu, writer: anytype) !void {...@@ -2616,7 +2621,8 @@ pub fn genGlobalAsm(zcu: *Zcu, writer: anytype) !void {
2616}2621}
26172622
2618pub fn genErrDecls(o: *Object) !void {2623pub fn genErrDecls(o: *Object) !void {
2619 const zcu = o.dg.zcu;2624 const pt = o.dg.pt;
2625 const zcu = pt.zcu;
2620 const ip = &zcu.intern_pool;2626 const ip = &zcu.intern_pool;
2621 const writer = o.writer();2627 const writer = o.writer();
26222628
...@@ -2628,7 +2634,7 @@ pub fn genErrDecls(o: *Object) !void {...@@ -2628,7 +2634,7 @@ pub fn genErrDecls(o: *Object) !void {
2628 for (zcu.global_error_set.keys()[1..], 1..) |name_nts, value| {2634 for (zcu.global_error_set.keys()[1..], 1..) |name_nts, value| {
2629 const name = name_nts.toSlice(ip);2635 const name = name_nts.toSlice(ip);
2630 max_name_len = @max(name.len, max_name_len);2636 max_name_len = @max(name.len, max_name_len);
2631 const err_val = try zcu.intern(.{ .err = .{2637 const err_val = try pt.intern(.{ .err = .{
2632 .ty = .anyerror_type,2638 .ty = .anyerror_type,
2633 .name = name_nts,2639 .name = name_nts,
2634 } });2640 } });
...@@ -2649,12 +2655,12 @@ pub fn genErrDecls(o: *Object) !void {...@@ -2649,12 +2655,12 @@ pub fn genErrDecls(o: *Object) !void {
2649 @memcpy(name_buf[name_prefix.len..][0..name_slice.len], name_slice);2655 @memcpy(name_buf[name_prefix.len..][0..name_slice.len], name_slice);
2650 const identifier = name_buf[0 .. name_prefix.len + name_slice.len];2656 const identifier = name_buf[0 .. name_prefix.len + name_slice.len];
26512657
2652 const name_ty = try zcu.arrayType(.{2658 const name_ty = try pt.arrayType(.{
2653 .len = name_slice.len,2659 .len = name_slice.len,
2654 .child = .u8_type,2660 .child = .u8_type,
2655 .sentinel = .zero_u8,2661 .sentinel = .zero_u8,
2656 });2662 });
2657 const name_val = try zcu.intern(.{ .aggregate = .{2663 const name_val = try pt.intern(.{ .aggregate = .{
2658 .ty = name_ty.toIntern(),2664 .ty = name_ty.toIntern(),
2659 .storage = .{ .bytes = name.toString() },2665 .storage = .{ .bytes = name.toString() },
2660 } });2666 } });
...@@ -2673,7 +2679,7 @@ pub fn genErrDecls(o: *Object) !void {...@@ -2673,7 +2679,7 @@ pub fn genErrDecls(o: *Object) !void {
2673 try writer.writeAll(";\n");2679 try writer.writeAll(";\n");
2674 }2680 }
26752681
2676 const name_array_ty = try zcu.arrayType(.{2682 const name_array_ty = try pt.arrayType(.{
2677 .len = zcu.global_error_set.count(),2683 .len = zcu.global_error_set.count(),
2678 .child = .slice_const_u8_sentinel_0_type,2684 .child = .slice_const_u8_sentinel_0_type,
2679 });2685 });
...@@ -2693,14 +2699,15 @@ pub fn genErrDecls(o: *Object) !void {...@@ -2693,14 +2699,15 @@ pub fn genErrDecls(o: *Object) !void {
2693 if (value != 0) try writer.writeByte(',');2699 if (value != 0) try writer.writeByte(',');
2694 try writer.print("{{" ++ name_prefix ++ "{}, {}}}", .{2700 try writer.print("{{" ++ name_prefix ++ "{}, {}}}", .{
2695 fmtIdent(name),2701 fmtIdent(name),
2696 try o.dg.fmtIntLiteral(try zcu.intValue(Type.usize, name.len), .StaticInitializer),2702 try o.dg.fmtIntLiteral(try pt.intValue(Type.usize, name.len), .StaticInitializer),
2697 });2703 });
2698 }2704 }
2699 try writer.writeAll("};\n");2705 try writer.writeAll("};\n");
2700}2706}
27012707
2702pub fn genLazyFn(o: *Object, lazy_ctype_pool: *const CType.Pool, lazy_fn: LazyFnMap.Entry) !void {2708pub fn genLazyFn(o: *Object, lazy_ctype_pool: *const CType.Pool, lazy_fn: LazyFnMap.Entry) !void {
2703 const zcu = o.dg.zcu;2709 const pt = o.dg.pt;
2710 const zcu = pt.zcu;
2704 const ip = &zcu.intern_pool;2711 const ip = &zcu.intern_pool;
2705 const ctype_pool = &o.dg.ctype_pool;2712 const ctype_pool = &o.dg.ctype_pool;
2706 const w = o.writer();2713 const w = o.writer();
...@@ -2721,20 +2728,20 @@ pub fn genLazyFn(o: *Object, lazy_ctype_pool: *const CType.Pool, lazy_fn: LazyFn...@@ -2721,20 +2728,20 @@ pub fn genLazyFn(o: *Object, lazy_ctype_pool: *const CType.Pool, lazy_fn: LazyFn
2721 for (0..tag_names.len) |tag_index| {2728 for (0..tag_names.len) |tag_index| {
2722 const tag_name = tag_names.get(ip)[tag_index];2729 const tag_name = tag_names.get(ip)[tag_index];
2723 const tag_name_len = tag_name.length(ip);2730 const tag_name_len = tag_name.length(ip);
2724 const tag_val = try zcu.enumValueFieldIndex(enum_ty, @intCast(tag_index));2731 const tag_val = try pt.enumValueFieldIndex(enum_ty, @intCast(tag_index));
27252732
2726 const name_ty = try zcu.arrayType(.{2733 const name_ty = try pt.arrayType(.{
2727 .len = tag_name_len,2734 .len = tag_name_len,
2728 .child = .u8_type,2735 .child = .u8_type,
2729 .sentinel = .zero_u8,2736 .sentinel = .zero_u8,
2730 });2737 });
2731 const name_val = try zcu.intern(.{ .aggregate = .{2738 const name_val = try pt.intern(.{ .aggregate = .{
2732 .ty = name_ty.toIntern(),2739 .ty = name_ty.toIntern(),
2733 .storage = .{ .bytes = tag_name.toString() },2740 .storage = .{ .bytes = tag_name.toString() },
2734 } });2741 } });
27352742
2736 try w.print(" case {}: {{\n static ", .{2743 try w.print(" case {}: {{\n static ", .{
2737 try o.dg.fmtIntLiteral(try tag_val.intFromEnum(enum_ty, zcu), .Other),2744 try o.dg.fmtIntLiteral(try tag_val.intFromEnum(enum_ty, pt), .Other),
2738 });2745 });
2739 try o.dg.renderTypeAndName(w, name_ty, .{ .identifier = "name" }, Const, .none, .complete);2746 try o.dg.renderTypeAndName(w, name_ty, .{ .identifier = "name" }, Const, .none, .complete);
2740 try w.writeAll(" = ");2747 try w.writeAll(" = ");
...@@ -2743,7 +2750,7 @@ pub fn genLazyFn(o: *Object, lazy_ctype_pool: *const CType.Pool, lazy_fn: LazyFn...@@ -2743,7 +2750,7 @@ pub fn genLazyFn(o: *Object, lazy_ctype_pool: *const CType.Pool, lazy_fn: LazyFn
2743 try o.dg.renderType(w, name_slice_ty);2750 try o.dg.renderType(w, name_slice_ty);
2744 try w.print("){{{}, {}}};\n", .{2751 try w.print("){{{}, {}}};\n", .{
2745 fmtIdent("name"),2752 fmtIdent("name"),
2746 try o.dg.fmtIntLiteral(try zcu.intValue(Type.usize, tag_name_len), .Other),2753 try o.dg.fmtIntLiteral(try pt.intValue(Type.usize, tag_name_len), .Other),
2747 });2754 });
27482755
2749 try w.writeAll(" }\n");2756 try w.writeAll(" }\n");
...@@ -2788,7 +2795,7 @@ pub fn genFunc(f: *Function) !void {...@@ -2788,7 +2795,7 @@ pub fn genFunc(f: *Function) !void {
2788 defer tracy.end();2795 defer tracy.end();
27892796
2790 const o = &f.object;2797 const o = &f.object;
2791 const zcu = o.dg.zcu;2798 const zcu = o.dg.pt.zcu;
2792 const gpa = o.dg.gpa;2799 const gpa = o.dg.gpa;
2793 const decl_index = o.dg.pass.decl;2800 const decl_index = o.dg.pass.decl;
2794 const decl = zcu.declPtr(decl_index);2801 const decl = zcu.declPtr(decl_index);
...@@ -2879,12 +2886,13 @@ pub fn genDecl(o: *Object) !void {...@@ -2879,12 +2886,13 @@ pub fn genDecl(o: *Object) !void {
2879 const tracy = trace(@src());2886 const tracy = trace(@src());
2880 defer tracy.end();2887 defer tracy.end();
28812888
2882 const zcu = o.dg.zcu;2889 const pt = o.dg.pt;
2890 const zcu = pt.zcu;
2883 const decl_index = o.dg.pass.decl;2891 const decl_index = o.dg.pass.decl;
2884 const decl = zcu.declPtr(decl_index);2892 const decl = zcu.declPtr(decl_index);
2885 const decl_ty = decl.typeOf(zcu);2893 const decl_ty = decl.typeOf(zcu);
28862894
2887 if (!decl_ty.isFnOrHasRuntimeBitsIgnoreComptime(zcu)) return;2895 if (!decl_ty.isFnOrHasRuntimeBitsIgnoreComptime(pt)) return;
2888 if (decl.val.getExternFunc(zcu)) |_| {2896 if (decl.val.getExternFunc(zcu)) |_| {
2889 const fwd = o.dg.fwdDeclWriter();2897 const fwd = o.dg.fwdDeclWriter();
2890 try fwd.writeAll("zig_extern ");2898 try fwd.writeAll("zig_extern ");
...@@ -2928,7 +2936,7 @@ pub fn genDeclValue(...@@ -2928,7 +2936,7 @@ pub fn genDeclValue(
2928 alignment: Alignment,2936 alignment: Alignment,
2929 @"linksection": InternPool.OptionalNullTerminatedString,2937 @"linksection": InternPool.OptionalNullTerminatedString,
2930) !void {2938) !void {
2931 const zcu = o.dg.zcu;2939 const zcu = o.dg.pt.zcu;
2932 const ty = val.typeOf(zcu);2940 const ty = val.typeOf(zcu);
29332941
2934 const fwd = o.dg.fwdDeclWriter();2942 const fwd = o.dg.fwdDeclWriter();
...@@ -2946,7 +2954,7 @@ pub fn genDeclValue(...@@ -2946,7 +2954,7 @@ pub fn genDeclValue(
2946}2954}
29472955
2948pub fn genExports(dg: *DeclGen, exported: Zcu.Exported, export_indices: []const u32) !void {2956pub fn genExports(dg: *DeclGen, exported: Zcu.Exported, export_indices: []const u32) !void {
2949 const zcu = dg.zcu;2957 const zcu = dg.pt.zcu;
2950 const ip = &zcu.intern_pool;2958 const ip = &zcu.intern_pool;
2951 const fwd = dg.fwdDeclWriter();2959 const fwd = dg.fwdDeclWriter();
29522960
...@@ -3088,7 +3096,7 @@ fn genBodyResolveState(f: *Function, inst: Air.Inst.Index, leading_deaths: []con...@@ -3088,7 +3096,7 @@ fn genBodyResolveState(f: *Function, inst: Air.Inst.Index, leading_deaths: []con
3088}3096}
30893097
3090fn genBodyInner(f: *Function, body: []const Air.Inst.Index) error{ AnalysisFail, OutOfMemory }!void {3098fn genBodyInner(f: *Function, body: []const Air.Inst.Index) error{ AnalysisFail, OutOfMemory }!void {
3091 const zcu = f.object.dg.zcu;3099 const zcu = f.object.dg.pt.zcu;
3092 const ip = &zcu.intern_pool;3100 const ip = &zcu.intern_pool;
3093 const air_tags = f.air.instructions.items(.tag);3101 const air_tags = f.air.instructions.items(.tag);
3094 const air_datas = f.air.instructions.items(.data);3102 const air_datas = f.air.instructions.items(.data);
...@@ -3388,10 +3396,10 @@ fn airSliceField(f: *Function, inst: Air.Inst.Index, is_ptr: bool, field_name: [...@@ -3388,10 +3396,10 @@ fn airSliceField(f: *Function, inst: Air.Inst.Index, is_ptr: bool, field_name: [
3388}3396}
33893397
3390fn airPtrElemVal(f: *Function, inst: Air.Inst.Index) !CValue {3398fn airPtrElemVal(f: *Function, inst: Air.Inst.Index) !CValue {
3391 const zcu = f.object.dg.zcu;3399 const pt = f.object.dg.pt;
3392 const inst_ty = f.typeOfIndex(inst);3400 const inst_ty = f.typeOfIndex(inst);
3393 const bin_op = f.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;3401 const bin_op = f.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
3394 if (!inst_ty.hasRuntimeBitsIgnoreComptime(zcu)) {3402 if (!inst_ty.hasRuntimeBitsIgnoreComptime(pt)) {
3395 try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs });3403 try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs });
3396 return .none;3404 return .none;
3397 }3405 }
...@@ -3414,13 +3422,14 @@ fn airPtrElemVal(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -3414,13 +3422,14 @@ fn airPtrElemVal(f: *Function, inst: Air.Inst.Index) !CValue {
3414}3422}
34153423
3416fn airPtrElemPtr(f: *Function, inst: Air.Inst.Index) !CValue {3424fn airPtrElemPtr(f: *Function, inst: Air.Inst.Index) !CValue {
3417 const zcu = f.object.dg.zcu;3425 const pt = f.object.dg.pt;
3426 const zcu = pt.zcu;
3418 const ty_pl = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;3427 const ty_pl = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
3419 const bin_op = f.air.extraData(Air.Bin, ty_pl.payload).data;3428 const bin_op = f.air.extraData(Air.Bin, ty_pl.payload).data;
34203429
3421 const inst_ty = f.typeOfIndex(inst);3430 const inst_ty = f.typeOfIndex(inst);
3422 const ptr_ty = f.typeOf(bin_op.lhs);3431 const ptr_ty = f.typeOf(bin_op.lhs);
3423 const elem_has_bits = ptr_ty.elemType2(zcu).hasRuntimeBitsIgnoreComptime(zcu);3432 const elem_has_bits = ptr_ty.elemType2(zcu).hasRuntimeBitsIgnoreComptime(pt);
34243433
3425 const ptr = try f.resolveInst(bin_op.lhs);3434 const ptr = try f.resolveInst(bin_op.lhs);
3426 const index = try f.resolveInst(bin_op.rhs);3435 const index = try f.resolveInst(bin_op.rhs);
...@@ -3449,10 +3458,10 @@ fn airPtrElemPtr(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -3449,10 +3458,10 @@ fn airPtrElemPtr(f: *Function, inst: Air.Inst.Index) !CValue {
3449}3458}
34503459
3451fn airSliceElemVal(f: *Function, inst: Air.Inst.Index) !CValue {3460fn airSliceElemVal(f: *Function, inst: Air.Inst.Index) !CValue {
3452 const zcu = f.object.dg.zcu;3461 const pt = f.object.dg.pt;
3453 const inst_ty = f.typeOfIndex(inst);3462 const inst_ty = f.typeOfIndex(inst);
3454 const bin_op = f.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;3463 const bin_op = f.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
3455 if (!inst_ty.hasRuntimeBitsIgnoreComptime(zcu)) {3464 if (!inst_ty.hasRuntimeBitsIgnoreComptime(pt)) {
3456 try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs });3465 try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs });
3457 return .none;3466 return .none;
3458 }3467 }
...@@ -3475,14 +3484,15 @@ fn airSliceElemVal(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -3475,14 +3484,15 @@ fn airSliceElemVal(f: *Function, inst: Air.Inst.Index) !CValue {
3475}3484}
34763485
3477fn airSliceElemPtr(f: *Function, inst: Air.Inst.Index) !CValue {3486fn airSliceElemPtr(f: *Function, inst: Air.Inst.Index) !CValue {
3478 const zcu = f.object.dg.zcu;3487 const pt = f.object.dg.pt;
3488 const zcu = pt.zcu;
3479 const ty_pl = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;3489 const ty_pl = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
3480 const bin_op = f.air.extraData(Air.Bin, ty_pl.payload).data;3490 const bin_op = f.air.extraData(Air.Bin, ty_pl.payload).data;
34813491
3482 const inst_ty = f.typeOfIndex(inst);3492 const inst_ty = f.typeOfIndex(inst);
3483 const slice_ty = f.typeOf(bin_op.lhs);3493 const slice_ty = f.typeOf(bin_op.lhs);
3484 const elem_ty = slice_ty.elemType2(zcu);3494 const elem_ty = slice_ty.elemType2(zcu);
3485 const elem_has_bits = elem_ty.hasRuntimeBitsIgnoreComptime(zcu);3495 const elem_has_bits = elem_ty.hasRuntimeBitsIgnoreComptime(pt);
34863496
3487 const slice = try f.resolveInst(bin_op.lhs);3497 const slice = try f.resolveInst(bin_op.lhs);
3488 const index = try f.resolveInst(bin_op.rhs);3498 const index = try f.resolveInst(bin_op.rhs);
...@@ -3505,10 +3515,10 @@ fn airSliceElemPtr(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -3505,10 +3515,10 @@ fn airSliceElemPtr(f: *Function, inst: Air.Inst.Index) !CValue {
3505}3515}
35063516
3507fn airArrayElemVal(f: *Function, inst: Air.Inst.Index) !CValue {3517fn airArrayElemVal(f: *Function, inst: Air.Inst.Index) !CValue {
3508 const zcu = f.object.dg.zcu;3518 const pt = f.object.dg.pt;
3509 const bin_op = f.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;3519 const bin_op = f.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
3510 const inst_ty = f.typeOfIndex(inst);3520 const inst_ty = f.typeOfIndex(inst);
3511 if (!inst_ty.hasRuntimeBitsIgnoreComptime(zcu)) {3521 if (!inst_ty.hasRuntimeBitsIgnoreComptime(pt)) {
3512 try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs });3522 try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs });
3513 return .none;3523 return .none;
3514 }3524 }
...@@ -3531,40 +3541,40 @@ fn airArrayElemVal(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -3531,40 +3541,40 @@ fn airArrayElemVal(f: *Function, inst: Air.Inst.Index) !CValue {
3531}3541}
35323542
3533fn airAlloc(f: *Function, inst: Air.Inst.Index) !CValue {3543fn airAlloc(f: *Function, inst: Air.Inst.Index) !CValue {
3534 const zcu = f.object.dg.zcu;3544 const pt = f.object.dg.pt;
3545 const zcu = pt.zcu;
3535 const inst_ty = f.typeOfIndex(inst);3546 const inst_ty = f.typeOfIndex(inst);
3536 const elem_ty = inst_ty.childType(zcu);3547 const elem_ty = inst_ty.childType(zcu);
3537 if (!elem_ty.isFnOrHasRuntimeBitsIgnoreComptime(zcu)) return .{ .undef = inst_ty };3548 if (!elem_ty.isFnOrHasRuntimeBitsIgnoreComptime(pt)) return .{ .undef = inst_ty };
35383549
3539 const local = try f.allocLocalValue(.{3550 const local = try f.allocLocalValue(.{
3540 .ctype = try f.ctypeFromType(elem_ty, .complete),3551 .ctype = try f.ctypeFromType(elem_ty, .complete),
3541 .alignas = CType.AlignAs.fromAlignment(.{3552 .alignas = CType.AlignAs.fromAlignment(.{
3542 .@"align" = inst_ty.ptrInfo(zcu).flags.alignment,3553 .@"align" = inst_ty.ptrInfo(zcu).flags.alignment,
3543 .abi = elem_ty.abiAlignment(zcu),3554 .abi = elem_ty.abiAlignment(pt),
3544 }),3555 }),
3545 });3556 });
3546 log.debug("%{d}: allocated unfreeable t{d}", .{ inst, local.new_local });3557 log.debug("%{d}: allocated unfreeable t{d}", .{ inst, local.new_local });
3547 const gpa = f.object.dg.zcu.gpa;3558 try f.allocs.put(zcu.gpa, local.new_local, true);
3548 try f.allocs.put(gpa, local.new_local, true);
3549 return .{ .local_ref = local.new_local };3559 return .{ .local_ref = local.new_local };
3550}3560}
35513561
3552fn airRetPtr(f: *Function, inst: Air.Inst.Index) !CValue {3562fn airRetPtr(f: *Function, inst: Air.Inst.Index) !CValue {
3553 const zcu = f.object.dg.zcu;3563 const pt = f.object.dg.pt;
3564 const zcu = pt.zcu;
3554 const inst_ty = f.typeOfIndex(inst);3565 const inst_ty = f.typeOfIndex(inst);
3555 const elem_ty = inst_ty.childType(zcu);3566 const elem_ty = inst_ty.childType(zcu);
3556 if (!elem_ty.isFnOrHasRuntimeBitsIgnoreComptime(zcu)) return .{ .undef = inst_ty };3567 if (!elem_ty.isFnOrHasRuntimeBitsIgnoreComptime(pt)) return .{ .undef = inst_ty };
35573568
3558 const local = try f.allocLocalValue(.{3569 const local = try f.allocLocalValue(.{
3559 .ctype = try f.ctypeFromType(elem_ty, .complete),3570 .ctype = try f.ctypeFromType(elem_ty, .complete),
3560 .alignas = CType.AlignAs.fromAlignment(.{3571 .alignas = CType.AlignAs.fromAlignment(.{
3561 .@"align" = inst_ty.ptrInfo(zcu).flags.alignment,3572 .@"align" = inst_ty.ptrInfo(zcu).flags.alignment,
3562 .abi = elem_ty.abiAlignment(zcu),3573 .abi = elem_ty.abiAlignment(pt),
3563 }),3574 }),
3564 });3575 });
3565 log.debug("%{d}: allocated unfreeable t{d}", .{ inst, local.new_local });3576 log.debug("%{d}: allocated unfreeable t{d}", .{ inst, local.new_local });
3566 const gpa = f.object.dg.zcu.gpa;3577 try f.allocs.put(zcu.gpa, local.new_local, true);
3567 try f.allocs.put(gpa, local.new_local, true);
3568 return .{ .local_ref = local.new_local };3578 return .{ .local_ref = local.new_local };
3569}3579}
35703580
...@@ -3593,7 +3603,8 @@ fn airArg(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -3593,7 +3603,8 @@ fn airArg(f: *Function, inst: Air.Inst.Index) !CValue {
3593}3603}
35943604
3595fn airLoad(f: *Function, inst: Air.Inst.Index) !CValue {3605fn airLoad(f: *Function, inst: Air.Inst.Index) !CValue {
3596 const zcu = f.object.dg.zcu;3606 const pt = f.object.dg.pt;
3607 const zcu = pt.zcu;
3597 const ty_op = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;3608 const ty_op = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
35983609
3599 const ptr_ty = f.typeOf(ty_op.operand);3610 const ptr_ty = f.typeOf(ty_op.operand);
...@@ -3601,7 +3612,7 @@ fn airLoad(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -3601,7 +3612,7 @@ fn airLoad(f: *Function, inst: Air.Inst.Index) !CValue {
3601 const ptr_info = ptr_scalar_ty.ptrInfo(zcu);3612 const ptr_info = ptr_scalar_ty.ptrInfo(zcu);
3602 const src_ty = Type.fromInterned(ptr_info.child);3613 const src_ty = Type.fromInterned(ptr_info.child);
36033614
3604 if (!src_ty.hasRuntimeBitsIgnoreComptime(zcu)) {3615 if (!src_ty.hasRuntimeBitsIgnoreComptime(pt)) {
3605 try reap(f, inst, &.{ty_op.operand});3616 try reap(f, inst, &.{ty_op.operand});
3606 return .none;3617 return .none;
3607 }3618 }
...@@ -3611,10 +3622,10 @@ fn airLoad(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -3611,10 +3622,10 @@ fn airLoad(f: *Function, inst: Air.Inst.Index) !CValue {
3611 try reap(f, inst, &.{ty_op.operand});3622 try reap(f, inst, &.{ty_op.operand});
36123623
3613 const is_aligned = if (ptr_info.flags.alignment != .none)3624 const is_aligned = if (ptr_info.flags.alignment != .none)
3614 ptr_info.flags.alignment.order(src_ty.abiAlignment(zcu)).compare(.gte)3625 ptr_info.flags.alignment.order(src_ty.abiAlignment(pt)).compare(.gte)
3615 else3626 else
3616 true;3627 true;
3617 const is_array = lowersToArray(src_ty, zcu);3628 const is_array = lowersToArray(src_ty, pt);
3618 const need_memcpy = !is_aligned or is_array;3629 const need_memcpy = !is_aligned or is_array;
36193630
3620 const writer = f.object.writer();3631 const writer = f.object.writer();
...@@ -3634,12 +3645,12 @@ fn airLoad(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -3634,12 +3645,12 @@ fn airLoad(f: *Function, inst: Air.Inst.Index) !CValue {
3634 try writer.writeAll("))");3645 try writer.writeAll("))");
3635 } else if (ptr_info.packed_offset.host_size > 0 and ptr_info.flags.vector_index == .none) {3646 } else if (ptr_info.packed_offset.host_size > 0 and ptr_info.flags.vector_index == .none) {
3636 const host_bits: u16 = ptr_info.packed_offset.host_size * 8;3647 const host_bits: u16 = ptr_info.packed_offset.host_size * 8;
3637 const host_ty = try zcu.intType(.unsigned, host_bits);3648 const host_ty = try pt.intType(.unsigned, host_bits);
36383649
3639 const bit_offset_ty = try zcu.intType(.unsigned, Type.smallestUnsignedBits(host_bits - 1));3650 const bit_offset_ty = try pt.intType(.unsigned, Type.smallestUnsignedBits(host_bits - 1));
3640 const bit_offset_val = try zcu.intValue(bit_offset_ty, ptr_info.packed_offset.bit_offset);3651 const bit_offset_val = try pt.intValue(bit_offset_ty, ptr_info.packed_offset.bit_offset);
36413652
3642 const field_ty = try zcu.intType(.unsigned, @as(u16, @intCast(src_ty.bitSize(zcu))));3653 const field_ty = try pt.intType(.unsigned, @as(u16, @intCast(src_ty.bitSize(pt))));
36433654
3644 try f.writeCValue(writer, local, .Other);3655 try f.writeCValue(writer, local, .Other);
3645 try v.elem(f, writer);3656 try v.elem(f, writer);
...@@ -3650,9 +3661,9 @@ fn airLoad(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -3650,9 +3661,9 @@ fn airLoad(f: *Function, inst: Air.Inst.Index) !CValue {
3650 try writer.writeAll("((");3661 try writer.writeAll("((");
3651 try f.renderType(writer, field_ty);3662 try f.renderType(writer, field_ty);
3652 try writer.writeByte(')');3663 try writer.writeByte(')');
3653 const cant_cast = host_ty.isInt(zcu) and host_ty.bitSize(zcu) > 64;3664 const cant_cast = host_ty.isInt(zcu) and host_ty.bitSize(pt) > 64;
3654 if (cant_cast) {3665 if (cant_cast) {
3655 if (field_ty.bitSize(zcu) > 64) return f.fail("TODO: C backend: implement casting between types > 64 bits", .{});3666 if (field_ty.bitSize(pt) > 64) return f.fail("TODO: C backend: implement casting between types > 64 bits", .{});
3656 try writer.writeAll("zig_lo_");3667 try writer.writeAll("zig_lo_");
3657 try f.object.dg.renderTypeForBuiltinFnName(writer, host_ty);3668 try f.object.dg.renderTypeForBuiltinFnName(writer, host_ty);
3658 try writer.writeByte('(');3669 try writer.writeByte('(');
...@@ -3680,7 +3691,8 @@ fn airLoad(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -3680,7 +3691,8 @@ fn airLoad(f: *Function, inst: Air.Inst.Index) !CValue {
3680}3691}
36813692
3682fn airRet(f: *Function, inst: Air.Inst.Index, is_ptr: bool) !CValue {3693fn airRet(f: *Function, inst: Air.Inst.Index, is_ptr: bool) !CValue {
3683 const zcu = f.object.dg.zcu;3694 const pt = f.object.dg.pt;
3695 const zcu = pt.zcu;
3684 const un_op = f.air.instructions.items(.data)[@intFromEnum(inst)].un_op;3696 const un_op = f.air.instructions.items(.data)[@intFromEnum(inst)].un_op;
3685 const writer = f.object.writer();3697 const writer = f.object.writer();
3686 const op_inst = un_op.toIndex();3698 const op_inst = un_op.toIndex();
...@@ -3695,11 +3707,11 @@ fn airRet(f: *Function, inst: Air.Inst.Index, is_ptr: bool) !CValue {...@@ -3695,11 +3707,11 @@ fn airRet(f: *Function, inst: Air.Inst.Index, is_ptr: bool) !CValue {
3695 const operand = try f.resolveInst(un_op);3707 const operand = try f.resolveInst(un_op);
3696 try reap(f, inst, &.{un_op});3708 try reap(f, inst, &.{un_op});
3697 var deref = is_ptr;3709 var deref = is_ptr;
3698 const is_array = lowersToArray(ret_ty, zcu);3710 const is_array = lowersToArray(ret_ty, pt);
3699 const ret_val = if (is_array) ret_val: {3711 const ret_val = if (is_array) ret_val: {
3700 const array_local = try f.allocAlignedLocal(inst, .{3712 const array_local = try f.allocAlignedLocal(inst, .{
3701 .ctype = ret_ctype,3713 .ctype = ret_ctype,
3702 .alignas = CType.AlignAs.fromAbiAlignment(ret_ty.abiAlignment(f.object.dg.zcu)),3714 .alignas = CType.AlignAs.fromAbiAlignment(ret_ty.abiAlignment(pt)),
3703 });3715 });
3704 try writer.writeAll("memcpy(");3716 try writer.writeAll("memcpy(");
3705 try f.writeCValueMember(writer, array_local, .{ .identifier = "array" });3717 try f.writeCValueMember(writer, array_local, .{ .identifier = "array" });
...@@ -3733,7 +3745,8 @@ fn airRet(f: *Function, inst: Air.Inst.Index, is_ptr: bool) !CValue {...@@ -3733,7 +3745,8 @@ fn airRet(f: *Function, inst: Air.Inst.Index, is_ptr: bool) !CValue {
3733}3745}
37343746
3735fn airIntCast(f: *Function, inst: Air.Inst.Index) !CValue {3747fn airIntCast(f: *Function, inst: Air.Inst.Index) !CValue {
3736 const zcu = f.object.dg.zcu;3748 const pt = f.object.dg.pt;
3749 const zcu = pt.zcu;
3737 const ty_op = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;3750 const ty_op = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
37383751
3739 const operand = try f.resolveInst(ty_op.operand);3752 const operand = try f.resolveInst(ty_op.operand);
...@@ -3760,7 +3773,8 @@ fn airIntCast(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -3760,7 +3773,8 @@ fn airIntCast(f: *Function, inst: Air.Inst.Index) !CValue {
3760}3773}
37613774
3762fn airTrunc(f: *Function, inst: Air.Inst.Index) !CValue {3775fn airTrunc(f: *Function, inst: Air.Inst.Index) !CValue {
3763 const zcu = f.object.dg.zcu;3776 const pt = f.object.dg.pt;
3777 const zcu = pt.zcu;
3764 const ty_op = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;3778 const ty_op = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
37653779
3766 const operand = try f.resolveInst(ty_op.operand);3780 const operand = try f.resolveInst(ty_op.operand);
...@@ -3809,13 +3823,13 @@ fn airTrunc(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -3809,13 +3823,13 @@ fn airTrunc(f: *Function, inst: Air.Inst.Index) !CValue {
3809 try f.writeCValue(writer, operand, .FunctionArgument);3823 try f.writeCValue(writer, operand, .FunctionArgument);
3810 try v.elem(f, writer);3824 try v.elem(f, writer);
3811 try writer.print(", {x})", .{3825 try writer.print(", {x})", .{
3812 try f.fmtIntLiteral(try inst_scalar_ty.maxIntScalar(zcu, scalar_ty)),3826 try f.fmtIntLiteral(try inst_scalar_ty.maxIntScalar(pt, scalar_ty)),
3813 });3827 });
3814 },3828 },
3815 .signed => {3829 .signed => {
3816 const c_bits = toCIntBits(scalar_int_info.bits) orelse3830 const c_bits = toCIntBits(scalar_int_info.bits) orelse
3817 return f.fail("TODO: C backend: implement integer types larger than 128 bits", .{});3831 return f.fail("TODO: C backend: implement integer types larger than 128 bits", .{});
3818 const shift_val = try zcu.intValue(Type.u8, c_bits - dest_bits);3832 const shift_val = try pt.intValue(Type.u8, c_bits - dest_bits);
38193833
3820 try writer.writeAll("zig_shr_");3834 try writer.writeAll("zig_shr_");
3821 try f.object.dg.renderTypeForBuiltinFnName(writer, scalar_ty);3835 try f.object.dg.renderTypeForBuiltinFnName(writer, scalar_ty);
...@@ -3860,7 +3874,8 @@ fn airIntFromBool(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -3860,7 +3874,8 @@ fn airIntFromBool(f: *Function, inst: Air.Inst.Index) !CValue {
3860}3874}
38613875
3862fn airStore(f: *Function, inst: Air.Inst.Index, safety: bool) !CValue {3876fn airStore(f: *Function, inst: Air.Inst.Index, safety: bool) !CValue {
3863 const zcu = f.object.dg.zcu;3877 const pt = f.object.dg.pt;
3878 const zcu = pt.zcu;
3864 // *a = b;3879 // *a = b;
3865 const bin_op = f.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;3880 const bin_op = f.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
38663881
...@@ -3871,7 +3886,7 @@ fn airStore(f: *Function, inst: Air.Inst.Index, safety: bool) !CValue {...@@ -3871,7 +3886,7 @@ fn airStore(f: *Function, inst: Air.Inst.Index, safety: bool) !CValue {
3871 const ptr_val = try f.resolveInst(bin_op.lhs);3886 const ptr_val = try f.resolveInst(bin_op.lhs);
3872 const src_ty = f.typeOf(bin_op.rhs);3887 const src_ty = f.typeOf(bin_op.rhs);
38733888
3874 const val_is_undef = if (try f.air.value(bin_op.rhs, zcu)) |v| v.isUndefDeep(zcu) else false;3889 const val_is_undef = if (try f.air.value(bin_op.rhs, pt)) |v| v.isUndefDeep(zcu) else false;
38753890
3876 if (val_is_undef) {3891 if (val_is_undef) {
3877 try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs });3892 try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs });
...@@ -3887,10 +3902,10 @@ fn airStore(f: *Function, inst: Air.Inst.Index, safety: bool) !CValue {...@@ -3887,10 +3902,10 @@ fn airStore(f: *Function, inst: Air.Inst.Index, safety: bool) !CValue {
3887 }3902 }
38883903
3889 const is_aligned = if (ptr_info.flags.alignment != .none)3904 const is_aligned = if (ptr_info.flags.alignment != .none)
3890 ptr_info.flags.alignment.order(src_ty.abiAlignment(zcu)).compare(.gte)3905 ptr_info.flags.alignment.order(src_ty.abiAlignment(pt)).compare(.gte)
3891 else3906 else
3892 true;3907 true;
3893 const is_array = lowersToArray(Type.fromInterned(ptr_info.child), zcu);3908 const is_array = lowersToArray(Type.fromInterned(ptr_info.child), pt);
3894 const need_memcpy = !is_aligned or is_array;3909 const need_memcpy = !is_aligned or is_array;
38953910
3896 const src_val = try f.resolveInst(bin_op.rhs);3911 const src_val = try f.resolveInst(bin_op.rhs);
...@@ -3901,7 +3916,7 @@ fn airStore(f: *Function, inst: Air.Inst.Index, safety: bool) !CValue {...@@ -3901,7 +3916,7 @@ fn airStore(f: *Function, inst: Air.Inst.Index, safety: bool) !CValue {
3901 if (need_memcpy) {3916 if (need_memcpy) {
3902 // For this memcpy to safely work we need the rhs to have the same3917 // For this memcpy to safely work we need the rhs to have the same
3903 // underlying type as the lhs (i.e. they must both be arrays of the same underlying type).3918 // underlying type as the lhs (i.e. they must both be arrays of the same underlying type).
3904 assert(src_ty.eql(Type.fromInterned(ptr_info.child), f.object.dg.zcu));3919 assert(src_ty.eql(Type.fromInterned(ptr_info.child), zcu));
39053920
3906 // If the source is a constant, writeCValue will emit a brace initialization3921 // If the source is a constant, writeCValue will emit a brace initialization
3907 // so work around this by initializing into new local.3922 // so work around this by initializing into new local.
...@@ -3932,12 +3947,12 @@ fn airStore(f: *Function, inst: Air.Inst.Index, safety: bool) !CValue {...@@ -3932,12 +3947,12 @@ fn airStore(f: *Function, inst: Air.Inst.Index, safety: bool) !CValue {
3932 try v.end(f, inst, writer);3947 try v.end(f, inst, writer);
3933 } else if (ptr_info.packed_offset.host_size > 0 and ptr_info.flags.vector_index == .none) {3948 } else if (ptr_info.packed_offset.host_size > 0 and ptr_info.flags.vector_index == .none) {
3934 const host_bits = ptr_info.packed_offset.host_size * 8;3949 const host_bits = ptr_info.packed_offset.host_size * 8;
3935 const host_ty = try zcu.intType(.unsigned, host_bits);3950 const host_ty = try pt.intType(.unsigned, host_bits);
39363951
3937 const bit_offset_ty = try zcu.intType(.unsigned, Type.smallestUnsignedBits(host_bits - 1));3952 const bit_offset_ty = try pt.intType(.unsigned, Type.smallestUnsignedBits(host_bits - 1));
3938 const bit_offset_val = try zcu.intValue(bit_offset_ty, ptr_info.packed_offset.bit_offset);3953 const bit_offset_val = try pt.intValue(bit_offset_ty, ptr_info.packed_offset.bit_offset);
39393954
3940 const src_bits = src_ty.bitSize(zcu);3955 const src_bits = src_ty.bitSize(pt);
39413956
3942 const ExpectedContents = [BigInt.Managed.default_capacity]BigIntLimb;3957 const ExpectedContents = [BigInt.Managed.default_capacity]BigIntLimb;
3943 var stack align(@alignOf(ExpectedContents)) =3958 var stack align(@alignOf(ExpectedContents)) =
...@@ -3950,7 +3965,7 @@ fn airStore(f: *Function, inst: Air.Inst.Index, safety: bool) !CValue {...@@ -3950,7 +3965,7 @@ fn airStore(f: *Function, inst: Air.Inst.Index, safety: bool) !CValue {
3950 try mask.shiftLeft(&mask, ptr_info.packed_offset.bit_offset);3965 try mask.shiftLeft(&mask, ptr_info.packed_offset.bit_offset);
3951 try mask.bitNotWrap(&mask, .unsigned, host_bits);3966 try mask.bitNotWrap(&mask, .unsigned, host_bits);
39523967
3953 const mask_val = try zcu.intValue_big(host_ty, mask.toConst());3968 const mask_val = try pt.intValue_big(host_ty, mask.toConst());
39543969
3955 const v = try Vectorize.start(f, inst, writer, ptr_ty);3970 const v = try Vectorize.start(f, inst, writer, ptr_ty);
3956 const a = try Assignment.start(f, writer, src_scalar_ctype);3971 const a = try Assignment.start(f, writer, src_scalar_ctype);
...@@ -3967,9 +3982,9 @@ fn airStore(f: *Function, inst: Air.Inst.Index, safety: bool) !CValue {...@@ -3967,9 +3982,9 @@ fn airStore(f: *Function, inst: Air.Inst.Index, safety: bool) !CValue {
3967 try writer.print(", {x}), zig_shl_", .{try f.fmtIntLiteral(mask_val)});3982 try writer.print(", {x}), zig_shl_", .{try f.fmtIntLiteral(mask_val)});
3968 try f.object.dg.renderTypeForBuiltinFnName(writer, host_ty);3983 try f.object.dg.renderTypeForBuiltinFnName(writer, host_ty);
3969 try writer.writeByte('(');3984 try writer.writeByte('(');
3970 const cant_cast = host_ty.isInt(zcu) and host_ty.bitSize(zcu) > 64;3985 const cant_cast = host_ty.isInt(zcu) and host_ty.bitSize(pt) > 64;
3971 if (cant_cast) {3986 if (cant_cast) {
3972 if (src_ty.bitSize(zcu) > 64) return f.fail("TODO: C backend: implement casting between types > 64 bits", .{});3987 if (src_ty.bitSize(pt) > 64) return f.fail("TODO: C backend: implement casting between types > 64 bits", .{});
3973 try writer.writeAll("zig_make_");3988 try writer.writeAll("zig_make_");
3974 try f.object.dg.renderTypeForBuiltinFnName(writer, host_ty);3989 try f.object.dg.renderTypeForBuiltinFnName(writer, host_ty);
3975 try writer.writeAll("(0, ");3990 try writer.writeAll("(0, ");
...@@ -4013,7 +4028,8 @@ fn airStore(f: *Function, inst: Air.Inst.Index, safety: bool) !CValue {...@@ -4013,7 +4028,8 @@ fn airStore(f: *Function, inst: Air.Inst.Index, safety: bool) !CValue {
4013}4028}
40144029
4015fn airOverflow(f: *Function, inst: Air.Inst.Index, operation: []const u8, info: BuiltinInfo) !CValue {4030fn airOverflow(f: *Function, inst: Air.Inst.Index, operation: []const u8, info: BuiltinInfo) !CValue {
4016 const zcu = f.object.dg.zcu;4031 const pt = f.object.dg.pt;
4032 const zcu = pt.zcu;
4017 const ty_pl = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;4033 const ty_pl = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
4018 const bin_op = f.air.extraData(Air.Bin, ty_pl.payload).data;4034 const bin_op = f.air.extraData(Air.Bin, ty_pl.payload).data;
40194035
...@@ -4051,7 +4067,8 @@ fn airOverflow(f: *Function, inst: Air.Inst.Index, operation: []const u8, info:...@@ -4051,7 +4067,8 @@ fn airOverflow(f: *Function, inst: Air.Inst.Index, operation: []const u8, info:
4051}4067}
40524068
4053fn airNot(f: *Function, inst: Air.Inst.Index) !CValue {4069fn airNot(f: *Function, inst: Air.Inst.Index) !CValue {
4054 const zcu = f.object.dg.zcu;4070 const pt = f.object.dg.pt;
4071 const zcu = pt.zcu;
4055 const ty_op = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;4072 const ty_op = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
4056 const operand_ty = f.typeOf(ty_op.operand);4073 const operand_ty = f.typeOf(ty_op.operand);
4057 const scalar_ty = operand_ty.scalarType(zcu);4074 const scalar_ty = operand_ty.scalarType(zcu);
...@@ -4084,11 +4101,12 @@ fn airBinOp(...@@ -4084,11 +4101,12 @@ fn airBinOp(
4084 operation: []const u8,4101 operation: []const u8,
4085 info: BuiltinInfo,4102 info: BuiltinInfo,
4086) !CValue {4103) !CValue {
4087 const zcu = f.object.dg.zcu;4104 const pt = f.object.dg.pt;
4105 const zcu = pt.zcu;
4088 const bin_op = f.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;4106 const bin_op = f.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
4089 const operand_ty = f.typeOf(bin_op.lhs);4107 const operand_ty = f.typeOf(bin_op.lhs);
4090 const scalar_ty = operand_ty.scalarType(zcu);4108 const scalar_ty = operand_ty.scalarType(zcu);
4091 if ((scalar_ty.isInt(zcu) and scalar_ty.bitSize(zcu) > 64) or scalar_ty.isRuntimeFloat())4109 if ((scalar_ty.isInt(zcu) and scalar_ty.bitSize(pt) > 64) or scalar_ty.isRuntimeFloat())
4092 return try airBinBuiltinCall(f, inst, operation, info);4110 return try airBinBuiltinCall(f, inst, operation, info);
40934111
4094 const lhs = try f.resolveInst(bin_op.lhs);4112 const lhs = try f.resolveInst(bin_op.lhs);
...@@ -4122,11 +4140,12 @@ fn airCmpOp(...@@ -4122,11 +4140,12 @@ fn airCmpOp(
4122 data: anytype,4140 data: anytype,
4123 operator: std.math.CompareOperator,4141 operator: std.math.CompareOperator,
4124) !CValue {4142) !CValue {
4125 const zcu = f.object.dg.zcu;4143 const pt = f.object.dg.pt;
4144 const zcu = pt.zcu;
4126 const lhs_ty = f.typeOf(data.lhs);4145 const lhs_ty = f.typeOf(data.lhs);
4127 const scalar_ty = lhs_ty.scalarType(zcu);4146 const scalar_ty = lhs_ty.scalarType(zcu);
41284147
4129 const scalar_bits = scalar_ty.bitSize(zcu);4148 const scalar_bits = scalar_ty.bitSize(pt);
4130 if (scalar_ty.isInt(zcu) and scalar_bits > 64)4149 if (scalar_ty.isInt(zcu) and scalar_bits > 64)
4131 return airCmpBuiltinCall(4150 return airCmpBuiltinCall(
4132 f,4151 f,
...@@ -4170,12 +4189,13 @@ fn airEquality(...@@ -4170,12 +4189,13 @@ fn airEquality(
4170 inst: Air.Inst.Index,4189 inst: Air.Inst.Index,
4171 operator: std.math.CompareOperator,4190 operator: std.math.CompareOperator,
4172) !CValue {4191) !CValue {
4173 const zcu = f.object.dg.zcu;4192 const pt = f.object.dg.pt;
4193 const zcu = pt.zcu;
4174 const ctype_pool = &f.object.dg.ctype_pool;4194 const ctype_pool = &f.object.dg.ctype_pool;
4175 const bin_op = f.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;4195 const bin_op = f.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
41764196
4177 const operand_ty = f.typeOf(bin_op.lhs);4197 const operand_ty = f.typeOf(bin_op.lhs);
4178 const operand_bits = operand_ty.bitSize(zcu);4198 const operand_bits = operand_ty.bitSize(pt);
4179 if (operand_ty.isAbiInt(zcu) and operand_bits > 64)4199 if (operand_ty.isAbiInt(zcu) and operand_bits > 64)
4180 return airCmpBuiltinCall(4200 return airCmpBuiltinCall(
4181 f,4201 f,
...@@ -4256,7 +4276,8 @@ fn airCmpLtErrorsLen(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -4256,7 +4276,8 @@ fn airCmpLtErrorsLen(f: *Function, inst: Air.Inst.Index) !CValue {
4256}4276}
42574277
4258fn airPtrAddSub(f: *Function, inst: Air.Inst.Index, operator: u8) !CValue {4278fn airPtrAddSub(f: *Function, inst: Air.Inst.Index, operator: u8) !CValue {
4259 const zcu = f.object.dg.zcu;4279 const pt = f.object.dg.pt;
4280 const zcu = pt.zcu;
4260 const ty_pl = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;4281 const ty_pl = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
4261 const bin_op = f.air.extraData(Air.Bin, ty_pl.payload).data;4282 const bin_op = f.air.extraData(Air.Bin, ty_pl.payload).data;
42624283
...@@ -4267,7 +4288,7 @@ fn airPtrAddSub(f: *Function, inst: Air.Inst.Index, operator: u8) !CValue {...@@ -4267,7 +4288,7 @@ fn airPtrAddSub(f: *Function, inst: Air.Inst.Index, operator: u8) !CValue {
4267 const inst_ty = f.typeOfIndex(inst);4288 const inst_ty = f.typeOfIndex(inst);
4268 const inst_scalar_ty = inst_ty.scalarType(zcu);4289 const inst_scalar_ty = inst_ty.scalarType(zcu);
4269 const elem_ty = inst_scalar_ty.elemType2(zcu);4290 const elem_ty = inst_scalar_ty.elemType2(zcu);
4270 if (!elem_ty.hasRuntimeBitsIgnoreComptime(zcu)) return f.moveCValue(inst, inst_ty, lhs);4291 if (!elem_ty.hasRuntimeBitsIgnoreComptime(pt)) return f.moveCValue(inst, inst_ty, lhs);
4271 const inst_scalar_ctype = try f.ctypeFromType(inst_scalar_ty, .complete);4292 const inst_scalar_ctype = try f.ctypeFromType(inst_scalar_ty, .complete);
42724293
4273 const local = try f.allocLocal(inst, inst_ty);4294 const local = try f.allocLocal(inst, inst_ty);
...@@ -4299,13 +4320,14 @@ fn airPtrAddSub(f: *Function, inst: Air.Inst.Index, operator: u8) !CValue {...@@ -4299,13 +4320,14 @@ fn airPtrAddSub(f: *Function, inst: Air.Inst.Index, operator: u8) !CValue {
4299}4320}
43004321
4301fn airMinMax(f: *Function, inst: Air.Inst.Index, operator: u8, operation: []const u8) !CValue {4322fn airMinMax(f: *Function, inst: Air.Inst.Index, operator: u8, operation: []const u8) !CValue {
4302 const zcu = f.object.dg.zcu;4323 const pt = f.object.dg.pt;
4324 const zcu = pt.zcu;
4303 const bin_op = f.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;4325 const bin_op = f.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
43044326
4305 const inst_ty = f.typeOfIndex(inst);4327 const inst_ty = f.typeOfIndex(inst);
4306 const inst_scalar_ty = inst_ty.scalarType(zcu);4328 const inst_scalar_ty = inst_ty.scalarType(zcu);
43074329
4308 if ((inst_scalar_ty.isInt(zcu) and inst_scalar_ty.bitSize(zcu) > 64) or inst_scalar_ty.isRuntimeFloat())4330 if ((inst_scalar_ty.isInt(zcu) and inst_scalar_ty.bitSize(pt) > 64) or inst_scalar_ty.isRuntimeFloat())
4309 return try airBinBuiltinCall(f, inst, operation, .none);4331 return try airBinBuiltinCall(f, inst, operation, .none);
43104332
4311 const lhs = try f.resolveInst(bin_op.lhs);4333 const lhs = try f.resolveInst(bin_op.lhs);
...@@ -4339,7 +4361,8 @@ fn airMinMax(f: *Function, inst: Air.Inst.Index, operator: u8, operation: []cons...@@ -4339,7 +4361,8 @@ fn airMinMax(f: *Function, inst: Air.Inst.Index, operator: u8, operation: []cons
4339}4361}
43404362
4341fn airSlice(f: *Function, inst: Air.Inst.Index) !CValue {4363fn airSlice(f: *Function, inst: Air.Inst.Index) !CValue {
4342 const zcu = f.object.dg.zcu;4364 const pt = f.object.dg.pt;
4365 const zcu = pt.zcu;
4343 const ty_pl = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;4366 const ty_pl = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
4344 const bin_op = f.air.extraData(Air.Bin, ty_pl.payload).data;4367 const bin_op = f.air.extraData(Air.Bin, ty_pl.payload).data;
43454368
...@@ -4374,7 +4397,8 @@ fn airCall(...@@ -4374,7 +4397,8 @@ fn airCall(
4374 inst: Air.Inst.Index,4397 inst: Air.Inst.Index,
4375 modifier: std.builtin.CallModifier,4398 modifier: std.builtin.CallModifier,
4376) !CValue {4399) !CValue {
4377 const zcu = f.object.dg.zcu;4400 const pt = f.object.dg.pt;
4401 const zcu = pt.zcu;
4378 // Not even allowed to call panic in a naked function.4402 // Not even allowed to call panic in a naked function.
4379 if (f.object.dg.is_naked_fn) return .none;4403 if (f.object.dg.is_naked_fn) return .none;
43804404
...@@ -4398,7 +4422,7 @@ fn airCall(...@@ -4398,7 +4422,7 @@ fn airCall(
4398 if (!arg_ctype.eql(try f.ctypeFromType(arg_ty, .complete))) {4422 if (!arg_ctype.eql(try f.ctypeFromType(arg_ty, .complete))) {
4399 const array_local = try f.allocAlignedLocal(inst, .{4423 const array_local = try f.allocAlignedLocal(inst, .{
4400 .ctype = arg_ctype,4424 .ctype = arg_ctype,
4401 .alignas = CType.AlignAs.fromAbiAlignment(arg_ty.abiAlignment(zcu)),4425 .alignas = CType.AlignAs.fromAbiAlignment(arg_ty.abiAlignment(pt)),
4402 });4426 });
4403 try writer.writeAll("memcpy(");4427 try writer.writeAll("memcpy(");
4404 try f.writeCValueMember(writer, array_local, .{ .identifier = "array" });4428 try f.writeCValueMember(writer, array_local, .{ .identifier = "array" });
...@@ -4445,7 +4469,7 @@ fn airCall(...@@ -4445,7 +4469,7 @@ fn airCall(
4445 } else {4469 } else {
4446 const local = try f.allocAlignedLocal(inst, .{4470 const local = try f.allocAlignedLocal(inst, .{
4447 .ctype = ret_ctype,4471 .ctype = ret_ctype,
4448 .alignas = CType.AlignAs.fromAbiAlignment(ret_ty.abiAlignment(zcu)),4472 .alignas = CType.AlignAs.fromAbiAlignment(ret_ty.abiAlignment(pt)),
4449 });4473 });
4450 try f.writeCValue(writer, local, .Other);4474 try f.writeCValue(writer, local, .Other);
4451 try writer.writeAll(" = ");4475 try writer.writeAll(" = ");
...@@ -4456,7 +4480,7 @@ fn airCall(...@@ -4456,7 +4480,7 @@ fn airCall(
4456 callee: {4480 callee: {
4457 known: {4481 known: {
4458 const fn_decl = fn_decl: {4482 const fn_decl = fn_decl: {
4459 const callee_val = (try f.air.value(pl_op.operand, zcu)) orelse break :known;4483 const callee_val = (try f.air.value(pl_op.operand, pt)) orelse break :known;
4460 break :fn_decl switch (zcu.intern_pool.indexToKey(callee_val.toIntern())) {4484 break :fn_decl switch (zcu.intern_pool.indexToKey(callee_val.toIntern())) {
4461 .extern_func => |extern_func| extern_func.decl,4485 .extern_func => |extern_func| extern_func.decl,
4462 .func => |func| func.owner_decl,4486 .func => |func| func.owner_decl,
...@@ -4499,7 +4523,7 @@ fn airCall(...@@ -4499,7 +4523,7 @@ fn airCall(
4499 try writer.writeAll(");\n");4523 try writer.writeAll(");\n");
45004524
4501 const result = result: {4525 const result = result: {
4502 if (result_local == .none or !lowersToArray(ret_ty, zcu))4526 if (result_local == .none or !lowersToArray(ret_ty, pt))
4503 break :result result_local;4527 break :result result_local;
45044528
4505 const array_local = try f.allocLocal(inst, ret_ty);4529 const array_local = try f.allocLocal(inst, ret_ty);
...@@ -4533,7 +4557,8 @@ fn airDbgStmt(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -4533,7 +4557,8 @@ fn airDbgStmt(f: *Function, inst: Air.Inst.Index) !CValue {
4533}4557}
45344558
4535fn airDbgInlineBlock(f: *Function, inst: Air.Inst.Index) !CValue {4559fn airDbgInlineBlock(f: *Function, inst: Air.Inst.Index) !CValue {
4536 const zcu = f.object.dg.zcu;4560 const pt = f.object.dg.pt;
4561 const zcu = pt.zcu;
4537 const ty_pl = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;4562 const ty_pl = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
4538 const extra = f.air.extraData(Air.DbgInlineBlock, ty_pl.payload);4563 const extra = f.air.extraData(Air.DbgInlineBlock, ty_pl.payload);
4539 const owner_decl = zcu.funcOwnerDeclPtr(extra.data.func);4564 const owner_decl = zcu.funcOwnerDeclPtr(extra.data.func);
...@@ -4545,10 +4570,11 @@ fn airDbgInlineBlock(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -4545,10 +4570,11 @@ fn airDbgInlineBlock(f: *Function, inst: Air.Inst.Index) !CValue {
4545}4570}
45464571
4547fn airDbgVar(f: *Function, inst: Air.Inst.Index) !CValue {4572fn airDbgVar(f: *Function, inst: Air.Inst.Index) !CValue {
4548 const zcu = f.object.dg.zcu;4573 const pt = f.object.dg.pt;
4574 const zcu = pt.zcu;
4549 const pl_op = f.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;4575 const pl_op = f.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;
4550 const name = f.air.nullTerminatedString(pl_op.payload);4576 const name = f.air.nullTerminatedString(pl_op.payload);
4551 const operand_is_undef = if (try f.air.value(pl_op.operand, zcu)) |v| v.isUndefDeep(zcu) else false;4577 const operand_is_undef = if (try f.air.value(pl_op.operand, pt)) |v| v.isUndefDeep(zcu) else false;
4552 if (!operand_is_undef) _ = try f.resolveInst(pl_op.operand);4578 if (!operand_is_undef) _ = try f.resolveInst(pl_op.operand);
45534579
4554 try reap(f, inst, &.{pl_op.operand});4580 try reap(f, inst, &.{pl_op.operand});
...@@ -4564,7 +4590,8 @@ fn airBlock(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -4564,7 +4590,8 @@ fn airBlock(f: *Function, inst: Air.Inst.Index) !CValue {
4564}4590}
45654591
4566fn lowerBlock(f: *Function, inst: Air.Inst.Index, body: []const Air.Inst.Index) !CValue {4592fn lowerBlock(f: *Function, inst: Air.Inst.Index, body: []const Air.Inst.Index) !CValue {
4567 const zcu = f.object.dg.zcu;4593 const pt = f.object.dg.pt;
4594 const zcu = pt.zcu;
4568 const liveness_block = f.liveness.getBlock(inst);4595 const liveness_block = f.liveness.getBlock(inst);
45694596
4570 const block_id: usize = f.next_block_index;4597 const block_id: usize = f.next_block_index;
...@@ -4572,7 +4599,7 @@ fn lowerBlock(f: *Function, inst: Air.Inst.Index, body: []const Air.Inst.Index)...@@ -4572,7 +4599,7 @@ fn lowerBlock(f: *Function, inst: Air.Inst.Index, body: []const Air.Inst.Index)
4572 const writer = f.object.writer();4599 const writer = f.object.writer();
45734600
4574 const inst_ty = f.typeOfIndex(inst);4601 const inst_ty = f.typeOfIndex(inst);
4575 const result = if (inst_ty.hasRuntimeBitsIgnoreComptime(zcu) and !f.liveness.isUnused(inst))4602 const result = if (inst_ty.hasRuntimeBitsIgnoreComptime(pt) and !f.liveness.isUnused(inst))
4576 try f.allocLocal(inst, inst_ty)4603 try f.allocLocal(inst, inst_ty)
4577 else4604 else
4578 .none;4605 .none;
...@@ -4611,7 +4638,8 @@ fn airTry(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -4611,7 +4638,8 @@ fn airTry(f: *Function, inst: Air.Inst.Index) !CValue {
4611}4638}
46124639
4613fn airTryPtr(f: *Function, inst: Air.Inst.Index) !CValue {4640fn airTryPtr(f: *Function, inst: Air.Inst.Index) !CValue {
4614 const zcu = f.object.dg.zcu;4641 const pt = f.object.dg.pt;
4642 const zcu = pt.zcu;
4615 const ty_pl = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;4643 const ty_pl = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
4616 const extra = f.air.extraData(Air.TryPtr, ty_pl.payload);4644 const extra = f.air.extraData(Air.TryPtr, ty_pl.payload);
4617 const body: []const Air.Inst.Index = @ptrCast(f.air.extra[extra.end..][0..extra.data.body_len]);4645 const body: []const Air.Inst.Index = @ptrCast(f.air.extra[extra.end..][0..extra.data.body_len]);
...@@ -4627,13 +4655,14 @@ fn lowerTry(...@@ -4627,13 +4655,14 @@ fn lowerTry(
4627 err_union_ty: Type,4655 err_union_ty: Type,
4628 is_ptr: bool,4656 is_ptr: bool,
4629) !CValue {4657) !CValue {
4630 const zcu = f.object.dg.zcu;4658 const pt = f.object.dg.pt;
4659 const zcu = pt.zcu;
4631 const err_union = try f.resolveInst(operand);4660 const err_union = try f.resolveInst(operand);
4632 const inst_ty = f.typeOfIndex(inst);4661 const inst_ty = f.typeOfIndex(inst);
4633 const liveness_condbr = f.liveness.getCondBr(inst);4662 const liveness_condbr = f.liveness.getCondBr(inst);
4634 const writer = f.object.writer();4663 const writer = f.object.writer();
4635 const payload_ty = err_union_ty.errorUnionPayload(zcu);4664 const payload_ty = err_union_ty.errorUnionPayload(zcu);
4636 const payload_has_bits = payload_ty.hasRuntimeBitsIgnoreComptime(zcu);4665 const payload_has_bits = payload_ty.hasRuntimeBitsIgnoreComptime(pt);
46374666
4638 if (!err_union_ty.errorUnionSet(zcu).errorSetIsEmpty(zcu)) {4667 if (!err_union_ty.errorUnionSet(zcu).errorSetIsEmpty(zcu)) {
4639 try writer.writeAll("if (");4668 try writer.writeAll("if (");
...@@ -4725,7 +4754,8 @@ fn airBitcast(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -4725,7 +4754,8 @@ fn airBitcast(f: *Function, inst: Air.Inst.Index) !CValue {
4725}4754}
47264755
4727fn bitcast(f: *Function, dest_ty: Type, operand: CValue, operand_ty: Type) !CValue {4756fn bitcast(f: *Function, dest_ty: Type, operand: CValue, operand_ty: Type) !CValue {
4728 const zcu = f.object.dg.zcu;4757 const pt = f.object.dg.pt;
4758 const zcu = pt.zcu;
4729 const target = &f.object.dg.mod.resolved_target.result;4759 const target = &f.object.dg.mod.resolved_target.result;
4730 const ctype_pool = &f.object.dg.ctype_pool;4760 const ctype_pool = &f.object.dg.ctype_pool;
4731 const writer = f.object.writer();4761 const writer = f.object.writer();
...@@ -4771,7 +4801,7 @@ fn bitcast(f: *Function, dest_ty: Type, operand: CValue, operand_ty: Type) !CVal...@@ -4771,7 +4801,7 @@ fn bitcast(f: *Function, dest_ty: Type, operand: CValue, operand_ty: Type) !CVal
4771 try writer.writeAll(", sizeof(");4801 try writer.writeAll(", sizeof(");
4772 try f.renderType(4802 try f.renderType(
4773 writer,4803 writer,
4774 if (dest_ty.abiSize(zcu) <= operand_ty.abiSize(zcu)) dest_ty else operand_ty,4804 if (dest_ty.abiSize(pt) <= operand_ty.abiSize(pt)) dest_ty else operand_ty,
4775 );4805 );
4776 try writer.writeAll("));\n");4806 try writer.writeAll("));\n");
47774807
...@@ -4805,7 +4835,7 @@ fn bitcast(f: *Function, dest_ty: Type, operand: CValue, operand_ty: Type) !CVal...@@ -4805,7 +4835,7 @@ fn bitcast(f: *Function, dest_ty: Type, operand: CValue, operand_ty: Type) !CVal
4805 try writer.writeByte('(');4835 try writer.writeByte('(');
4806 }4836 }
4807 try writer.writeAll("zig_wrap_");4837 try writer.writeAll("zig_wrap_");
4808 const info_ty = try zcu.intType(dest_info.signedness, bits);4838 const info_ty = try pt.intType(dest_info.signedness, bits);
4809 if (wrap_ctype) |ctype|4839 if (wrap_ctype) |ctype|
4810 try f.object.dg.renderCTypeForBuiltinFnName(writer, ctype)4840 try f.object.dg.renderCTypeForBuiltinFnName(writer, ctype)
4811 else4841 else
...@@ -4935,7 +4965,8 @@ fn airCondBr(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -4935,7 +4965,8 @@ fn airCondBr(f: *Function, inst: Air.Inst.Index) !CValue {
4935}4965}
49364966
4937fn airSwitchBr(f: *Function, inst: Air.Inst.Index) !CValue {4967fn airSwitchBr(f: *Function, inst: Air.Inst.Index) !CValue {
4938 const zcu = f.object.dg.zcu;4968 const pt = f.object.dg.pt;
4969 const zcu = pt.zcu;
4939 const pl_op = f.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;4970 const pl_op = f.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;
4940 const condition = try f.resolveInst(pl_op.operand);4971 const condition = try f.resolveInst(pl_op.operand);
4941 try reap(f, inst, &.{pl_op.operand});4972 try reap(f, inst, &.{pl_op.operand});
...@@ -4979,16 +5010,16 @@ fn airSwitchBr(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -4979,16 +5010,16 @@ fn airSwitchBr(f: *Function, inst: Air.Inst.Index) !CValue {
4979 for (items) |item| {5010 for (items) |item| {
4980 try f.object.indent_writer.insertNewline();5011 try f.object.indent_writer.insertNewline();
4981 try writer.writeAll("case ");5012 try writer.writeAll("case ");
4982 const item_value = try f.air.value(item, zcu);5013 const item_value = try f.air.value(item, pt);
4983 if (item_value.?.getUnsignedInt(zcu)) |item_int| try writer.print("{}\n", .{5014 if (item_value.?.getUnsignedInt(pt)) |item_int| try writer.print("{}\n", .{
4984 try f.fmtIntLiteral(try zcu.intValue(lowered_condition_ty, item_int)),5015 try f.fmtIntLiteral(try pt.intValue(lowered_condition_ty, item_int)),
4985 }) else {5016 }) else {
4986 if (condition_ty.isPtrAtRuntime(zcu)) {5017 if (condition_ty.isPtrAtRuntime(zcu)) {
4987 try writer.writeByte('(');5018 try writer.writeByte('(');
4988 try f.renderType(writer, Type.usize);5019 try f.renderType(writer, Type.usize);
4989 try writer.writeByte(')');5020 try writer.writeByte(')');
4990 }5021 }
4991 try f.object.dg.renderValue(writer, (try f.air.value(item, zcu)).?, .Other);5022 try f.object.dg.renderValue(writer, (try f.air.value(item, pt)).?, .Other);
4992 }5023 }
4993 try writer.writeByte(':');5024 try writer.writeByte(':');
4994 }5025 }
...@@ -5026,13 +5057,14 @@ fn airSwitchBr(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -5026,13 +5057,14 @@ fn airSwitchBr(f: *Function, inst: Air.Inst.Index) !CValue {
5026}5057}
50275058
5028fn asmInputNeedsLocal(f: *Function, constraint: []const u8, value: CValue) bool {5059fn asmInputNeedsLocal(f: *Function, constraint: []const u8, value: CValue) bool {
5029 const target = &f.object.dg.mod.resolved_target.result;5060 const dg = f.object.dg;
5061 const target = &dg.mod.resolved_target.result;
5030 return switch (constraint[0]) {5062 return switch (constraint[0]) {
5031 '{' => true,5063 '{' => true,
5032 'i', 'r' => false,5064 'i', 'r' => false,
5033 'I' => !target.cpu.arch.isArmOrThumb(),5065 'I' => !target.cpu.arch.isArmOrThumb(),
5034 else => switch (value) {5066 else => switch (value) {
5035 .constant => |val| switch (f.object.dg.zcu.intern_pool.indexToKey(val.toIntern())) {5067 .constant => |val| switch (dg.pt.zcu.intern_pool.indexToKey(val.toIntern())) {
5036 .ptr => |ptr| if (ptr.byte_offset == 0) switch (ptr.base_addr) {5068 .ptr => |ptr| if (ptr.byte_offset == 0) switch (ptr.base_addr) {
5037 .decl => false,5069 .decl => false,
5038 else => true,5070 else => true,
...@@ -5045,7 +5077,8 @@ fn asmInputNeedsLocal(f: *Function, constraint: []const u8, value: CValue) bool...@@ -5045,7 +5077,8 @@ fn asmInputNeedsLocal(f: *Function, constraint: []const u8, value: CValue) bool
5045}5077}
50465078
5047fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue {5079fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue {
5048 const zcu = f.object.dg.zcu;5080 const pt = f.object.dg.pt;
5081 const zcu = pt.zcu;
5049 const ty_pl = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;5082 const ty_pl = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
5050 const extra = f.air.extraData(Air.Asm, ty_pl.payload);5083 const extra = f.air.extraData(Air.Asm, ty_pl.payload);
5051 const is_volatile = @as(u1, @truncate(extra.data.flags >> 31)) != 0;5084 const is_volatile = @as(u1, @truncate(extra.data.flags >> 31)) != 0;
...@@ -5060,10 +5093,10 @@ fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -5060,10 +5093,10 @@ fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue {
5060 const result = result: {5093 const result = result: {
5061 const writer = f.object.writer();5094 const writer = f.object.writer();
5062 const inst_ty = f.typeOfIndex(inst);5095 const inst_ty = f.typeOfIndex(inst);
5063 const inst_local = if (inst_ty.hasRuntimeBitsIgnoreComptime(zcu)) local: {5096 const inst_local = if (inst_ty.hasRuntimeBitsIgnoreComptime(pt)) local: {
5064 const inst_local = try f.allocLocalValue(.{5097 const inst_local = try f.allocLocalValue(.{
5065 .ctype = try f.ctypeFromType(inst_ty, .complete),5098 .ctype = try f.ctypeFromType(inst_ty, .complete),
5066 .alignas = CType.AlignAs.fromAbiAlignment(inst_ty.abiAlignment(zcu)),5099 .alignas = CType.AlignAs.fromAbiAlignment(inst_ty.abiAlignment(pt)),
5067 });5100 });
5068 if (f.wantSafety()) {5101 if (f.wantSafety()) {
5069 try f.writeCValue(writer, inst_local, .Other);5102 try f.writeCValue(writer, inst_local, .Other);
...@@ -5096,7 +5129,7 @@ fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -5096,7 +5129,7 @@ fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue {
5096 try writer.writeAll("register ");5129 try writer.writeAll("register ");
5097 const output_local = try f.allocLocalValue(.{5130 const output_local = try f.allocLocalValue(.{
5098 .ctype = try f.ctypeFromType(output_ty, .complete),5131 .ctype = try f.ctypeFromType(output_ty, .complete),
5099 .alignas = CType.AlignAs.fromAbiAlignment(output_ty.abiAlignment(zcu)),5132 .alignas = CType.AlignAs.fromAbiAlignment(output_ty.abiAlignment(pt)),
5100 });5133 });
5101 try f.allocs.put(gpa, output_local.new_local, false);5134 try f.allocs.put(gpa, output_local.new_local, false);
5102 try f.object.dg.renderTypeAndName(writer, output_ty, output_local, .{}, .none, .complete);5135 try f.object.dg.renderTypeAndName(writer, output_ty, output_local, .{}, .none, .complete);
...@@ -5131,7 +5164,7 @@ fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -5131,7 +5164,7 @@ fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue {
5131 if (is_reg) try writer.writeAll("register ");5164 if (is_reg) try writer.writeAll("register ");
5132 const input_local = try f.allocLocalValue(.{5165 const input_local = try f.allocLocalValue(.{
5133 .ctype = try f.ctypeFromType(input_ty, .complete),5166 .ctype = try f.ctypeFromType(input_ty, .complete),
5134 .alignas = CType.AlignAs.fromAbiAlignment(input_ty.abiAlignment(zcu)),5167 .alignas = CType.AlignAs.fromAbiAlignment(input_ty.abiAlignment(pt)),
5135 });5168 });
5136 try f.allocs.put(gpa, input_local.new_local, false);5169 try f.allocs.put(gpa, input_local.new_local, false);
5137 try f.object.dg.renderTypeAndName(writer, input_ty, input_local, Const, .none, .complete);5170 try f.object.dg.renderTypeAndName(writer, input_ty, input_local, Const, .none, .complete);
...@@ -5314,7 +5347,8 @@ fn airIsNull(...@@ -5314,7 +5347,8 @@ fn airIsNull(
5314 operator: std.math.CompareOperator,5347 operator: std.math.CompareOperator,
5315 is_ptr: bool,5348 is_ptr: bool,
5316) !CValue {5349) !CValue {
5317 const zcu = f.object.dg.zcu;5350 const pt = f.object.dg.pt;
5351 const zcu = pt.zcu;
5318 const ctype_pool = &f.object.dg.ctype_pool;5352 const ctype_pool = &f.object.dg.ctype_pool;
5319 const un_op = f.air.instructions.items(.data)[@intFromEnum(inst)].un_op;5353 const un_op = f.air.instructions.items(.data)[@intFromEnum(inst)].un_op;
53205354
...@@ -5369,7 +5403,8 @@ fn airIsNull(...@@ -5369,7 +5403,8 @@ fn airIsNull(
5369}5403}
53705404
5371fn airOptionalPayload(f: *Function, inst: Air.Inst.Index, is_ptr: bool) !CValue {5405fn airOptionalPayload(f: *Function, inst: Air.Inst.Index, is_ptr: bool) !CValue {
5372 const zcu = f.object.dg.zcu;5406 const pt = f.object.dg.pt;
5407 const zcu = pt.zcu;
5373 const ctype_pool = &f.object.dg.ctype_pool;5408 const ctype_pool = &f.object.dg.ctype_pool;
5374 const ty_op = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;5409 const ty_op = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
53755410
...@@ -5404,7 +5439,8 @@ fn airOptionalPayload(f: *Function, inst: Air.Inst.Index, is_ptr: bool) !CValue...@@ -5404,7 +5439,8 @@ fn airOptionalPayload(f: *Function, inst: Air.Inst.Index, is_ptr: bool) !CValue
5404}5439}
54055440
5406fn airOptionalPayloadPtrSet(f: *Function, inst: Air.Inst.Index) !CValue {5441fn airOptionalPayloadPtrSet(f: *Function, inst: Air.Inst.Index) !CValue {
5407 const zcu = f.object.dg.zcu;5442 const pt = f.object.dg.pt;
5443 const zcu = pt.zcu;
5408 const ty_op = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;5444 const ty_op = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
5409 const writer = f.object.writer();5445 const writer = f.object.writer();
5410 const operand = try f.resolveInst(ty_op.operand);5446 const operand = try f.resolveInst(ty_op.operand);
...@@ -5458,21 +5494,22 @@ fn fieldLocation(...@@ -5458,21 +5494,22 @@ fn fieldLocation(
5458 container_ptr_ty: Type,5494 container_ptr_ty: Type,
5459 field_ptr_ty: Type,5495 field_ptr_ty: Type,
5460 field_index: u32,5496 field_index: u32,
5461 zcu: *Zcu,5497 pt: Zcu.PerThread,
5462) union(enum) {5498) union(enum) {
5463 begin: void,5499 begin: void,
5464 field: CValue,5500 field: CValue,
5465 byte_offset: u64,5501 byte_offset: u64,
5466} {5502} {
5503 const zcu = pt.zcu;
5467 const ip = &zcu.intern_pool;5504 const ip = &zcu.intern_pool;
5468 const container_ty = Type.fromInterned(ip.indexToKey(container_ptr_ty.toIntern()).ptr_type.child);5505 const container_ty = Type.fromInterned(ip.indexToKey(container_ptr_ty.toIntern()).ptr_type.child);
5469 switch (ip.indexToKey(container_ty.toIntern())) {5506 switch (ip.indexToKey(container_ty.toIntern())) {
5470 .struct_type => {5507 .struct_type => {
5471 const loaded_struct = ip.loadStructType(container_ty.toIntern());5508 const loaded_struct = ip.loadStructType(container_ty.toIntern());
5472 return switch (loaded_struct.layout) {5509 return switch (loaded_struct.layout) {
5473 .auto, .@"extern" => if (!container_ty.hasRuntimeBitsIgnoreComptime(zcu))5510 .auto, .@"extern" => if (!container_ty.hasRuntimeBitsIgnoreComptime(pt))
5474 .begin5511 .begin
5475 else if (!field_ptr_ty.childType(zcu).hasRuntimeBitsIgnoreComptime(zcu))5512 else if (!field_ptr_ty.childType(zcu).hasRuntimeBitsIgnoreComptime(pt))
5476 .{ .byte_offset = loaded_struct.offsets.get(ip)[field_index] }5513 .{ .byte_offset = loaded_struct.offsets.get(ip)[field_index] }
5477 else5514 else
5478 .{ .field = if (loaded_struct.fieldName(ip, field_index).unwrap()) |field_name|5515 .{ .field = if (loaded_struct.fieldName(ip, field_index).unwrap()) |field_name|
...@@ -5480,16 +5517,16 @@ fn fieldLocation(...@@ -5480,16 +5517,16 @@ fn fieldLocation(
5480 else5517 else
5481 .{ .field = field_index } },5518 .{ .field = field_index } },
5482 .@"packed" => if (field_ptr_ty.ptrInfo(zcu).packed_offset.host_size == 0)5519 .@"packed" => if (field_ptr_ty.ptrInfo(zcu).packed_offset.host_size == 0)
5483 .{ .byte_offset = @divExact(zcu.structPackedFieldBitOffset(loaded_struct, field_index) +5520 .{ .byte_offset = @divExact(pt.structPackedFieldBitOffset(loaded_struct, field_index) +
5484 container_ptr_ty.ptrInfo(zcu).packed_offset.bit_offset, 8) }5521 container_ptr_ty.ptrInfo(zcu).packed_offset.bit_offset, 8) }
5485 else5522 else
5486 .begin,5523 .begin,
5487 };5524 };
5488 },5525 },
5489 .anon_struct_type => |anon_struct_info| return if (!container_ty.hasRuntimeBitsIgnoreComptime(zcu))5526 .anon_struct_type => |anon_struct_info| return if (!container_ty.hasRuntimeBitsIgnoreComptime(pt))
5490 .begin5527 .begin
5491 else if (!field_ptr_ty.childType(zcu).hasRuntimeBitsIgnoreComptime(zcu))5528 else if (!field_ptr_ty.childType(zcu).hasRuntimeBitsIgnoreComptime(pt))
5492 .{ .byte_offset = container_ty.structFieldOffset(field_index, zcu) }5529 .{ .byte_offset = container_ty.structFieldOffset(field_index, pt) }
5493 else5530 else
5494 .{ .field = if (anon_struct_info.fieldName(ip, field_index).unwrap()) |field_name|5531 .{ .field = if (anon_struct_info.fieldName(ip, field_index).unwrap()) |field_name|
5495 .{ .identifier = field_name.toSlice(ip) }5532 .{ .identifier = field_name.toSlice(ip) }
...@@ -5500,8 +5537,8 @@ fn fieldLocation(...@@ -5500,8 +5537,8 @@ fn fieldLocation(
5500 switch (loaded_union.getLayout(ip)) {5537 switch (loaded_union.getLayout(ip)) {
5501 .auto, .@"extern" => {5538 .auto, .@"extern" => {
5502 const field_ty = Type.fromInterned(loaded_union.field_types.get(ip)[field_index]);5539 const field_ty = Type.fromInterned(loaded_union.field_types.get(ip)[field_index]);
5503 if (!field_ty.hasRuntimeBitsIgnoreComptime(zcu))5540 if (!field_ty.hasRuntimeBitsIgnoreComptime(pt))
5504 return if (loaded_union.hasTag(ip) and !container_ty.unionHasAllZeroBitFieldTypes(zcu))5541 return if (loaded_union.hasTag(ip) and !container_ty.unionHasAllZeroBitFieldTypes(pt))
5505 .{ .field = .{ .identifier = "payload" } }5542 .{ .field = .{ .identifier = "payload" } }
5506 else5543 else
5507 .begin;5544 .begin;
...@@ -5546,7 +5583,8 @@ fn airStructFieldPtrIndex(f: *Function, inst: Air.Inst.Index, index: u8) !CValue...@@ -5546,7 +5583,8 @@ fn airStructFieldPtrIndex(f: *Function, inst: Air.Inst.Index, index: u8) !CValue
5546}5583}
55475584
5548fn airFieldParentPtr(f: *Function, inst: Air.Inst.Index) !CValue {5585fn airFieldParentPtr(f: *Function, inst: Air.Inst.Index) !CValue {
5549 const zcu = f.object.dg.zcu;5586 const pt = f.object.dg.pt;
5587 const zcu = pt.zcu;
5550 const ty_pl = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;5588 const ty_pl = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
5551 const extra = f.air.extraData(Air.FieldParentPtr, ty_pl.payload).data;5589 const extra = f.air.extraData(Air.FieldParentPtr, ty_pl.payload).data;
55525590
...@@ -5564,10 +5602,10 @@ fn airFieldParentPtr(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -5564,10 +5602,10 @@ fn airFieldParentPtr(f: *Function, inst: Air.Inst.Index) !CValue {
5564 try f.renderType(writer, container_ptr_ty);5602 try f.renderType(writer, container_ptr_ty);
5565 try writer.writeByte(')');5603 try writer.writeByte(')');
55665604
5567 switch (fieldLocation(container_ptr_ty, field_ptr_ty, extra.field_index, zcu)) {5605 switch (fieldLocation(container_ptr_ty, field_ptr_ty, extra.field_index, pt)) {
5568 .begin => try f.writeCValue(writer, field_ptr_val, .Initializer),5606 .begin => try f.writeCValue(writer, field_ptr_val, .Initializer),
5569 .field => |field| {5607 .field => |field| {
5570 const u8_ptr_ty = try zcu.adjustPtrTypeChild(field_ptr_ty, Type.u8);5608 const u8_ptr_ty = try pt.adjustPtrTypeChild(field_ptr_ty, Type.u8);
55715609
5572 try writer.writeAll("((");5610 try writer.writeAll("((");
5573 try f.renderType(writer, u8_ptr_ty);5611 try f.renderType(writer, u8_ptr_ty);
...@@ -5580,14 +5618,14 @@ fn airFieldParentPtr(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -5580,14 +5618,14 @@ fn airFieldParentPtr(f: *Function, inst: Air.Inst.Index) !CValue {
5580 try writer.writeAll("))");5618 try writer.writeAll("))");
5581 },5619 },
5582 .byte_offset => |byte_offset| {5620 .byte_offset => |byte_offset| {
5583 const u8_ptr_ty = try zcu.adjustPtrTypeChild(field_ptr_ty, Type.u8);5621 const u8_ptr_ty = try pt.adjustPtrTypeChild(field_ptr_ty, Type.u8);
55845622
5585 try writer.writeAll("((");5623 try writer.writeAll("((");
5586 try f.renderType(writer, u8_ptr_ty);5624 try f.renderType(writer, u8_ptr_ty);
5587 try writer.writeByte(')');5625 try writer.writeByte(')');
5588 try f.writeCValue(writer, field_ptr_val, .Other);5626 try f.writeCValue(writer, field_ptr_val, .Other);
5589 try writer.print(" - {})", .{5627 try writer.print(" - {})", .{
5590 try f.fmtIntLiteral(try zcu.intValue(Type.usize, byte_offset)),5628 try f.fmtIntLiteral(try pt.intValue(Type.usize, byte_offset)),
5591 });5629 });
5592 },5630 },
5593 }5631 }
...@@ -5603,7 +5641,8 @@ fn fieldPtr(...@@ -5603,7 +5641,8 @@ fn fieldPtr(
5603 container_ptr_val: CValue,5641 container_ptr_val: CValue,
5604 field_index: u32,5642 field_index: u32,
5605) !CValue {5643) !CValue {
5606 const zcu = f.object.dg.zcu;5644 const pt = f.object.dg.pt;
5645 const zcu = pt.zcu;
5607 const container_ty = container_ptr_ty.childType(zcu);5646 const container_ty = container_ptr_ty.childType(zcu);
5608 const field_ptr_ty = f.typeOfIndex(inst);5647 const field_ptr_ty = f.typeOfIndex(inst);
56095648
...@@ -5617,21 +5656,21 @@ fn fieldPtr(...@@ -5617,21 +5656,21 @@ fn fieldPtr(
5617 try f.renderType(writer, field_ptr_ty);5656 try f.renderType(writer, field_ptr_ty);
5618 try writer.writeByte(')');5657 try writer.writeByte(')');
56195658
5620 switch (fieldLocation(container_ptr_ty, field_ptr_ty, field_index, zcu)) {5659 switch (fieldLocation(container_ptr_ty, field_ptr_ty, field_index, pt)) {
5621 .begin => try f.writeCValue(writer, container_ptr_val, .Initializer),5660 .begin => try f.writeCValue(writer, container_ptr_val, .Initializer),
5622 .field => |field| {5661 .field => |field| {
5623 try writer.writeByte('&');5662 try writer.writeByte('&');
5624 try f.writeCValueDerefMember(writer, container_ptr_val, field);5663 try f.writeCValueDerefMember(writer, container_ptr_val, field);
5625 },5664 },
5626 .byte_offset => |byte_offset| {5665 .byte_offset => |byte_offset| {
5627 const u8_ptr_ty = try zcu.adjustPtrTypeChild(field_ptr_ty, Type.u8);5666 const u8_ptr_ty = try pt.adjustPtrTypeChild(field_ptr_ty, Type.u8);
56285667
5629 try writer.writeAll("((");5668 try writer.writeAll("((");
5630 try f.renderType(writer, u8_ptr_ty);5669 try f.renderType(writer, u8_ptr_ty);
5631 try writer.writeByte(')');5670 try writer.writeByte(')');
5632 try f.writeCValue(writer, container_ptr_val, .Other);5671 try f.writeCValue(writer, container_ptr_val, .Other);
5633 try writer.print(" + {})", .{5672 try writer.print(" + {})", .{
5634 try f.fmtIntLiteral(try zcu.intValue(Type.usize, byte_offset)),5673 try f.fmtIntLiteral(try pt.intValue(Type.usize, byte_offset)),
5635 });5674 });
5636 },5675 },
5637 }5676 }
...@@ -5641,13 +5680,14 @@ fn fieldPtr(...@@ -5641,13 +5680,14 @@ fn fieldPtr(
5641}5680}
56425681
5643fn airStructFieldVal(f: *Function, inst: Air.Inst.Index) !CValue {5682fn airStructFieldVal(f: *Function, inst: Air.Inst.Index) !CValue {
5644 const zcu = f.object.dg.zcu;5683 const pt = f.object.dg.pt;
5684 const zcu = pt.zcu;
5645 const ip = &zcu.intern_pool;5685 const ip = &zcu.intern_pool;
5646 const ty_pl = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;5686 const ty_pl = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
5647 const extra = f.air.extraData(Air.StructField, ty_pl.payload).data;5687 const extra = f.air.extraData(Air.StructField, ty_pl.payload).data;
56485688
5649 const inst_ty = f.typeOfIndex(inst);5689 const inst_ty = f.typeOfIndex(inst);
5650 if (!inst_ty.hasRuntimeBitsIgnoreComptime(zcu)) {5690 if (!inst_ty.hasRuntimeBitsIgnoreComptime(pt)) {
5651 try reap(f, inst, &.{extra.struct_operand});5691 try reap(f, inst, &.{extra.struct_operand});
5652 return .none;5692 return .none;
5653 }5693 }
...@@ -5671,15 +5711,15 @@ fn airStructFieldVal(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -5671,15 +5711,15 @@ fn airStructFieldVal(f: *Function, inst: Air.Inst.Index) !CValue {
5671 .@"packed" => {5711 .@"packed" => {
5672 const int_info = struct_ty.intInfo(zcu);5712 const int_info = struct_ty.intInfo(zcu);
56735713
5674 const bit_offset_ty = try zcu.intType(.unsigned, Type.smallestUnsignedBits(int_info.bits - 1));5714 const bit_offset_ty = try pt.intType(.unsigned, Type.smallestUnsignedBits(int_info.bits - 1));
56755715
5676 const bit_offset = zcu.structPackedFieldBitOffset(loaded_struct, extra.field_index);5716 const bit_offset = pt.structPackedFieldBitOffset(loaded_struct, extra.field_index);
56775717
5678 const field_int_signedness = if (inst_ty.isAbiInt(zcu))5718 const field_int_signedness = if (inst_ty.isAbiInt(zcu))
5679 inst_ty.intInfo(zcu).signedness5719 inst_ty.intInfo(zcu).signedness
5680 else5720 else
5681 .unsigned;5721 .unsigned;
5682 const field_int_ty = try zcu.intType(field_int_signedness, @as(u16, @intCast(inst_ty.bitSize(zcu))));5722 const field_int_ty = try pt.intType(field_int_signedness, @as(u16, @intCast(inst_ty.bitSize(pt))));
56835723
5684 const temp_local = try f.allocLocal(inst, field_int_ty);5724 const temp_local = try f.allocLocal(inst, field_int_ty);
5685 try f.writeCValue(writer, temp_local, .Other);5725 try f.writeCValue(writer, temp_local, .Other);
...@@ -5690,7 +5730,7 @@ fn airStructFieldVal(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -5690,7 +5730,7 @@ fn airStructFieldVal(f: *Function, inst: Air.Inst.Index) !CValue {
5690 try writer.writeByte(')');5730 try writer.writeByte(')');
5691 const cant_cast = int_info.bits > 64;5731 const cant_cast = int_info.bits > 64;
5692 if (cant_cast) {5732 if (cant_cast) {
5693 if (field_int_ty.bitSize(zcu) > 64) return f.fail("TODO: C backend: implement casting between types > 64 bits", .{});5733 if (field_int_ty.bitSize(pt) > 64) return f.fail("TODO: C backend: implement casting between types > 64 bits", .{});
5694 try writer.writeAll("zig_lo_");5734 try writer.writeAll("zig_lo_");
5695 try f.object.dg.renderTypeForBuiltinFnName(writer, struct_ty);5735 try f.object.dg.renderTypeForBuiltinFnName(writer, struct_ty);
5696 try writer.writeByte('(');5736 try writer.writeByte('(');
...@@ -5702,12 +5742,12 @@ fn airStructFieldVal(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -5702,12 +5742,12 @@ fn airStructFieldVal(f: *Function, inst: Air.Inst.Index) !CValue {
5702 }5742 }
5703 try f.writeCValue(writer, struct_byval, .Other);5743 try f.writeCValue(writer, struct_byval, .Other);
5704 if (bit_offset > 0) try writer.print(", {})", .{5744 if (bit_offset > 0) try writer.print(", {})", .{
5705 try f.fmtIntLiteral(try zcu.intValue(bit_offset_ty, bit_offset)),5745 try f.fmtIntLiteral(try pt.intValue(bit_offset_ty, bit_offset)),
5706 });5746 });
5707 if (cant_cast) try writer.writeByte(')');5747 if (cant_cast) try writer.writeByte(')');
5708 try f.object.dg.renderBuiltinInfo(writer, field_int_ty, .bits);5748 try f.object.dg.renderBuiltinInfo(writer, field_int_ty, .bits);
5709 try writer.writeAll(");\n");5749 try writer.writeAll(");\n");
5710 if (inst_ty.eql(field_int_ty, f.object.dg.zcu)) return temp_local;5750 if (inst_ty.eql(field_int_ty, zcu)) return temp_local;
57115751
5712 const local = try f.allocLocal(inst, inst_ty);5752 const local = try f.allocLocal(inst, inst_ty);
5713 if (local.new_local != temp_local.new_local) {5753 if (local.new_local != temp_local.new_local) {
...@@ -5783,7 +5823,8 @@ fn airStructFieldVal(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -5783,7 +5823,8 @@ fn airStructFieldVal(f: *Function, inst: Air.Inst.Index) !CValue {
5783/// *(E!T) -> E5823/// *(E!T) -> E
5784/// Note that the result is never a pointer.5824/// Note that the result is never a pointer.
5785fn airUnwrapErrUnionErr(f: *Function, inst: Air.Inst.Index) !CValue {5825fn airUnwrapErrUnionErr(f: *Function, inst: Air.Inst.Index) !CValue {
5786 const zcu = f.object.dg.zcu;5826 const pt = f.object.dg.pt;
5827 const zcu = pt.zcu;
5787 const ty_op = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;5828 const ty_op = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
57885829
5789 const inst_ty = f.typeOfIndex(inst);5830 const inst_ty = f.typeOfIndex(inst);
...@@ -5797,7 +5838,7 @@ fn airUnwrapErrUnionErr(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -5797,7 +5838,7 @@ fn airUnwrapErrUnionErr(f: *Function, inst: Air.Inst.Index) !CValue {
5797 const payload_ty = error_union_ty.errorUnionPayload(zcu);5838 const payload_ty = error_union_ty.errorUnionPayload(zcu);
5798 const local = try f.allocLocal(inst, inst_ty);5839 const local = try f.allocLocal(inst, inst_ty);
57995840
5800 if (!payload_ty.hasRuntimeBits(zcu) and operand == .local and operand.local == local.new_local) {5841 if (!payload_ty.hasRuntimeBits(pt) and operand == .local and operand.local == local.new_local) {
5801 // The store will be 'x = x'; elide it.5842 // The store will be 'x = x'; elide it.
5802 return local;5843 return local;
5803 }5844 }
...@@ -5806,11 +5847,11 @@ fn airUnwrapErrUnionErr(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -5806,11 +5847,11 @@ fn airUnwrapErrUnionErr(f: *Function, inst: Air.Inst.Index) !CValue {
5806 try f.writeCValue(writer, local, .Other);5847 try f.writeCValue(writer, local, .Other);
5807 try writer.writeAll(" = ");5848 try writer.writeAll(" = ");
58085849
5809 if (!payload_ty.hasRuntimeBits(zcu))5850 if (!payload_ty.hasRuntimeBits(pt))
5810 try f.writeCValue(writer, operand, .Other)5851 try f.writeCValue(writer, operand, .Other)
5811 else if (error_ty.errorSetIsEmpty(zcu))5852 else if (error_ty.errorSetIsEmpty(zcu))
5812 try writer.print("{}", .{5853 try writer.print("{}", .{
5813 try f.fmtIntLiteral(try zcu.intValue(try zcu.errorIntType(), 0)),5854 try f.fmtIntLiteral(try pt.intValue(try pt.errorIntType(), 0)),
5814 })5855 })
5815 else if (operand_is_ptr)5856 else if (operand_is_ptr)
5816 try f.writeCValueDerefMember(writer, operand, .{ .identifier = "error" })5857 try f.writeCValueDerefMember(writer, operand, .{ .identifier = "error" })
...@@ -5821,7 +5862,8 @@ fn airUnwrapErrUnionErr(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -5821,7 +5862,8 @@ fn airUnwrapErrUnionErr(f: *Function, inst: Air.Inst.Index) !CValue {
5821}5862}
58225863
5823fn airUnwrapErrUnionPay(f: *Function, inst: Air.Inst.Index, is_ptr: bool) !CValue {5864fn airUnwrapErrUnionPay(f: *Function, inst: Air.Inst.Index, is_ptr: bool) !CValue {
5824 const zcu = f.object.dg.zcu;5865 const pt = f.object.dg.pt;
5866 const zcu = pt.zcu;
5825 const ty_op = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;5867 const ty_op = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
58265868
5827 const inst_ty = f.typeOfIndex(inst);5869 const inst_ty = f.typeOfIndex(inst);
...@@ -5831,7 +5873,7 @@ fn airUnwrapErrUnionPay(f: *Function, inst: Air.Inst.Index, is_ptr: bool) !CValu...@@ -5831,7 +5873,7 @@ fn airUnwrapErrUnionPay(f: *Function, inst: Air.Inst.Index, is_ptr: bool) !CValu
5831 const error_union_ty = if (is_ptr) operand_ty.childType(zcu) else operand_ty;5873 const error_union_ty = if (is_ptr) operand_ty.childType(zcu) else operand_ty;
58325874
5833 const writer = f.object.writer();5875 const writer = f.object.writer();
5834 if (!error_union_ty.errorUnionPayload(zcu).hasRuntimeBits(zcu)) {5876 if (!error_union_ty.errorUnionPayload(zcu).hasRuntimeBits(pt)) {
5835 if (!is_ptr) return .none;5877 if (!is_ptr) return .none;
58365878
5837 const local = try f.allocLocal(inst, inst_ty);5879 const local = try f.allocLocal(inst, inst_ty);
...@@ -5896,12 +5938,13 @@ fn airWrapOptional(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -5896,12 +5938,13 @@ fn airWrapOptional(f: *Function, inst: Air.Inst.Index) !CValue {
5896}5938}
58975939
5898fn airWrapErrUnionErr(f: *Function, inst: Air.Inst.Index) !CValue {5940fn airWrapErrUnionErr(f: *Function, inst: Air.Inst.Index) !CValue {
5899 const zcu = f.object.dg.zcu;5941 const pt = f.object.dg.pt;
5942 const zcu = pt.zcu;
5900 const ty_op = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;5943 const ty_op = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
59015944
5902 const inst_ty = f.typeOfIndex(inst);5945 const inst_ty = f.typeOfIndex(inst);
5903 const payload_ty = inst_ty.errorUnionPayload(zcu);5946 const payload_ty = inst_ty.errorUnionPayload(zcu);
5904 const repr_is_err = !payload_ty.hasRuntimeBitsIgnoreComptime(zcu);5947 const repr_is_err = !payload_ty.hasRuntimeBitsIgnoreComptime(pt);
5905 const err_ty = inst_ty.errorUnionSet(zcu);5948 const err_ty = inst_ty.errorUnionSet(zcu);
5906 const err = try f.resolveInst(ty_op.operand);5949 const err = try f.resolveInst(ty_op.operand);
5907 try reap(f, inst, &.{ty_op.operand});5950 try reap(f, inst, &.{ty_op.operand});
...@@ -5935,7 +5978,8 @@ fn airWrapErrUnionErr(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -5935,7 +5978,8 @@ fn airWrapErrUnionErr(f: *Function, inst: Air.Inst.Index) !CValue {
5935}5978}
59365979
5937fn airErrUnionPayloadPtrSet(f: *Function, inst: Air.Inst.Index) !CValue {5980fn airErrUnionPayloadPtrSet(f: *Function, inst: Air.Inst.Index) !CValue {
5938 const zcu = f.object.dg.zcu;5981 const pt = f.object.dg.pt;
5982 const zcu = pt.zcu;
5939 const writer = f.object.writer();5983 const writer = f.object.writer();
5940 const ty_op = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;5984 const ty_op = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
5941 const inst_ty = f.typeOfIndex(inst);5985 const inst_ty = f.typeOfIndex(inst);
...@@ -5944,12 +5988,12 @@ fn airErrUnionPayloadPtrSet(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -5944,12 +5988,12 @@ fn airErrUnionPayloadPtrSet(f: *Function, inst: Air.Inst.Index) !CValue {
5944 const error_union_ty = operand_ty.childType(zcu);5988 const error_union_ty = operand_ty.childType(zcu);
59455989
5946 const payload_ty = error_union_ty.errorUnionPayload(zcu);5990 const payload_ty = error_union_ty.errorUnionPayload(zcu);
5947 const err_int_ty = try zcu.errorIntType();5991 const err_int_ty = try pt.errorIntType();
5948 const no_err = try zcu.intValue(err_int_ty, 0);5992 const no_err = try pt.intValue(err_int_ty, 0);
5949 try reap(f, inst, &.{ty_op.operand});5993 try reap(f, inst, &.{ty_op.operand});
59505994
5951 // First, set the non-error value.5995 // First, set the non-error value.
5952 if (!payload_ty.hasRuntimeBitsIgnoreComptime(zcu)) {5996 if (!payload_ty.hasRuntimeBitsIgnoreComptime(pt)) {
5953 const a = try Assignment.start(f, writer, try f.ctypeFromType(operand_ty, .complete));5997 const a = try Assignment.start(f, writer, try f.ctypeFromType(operand_ty, .complete));
5954 try f.writeCValueDeref(writer, operand);5998 try f.writeCValueDeref(writer, operand);
5955 try a.assign(f, writer);5999 try a.assign(f, writer);
...@@ -5994,13 +6038,14 @@ fn airSaveErrReturnTraceIndex(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -5994,13 +6038,14 @@ fn airSaveErrReturnTraceIndex(f: *Function, inst: Air.Inst.Index) !CValue {
5994}6038}
59956039
5996fn airWrapErrUnionPay(f: *Function, inst: Air.Inst.Index) !CValue {6040fn airWrapErrUnionPay(f: *Function, inst: Air.Inst.Index) !CValue {
5997 const zcu = f.object.dg.zcu;6041 const pt = f.object.dg.pt;
6042 const zcu = pt.zcu;
5998 const ty_op = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;6043 const ty_op = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
59996044
6000 const inst_ty = f.typeOfIndex(inst);6045 const inst_ty = f.typeOfIndex(inst);
6001 const payload_ty = inst_ty.errorUnionPayload(zcu);6046 const payload_ty = inst_ty.errorUnionPayload(zcu);
6002 const payload = try f.resolveInst(ty_op.operand);6047 const payload = try f.resolveInst(ty_op.operand);
6003 const repr_is_err = !payload_ty.hasRuntimeBitsIgnoreComptime(zcu);6048 const repr_is_err = !payload_ty.hasRuntimeBitsIgnoreComptime(pt);
6004 const err_ty = inst_ty.errorUnionSet(zcu);6049 const err_ty = inst_ty.errorUnionSet(zcu);
6005 try reap(f, inst, &.{ty_op.operand});6050 try reap(f, inst, &.{ty_op.operand});
60066051
...@@ -6020,14 +6065,15 @@ fn airWrapErrUnionPay(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -6020,14 +6065,15 @@ fn airWrapErrUnionPay(f: *Function, inst: Air.Inst.Index) !CValue {
6020 else6065 else
6021 try f.writeCValueMember(writer, local, .{ .identifier = "error" });6066 try f.writeCValueMember(writer, local, .{ .identifier = "error" });
6022 try a.assign(f, writer);6067 try a.assign(f, writer);
6023 try f.object.dg.renderValue(writer, try zcu.intValue(try zcu.errorIntType(), 0), .Other);6068 try f.object.dg.renderValue(writer, try pt.intValue(try pt.errorIntType(), 0), .Other);
6024 try a.end(f, writer);6069 try a.end(f, writer);
6025 }6070 }
6026 return local;6071 return local;
6027}6072}
60286073
6029fn airIsErr(f: *Function, inst: Air.Inst.Index, is_ptr: bool, operator: []const u8) !CValue {6074fn airIsErr(f: *Function, inst: Air.Inst.Index, is_ptr: bool, operator: []const u8) !CValue {
6030 const zcu = f.object.dg.zcu;6075 const pt = f.object.dg.pt;
6076 const zcu = pt.zcu;
6031 const un_op = f.air.instructions.items(.data)[@intFromEnum(inst)].un_op;6077 const un_op = f.air.instructions.items(.data)[@intFromEnum(inst)].un_op;
60326078
6033 const writer = f.object.writer();6079 const writer = f.object.writer();
...@@ -6042,9 +6088,9 @@ fn airIsErr(f: *Function, inst: Air.Inst.Index, is_ptr: bool, operator: []const...@@ -6042,9 +6088,9 @@ fn airIsErr(f: *Function, inst: Air.Inst.Index, is_ptr: bool, operator: []const
6042 const a = try Assignment.start(f, writer, CType.bool);6088 const a = try Assignment.start(f, writer, CType.bool);
6043 try f.writeCValue(writer, local, .Other);6089 try f.writeCValue(writer, local, .Other);
6044 try a.assign(f, writer);6090 try a.assign(f, writer);
6045 const err_int_ty = try zcu.errorIntType();6091 const err_int_ty = try pt.errorIntType();
6046 if (!error_ty.errorSetIsEmpty(zcu))6092 if (!error_ty.errorSetIsEmpty(zcu))
6047 if (payload_ty.hasRuntimeBits(zcu))6093 if (payload_ty.hasRuntimeBits(pt))
6048 if (is_ptr)6094 if (is_ptr)
6049 try f.writeCValueDerefMember(writer, operand, .{ .identifier = "error" })6095 try f.writeCValueDerefMember(writer, operand, .{ .identifier = "error" })
6050 else6096 else
...@@ -6052,17 +6098,18 @@ fn airIsErr(f: *Function, inst: Air.Inst.Index, is_ptr: bool, operator: []const...@@ -6052,17 +6098,18 @@ fn airIsErr(f: *Function, inst: Air.Inst.Index, is_ptr: bool, operator: []const
6052 else6098 else
6053 try f.writeCValue(writer, operand, .Other)6099 try f.writeCValue(writer, operand, .Other)
6054 else6100 else
6055 try f.object.dg.renderValue(writer, try zcu.intValue(err_int_ty, 0), .Other);6101 try f.object.dg.renderValue(writer, try pt.intValue(err_int_ty, 0), .Other);
6056 try writer.writeByte(' ');6102 try writer.writeByte(' ');
6057 try writer.writeAll(operator);6103 try writer.writeAll(operator);
6058 try writer.writeByte(' ');6104 try writer.writeByte(' ');
6059 try f.object.dg.renderValue(writer, try zcu.intValue(err_int_ty, 0), .Other);6105 try f.object.dg.renderValue(writer, try pt.intValue(err_int_ty, 0), .Other);
6060 try a.end(f, writer);6106 try a.end(f, writer);
6061 return local;6107 return local;
6062}6108}
60636109
6064fn airArrayToSlice(f: *Function, inst: Air.Inst.Index) !CValue {6110fn airArrayToSlice(f: *Function, inst: Air.Inst.Index) !CValue {
6065 const zcu = f.object.dg.zcu;6111 const pt = f.object.dg.pt;
6112 const zcu = pt.zcu;
6066 const ctype_pool = &f.object.dg.ctype_pool;6113 const ctype_pool = &f.object.dg.ctype_pool;
6067 const ty_op = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;6114 const ty_op = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
60686115
...@@ -6096,7 +6143,7 @@ fn airArrayToSlice(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -6096,7 +6143,7 @@ fn airArrayToSlice(f: *Function, inst: Air.Inst.Index) !CValue {
6096 if (operand_child_ctype.info(ctype_pool) == .array) {6143 if (operand_child_ctype.info(ctype_pool) == .array) {
6097 try writer.writeByte('&');6144 try writer.writeByte('&');
6098 try f.writeCValueDeref(writer, operand);6145 try f.writeCValueDeref(writer, operand);
6099 try writer.print("[{}]", .{try f.fmtIntLiteral(try zcu.intValue(Type.usize, 0))});6146 try writer.print("[{}]", .{try f.fmtIntLiteral(try pt.intValue(Type.usize, 0))});
6100 } else try f.writeCValue(writer, operand, .Initializer);6147 } else try f.writeCValue(writer, operand, .Initializer);
6101 }6148 }
6102 try a.end(f, writer);6149 try a.end(f, writer);
...@@ -6106,7 +6153,7 @@ fn airArrayToSlice(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -6106,7 +6153,7 @@ fn airArrayToSlice(f: *Function, inst: Air.Inst.Index) !CValue {
6106 try f.writeCValueMember(writer, local, .{ .identifier = "len" });6153 try f.writeCValueMember(writer, local, .{ .identifier = "len" });
6107 try a.assign(f, writer);6154 try a.assign(f, writer);
6108 try writer.print("{}", .{6155 try writer.print("{}", .{
6109 try f.fmtIntLiteral(try zcu.intValue(Type.usize, array_ty.arrayLen(zcu))),6156 try f.fmtIntLiteral(try pt.intValue(Type.usize, array_ty.arrayLen(zcu))),
6110 });6157 });
6111 try a.end(f, writer);6158 try a.end(f, writer);
6112 }6159 }
...@@ -6115,7 +6162,8 @@ fn airArrayToSlice(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -6115,7 +6162,8 @@ fn airArrayToSlice(f: *Function, inst: Air.Inst.Index) !CValue {
6115}6162}
61166163
6117fn airFloatCast(f: *Function, inst: Air.Inst.Index) !CValue {6164fn airFloatCast(f: *Function, inst: Air.Inst.Index) !CValue {
6118 const zcu = f.object.dg.zcu;6165 const pt = f.object.dg.pt;
6166 const zcu = pt.zcu;
6119 const ty_op = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;6167 const ty_op = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
61206168
6121 const inst_ty = f.typeOfIndex(inst);6169 const inst_ty = f.typeOfIndex(inst);
...@@ -6165,7 +6213,8 @@ fn airFloatCast(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -6165,7 +6213,8 @@ fn airFloatCast(f: *Function, inst: Air.Inst.Index) !CValue {
6165}6213}
61666214
6167fn airIntFromPtr(f: *Function, inst: Air.Inst.Index) !CValue {6215fn airIntFromPtr(f: *Function, inst: Air.Inst.Index) !CValue {
6168 const zcu = f.object.dg.zcu;6216 const pt = f.object.dg.pt;
6217 const zcu = pt.zcu;
6169 const un_op = f.air.instructions.items(.data)[@intFromEnum(inst)].un_op;6218 const un_op = f.air.instructions.items(.data)[@intFromEnum(inst)].un_op;
61706219
6171 const operand = try f.resolveInst(un_op);6220 const operand = try f.resolveInst(un_op);
...@@ -6194,7 +6243,8 @@ fn airUnBuiltinCall(...@@ -6194,7 +6243,8 @@ fn airUnBuiltinCall(
6194 operation: []const u8,6243 operation: []const u8,
6195 info: BuiltinInfo,6244 info: BuiltinInfo,
6196) !CValue {6245) !CValue {
6197 const zcu = f.object.dg.zcu;6246 const pt = f.object.dg.pt;
6247 const zcu = pt.zcu;
61986248
6199 const operand = try f.resolveInst(operand_ref);6249 const operand = try f.resolveInst(operand_ref);
6200 try reap(f, inst, &.{operand_ref});6250 try reap(f, inst, &.{operand_ref});
...@@ -6237,7 +6287,8 @@ fn airBinBuiltinCall(...@@ -6237,7 +6287,8 @@ fn airBinBuiltinCall(
6237 operation: []const u8,6287 operation: []const u8,
6238 info: BuiltinInfo,6288 info: BuiltinInfo,
6239) !CValue {6289) !CValue {
6240 const zcu = f.object.dg.zcu;6290 const pt = f.object.dg.pt;
6291 const zcu = pt.zcu;
6241 const bin_op = f.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;6292 const bin_op = f.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
62426293
6243 const operand_ty = f.typeOf(bin_op.lhs);6294 const operand_ty = f.typeOf(bin_op.lhs);
...@@ -6292,7 +6343,8 @@ fn airCmpBuiltinCall(...@@ -6292,7 +6343,8 @@ fn airCmpBuiltinCall(
6292 operation: enum { cmp, operator },6343 operation: enum { cmp, operator },
6293 info: BuiltinInfo,6344 info: BuiltinInfo,
6294) !CValue {6345) !CValue {
6295 const zcu = f.object.dg.zcu;6346 const pt = f.object.dg.pt;
6347 const zcu = pt.zcu;
6296 const lhs = try f.resolveInst(data.lhs);6348 const lhs = try f.resolveInst(data.lhs);
6297 const rhs = try f.resolveInst(data.rhs);6349 const rhs = try f.resolveInst(data.rhs);
6298 try reap(f, inst, &.{ data.lhs, data.rhs });6350 try reap(f, inst, &.{ data.lhs, data.rhs });
...@@ -6333,7 +6385,7 @@ fn airCmpBuiltinCall(...@@ -6333,7 +6385,7 @@ fn airCmpBuiltinCall(
6333 try writer.writeByte(')');6385 try writer.writeByte(')');
6334 if (!ref_ret) try writer.print("{s}{}", .{6386 if (!ref_ret) try writer.print("{s}{}", .{
6335 compareOperatorC(operator),6387 compareOperatorC(operator),
6336 try f.fmtIntLiteral(try zcu.intValue(Type.i32, 0)),6388 try f.fmtIntLiteral(try pt.intValue(Type.i32, 0)),
6337 });6389 });
6338 try writer.writeAll(";\n");6390 try writer.writeAll(";\n");
6339 try v.end(f, inst, writer);6391 try v.end(f, inst, writer);
...@@ -6342,7 +6394,8 @@ fn airCmpBuiltinCall(...@@ -6342,7 +6394,8 @@ fn airCmpBuiltinCall(
6342}6394}
63436395
6344fn airCmpxchg(f: *Function, inst: Air.Inst.Index, flavor: [*:0]const u8) !CValue {6396fn airCmpxchg(f: *Function, inst: Air.Inst.Index, flavor: [*:0]const u8) !CValue {
6345 const zcu = f.object.dg.zcu;6397 const pt = f.object.dg.pt;
6398 const zcu = pt.zcu;
6346 const ty_pl = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;6399 const ty_pl = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
6347 const extra = f.air.extraData(Air.Cmpxchg, ty_pl.payload).data;6400 const extra = f.air.extraData(Air.Cmpxchg, ty_pl.payload).data;
6348 const inst_ty = f.typeOfIndex(inst);6401 const inst_ty = f.typeOfIndex(inst);
...@@ -6358,7 +6411,7 @@ fn airCmpxchg(f: *Function, inst: Air.Inst.Index, flavor: [*:0]const u8) !CValue...@@ -6358,7 +6411,7 @@ fn airCmpxchg(f: *Function, inst: Air.Inst.Index, flavor: [*:0]const u8) !CValue
6358 try reap(f, inst, &.{ extra.ptr, extra.expected_value, extra.new_value });6411 try reap(f, inst, &.{ extra.ptr, extra.expected_value, extra.new_value });
63596412
6360 const repr_ty = if (ty.isRuntimeFloat())6413 const repr_ty = if (ty.isRuntimeFloat())
6361 zcu.intType(.unsigned, @as(u16, @intCast(ty.abiSize(zcu) * 8))) catch unreachable6414 pt.intType(.unsigned, @as(u16, @intCast(ty.abiSize(pt) * 8))) catch unreachable
6362 else6415 else
6363 ty;6416 ty;
63646417
...@@ -6448,7 +6501,8 @@ fn airCmpxchg(f: *Function, inst: Air.Inst.Index, flavor: [*:0]const u8) !CValue...@@ -6448,7 +6501,8 @@ fn airCmpxchg(f: *Function, inst: Air.Inst.Index, flavor: [*:0]const u8) !CValue
6448}6501}
64496502
6450fn airAtomicRmw(f: *Function, inst: Air.Inst.Index) !CValue {6503fn airAtomicRmw(f: *Function, inst: Air.Inst.Index) !CValue {
6451 const zcu = f.object.dg.zcu;6504 const pt = f.object.dg.pt;
6505 const zcu = pt.zcu;
6452 const pl_op = f.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;6506 const pl_op = f.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;
6453 const extra = f.air.extraData(Air.AtomicRmw, pl_op.payload).data;6507 const extra = f.air.extraData(Air.AtomicRmw, pl_op.payload).data;
6454 const inst_ty = f.typeOfIndex(inst);6508 const inst_ty = f.typeOfIndex(inst);
...@@ -6461,10 +6515,10 @@ fn airAtomicRmw(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -6461,10 +6515,10 @@ fn airAtomicRmw(f: *Function, inst: Air.Inst.Index) !CValue {
6461 const operand_mat = try Materialize.start(f, inst, ty, operand);6515 const operand_mat = try Materialize.start(f, inst, ty, operand);
6462 try reap(f, inst, &.{ pl_op.operand, extra.operand });6516 try reap(f, inst, &.{ pl_op.operand, extra.operand });
64636517
6464 const repr_bits = @as(u16, @intCast(ty.abiSize(zcu) * 8));6518 const repr_bits = @as(u16, @intCast(ty.abiSize(pt) * 8));
6465 const is_float = ty.isRuntimeFloat();6519 const is_float = ty.isRuntimeFloat();
6466 const is_128 = repr_bits == 128;6520 const is_128 = repr_bits == 128;
6467 const repr_ty = if (is_float) zcu.intType(.unsigned, repr_bits) catch unreachable else ty;6521 const repr_ty = if (is_float) pt.intType(.unsigned, repr_bits) catch unreachable else ty;
64686522
6469 const local = try f.allocLocal(inst, inst_ty);6523 const local = try f.allocLocal(inst, inst_ty);
6470 try writer.print("zig_atomicrmw_{s}", .{toAtomicRmwSuffix(extra.op())});6524 try writer.print("zig_atomicrmw_{s}", .{toAtomicRmwSuffix(extra.op())});
...@@ -6503,7 +6557,8 @@ fn airAtomicRmw(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -6503,7 +6557,8 @@ fn airAtomicRmw(f: *Function, inst: Air.Inst.Index) !CValue {
6503}6557}
65046558
6505fn airAtomicLoad(f: *Function, inst: Air.Inst.Index) !CValue {6559fn airAtomicLoad(f: *Function, inst: Air.Inst.Index) !CValue {
6506 const zcu = f.object.dg.zcu;6560 const pt = f.object.dg.pt;
6561 const zcu = pt.zcu;
6507 const atomic_load = f.air.instructions.items(.data)[@intFromEnum(inst)].atomic_load;6562 const atomic_load = f.air.instructions.items(.data)[@intFromEnum(inst)].atomic_load;
6508 const ptr = try f.resolveInst(atomic_load.ptr);6563 const ptr = try f.resolveInst(atomic_load.ptr);
6509 try reap(f, inst, &.{atomic_load.ptr});6564 try reap(f, inst, &.{atomic_load.ptr});
...@@ -6511,7 +6566,7 @@ fn airAtomicLoad(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -6511,7 +6566,7 @@ fn airAtomicLoad(f: *Function, inst: Air.Inst.Index) !CValue {
6511 const ty = ptr_ty.childType(zcu);6566 const ty = ptr_ty.childType(zcu);
65126567
6513 const repr_ty = if (ty.isRuntimeFloat())6568 const repr_ty = if (ty.isRuntimeFloat())
6514 zcu.intType(.unsigned, @as(u16, @intCast(ty.abiSize(zcu) * 8))) catch unreachable6569 pt.intType(.unsigned, @as(u16, @intCast(ty.abiSize(pt) * 8))) catch unreachable
6515 else6570 else
6516 ty;6571 ty;
65176572
...@@ -6539,7 +6594,8 @@ fn airAtomicLoad(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -6539,7 +6594,8 @@ fn airAtomicLoad(f: *Function, inst: Air.Inst.Index) !CValue {
6539}6594}
65406595
6541fn airAtomicStore(f: *Function, inst: Air.Inst.Index, order: [*:0]const u8) !CValue {6596fn airAtomicStore(f: *Function, inst: Air.Inst.Index, order: [*:0]const u8) !CValue {
6542 const zcu = f.object.dg.zcu;6597 const pt = f.object.dg.pt;
6598 const zcu = pt.zcu;
6543 const bin_op = f.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;6599 const bin_op = f.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
6544 const ptr_ty = f.typeOf(bin_op.lhs);6600 const ptr_ty = f.typeOf(bin_op.lhs);
6545 const ty = ptr_ty.childType(zcu);6601 const ty = ptr_ty.childType(zcu);
...@@ -6551,7 +6607,7 @@ fn airAtomicStore(f: *Function, inst: Air.Inst.Index, order: [*:0]const u8) !CVa...@@ -6551,7 +6607,7 @@ fn airAtomicStore(f: *Function, inst: Air.Inst.Index, order: [*:0]const u8) !CVa
6551 try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs });6607 try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs });
65526608
6553 const repr_ty = if (ty.isRuntimeFloat())6609 const repr_ty = if (ty.isRuntimeFloat())
6554 zcu.intType(.unsigned, @as(u16, @intCast(ty.abiSize(zcu) * 8))) catch unreachable6610 pt.intType(.unsigned, @as(u16, @intCast(ty.abiSize(pt) * 8))) catch unreachable
6555 else6611 else
6556 ty;6612 ty;
65576613
...@@ -6574,7 +6630,8 @@ fn airAtomicStore(f: *Function, inst: Air.Inst.Index, order: [*:0]const u8) !CVa...@@ -6574,7 +6630,8 @@ fn airAtomicStore(f: *Function, inst: Air.Inst.Index, order: [*:0]const u8) !CVa
6574}6630}
65756631
6576fn writeSliceOrPtr(f: *Function, writer: anytype, ptr: CValue, ptr_ty: Type) !void {6632fn writeSliceOrPtr(f: *Function, writer: anytype, ptr: CValue, ptr_ty: Type) !void {
6577 const zcu = f.object.dg.zcu;6633 const pt = f.object.dg.pt;
6634 const zcu = pt.zcu;
6578 if (ptr_ty.isSlice(zcu)) {6635 if (ptr_ty.isSlice(zcu)) {
6579 try f.writeCValueMember(writer, ptr, .{ .identifier = "ptr" });6636 try f.writeCValueMember(writer, ptr, .{ .identifier = "ptr" });
6580 } else {6637 } else {
...@@ -6583,14 +6640,15 @@ fn writeSliceOrPtr(f: *Function, writer: anytype, ptr: CValue, ptr_ty: Type) !vo...@@ -6583,14 +6640,15 @@ fn writeSliceOrPtr(f: *Function, writer: anytype, ptr: CValue, ptr_ty: Type) !vo
6583}6640}
65846641
6585fn airMemset(f: *Function, inst: Air.Inst.Index, safety: bool) !CValue {6642fn airMemset(f: *Function, inst: Air.Inst.Index, safety: bool) !CValue {
6586 const zcu = f.object.dg.zcu;6643 const pt = f.object.dg.pt;
6644 const zcu = pt.zcu;
6587 const bin_op = f.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;6645 const bin_op = f.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
6588 const dest_ty = f.typeOf(bin_op.lhs);6646 const dest_ty = f.typeOf(bin_op.lhs);
6589 const dest_slice = try f.resolveInst(bin_op.lhs);6647 const dest_slice = try f.resolveInst(bin_op.lhs);
6590 const value = try f.resolveInst(bin_op.rhs);6648 const value = try f.resolveInst(bin_op.rhs);
6591 const elem_ty = f.typeOf(bin_op.rhs);6649 const elem_ty = f.typeOf(bin_op.rhs);
6592 const elem_abi_size = elem_ty.abiSize(zcu);6650 const elem_abi_size = elem_ty.abiSize(pt);
6593 const val_is_undef = if (try f.air.value(bin_op.rhs, zcu)) |val| val.isUndefDeep(zcu) else false;6651 const val_is_undef = if (try f.air.value(bin_op.rhs, pt)) |val| val.isUndefDeep(zcu) else false;
6594 const writer = f.object.writer();6652 const writer = f.object.writer();
65956653
6596 if (val_is_undef) {6654 if (val_is_undef) {
...@@ -6628,7 +6686,7 @@ fn airMemset(f: *Function, inst: Air.Inst.Index, safety: bool) !CValue {...@@ -6628,7 +6686,7 @@ fn airMemset(f: *Function, inst: Air.Inst.Index, safety: bool) !CValue {
6628 // For the assignment in this loop, the array pointer needs to get6686 // For the assignment in this loop, the array pointer needs to get
6629 // casted to a regular pointer, otherwise an error like this occurs:6687 // casted to a regular pointer, otherwise an error like this occurs:
6630 // error: array type 'uint32_t[20]' (aka 'unsigned int[20]') is not assignable6688 // error: array type 'uint32_t[20]' (aka 'unsigned int[20]') is not assignable
6631 const elem_ptr_ty = try zcu.ptrType(.{6689 const elem_ptr_ty = try pt.ptrType(.{
6632 .child = elem_ty.toIntern(),6690 .child = elem_ty.toIntern(),
6633 .flags = .{6691 .flags = .{
6634 .size = .C,6692 .size = .C,
...@@ -6640,7 +6698,7 @@ fn airMemset(f: *Function, inst: Air.Inst.Index, safety: bool) !CValue {...@@ -6640,7 +6698,7 @@ fn airMemset(f: *Function, inst: Air.Inst.Index, safety: bool) !CValue {
6640 try writer.writeAll("for (");6698 try writer.writeAll("for (");
6641 try f.writeCValue(writer, index, .Other);6699 try f.writeCValue(writer, index, .Other);
6642 try writer.writeAll(" = ");6700 try writer.writeAll(" = ");
6643 try f.object.dg.renderValue(writer, try zcu.intValue(Type.usize, 0), .Initializer);6701 try f.object.dg.renderValue(writer, try pt.intValue(Type.usize, 0), .Initializer);
6644 try writer.writeAll("; ");6702 try writer.writeAll("; ");
6645 try f.writeCValue(writer, index, .Other);6703 try f.writeCValue(writer, index, .Other);
6646 try writer.writeAll(" != ");6704 try writer.writeAll(" != ");
...@@ -6705,7 +6763,8 @@ fn airMemset(f: *Function, inst: Air.Inst.Index, safety: bool) !CValue {...@@ -6705,7 +6763,8 @@ fn airMemset(f: *Function, inst: Air.Inst.Index, safety: bool) !CValue {
6705}6763}
67066764
6707fn airMemcpy(f: *Function, inst: Air.Inst.Index) !CValue {6765fn airMemcpy(f: *Function, inst: Air.Inst.Index) !CValue {
6708 const zcu = f.object.dg.zcu;6766 const pt = f.object.dg.pt;
6767 const zcu = pt.zcu;
6709 const bin_op = f.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;6768 const bin_op = f.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
6710 const dest_ptr = try f.resolveInst(bin_op.lhs);6769 const dest_ptr = try f.resolveInst(bin_op.lhs);
6711 const src_ptr = try f.resolveInst(bin_op.rhs);6770 const src_ptr = try f.resolveInst(bin_op.rhs);
...@@ -6733,10 +6792,11 @@ fn airMemcpy(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -6733,10 +6792,11 @@ fn airMemcpy(f: *Function, inst: Air.Inst.Index) !CValue {
6733}6792}
67346793
6735fn writeArrayLen(f: *Function, writer: ArrayListWriter, dest_ptr: CValue, dest_ty: Type) !void {6794fn writeArrayLen(f: *Function, writer: ArrayListWriter, dest_ptr: CValue, dest_ty: Type) !void {
6736 const zcu = f.object.dg.zcu;6795 const pt = f.object.dg.pt;
6796 const zcu = pt.zcu;
6737 switch (dest_ty.ptrSize(zcu)) {6797 switch (dest_ty.ptrSize(zcu)) {
6738 .One => try writer.print("{}", .{6798 .One => try writer.print("{}", .{
6739 try f.fmtIntLiteral(try zcu.intValue(Type.usize, dest_ty.childType(zcu).arrayLen(zcu))),6799 try f.fmtIntLiteral(try pt.intValue(Type.usize, dest_ty.childType(zcu).arrayLen(zcu))),
6740 }),6800 }),
6741 .Many, .C => unreachable,6801 .Many, .C => unreachable,
6742 .Slice => try f.writeCValueMember(writer, dest_ptr, .{ .identifier = "len" }),6802 .Slice => try f.writeCValueMember(writer, dest_ptr, .{ .identifier = "len" }),
...@@ -6744,14 +6804,15 @@ fn writeArrayLen(f: *Function, writer: ArrayListWriter, dest_ptr: CValue, dest_t...@@ -6744,14 +6804,15 @@ fn writeArrayLen(f: *Function, writer: ArrayListWriter, dest_ptr: CValue, dest_t
6744}6804}
67456805
6746fn airSetUnionTag(f: *Function, inst: Air.Inst.Index) !CValue {6806fn airSetUnionTag(f: *Function, inst: Air.Inst.Index) !CValue {
6747 const zcu = f.object.dg.zcu;6807 const pt = f.object.dg.pt;
6808 const zcu = pt.zcu;
6748 const bin_op = f.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;6809 const bin_op = f.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
6749 const union_ptr = try f.resolveInst(bin_op.lhs);6810 const union_ptr = try f.resolveInst(bin_op.lhs);
6750 const new_tag = try f.resolveInst(bin_op.rhs);6811 const new_tag = try f.resolveInst(bin_op.rhs);
6751 try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs });6812 try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs });
67526813
6753 const union_ty = f.typeOf(bin_op.lhs).childType(zcu);6814 const union_ty = f.typeOf(bin_op.lhs).childType(zcu);
6754 const layout = union_ty.unionGetLayout(zcu);6815 const layout = union_ty.unionGetLayout(pt);
6755 if (layout.tag_size == 0) return .none;6816 if (layout.tag_size == 0) return .none;
6756 const tag_ty = union_ty.unionTagTypeSafety(zcu).?;6817 const tag_ty = union_ty.unionTagTypeSafety(zcu).?;
67576818
...@@ -6765,14 +6826,14 @@ fn airSetUnionTag(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -6765,14 +6826,14 @@ fn airSetUnionTag(f: *Function, inst: Air.Inst.Index) !CValue {
6765}6826}
67666827
6767fn airGetUnionTag(f: *Function, inst: Air.Inst.Index) !CValue {6828fn airGetUnionTag(f: *Function, inst: Air.Inst.Index) !CValue {
6768 const zcu = f.object.dg.zcu;6829 const pt = f.object.dg.pt;
6769 const ty_op = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;6830 const ty_op = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
67706831
6771 const operand = try f.resolveInst(ty_op.operand);6832 const operand = try f.resolveInst(ty_op.operand);
6772 try reap(f, inst, &.{ty_op.operand});6833 try reap(f, inst, &.{ty_op.operand});
67736834
6774 const union_ty = f.typeOf(ty_op.operand);6835 const union_ty = f.typeOf(ty_op.operand);
6775 const layout = union_ty.unionGetLayout(zcu);6836 const layout = union_ty.unionGetLayout(pt);
6776 if (layout.tag_size == 0) return .none;6837 if (layout.tag_size == 0) return .none;
67776838
6778 const inst_ty = f.typeOfIndex(inst);6839 const inst_ty = f.typeOfIndex(inst);
...@@ -6787,7 +6848,8 @@ fn airGetUnionTag(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -6787,7 +6848,8 @@ fn airGetUnionTag(f: *Function, inst: Air.Inst.Index) !CValue {
6787}6848}
67886849
6789fn airTagName(f: *Function, inst: Air.Inst.Index) !CValue {6850fn airTagName(f: *Function, inst: Air.Inst.Index) !CValue {
6790 const zcu = f.object.dg.zcu;6851 const pt = f.object.dg.pt;
6852 const zcu = pt.zcu;
6791 const un_op = f.air.instructions.items(.data)[@intFromEnum(inst)].un_op;6853 const un_op = f.air.instructions.items(.data)[@intFromEnum(inst)].un_op;
67926854
6793 const inst_ty = f.typeOfIndex(inst);6855 const inst_ty = f.typeOfIndex(inst);
...@@ -6824,7 +6886,8 @@ fn airErrorName(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -6824,7 +6886,8 @@ fn airErrorName(f: *Function, inst: Air.Inst.Index) !CValue {
6824}6886}
68256887
6826fn airSplat(f: *Function, inst: Air.Inst.Index) !CValue {6888fn airSplat(f: *Function, inst: Air.Inst.Index) !CValue {
6827 const zcu = f.object.dg.zcu;6889 const pt = f.object.dg.pt;
6890 const zcu = pt.zcu;
6828 const ty_op = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;6891 const ty_op = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
68296892
6830 const operand = try f.resolveInst(ty_op.operand);6893 const operand = try f.resolveInst(ty_op.operand);
...@@ -6879,7 +6942,7 @@ fn airSelect(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -6879,7 +6942,7 @@ fn airSelect(f: *Function, inst: Air.Inst.Index) !CValue {
6879}6942}
68806943
6881fn airShuffle(f: *Function, inst: Air.Inst.Index) !CValue {6944fn airShuffle(f: *Function, inst: Air.Inst.Index) !CValue {
6882 const zcu = f.object.dg.zcu;6945 const pt = f.object.dg.pt;
6883 const ty_pl = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;6946 const ty_pl = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
6884 const extra = f.air.extraData(Air.Shuffle, ty_pl.payload).data;6947 const extra = f.air.extraData(Air.Shuffle, ty_pl.payload).data;
68856948
...@@ -6895,11 +6958,11 @@ fn airShuffle(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -6895,11 +6958,11 @@ fn airShuffle(f: *Function, inst: Air.Inst.Index) !CValue {
6895 for (0..extra.mask_len) |index| {6958 for (0..extra.mask_len) |index| {
6896 try f.writeCValue(writer, local, .Other);6959 try f.writeCValue(writer, local, .Other);
6897 try writer.writeByte('[');6960 try writer.writeByte('[');
6898 try f.object.dg.renderValue(writer, try zcu.intValue(Type.usize, index), .Other);6961 try f.object.dg.renderValue(writer, try pt.intValue(Type.usize, index), .Other);
6899 try writer.writeAll("] = ");6962 try writer.writeAll("] = ");
69006963
6901 const mask_elem = (try mask.elemValue(zcu, index)).toSignedInt(zcu);6964 const mask_elem = (try mask.elemValue(pt, index)).toSignedInt(pt);
6902 const src_val = try zcu.intValue(Type.usize, @as(u64, @intCast(mask_elem ^ mask_elem >> 63)));6965 const src_val = try pt.intValue(Type.usize, @as(u64, @intCast(mask_elem ^ mask_elem >> 63)));
69036966
6904 try f.writeCValue(writer, if (mask_elem >= 0) lhs else rhs, .Other);6967 try f.writeCValue(writer, if (mask_elem >= 0) lhs else rhs, .Other);
6905 try writer.writeByte('[');6968 try writer.writeByte('[');
...@@ -6911,7 +6974,8 @@ fn airShuffle(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -6911,7 +6974,8 @@ fn airShuffle(f: *Function, inst: Air.Inst.Index) !CValue {
6911}6974}
69126975
6913fn airReduce(f: *Function, inst: Air.Inst.Index) !CValue {6976fn airReduce(f: *Function, inst: Air.Inst.Index) !CValue {
6914 const zcu = f.object.dg.zcu;6977 const pt = f.object.dg.pt;
6978 const zcu = pt.zcu;
6915 const reduce = f.air.instructions.items(.data)[@intFromEnum(inst)].reduce;6979 const reduce = f.air.instructions.items(.data)[@intFromEnum(inst)].reduce;
69166980
6917 const scalar_ty = f.typeOfIndex(inst);6981 const scalar_ty = f.typeOfIndex(inst);
...@@ -6920,7 +6984,7 @@ fn airReduce(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -6920,7 +6984,7 @@ fn airReduce(f: *Function, inst: Air.Inst.Index) !CValue {
6920 const operand_ty = f.typeOf(reduce.operand);6984 const operand_ty = f.typeOf(reduce.operand);
6921 const writer = f.object.writer();6985 const writer = f.object.writer();
69226986
6923 const use_operator = scalar_ty.bitSize(zcu) <= 64;6987 const use_operator = scalar_ty.bitSize(pt) <= 64;
6924 const op: union(enum) {6988 const op: union(enum) {
6925 const Func = struct { operation: []const u8, info: BuiltinInfo = .none };6989 const Func = struct { operation: []const u8, info: BuiltinInfo = .none };
6926 builtin: Func,6990 builtin: Func,
...@@ -6971,37 +7035,37 @@ fn airReduce(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -6971,37 +7035,37 @@ fn airReduce(f: *Function, inst: Air.Inst.Index) !CValue {
6971 try f.object.dg.renderValue(writer, switch (reduce.operation) {7035 try f.object.dg.renderValue(writer, switch (reduce.operation) {
6972 .Or, .Xor => switch (scalar_ty.zigTypeTag(zcu)) {7036 .Or, .Xor => switch (scalar_ty.zigTypeTag(zcu)) {
6973 .Bool => Value.false,7037 .Bool => Value.false,
6974 .Int => try zcu.intValue(scalar_ty, 0),7038 .Int => try pt.intValue(scalar_ty, 0),
6975 else => unreachable,7039 else => unreachable,
6976 },7040 },
6977 .And => switch (scalar_ty.zigTypeTag(zcu)) {7041 .And => switch (scalar_ty.zigTypeTag(zcu)) {
6978 .Bool => Value.true,7042 .Bool => Value.true,
6979 .Int => switch (scalar_ty.intInfo(zcu).signedness) {7043 .Int => switch (scalar_ty.intInfo(zcu).signedness) {
6980 .unsigned => try scalar_ty.maxIntScalar(zcu, scalar_ty),7044 .unsigned => try scalar_ty.maxIntScalar(pt, scalar_ty),
6981 .signed => try zcu.intValue(scalar_ty, -1),7045 .signed => try pt.intValue(scalar_ty, -1),
6982 },7046 },
6983 else => unreachable,7047 else => unreachable,
6984 },7048 },
6985 .Add => switch (scalar_ty.zigTypeTag(zcu)) {7049 .Add => switch (scalar_ty.zigTypeTag(zcu)) {
6986 .Int => try zcu.intValue(scalar_ty, 0),7050 .Int => try pt.intValue(scalar_ty, 0),
6987 .Float => try zcu.floatValue(scalar_ty, 0.0),7051 .Float => try pt.floatValue(scalar_ty, 0.0),
6988 else => unreachable,7052 else => unreachable,
6989 },7053 },
6990 .Mul => switch (scalar_ty.zigTypeTag(zcu)) {7054 .Mul => switch (scalar_ty.zigTypeTag(zcu)) {
6991 .Int => try zcu.intValue(scalar_ty, 1),7055 .Int => try pt.intValue(scalar_ty, 1),
6992 .Float => try zcu.floatValue(scalar_ty, 1.0),7056 .Float => try pt.floatValue(scalar_ty, 1.0),
6993 else => unreachable,7057 else => unreachable,
6994 },7058 },
6995 .Min => switch (scalar_ty.zigTypeTag(zcu)) {7059 .Min => switch (scalar_ty.zigTypeTag(zcu)) {
6996 .Bool => Value.true,7060 .Bool => Value.true,
6997 .Int => try scalar_ty.maxIntScalar(zcu, scalar_ty),7061 .Int => try scalar_ty.maxIntScalar(pt, scalar_ty),
6998 .Float => try zcu.floatValue(scalar_ty, std.math.nan(f128)),7062 .Float => try pt.floatValue(scalar_ty, std.math.nan(f128)),
6999 else => unreachable,7063 else => unreachable,
7000 },7064 },
7001 .Max => switch (scalar_ty.zigTypeTag(zcu)) {7065 .Max => switch (scalar_ty.zigTypeTag(zcu)) {
7002 .Bool => Value.false,7066 .Bool => Value.false,
7003 .Int => try scalar_ty.minIntScalar(zcu, scalar_ty),7067 .Int => try scalar_ty.minIntScalar(pt, scalar_ty),
7004 .Float => try zcu.floatValue(scalar_ty, std.math.nan(f128)),7068 .Float => try pt.floatValue(scalar_ty, std.math.nan(f128)),
7005 else => unreachable,7069 else => unreachable,
7006 },7070 },
7007 }, .Initializer);7071 }, .Initializer);
...@@ -7046,7 +7110,8 @@ fn airReduce(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -7046,7 +7110,8 @@ fn airReduce(f: *Function, inst: Air.Inst.Index) !CValue {
7046}7110}
70477111
7048fn airAggregateInit(f: *Function, inst: Air.Inst.Index) !CValue {7112fn airAggregateInit(f: *Function, inst: Air.Inst.Index) !CValue {
7049 const zcu = f.object.dg.zcu;7113 const pt = f.object.dg.pt;
7114 const zcu = pt.zcu;
7050 const ip = &zcu.intern_pool;7115 const ip = &zcu.intern_pool;
7051 const ty_pl = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;7116 const ty_pl = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
7052 const inst_ty = f.typeOfIndex(inst);7117 const inst_ty = f.typeOfIndex(inst);
...@@ -7096,7 +7161,7 @@ fn airAggregateInit(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -7096,7 +7161,7 @@ fn airAggregateInit(f: *Function, inst: Air.Inst.Index) !CValue {
7096 var field_it = loaded_struct.iterateRuntimeOrder(ip);7161 var field_it = loaded_struct.iterateRuntimeOrder(ip);
7097 while (field_it.next()) |field_index| {7162 while (field_it.next()) |field_index| {
7098 const field_ty = Type.fromInterned(loaded_struct.field_types.get(ip)[field_index]);7163 const field_ty = Type.fromInterned(loaded_struct.field_types.get(ip)[field_index]);
7099 if (!field_ty.hasRuntimeBitsIgnoreComptime(zcu)) continue;7164 if (!field_ty.hasRuntimeBitsIgnoreComptime(pt)) continue;
71007165
7101 const a = try Assignment.start(f, writer, try f.ctypeFromType(field_ty, .complete));7166 const a = try Assignment.start(f, writer, try f.ctypeFromType(field_ty, .complete));
7102 try f.writeCValueMember(writer, local, if (loaded_struct.fieldName(ip, field_index).unwrap()) |field_name|7167 try f.writeCValueMember(writer, local, if (loaded_struct.fieldName(ip, field_index).unwrap()) |field_name|
...@@ -7113,7 +7178,7 @@ fn airAggregateInit(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -7113,7 +7178,7 @@ fn airAggregateInit(f: *Function, inst: Air.Inst.Index) !CValue {
7113 try writer.writeAll(" = ");7178 try writer.writeAll(" = ");
7114 const int_info = inst_ty.intInfo(zcu);7179 const int_info = inst_ty.intInfo(zcu);
71157180
7116 const bit_offset_ty = try zcu.intType(.unsigned, Type.smallestUnsignedBits(int_info.bits - 1));7181 const bit_offset_ty = try pt.intType(.unsigned, Type.smallestUnsignedBits(int_info.bits - 1));
71177182
7118 var bit_offset: u64 = 0;7183 var bit_offset: u64 = 0;
71197184
...@@ -7121,7 +7186,7 @@ fn airAggregateInit(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -7121,7 +7186,7 @@ fn airAggregateInit(f: *Function, inst: Air.Inst.Index) !CValue {
7121 for (0..elements.len) |field_index| {7186 for (0..elements.len) |field_index| {
7122 if (inst_ty.structFieldIsComptime(field_index, zcu)) continue;7187 if (inst_ty.structFieldIsComptime(field_index, zcu)) continue;
7123 const field_ty = inst_ty.structFieldType(field_index, zcu);7188 const field_ty = inst_ty.structFieldType(field_index, zcu);
7124 if (!field_ty.hasRuntimeBitsIgnoreComptime(zcu)) continue;7189 if (!field_ty.hasRuntimeBitsIgnoreComptime(pt)) continue;
71257190
7126 if (!empty) {7191 if (!empty) {
7127 try writer.writeAll("zig_or_");7192 try writer.writeAll("zig_or_");
...@@ -7134,7 +7199,7 @@ fn airAggregateInit(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -7134,7 +7199,7 @@ fn airAggregateInit(f: *Function, inst: Air.Inst.Index) !CValue {
7134 for (resolved_elements, 0..) |element, field_index| {7199 for (resolved_elements, 0..) |element, field_index| {
7135 if (inst_ty.structFieldIsComptime(field_index, zcu)) continue;7200 if (inst_ty.structFieldIsComptime(field_index, zcu)) continue;
7136 const field_ty = inst_ty.structFieldType(field_index, zcu);7201 const field_ty = inst_ty.structFieldType(field_index, zcu);
7137 if (!field_ty.hasRuntimeBitsIgnoreComptime(zcu)) continue;7202 if (!field_ty.hasRuntimeBitsIgnoreComptime(pt)) continue;
71387203
7139 if (!empty) try writer.writeAll(", ");7204 if (!empty) try writer.writeAll(", ");
7140 // TODO: Skip this entire shift if val is 0?7205 // TODO: Skip this entire shift if val is 0?
...@@ -7160,13 +7225,13 @@ fn airAggregateInit(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -7160,13 +7225,13 @@ fn airAggregateInit(f: *Function, inst: Air.Inst.Index) !CValue {
7160 }7225 }
71617226
7162 try writer.print(", {}", .{7227 try writer.print(", {}", .{
7163 try f.fmtIntLiteral(try zcu.intValue(bit_offset_ty, bit_offset)),7228 try f.fmtIntLiteral(try pt.intValue(bit_offset_ty, bit_offset)),
7164 });7229 });
7165 try f.object.dg.renderBuiltinInfo(writer, inst_ty, .bits);7230 try f.object.dg.renderBuiltinInfo(writer, inst_ty, .bits);
7166 try writer.writeByte(')');7231 try writer.writeByte(')');
7167 if (!empty) try writer.writeByte(')');7232 if (!empty) try writer.writeByte(')');
71687233
7169 bit_offset += field_ty.bitSize(zcu);7234 bit_offset += field_ty.bitSize(pt);
7170 empty = false;7235 empty = false;
7171 }7236 }
7172 try writer.writeAll(";\n");7237 try writer.writeAll(";\n");
...@@ -7176,7 +7241,7 @@ fn airAggregateInit(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -7176,7 +7241,7 @@ fn airAggregateInit(f: *Function, inst: Air.Inst.Index) !CValue {
7176 .anon_struct_type => |anon_struct_info| for (0..anon_struct_info.types.len) |field_index| {7241 .anon_struct_type => |anon_struct_info| for (0..anon_struct_info.types.len) |field_index| {
7177 if (anon_struct_info.values.get(ip)[field_index] != .none) continue;7242 if (anon_struct_info.values.get(ip)[field_index] != .none) continue;
7178 const field_ty = Type.fromInterned(anon_struct_info.types.get(ip)[field_index]);7243 const field_ty = Type.fromInterned(anon_struct_info.types.get(ip)[field_index]);
7179 if (!field_ty.hasRuntimeBitsIgnoreComptime(zcu)) continue;7244 if (!field_ty.hasRuntimeBitsIgnoreComptime(pt)) continue;
71807245
7181 const a = try Assignment.start(f, writer, try f.ctypeFromType(field_ty, .complete));7246 const a = try Assignment.start(f, writer, try f.ctypeFromType(field_ty, .complete));
7182 try f.writeCValueMember(writer, local, if (anon_struct_info.fieldName(ip, field_index).unwrap()) |field_name|7247 try f.writeCValueMember(writer, local, if (anon_struct_info.fieldName(ip, field_index).unwrap()) |field_name|
...@@ -7194,7 +7259,8 @@ fn airAggregateInit(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -7194,7 +7259,8 @@ fn airAggregateInit(f: *Function, inst: Air.Inst.Index) !CValue {
7194}7259}
71957260
7196fn airUnionInit(f: *Function, inst: Air.Inst.Index) !CValue {7261fn airUnionInit(f: *Function, inst: Air.Inst.Index) !CValue {
7197 const zcu = f.object.dg.zcu;7262 const pt = f.object.dg.pt;
7263 const zcu = pt.zcu;
7198 const ip = &zcu.intern_pool;7264 const ip = &zcu.intern_pool;
7199 const ty_pl = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;7265 const ty_pl = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
7200 const extra = f.air.extraData(Air.UnionInit, ty_pl.payload).data;7266 const extra = f.air.extraData(Air.UnionInit, ty_pl.payload).data;
...@@ -7211,15 +7277,15 @@ fn airUnionInit(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -7211,15 +7277,15 @@ fn airUnionInit(f: *Function, inst: Air.Inst.Index) !CValue {
7211 if (loaded_union.getLayout(ip) == .@"packed") return f.moveCValue(inst, union_ty, payload);7277 if (loaded_union.getLayout(ip) == .@"packed") return f.moveCValue(inst, union_ty, payload);
72127278
7213 const field: CValue = if (union_ty.unionTagTypeSafety(zcu)) |tag_ty| field: {7279 const field: CValue = if (union_ty.unionTagTypeSafety(zcu)) |tag_ty| field: {
7214 const layout = union_ty.unionGetLayout(zcu);7280 const layout = union_ty.unionGetLayout(pt);
7215 if (layout.tag_size != 0) {7281 if (layout.tag_size != 0) {
7216 const field_index = tag_ty.enumFieldIndex(field_name, zcu).?;7282 const field_index = tag_ty.enumFieldIndex(field_name, zcu).?;
7217 const tag_val = try zcu.enumValueFieldIndex(tag_ty, field_index);7283 const tag_val = try pt.enumValueFieldIndex(tag_ty, field_index);
72187284
7219 const a = try Assignment.start(f, writer, try f.ctypeFromType(tag_ty, .complete));7285 const a = try Assignment.start(f, writer, try f.ctypeFromType(tag_ty, .complete));
7220 try f.writeCValueMember(writer, local, .{ .identifier = "tag" });7286 try f.writeCValueMember(writer, local, .{ .identifier = "tag" });
7221 try a.assign(f, writer);7287 try a.assign(f, writer);
7222 try writer.print("{}", .{try f.fmtIntLiteral(try tag_val.intFromEnum(tag_ty, zcu))});7288 try writer.print("{}", .{try f.fmtIntLiteral(try tag_val.intFromEnum(tag_ty, pt))});
7223 try a.end(f, writer);7289 try a.end(f, writer);
7224 }7290 }
7225 break :field .{ .payload_identifier = field_name.toSlice(ip) };7291 break :field .{ .payload_identifier = field_name.toSlice(ip) };
...@@ -7234,7 +7300,8 @@ fn airUnionInit(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -7234,7 +7300,8 @@ fn airUnionInit(f: *Function, inst: Air.Inst.Index) !CValue {
7234}7300}
72357301
7236fn airPrefetch(f: *Function, inst: Air.Inst.Index) !CValue {7302fn airPrefetch(f: *Function, inst: Air.Inst.Index) !CValue {
7237 const zcu = f.object.dg.zcu;7303 const pt = f.object.dg.pt;
7304 const zcu = pt.zcu;
7238 const prefetch = f.air.instructions.items(.data)[@intFromEnum(inst)].prefetch;7305 const prefetch = f.air.instructions.items(.data)[@intFromEnum(inst)].prefetch;
72397306
7240 const ptr_ty = f.typeOf(prefetch.ptr);7307 const ptr_ty = f.typeOf(prefetch.ptr);
...@@ -7291,7 +7358,8 @@ fn airWasmMemoryGrow(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -7291,7 +7358,8 @@ fn airWasmMemoryGrow(f: *Function, inst: Air.Inst.Index) !CValue {
7291}7358}
72927359
7293fn airMulAdd(f: *Function, inst: Air.Inst.Index) !CValue {7360fn airMulAdd(f: *Function, inst: Air.Inst.Index) !CValue {
7294 const zcu = f.object.dg.zcu;7361 const pt = f.object.dg.pt;
7362 const zcu = pt.zcu;
7295 const pl_op = f.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;7363 const pl_op = f.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;
7296 const bin_op = f.air.extraData(Air.Bin, pl_op.payload).data;7364 const bin_op = f.air.extraData(Air.Bin, pl_op.payload).data;
72977365
...@@ -7326,7 +7394,8 @@ fn airMulAdd(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -7326,7 +7394,8 @@ fn airMulAdd(f: *Function, inst: Air.Inst.Index) !CValue {
7326}7394}
73277395
7328fn airCVaStart(f: *Function, inst: Air.Inst.Index) !CValue {7396fn airCVaStart(f: *Function, inst: Air.Inst.Index) !CValue {
7329 const zcu = f.object.dg.zcu;7397 const pt = f.object.dg.pt;
7398 const zcu = pt.zcu;
7330 const inst_ty = f.typeOfIndex(inst);7399 const inst_ty = f.typeOfIndex(inst);
7331 const decl_index = f.object.dg.pass.decl;7400 const decl_index = f.object.dg.pass.decl;
7332 const decl = zcu.declPtr(decl_index);7401 const decl = zcu.declPtr(decl_index);
...@@ -7699,7 +7768,8 @@ fn formatIntLiteral(...@@ -7699,7 +7768,8 @@ fn formatIntLiteral(
7699 options: std.fmt.FormatOptions,7768 options: std.fmt.FormatOptions,
7700 writer: anytype,7769 writer: anytype,
7701) @TypeOf(writer).Error!void {7770) @TypeOf(writer).Error!void {
7702 const zcu = data.dg.zcu;7771 const pt = data.dg.pt;
7772 const zcu = pt.zcu;
7703 const target = &data.dg.mod.resolved_target.result;7773 const target = &data.dg.mod.resolved_target.result;
7704 const ctype_pool = &data.dg.ctype_pool;7774 const ctype_pool = &data.dg.ctype_pool;
77057775
...@@ -7732,7 +7802,7 @@ fn formatIntLiteral(...@@ -7732,7 +7802,7 @@ fn formatIntLiteral(
7732 };7802 };
7733 undef_int.truncate(undef_int.toConst(), data.int_info.signedness, data.int_info.bits);7803 undef_int.truncate(undef_int.toConst(), data.int_info.signedness, data.int_info.bits);
7734 break :blk undef_int.toConst();7804 break :blk undef_int.toConst();
7735 } else data.val.toBigInt(&int_buf, zcu);7805 } else data.val.toBigInt(&int_buf, pt);
7736 assert(int.fitsInTwosComp(data.int_info.signedness, data.int_info.bits));7806 assert(int.fitsInTwosComp(data.int_info.signedness, data.int_info.bits));
77377807
7738 const c_bits: usize = @intCast(data.ctype.byteSize(ctype_pool, data.dg.mod) * 8);7808 const c_bits: usize = @intCast(data.ctype.byteSize(ctype_pool, data.dg.mod) * 8);
...@@ -7866,7 +7936,7 @@ fn formatIntLiteral(...@@ -7866,7 +7936,7 @@ fn formatIntLiteral(
7866 .int_info = c_limb_int_info,7936 .int_info = c_limb_int_info,
7867 .kind = data.kind,7937 .kind = data.kind,
7868 .ctype = c_limb_ctype,7938 .ctype = c_limb_ctype,
7869 .val = try zcu.intValue_big(Type.comptime_int, c_limb_mut.toConst()),7939 .val = try pt.intValue_big(Type.comptime_int, c_limb_mut.toConst()),
7870 }, fmt, options, writer);7940 }, fmt, options, writer);
7871 }7941 }
7872 }7942 }
...@@ -7940,17 +8010,18 @@ const Vectorize = struct {...@@ -7940,17 +8010,18 @@ const Vectorize = struct {
7940 index: CValue = .none,8010 index: CValue = .none,
79418011
7942 pub fn start(f: *Function, inst: Air.Inst.Index, writer: anytype, ty: Type) !Vectorize {8012 pub fn start(f: *Function, inst: Air.Inst.Index, writer: anytype, ty: Type) !Vectorize {
7943 const zcu = f.object.dg.zcu;8013 const pt = f.object.dg.pt;
8014 const zcu = pt.zcu;
7944 return if (ty.zigTypeTag(zcu) == .Vector) index: {8015 return if (ty.zigTypeTag(zcu) == .Vector) index: {
7945 const local = try f.allocLocal(inst, Type.usize);8016 const local = try f.allocLocal(inst, Type.usize);
79468017
7947 try writer.writeAll("for (");8018 try writer.writeAll("for (");
7948 try f.writeCValue(writer, local, .Other);8019 try f.writeCValue(writer, local, .Other);
7949 try writer.print(" = {d}; ", .{try f.fmtIntLiteral(try zcu.intValue(Type.usize, 0))});8020 try writer.print(" = {d}; ", .{try f.fmtIntLiteral(try pt.intValue(Type.usize, 0))});
7950 try f.writeCValue(writer, local, .Other);8021 try f.writeCValue(writer, local, .Other);
7951 try writer.print(" < {d}; ", .{try f.fmtIntLiteral(try zcu.intValue(Type.usize, ty.vectorLen(zcu)))});8022 try writer.print(" < {d}; ", .{try f.fmtIntLiteral(try pt.intValue(Type.usize, ty.vectorLen(zcu)))});
7952 try f.writeCValue(writer, local, .Other);8023 try f.writeCValue(writer, local, .Other);
7953 try writer.print(" += {d}) {{\n", .{try f.fmtIntLiteral(try zcu.intValue(Type.usize, 1))});8024 try writer.print(" += {d}) {{\n", .{try f.fmtIntLiteral(try pt.intValue(Type.usize, 1))});
7954 f.object.indent_writer.pushIndent();8025 f.object.indent_writer.pushIndent();
79558026
7956 break :index .{ .index = local };8027 break :index .{ .index = local };
...@@ -7974,10 +8045,10 @@ const Vectorize = struct {...@@ -7974,10 +8045,10 @@ const Vectorize = struct {
7974 }8045 }
7975};8046};
79768047
7977fn lowersToArray(ty: Type, zcu: *Zcu) bool {8048fn lowersToArray(ty: Type, pt: Zcu.PerThread) bool {
7978 return switch (ty.zigTypeTag(zcu)) {8049 return switch (ty.zigTypeTag(pt.zcu)) {
7979 .Array, .Vector => return true,8050 .Array, .Vector => return true,
7980 else => return ty.isAbiInt(zcu) and toCIntBits(@as(u32, @intCast(ty.bitSize(zcu)))) == null,8051 else => return ty.isAbiInt(pt.zcu) and toCIntBits(@as(u32, @intCast(ty.bitSize(pt)))) == null,
7981 };8052 };
7982}8053}
79838054
src/codegen/c/Type.zig+33-33
...@@ -1339,11 +1339,11 @@ pub const Pool = struct {...@@ -1339,11 +1339,11 @@ pub const Pool = struct {
1339 allocator: std.mem.Allocator,1339 allocator: std.mem.Allocator,
1340 scratch: *std.ArrayListUnmanaged(u32),1340 scratch: *std.ArrayListUnmanaged(u32),
1341 ty: Type,1341 ty: Type,
1342 zcu: *Zcu,1342 pt: Zcu.PerThread,
1343 mod: *Module,1343 mod: *Module,
1344 kind: Kind,1344 kind: Kind,
1345 ) !CType {1345 ) !CType {
1346 const ip = &zcu.intern_pool;1346 const ip = &pt.zcu.intern_pool;
1347 switch (ty.toIntern()) {1347 switch (ty.toIntern()) {
1348 .u0_type,1348 .u0_type,
1349 .i0_type,1349 .i0_type,
...@@ -1400,7 +1400,7 @@ pub const Pool = struct {...@@ -1400,7 +1400,7 @@ pub const Pool = struct {
1400 allocator,1400 allocator,
1401 scratch,1401 scratch,
1402 Type.fromInterned(ip.loadEnumType(ip_index).tag_ty),1402 Type.fromInterned(ip.loadEnumType(ip_index).tag_ty),
1403 zcu,1403 pt,
1404 mod,1404 mod,
1405 kind,1405 kind,
1406 ),1406 ),
...@@ -1409,7 +1409,7 @@ pub const Pool = struct {...@@ -1409,7 +1409,7 @@ pub const Pool = struct {
1409 .adhoc_inferred_error_set_type,1409 .adhoc_inferred_error_set_type,
1410 => return pool.fromIntInfo(allocator, .{1410 => return pool.fromIntInfo(allocator, .{
1411 .signedness = .unsigned,1411 .signedness = .unsigned,
1412 .bits = zcu.errorSetBits(),1412 .bits = pt.zcu.errorSetBits(),
1413 }, mod, kind),1413 }, mod, kind),
1414 .manyptr_u8_type,1414 .manyptr_u8_type,
1415 => return pool.getPointer(allocator, .{1415 => return pool.getPointer(allocator, .{
...@@ -1492,13 +1492,13 @@ pub const Pool = struct {...@@ -1492,13 +1492,13 @@ pub const Pool = struct {
1492 allocator,1492 allocator,
1493 scratch,1493 scratch,
1494 Type.fromInterned(ptr_info.child),1494 Type.fromInterned(ptr_info.child),
1495 zcu,1495 pt,
1496 mod,1496 mod,
1497 .forward,1497 .forward,
1498 ),1498 ),
1499 .alignas = AlignAs.fromAlignment(.{1499 .alignas = AlignAs.fromAlignment(.{
1500 .@"align" = ptr_info.flags.alignment,1500 .@"align" = ptr_info.flags.alignment,
1501 .abi = Type.fromInterned(ptr_info.child).abiAlignment(zcu),1501 .abi = Type.fromInterned(ptr_info.child).abiAlignment(pt),
1502 }),1502 }),
1503 };1503 };
1504 break :elem_ctype if (elem.alignas.abiOrder().compare(.gte))1504 break :elem_ctype if (elem.alignas.abiOrder().compare(.gte))
...@@ -1535,7 +1535,7 @@ pub const Pool = struct {...@@ -1535,7 +1535,7 @@ pub const Pool = struct {
1535 allocator,1535 allocator,
1536 scratch,1536 scratch,
1537 Type.fromInterned(ip.slicePtrType(ip_index)),1537 Type.fromInterned(ip.slicePtrType(ip_index)),
1538 zcu,1538 pt,
1539 mod,1539 mod,
1540 kind,1540 kind,
1541 ),1541 ),
...@@ -1560,7 +1560,7 @@ pub const Pool = struct {...@@ -1560,7 +1560,7 @@ pub const Pool = struct {
1560 allocator,1560 allocator,
1561 scratch,1561 scratch,
1562 elem_type,1562 elem_type,
1563 zcu,1563 pt,
1564 mod,1564 mod,
1565 kind.noParameter(),1565 kind.noParameter(),
1566 );1566 );
...@@ -1574,7 +1574,7 @@ pub const Pool = struct {...@@ -1574,7 +1574,7 @@ pub const Pool = struct {
1574 .{1574 .{
1575 .name = .{ .index = .array },1575 .name = .{ .index = .array },
1576 .ctype = array_ctype,1576 .ctype = array_ctype,
1577 .alignas = AlignAs.fromAbiAlignment(elem_type.abiAlignment(zcu)),1577 .alignas = AlignAs.fromAbiAlignment(elem_type.abiAlignment(pt)),
1578 },1578 },
1579 };1579 };
1580 return pool.fromFields(allocator, .@"struct", &fields, kind);1580 return pool.fromFields(allocator, .@"struct", &fields, kind);
...@@ -1586,7 +1586,7 @@ pub const Pool = struct {...@@ -1586,7 +1586,7 @@ pub const Pool = struct {
1586 allocator,1586 allocator,
1587 scratch,1587 scratch,
1588 elem_type,1588 elem_type,
1589 zcu,1589 pt,
1590 mod,1590 mod,
1591 kind.noParameter(),1591 kind.noParameter(),
1592 );1592 );
...@@ -1600,7 +1600,7 @@ pub const Pool = struct {...@@ -1600,7 +1600,7 @@ pub const Pool = struct {
1600 .{1600 .{
1601 .name = .{ .index = .array },1601 .name = .{ .index = .array },
1602 .ctype = vector_ctype,1602 .ctype = vector_ctype,
1603 .alignas = AlignAs.fromAbiAlignment(elem_type.abiAlignment(zcu)),1603 .alignas = AlignAs.fromAbiAlignment(elem_type.abiAlignment(pt)),
1604 },1604 },
1605 };1605 };
1606 return pool.fromFields(allocator, .@"struct", &fields, kind);1606 return pool.fromFields(allocator, .@"struct", &fields, kind);
...@@ -1611,7 +1611,7 @@ pub const Pool = struct {...@@ -1611,7 +1611,7 @@ pub const Pool = struct {
1611 allocator,1611 allocator,
1612 scratch,1612 scratch,
1613 Type.fromInterned(payload_type),1613 Type.fromInterned(payload_type),
1614 zcu,1614 pt,
1615 mod,1615 mod,
1616 kind.noParameter(),1616 kind.noParameter(),
1617 );1617 );
...@@ -1635,7 +1635,7 @@ pub const Pool = struct {...@@ -1635,7 +1635,7 @@ pub const Pool = struct {
1635 .name = .{ .index = .payload },1635 .name = .{ .index = .payload },
1636 .ctype = payload_ctype,1636 .ctype = payload_ctype,
1637 .alignas = AlignAs.fromAbiAlignment(1637 .alignas = AlignAs.fromAbiAlignment(
1638 Type.fromInterned(payload_type).abiAlignment(zcu),1638 Type.fromInterned(payload_type).abiAlignment(pt),
1639 ),1639 ),
1640 },1640 },
1641 };1641 };
...@@ -1643,7 +1643,7 @@ pub const Pool = struct {...@@ -1643,7 +1643,7 @@ pub const Pool = struct {
1643 },1643 },
1644 .anyframe_type => unreachable,1644 .anyframe_type => unreachable,
1645 .error_union_type => |error_union_info| {1645 .error_union_type => |error_union_info| {
1646 const error_set_bits = zcu.errorSetBits();1646 const error_set_bits = pt.zcu.errorSetBits();
1647 const error_set_ctype = try pool.fromIntInfo(allocator, .{1647 const error_set_ctype = try pool.fromIntInfo(allocator, .{
1648 .signedness = .unsigned,1648 .signedness = .unsigned,
1649 .bits = error_set_bits,1649 .bits = error_set_bits,
...@@ -1654,7 +1654,7 @@ pub const Pool = struct {...@@ -1654,7 +1654,7 @@ pub const Pool = struct {
1654 allocator,1654 allocator,
1655 scratch,1655 scratch,
1656 payload_type,1656 payload_type,
1657 zcu,1657 pt,
1658 mod,1658 mod,
1659 kind.noParameter(),1659 kind.noParameter(),
1660 );1660 );
...@@ -1671,7 +1671,7 @@ pub const Pool = struct {...@@ -1671,7 +1671,7 @@ pub const Pool = struct {
1671 .{1671 .{
1672 .name = .{ .index = .payload },1672 .name = .{ .index = .payload },
1673 .ctype = payload_ctype,1673 .ctype = payload_ctype,
1674 .alignas = AlignAs.fromAbiAlignment(payload_type.abiAlignment(zcu)),1674 .alignas = AlignAs.fromAbiAlignment(payload_type.abiAlignment(pt)),
1675 },1675 },
1676 };1676 };
1677 return pool.fromFields(allocator, .@"struct", &fields, kind);1677 return pool.fromFields(allocator, .@"struct", &fields, kind);
...@@ -1685,7 +1685,7 @@ pub const Pool = struct {...@@ -1685,7 +1685,7 @@ pub const Pool = struct {
1685 .tag = .@"struct",1685 .tag = .@"struct",
1686 .name = .{ .owner_decl = loaded_struct.decl.unwrap().? },1686 .name = .{ .owner_decl = loaded_struct.decl.unwrap().? },
1687 });1687 });
1688 if (kind.isForward()) return if (ty.hasRuntimeBitsIgnoreComptime(zcu))1688 if (kind.isForward()) return if (ty.hasRuntimeBitsIgnoreComptime(pt))
1689 fwd_decl1689 fwd_decl
1690 else1690 else
1691 CType.void;1691 CType.void;
...@@ -1706,7 +1706,7 @@ pub const Pool = struct {...@@ -1706,7 +1706,7 @@ pub const Pool = struct {
1706 allocator,1706 allocator,
1707 scratch,1707 scratch,
1708 field_type,1708 field_type,
1709 zcu,1709 pt,
1710 mod,1710 mod,
1711 kind.noParameter(),1711 kind.noParameter(),
1712 );1712 );
...@@ -1718,7 +1718,7 @@ pub const Pool = struct {...@@ -1718,7 +1718,7 @@ pub const Pool = struct {
1718 String.fromUnnamed(@intCast(field_index));1718 String.fromUnnamed(@intCast(field_index));
1719 const field_alignas = AlignAs.fromAlignment(.{1719 const field_alignas = AlignAs.fromAlignment(.{
1720 .@"align" = loaded_struct.fieldAlign(ip, field_index),1720 .@"align" = loaded_struct.fieldAlign(ip, field_index),
1721 .abi = field_type.abiAlignment(zcu),1721 .abi = field_type.abiAlignment(pt),
1722 });1722 });
1723 pool.addHashedExtraAssumeCapacityTo(scratch, &hasher, Field, .{1723 pool.addHashedExtraAssumeCapacityTo(scratch, &hasher, Field, .{
1724 .name = field_name.index,1724 .name = field_name.index,
...@@ -1745,7 +1745,7 @@ pub const Pool = struct {...@@ -1745,7 +1745,7 @@ pub const Pool = struct {
1745 allocator,1745 allocator,
1746 scratch,1746 scratch,
1747 Type.fromInterned(loaded_struct.backingIntType(ip).*),1747 Type.fromInterned(loaded_struct.backingIntType(ip).*),
1748 zcu,1748 pt,
1749 mod,1749 mod,
1750 kind,1750 kind,
1751 ),1751 ),
...@@ -1766,7 +1766,7 @@ pub const Pool = struct {...@@ -1766,7 +1766,7 @@ pub const Pool = struct {
1766 allocator,1766 allocator,
1767 scratch,1767 scratch,
1768 field_type,1768 field_type,
1769 zcu,1769 pt,
1770 mod,1770 mod,
1771 kind.noParameter(),1771 kind.noParameter(),
1772 );1772 );
...@@ -1780,7 +1780,7 @@ pub const Pool = struct {...@@ -1780,7 +1780,7 @@ pub const Pool = struct {
1780 .name = field_name.index,1780 .name = field_name.index,
1781 .ctype = field_ctype.index,1781 .ctype = field_ctype.index,
1782 .flags = .{ .alignas = AlignAs.fromAbiAlignment(1782 .flags = .{ .alignas = AlignAs.fromAbiAlignment(
1783 field_type.abiAlignment(zcu),1783 field_type.abiAlignment(pt),
1784 ) },1784 ) },
1785 });1785 });
1786 }1786 }
...@@ -1806,7 +1806,7 @@ pub const Pool = struct {...@@ -1806,7 +1806,7 @@ pub const Pool = struct {
1806 extra_index,1806 extra_index,
1807 );1807 );
1808 }1808 }
1809 const fwd_decl = try pool.fromType(allocator, scratch, ty, zcu, mod, .forward);1809 const fwd_decl = try pool.fromType(allocator, scratch, ty, pt, mod, .forward);
1810 try pool.ensureUnusedCapacity(allocator, 1);1810 try pool.ensureUnusedCapacity(allocator, 1);
1811 const extra_index = try pool.addHashedExtra(allocator, &hasher, Aggregate, .{1811 const extra_index = try pool.addHashedExtra(allocator, &hasher, Aggregate, .{
1812 .fwd_decl = fwd_decl.index,1812 .fwd_decl = fwd_decl.index,
...@@ -1824,7 +1824,7 @@ pub const Pool = struct {...@@ -1824,7 +1824,7 @@ pub const Pool = struct {
1824 .tag = if (has_tag) .@"struct" else .@"union",1824 .tag = if (has_tag) .@"struct" else .@"union",
1825 .name = .{ .owner_decl = loaded_union.decl },1825 .name = .{ .owner_decl = loaded_union.decl },
1826 });1826 });
1827 if (kind.isForward()) return if (ty.hasRuntimeBitsIgnoreComptime(zcu))1827 if (kind.isForward()) return if (ty.hasRuntimeBitsIgnoreComptime(pt))
1828 fwd_decl1828 fwd_decl
1829 else1829 else
1830 CType.void;1830 CType.void;
...@@ -1847,7 +1847,7 @@ pub const Pool = struct {...@@ -1847,7 +1847,7 @@ pub const Pool = struct {
1847 allocator,1847 allocator,
1848 scratch,1848 scratch,
1849 field_type,1849 field_type,
1850 zcu,1850 pt,
1851 mod,1851 mod,
1852 kind.noParameter(),1852 kind.noParameter(),
1853 );1853 );
...@@ -1858,7 +1858,7 @@ pub const Pool = struct {...@@ -1858,7 +1858,7 @@ pub const Pool = struct {
1858 );1858 );
1859 const field_alignas = AlignAs.fromAlignment(.{1859 const field_alignas = AlignAs.fromAlignment(.{
1860 .@"align" = loaded_union.fieldAlign(ip, field_index),1860 .@"align" = loaded_union.fieldAlign(ip, field_index),
1861 .abi = field_type.abiAlignment(zcu),1861 .abi = field_type.abiAlignment(pt),
1862 });1862 });
1863 pool.addHashedExtraAssumeCapacityTo(scratch, &hasher, Field, .{1863 pool.addHashedExtraAssumeCapacityTo(scratch, &hasher, Field, .{
1864 .name = field_name.index,1864 .name = field_name.index,
...@@ -1895,7 +1895,7 @@ pub const Pool = struct {...@@ -1895,7 +1895,7 @@ pub const Pool = struct {
1895 allocator,1895 allocator,
1896 scratch,1896 scratch,
1897 tag_type,1897 tag_type,
1898 zcu,1898 pt,
1899 mod,1899 mod,
1900 kind.noParameter(),1900 kind.noParameter(),
1901 );1901 );
...@@ -1903,7 +1903,7 @@ pub const Pool = struct {...@@ -1903,7 +1903,7 @@ pub const Pool = struct {
1903 struct_fields[struct_fields_len] = .{1903 struct_fields[struct_fields_len] = .{
1904 .name = .{ .index = .tag },1904 .name = .{ .index = .tag },
1905 .ctype = tag_ctype,1905 .ctype = tag_ctype,
1906 .alignas = AlignAs.fromAbiAlignment(tag_type.abiAlignment(zcu)),1906 .alignas = AlignAs.fromAbiAlignment(tag_type.abiAlignment(pt)),
1907 };1907 };
1908 struct_fields_len += 1;1908 struct_fields_len += 1;
1909 }1909 }
...@@ -1951,7 +1951,7 @@ pub const Pool = struct {...@@ -1951,7 +1951,7 @@ pub const Pool = struct {
1951 },1951 },
1952 .@"packed" => return pool.fromIntInfo(allocator, .{1952 .@"packed" => return pool.fromIntInfo(allocator, .{
1953 .signedness = .unsigned,1953 .signedness = .unsigned,
1954 .bits = @intCast(ty.bitSize(zcu)),1954 .bits = @intCast(ty.bitSize(pt)),
1955 }, mod, kind),1955 }, mod, kind),
1956 }1956 }
1957 },1957 },
...@@ -1960,7 +1960,7 @@ pub const Pool = struct {...@@ -1960,7 +1960,7 @@ pub const Pool = struct {
1960 allocator,1960 allocator,
1961 scratch,1961 scratch,
1962 Type.fromInterned(ip.loadEnumType(ip_index).tag_ty),1962 Type.fromInterned(ip.loadEnumType(ip_index).tag_ty),
1963 zcu,1963 pt,
1964 mod,1964 mod,
1965 kind,1965 kind,
1966 ),1966 ),
...@@ -1975,7 +1975,7 @@ pub const Pool = struct {...@@ -1975,7 +1975,7 @@ pub const Pool = struct {
1975 allocator,1975 allocator,
1976 scratch,1976 scratch,
1977 return_type,1977 return_type,
1978 zcu,1978 pt,
1979 mod,1979 mod,
1980 kind.asParameter(),1980 kind.asParameter(),
1981 ) else CType.void;1981 ) else CType.void;
...@@ -1987,7 +1987,7 @@ pub const Pool = struct {...@@ -1987,7 +1987,7 @@ pub const Pool = struct {
1987 allocator,1987 allocator,
1988 scratch,1988 scratch,
1989 param_type,1989 param_type,
1990 zcu,1990 pt,
1991 mod,1991 mod,
1992 kind.asParameter(),1992 kind.asParameter(),
1993 );1993 );
...@@ -2011,7 +2011,7 @@ pub const Pool = struct {...@@ -2011,7 +2011,7 @@ pub const Pool = struct {
2011 .inferred_error_set_type,2011 .inferred_error_set_type,
2012 => return pool.fromIntInfo(allocator, .{2012 => return pool.fromIntInfo(allocator, .{
2013 .signedness = .unsigned,2013 .signedness = .unsigned,
2014 .bits = zcu.errorSetBits(),2014 .bits = pt.zcu.errorSetBits(),
2015 }, mod, kind),2015 }, mod, kind),
20162016
2017 .undef,2017 .undef,
src/codegen/llvm.zig+765-692
...@@ -15,8 +15,6 @@ const link = @import("../link.zig");...@@ -15,8 +15,6 @@ const link = @import("../link.zig");
15const Compilation = @import("../Compilation.zig");15const Compilation = @import("../Compilation.zig");
16const build_options = @import("build_options");16const build_options = @import("build_options");
17const Zcu = @import("../Zcu.zig");17const Zcu = @import("../Zcu.zig");
18/// Deprecated.
19const Module = Zcu;
20const InternPool = @import("../InternPool.zig");18const InternPool = @import("../InternPool.zig");
21const Package = @import("../Package.zig");19const Package = @import("../Package.zig");
22const Air = @import("../Air.zig");20const Air = @import("../Air.zig");
...@@ -810,7 +808,7 @@ pub const Object = struct {...@@ -810,7 +808,7 @@ pub const Object = struct {
810 gpa: Allocator,808 gpa: Allocator,
811 builder: Builder,809 builder: Builder,
812810
813 module: *Module,811 pt: Zcu.PerThread,
814812
815 debug_compile_unit: Builder.Metadata,813 debug_compile_unit: Builder.Metadata,
816814
...@@ -820,7 +818,7 @@ pub const Object = struct {...@@ -820,7 +818,7 @@ pub const Object = struct {
820 debug_enums: std.ArrayListUnmanaged(Builder.Metadata),818 debug_enums: std.ArrayListUnmanaged(Builder.Metadata),
821 debug_globals: std.ArrayListUnmanaged(Builder.Metadata),819 debug_globals: std.ArrayListUnmanaged(Builder.Metadata),
822820
823 debug_file_map: std.AutoHashMapUnmanaged(*const Module.File, Builder.Metadata),821 debug_file_map: std.AutoHashMapUnmanaged(*const Zcu.File, Builder.Metadata),
824 debug_type_map: std.AutoHashMapUnmanaged(Type, Builder.Metadata),822 debug_type_map: std.AutoHashMapUnmanaged(Type, Builder.Metadata),
825823
826 debug_unresolved_namespace_scopes: std.AutoArrayHashMapUnmanaged(InternPool.NamespaceIndex, Builder.Metadata),824 debug_unresolved_namespace_scopes: std.AutoArrayHashMapUnmanaged(InternPool.NamespaceIndex, Builder.Metadata),
...@@ -992,7 +990,10 @@ pub const Object = struct {...@@ -992,7 +990,10 @@ pub const Object = struct {
992 obj.* = .{990 obj.* = .{
993 .gpa = gpa,991 .gpa = gpa,
994 .builder = builder,992 .builder = builder,
995 .module = comp.module.?,993 .pt = .{
994 .zcu = comp.module.?,
995 .tid = .main,
996 },
996 .debug_compile_unit = debug_compile_unit,997 .debug_compile_unit = debug_compile_unit,
997 .debug_enums_fwd_ref = debug_enums_fwd_ref,998 .debug_enums_fwd_ref = debug_enums_fwd_ref,
998 .debug_globals_fwd_ref = debug_globals_fwd_ref,999 .debug_globals_fwd_ref = debug_globals_fwd_ref,
...@@ -1033,7 +1034,8 @@ pub const Object = struct {...@@ -1033,7 +1034,8 @@ pub const Object = struct {
1033 // If o.error_name_table is null, then it was not referenced by any instructions.1034 // If o.error_name_table is null, then it was not referenced by any instructions.
1034 if (o.error_name_table == .none) return;1035 if (o.error_name_table == .none) return;
10351036
1036 const mod = o.module;1037 const pt = o.pt;
1038 const mod = pt.zcu;
10371039
1038 const error_name_list = mod.global_error_set.keys();1040 const error_name_list = mod.global_error_set.keys();
1039 const llvm_errors = try mod.gpa.alloc(Builder.Constant, error_name_list.len);1041 const llvm_errors = try mod.gpa.alloc(Builder.Constant, error_name_list.len);
...@@ -1072,7 +1074,7 @@ pub const Object = struct {...@@ -1072,7 +1074,7 @@ pub const Object = struct {
1072 table_variable_index.setMutability(.constant, &o.builder);1074 table_variable_index.setMutability(.constant, &o.builder);
1073 table_variable_index.setUnnamedAddr(.unnamed_addr, &o.builder);1075 table_variable_index.setUnnamedAddr(.unnamed_addr, &o.builder);
1074 table_variable_index.setAlignment(1076 table_variable_index.setAlignment(
1075 slice_ty.abiAlignment(mod).toLlvm(),1077 slice_ty.abiAlignment(pt).toLlvm(),
1076 &o.builder,1078 &o.builder,
1077 );1079 );
10781080
...@@ -1083,8 +1085,7 @@ pub const Object = struct {...@@ -1083,8 +1085,7 @@ pub const Object = struct {
1083 // If there is no such function in the module, it means the source code does not need it.1085 // If there is no such function in the module, it means the source code does not need it.
1084 const name = o.builder.strtabStringIfExists(lt_errors_fn_name) orelse return;1086 const name = o.builder.strtabStringIfExists(lt_errors_fn_name) orelse return;
1085 const llvm_fn = o.builder.getGlobal(name) orelse return;1087 const llvm_fn = o.builder.getGlobal(name) orelse return;
1086 const mod = o.module;1088 const errors_len = o.pt.zcu.global_error_set.count();
1087 const errors_len = mod.global_error_set.count();
10881089
1089 var wip = try Builder.WipFunction.init(&o.builder, .{1090 var wip = try Builder.WipFunction.init(&o.builder, .{
1090 .function = llvm_fn.ptrConst(&o.builder).kind.function,1091 .function = llvm_fn.ptrConst(&o.builder).kind.function,
...@@ -1106,10 +1107,8 @@ pub const Object = struct {...@@ -1106,10 +1107,8 @@ pub const Object = struct {
1106 }1107 }
11071108
1108 fn genModuleLevelAssembly(object: *Object) !void {1109 fn genModuleLevelAssembly(object: *Object) !void {
1109 const mod = object.module;
1110
1111 const writer = object.builder.setModuleAsm();1110 const writer = object.builder.setModuleAsm();
1112 for (mod.global_assembly.values()) |assembly| {1111 for (object.pt.zcu.global_assembly.values()) |assembly| {
1113 try writer.print("{s}\n", .{assembly});1112 try writer.print("{s}\n", .{assembly});
1114 }1113 }
1115 try object.builder.finishModuleAsm();1114 try object.builder.finishModuleAsm();
...@@ -1131,6 +1130,9 @@ pub const Object = struct {...@@ -1131,6 +1130,9 @@ pub const Object = struct {
1131 };1130 };
11321131
1133 pub fn emit(self: *Object, options: EmitOptions) !void {1132 pub fn emit(self: *Object, options: EmitOptions) !void {
1133 const zcu = self.pt.zcu;
1134 const comp = zcu.comp;
1135
1134 {1136 {
1135 try self.genErrorNameTable();1137 try self.genErrorNameTable();
1136 try self.genCmpLtErrorsLenFunction();1138 try self.genCmpLtErrorsLenFunction();
...@@ -1143,8 +1145,8 @@ pub const Object = struct {...@@ -1143,8 +1145,8 @@ pub const Object = struct {
1143 const namespace_index = self.debug_unresolved_namespace_scopes.keys()[i];1145 const namespace_index = self.debug_unresolved_namespace_scopes.keys()[i];
1144 const fwd_ref = self.debug_unresolved_namespace_scopes.values()[i];1146 const fwd_ref = self.debug_unresolved_namespace_scopes.values()[i];
11451147
1146 const namespace = self.module.namespacePtr(namespace_index);1148 const namespace = zcu.namespacePtr(namespace_index);
1147 const debug_type = try self.lowerDebugType(namespace.getType(self.module));1149 const debug_type = try self.lowerDebugType(namespace.getType(zcu));
11481150
1149 self.builder.debugForwardReferenceSetType(fwd_ref, debug_type);1151 self.builder.debugForwardReferenceSetType(fwd_ref, debug_type);
1150 }1152 }
...@@ -1206,12 +1208,12 @@ pub const Object = struct {...@@ -1206,12 +1208,12 @@ pub const Object = struct {
1206 try file.writeAll(ptr[0..(bitcode.len * 4)]);1208 try file.writeAll(ptr[0..(bitcode.len * 4)]);
1207 }1209 }
12081210
1209 if (!build_options.have_llvm or !self.module.comp.config.use_lib_llvm) {1211 if (!build_options.have_llvm or !comp.config.use_lib_llvm) {
1210 log.err("emitting without libllvm not implemented", .{});1212 log.err("emitting without libllvm not implemented", .{});
1211 return error.FailedToEmit;1213 return error.FailedToEmit;
1212 }1214 }
12131215
1214 initializeLLVMTarget(self.module.comp.root_mod.resolved_target.result.cpu.arch);1216 initializeLLVMTarget(comp.root_mod.resolved_target.result.cpu.arch);
12151217
1216 const context: *llvm.Context = llvm.Context.create();1218 const context: *llvm.Context = llvm.Context.create();
1217 errdefer context.dispose();1219 errdefer context.dispose();
...@@ -1247,8 +1249,8 @@ pub const Object = struct {...@@ -1247,8 +1249,8 @@ pub const Object = struct {
1247 @panic("Invalid LLVM triple");1249 @panic("Invalid LLVM triple");
1248 }1250 }
12491251
1250 const optimize_mode = self.module.comp.root_mod.optimize_mode;1252 const optimize_mode = comp.root_mod.optimize_mode;
1251 const pic = self.module.comp.root_mod.pic;1253 const pic = comp.root_mod.pic;
12521254
1253 const opt_level: llvm.CodeGenOptLevel = if (optimize_mode == .Debug)1255 const opt_level: llvm.CodeGenOptLevel = if (optimize_mode == .Debug)
1254 .None1256 .None
...@@ -1257,12 +1259,12 @@ pub const Object = struct {...@@ -1257,12 +1259,12 @@ pub const Object = struct {
12571259
1258 const reloc_mode: llvm.RelocMode = if (pic)1260 const reloc_mode: llvm.RelocMode = if (pic)
1259 .PIC1261 .PIC
1260 else if (self.module.comp.config.link_mode == .dynamic)1262 else if (comp.config.link_mode == .dynamic)
1261 llvm.RelocMode.DynamicNoPIC1263 llvm.RelocMode.DynamicNoPIC
1262 else1264 else
1263 .Static;1265 .Static;
12641266
1265 const code_model: llvm.CodeModel = switch (self.module.comp.root_mod.code_model) {1267 const code_model: llvm.CodeModel = switch (comp.root_mod.code_model) {
1266 .default => .Default,1268 .default => .Default,
1267 .tiny => .Tiny,1269 .tiny => .Tiny,
1268 .small => .Small,1270 .small => .Small,
...@@ -1277,24 +1279,24 @@ pub const Object = struct {...@@ -1277,24 +1279,24 @@ pub const Object = struct {
1277 var target_machine = llvm.TargetMachine.create(1279 var target_machine = llvm.TargetMachine.create(
1278 target,1280 target,
1279 target_triple_sentinel,1281 target_triple_sentinel,
1280 if (self.module.comp.root_mod.resolved_target.result.cpu.model.llvm_name) |s| s.ptr else null,1282 if (comp.root_mod.resolved_target.result.cpu.model.llvm_name) |s| s.ptr else null,
1281 self.module.comp.root_mod.resolved_target.llvm_cpu_features.?,1283 comp.root_mod.resolved_target.llvm_cpu_features.?,
1282 opt_level,1284 opt_level,
1283 reloc_mode,1285 reloc_mode,
1284 code_model,1286 code_model,
1285 self.module.comp.function_sections,1287 comp.function_sections,
1286 self.module.comp.data_sections,1288 comp.data_sections,
1287 float_abi,1289 float_abi,
1288 if (target_util.llvmMachineAbi(self.module.comp.root_mod.resolved_target.result)) |s| s.ptr else null,1290 if (target_util.llvmMachineAbi(comp.root_mod.resolved_target.result)) |s| s.ptr else null,
1289 );1291 );
1290 errdefer target_machine.dispose();1292 errdefer target_machine.dispose();
12911293
1292 if (pic) module.setModulePICLevel();1294 if (pic) module.setModulePICLevel();
1293 if (self.module.comp.config.pie) module.setModulePIELevel();1295 if (comp.config.pie) module.setModulePIELevel();
1294 if (code_model != .Default) module.setModuleCodeModel(code_model);1296 if (code_model != .Default) module.setModuleCodeModel(code_model);
12951297
1296 if (self.module.comp.llvm_opt_bisect_limit >= 0) {1298 if (comp.llvm_opt_bisect_limit >= 0) {
1297 context.setOptBisectLimit(self.module.comp.llvm_opt_bisect_limit);1299 context.setOptBisectLimit(comp.llvm_opt_bisect_limit);
1298 }1300 }
12991301
1300 // Unfortunately, LLVM shits the bed when we ask for both binary and assembly.1302 // Unfortunately, LLVM shits the bed when we ask for both binary and assembly.
...@@ -1352,11 +1354,13 @@ pub const Object = struct {...@@ -1352,11 +1354,13 @@ pub const Object = struct {
13521354
1353 pub fn updateFunc(1355 pub fn updateFunc(
1354 o: *Object,1356 o: *Object,
1355 zcu: *Module,1357 pt: Zcu.PerThread,
1356 func_index: InternPool.Index,1358 func_index: InternPool.Index,
1357 air: Air,1359 air: Air,
1358 liveness: Liveness,1360 liveness: Liveness,
1359 ) !void {1361 ) !void {
1362 assert(std.meta.eql(pt, o.pt));
1363 const zcu = pt.zcu;
1360 const comp = zcu.comp;1364 const comp = zcu.comp;
1361 const func = zcu.funcInfo(func_index);1365 const func = zcu.funcInfo(func_index);
1362 const decl_index = func.owner_decl;1366 const decl_index = func.owner_decl;
...@@ -1437,7 +1441,7 @@ pub const Object = struct {...@@ -1437,7 +1441,7 @@ pub const Object = struct {
1437 var llvm_arg_i: u32 = 0;1441 var llvm_arg_i: u32 = 0;
14381442
1439 // This gets the LLVM values from the function and stores them in `dg.args`.1443 // This gets the LLVM values from the function and stores them in `dg.args`.
1440 const sret = firstParamSRet(fn_info, zcu, target);1444 const sret = firstParamSRet(fn_info, pt, target);
1441 const ret_ptr: Builder.Value = if (sret) param: {1445 const ret_ptr: Builder.Value = if (sret) param: {
1442 const param = wip.arg(llvm_arg_i);1446 const param = wip.arg(llvm_arg_i);
1443 llvm_arg_i += 1;1447 llvm_arg_i += 1;
...@@ -1478,8 +1482,8 @@ pub const Object = struct {...@@ -1478,8 +1482,8 @@ pub const Object = struct {
1478 const param_ty = Type.fromInterned(fn_info.param_types.get(ip)[param_index]);1482 const param_ty = Type.fromInterned(fn_info.param_types.get(ip)[param_index]);
1479 const param = wip.arg(llvm_arg_i);1483 const param = wip.arg(llvm_arg_i);
14801484
1481 if (isByRef(param_ty, zcu)) {1485 if (isByRef(param_ty, pt)) {
1482 const alignment = param_ty.abiAlignment(zcu).toLlvm();1486 const alignment = param_ty.abiAlignment(pt).toLlvm();
1483 const param_llvm_ty = param.typeOfWip(&wip);1487 const param_llvm_ty = param.typeOfWip(&wip);
1484 const arg_ptr = try buildAllocaInner(&wip, param_llvm_ty, alignment, target);1488 const arg_ptr = try buildAllocaInner(&wip, param_llvm_ty, alignment, target);
1485 _ = try wip.store(.normal, param, arg_ptr, alignment);1489 _ = try wip.store(.normal, param, arg_ptr, alignment);
...@@ -1495,12 +1499,12 @@ pub const Object = struct {...@@ -1495,12 +1499,12 @@ pub const Object = struct {
1495 const param_ty = Type.fromInterned(fn_info.param_types.get(ip)[it.zig_index - 1]);1499 const param_ty = Type.fromInterned(fn_info.param_types.get(ip)[it.zig_index - 1]);
1496 const param_llvm_ty = try o.lowerType(param_ty);1500 const param_llvm_ty = try o.lowerType(param_ty);
1497 const param = wip.arg(llvm_arg_i);1501 const param = wip.arg(llvm_arg_i);
1498 const alignment = param_ty.abiAlignment(zcu).toLlvm();1502 const alignment = param_ty.abiAlignment(pt).toLlvm();
14991503
1500 try o.addByRefParamAttrs(&attributes, llvm_arg_i, alignment, it.byval_attr, param_llvm_ty);1504 try o.addByRefParamAttrs(&attributes, llvm_arg_i, alignment, it.byval_attr, param_llvm_ty);
1501 llvm_arg_i += 1;1505 llvm_arg_i += 1;
15021506
1503 if (isByRef(param_ty, zcu)) {1507 if (isByRef(param_ty, pt)) {
1504 args.appendAssumeCapacity(param);1508 args.appendAssumeCapacity(param);
1505 } else {1509 } else {
1506 args.appendAssumeCapacity(try wip.load(.normal, param_llvm_ty, param, alignment, ""));1510 args.appendAssumeCapacity(try wip.load(.normal, param_llvm_ty, param, alignment, ""));
...@@ -1510,12 +1514,12 @@ pub const Object = struct {...@@ -1510,12 +1514,12 @@ pub const Object = struct {
1510 const param_ty = Type.fromInterned(fn_info.param_types.get(ip)[it.zig_index - 1]);1514 const param_ty = Type.fromInterned(fn_info.param_types.get(ip)[it.zig_index - 1]);
1511 const param_llvm_ty = try o.lowerType(param_ty);1515 const param_llvm_ty = try o.lowerType(param_ty);
1512 const param = wip.arg(llvm_arg_i);1516 const param = wip.arg(llvm_arg_i);
1513 const alignment = param_ty.abiAlignment(zcu).toLlvm();1517 const alignment = param_ty.abiAlignment(pt).toLlvm();
15141518
1515 try attributes.addParamAttr(llvm_arg_i, .noundef, &o.builder);1519 try attributes.addParamAttr(llvm_arg_i, .noundef, &o.builder);
1516 llvm_arg_i += 1;1520 llvm_arg_i += 1;
15171521
1518 if (isByRef(param_ty, zcu)) {1522 if (isByRef(param_ty, pt)) {
1519 args.appendAssumeCapacity(param);1523 args.appendAssumeCapacity(param);
1520 } else {1524 } else {
1521 args.appendAssumeCapacity(try wip.load(.normal, param_llvm_ty, param, alignment, ""));1525 args.appendAssumeCapacity(try wip.load(.normal, param_llvm_ty, param, alignment, ""));
...@@ -1528,11 +1532,11 @@ pub const Object = struct {...@@ -1528,11 +1532,11 @@ pub const Object = struct {
1528 llvm_arg_i += 1;1532 llvm_arg_i += 1;
15291533
1530 const param_llvm_ty = try o.lowerType(param_ty);1534 const param_llvm_ty = try o.lowerType(param_ty);
1531 const alignment = param_ty.abiAlignment(zcu).toLlvm();1535 const alignment = param_ty.abiAlignment(pt).toLlvm();
1532 const arg_ptr = try buildAllocaInner(&wip, param_llvm_ty, alignment, target);1536 const arg_ptr = try buildAllocaInner(&wip, param_llvm_ty, alignment, target);
1533 _ = try wip.store(.normal, param, arg_ptr, alignment);1537 _ = try wip.store(.normal, param, arg_ptr, alignment);
15341538
1535 args.appendAssumeCapacity(if (isByRef(param_ty, zcu))1539 args.appendAssumeCapacity(if (isByRef(param_ty, pt))
1536 arg_ptr1540 arg_ptr
1537 else1541 else
1538 try wip.load(.normal, param_llvm_ty, arg_ptr, alignment, ""));1542 try wip.load(.normal, param_llvm_ty, arg_ptr, alignment, ""));
...@@ -1556,7 +1560,7 @@ pub const Object = struct {...@@ -1556,7 +1560,7 @@ pub const Object = struct {
1556 const elem_align = (if (ptr_info.flags.alignment != .none)1560 const elem_align = (if (ptr_info.flags.alignment != .none)
1557 @as(InternPool.Alignment, ptr_info.flags.alignment)1561 @as(InternPool.Alignment, ptr_info.flags.alignment)
1558 else1562 else
1559 Type.fromInterned(ptr_info.child).abiAlignment(zcu).max(.@"1")).toLlvm();1563 Type.fromInterned(ptr_info.child).abiAlignment(pt).max(.@"1")).toLlvm();
1560 try attributes.addParamAttr(llvm_arg_i, .{ .@"align" = elem_align }, &o.builder);1564 try attributes.addParamAttr(llvm_arg_i, .{ .@"align" = elem_align }, &o.builder);
1561 const ptr_param = wip.arg(llvm_arg_i);1565 const ptr_param = wip.arg(llvm_arg_i);
1562 llvm_arg_i += 1;1566 llvm_arg_i += 1;
...@@ -1573,7 +1577,7 @@ pub const Object = struct {...@@ -1573,7 +1577,7 @@ pub const Object = struct {
1573 const field_types = it.types_buffer[0..it.types_len];1577 const field_types = it.types_buffer[0..it.types_len];
1574 const param_ty = Type.fromInterned(fn_info.param_types.get(ip)[it.zig_index - 1]);1578 const param_ty = Type.fromInterned(fn_info.param_types.get(ip)[it.zig_index - 1]);
1575 const param_llvm_ty = try o.lowerType(param_ty);1579 const param_llvm_ty = try o.lowerType(param_ty);
1576 const param_alignment = param_ty.abiAlignment(zcu).toLlvm();1580 const param_alignment = param_ty.abiAlignment(pt).toLlvm();
1577 const arg_ptr = try buildAllocaInner(&wip, param_llvm_ty, param_alignment, target);1581 const arg_ptr = try buildAllocaInner(&wip, param_llvm_ty, param_alignment, target);
1578 const llvm_ty = try o.builder.structType(.normal, field_types);1582 const llvm_ty = try o.builder.structType(.normal, field_types);
1579 for (0..field_types.len) |field_i| {1583 for (0..field_types.len) |field_i| {
...@@ -1585,7 +1589,7 @@ pub const Object = struct {...@@ -1585,7 +1589,7 @@ pub const Object = struct {
1585 _ = try wip.store(.normal, param, field_ptr, alignment);1589 _ = try wip.store(.normal, param, field_ptr, alignment);
1586 }1590 }
15871591
1588 const is_by_ref = isByRef(param_ty, zcu);1592 const is_by_ref = isByRef(param_ty, pt);
1589 args.appendAssumeCapacity(if (is_by_ref)1593 args.appendAssumeCapacity(if (is_by_ref)
1590 arg_ptr1594 arg_ptr
1591 else1595 else
...@@ -1603,11 +1607,11 @@ pub const Object = struct {...@@ -1603,11 +1607,11 @@ pub const Object = struct {
1603 const param = wip.arg(llvm_arg_i);1607 const param = wip.arg(llvm_arg_i);
1604 llvm_arg_i += 1;1608 llvm_arg_i += 1;
16051609
1606 const alignment = param_ty.abiAlignment(zcu).toLlvm();1610 const alignment = param_ty.abiAlignment(pt).toLlvm();
1607 const arg_ptr = try buildAllocaInner(&wip, param_llvm_ty, alignment, target);1611 const arg_ptr = try buildAllocaInner(&wip, param_llvm_ty, alignment, target);
1608 _ = try wip.store(.normal, param, arg_ptr, alignment);1612 _ = try wip.store(.normal, param, arg_ptr, alignment);
16091613
1610 args.appendAssumeCapacity(if (isByRef(param_ty, zcu))1614 args.appendAssumeCapacity(if (isByRef(param_ty, pt))
1611 arg_ptr1615 arg_ptr
1612 else1616 else
1613 try wip.load(.normal, param_llvm_ty, arg_ptr, alignment, ""));1617 try wip.load(.normal, param_llvm_ty, arg_ptr, alignment, ""));
...@@ -1618,11 +1622,11 @@ pub const Object = struct {...@@ -1618,11 +1622,11 @@ pub const Object = struct {
1618 const param = wip.arg(llvm_arg_i);1622 const param = wip.arg(llvm_arg_i);
1619 llvm_arg_i += 1;1623 llvm_arg_i += 1;
16201624
1621 const alignment = param_ty.abiAlignment(zcu).toLlvm();1625 const alignment = param_ty.abiAlignment(pt).toLlvm();
1622 const arg_ptr = try buildAllocaInner(&wip, param_llvm_ty, alignment, target);1626 const arg_ptr = try buildAllocaInner(&wip, param_llvm_ty, alignment, target);
1623 _ = try wip.store(.normal, param, arg_ptr, alignment);1627 _ = try wip.store(.normal, param, arg_ptr, alignment);
16241628
1625 args.appendAssumeCapacity(if (isByRef(param_ty, zcu))1629 args.appendAssumeCapacity(if (isByRef(param_ty, pt))
1626 arg_ptr1630 arg_ptr
1627 else1631 else
1628 try wip.load(.normal, param_llvm_ty, arg_ptr, alignment, ""));1632 try wip.load(.normal, param_llvm_ty, arg_ptr, alignment, ""));
...@@ -1700,8 +1704,9 @@ pub const Object = struct {...@@ -1700,8 +1704,9 @@ pub const Object = struct {
1700 try fg.wip.finish();1704 try fg.wip.finish();
1701 }1705 }
17021706
1703 pub fn updateDecl(self: *Object, module: *Module, decl_index: InternPool.DeclIndex) !void {1707 pub fn updateDecl(self: *Object, pt: Zcu.PerThread, decl_index: InternPool.DeclIndex) !void {
1704 const decl = module.declPtr(decl_index);1708 assert(std.meta.eql(pt, self.pt));
1709 const decl = pt.zcu.declPtr(decl_index);
1705 var dg: DeclGen = .{1710 var dg: DeclGen = .{
1706 .object = self,1711 .object = self,
1707 .decl = decl,1712 .decl = decl,
...@@ -1711,7 +1716,7 @@ pub const Object = struct {...@@ -1711,7 +1716,7 @@ pub const Object = struct {
1711 dg.genDecl() catch |err| switch (err) {1716 dg.genDecl() catch |err| switch (err) {
1712 error.CodegenFail => {1717 error.CodegenFail => {
1713 decl.analysis = .codegen_failure;1718 decl.analysis = .codegen_failure;
1714 try module.failed_analysis.put(module.gpa, InternPool.AnalUnit.wrap(.{ .decl = decl_index }), dg.err_msg.?);1719 try pt.zcu.failed_analysis.put(pt.zcu.gpa, InternPool.AnalUnit.wrap(.{ .decl = decl_index }), dg.err_msg.?);
1715 dg.err_msg = null;1720 dg.err_msg = null;
1716 return;1721 return;
1717 },1722 },
...@@ -1721,10 +1726,12 @@ pub const Object = struct {...@@ -1721,10 +1726,12 @@ pub const Object = struct {
17211726
1722 pub fn updateExports(1727 pub fn updateExports(
1723 self: *Object,1728 self: *Object,
1724 zcu: *Zcu,1729 pt: Zcu.PerThread,
1725 exported: Module.Exported,1730 exported: Zcu.Exported,
1726 export_indices: []const u32,1731 export_indices: []const u32,
1727 ) link.File.UpdateExportsError!void {1732 ) link.File.UpdateExportsError!void {
1733 assert(std.meta.eql(pt, self.pt));
1734 const zcu = pt.zcu;
1728 const decl_index = switch (exported) {1735 const decl_index = switch (exported) {
1729 .decl_index => |i| i,1736 .decl_index => |i| i,
1730 .value => |val| return updateExportedValue(self, zcu, val, export_indices),1737 .value => |val| return updateExportedValue(self, zcu, val, export_indices),
...@@ -1737,7 +1744,7 @@ pub const Object = struct {...@@ -1737,7 +1744,7 @@ pub const Object = struct {
1737 if (export_indices.len != 0) {1744 if (export_indices.len != 0) {
1738 return updateExportedGlobal(self, zcu, global_index, export_indices);1745 return updateExportedGlobal(self, zcu, global_index, export_indices);
1739 } else {1746 } else {
1740 const fqn = try self.builder.strtabString((try decl.fullyQualifiedName(zcu)).toSlice(ip));1747 const fqn = try self.builder.strtabString((try decl.fullyQualifiedName(pt)).toSlice(ip));
1741 try global_index.rename(fqn, &self.builder);1748 try global_index.rename(fqn, &self.builder);
1742 global_index.setLinkage(.internal, &self.builder);1749 global_index.setLinkage(.internal, &self.builder);
1743 if (comp.config.dll_export_fns)1750 if (comp.config.dll_export_fns)
...@@ -1748,7 +1755,7 @@ pub const Object = struct {...@@ -1748,7 +1755,7 @@ pub const Object = struct {
17481755
1749 fn updateExportedValue(1756 fn updateExportedValue(
1750 o: *Object,1757 o: *Object,
1751 mod: *Module,1758 mod: *Zcu,
1752 exported_value: InternPool.Index,1759 exported_value: InternPool.Index,
1753 export_indices: []const u32,1760 export_indices: []const u32,
1754 ) link.File.UpdateExportsError!void {1761 ) link.File.UpdateExportsError!void {
...@@ -1783,7 +1790,7 @@ pub const Object = struct {...@@ -1783,7 +1790,7 @@ pub const Object = struct {
17831790
1784 fn updateExportedGlobal(1791 fn updateExportedGlobal(
1785 o: *Object,1792 o: *Object,
1786 mod: *Module,1793 mod: *Zcu,
1787 global_index: Builder.Global.Index,1794 global_index: Builder.Global.Index,
1788 export_indices: []const u32,1795 export_indices: []const u32,
1789 ) link.File.UpdateExportsError!void {1796 ) link.File.UpdateExportsError!void {
...@@ -1879,7 +1886,7 @@ pub const Object = struct {...@@ -1879,7 +1886,7 @@ pub const Object = struct {
1879 global.delete(&self.builder);1886 global.delete(&self.builder);
1880 }1887 }
18811888
1882 fn getDebugFile(o: *Object, file: *const Module.File) Allocator.Error!Builder.Metadata {1889 fn getDebugFile(o: *Object, file: *const Zcu.File) Allocator.Error!Builder.Metadata {
1883 const gpa = o.gpa;1890 const gpa = o.gpa;
1884 const gop = try o.debug_file_map.getOrPut(gpa, file);1891 const gop = try o.debug_file_map.getOrPut(gpa, file);
1885 errdefer assert(o.debug_file_map.remove(file));1892 errdefer assert(o.debug_file_map.remove(file));
...@@ -1909,7 +1916,8 @@ pub const Object = struct {...@@ -1909,7 +1916,8 @@ pub const Object = struct {
19091916
1910 const gpa = o.gpa;1917 const gpa = o.gpa;
1911 const target = o.target;1918 const target = o.target;
1912 const zcu = o.module;1919 const pt = o.pt;
1920 const zcu = pt.zcu;
1913 const ip = &zcu.intern_pool;1921 const ip = &zcu.intern_pool;
19141922
1915 if (o.debug_type_map.get(ty)) |debug_type| return debug_type;1923 if (o.debug_type_map.get(ty)) |debug_type| return debug_type;
...@@ -1931,7 +1939,7 @@ pub const Object = struct {...@@ -1931,7 +1939,7 @@ pub const Object = struct {
1931 const name = try o.allocTypeName(ty);1939 const name = try o.allocTypeName(ty);
1932 defer gpa.free(name);1940 defer gpa.free(name);
1933 const builder_name = try o.builder.metadataString(name);1941 const builder_name = try o.builder.metadataString(name);
1934 const debug_bits = ty.abiSize(zcu) * 8; // lldb cannot handle non-byte sized types1942 const debug_bits = ty.abiSize(pt) * 8; // lldb cannot handle non-byte sized types
1935 const debug_int_type = switch (info.signedness) {1943 const debug_int_type = switch (info.signedness) {
1936 .signed => try o.builder.debugSignedType(builder_name, debug_bits),1944 .signed => try o.builder.debugSignedType(builder_name, debug_bits),
1937 .unsigned => try o.builder.debugUnsignedType(builder_name, debug_bits),1945 .unsigned => try o.builder.debugUnsignedType(builder_name, debug_bits),
...@@ -1941,9 +1949,9 @@ pub const Object = struct {...@@ -1941,9 +1949,9 @@ pub const Object = struct {
1941 },1949 },
1942 .Enum => {1950 .Enum => {
1943 const owner_decl_index = ty.getOwnerDecl(zcu);1951 const owner_decl_index = ty.getOwnerDecl(zcu);
1944 const owner_decl = o.module.declPtr(owner_decl_index);1952 const owner_decl = zcu.declPtr(owner_decl_index);
19451953
1946 if (!ty.hasRuntimeBitsIgnoreComptime(zcu)) {1954 if (!ty.hasRuntimeBitsIgnoreComptime(pt)) {
1947 const debug_enum_type = try o.makeEmptyNamespaceDebugType(owner_decl_index);1955 const debug_enum_type = try o.makeEmptyNamespaceDebugType(owner_decl_index);
1948 try o.debug_type_map.put(gpa, ty, debug_enum_type);1956 try o.debug_type_map.put(gpa, ty, debug_enum_type);
1949 return debug_enum_type;1957 return debug_enum_type;
...@@ -1961,7 +1969,7 @@ pub const Object = struct {...@@ -1961,7 +1969,7 @@ pub const Object = struct {
1961 for (enum_type.names.get(ip), 0..) |field_name_ip, i| {1969 for (enum_type.names.get(ip), 0..) |field_name_ip, i| {
1962 var bigint_space: Value.BigIntSpace = undefined;1970 var bigint_space: Value.BigIntSpace = undefined;
1963 const bigint = if (enum_type.values.len != 0)1971 const bigint = if (enum_type.values.len != 0)
1964 Value.fromInterned(enum_type.values.get(ip)[i]).toBigInt(&bigint_space, zcu)1972 Value.fromInterned(enum_type.values.get(ip)[i]).toBigInt(&bigint_space, pt)
1965 else1973 else
1966 std.math.big.int.Mutable.init(&bigint_space.limbs, i).toConst();1974 std.math.big.int.Mutable.init(&bigint_space.limbs, i).toConst();
19671975
...@@ -1986,8 +1994,8 @@ pub const Object = struct {...@@ -1986,8 +1994,8 @@ pub const Object = struct {
1986 scope,1994 scope,
1987 owner_decl.typeSrcLine(zcu) + 1, // Line1995 owner_decl.typeSrcLine(zcu) + 1, // Line
1988 try o.lowerDebugType(int_ty),1996 try o.lowerDebugType(int_ty),
1989 ty.abiSize(zcu) * 8,1997 ty.abiSize(pt) * 8,
1990 (ty.abiAlignment(zcu).toByteUnits() orelse 0) * 8,1998 (ty.abiAlignment(pt).toByteUnits() orelse 0) * 8,
1991 try o.builder.debugTuple(enumerators),1999 try o.builder.debugTuple(enumerators),
1992 );2000 );
19932001
...@@ -2027,10 +2035,10 @@ pub const Object = struct {...@@ -2027,10 +2035,10 @@ pub const Object = struct {
2027 ptr_info.flags.is_const or2035 ptr_info.flags.is_const or
2028 ptr_info.flags.is_volatile or2036 ptr_info.flags.is_volatile or
2029 ptr_info.flags.size == .Many or ptr_info.flags.size == .C or2037 ptr_info.flags.size == .Many or ptr_info.flags.size == .C or
2030 !Type.fromInterned(ptr_info.child).hasRuntimeBitsIgnoreComptime(zcu))2038 !Type.fromInterned(ptr_info.child).hasRuntimeBitsIgnoreComptime(pt))
2031 {2039 {
2032 const bland_ptr_ty = try zcu.ptrType(.{2040 const bland_ptr_ty = try pt.ptrType(.{
2033 .child = if (!Type.fromInterned(ptr_info.child).hasRuntimeBitsIgnoreComptime(zcu))2041 .child = if (!Type.fromInterned(ptr_info.child).hasRuntimeBitsIgnoreComptime(pt))
2034 .anyopaque_type2042 .anyopaque_type
2035 else2043 else
2036 ptr_info.child,2044 ptr_info.child,
...@@ -2060,10 +2068,10 @@ pub const Object = struct {...@@ -2060,10 +2068,10 @@ pub const Object = struct {
2060 defer gpa.free(name);2068 defer gpa.free(name);
2061 const line = 0;2069 const line = 0;
20622070
2063 const ptr_size = ptr_ty.abiSize(zcu);2071 const ptr_size = ptr_ty.abiSize(pt);
2064 const ptr_align = ptr_ty.abiAlignment(zcu);2072 const ptr_align = ptr_ty.abiAlignment(pt);
2065 const len_size = len_ty.abiSize(zcu);2073 const len_size = len_ty.abiSize(pt);
2066 const len_align = len_ty.abiAlignment(zcu);2074 const len_align = len_ty.abiAlignment(pt);
20672075
2068 const len_offset = len_align.forward(ptr_size);2076 const len_offset = len_align.forward(ptr_size);
20692077
...@@ -2095,8 +2103,8 @@ pub const Object = struct {...@@ -2095,8 +2103,8 @@ pub const Object = struct {
2095 o.debug_compile_unit, // Scope2103 o.debug_compile_unit, // Scope
2096 line,2104 line,
2097 .none, // Underlying type2105 .none, // Underlying type
2098 ty.abiSize(zcu) * 8,2106 ty.abiSize(pt) * 8,
2099 (ty.abiAlignment(zcu).toByteUnits() orelse 0) * 8,2107 (ty.abiAlignment(pt).toByteUnits() orelse 0) * 8,
2100 try o.builder.debugTuple(&.{2108 try o.builder.debugTuple(&.{
2101 debug_ptr_type,2109 debug_ptr_type,
2102 debug_len_type,2110 debug_len_type,
...@@ -2124,7 +2132,7 @@ pub const Object = struct {...@@ -2124,7 +2132,7 @@ pub const Object = struct {
2124 0, // Line2132 0, // Line
2125 debug_elem_ty,2133 debug_elem_ty,
2126 target.ptrBitWidth(),2134 target.ptrBitWidth(),
2127 (ty.ptrAlignment(zcu).toByteUnits() orelse 0) * 8,2135 (ty.ptrAlignment(pt).toByteUnits() orelse 0) * 8,
2128 0, // Offset2136 0, // Offset
2129 );2137 );
21302138
...@@ -2149,7 +2157,7 @@ pub const Object = struct {...@@ -2149,7 +2157,7 @@ pub const Object = struct {
2149 const name = try o.allocTypeName(ty);2157 const name = try o.allocTypeName(ty);
2150 defer gpa.free(name);2158 defer gpa.free(name);
2151 const owner_decl_index = ty.getOwnerDecl(zcu);2159 const owner_decl_index = ty.getOwnerDecl(zcu);
2152 const owner_decl = o.module.declPtr(owner_decl_index);2160 const owner_decl = zcu.declPtr(owner_decl_index);
2153 const file_scope = zcu.namespacePtr(owner_decl.src_namespace).fileScope(zcu);2161 const file_scope = zcu.namespacePtr(owner_decl.src_namespace).fileScope(zcu);
2154 const debug_opaque_type = try o.builder.debugStructType(2162 const debug_opaque_type = try o.builder.debugStructType(
2155 try o.builder.metadataString(name),2163 try o.builder.metadataString(name),
...@@ -2171,8 +2179,8 @@ pub const Object = struct {...@@ -2171,8 +2179,8 @@ pub const Object = struct {
2171 .none, // Scope2179 .none, // Scope
2172 0, // Line2180 0, // Line
2173 try o.lowerDebugType(ty.childType(zcu)),2181 try o.lowerDebugType(ty.childType(zcu)),
2174 ty.abiSize(zcu) * 8,2182 ty.abiSize(pt) * 8,
2175 (ty.abiAlignment(zcu).toByteUnits() orelse 0) * 8,2183 (ty.abiAlignment(pt).toByteUnits() orelse 0) * 8,
2176 try o.builder.debugTuple(&.{2184 try o.builder.debugTuple(&.{
2177 try o.builder.debugSubrange(2185 try o.builder.debugSubrange(
2178 try o.builder.debugConstant(try o.builder.intConst(.i64, 0)),2186 try o.builder.debugConstant(try o.builder.intConst(.i64, 0)),
...@@ -2214,8 +2222,8 @@ pub const Object = struct {...@@ -2214,8 +2222,8 @@ pub const Object = struct {
2214 .none, // Scope2222 .none, // Scope
2215 0, // Line2223 0, // Line
2216 debug_elem_type,2224 debug_elem_type,
2217 ty.abiSize(zcu) * 8,2225 ty.abiSize(pt) * 8,
2218 (ty.abiAlignment(zcu).toByteUnits() orelse 0) * 8,2226 (ty.abiAlignment(pt).toByteUnits() orelse 0) * 8,
2219 try o.builder.debugTuple(&.{2227 try o.builder.debugTuple(&.{
2220 try o.builder.debugSubrange(2228 try o.builder.debugSubrange(
2221 try o.builder.debugConstant(try o.builder.intConst(.i64, 0)),2229 try o.builder.debugConstant(try o.builder.intConst(.i64, 0)),
...@@ -2231,7 +2239,7 @@ pub const Object = struct {...@@ -2231,7 +2239,7 @@ pub const Object = struct {
2231 const name = try o.allocTypeName(ty);2239 const name = try o.allocTypeName(ty);
2232 defer gpa.free(name);2240 defer gpa.free(name);
2233 const child_ty = ty.optionalChild(zcu);2241 const child_ty = ty.optionalChild(zcu);
2234 if (!child_ty.hasRuntimeBitsIgnoreComptime(zcu)) {2242 if (!child_ty.hasRuntimeBitsIgnoreComptime(pt)) {
2235 const debug_bool_type = try o.builder.debugBoolType(2243 const debug_bool_type = try o.builder.debugBoolType(
2236 try o.builder.metadataString(name),2244 try o.builder.metadataString(name),
2237 8,2245 8,
...@@ -2258,10 +2266,10 @@ pub const Object = struct {...@@ -2258,10 +2266,10 @@ pub const Object = struct {
2258 }2266 }
22592267
2260 const non_null_ty = Type.u8;2268 const non_null_ty = Type.u8;
2261 const payload_size = child_ty.abiSize(zcu);2269 const payload_size = child_ty.abiSize(pt);
2262 const payload_align = child_ty.abiAlignment(zcu);2270 const payload_align = child_ty.abiAlignment(pt);
2263 const non_null_size = non_null_ty.abiSize(zcu);2271 const non_null_size = non_null_ty.abiSize(pt);
2264 const non_null_align = non_null_ty.abiAlignment(zcu);2272 const non_null_align = non_null_ty.abiAlignment(pt);
2265 const non_null_offset = non_null_align.forward(payload_size);2273 const non_null_offset = non_null_align.forward(payload_size);
22662274
2267 const debug_data_type = try o.builder.debugMemberType(2275 const debug_data_type = try o.builder.debugMemberType(
...@@ -2292,8 +2300,8 @@ pub const Object = struct {...@@ -2292,8 +2300,8 @@ pub const Object = struct {
2292 o.debug_compile_unit, // Scope2300 o.debug_compile_unit, // Scope
2293 0, // Line2301 0, // Line
2294 .none, // Underlying type2302 .none, // Underlying type
2295 ty.abiSize(zcu) * 8,2303 ty.abiSize(pt) * 8,
2296 (ty.abiAlignment(zcu).toByteUnits() orelse 0) * 8,2304 (ty.abiAlignment(pt).toByteUnits() orelse 0) * 8,
2297 try o.builder.debugTuple(&.{2305 try o.builder.debugTuple(&.{
2298 debug_data_type,2306 debug_data_type,
2299 debug_some_type,2307 debug_some_type,
...@@ -2310,7 +2318,7 @@ pub const Object = struct {...@@ -2310,7 +2318,7 @@ pub const Object = struct {
2310 },2318 },
2311 .ErrorUnion => {2319 .ErrorUnion => {
2312 const payload_ty = ty.errorUnionPayload(zcu);2320 const payload_ty = ty.errorUnionPayload(zcu);
2313 if (!payload_ty.hasRuntimeBitsIgnoreComptime(zcu)) {2321 if (!payload_ty.hasRuntimeBitsIgnoreComptime(pt)) {
2314 // TODO: Maybe remove?2322 // TODO: Maybe remove?
2315 const debug_error_union_type = try o.lowerDebugType(Type.anyerror);2323 const debug_error_union_type = try o.lowerDebugType(Type.anyerror);
2316 try o.debug_type_map.put(gpa, ty, debug_error_union_type);2324 try o.debug_type_map.put(gpa, ty, debug_error_union_type);
...@@ -2320,10 +2328,10 @@ pub const Object = struct {...@@ -2320,10 +2328,10 @@ pub const Object = struct {
2320 const name = try o.allocTypeName(ty);2328 const name = try o.allocTypeName(ty);
2321 defer gpa.free(name);2329 defer gpa.free(name);
23222330
2323 const error_size = Type.anyerror.abiSize(zcu);2331 const error_size = Type.anyerror.abiSize(pt);
2324 const error_align = Type.anyerror.abiAlignment(zcu);2332 const error_align = Type.anyerror.abiAlignment(pt);
2325 const payload_size = payload_ty.abiSize(zcu);2333 const payload_size = payload_ty.abiSize(pt);
2326 const payload_align = payload_ty.abiAlignment(zcu);2334 const payload_align = payload_ty.abiAlignment(pt);
23272335
2328 var error_index: u32 = undefined;2336 var error_index: u32 = undefined;
2329 var payload_index: u32 = undefined;2337 var payload_index: u32 = undefined;
...@@ -2371,8 +2379,8 @@ pub const Object = struct {...@@ -2371,8 +2379,8 @@ pub const Object = struct {
2371 o.debug_compile_unit, // Sope2379 o.debug_compile_unit, // Sope
2372 0, // Line2380 0, // Line
2373 .none, // Underlying type2381 .none, // Underlying type
2374 ty.abiSize(zcu) * 8,2382 ty.abiSize(pt) * 8,
2375 (ty.abiAlignment(zcu).toByteUnits() orelse 0) * 8,2383 (ty.abiAlignment(pt).toByteUnits() orelse 0) * 8,
2376 try o.builder.debugTuple(&fields),2384 try o.builder.debugTuple(&fields),
2377 );2385 );
23782386
...@@ -2399,8 +2407,8 @@ pub const Object = struct {...@@ -2399,8 +2407,8 @@ pub const Object = struct {
2399 const info = Type.fromInterned(backing_int_ty).intInfo(zcu);2407 const info = Type.fromInterned(backing_int_ty).intInfo(zcu);
2400 const builder_name = try o.builder.metadataString(name);2408 const builder_name = try o.builder.metadataString(name);
2401 const debug_int_type = switch (info.signedness) {2409 const debug_int_type = switch (info.signedness) {
2402 .signed => try o.builder.debugSignedType(builder_name, ty.abiSize(zcu) * 8),2410 .signed => try o.builder.debugSignedType(builder_name, ty.abiSize(pt) * 8),
2403 .unsigned => try o.builder.debugUnsignedType(builder_name, ty.abiSize(zcu) * 8),2411 .unsigned => try o.builder.debugUnsignedType(builder_name, ty.abiSize(pt) * 8),
2404 };2412 };
2405 try o.debug_type_map.put(gpa, ty, debug_int_type);2413 try o.debug_type_map.put(gpa, ty, debug_int_type);
2406 return debug_int_type;2414 return debug_int_type;
...@@ -2420,10 +2428,10 @@ pub const Object = struct {...@@ -2420,10 +2428,10 @@ pub const Object = struct {
2420 const debug_fwd_ref = try o.builder.debugForwardReference();2428 const debug_fwd_ref = try o.builder.debugForwardReference();
24212429
2422 for (tuple.types.get(ip), tuple.values.get(ip), 0..) |field_ty, field_val, i| {2430 for (tuple.types.get(ip), tuple.values.get(ip), 0..) |field_ty, field_val, i| {
2423 if (field_val != .none or !Type.fromInterned(field_ty).hasRuntimeBits(zcu)) continue;2431 if (field_val != .none or !Type.fromInterned(field_ty).hasRuntimeBits(pt)) continue;
24242432
2425 const field_size = Type.fromInterned(field_ty).abiSize(zcu);2433 const field_size = Type.fromInterned(field_ty).abiSize(pt);
2426 const field_align = Type.fromInterned(field_ty).abiAlignment(zcu);2434 const field_align = Type.fromInterned(field_ty).abiAlignment(pt);
2427 const field_offset = field_align.forward(offset);2435 const field_offset = field_align.forward(offset);
2428 offset = field_offset + field_size;2436 offset = field_offset + field_size;
24292437
...@@ -2451,8 +2459,8 @@ pub const Object = struct {...@@ -2451,8 +2459,8 @@ pub const Object = struct {
2451 o.debug_compile_unit, // Scope2459 o.debug_compile_unit, // Scope
2452 0, // Line2460 0, // Line
2453 .none, // Underlying type2461 .none, // Underlying type
2454 ty.abiSize(zcu) * 8,2462 ty.abiSize(pt) * 8,
2455 (ty.abiAlignment(zcu).toByteUnits() orelse 0) * 8,2463 (ty.abiAlignment(pt).toByteUnits() orelse 0) * 8,
2456 try o.builder.debugTuple(fields.items),2464 try o.builder.debugTuple(fields.items),
2457 );2465 );
24582466
...@@ -2479,7 +2487,7 @@ pub const Object = struct {...@@ -2479,7 +2487,7 @@ pub const Object = struct {
2479 else => {},2487 else => {},
2480 }2488 }
24812489
2482 if (!ty.hasRuntimeBitsIgnoreComptime(zcu)) {2490 if (!ty.hasRuntimeBitsIgnoreComptime(pt)) {
2483 const owner_decl_index = ty.getOwnerDecl(zcu);2491 const owner_decl_index = ty.getOwnerDecl(zcu);
2484 const debug_struct_type = try o.makeEmptyNamespaceDebugType(owner_decl_index);2492 const debug_struct_type = try o.makeEmptyNamespaceDebugType(owner_decl_index);
2485 try o.debug_type_map.put(gpa, ty, debug_struct_type);2493 try o.debug_type_map.put(gpa, ty, debug_struct_type);
...@@ -2502,17 +2510,17 @@ pub const Object = struct {...@@ -2502,17 +2510,17 @@ pub const Object = struct {
2502 var it = struct_type.iterateRuntimeOrder(ip);2510 var it = struct_type.iterateRuntimeOrder(ip);
2503 while (it.next()) |field_index| {2511 while (it.next()) |field_index| {
2504 const field_ty = Type.fromInterned(struct_type.field_types.get(ip)[field_index]);2512 const field_ty = Type.fromInterned(struct_type.field_types.get(ip)[field_index]);
2505 if (!field_ty.hasRuntimeBitsIgnoreComptime(zcu)) continue;2513 if (!field_ty.hasRuntimeBitsIgnoreComptime(pt)) continue;
2506 const field_size = field_ty.abiSize(zcu);2514 const field_size = field_ty.abiSize(pt);
2507 const field_align = zcu.structFieldAlignment(2515 const field_align = pt.structFieldAlignment(
2508 struct_type.fieldAlign(ip, field_index),2516 struct_type.fieldAlign(ip, field_index),
2509 field_ty,2517 field_ty,
2510 struct_type.layout,2518 struct_type.layout,
2511 );2519 );
2512 const field_offset = ty.structFieldOffset(field_index, zcu);2520 const field_offset = ty.structFieldOffset(field_index, pt);
25132521
2514 const field_name = struct_type.fieldName(ip, field_index).unwrap() orelse2522 const field_name = struct_type.fieldName(ip, field_index).unwrap() orelse
2515 try ip.getOrPutStringFmt(gpa, "{d}", .{field_index}, .no_embedded_nulls);2523 try ip.getOrPutStringFmt(gpa, pt.tid, "{d}", .{field_index}, .no_embedded_nulls);
25162524
2517 fields.appendAssumeCapacity(try o.builder.debugMemberType(2525 fields.appendAssumeCapacity(try o.builder.debugMemberType(
2518 try o.builder.metadataString(field_name.toSlice(ip)),2526 try o.builder.metadataString(field_name.toSlice(ip)),
...@@ -2532,8 +2540,8 @@ pub const Object = struct {...@@ -2532,8 +2540,8 @@ pub const Object = struct {
2532 o.debug_compile_unit, // Scope2540 o.debug_compile_unit, // Scope
2533 0, // Line2541 0, // Line
2534 .none, // Underlying type2542 .none, // Underlying type
2535 ty.abiSize(zcu) * 8,2543 ty.abiSize(pt) * 8,
2536 (ty.abiAlignment(zcu).toByteUnits() orelse 0) * 8,2544 (ty.abiAlignment(pt).toByteUnits() orelse 0) * 8,
2537 try o.builder.debugTuple(fields.items),2545 try o.builder.debugTuple(fields.items),
2538 );2546 );
25392547
...@@ -2553,7 +2561,7 @@ pub const Object = struct {...@@ -2553,7 +2561,7 @@ pub const Object = struct {
25532561
2554 const union_type = ip.loadUnionType(ty.toIntern());2562 const union_type = ip.loadUnionType(ty.toIntern());
2555 if (!union_type.haveFieldTypes(ip) or2563 if (!union_type.haveFieldTypes(ip) or
2556 !ty.hasRuntimeBitsIgnoreComptime(zcu) or2564 !ty.hasRuntimeBitsIgnoreComptime(pt) or
2557 !union_type.haveLayout(ip))2565 !union_type.haveLayout(ip))
2558 {2566 {
2559 const debug_union_type = try o.makeEmptyNamespaceDebugType(owner_decl_index);2567 const debug_union_type = try o.makeEmptyNamespaceDebugType(owner_decl_index);
...@@ -2561,7 +2569,7 @@ pub const Object = struct {...@@ -2561,7 +2569,7 @@ pub const Object = struct {
2561 return debug_union_type;2569 return debug_union_type;
2562 }2570 }
25632571
2564 const layout = zcu.getUnionLayout(union_type);2572 const layout = pt.getUnionLayout(union_type);
25652573
2566 const debug_fwd_ref = try o.builder.debugForwardReference();2574 const debug_fwd_ref = try o.builder.debugForwardReference();
25672575
...@@ -2575,8 +2583,8 @@ pub const Object = struct {...@@ -2575,8 +2583,8 @@ pub const Object = struct {
2575 o.debug_compile_unit, // Scope2583 o.debug_compile_unit, // Scope
2576 0, // Line2584 0, // Line
2577 .none, // Underlying type2585 .none, // Underlying type
2578 ty.abiSize(zcu) * 8,2586 ty.abiSize(pt) * 8,
2579 (ty.abiAlignment(zcu).toByteUnits() orelse 0) * 8,2587 (ty.abiAlignment(pt).toByteUnits() orelse 0) * 8,
2580 try o.builder.debugTuple(2588 try o.builder.debugTuple(
2581 &.{try o.lowerDebugType(Type.fromInterned(union_type.enum_tag_ty))},2589 &.{try o.lowerDebugType(Type.fromInterned(union_type.enum_tag_ty))},
2582 ),2590 ),
...@@ -2603,12 +2611,12 @@ pub const Object = struct {...@@ -2603,12 +2611,12 @@ pub const Object = struct {
26032611
2604 for (0..tag_type.names.len) |field_index| {2612 for (0..tag_type.names.len) |field_index| {
2605 const field_ty = union_type.field_types.get(ip)[field_index];2613 const field_ty = union_type.field_types.get(ip)[field_index];
2606 if (!Type.fromInterned(field_ty).hasRuntimeBitsIgnoreComptime(zcu)) continue;2614 if (!Type.fromInterned(field_ty).hasRuntimeBitsIgnoreComptime(pt)) continue;
26072615
2608 const field_size = Type.fromInterned(field_ty).abiSize(zcu);2616 const field_size = Type.fromInterned(field_ty).abiSize(pt);
2609 const field_align: InternPool.Alignment = switch (union_type.flagsPtr(ip).layout) {2617 const field_align: InternPool.Alignment = switch (union_type.flagsPtr(ip).layout) {
2610 .@"packed" => .none,2618 .@"packed" => .none,
2611 .auto, .@"extern" => zcu.unionFieldNormalAlignment(union_type, @intCast(field_index)),2619 .auto, .@"extern" => pt.unionFieldNormalAlignment(union_type, @intCast(field_index)),
2612 };2620 };
26132621
2614 const field_name = tag_type.names.get(ip)[field_index];2622 const field_name = tag_type.names.get(ip)[field_index];
...@@ -2637,8 +2645,8 @@ pub const Object = struct {...@@ -2637,8 +2645,8 @@ pub const Object = struct {
2637 o.debug_compile_unit, // Scope2645 o.debug_compile_unit, // Scope
2638 0, // Line2646 0, // Line
2639 .none, // Underlying type2647 .none, // Underlying type
2640 ty.abiSize(zcu) * 8,2648 ty.abiSize(pt) * 8,
2641 (ty.abiAlignment(zcu).toByteUnits() orelse 0) * 8,2649 (ty.abiAlignment(pt).toByteUnits() orelse 0) * 8,
2642 try o.builder.debugTuple(fields.items),2650 try o.builder.debugTuple(fields.items),
2643 );2651 );
26442652
...@@ -2696,8 +2704,8 @@ pub const Object = struct {...@@ -2696,8 +2704,8 @@ pub const Object = struct {
2696 o.debug_compile_unit, // Scope2704 o.debug_compile_unit, // Scope
2697 0, // Line2705 0, // Line
2698 .none, // Underlying type2706 .none, // Underlying type
2699 ty.abiSize(zcu) * 8,2707 ty.abiSize(pt) * 8,
2700 (ty.abiAlignment(zcu).toByteUnits() orelse 0) * 8,2708 (ty.abiAlignment(pt).toByteUnits() orelse 0) * 8,
2701 try o.builder.debugTuple(&full_fields),2709 try o.builder.debugTuple(&full_fields),
2702 );2710 );
27032711
...@@ -2718,13 +2726,13 @@ pub const Object = struct {...@@ -2718,13 +2726,13 @@ pub const Object = struct {
2718 try debug_param_types.ensureUnusedCapacity(3 + fn_info.param_types.len);2726 try debug_param_types.ensureUnusedCapacity(3 + fn_info.param_types.len);
27192727
2720 // Return type goes first.2728 // Return type goes first.
2721 if (Type.fromInterned(fn_info.return_type).hasRuntimeBitsIgnoreComptime(zcu)) {2729 if (Type.fromInterned(fn_info.return_type).hasRuntimeBitsIgnoreComptime(pt)) {
2722 const sret = firstParamSRet(fn_info, zcu, target);2730 const sret = firstParamSRet(fn_info, pt, target);
2723 const ret_ty = if (sret) Type.void else Type.fromInterned(fn_info.return_type);2731 const ret_ty = if (sret) Type.void else Type.fromInterned(fn_info.return_type);
2724 debug_param_types.appendAssumeCapacity(try o.lowerDebugType(ret_ty));2732 debug_param_types.appendAssumeCapacity(try o.lowerDebugType(ret_ty));
27252733
2726 if (sret) {2734 if (sret) {
2727 const ptr_ty = try zcu.singleMutPtrType(Type.fromInterned(fn_info.return_type));2735 const ptr_ty = try pt.singleMutPtrType(Type.fromInterned(fn_info.return_type));
2728 debug_param_types.appendAssumeCapacity(try o.lowerDebugType(ptr_ty));2736 debug_param_types.appendAssumeCapacity(try o.lowerDebugType(ptr_ty));
2729 }2737 }
2730 } else {2738 } else {
...@@ -2732,18 +2740,18 @@ pub const Object = struct {...@@ -2732,18 +2740,18 @@ pub const Object = struct {
2732 }2740 }
27332741
2734 if (Type.fromInterned(fn_info.return_type).isError(zcu) and2742 if (Type.fromInterned(fn_info.return_type).isError(zcu) and
2735 o.module.comp.config.any_error_tracing)2743 zcu.comp.config.any_error_tracing)
2736 {2744 {
2737 const ptr_ty = try zcu.singleMutPtrType(try o.getStackTraceType());2745 const ptr_ty = try pt.singleMutPtrType(try o.getStackTraceType());
2738 debug_param_types.appendAssumeCapacity(try o.lowerDebugType(ptr_ty));2746 debug_param_types.appendAssumeCapacity(try o.lowerDebugType(ptr_ty));
2739 }2747 }
27402748
2741 for (0..fn_info.param_types.len) |i| {2749 for (0..fn_info.param_types.len) |i| {
2742 const param_ty = Type.fromInterned(fn_info.param_types.get(ip)[i]);2750 const param_ty = Type.fromInterned(fn_info.param_types.get(ip)[i]);
2743 if (!param_ty.hasRuntimeBitsIgnoreComptime(zcu)) continue;2751 if (!param_ty.hasRuntimeBitsIgnoreComptime(pt)) continue;
27442752
2745 if (isByRef(param_ty, zcu)) {2753 if (isByRef(param_ty, pt)) {
2746 const ptr_ty = try zcu.singleMutPtrType(param_ty);2754 const ptr_ty = try pt.singleMutPtrType(param_ty);
2747 debug_param_types.appendAssumeCapacity(try o.lowerDebugType(ptr_ty));2755 debug_param_types.appendAssumeCapacity(try o.lowerDebugType(ptr_ty));
2748 } else {2756 } else {
2749 debug_param_types.appendAssumeCapacity(try o.lowerDebugType(param_ty));2757 debug_param_types.appendAssumeCapacity(try o.lowerDebugType(param_ty));
...@@ -2770,7 +2778,7 @@ pub const Object = struct {...@@ -2770,7 +2778,7 @@ pub const Object = struct {
2770 }2778 }
27712779
2772 fn namespaceToDebugScope(o: *Object, namespace_index: InternPool.NamespaceIndex) !Builder.Metadata {2780 fn namespaceToDebugScope(o: *Object, namespace_index: InternPool.NamespaceIndex) !Builder.Metadata {
2773 const zcu = o.module;2781 const zcu = o.pt.zcu;
2774 const namespace = zcu.namespacePtr(namespace_index);2782 const namespace = zcu.namespacePtr(namespace_index);
2775 const file_scope = namespace.fileScope(zcu);2783 const file_scope = namespace.fileScope(zcu);
2776 if (namespace.parent == .none) return try o.getDebugFile(file_scope);2784 if (namespace.parent == .none) return try o.getDebugFile(file_scope);
...@@ -2783,7 +2791,7 @@ pub const Object = struct {...@@ -2783,7 +2791,7 @@ pub const Object = struct {
2783 }2791 }
27842792
2785 fn makeEmptyNamespaceDebugType(o: *Object, decl_index: InternPool.DeclIndex) !Builder.Metadata {2793 fn makeEmptyNamespaceDebugType(o: *Object, decl_index: InternPool.DeclIndex) !Builder.Metadata {
2786 const zcu = o.module;2794 const zcu = o.pt.zcu;
2787 const decl = zcu.declPtr(decl_index);2795 const decl = zcu.declPtr(decl_index);
2788 const file_scope = zcu.namespacePtr(decl.src_namespace).fileScope(zcu);2796 const file_scope = zcu.namespacePtr(decl.src_namespace).fileScope(zcu);
2789 return o.builder.debugStructType(2797 return o.builder.debugStructType(
...@@ -2799,21 +2807,22 @@ pub const Object = struct {...@@ -2799,21 +2807,22 @@ pub const Object = struct {
2799 }2807 }
28002808
2801 fn getStackTraceType(o: *Object) Allocator.Error!Type {2809 fn getStackTraceType(o: *Object) Allocator.Error!Type {
2802 const zcu = o.module;2810 const pt = o.pt;
2811 const zcu = pt.zcu;
28032812
2804 const std_mod = zcu.std_mod;2813 const std_mod = zcu.std_mod;
2805 const std_file_imported = zcu.importPkg(std_mod) catch unreachable;2814 const std_file_imported = zcu.importPkg(std_mod) catch unreachable;
28062815
2807 const builtin_str = try zcu.intern_pool.getOrPutString(zcu.gpa, "builtin", .no_embedded_nulls);2816 const builtin_str = try zcu.intern_pool.getOrPutString(zcu.gpa, pt.tid, "builtin", .no_embedded_nulls);
2808 const std_file_root_decl = zcu.fileRootDecl(std_file_imported.file_index);2817 const std_file_root_decl = zcu.fileRootDecl(std_file_imported.file_index);
2809 const std_namespace = zcu.namespacePtr(zcu.declPtr(std_file_root_decl.unwrap().?).src_namespace);2818 const std_namespace = zcu.namespacePtr(zcu.declPtr(std_file_root_decl.unwrap().?).src_namespace);
2810 const builtin_decl = std_namespace.decls.getKeyAdapted(builtin_str, Module.DeclAdapter{ .zcu = zcu }).?;2819 const builtin_decl = std_namespace.decls.getKeyAdapted(builtin_str, Zcu.DeclAdapter{ .zcu = zcu }).?;
28112820
2812 const stack_trace_str = try zcu.intern_pool.getOrPutString(zcu.gpa, "StackTrace", .no_embedded_nulls);2821 const stack_trace_str = try zcu.intern_pool.getOrPutString(zcu.gpa, pt.tid, "StackTrace", .no_embedded_nulls);
2813 // buffer is only used for int_type, `builtin` is a struct.2822 // buffer is only used for int_type, `builtin` is a struct.
2814 const builtin_ty = zcu.declPtr(builtin_decl).val.toType();2823 const builtin_ty = zcu.declPtr(builtin_decl).val.toType();
2815 const builtin_namespace = zcu.namespacePtrUnwrap(builtin_ty.getNamespaceIndex(zcu)).?;2824 const builtin_namespace = zcu.namespacePtrUnwrap(builtin_ty.getNamespaceIndex(zcu)).?;
2816 const stack_trace_decl_index = builtin_namespace.decls.getKeyAdapted(stack_trace_str, Module.DeclAdapter{ .zcu = zcu }).?;2825 const stack_trace_decl_index = builtin_namespace.decls.getKeyAdapted(stack_trace_str, Zcu.DeclAdapter{ .zcu = zcu }).?;
2817 const stack_trace_decl = zcu.declPtr(stack_trace_decl_index);2826 const stack_trace_decl = zcu.declPtr(stack_trace_decl_index);
28182827
2819 // Sema should have ensured that StackTrace was analyzed.2828 // Sema should have ensured that StackTrace was analyzed.
...@@ -2824,7 +2833,7 @@ pub const Object = struct {...@@ -2824,7 +2833,7 @@ pub const Object = struct {
2824 fn allocTypeName(o: *Object, ty: Type) Allocator.Error![:0]const u8 {2833 fn allocTypeName(o: *Object, ty: Type) Allocator.Error![:0]const u8 {
2825 var buffer = std.ArrayList(u8).init(o.gpa);2834 var buffer = std.ArrayList(u8).init(o.gpa);
2826 errdefer buffer.deinit();2835 errdefer buffer.deinit();
2827 try ty.print(buffer.writer(), o.module);2836 try ty.print(buffer.writer(), o.pt);
2828 return buffer.toOwnedSliceSentinel(0);2837 return buffer.toOwnedSliceSentinel(0);
2829 }2838 }
28302839
...@@ -2835,7 +2844,8 @@ pub const Object = struct {...@@ -2835,7 +2844,8 @@ pub const Object = struct {
2835 o: *Object,2844 o: *Object,
2836 decl_index: InternPool.DeclIndex,2845 decl_index: InternPool.DeclIndex,
2837 ) Allocator.Error!Builder.Function.Index {2846 ) Allocator.Error!Builder.Function.Index {
2838 const zcu = o.module;2847 const pt = o.pt;
2848 const zcu = pt.zcu;
2839 const ip = &zcu.intern_pool;2849 const ip = &zcu.intern_pool;
2840 const gpa = o.gpa;2850 const gpa = o.gpa;
2841 const decl = zcu.declPtr(decl_index);2851 const decl = zcu.declPtr(decl_index);
...@@ -2848,7 +2858,7 @@ pub const Object = struct {...@@ -2848,7 +2858,7 @@ pub const Object = struct {
2848 assert(decl.has_tv);2858 assert(decl.has_tv);
2849 const fn_info = zcu.typeToFunc(zig_fn_type).?;2859 const fn_info = zcu.typeToFunc(zig_fn_type).?;
2850 const target = owner_mod.resolved_target.result;2860 const target = owner_mod.resolved_target.result;
2851 const sret = firstParamSRet(fn_info, zcu, target);2861 const sret = firstParamSRet(fn_info, pt, target);
28522862
2853 const is_extern = decl.isExtern(zcu);2863 const is_extern = decl.isExtern(zcu);
2854 const function_index = try o.builder.addFunction(2864 const function_index = try o.builder.addFunction(
...@@ -2856,7 +2866,7 @@ pub const Object = struct {...@@ -2856,7 +2866,7 @@ pub const Object = struct {
2856 try o.builder.strtabString((if (is_extern)2866 try o.builder.strtabString((if (is_extern)
2857 decl.name2867 decl.name
2858 else2868 else
2859 try decl.fullyQualifiedName(zcu)).toSlice(ip)),2869 try decl.fullyQualifiedName(pt)).toSlice(ip)),
2860 toLlvmAddressSpace(decl.@"addrspace", target),2870 toLlvmAddressSpace(decl.@"addrspace", target),
2861 );2871 );
2862 gop.value_ptr.* = function_index.ptrConst(&o.builder).global;2872 gop.value_ptr.* = function_index.ptrConst(&o.builder).global;
...@@ -2929,14 +2939,14 @@ pub const Object = struct {...@@ -2929,14 +2939,14 @@ pub const Object = struct {
2929 .byval => {2939 .byval => {
2930 const param_index = it.zig_index - 1;2940 const param_index = it.zig_index - 1;
2931 const param_ty = Type.fromInterned(fn_info.param_types.get(ip)[param_index]);2941 const param_ty = Type.fromInterned(fn_info.param_types.get(ip)[param_index]);
2932 if (!isByRef(param_ty, zcu)) {2942 if (!isByRef(param_ty, pt)) {
2933 try o.addByValParamAttrs(&attributes, param_ty, param_index, fn_info, it.llvm_index - 1);2943 try o.addByValParamAttrs(&attributes, param_ty, param_index, fn_info, it.llvm_index - 1);
2934 }2944 }
2935 },2945 },
2936 .byref => {2946 .byref => {
2937 const param_ty = Type.fromInterned(fn_info.param_types.get(ip)[it.zig_index - 1]);2947 const param_ty = Type.fromInterned(fn_info.param_types.get(ip)[it.zig_index - 1]);
2938 const param_llvm_ty = try o.lowerType(param_ty);2948 const param_llvm_ty = try o.lowerType(param_ty);
2939 const alignment = param_ty.abiAlignment(zcu);2949 const alignment = param_ty.abiAlignment(pt);
2940 try o.addByRefParamAttrs(&attributes, it.llvm_index - 1, alignment.toLlvm(), it.byval_attr, param_llvm_ty);2950 try o.addByRefParamAttrs(&attributes, it.llvm_index - 1, alignment.toLlvm(), it.byval_attr, param_llvm_ty);
2941 },2951 },
2942 .byref_mut => try attributes.addParamAttr(it.llvm_index - 1, .noundef, &o.builder),2952 .byref_mut => try attributes.addParamAttr(it.llvm_index - 1, .noundef, &o.builder),
...@@ -2964,7 +2974,7 @@ pub const Object = struct {...@@ -2964,7 +2974,7 @@ pub const Object = struct {
2964 attributes: *Builder.FunctionAttributes.Wip,2974 attributes: *Builder.FunctionAttributes.Wip,
2965 owner_mod: *Package.Module,2975 owner_mod: *Package.Module,
2966 ) Allocator.Error!void {2976 ) Allocator.Error!void {
2967 const comp = o.module.comp;2977 const comp = o.pt.zcu.comp;
29682978
2969 if (!owner_mod.red_zone) {2979 if (!owner_mod.red_zone) {
2970 try attributes.addFnAttr(.noredzone, &o.builder);2980 try attributes.addFnAttr(.noredzone, &o.builder);
...@@ -3039,7 +3049,7 @@ pub const Object = struct {...@@ -3039,7 +3049,7 @@ pub const Object = struct {
3039 }3049 }
3040 errdefer assert(o.anon_decl_map.remove(decl_val));3050 errdefer assert(o.anon_decl_map.remove(decl_val));
30413051
3042 const mod = o.module;3052 const mod = o.pt.zcu;
3043 const decl_ty = mod.intern_pool.typeOf(decl_val);3053 const decl_ty = mod.intern_pool.typeOf(decl_val);
30443054
3045 const variable_index = try o.builder.addVariable(3055 const variable_index = try o.builder.addVariable(
...@@ -3065,7 +3075,8 @@ pub const Object = struct {...@@ -3065,7 +3075,8 @@ pub const Object = struct {
3065 if (gop.found_existing) return gop.value_ptr.ptr(&o.builder).kind.variable;3075 if (gop.found_existing) return gop.value_ptr.ptr(&o.builder).kind.variable;
3066 errdefer assert(o.decl_map.remove(decl_index));3076 errdefer assert(o.decl_map.remove(decl_index));
30673077
3068 const zcu = o.module;3078 const pt = o.pt;
3079 const zcu = pt.zcu;
3069 const decl = zcu.declPtr(decl_index);3080 const decl = zcu.declPtr(decl_index);
3070 const is_extern = decl.isExtern(zcu);3081 const is_extern = decl.isExtern(zcu);
30713082
...@@ -3073,7 +3084,7 @@ pub const Object = struct {...@@ -3073,7 +3084,7 @@ pub const Object = struct {
3073 try o.builder.strtabString((if (is_extern)3084 try o.builder.strtabString((if (is_extern)
3074 decl.name3085 decl.name
3075 else3086 else
3076 try decl.fullyQualifiedName(zcu)).toSlice(&zcu.intern_pool)),3087 try decl.fullyQualifiedName(pt)).toSlice(&zcu.intern_pool)),
3077 try o.lowerType(decl.typeOf(zcu)),3088 try o.lowerType(decl.typeOf(zcu)),
3078 toLlvmGlobalAddressSpace(decl.@"addrspace", zcu.getTarget()),3089 toLlvmGlobalAddressSpace(decl.@"addrspace", zcu.getTarget()),
3079 );3090 );
...@@ -3100,11 +3111,12 @@ pub const Object = struct {...@@ -3100,11 +3111,12 @@ pub const Object = struct {
3100 }3111 }
31013112
3102 fn errorIntType(o: *Object) Allocator.Error!Builder.Type {3113 fn errorIntType(o: *Object) Allocator.Error!Builder.Type {
3103 return o.builder.intType(o.module.errorSetBits());3114 return o.builder.intType(o.pt.zcu.errorSetBits());
3104 }3115 }
31053116
3106 fn lowerType(o: *Object, t: Type) Allocator.Error!Builder.Type {3117 fn lowerType(o: *Object, t: Type) Allocator.Error!Builder.Type {
3107 const mod = o.module;3118 const pt = o.pt;
3119 const mod = pt.zcu;
3108 const target = mod.getTarget();3120 const target = mod.getTarget();
3109 const ip = &mod.intern_pool;3121 const ip = &mod.intern_pool;
3110 return switch (t.toIntern()) {3122 return switch (t.toIntern()) {
...@@ -3230,7 +3242,7 @@ pub const Object = struct {...@@ -3230,7 +3242,7 @@ pub const Object = struct {
3230 ),3242 ),
3231 .opt_type => |child_ty| {3243 .opt_type => |child_ty| {
3232 // Must stay in sync with `opt_payload` logic in `lowerPtr`.3244 // Must stay in sync with `opt_payload` logic in `lowerPtr`.
3233 if (!Type.fromInterned(child_ty).hasRuntimeBitsIgnoreComptime(mod)) return .i8;3245 if (!Type.fromInterned(child_ty).hasRuntimeBitsIgnoreComptime(pt)) return .i8;
32343246
3235 const payload_ty = try o.lowerType(Type.fromInterned(child_ty));3247 const payload_ty = try o.lowerType(Type.fromInterned(child_ty));
3236 if (t.optionalReprIsPayload(mod)) return payload_ty;3248 if (t.optionalReprIsPayload(mod)) return payload_ty;
...@@ -3238,8 +3250,8 @@ pub const Object = struct {...@@ -3238,8 +3250,8 @@ pub const Object = struct {
3238 comptime assert(optional_layout_version == 3);3250 comptime assert(optional_layout_version == 3);
3239 var fields: [3]Builder.Type = .{ payload_ty, .i8, undefined };3251 var fields: [3]Builder.Type = .{ payload_ty, .i8, undefined };
3240 var fields_len: usize = 2;3252 var fields_len: usize = 2;
3241 const offset = Type.fromInterned(child_ty).abiSize(mod) + 1;3253 const offset = Type.fromInterned(child_ty).abiSize(pt) + 1;
3242 const abi_size = t.abiSize(mod);3254 const abi_size = t.abiSize(pt);
3243 const padding_len = abi_size - offset;3255 const padding_len = abi_size - offset;
3244 if (padding_len > 0) {3256 if (padding_len > 0) {
3245 fields[2] = try o.builder.arrayType(padding_len, .i8);3257 fields[2] = try o.builder.arrayType(padding_len, .i8);
...@@ -3252,16 +3264,16 @@ pub const Object = struct {...@@ -3252,16 +3264,16 @@ pub const Object = struct {
3252 // Must stay in sync with `codegen.errUnionPayloadOffset`.3264 // Must stay in sync with `codegen.errUnionPayloadOffset`.
3253 // See logic in `lowerPtr`.3265 // See logic in `lowerPtr`.
3254 const error_type = try o.errorIntType();3266 const error_type = try o.errorIntType();
3255 if (!Type.fromInterned(error_union_type.payload_type).hasRuntimeBitsIgnoreComptime(mod))3267 if (!Type.fromInterned(error_union_type.payload_type).hasRuntimeBitsIgnoreComptime(pt))
3256 return error_type;3268 return error_type;
3257 const payload_type = try o.lowerType(Type.fromInterned(error_union_type.payload_type));3269 const payload_type = try o.lowerType(Type.fromInterned(error_union_type.payload_type));
3258 const err_int_ty = try mod.errorIntType();3270 const err_int_ty = try o.pt.errorIntType();
32593271
3260 const payload_align = Type.fromInterned(error_union_type.payload_type).abiAlignment(mod);3272 const payload_align = Type.fromInterned(error_union_type.payload_type).abiAlignment(pt);
3261 const error_align = err_int_ty.abiAlignment(mod);3273 const error_align = err_int_ty.abiAlignment(pt);
32623274
3263 const payload_size = Type.fromInterned(error_union_type.payload_type).abiSize(mod);3275 const payload_size = Type.fromInterned(error_union_type.payload_type).abiSize(pt);
3264 const error_size = err_int_ty.abiSize(mod);3276 const error_size = err_int_ty.abiSize(pt);
32653277
3266 var fields: [3]Builder.Type = undefined;3278 var fields: [3]Builder.Type = undefined;
3267 var fields_len: usize = 2;3279 var fields_len: usize = 2;
...@@ -3300,7 +3312,7 @@ pub const Object = struct {...@@ -3300,7 +3312,7 @@ pub const Object = struct {
3300 return int_ty;3312 return int_ty;
3301 }3313 }
33023314
3303 const fqn = try mod.declPtr(struct_type.decl.unwrap().?).fullyQualifiedName(mod);3315 const fqn = try mod.declPtr(struct_type.decl.unwrap().?).fullyQualifiedName(pt);
33043316
3305 var llvm_field_types = std.ArrayListUnmanaged(Builder.Type){};3317 var llvm_field_types = std.ArrayListUnmanaged(Builder.Type){};
3306 defer llvm_field_types.deinit(o.gpa);3318 defer llvm_field_types.deinit(o.gpa);
...@@ -3317,12 +3329,12 @@ pub const Object = struct {...@@ -3317,12 +3329,12 @@ pub const Object = struct {
3317 var it = struct_type.iterateRuntimeOrder(ip);3329 var it = struct_type.iterateRuntimeOrder(ip);
3318 while (it.next()) |field_index| {3330 while (it.next()) |field_index| {
3319 const field_ty = Type.fromInterned(struct_type.field_types.get(ip)[field_index]);3331 const field_ty = Type.fromInterned(struct_type.field_types.get(ip)[field_index]);
3320 const field_align = mod.structFieldAlignment(3332 const field_align = pt.structFieldAlignment(
3321 struct_type.fieldAlign(ip, field_index),3333 struct_type.fieldAlign(ip, field_index),
3322 field_ty,3334 field_ty,
3323 struct_type.layout,3335 struct_type.layout,
3324 );3336 );
3325 const field_ty_align = field_ty.abiAlignment(mod);3337 const field_ty_align = field_ty.abiAlignment(pt);
3326 if (field_align.compare(.lt, field_ty_align)) struct_kind = .@"packed";3338 if (field_align.compare(.lt, field_ty_align)) struct_kind = .@"packed";
3327 big_align = big_align.max(field_align);3339 big_align = big_align.max(field_align);
3328 const prev_offset = offset;3340 const prev_offset = offset;
...@@ -3334,7 +3346,7 @@ pub const Object = struct {...@@ -3334,7 +3346,7 @@ pub const Object = struct {
3334 try o.builder.arrayType(padding_len, .i8),3346 try o.builder.arrayType(padding_len, .i8),
3335 );3347 );
33363348
3337 if (!field_ty.hasRuntimeBitsIgnoreComptime(mod)) {3349 if (!field_ty.hasRuntimeBitsIgnoreComptime(pt)) {
3338 // This is a zero-bit field. If there are runtime bits after this field,3350 // This is a zero-bit field. If there are runtime bits after this field,
3339 // map to the next LLVM field (which we know exists): otherwise, don't3351 // map to the next LLVM field (which we know exists): otherwise, don't
3340 // map the field, indicating it's at the end of the struct.3352 // map the field, indicating it's at the end of the struct.
...@@ -3353,7 +3365,7 @@ pub const Object = struct {...@@ -3353,7 +3365,7 @@ pub const Object = struct {
3353 }, @intCast(llvm_field_types.items.len));3365 }, @intCast(llvm_field_types.items.len));
3354 try llvm_field_types.append(o.gpa, try o.lowerType(field_ty));3366 try llvm_field_types.append(o.gpa, try o.lowerType(field_ty));
33553367
3356 offset += field_ty.abiSize(mod);3368 offset += field_ty.abiSize(pt);
3357 }3369 }
3358 {3370 {
3359 const prev_offset = offset;3371 const prev_offset = offset;
...@@ -3386,7 +3398,7 @@ pub const Object = struct {...@@ -3386,7 +3398,7 @@ pub const Object = struct {
3386 var offset: u64 = 0;3398 var offset: u64 = 0;
3387 var big_align: InternPool.Alignment = .none;3399 var big_align: InternPool.Alignment = .none;
33883400
3389 const struct_size = t.abiSize(mod);3401 const struct_size = t.abiSize(pt);
33903402
3391 for (3403 for (
3392 anon_struct_type.types.get(ip),3404 anon_struct_type.types.get(ip),
...@@ -3395,7 +3407,7 @@ pub const Object = struct {...@@ -3395,7 +3407,7 @@ pub const Object = struct {
3395 ) |field_ty, field_val, field_index| {3407 ) |field_ty, field_val, field_index| {
3396 if (field_val != .none) continue;3408 if (field_val != .none) continue;
33973409
3398 const field_align = Type.fromInterned(field_ty).abiAlignment(mod);3410 const field_align = Type.fromInterned(field_ty).abiAlignment(pt);
3399 big_align = big_align.max(field_align);3411 big_align = big_align.max(field_align);
3400 const prev_offset = offset;3412 const prev_offset = offset;
3401 offset = field_align.forward(offset);3413 offset = field_align.forward(offset);
...@@ -3405,7 +3417,7 @@ pub const Object = struct {...@@ -3405,7 +3417,7 @@ pub const Object = struct {
3405 o.gpa,3417 o.gpa,
3406 try o.builder.arrayType(padding_len, .i8),3418 try o.builder.arrayType(padding_len, .i8),
3407 );3419 );
3408 if (!Type.fromInterned(field_ty).hasRuntimeBitsIgnoreComptime(mod)) {3420 if (!Type.fromInterned(field_ty).hasRuntimeBitsIgnoreComptime(pt)) {
3409 // This is a zero-bit field. If there are runtime bits after this field,3421 // This is a zero-bit field. If there are runtime bits after this field,
3410 // map to the next LLVM field (which we know exists): otherwise, don't3422 // map to the next LLVM field (which we know exists): otherwise, don't
3411 // map the field, indicating it's at the end of the struct.3423 // map the field, indicating it's at the end of the struct.
...@@ -3423,7 +3435,7 @@ pub const Object = struct {...@@ -3423,7 +3435,7 @@ pub const Object = struct {
3423 }, @intCast(llvm_field_types.items.len));3435 }, @intCast(llvm_field_types.items.len));
3424 try llvm_field_types.append(o.gpa, try o.lowerType(Type.fromInterned(field_ty)));3436 try llvm_field_types.append(o.gpa, try o.lowerType(Type.fromInterned(field_ty)));
34253437
3426 offset += Type.fromInterned(field_ty).abiSize(mod);3438 offset += Type.fromInterned(field_ty).abiSize(pt);
3427 }3439 }
3428 {3440 {
3429 const prev_offset = offset;3441 const prev_offset = offset;
...@@ -3440,10 +3452,10 @@ pub const Object = struct {...@@ -3440,10 +3452,10 @@ pub const Object = struct {
3440 if (o.type_map.get(t.toIntern())) |value| return value;3452 if (o.type_map.get(t.toIntern())) |value| return value;
34413453
3442 const union_obj = ip.loadUnionType(t.toIntern());3454 const union_obj = ip.loadUnionType(t.toIntern());
3443 const layout = mod.getUnionLayout(union_obj);3455 const layout = pt.getUnionLayout(union_obj);
34443456
3445 if (union_obj.flagsPtr(ip).layout == .@"packed") {3457 if (union_obj.flagsPtr(ip).layout == .@"packed") {
3446 const int_ty = try o.builder.intType(@intCast(t.bitSize(mod)));3458 const int_ty = try o.builder.intType(@intCast(t.bitSize(pt)));
3447 try o.type_map.put(o.gpa, t.toIntern(), int_ty);3459 try o.type_map.put(o.gpa, t.toIntern(), int_ty);
3448 return int_ty;3460 return int_ty;
3449 }3461 }
...@@ -3454,7 +3466,7 @@ pub const Object = struct {...@@ -3454,7 +3466,7 @@ pub const Object = struct {
3454 return enum_tag_ty;3466 return enum_tag_ty;
3455 }3467 }
34563468
3457 const fqn = try mod.declPtr(union_obj.decl).fullyQualifiedName(mod);3469 const fqn = try mod.declPtr(union_obj.decl).fullyQualifiedName(pt);
34583470
3459 const aligned_field_ty = Type.fromInterned(union_obj.field_types.get(ip)[layout.most_aligned_field]);3471 const aligned_field_ty = Type.fromInterned(union_obj.field_types.get(ip)[layout.most_aligned_field]);
3460 const aligned_field_llvm_ty = try o.lowerType(aligned_field_ty);3472 const aligned_field_llvm_ty = try o.lowerType(aligned_field_ty);
...@@ -3515,7 +3527,7 @@ pub const Object = struct {...@@ -3515,7 +3527,7 @@ pub const Object = struct {
3515 const gop = try o.type_map.getOrPut(o.gpa, t.toIntern());3527 const gop = try o.type_map.getOrPut(o.gpa, t.toIntern());
3516 if (!gop.found_existing) {3528 if (!gop.found_existing) {
3517 const decl = mod.declPtr(ip.loadOpaqueType(t.toIntern()).decl);3529 const decl = mod.declPtr(ip.loadOpaqueType(t.toIntern()).decl);
3518 const fqn = try decl.fullyQualifiedName(mod);3530 const fqn = try decl.fullyQualifiedName(pt);
3519 gop.value_ptr.* = try o.builder.opaqueType(try o.builder.string(fqn.toSlice(ip)));3531 gop.value_ptr.* = try o.builder.opaqueType(try o.builder.string(fqn.toSlice(ip)));
3520 }3532 }
3521 return gop.value_ptr.*;3533 return gop.value_ptr.*;
...@@ -3552,18 +3564,20 @@ pub const Object = struct {...@@ -3552,18 +3564,20 @@ pub const Object = struct {
3552 /// being a zero bit type, but it should still be lowered as an i8 in such case.3564 /// being a zero bit type, but it should still be lowered as an i8 in such case.
3553 /// There are other similar cases handled here as well.3565 /// There are other similar cases handled here as well.
3554 fn lowerPtrElemTy(o: *Object, elem_ty: Type) Allocator.Error!Builder.Type {3566 fn lowerPtrElemTy(o: *Object, elem_ty: Type) Allocator.Error!Builder.Type {
3555 const mod = o.module;3567 const pt = o.pt;
3568 const mod = pt.zcu;
3556 const lower_elem_ty = switch (elem_ty.zigTypeTag(mod)) {3569 const lower_elem_ty = switch (elem_ty.zigTypeTag(mod)) {
3557 .Opaque => true,3570 .Opaque => true,
3558 .Fn => !mod.typeToFunc(elem_ty).?.is_generic,3571 .Fn => !mod.typeToFunc(elem_ty).?.is_generic,
3559 .Array => elem_ty.childType(mod).hasRuntimeBitsIgnoreComptime(mod),3572 .Array => elem_ty.childType(mod).hasRuntimeBitsIgnoreComptime(pt),
3560 else => elem_ty.hasRuntimeBitsIgnoreComptime(mod),3573 else => elem_ty.hasRuntimeBitsIgnoreComptime(pt),
3561 };3574 };
3562 return if (lower_elem_ty) try o.lowerType(elem_ty) else .i8;3575 return if (lower_elem_ty) try o.lowerType(elem_ty) else .i8;
3563 }3576 }
35643577
3565 fn lowerTypeFn(o: *Object, fn_info: InternPool.Key.FuncType) Allocator.Error!Builder.Type {3578 fn lowerTypeFn(o: *Object, fn_info: InternPool.Key.FuncType) Allocator.Error!Builder.Type {
3566 const mod = o.module;3579 const pt = o.pt;
3580 const mod = pt.zcu;
3567 const ip = &mod.intern_pool;3581 const ip = &mod.intern_pool;
3568 const target = mod.getTarget();3582 const target = mod.getTarget();
3569 const ret_ty = try lowerFnRetTy(o, fn_info);3583 const ret_ty = try lowerFnRetTy(o, fn_info);
...@@ -3571,14 +3585,14 @@ pub const Object = struct {...@@ -3571,14 +3585,14 @@ pub const Object = struct {
3571 var llvm_params = std.ArrayListUnmanaged(Builder.Type){};3585 var llvm_params = std.ArrayListUnmanaged(Builder.Type){};
3572 defer llvm_params.deinit(o.gpa);3586 defer llvm_params.deinit(o.gpa);
35733587
3574 if (firstParamSRet(fn_info, mod, target)) {3588 if (firstParamSRet(fn_info, pt, target)) {
3575 try llvm_params.append(o.gpa, .ptr);3589 try llvm_params.append(o.gpa, .ptr);
3576 }3590 }
35773591
3578 if (Type.fromInterned(fn_info.return_type).isError(mod) and3592 if (Type.fromInterned(fn_info.return_type).isError(mod) and
3579 mod.comp.config.any_error_tracing)3593 mod.comp.config.any_error_tracing)
3580 {3594 {
3581 const ptr_ty = try mod.singleMutPtrType(try o.getStackTraceType());3595 const ptr_ty = try pt.singleMutPtrType(try o.getStackTraceType());
3582 try llvm_params.append(o.gpa, try o.lowerType(ptr_ty));3596 try llvm_params.append(o.gpa, try o.lowerType(ptr_ty));
3583 }3597 }
35843598
...@@ -3595,7 +3609,7 @@ pub const Object = struct {...@@ -3595,7 +3609,7 @@ pub const Object = struct {
3595 .abi_sized_int => {3609 .abi_sized_int => {
3596 const param_ty = Type.fromInterned(fn_info.param_types.get(ip)[it.zig_index - 1]);3610 const param_ty = Type.fromInterned(fn_info.param_types.get(ip)[it.zig_index - 1]);
3597 try llvm_params.append(o.gpa, try o.builder.intType(3611 try llvm_params.append(o.gpa, try o.builder.intType(
3598 @intCast(param_ty.abiSize(mod) * 8),3612 @intCast(param_ty.abiSize(pt) * 8),
3599 ));3613 ));
3600 },3614 },
3601 .slice => {3615 .slice => {
...@@ -3633,7 +3647,8 @@ pub const Object = struct {...@@ -3633,7 +3647,8 @@ pub const Object = struct {
3633 }3647 }
36343648
3635 fn lowerValueToInt(o: *Object, llvm_int_ty: Builder.Type, arg_val: InternPool.Index) Error!Builder.Constant {3649 fn lowerValueToInt(o: *Object, llvm_int_ty: Builder.Type, arg_val: InternPool.Index) Error!Builder.Constant {
3636 const mod = o.module;3650 const pt = o.pt;
3651 const mod = pt.zcu;
3637 const ip = &mod.intern_pool;3652 const ip = &mod.intern_pool;
3638 const target = mod.getTarget();3653 const target = mod.getTarget();
36393654
...@@ -3666,15 +3681,15 @@ pub const Object = struct {...@@ -3666,15 +3681,15 @@ pub const Object = struct {
3666 var running_int = try o.builder.intConst(llvm_int_ty, 0);3681 var running_int = try o.builder.intConst(llvm_int_ty, 0);
3667 var running_bits: u16 = 0;3682 var running_bits: u16 = 0;
3668 for (struct_type.field_types.get(ip), 0..) |field_ty, field_index| {3683 for (struct_type.field_types.get(ip), 0..) |field_ty, field_index| {
3669 if (!Type.fromInterned(field_ty).hasRuntimeBitsIgnoreComptime(mod)) continue;3684 if (!Type.fromInterned(field_ty).hasRuntimeBitsIgnoreComptime(pt)) continue;
36703685
3671 const shift_rhs = try o.builder.intConst(llvm_int_ty, running_bits);3686 const shift_rhs = try o.builder.intConst(llvm_int_ty, running_bits);
3672 const field_val = try o.lowerValueToInt(llvm_int_ty, (try val.fieldValue(mod, field_index)).toIntern());3687 const field_val = try o.lowerValueToInt(llvm_int_ty, (try val.fieldValue(pt, field_index)).toIntern());
3673 const shifted = try o.builder.binConst(.shl, field_val, shift_rhs);3688 const shifted = try o.builder.binConst(.shl, field_val, shift_rhs);
36743689
3675 running_int = try o.builder.binConst(.xor, running_int, shifted);3690 running_int = try o.builder.binConst(.xor, running_int, shifted);
36763691
3677 const ty_bit_size: u16 = @intCast(Type.fromInterned(field_ty).bitSize(mod));3692 const ty_bit_size: u16 = @intCast(Type.fromInterned(field_ty).bitSize(pt));
3678 running_bits += ty_bit_size;3693 running_bits += ty_bit_size;
3679 }3694 }
3680 return running_int;3695 return running_int;
...@@ -3683,7 +3698,7 @@ pub const Object = struct {...@@ -3683,7 +3698,7 @@ pub const Object = struct {
3683 else => unreachable,3698 else => unreachable,
3684 },3699 },
3685 .un => |un| {3700 .un => |un| {
3686 const layout = ty.unionGetLayout(mod);3701 const layout = ty.unionGetLayout(pt);
3687 if (layout.payload_size == 0) return o.lowerValue(un.tag);3702 if (layout.payload_size == 0) return o.lowerValue(un.tag);
36883703
3689 const union_obj = mod.typeToUnion(ty).?;3704 const union_obj = mod.typeToUnion(ty).?;
...@@ -3701,7 +3716,7 @@ pub const Object = struct {...@@ -3701,7 +3716,7 @@ pub const Object = struct {
3701 }3716 }
3702 const field_index = mod.unionTagFieldIndex(union_obj, Value.fromInterned(un.tag)).?;3717 const field_index = mod.unionTagFieldIndex(union_obj, Value.fromInterned(un.tag)).?;
3703 const field_ty = Type.fromInterned(union_obj.field_types.get(ip)[field_index]);3718 const field_ty = Type.fromInterned(union_obj.field_types.get(ip)[field_index]);
3704 if (!field_ty.hasRuntimeBits(mod)) return o.builder.intConst(llvm_int_ty, 0);3719 if (!field_ty.hasRuntimeBits(pt)) return o.builder.intConst(llvm_int_ty, 0);
3705 return o.lowerValueToInt(llvm_int_ty, un.val);3720 return o.lowerValueToInt(llvm_int_ty, un.val);
3706 },3721 },
3707 .simple_value => |simple_value| switch (simple_value) {3722 .simple_value => |simple_value| switch (simple_value) {
...@@ -3715,7 +3730,7 @@ pub const Object = struct {...@@ -3715,7 +3730,7 @@ pub const Object = struct {
3715 .opt => {}, // pointer like optional expected3730 .opt => {}, // pointer like optional expected
3716 else => unreachable,3731 else => unreachable,
3717 }3732 }
3718 const bits = ty.bitSize(mod);3733 const bits = ty.bitSize(pt);
3719 const bytes: usize = @intCast(std.mem.alignForward(u64, bits, 8) / 8);3734 const bytes: usize = @intCast(std.mem.alignForward(u64, bits, 8) / 8);
37203735
3721 var stack = std.heap.stackFallback(32, o.gpa);3736 var stack = std.heap.stackFallback(32, o.gpa);
...@@ -3729,12 +3744,7 @@ pub const Object = struct {...@@ -3729,12 +3744,7 @@ pub const Object = struct {
3729 defer allocator.free(limbs);3744 defer allocator.free(limbs);
3730 @memset(limbs, 0);3745 @memset(limbs, 0);
37313746
3732 val.writeToPackedMemory(3747 val.writeToPackedMemory(ty, pt, std.mem.sliceAsBytes(limbs)[0..bytes], 0) catch unreachable;
3733 ty,
3734 mod,
3735 std.mem.sliceAsBytes(limbs)[0..bytes],
3736 0,
3737 ) catch unreachable;
37383748
3739 if (builtin.target.cpu.arch.endian() == .little) {3749 if (builtin.target.cpu.arch.endian() == .little) {
3740 if (target.cpu.arch.endian() == .big)3750 if (target.cpu.arch.endian() == .big)
...@@ -3752,7 +3762,8 @@ pub const Object = struct {...@@ -3752,7 +3762,8 @@ pub const Object = struct {
3752 }3762 }
37533763
3754 fn lowerValue(o: *Object, arg_val: InternPool.Index) Error!Builder.Constant {3764 fn lowerValue(o: *Object, arg_val: InternPool.Index) Error!Builder.Constant {
3755 const mod = o.module;3765 const pt = o.pt;
3766 const mod = pt.zcu;
3756 const ip = &mod.intern_pool;3767 const ip = &mod.intern_pool;
3757 const target = mod.getTarget();3768 const target = mod.getTarget();
37583769
...@@ -3811,7 +3822,7 @@ pub const Object = struct {...@@ -3811,7 +3822,7 @@ pub const Object = struct {
3811 },3822 },
3812 .int => {3823 .int => {
3813 var bigint_space: Value.BigIntSpace = undefined;3824 var bigint_space: Value.BigIntSpace = undefined;
3814 const bigint = val.toBigInt(&bigint_space, mod);3825 const bigint = val.toBigInt(&bigint_space, pt);
3815 return lowerBigInt(o, ty, bigint);3826 return lowerBigInt(o, ty, bigint);
3816 },3827 },
3817 .err => |err| {3828 .err => |err| {
...@@ -3821,24 +3832,24 @@ pub const Object = struct {...@@ -3821,24 +3832,24 @@ pub const Object = struct {
3821 },3832 },
3822 .error_union => |error_union| {3833 .error_union => |error_union| {
3823 const err_val = switch (error_union.val) {3834 const err_val = switch (error_union.val) {
3824 .err_name => |err_name| try mod.intern(.{ .err = .{3835 .err_name => |err_name| try pt.intern(.{ .err = .{
3825 .ty = ty.errorUnionSet(mod).toIntern(),3836 .ty = ty.errorUnionSet(mod).toIntern(),
3826 .name = err_name,3837 .name = err_name,
3827 } }),3838 } }),
3828 .payload => (try mod.intValue(try mod.errorIntType(), 0)).toIntern(),3839 .payload => (try pt.intValue(try pt.errorIntType(), 0)).toIntern(),
3829 };3840 };
3830 const err_int_ty = try mod.errorIntType();3841 const err_int_ty = try pt.errorIntType();
3831 const payload_type = ty.errorUnionPayload(mod);3842 const payload_type = ty.errorUnionPayload(mod);
3832 if (!payload_type.hasRuntimeBitsIgnoreComptime(mod)) {3843 if (!payload_type.hasRuntimeBitsIgnoreComptime(pt)) {
3833 // We use the error type directly as the type.3844 // We use the error type directly as the type.
3834 return o.lowerValue(err_val);3845 return o.lowerValue(err_val);
3835 }3846 }
38363847
3837 const payload_align = payload_type.abiAlignment(mod);3848 const payload_align = payload_type.abiAlignment(pt);
3838 const error_align = err_int_ty.abiAlignment(mod);3849 const error_align = err_int_ty.abiAlignment(pt);
3839 const llvm_error_value = try o.lowerValue(err_val);3850 const llvm_error_value = try o.lowerValue(err_val);
3840 const llvm_payload_value = try o.lowerValue(switch (error_union.val) {3851 const llvm_payload_value = try o.lowerValue(switch (error_union.val) {
3841 .err_name => try mod.intern(.{ .undef = payload_type.toIntern() }),3852 .err_name => try pt.intern(.{ .undef = payload_type.toIntern() }),
3842 .payload => |payload| payload,3853 .payload => |payload| payload,
3843 });3854 });
38443855
...@@ -3869,16 +3880,16 @@ pub const Object = struct {...@@ -3869,16 +3880,16 @@ pub const Object = struct {
3869 .enum_tag => |enum_tag| o.lowerValue(enum_tag.int),3880 .enum_tag => |enum_tag| o.lowerValue(enum_tag.int),
3870 .float => switch (ty.floatBits(target)) {3881 .float => switch (ty.floatBits(target)) {
3871 16 => if (backendSupportsF16(target))3882 16 => if (backendSupportsF16(target))
3872 try o.builder.halfConst(val.toFloat(f16, mod))3883 try o.builder.halfConst(val.toFloat(f16, pt))
3873 else3884 else
3874 try o.builder.intConst(.i16, @as(i16, @bitCast(val.toFloat(f16, mod)))),3885 try o.builder.intConst(.i16, @as(i16, @bitCast(val.toFloat(f16, pt)))),
3875 32 => try o.builder.floatConst(val.toFloat(f32, mod)),3886 32 => try o.builder.floatConst(val.toFloat(f32, pt)),
3876 64 => try o.builder.doubleConst(val.toFloat(f64, mod)),3887 64 => try o.builder.doubleConst(val.toFloat(f64, pt)),
3877 80 => if (backendSupportsF80(target))3888 80 => if (backendSupportsF80(target))
3878 try o.builder.x86_fp80Const(val.toFloat(f80, mod))3889 try o.builder.x86_fp80Const(val.toFloat(f80, pt))
3879 else3890 else
3880 try o.builder.intConst(.i80, @as(i80, @bitCast(val.toFloat(f80, mod)))),3891 try o.builder.intConst(.i80, @as(i80, @bitCast(val.toFloat(f80, pt)))),
3881 128 => try o.builder.fp128Const(val.toFloat(f128, mod)),3892 128 => try o.builder.fp128Const(val.toFloat(f128, pt)),
3882 else => unreachable,3893 else => unreachable,
3883 },3894 },
3884 .ptr => try o.lowerPtr(arg_val, 0),3895 .ptr => try o.lowerPtr(arg_val, 0),
...@@ -3891,7 +3902,7 @@ pub const Object = struct {...@@ -3891,7 +3902,7 @@ pub const Object = struct {
3891 const payload_ty = ty.optionalChild(mod);3902 const payload_ty = ty.optionalChild(mod);
38923903
3893 const non_null_bit = try o.builder.intConst(.i8, @intFromBool(opt.val != .none));3904 const non_null_bit = try o.builder.intConst(.i8, @intFromBool(opt.val != .none));
3894 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) {3905 if (!payload_ty.hasRuntimeBitsIgnoreComptime(pt)) {
3895 return non_null_bit;3906 return non_null_bit;
3896 }3907 }
3897 const llvm_ty = try o.lowerType(ty);3908 const llvm_ty = try o.lowerType(ty);
...@@ -3909,7 +3920,7 @@ pub const Object = struct {...@@ -3909,7 +3920,7 @@ pub const Object = struct {
3909 var fields: [3]Builder.Type = undefined;3920 var fields: [3]Builder.Type = undefined;
3910 var vals: [3]Builder.Constant = undefined;3921 var vals: [3]Builder.Constant = undefined;
3911 vals[0] = try o.lowerValue(switch (opt.val) {3922 vals[0] = try o.lowerValue(switch (opt.val) {
3912 .none => try mod.intern(.{ .undef = payload_ty.toIntern() }),3923 .none => try pt.intern(.{ .undef = payload_ty.toIntern() }),
3913 else => |payload| payload,3924 else => |payload| payload,
3914 });3925 });
3915 vals[1] = non_null_bit;3926 vals[1] = non_null_bit;
...@@ -4058,9 +4069,9 @@ pub const Object = struct {...@@ -4058,9 +4069,9 @@ pub const Object = struct {
4058 0..,4069 0..,
4059 ) |field_ty, field_val, field_index| {4070 ) |field_ty, field_val, field_index| {
4060 if (field_val != .none) continue;4071 if (field_val != .none) continue;
4061 if (!Type.fromInterned(field_ty).hasRuntimeBitsIgnoreComptime(mod)) continue;4072 if (!Type.fromInterned(field_ty).hasRuntimeBitsIgnoreComptime(pt)) continue;
40624073
4063 const field_align = Type.fromInterned(field_ty).abiAlignment(mod);4074 const field_align = Type.fromInterned(field_ty).abiAlignment(pt);
4064 big_align = big_align.max(field_align);4075 big_align = big_align.max(field_align);
4065 const prev_offset = offset;4076 const prev_offset = offset;
4066 offset = field_align.forward(offset);4077 offset = field_align.forward(offset);
...@@ -4076,13 +4087,13 @@ pub const Object = struct {...@@ -4076,13 +4087,13 @@ pub const Object = struct {
4076 }4087 }
40774088
4078 vals[llvm_index] =4089 vals[llvm_index] =
4079 try o.lowerValue((try val.fieldValue(mod, field_index)).toIntern());4090 try o.lowerValue((try val.fieldValue(pt, field_index)).toIntern());
4080 fields[llvm_index] = vals[llvm_index].typeOf(&o.builder);4091 fields[llvm_index] = vals[llvm_index].typeOf(&o.builder);
4081 if (fields[llvm_index] != struct_ty.structFields(&o.builder)[llvm_index])4092 if (fields[llvm_index] != struct_ty.structFields(&o.builder)[llvm_index])
4082 need_unnamed = true;4093 need_unnamed = true;
4083 llvm_index += 1;4094 llvm_index += 1;
40844095
4085 offset += Type.fromInterned(field_ty).abiSize(mod);4096 offset += Type.fromInterned(field_ty).abiSize(pt);
4086 }4097 }
4087 {4098 {
4088 const prev_offset = offset;4099 const prev_offset = offset;
...@@ -4109,7 +4120,7 @@ pub const Object = struct {...@@ -4109,7 +4120,7 @@ pub const Object = struct {
4109 if (struct_type.layout == .@"packed") {4120 if (struct_type.layout == .@"packed") {
4110 comptime assert(Type.packed_struct_layout_version == 2);4121 comptime assert(Type.packed_struct_layout_version == 2);
41114122
4112 const bits = ty.bitSize(mod);4123 const bits = ty.bitSize(pt);
4113 const llvm_int_ty = try o.builder.intType(@intCast(bits));4124 const llvm_int_ty = try o.builder.intType(@intCast(bits));
41144125
4115 return o.lowerValueToInt(llvm_int_ty, arg_val);4126 return o.lowerValueToInt(llvm_int_ty, arg_val);
...@@ -4138,7 +4149,7 @@ pub const Object = struct {...@@ -4138,7 +4149,7 @@ pub const Object = struct {
4138 var field_it = struct_type.iterateRuntimeOrder(ip);4149 var field_it = struct_type.iterateRuntimeOrder(ip);
4139 while (field_it.next()) |field_index| {4150 while (field_it.next()) |field_index| {
4140 const field_ty = Type.fromInterned(struct_type.field_types.get(ip)[field_index]);4151 const field_ty = Type.fromInterned(struct_type.field_types.get(ip)[field_index]);
4141 const field_align = mod.structFieldAlignment(4152 const field_align = pt.structFieldAlignment(
4142 struct_type.fieldAlign(ip, field_index),4153 struct_type.fieldAlign(ip, field_index),
4143 field_ty,4154 field_ty,
4144 struct_type.layout,4155 struct_type.layout,
...@@ -4158,20 +4169,20 @@ pub const Object = struct {...@@ -4158,20 +4169,20 @@ pub const Object = struct {
4158 llvm_index += 1;4169 llvm_index += 1;
4159 }4170 }
41604171
4161 if (!field_ty.hasRuntimeBitsIgnoreComptime(mod)) {4172 if (!field_ty.hasRuntimeBitsIgnoreComptime(pt)) {
4162 // This is a zero-bit field - we only needed it for the alignment.4173 // This is a zero-bit field - we only needed it for the alignment.
4163 continue;4174 continue;
4164 }4175 }
41654176
4166 vals[llvm_index] = try o.lowerValue(4177 vals[llvm_index] = try o.lowerValue(
4167 (try val.fieldValue(mod, field_index)).toIntern(),4178 (try val.fieldValue(pt, field_index)).toIntern(),
4168 );4179 );
4169 fields[llvm_index] = vals[llvm_index].typeOf(&o.builder);4180 fields[llvm_index] = vals[llvm_index].typeOf(&o.builder);
4170 if (fields[llvm_index] != struct_ty.structFields(&o.builder)[llvm_index])4181 if (fields[llvm_index] != struct_ty.structFields(&o.builder)[llvm_index])
4171 need_unnamed = true;4182 need_unnamed = true;
4172 llvm_index += 1;4183 llvm_index += 1;
41734184
4174 offset += field_ty.abiSize(mod);4185 offset += field_ty.abiSize(pt);
4175 }4186 }
4176 {4187 {
4177 const prev_offset = offset;4188 const prev_offset = offset;
...@@ -4195,7 +4206,7 @@ pub const Object = struct {...@@ -4195,7 +4206,7 @@ pub const Object = struct {
4195 },4206 },
4196 .un => |un| {4207 .un => |un| {
4197 const union_ty = try o.lowerType(ty);4208 const union_ty = try o.lowerType(ty);
4198 const layout = ty.unionGetLayout(mod);4209 const layout = ty.unionGetLayout(pt);
4199 if (layout.payload_size == 0) return o.lowerValue(un.tag);4210 if (layout.payload_size == 0) return o.lowerValue(un.tag);
42004211
4201 const union_obj = mod.typeToUnion(ty).?;4212 const union_obj = mod.typeToUnion(ty).?;
...@@ -4206,8 +4217,8 @@ pub const Object = struct {...@@ -4206,8 +4217,8 @@ pub const Object = struct {
4206 const field_index = mod.unionTagFieldIndex(union_obj, Value.fromInterned(un.tag)).?;4217 const field_index = mod.unionTagFieldIndex(union_obj, Value.fromInterned(un.tag)).?;
4207 const field_ty = Type.fromInterned(union_obj.field_types.get(ip)[field_index]);4218 const field_ty = Type.fromInterned(union_obj.field_types.get(ip)[field_index]);
4208 if (container_layout == .@"packed") {4219 if (container_layout == .@"packed") {
4209 if (!field_ty.hasRuntimeBits(mod)) return o.builder.intConst(union_ty, 0);4220 if (!field_ty.hasRuntimeBits(pt)) return o.builder.intConst(union_ty, 0);
4210 const bits = ty.bitSize(mod);4221 const bits = ty.bitSize(pt);
4211 const llvm_int_ty = try o.builder.intType(@intCast(bits));4222 const llvm_int_ty = try o.builder.intType(@intCast(bits));
42124223
4213 return o.lowerValueToInt(llvm_int_ty, arg_val);4224 return o.lowerValueToInt(llvm_int_ty, arg_val);
...@@ -4219,7 +4230,7 @@ pub const Object = struct {...@@ -4219,7 +4230,7 @@ pub const Object = struct {
4219 // must pointer cast to the expected type before accessing the union.4230 // must pointer cast to the expected type before accessing the union.
4220 need_unnamed = layout.most_aligned_field != field_index;4231 need_unnamed = layout.most_aligned_field != field_index;
42214232
4222 if (!field_ty.hasRuntimeBitsIgnoreComptime(mod)) {4233 if (!field_ty.hasRuntimeBitsIgnoreComptime(pt)) {
4223 const padding_len = layout.payload_size;4234 const padding_len = layout.payload_size;
4224 break :p try o.builder.undefConst(try o.builder.arrayType(padding_len, .i8));4235 break :p try o.builder.undefConst(try o.builder.arrayType(padding_len, .i8));
4225 }4236 }
...@@ -4228,7 +4239,7 @@ pub const Object = struct {...@@ -4228,7 +4239,7 @@ pub const Object = struct {
4228 if (payload_ty != union_ty.structFields(&o.builder)[4239 if (payload_ty != union_ty.structFields(&o.builder)[
4229 @intFromBool(layout.tag_align.compare(.gte, layout.payload_align))4240 @intFromBool(layout.tag_align.compare(.gte, layout.payload_align))
4230 ]) need_unnamed = true;4241 ]) need_unnamed = true;
4231 const field_size = field_ty.abiSize(mod);4242 const field_size = field_ty.abiSize(pt);
4232 if (field_size == layout.payload_size) break :p payload;4243 if (field_size == layout.payload_size) break :p payload;
4233 const padding_len = layout.payload_size - field_size;4244 const padding_len = layout.payload_size - field_size;
4234 const padding_ty = try o.builder.arrayType(padding_len, .i8);4245 const padding_ty = try o.builder.arrayType(padding_len, .i8);
...@@ -4239,7 +4250,7 @@ pub const Object = struct {...@@ -4239,7 +4250,7 @@ pub const Object = struct {
4239 } else p: {4250 } else p: {
4240 assert(layout.tag_size == 0);4251 assert(layout.tag_size == 0);
4241 if (container_layout == .@"packed") {4252 if (container_layout == .@"packed") {
4242 const bits = ty.bitSize(mod);4253 const bits = ty.bitSize(pt);
4243 const llvm_int_ty = try o.builder.intType(@intCast(bits));4254 const llvm_int_ty = try o.builder.intType(@intCast(bits));
42444255
4245 return o.lowerValueToInt(llvm_int_ty, arg_val);4256 return o.lowerValueToInt(llvm_int_ty, arg_val);
...@@ -4286,7 +4297,7 @@ pub const Object = struct {...@@ -4286,7 +4297,7 @@ pub const Object = struct {
4286 ty: Type,4297 ty: Type,
4287 bigint: std.math.big.int.Const,4298 bigint: std.math.big.int.Const,
4288 ) Allocator.Error!Builder.Constant {4299 ) Allocator.Error!Builder.Constant {
4289 const mod = o.module;4300 const mod = o.pt.zcu;
4290 return o.builder.bigIntConst(try o.builder.intType(ty.intInfo(mod).bits), bigint);4301 return o.builder.bigIntConst(try o.builder.intType(ty.intInfo(mod).bits), bigint);
4291 }4302 }
42924303
...@@ -4295,7 +4306,8 @@ pub const Object = struct {...@@ -4295,7 +4306,8 @@ pub const Object = struct {
4295 ptr_val: InternPool.Index,4306 ptr_val: InternPool.Index,
4296 prev_offset: u64,4307 prev_offset: u64,
4297 ) Error!Builder.Constant {4308 ) Error!Builder.Constant {
4298 const zcu = o.module;4309 const pt = o.pt;
4310 const zcu = pt.zcu;
4299 const ptr = zcu.intern_pool.indexToKey(ptr_val).ptr;4311 const ptr = zcu.intern_pool.indexToKey(ptr_val).ptr;
4300 const offset: u64 = prev_offset + ptr.byte_offset;4312 const offset: u64 = prev_offset + ptr.byte_offset;
4301 return switch (ptr.base_addr) {4313 return switch (ptr.base_addr) {
...@@ -4320,7 +4332,7 @@ pub const Object = struct {...@@ -4320,7 +4332,7 @@ pub const Object = struct {
4320 eu_ptr,4332 eu_ptr,
4321 offset + @import("../codegen.zig").errUnionPayloadOffset(4333 offset + @import("../codegen.zig").errUnionPayloadOffset(
4322 Value.fromInterned(eu_ptr).typeOf(zcu).childType(zcu),4334 Value.fromInterned(eu_ptr).typeOf(zcu).childType(zcu),
4323 zcu,4335 pt,
4324 ),4336 ),
4325 ),4337 ),
4326 .opt_payload => |opt_ptr| try o.lowerPtr(opt_ptr, offset),4338 .opt_payload => |opt_ptr| try o.lowerPtr(opt_ptr, offset),
...@@ -4336,7 +4348,7 @@ pub const Object = struct {...@@ -4336,7 +4348,7 @@ pub const Object = struct {
4336 };4348 };
4337 },4349 },
4338 .Struct, .Union => switch (agg_ty.containerLayout(zcu)) {4350 .Struct, .Union => switch (agg_ty.containerLayout(zcu)) {
4339 .auto => agg_ty.structFieldOffset(@intCast(field.index), zcu),4351 .auto => agg_ty.structFieldOffset(@intCast(field.index), pt),
4340 .@"extern", .@"packed" => unreachable,4352 .@"extern", .@"packed" => unreachable,
4341 },4353 },
4342 else => unreachable,4354 else => unreachable,
...@@ -4353,7 +4365,8 @@ pub const Object = struct {...@@ -4353,7 +4365,8 @@ pub const Object = struct {
4353 o: *Object,4365 o: *Object,
4354 anon_decl: InternPool.Key.Ptr.BaseAddr.AnonDecl,4366 anon_decl: InternPool.Key.Ptr.BaseAddr.AnonDecl,
4355 ) Error!Builder.Constant {4367 ) Error!Builder.Constant {
4356 const mod = o.module;4368 const pt = o.pt;
4369 const mod = pt.zcu;
4357 const ip = &mod.intern_pool;4370 const ip = &mod.intern_pool;
4358 const decl_val = anon_decl.val;4371 const decl_val = anon_decl.val;
4359 const decl_ty = Type.fromInterned(ip.typeOf(decl_val));4372 const decl_ty = Type.fromInterned(ip.typeOf(decl_val));
...@@ -4370,14 +4383,14 @@ pub const Object = struct {...@@ -4370,14 +4383,14 @@ pub const Object = struct {
4370 const ptr_ty = Type.fromInterned(anon_decl.orig_ty);4383 const ptr_ty = Type.fromInterned(anon_decl.orig_ty);
43714384
4372 const is_fn_body = decl_ty.zigTypeTag(mod) == .Fn;4385 const is_fn_body = decl_ty.zigTypeTag(mod) == .Fn;
4373 if ((!is_fn_body and !decl_ty.hasRuntimeBits(mod)) or4386 if ((!is_fn_body and !decl_ty.hasRuntimeBits(pt)) or
4374 (is_fn_body and mod.typeToFunc(decl_ty).?.is_generic)) return o.lowerPtrToVoid(ptr_ty);4387 (is_fn_body and mod.typeToFunc(decl_ty).?.is_generic)) return o.lowerPtrToVoid(ptr_ty);
43754388
4376 if (is_fn_body)4389 if (is_fn_body)
4377 @panic("TODO");4390 @panic("TODO");
43784391
4379 const llvm_addr_space = toLlvmAddressSpace(ptr_ty.ptrAddressSpace(mod), target);4392 const llvm_addr_space = toLlvmAddressSpace(ptr_ty.ptrAddressSpace(mod), target);
4380 const alignment = ptr_ty.ptrAlignment(mod);4393 const alignment = ptr_ty.ptrAlignment(pt);
4381 const llvm_global = (try o.resolveGlobalAnonDecl(decl_val, llvm_addr_space, alignment)).ptrConst(&o.builder).global;4394 const llvm_global = (try o.resolveGlobalAnonDecl(decl_val, llvm_addr_space, alignment)).ptrConst(&o.builder).global;
43824395
4383 const llvm_val = try o.builder.convConst(4396 const llvm_val = try o.builder.convConst(
...@@ -4389,7 +4402,8 @@ pub const Object = struct {...@@ -4389,7 +4402,8 @@ pub const Object = struct {
4389 }4402 }
43904403
4391 fn lowerDeclRefValue(o: *Object, decl_index: InternPool.DeclIndex) Allocator.Error!Builder.Constant {4404 fn lowerDeclRefValue(o: *Object, decl_index: InternPool.DeclIndex) Allocator.Error!Builder.Constant {
4392 const mod = o.module;4405 const pt = o.pt;
4406 const mod = pt.zcu;
43934407
4394 // In the case of something like:4408 // In the case of something like:
4395 // fn foo() void {}4409 // fn foo() void {}
...@@ -4408,10 +4422,10 @@ pub const Object = struct {...@@ -4408,10 +4422,10 @@ pub const Object = struct {
4408 }4422 }
44094423
4410 const decl_ty = decl.typeOf(mod);4424 const decl_ty = decl.typeOf(mod);
4411 const ptr_ty = try decl.declPtrType(mod);4425 const ptr_ty = try decl.declPtrType(pt);
44124426
4413 const is_fn_body = decl_ty.zigTypeTag(mod) == .Fn;4427 const is_fn_body = decl_ty.zigTypeTag(mod) == .Fn;
4414 if ((!is_fn_body and !decl_ty.hasRuntimeBits(mod)) or4428 if ((!is_fn_body and !decl_ty.hasRuntimeBits(pt)) or
4415 (is_fn_body and mod.typeToFunc(decl_ty).?.is_generic))4429 (is_fn_body and mod.typeToFunc(decl_ty).?.is_generic))
4416 {4430 {
4417 return o.lowerPtrToVoid(ptr_ty);4431 return o.lowerPtrToVoid(ptr_ty);
...@@ -4431,7 +4445,7 @@ pub const Object = struct {...@@ -4431,7 +4445,7 @@ pub const Object = struct {
4431 }4445 }
44324446
4433 fn lowerPtrToVoid(o: *Object, ptr_ty: Type) Allocator.Error!Builder.Constant {4447 fn lowerPtrToVoid(o: *Object, ptr_ty: Type) Allocator.Error!Builder.Constant {
4434 const mod = o.module;4448 const mod = o.pt.zcu;
4435 // Even though we are pointing at something which has zero bits (e.g. `void`),4449 // Even though we are pointing at something which has zero bits (e.g. `void`),
4436 // Pointers are defined to have bits. So we must return something here.4450 // Pointers are defined to have bits. So we must return something here.
4437 // The value cannot be undefined, because we use the `nonnull` annotation4451 // The value cannot be undefined, because we use the `nonnull` annotation
...@@ -4459,20 +4473,21 @@ pub const Object = struct {...@@ -4459,20 +4473,21 @@ pub const Object = struct {
4459 /// RMW exchange of floating-point values is bitcasted to same-sized integer4473 /// RMW exchange of floating-point values is bitcasted to same-sized integer
4460 /// types to work around a LLVM deficiency when targeting ARM/AArch64.4474 /// types to work around a LLVM deficiency when targeting ARM/AArch64.
4461 fn getAtomicAbiType(o: *Object, ty: Type, is_rmw_xchg: bool) Allocator.Error!Builder.Type {4475 fn getAtomicAbiType(o: *Object, ty: Type, is_rmw_xchg: bool) Allocator.Error!Builder.Type {
4462 const mod = o.module;4476 const pt = o.pt;
4477 const mod = pt.zcu;
4463 const int_ty = switch (ty.zigTypeTag(mod)) {4478 const int_ty = switch (ty.zigTypeTag(mod)) {
4464 .Int => ty,4479 .Int => ty,
4465 .Enum => ty.intTagType(mod),4480 .Enum => ty.intTagType(mod),
4466 .Float => {4481 .Float => {
4467 if (!is_rmw_xchg) return .none;4482 if (!is_rmw_xchg) return .none;
4468 return o.builder.intType(@intCast(ty.abiSize(mod) * 8));4483 return o.builder.intType(@intCast(ty.abiSize(pt) * 8));
4469 },4484 },
4470 .Bool => return .i8,4485 .Bool => return .i8,
4471 else => return .none,4486 else => return .none,
4472 };4487 };
4473 const bit_count = int_ty.intInfo(mod).bits;4488 const bit_count = int_ty.intInfo(mod).bits;
4474 if (!std.math.isPowerOfTwo(bit_count) or (bit_count % 8) != 0) {4489 if (!std.math.isPowerOfTwo(bit_count) or (bit_count % 8) != 0) {
4475 return o.builder.intType(@intCast(int_ty.abiSize(mod) * 8));4490 return o.builder.intType(@intCast(int_ty.abiSize(pt) * 8));
4476 } else {4491 } else {
4477 return .none;4492 return .none;
4478 }4493 }
...@@ -4486,7 +4501,8 @@ pub const Object = struct {...@@ -4486,7 +4501,8 @@ pub const Object = struct {
4486 fn_info: InternPool.Key.FuncType,4501 fn_info: InternPool.Key.FuncType,
4487 llvm_arg_i: u32,4502 llvm_arg_i: u32,
4488 ) Allocator.Error!void {4503 ) Allocator.Error!void {
4489 const mod = o.module;4504 const pt = o.pt;
4505 const mod = pt.zcu;
4490 if (param_ty.isPtrAtRuntime(mod)) {4506 if (param_ty.isPtrAtRuntime(mod)) {
4491 const ptr_info = param_ty.ptrInfo(mod);4507 const ptr_info = param_ty.ptrInfo(mod);
4492 if (math.cast(u5, param_index)) |i| {4508 if (math.cast(u5, param_index)) |i| {
...@@ -4507,7 +4523,7 @@ pub const Object = struct {...@@ -4507,7 +4523,7 @@ pub const Object = struct {
4507 const elem_align = if (ptr_info.flags.alignment != .none)4523 const elem_align = if (ptr_info.flags.alignment != .none)
4508 ptr_info.flags.alignment4524 ptr_info.flags.alignment
4509 else4525 else
4510 Type.fromInterned(ptr_info.child).abiAlignment(mod).max(.@"1");4526 Type.fromInterned(ptr_info.child).abiAlignment(pt).max(.@"1");
4511 try attributes.addParamAttr(llvm_arg_i, .{ .@"align" = elem_align.toLlvm() }, &o.builder);4527 try attributes.addParamAttr(llvm_arg_i, .{ .@"align" = elem_align.toLlvm() }, &o.builder);
4512 } else if (ccAbiPromoteInt(fn_info.cc, mod, param_ty)) |s| switch (s) {4528 } else if (ccAbiPromoteInt(fn_info.cc, mod, param_ty)) |s| switch (s) {
4513 .signed => try attributes.addParamAttr(llvm_arg_i, .signext, &o.builder),4529 .signed => try attributes.addParamAttr(llvm_arg_i, .signext, &o.builder),
...@@ -4540,7 +4556,7 @@ pub const Object = struct {...@@ -4540,7 +4556,7 @@ pub const Object = struct {
4540 const name = try o.builder.strtabString(lt_errors_fn_name);4556 const name = try o.builder.strtabString(lt_errors_fn_name);
4541 if (o.builder.getGlobal(name)) |llvm_fn| return llvm_fn.ptrConst(&o.builder).kind.function;4557 if (o.builder.getGlobal(name)) |llvm_fn| return llvm_fn.ptrConst(&o.builder).kind.function;
45424558
4543 const zcu = o.module;4559 const zcu = o.pt.zcu;
4544 const target = zcu.root_mod.resolved_target.result;4560 const target = zcu.root_mod.resolved_target.result;
4545 const function_index = try o.builder.addFunction(4561 const function_index = try o.builder.addFunction(
4546 try o.builder.fnType(.i1, &.{try o.errorIntType()}, .normal),4562 try o.builder.fnType(.i1, &.{try o.errorIntType()}, .normal),
...@@ -4559,7 +4575,8 @@ pub const Object = struct {...@@ -4559,7 +4575,8 @@ pub const Object = struct {
4559 }4575 }
45604576
4561 fn getEnumTagNameFunction(o: *Object, enum_ty: Type) !Builder.Function.Index {4577 fn getEnumTagNameFunction(o: *Object, enum_ty: Type) !Builder.Function.Index {
4562 const zcu = o.module;4578 const pt = o.pt;
4579 const zcu = pt.zcu;
4563 const ip = &zcu.intern_pool;4580 const ip = &zcu.intern_pool;
4564 const enum_type = ip.loadEnumType(enum_ty.toIntern());4581 const enum_type = ip.loadEnumType(enum_ty.toIntern());
45654582
...@@ -4570,7 +4587,7 @@ pub const Object = struct {...@@ -4570,7 +4587,7 @@ pub const Object = struct {
45704587
4571 const usize_ty = try o.lowerType(Type.usize);4588 const usize_ty = try o.lowerType(Type.usize);
4572 const ret_ty = try o.lowerType(Type.slice_const_u8_sentinel_0);4589 const ret_ty = try o.lowerType(Type.slice_const_u8_sentinel_0);
4573 const fqn = try zcu.declPtr(enum_type.decl).fullyQualifiedName(zcu);4590 const fqn = try zcu.declPtr(enum_type.decl).fullyQualifiedName(pt);
4574 const target = zcu.root_mod.resolved_target.result;4591 const target = zcu.root_mod.resolved_target.result;
4575 const function_index = try o.builder.addFunction(4592 const function_index = try o.builder.addFunction(
4576 try o.builder.fnType(ret_ty, &.{try o.lowerType(Type.fromInterned(enum_type.tag_ty))}, .normal),4593 try o.builder.fnType(ret_ty, &.{try o.lowerType(Type.fromInterned(enum_type.tag_ty))}, .normal),
...@@ -4618,7 +4635,7 @@ pub const Object = struct {...@@ -4618,7 +4635,7 @@ pub const Object = struct {
46184635
4619 const return_block = try wip.block(1, "Name");4636 const return_block = try wip.block(1, "Name");
4620 const this_tag_int_value = try o.lowerValue(4637 const this_tag_int_value = try o.lowerValue(
4621 (try zcu.enumValueFieldIndex(enum_ty, @intCast(field_index))).toIntern(),4638 (try pt.enumValueFieldIndex(enum_ty, @intCast(field_index))).toIntern(),
4622 );4639 );
4623 try wip_switch.addCase(this_tag_int_value, return_block, &wip);4640 try wip_switch.addCase(this_tag_int_value, return_block, &wip);
46244641
...@@ -4636,13 +4653,13 @@ pub const Object = struct {...@@ -4636,13 +4653,13 @@ pub const Object = struct {
46364653
4637pub const DeclGen = struct {4654pub const DeclGen = struct {
4638 object: *Object,4655 object: *Object,
4639 decl: *Module.Decl,4656 decl: *Zcu.Decl,
4640 decl_index: InternPool.DeclIndex,4657 decl_index: InternPool.DeclIndex,
4641 err_msg: ?*Module.ErrorMsg,4658 err_msg: ?*Zcu.ErrorMsg,
46424659
4643 fn ownerModule(dg: DeclGen) *Package.Module {4660 fn ownerModule(dg: DeclGen) *Package.Module {
4644 const o = dg.object;4661 const o = dg.object;
4645 const zcu = o.module;4662 const zcu = o.pt.zcu;
4646 const namespace = zcu.namespacePtr(dg.decl.src_namespace);4663 const namespace = zcu.namespacePtr(dg.decl.src_namespace);
4647 const file_scope = namespace.fileScope(zcu);4664 const file_scope = namespace.fileScope(zcu);
4648 return file_scope.mod;4665 return file_scope.mod;
...@@ -4653,15 +4670,15 @@ pub const DeclGen = struct {...@@ -4653,15 +4670,15 @@ pub const DeclGen = struct {
4653 assert(dg.err_msg == null);4670 assert(dg.err_msg == null);
4654 const o = dg.object;4671 const o = dg.object;
4655 const gpa = o.gpa;4672 const gpa = o.gpa;
4656 const mod = o.module;4673 const src_loc = dg.decl.navSrcLoc(o.pt.zcu);
4657 const src_loc = dg.decl.navSrcLoc(mod);4674 dg.err_msg = try Zcu.ErrorMsg.create(gpa, src_loc, "TODO (LLVM): " ++ format, args);
4658 dg.err_msg = try Module.ErrorMsg.create(gpa, src_loc, "TODO (LLVM): " ++ format, args);
4659 return error.CodegenFail;4675 return error.CodegenFail;
4660 }4676 }
46614677
4662 fn genDecl(dg: *DeclGen) !void {4678 fn genDecl(dg: *DeclGen) !void {
4663 const o = dg.object;4679 const o = dg.object;
4664 const zcu = o.module;4680 const pt = o.pt;
4681 const zcu = pt.zcu;
4665 const ip = &zcu.intern_pool;4682 const ip = &zcu.intern_pool;
4666 const decl = dg.decl;4683 const decl = dg.decl;
4667 const decl_index = dg.decl_index;4684 const decl_index = dg.decl_index;
...@@ -4672,7 +4689,7 @@ pub const DeclGen = struct {...@@ -4672,7 +4689,7 @@ pub const DeclGen = struct {
4672 } else {4689 } else {
4673 const variable_index = try o.resolveGlobalDecl(decl_index);4690 const variable_index = try o.resolveGlobalDecl(decl_index);
4674 variable_index.setAlignment(4691 variable_index.setAlignment(
4675 decl.getAlignment(zcu).toLlvm(),4692 decl.getAlignment(pt).toLlvm(),
4676 &o.builder,4693 &o.builder,
4677 );4694 );
4678 if (decl.@"linksection".toSlice(ip)) |section|4695 if (decl.@"linksection".toSlice(ip)) |section|
...@@ -4833,23 +4850,21 @@ pub const FuncGen = struct {...@@ -4833,23 +4850,21 @@ pub const FuncGen = struct {
4833 const gop = try self.func_inst_table.getOrPut(gpa, inst);4850 const gop = try self.func_inst_table.getOrPut(gpa, inst);
4834 if (gop.found_existing) return gop.value_ptr.*;4851 if (gop.found_existing) return gop.value_ptr.*;
48354852
4836 const o = self.dg.object;4853 const llvm_val = try self.resolveValue((try self.air.value(inst, self.dg.object.pt)).?);
4837 const mod = o.module;
4838 const llvm_val = try self.resolveValue((try self.air.value(inst, mod)).?);
4839 gop.value_ptr.* = llvm_val.toValue();4854 gop.value_ptr.* = llvm_val.toValue();
4840 return llvm_val.toValue();4855 return llvm_val.toValue();
4841 }4856 }
48424857
4843 fn resolveValue(self: *FuncGen, val: Value) Error!Builder.Constant {4858 fn resolveValue(self: *FuncGen, val: Value) Error!Builder.Constant {
4844 const o = self.dg.object;4859 const o = self.dg.object;
4845 const mod = o.module;4860 const pt = o.pt;
4846 const ty = val.typeOf(mod);4861 const ty = val.typeOf(pt.zcu);
4847 const llvm_val = try o.lowerValue(val.toIntern());4862 const llvm_val = try o.lowerValue(val.toIntern());
4848 if (!isByRef(ty, mod)) return llvm_val;4863 if (!isByRef(ty, pt)) return llvm_val;
48494864
4850 // We have an LLVM value but we need to create a global constant and4865 // We have an LLVM value but we need to create a global constant and
4851 // set the value as its initializer, and then return a pointer to the global.4866 // set the value as its initializer, and then return a pointer to the global.
4852 const target = mod.getTarget();4867 const target = pt.zcu.getTarget();
4853 const variable_index = try o.builder.addVariable(4868 const variable_index = try o.builder.addVariable(
4854 .empty,4869 .empty,
4855 llvm_val.typeOf(&o.builder),4870 llvm_val.typeOf(&o.builder),
...@@ -4859,7 +4874,7 @@ pub const FuncGen = struct {...@@ -4859,7 +4874,7 @@ pub const FuncGen = struct {
4859 variable_index.setLinkage(.private, &o.builder);4874 variable_index.setLinkage(.private, &o.builder);
4860 variable_index.setMutability(.constant, &o.builder);4875 variable_index.setMutability(.constant, &o.builder);
4861 variable_index.setUnnamedAddr(.unnamed_addr, &o.builder);4876 variable_index.setUnnamedAddr(.unnamed_addr, &o.builder);
4862 variable_index.setAlignment(ty.abiAlignment(mod).toLlvm(), &o.builder);4877 variable_index.setAlignment(ty.abiAlignment(pt).toLlvm(), &o.builder);
4863 return o.builder.convConst(4878 return o.builder.convConst(
4864 variable_index.toConst(&o.builder),4879 variable_index.toConst(&o.builder),
4865 try o.builder.ptrType(toLlvmAddressSpace(.generic, target)),4880 try o.builder.ptrType(toLlvmAddressSpace(.generic, target)),
...@@ -4868,10 +4883,10 @@ pub const FuncGen = struct {...@@ -4868,10 +4883,10 @@ pub const FuncGen = struct {
48684883
4869 fn resolveNullOptUsize(self: *FuncGen) Error!Builder.Constant {4884 fn resolveNullOptUsize(self: *FuncGen) Error!Builder.Constant {
4870 const o = self.dg.object;4885 const o = self.dg.object;
4871 const mod = o.module;4886 const pt = o.pt;
4872 if (o.null_opt_usize == .no_init) {4887 if (o.null_opt_usize == .no_init) {
4873 o.null_opt_usize = try self.resolveValue(Value.fromInterned(try mod.intern(.{ .opt = .{4888 o.null_opt_usize = try self.resolveValue(Value.fromInterned(try pt.intern(.{ .opt = .{
4874 .ty = try mod.intern(.{ .opt_type = .usize_type }),4889 .ty = try pt.intern(.{ .opt_type = .usize_type }),
4875 .val = .none,4890 .val = .none,
4876 } })));4891 } })));
4877 }4892 }
...@@ -4880,7 +4895,7 @@ pub const FuncGen = struct {...@@ -4880,7 +4895,7 @@ pub const FuncGen = struct {
48804895
4881 fn genBody(self: *FuncGen, body: []const Air.Inst.Index) Error!void {4896 fn genBody(self: *FuncGen, body: []const Air.Inst.Index) Error!void {
4882 const o = self.dg.object;4897 const o = self.dg.object;
4883 const mod = o.module;4898 const mod = o.pt.zcu;
4884 const ip = &mod.intern_pool;4899 const ip = &mod.intern_pool;
4885 const air_tags = self.air.instructions.items(.tag);4900 const air_tags = self.air.instructions.items(.tag);
4886 for (body, 0..) |inst, i| {4901 for (body, 0..) |inst, i| {
...@@ -5145,7 +5160,8 @@ pub const FuncGen = struct {...@@ -5145,7 +5160,8 @@ pub const FuncGen = struct {
51455160
5146 if (maybe_inline_func) |inline_func| {5161 if (maybe_inline_func) |inline_func| {
5147 const o = self.dg.object;5162 const o = self.dg.object;
5148 const zcu = o.module;5163 const pt = o.pt;
5164 const zcu = pt.zcu;
51495165
5150 const func = zcu.funcInfo(inline_func);5166 const func = zcu.funcInfo(inline_func);
5151 const decl_index = func.owner_decl;5167 const decl_index = func.owner_decl;
...@@ -5159,9 +5175,9 @@ pub const FuncGen = struct {...@@ -5159,9 +5175,9 @@ pub const FuncGen = struct {
5159 const line_number = decl.navSrcLine(zcu) + 1;5175 const line_number = decl.navSrcLine(zcu) + 1;
5160 self.inlined = self.wip.debug_location;5176 self.inlined = self.wip.debug_location;
51615177
5162 const fqn = try decl.fullyQualifiedName(zcu);5178 const fqn = try decl.fullyQualifiedName(pt);
51635179
5164 const fn_ty = try zcu.funcType(.{5180 const fn_ty = try pt.funcType(.{
5165 .param_types = &.{},5181 .param_types = &.{},
5166 .return_type = .void_type,5182 .return_type = .void_type,
5167 });5183 });
...@@ -5228,7 +5244,8 @@ pub const FuncGen = struct {...@@ -5228,7 +5244,8 @@ pub const FuncGen = struct {
5228 const extra = self.air.extraData(Air.Call, pl_op.payload);5244 const extra = self.air.extraData(Air.Call, pl_op.payload);
5229 const args: []const Air.Inst.Ref = @ptrCast(self.air.extra[extra.end..][0..extra.data.args_len]);5245 const args: []const Air.Inst.Ref = @ptrCast(self.air.extra[extra.end..][0..extra.data.args_len]);
5230 const o = self.dg.object;5246 const o = self.dg.object;
5231 const mod = o.module;5247 const pt = o.pt;
5248 const mod = pt.zcu;
5232 const ip = &mod.intern_pool;5249 const ip = &mod.intern_pool;
5233 const callee_ty = self.typeOf(pl_op.operand);5250 const callee_ty = self.typeOf(pl_op.operand);
5234 const zig_fn_ty = switch (callee_ty.zigTypeTag(mod)) {5251 const zig_fn_ty = switch (callee_ty.zigTypeTag(mod)) {
...@@ -5240,7 +5257,7 @@ pub const FuncGen = struct {...@@ -5240,7 +5257,7 @@ pub const FuncGen = struct {
5240 const return_type = Type.fromInterned(fn_info.return_type);5257 const return_type = Type.fromInterned(fn_info.return_type);
5241 const llvm_fn = try self.resolveInst(pl_op.operand);5258 const llvm_fn = try self.resolveInst(pl_op.operand);
5242 const target = mod.getTarget();5259 const target = mod.getTarget();
5243 const sret = firstParamSRet(fn_info, mod, target);5260 const sret = firstParamSRet(fn_info, pt, target);
52445261
5245 var llvm_args = std.ArrayList(Builder.Value).init(self.gpa);5262 var llvm_args = std.ArrayList(Builder.Value).init(self.gpa);
5246 defer llvm_args.deinit();5263 defer llvm_args.deinit();
...@@ -5258,14 +5275,13 @@ pub const FuncGen = struct {...@@ -5258,14 +5275,13 @@ pub const FuncGen = struct {
5258 const llvm_ret_ty = try o.lowerType(return_type);5275 const llvm_ret_ty = try o.lowerType(return_type);
5259 try attributes.addParamAttr(0, .{ .sret = llvm_ret_ty }, &o.builder);5276 try attributes.addParamAttr(0, .{ .sret = llvm_ret_ty }, &o.builder);
52605277
5261 const alignment = return_type.abiAlignment(mod).toLlvm();5278 const alignment = return_type.abiAlignment(pt).toLlvm();
5262 const ret_ptr = try self.buildAllocaWorkaround(return_type, alignment);5279 const ret_ptr = try self.buildAllocaWorkaround(return_type, alignment);
5263 try llvm_args.append(ret_ptr);5280 try llvm_args.append(ret_ptr);
5264 break :blk ret_ptr;5281 break :blk ret_ptr;
5265 };5282 };
52665283
5267 const err_return_tracing = return_type.isError(mod) and5284 const err_return_tracing = return_type.isError(mod) and mod.comp.config.any_error_tracing;
5268 o.module.comp.config.any_error_tracing;
5269 if (err_return_tracing) {5285 if (err_return_tracing) {
5270 assert(self.err_ret_trace != .none);5286 assert(self.err_ret_trace != .none);
5271 try llvm_args.append(self.err_ret_trace);5287 try llvm_args.append(self.err_ret_trace);
...@@ -5279,8 +5295,8 @@ pub const FuncGen = struct {...@@ -5279,8 +5295,8 @@ pub const FuncGen = struct {
5279 const param_ty = self.typeOf(arg);5295 const param_ty = self.typeOf(arg);
5280 const llvm_arg = try self.resolveInst(arg);5296 const llvm_arg = try self.resolveInst(arg);
5281 const llvm_param_ty = try o.lowerType(param_ty);5297 const llvm_param_ty = try o.lowerType(param_ty);
5282 if (isByRef(param_ty, mod)) {5298 if (isByRef(param_ty, pt)) {
5283 const alignment = param_ty.abiAlignment(mod).toLlvm();5299 const alignment = param_ty.abiAlignment(pt).toLlvm();
5284 const loaded = try self.wip.load(.normal, llvm_param_ty, llvm_arg, alignment, "");5300 const loaded = try self.wip.load(.normal, llvm_param_ty, llvm_arg, alignment, "");
5285 try llvm_args.append(loaded);5301 try llvm_args.append(loaded);
5286 } else {5302 } else {
...@@ -5291,10 +5307,10 @@ pub const FuncGen = struct {...@@ -5291,10 +5307,10 @@ pub const FuncGen = struct {
5291 const arg = args[it.zig_index - 1];5307 const arg = args[it.zig_index - 1];
5292 const param_ty = self.typeOf(arg);5308 const param_ty = self.typeOf(arg);
5293 const llvm_arg = try self.resolveInst(arg);5309 const llvm_arg = try self.resolveInst(arg);
5294 if (isByRef(param_ty, mod)) {5310 if (isByRef(param_ty, pt)) {
5295 try llvm_args.append(llvm_arg);5311 try llvm_args.append(llvm_arg);
5296 } else {5312 } else {
5297 const alignment = param_ty.abiAlignment(mod).toLlvm();5313 const alignment = param_ty.abiAlignment(pt).toLlvm();
5298 const param_llvm_ty = llvm_arg.typeOfWip(&self.wip);5314 const param_llvm_ty = llvm_arg.typeOfWip(&self.wip);
5299 const arg_ptr = try self.buildAlloca(param_llvm_ty, alignment);5315 const arg_ptr = try self.buildAlloca(param_llvm_ty, alignment);
5300 _ = try self.wip.store(.normal, llvm_arg, arg_ptr, alignment);5316 _ = try self.wip.store(.normal, llvm_arg, arg_ptr, alignment);
...@@ -5306,10 +5322,10 @@ pub const FuncGen = struct {...@@ -5306,10 +5322,10 @@ pub const FuncGen = struct {
5306 const param_ty = self.typeOf(arg);5322 const param_ty = self.typeOf(arg);
5307 const llvm_arg = try self.resolveInst(arg);5323 const llvm_arg = try self.resolveInst(arg);
53085324
5309 const alignment = param_ty.abiAlignment(mod).toLlvm();5325 const alignment = param_ty.abiAlignment(pt).toLlvm();
5310 const param_llvm_ty = try o.lowerType(param_ty);5326 const param_llvm_ty = try o.lowerType(param_ty);
5311 const arg_ptr = try self.buildAllocaWorkaround(param_ty, alignment);5327 const arg_ptr = try self.buildAllocaWorkaround(param_ty, alignment);
5312 if (isByRef(param_ty, mod)) {5328 if (isByRef(param_ty, pt)) {
5313 const loaded = try self.wip.load(.normal, param_llvm_ty, llvm_arg, alignment, "");5329 const loaded = try self.wip.load(.normal, param_llvm_ty, llvm_arg, alignment, "");
5314 _ = try self.wip.store(.normal, loaded, arg_ptr, alignment);5330 _ = try self.wip.store(.normal, loaded, arg_ptr, alignment);
5315 } else {5331 } else {
...@@ -5321,16 +5337,16 @@ pub const FuncGen = struct {...@@ -5321,16 +5337,16 @@ pub const FuncGen = struct {
5321 const arg = args[it.zig_index - 1];5337 const arg = args[it.zig_index - 1];
5322 const param_ty = self.typeOf(arg);5338 const param_ty = self.typeOf(arg);
5323 const llvm_arg = try self.resolveInst(arg);5339 const llvm_arg = try self.resolveInst(arg);
5324 const int_llvm_ty = try o.builder.intType(@intCast(param_ty.abiSize(mod) * 8));5340 const int_llvm_ty = try o.builder.intType(@intCast(param_ty.abiSize(pt) * 8));
53255341
5326 if (isByRef(param_ty, mod)) {5342 if (isByRef(param_ty, pt)) {
5327 const alignment = param_ty.abiAlignment(mod).toLlvm();5343 const alignment = param_ty.abiAlignment(pt).toLlvm();
5328 const loaded = try self.wip.load(.normal, int_llvm_ty, llvm_arg, alignment, "");5344 const loaded = try self.wip.load(.normal, int_llvm_ty, llvm_arg, alignment, "");
5329 try llvm_args.append(loaded);5345 try llvm_args.append(loaded);
5330 } else {5346 } else {
5331 // LLVM does not allow bitcasting structs so we must allocate5347 // LLVM does not allow bitcasting structs so we must allocate
5332 // a local, store as one type, and then load as another type.5348 // a local, store as one type, and then load as another type.
5333 const alignment = param_ty.abiAlignment(mod).toLlvm();5349 const alignment = param_ty.abiAlignment(pt).toLlvm();
5334 const int_ptr = try self.buildAllocaWorkaround(param_ty, alignment);5350 const int_ptr = try self.buildAllocaWorkaround(param_ty, alignment);
5335 _ = try self.wip.store(.normal, llvm_arg, int_ptr, alignment);5351 _ = try self.wip.store(.normal, llvm_arg, int_ptr, alignment);
5336 const loaded = try self.wip.load(.normal, int_llvm_ty, int_ptr, alignment, "");5352 const loaded = try self.wip.load(.normal, int_llvm_ty, int_ptr, alignment, "");
...@@ -5349,9 +5365,9 @@ pub const FuncGen = struct {...@@ -5349,9 +5365,9 @@ pub const FuncGen = struct {
5349 const param_ty = self.typeOf(arg);5365 const param_ty = self.typeOf(arg);
5350 const llvm_types = it.types_buffer[0..it.types_len];5366 const llvm_types = it.types_buffer[0..it.types_len];
5351 const llvm_arg = try self.resolveInst(arg);5367 const llvm_arg = try self.resolveInst(arg);
5352 const is_by_ref = isByRef(param_ty, mod);5368 const is_by_ref = isByRef(param_ty, pt);
5353 const arg_ptr = if (is_by_ref) llvm_arg else ptr: {5369 const arg_ptr = if (is_by_ref) llvm_arg else ptr: {
5354 const alignment = param_ty.abiAlignment(mod).toLlvm();5370 const alignment = param_ty.abiAlignment(pt).toLlvm();
5355 const ptr = try self.buildAlloca(llvm_arg.typeOfWip(&self.wip), alignment);5371 const ptr = try self.buildAlloca(llvm_arg.typeOfWip(&self.wip), alignment);
5356 _ = try self.wip.store(.normal, llvm_arg, ptr, alignment);5372 _ = try self.wip.store(.normal, llvm_arg, ptr, alignment);
5357 break :ptr ptr;5373 break :ptr ptr;
...@@ -5377,8 +5393,8 @@ pub const FuncGen = struct {...@@ -5377,8 +5393,8 @@ pub const FuncGen = struct {
5377 const arg = args[it.zig_index - 1];5393 const arg = args[it.zig_index - 1];
5378 const arg_ty = self.typeOf(arg);5394 const arg_ty = self.typeOf(arg);
5379 var llvm_arg = try self.resolveInst(arg);5395 var llvm_arg = try self.resolveInst(arg);
5380 const alignment = arg_ty.abiAlignment(mod).toLlvm();5396 const alignment = arg_ty.abiAlignment(pt).toLlvm();
5381 if (!isByRef(arg_ty, mod)) {5397 if (!isByRef(arg_ty, pt)) {
5382 const ptr = try self.buildAlloca(llvm_arg.typeOfWip(&self.wip), alignment);5398 const ptr = try self.buildAlloca(llvm_arg.typeOfWip(&self.wip), alignment);
5383 _ = try self.wip.store(.normal, llvm_arg, ptr, alignment);5399 _ = try self.wip.store(.normal, llvm_arg, ptr, alignment);
5384 llvm_arg = ptr;5400 llvm_arg = ptr;
...@@ -5395,8 +5411,8 @@ pub const FuncGen = struct {...@@ -5395,8 +5411,8 @@ pub const FuncGen = struct {
5395 const arg = args[it.zig_index - 1];5411 const arg = args[it.zig_index - 1];
5396 const arg_ty = self.typeOf(arg);5412 const arg_ty = self.typeOf(arg);
5397 var llvm_arg = try self.resolveInst(arg);5413 var llvm_arg = try self.resolveInst(arg);
5398 const alignment = arg_ty.abiAlignment(mod).toLlvm();5414 const alignment = arg_ty.abiAlignment(pt).toLlvm();
5399 if (!isByRef(arg_ty, mod)) {5415 if (!isByRef(arg_ty, pt)) {
5400 const ptr = try self.buildAlloca(llvm_arg.typeOfWip(&self.wip), alignment);5416 const ptr = try self.buildAlloca(llvm_arg.typeOfWip(&self.wip), alignment);
5401 _ = try self.wip.store(.normal, llvm_arg, ptr, alignment);5417 _ = try self.wip.store(.normal, llvm_arg, ptr, alignment);
5402 llvm_arg = ptr;5418 llvm_arg = ptr;
...@@ -5418,7 +5434,7 @@ pub const FuncGen = struct {...@@ -5418,7 +5434,7 @@ pub const FuncGen = struct {
5418 .byval => {5434 .byval => {
5419 const param_index = it.zig_index - 1;5435 const param_index = it.zig_index - 1;
5420 const param_ty = Type.fromInterned(fn_info.param_types.get(ip)[param_index]);5436 const param_ty = Type.fromInterned(fn_info.param_types.get(ip)[param_index]);
5421 if (!isByRef(param_ty, mod)) {5437 if (!isByRef(param_ty, pt)) {
5422 try o.addByValParamAttrs(&attributes, param_ty, param_index, fn_info, it.llvm_index - 1);5438 try o.addByValParamAttrs(&attributes, param_ty, param_index, fn_info, it.llvm_index - 1);
5423 }5439 }
5424 },5440 },
...@@ -5426,7 +5442,7 @@ pub const FuncGen = struct {...@@ -5426,7 +5442,7 @@ pub const FuncGen = struct {
5426 const param_index = it.zig_index - 1;5442 const param_index = it.zig_index - 1;
5427 const param_ty = Type.fromInterned(fn_info.param_types.get(ip)[param_index]);5443 const param_ty = Type.fromInterned(fn_info.param_types.get(ip)[param_index]);
5428 const param_llvm_ty = try o.lowerType(param_ty);5444 const param_llvm_ty = try o.lowerType(param_ty);
5429 const alignment = param_ty.abiAlignment(mod).toLlvm();5445 const alignment = param_ty.abiAlignment(pt).toLlvm();
5430 try o.addByRefParamAttrs(&attributes, it.llvm_index - 1, alignment, it.byval_attr, param_llvm_ty);5446 try o.addByRefParamAttrs(&attributes, it.llvm_index - 1, alignment, it.byval_attr, param_llvm_ty);
5431 },5447 },
5432 .byref_mut => try attributes.addParamAttr(it.llvm_index - 1, .noundef, &o.builder),5448 .byref_mut => try attributes.addParamAttr(it.llvm_index - 1, .noundef, &o.builder),
...@@ -5460,7 +5476,7 @@ pub const FuncGen = struct {...@@ -5460,7 +5476,7 @@ pub const FuncGen = struct {
5460 const elem_align = (if (ptr_info.flags.alignment != .none)5476 const elem_align = (if (ptr_info.flags.alignment != .none)
5461 @as(InternPool.Alignment, ptr_info.flags.alignment)5477 @as(InternPool.Alignment, ptr_info.flags.alignment)
5462 else5478 else
5463 Type.fromInterned(ptr_info.child).abiAlignment(mod).max(.@"1")).toLlvm();5479 Type.fromInterned(ptr_info.child).abiAlignment(pt).max(.@"1")).toLlvm();
5464 try attributes.addParamAttr(llvm_arg_i, .{ .@"align" = elem_align }, &o.builder);5480 try attributes.addParamAttr(llvm_arg_i, .{ .@"align" = elem_align }, &o.builder);
5465 },5481 },
5466 };5482 };
...@@ -5485,17 +5501,17 @@ pub const FuncGen = struct {...@@ -5485,17 +5501,17 @@ pub const FuncGen = struct {
5485 return .none;5501 return .none;
5486 }5502 }
54875503
5488 if (self.liveness.isUnused(inst) or !return_type.hasRuntimeBitsIgnoreComptime(mod)) {5504 if (self.liveness.isUnused(inst) or !return_type.hasRuntimeBitsIgnoreComptime(pt)) {
5489 return .none;5505 return .none;
5490 }5506 }
54915507
5492 const llvm_ret_ty = try o.lowerType(return_type);5508 const llvm_ret_ty = try o.lowerType(return_type);
5493 if (ret_ptr) |rp| {5509 if (ret_ptr) |rp| {
5494 if (isByRef(return_type, mod)) {5510 if (isByRef(return_type, pt)) {
5495 return rp;5511 return rp;
5496 } else {5512 } else {
5497 // our by-ref status disagrees with sret so we must load.5513 // our by-ref status disagrees with sret so we must load.
5498 const return_alignment = return_type.abiAlignment(mod).toLlvm();5514 const return_alignment = return_type.abiAlignment(pt).toLlvm();
5499 return self.wip.load(.normal, llvm_ret_ty, rp, return_alignment, "");5515 return self.wip.load(.normal, llvm_ret_ty, rp, return_alignment, "");
5500 }5516 }
5501 }5517 }
...@@ -5506,19 +5522,19 @@ pub const FuncGen = struct {...@@ -5506,19 +5522,19 @@ pub const FuncGen = struct {
5506 // In this case the function return type is honoring the calling convention by having5522 // In this case the function return type is honoring the calling convention by having
5507 // a different LLVM type than the usual one. We solve this here at the callsite5523 // a different LLVM type than the usual one. We solve this here at the callsite
5508 // by using our canonical type, then loading it if necessary.5524 // by using our canonical type, then loading it if necessary.
5509 const alignment = return_type.abiAlignment(mod).toLlvm();5525 const alignment = return_type.abiAlignment(pt).toLlvm();
5510 const rp = try self.buildAlloca(abi_ret_ty, alignment);5526 const rp = try self.buildAlloca(abi_ret_ty, alignment);
5511 _ = try self.wip.store(.normal, call, rp, alignment);5527 _ = try self.wip.store(.normal, call, rp, alignment);
5512 return if (isByRef(return_type, mod))5528 return if (isByRef(return_type, pt))
5513 rp5529 rp
5514 else5530 else
5515 try self.wip.load(.normal, llvm_ret_ty, rp, alignment, "");5531 try self.wip.load(.normal, llvm_ret_ty, rp, alignment, "");
5516 }5532 }
55175533
5518 if (isByRef(return_type, mod)) {5534 if (isByRef(return_type, pt)) {
5519 // our by-ref status disagrees with sret so we must allocate, store,5535 // our by-ref status disagrees with sret so we must allocate, store,
5520 // and return the allocation pointer.5536 // and return the allocation pointer.
5521 const alignment = return_type.abiAlignment(mod).toLlvm();5537 const alignment = return_type.abiAlignment(pt).toLlvm();
5522 const rp = try self.buildAlloca(llvm_ret_ty, alignment);5538 const rp = try self.buildAlloca(llvm_ret_ty, alignment);
5523 _ = try self.wip.store(.normal, call, rp, alignment);5539 _ = try self.wip.store(.normal, call, rp, alignment);
5524 return rp;5540 return rp;
...@@ -5527,9 +5543,9 @@ pub const FuncGen = struct {...@@ -5527,9 +5543,9 @@ pub const FuncGen = struct {
5527 }5543 }
5528 }5544 }
55295545
5530 fn buildSimplePanic(fg: *FuncGen, panic_id: Module.PanicId) !void {5546 fn buildSimplePanic(fg: *FuncGen, panic_id: Zcu.PanicId) !void {
5531 const o = fg.dg.object;5547 const o = fg.dg.object;
5532 const mod = o.module;5548 const mod = o.pt.zcu;
5533 const msg_decl_index = mod.panic_messages[@intFromEnum(panic_id)].unwrap().?;5549 const msg_decl_index = mod.panic_messages[@intFromEnum(panic_id)].unwrap().?;
5534 const msg_decl = mod.declPtr(msg_decl_index);5550 const msg_decl = mod.declPtr(msg_decl_index);
5535 const msg_len = msg_decl.typeOf(mod).childType(mod).arrayLen(mod);5551 const msg_len = msg_decl.typeOf(mod).childType(mod).arrayLen(mod);
...@@ -5567,15 +5583,16 @@ pub const FuncGen = struct {...@@ -5567,15 +5583,16 @@ pub const FuncGen = struct {
55675583
5568 fn airRet(self: *FuncGen, inst: Air.Inst.Index, safety: bool) !Builder.Value {5584 fn airRet(self: *FuncGen, inst: Air.Inst.Index, safety: bool) !Builder.Value {
5569 const o = self.dg.object;5585 const o = self.dg.object;
5570 const mod = o.module;5586 const pt = o.pt;
5587 const mod = pt.zcu;
5571 const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op;5588 const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op;
5572 const ret_ty = self.typeOf(un_op);5589 const ret_ty = self.typeOf(un_op);
55735590
5574 if (self.ret_ptr != .none) {5591 if (self.ret_ptr != .none) {
5575 const ptr_ty = try mod.singleMutPtrType(ret_ty);5592 const ptr_ty = try pt.singleMutPtrType(ret_ty);
55765593
5577 const operand = try self.resolveInst(un_op);5594 const operand = try self.resolveInst(un_op);
5578 const val_is_undef = if (try self.air.value(un_op, mod)) |val| val.isUndefDeep(mod) else false;5595 const val_is_undef = if (try self.air.value(un_op, pt)) |val| val.isUndefDeep(mod) else false;
5579 if (val_is_undef and safety) undef: {5596 if (val_is_undef and safety) undef: {
5580 const ptr_info = ptr_ty.ptrInfo(mod);5597 const ptr_info = ptr_ty.ptrInfo(mod);
5581 const needs_bitmask = (ptr_info.packed_offset.host_size != 0);5598 const needs_bitmask = (ptr_info.packed_offset.host_size != 0);
...@@ -5585,10 +5602,10 @@ pub const FuncGen = struct {...@@ -5585,10 +5602,10 @@ pub const FuncGen = struct {
5585 // https://github.com/ziglang/zig/issues/153375602 // https://github.com/ziglang/zig/issues/15337
5586 break :undef;5603 break :undef;
5587 }5604 }
5588 const len = try o.builder.intValue(try o.lowerType(Type.usize), ret_ty.abiSize(mod));5605 const len = try o.builder.intValue(try o.lowerType(Type.usize), ret_ty.abiSize(pt));
5589 _ = try self.wip.callMemSet(5606 _ = try self.wip.callMemSet(
5590 self.ret_ptr,5607 self.ret_ptr,
5591 ptr_ty.ptrAlignment(mod).toLlvm(),5608 ptr_ty.ptrAlignment(pt).toLlvm(),
5592 try o.builder.intValue(.i8, 0xaa),5609 try o.builder.intValue(.i8, 0xaa),
5593 len,5610 len,
5594 if (ptr_ty.isVolatilePtr(mod)) .@"volatile" else .normal,5611 if (ptr_ty.isVolatilePtr(mod)) .@"volatile" else .normal,
...@@ -5615,7 +5632,7 @@ pub const FuncGen = struct {...@@ -5615,7 +5632,7 @@ pub const FuncGen = struct {
5615 return .none;5632 return .none;
5616 }5633 }
5617 const fn_info = mod.typeToFunc(self.dg.decl.typeOf(mod)).?;5634 const fn_info = mod.typeToFunc(self.dg.decl.typeOf(mod)).?;
5618 if (!ret_ty.hasRuntimeBitsIgnoreComptime(mod)) {5635 if (!ret_ty.hasRuntimeBitsIgnoreComptime(pt)) {
5619 if (Type.fromInterned(fn_info.return_type).isError(mod)) {5636 if (Type.fromInterned(fn_info.return_type).isError(mod)) {
5620 // Functions with an empty error set are emitted with an error code5637 // Functions with an empty error set are emitted with an error code
5621 // return type and return zero so they can be function pointers coerced5638 // return type and return zero so they can be function pointers coerced
...@@ -5629,13 +5646,13 @@ pub const FuncGen = struct {...@@ -5629,13 +5646,13 @@ pub const FuncGen = struct {
56295646
5630 const abi_ret_ty = try lowerFnRetTy(o, fn_info);5647 const abi_ret_ty = try lowerFnRetTy(o, fn_info);
5631 const operand = try self.resolveInst(un_op);5648 const operand = try self.resolveInst(un_op);
5632 const val_is_undef = if (try self.air.value(un_op, mod)) |val| val.isUndefDeep(mod) else false;5649 const val_is_undef = if (try self.air.value(un_op, pt)) |val| val.isUndefDeep(mod) else false;
5633 const alignment = ret_ty.abiAlignment(mod).toLlvm();5650 const alignment = ret_ty.abiAlignment(pt).toLlvm();
56345651
5635 if (val_is_undef and safety) {5652 if (val_is_undef and safety) {
5636 const llvm_ret_ty = operand.typeOfWip(&self.wip);5653 const llvm_ret_ty = operand.typeOfWip(&self.wip);
5637 const rp = try self.buildAlloca(llvm_ret_ty, alignment);5654 const rp = try self.buildAlloca(llvm_ret_ty, alignment);
5638 const len = try o.builder.intValue(try o.lowerType(Type.usize), ret_ty.abiSize(mod));5655 const len = try o.builder.intValue(try o.lowerType(Type.usize), ret_ty.abiSize(pt));
5639 _ = try self.wip.callMemSet(5656 _ = try self.wip.callMemSet(
5640 rp,5657 rp,
5641 alignment,5658 alignment,
...@@ -5651,7 +5668,7 @@ pub const FuncGen = struct {...@@ -5651,7 +5668,7 @@ pub const FuncGen = struct {
5651 return .none;5668 return .none;
5652 }5669 }
56535670
5654 if (isByRef(ret_ty, mod)) {5671 if (isByRef(ret_ty, pt)) {
5655 // operand is a pointer however self.ret_ptr is null so that means5672 // operand is a pointer however self.ret_ptr is null so that means
5656 // we need to return a value.5673 // we need to return a value.
5657 _ = try self.wip.ret(try self.wip.load(.normal, abi_ret_ty, operand, alignment, ""));5674 _ = try self.wip.ret(try self.wip.load(.normal, abi_ret_ty, operand, alignment, ""));
...@@ -5672,12 +5689,13 @@ pub const FuncGen = struct {...@@ -5672,12 +5689,13 @@ pub const FuncGen = struct {
56725689
5673 fn airRetLoad(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {5690 fn airRetLoad(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
5674 const o = self.dg.object;5691 const o = self.dg.object;
5675 const mod = o.module;5692 const pt = o.pt;
5693 const mod = pt.zcu;
5676 const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op;5694 const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op;
5677 const ptr_ty = self.typeOf(un_op);5695 const ptr_ty = self.typeOf(un_op);
5678 const ret_ty = ptr_ty.childType(mod);5696 const ret_ty = ptr_ty.childType(mod);
5679 const fn_info = mod.typeToFunc(self.dg.decl.typeOf(mod)).?;5697 const fn_info = mod.typeToFunc(self.dg.decl.typeOf(mod)).?;
5680 if (!ret_ty.hasRuntimeBitsIgnoreComptime(mod)) {5698 if (!ret_ty.hasRuntimeBitsIgnoreComptime(pt)) {
5681 if (Type.fromInterned(fn_info.return_type).isError(mod)) {5699 if (Type.fromInterned(fn_info.return_type).isError(mod)) {
5682 // Functions with an empty error set are emitted with an error code5700 // Functions with an empty error set are emitted with an error code
5683 // return type and return zero so they can be function pointers coerced5701 // return type and return zero so they can be function pointers coerced
...@@ -5694,7 +5712,7 @@ pub const FuncGen = struct {...@@ -5694,7 +5712,7 @@ pub const FuncGen = struct {
5694 }5712 }
5695 const ptr = try self.resolveInst(un_op);5713 const ptr = try self.resolveInst(un_op);
5696 const abi_ret_ty = try lowerFnRetTy(o, fn_info);5714 const abi_ret_ty = try lowerFnRetTy(o, fn_info);
5697 const alignment = ret_ty.abiAlignment(mod).toLlvm();5715 const alignment = ret_ty.abiAlignment(pt).toLlvm();
5698 _ = try self.wip.ret(try self.wip.load(.normal, abi_ret_ty, ptr, alignment, ""));5716 _ = try self.wip.ret(try self.wip.load(.normal, abi_ret_ty, ptr, alignment, ""));
5699 return .none;5717 return .none;
5700 }5718 }
...@@ -5711,17 +5729,17 @@ pub const FuncGen = struct {...@@ -5711,17 +5729,17 @@ pub const FuncGen = struct {
57115729
5712 fn airCVaCopy(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {5730 fn airCVaCopy(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
5713 const o = self.dg.object;5731 const o = self.dg.object;
5732 const pt = o.pt;
5714 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;5733 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
5715 const src_list = try self.resolveInst(ty_op.operand);5734 const src_list = try self.resolveInst(ty_op.operand);
5716 const va_list_ty = ty_op.ty.toType();5735 const va_list_ty = ty_op.ty.toType();
5717 const llvm_va_list_ty = try o.lowerType(va_list_ty);5736 const llvm_va_list_ty = try o.lowerType(va_list_ty);
5718 const mod = o.module;
57195737
5720 const result_alignment = va_list_ty.abiAlignment(mod).toLlvm();5738 const result_alignment = va_list_ty.abiAlignment(pt).toLlvm();
5721 const dest_list = try self.buildAllocaWorkaround(va_list_ty, result_alignment);5739 const dest_list = try self.buildAllocaWorkaround(va_list_ty, result_alignment);
57225740
5723 _ = try self.wip.callIntrinsic(.normal, .none, .va_copy, &.{}, &.{ dest_list, src_list }, "");5741 _ = try self.wip.callIntrinsic(.normal, .none, .va_copy, &.{}, &.{ dest_list, src_list }, "");
5724 return if (isByRef(va_list_ty, mod))5742 return if (isByRef(va_list_ty, pt))
5725 dest_list5743 dest_list
5726 else5744 else
5727 try self.wip.load(.normal, llvm_va_list_ty, dest_list, result_alignment, "");5745 try self.wip.load(.normal, llvm_va_list_ty, dest_list, result_alignment, "");
...@@ -5737,15 +5755,15 @@ pub const FuncGen = struct {...@@ -5737,15 +5755,15 @@ pub const FuncGen = struct {
57375755
5738 fn airCVaStart(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {5756 fn airCVaStart(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
5739 const o = self.dg.object;5757 const o = self.dg.object;
5740 const mod = o.module;5758 const pt = o.pt;
5741 const va_list_ty = self.typeOfIndex(inst);5759 const va_list_ty = self.typeOfIndex(inst);
5742 const llvm_va_list_ty = try o.lowerType(va_list_ty);5760 const llvm_va_list_ty = try o.lowerType(va_list_ty);
57435761
5744 const result_alignment = va_list_ty.abiAlignment(mod).toLlvm();5762 const result_alignment = va_list_ty.abiAlignment(pt).toLlvm();
5745 const dest_list = try self.buildAllocaWorkaround(va_list_ty, result_alignment);5763 const dest_list = try self.buildAllocaWorkaround(va_list_ty, result_alignment);
57465764
5747 _ = try self.wip.callIntrinsic(.normal, .none, .va_start, &.{}, &.{dest_list}, "");5765 _ = try self.wip.callIntrinsic(.normal, .none, .va_start, &.{}, &.{dest_list}, "");
5748 return if (isByRef(va_list_ty, mod))5766 return if (isByRef(va_list_ty, pt))
5749 dest_list5767 dest_list
5750 else5768 else
5751 try self.wip.load(.normal, llvm_va_list_ty, dest_list, result_alignment, "");5769 try self.wip.load(.normal, llvm_va_list_ty, dest_list, result_alignment, "");
...@@ -5802,21 +5820,22 @@ pub const FuncGen = struct {...@@ -5802,21 +5820,22 @@ pub const FuncGen = struct {
5802 rhs: Builder.Value,5820 rhs: Builder.Value,
5803 ) Allocator.Error!Builder.Value {5821 ) Allocator.Error!Builder.Value {
5804 const o = self.dg.object;5822 const o = self.dg.object;
5805 const mod = o.module;5823 const pt = o.pt;
5824 const mod = pt.zcu;
5806 const scalar_ty = operand_ty.scalarType(mod);5825 const scalar_ty = operand_ty.scalarType(mod);
5807 const int_ty = switch (scalar_ty.zigTypeTag(mod)) {5826 const int_ty = switch (scalar_ty.zigTypeTag(mod)) {
5808 .Enum => scalar_ty.intTagType(mod),5827 .Enum => scalar_ty.intTagType(mod),
5809 .Int, .Bool, .Pointer, .ErrorSet => scalar_ty,5828 .Int, .Bool, .Pointer, .ErrorSet => scalar_ty,
5810 .Optional => blk: {5829 .Optional => blk: {
5811 const payload_ty = operand_ty.optionalChild(mod);5830 const payload_ty = operand_ty.optionalChild(mod);
5812 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod) or5831 if (!payload_ty.hasRuntimeBitsIgnoreComptime(pt) or
5813 operand_ty.optionalReprIsPayload(mod))5832 operand_ty.optionalReprIsPayload(mod))
5814 {5833 {
5815 break :blk operand_ty;5834 break :blk operand_ty;
5816 }5835 }
5817 // We need to emit instructions to check for equality/inequality5836 // We need to emit instructions to check for equality/inequality
5818 // of optionals that are not pointers.5837 // of optionals that are not pointers.
5819 const is_by_ref = isByRef(scalar_ty, mod);5838 const is_by_ref = isByRef(scalar_ty, pt);
5820 const opt_llvm_ty = try o.lowerType(scalar_ty);5839 const opt_llvm_ty = try o.lowerType(scalar_ty);
5821 const lhs_non_null = try self.optCmpNull(.ne, opt_llvm_ty, lhs, is_by_ref);5840 const lhs_non_null = try self.optCmpNull(.ne, opt_llvm_ty, lhs, is_by_ref);
5822 const rhs_non_null = try self.optCmpNull(.ne, opt_llvm_ty, rhs, is_by_ref);5841 const rhs_non_null = try self.optCmpNull(.ne, opt_llvm_ty, rhs, is_by_ref);
...@@ -5908,7 +5927,8 @@ pub const FuncGen = struct {...@@ -5908,7 +5927,8 @@ pub const FuncGen = struct {
5908 body: []const Air.Inst.Index,5927 body: []const Air.Inst.Index,
5909 ) !Builder.Value {5928 ) !Builder.Value {
5910 const o = self.dg.object;5929 const o = self.dg.object;
5911 const mod = o.module;5930 const pt = o.pt;
5931 const mod = pt.zcu;
5912 const inst_ty = self.typeOfIndex(inst);5932 const inst_ty = self.typeOfIndex(inst);
59135933
5914 if (inst_ty.isNoReturn(mod)) {5934 if (inst_ty.isNoReturn(mod)) {
...@@ -5916,7 +5936,7 @@ pub const FuncGen = struct {...@@ -5916,7 +5936,7 @@ pub const FuncGen = struct {
5916 return .none;5936 return .none;
5917 }5937 }
59185938
5919 const have_block_result = inst_ty.isFnOrHasRuntimeBitsIgnoreComptime(mod);5939 const have_block_result = inst_ty.isFnOrHasRuntimeBitsIgnoreComptime(pt);
59205940
5921 var breaks: BreakList = if (have_block_result) .{ .list = .{} } else .{ .len = 0 };5941 var breaks: BreakList = if (have_block_result) .{ .list = .{} } else .{ .len = 0 };
5922 defer if (have_block_result) breaks.list.deinit(self.gpa);5942 defer if (have_block_result) breaks.list.deinit(self.gpa);
...@@ -5940,7 +5960,7 @@ pub const FuncGen = struct {...@@ -5940,7 +5960,7 @@ pub const FuncGen = struct {
5940 // a pointer to it. LLVM IR allows the call instruction to use function bodies instead5960 // a pointer to it. LLVM IR allows the call instruction to use function bodies instead
5941 // of function pointers, however the phi makes it a runtime value and therefore5961 // of function pointers, however the phi makes it a runtime value and therefore
5942 // the LLVM type has to be wrapped in a pointer.5962 // the LLVM type has to be wrapped in a pointer.
5943 if (inst_ty.zigTypeTag(mod) == .Fn or isByRef(inst_ty, mod)) {5963 if (inst_ty.zigTypeTag(mod) == .Fn or isByRef(inst_ty, pt)) {
5944 break :ty .ptr;5964 break :ty .ptr;
5945 }5965 }
5946 break :ty raw_llvm_ty;5966 break :ty raw_llvm_ty;
...@@ -5958,13 +5978,13 @@ pub const FuncGen = struct {...@@ -5958,13 +5978,13 @@ pub const FuncGen = struct {
59585978
5959 fn airBr(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {5979 fn airBr(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
5960 const o = self.dg.object;5980 const o = self.dg.object;
5981 const pt = o.pt;
5961 const branch = self.air.instructions.items(.data)[@intFromEnum(inst)].br;5982 const branch = self.air.instructions.items(.data)[@intFromEnum(inst)].br;
5962 const block = self.blocks.get(branch.block_inst).?;5983 const block = self.blocks.get(branch.block_inst).?;
59635984
5964 // Add the values to the lists only if the break provides a value.5985 // Add the values to the lists only if the break provides a value.
5965 const operand_ty = self.typeOf(branch.operand);5986 const operand_ty = self.typeOf(branch.operand);
5966 const mod = o.module;5987 if (operand_ty.isFnOrHasRuntimeBitsIgnoreComptime(pt)) {
5967 if (operand_ty.isFnOrHasRuntimeBitsIgnoreComptime(mod)) {
5968 const val = try self.resolveInst(branch.operand);5988 const val = try self.resolveInst(branch.operand);
59695989
5970 // For the phi node, we need the basic blocks and the values of the5990 // For the phi node, we need the basic blocks and the values of the
...@@ -5998,7 +6018,7 @@ pub const FuncGen = struct {...@@ -5998,7 +6018,7 @@ pub const FuncGen = struct {
59986018
5999 fn airTry(self: *FuncGen, body_tail: []const Air.Inst.Index) !Builder.Value {6019 fn airTry(self: *FuncGen, body_tail: []const Air.Inst.Index) !Builder.Value {
6000 const o = self.dg.object;6020 const o = self.dg.object;
6001 const mod = o.module;6021 const pt = o.pt;
6002 const inst = body_tail[0];6022 const inst = body_tail[0];
6003 const pl_op = self.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;6023 const pl_op = self.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;
6004 const err_union = try self.resolveInst(pl_op.operand);6024 const err_union = try self.resolveInst(pl_op.operand);
...@@ -6006,14 +6026,14 @@ pub const FuncGen = struct {...@@ -6006,14 +6026,14 @@ pub const FuncGen = struct {
6006 const body: []const Air.Inst.Index = @ptrCast(self.air.extra[extra.end..][0..extra.data.body_len]);6026 const body: []const Air.Inst.Index = @ptrCast(self.air.extra[extra.end..][0..extra.data.body_len]);
6007 const err_union_ty = self.typeOf(pl_op.operand);6027 const err_union_ty = self.typeOf(pl_op.operand);
6008 const payload_ty = self.typeOfIndex(inst);6028 const payload_ty = self.typeOfIndex(inst);
6009 const can_elide_load = if (isByRef(payload_ty, mod)) self.canElideLoad(body_tail) else false;6029 const can_elide_load = if (isByRef(payload_ty, pt)) self.canElideLoad(body_tail) else false;
6010 const is_unused = self.liveness.isUnused(inst);6030 const is_unused = self.liveness.isUnused(inst);
6011 return lowerTry(self, err_union, body, err_union_ty, false, can_elide_load, is_unused);6031 return lowerTry(self, err_union, body, err_union_ty, false, can_elide_load, is_unused);
6012 }6032 }
60136033
6014 fn airTryPtr(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {6034 fn airTryPtr(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
6015 const o = self.dg.object;6035 const o = self.dg.object;
6016 const mod = o.module;6036 const mod = o.pt.zcu;
6017 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;6037 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
6018 const extra = self.air.extraData(Air.TryPtr, ty_pl.payload);6038 const extra = self.air.extraData(Air.TryPtr, ty_pl.payload);
6019 const err_union_ptr = try self.resolveInst(extra.data.ptr);6039 const err_union_ptr = try self.resolveInst(extra.data.ptr);
...@@ -6033,9 +6053,10 @@ pub const FuncGen = struct {...@@ -6033,9 +6053,10 @@ pub const FuncGen = struct {
6033 is_unused: bool,6053 is_unused: bool,
6034 ) !Builder.Value {6054 ) !Builder.Value {
6035 const o = fg.dg.object;6055 const o = fg.dg.object;
6036 const mod = o.module;6056 const pt = o.pt;
6057 const mod = pt.zcu;
6037 const payload_ty = err_union_ty.errorUnionPayload(mod);6058 const payload_ty = err_union_ty.errorUnionPayload(mod);
6038 const payload_has_bits = payload_ty.hasRuntimeBitsIgnoreComptime(mod);6059 const payload_has_bits = payload_ty.hasRuntimeBitsIgnoreComptime(pt);
6039 const err_union_llvm_ty = try o.lowerType(err_union_ty);6060 const err_union_llvm_ty = try o.lowerType(err_union_ty);
6040 const error_type = try o.errorIntType();6061 const error_type = try o.errorIntType();
60416062
...@@ -6048,8 +6069,8 @@ pub const FuncGen = struct {...@@ -6048,8 +6069,8 @@ pub const FuncGen = struct {
6048 else6069 else
6049 err_union;6070 err_union;
6050 }6071 }
6051 const err_field_index = try errUnionErrorOffset(payload_ty, mod);6072 const err_field_index = try errUnionErrorOffset(payload_ty, pt);
6052 if (operand_is_ptr or isByRef(err_union_ty, mod)) {6073 if (operand_is_ptr or isByRef(err_union_ty, pt)) {
6053 const err_field_ptr =6074 const err_field_ptr =
6054 try fg.wip.gepStruct(err_union_llvm_ty, err_union, err_field_index, "");6075 try fg.wip.gepStruct(err_union_llvm_ty, err_union, err_field_index, "");
6055 // TODO add alignment to this load6076 // TODO add alignment to this load
...@@ -6077,13 +6098,13 @@ pub const FuncGen = struct {...@@ -6077,13 +6098,13 @@ pub const FuncGen = struct {
6077 }6098 }
6078 if (is_unused) return .none;6099 if (is_unused) return .none;
6079 if (!payload_has_bits) return if (operand_is_ptr) err_union else .none;6100 if (!payload_has_bits) return if (operand_is_ptr) err_union else .none;
6080 const offset = try errUnionPayloadOffset(payload_ty, mod);6101 const offset = try errUnionPayloadOffset(payload_ty, pt);
6081 if (operand_is_ptr) {6102 if (operand_is_ptr) {
6082 return fg.wip.gepStruct(err_union_llvm_ty, err_union, offset, "");6103 return fg.wip.gepStruct(err_union_llvm_ty, err_union, offset, "");
6083 } else if (isByRef(err_union_ty, mod)) {6104 } else if (isByRef(err_union_ty, pt)) {
6084 const payload_ptr = try fg.wip.gepStruct(err_union_llvm_ty, err_union, offset, "");6105 const payload_ptr = try fg.wip.gepStruct(err_union_llvm_ty, err_union, offset, "");
6085 const payload_alignment = payload_ty.abiAlignment(mod).toLlvm();6106 const payload_alignment = payload_ty.abiAlignment(pt).toLlvm();
6086 if (isByRef(payload_ty, mod)) {6107 if (isByRef(payload_ty, pt)) {
6087 if (can_elide_load)6108 if (can_elide_load)
6088 return payload_ptr;6109 return payload_ptr;
60896110
...@@ -6161,7 +6182,7 @@ pub const FuncGen = struct {...@@ -6161,7 +6182,7 @@ pub const FuncGen = struct {
61616182
6162 fn airLoop(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {6183 fn airLoop(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
6163 const o = self.dg.object;6184 const o = self.dg.object;
6164 const mod = o.module;6185 const mod = o.pt.zcu;
6165 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;6186 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
6166 const loop = self.air.extraData(Air.Block, ty_pl.payload);6187 const loop = self.air.extraData(Air.Block, ty_pl.payload);
6167 const body: []const Air.Inst.Index = @ptrCast(self.air.extra[loop.end..][0..loop.data.body_len]);6188 const body: []const Air.Inst.Index = @ptrCast(self.air.extra[loop.end..][0..loop.data.body_len]);
...@@ -6185,7 +6206,8 @@ pub const FuncGen = struct {...@@ -6185,7 +6206,8 @@ pub const FuncGen = struct {
61856206
6186 fn airArrayToSlice(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {6207 fn airArrayToSlice(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
6187 const o = self.dg.object;6208 const o = self.dg.object;
6188 const mod = o.module;6209 const pt = o.pt;
6210 const mod = pt.zcu;
6189 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;6211 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
6190 const operand_ty = self.typeOf(ty_op.operand);6212 const operand_ty = self.typeOf(ty_op.operand);
6191 const array_ty = operand_ty.childType(mod);6213 const array_ty = operand_ty.childType(mod);
...@@ -6193,7 +6215,7 @@ pub const FuncGen = struct {...@@ -6193,7 +6215,7 @@ pub const FuncGen = struct {
6193 const len = try o.builder.intValue(llvm_usize, array_ty.arrayLen(mod));6215 const len = try o.builder.intValue(llvm_usize, array_ty.arrayLen(mod));
6194 const slice_llvm_ty = try o.lowerType(self.typeOfIndex(inst));6216 const slice_llvm_ty = try o.lowerType(self.typeOfIndex(inst));
6195 const operand = try self.resolveInst(ty_op.operand);6217 const operand = try self.resolveInst(ty_op.operand);
6196 if (!array_ty.hasRuntimeBitsIgnoreComptime(mod))6218 if (!array_ty.hasRuntimeBitsIgnoreComptime(pt))
6197 return self.wip.buildAggregate(slice_llvm_ty, &.{ operand, len }, "");6219 return self.wip.buildAggregate(slice_llvm_ty, &.{ operand, len }, "");
6198 const ptr = try self.wip.gep(.inbounds, try o.lowerType(array_ty), operand, &.{6220 const ptr = try self.wip.gep(.inbounds, try o.lowerType(array_ty), operand, &.{
6199 try o.builder.intValue(llvm_usize, 0), try o.builder.intValue(llvm_usize, 0),6221 try o.builder.intValue(llvm_usize, 0), try o.builder.intValue(llvm_usize, 0),
...@@ -6203,7 +6225,8 @@ pub const FuncGen = struct {...@@ -6203,7 +6225,8 @@ pub const FuncGen = struct {
62036225
6204 fn airFloatFromInt(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {6226 fn airFloatFromInt(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
6205 const o = self.dg.object;6227 const o = self.dg.object;
6206 const mod = o.module;6228 const pt = o.pt;
6229 const mod = pt.zcu;
6207 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;6230 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
62086231
6209 const workaround_operand = try self.resolveInst(ty_op.operand);6232 const workaround_operand = try self.resolveInst(ty_op.operand);
...@@ -6213,7 +6236,7 @@ pub const FuncGen = struct {...@@ -6213,7 +6236,7 @@ pub const FuncGen = struct {
62136236
6214 const operand = o: {6237 const operand = o: {
6215 // Work around LLVM bug. See https://github.com/ziglang/zig/issues/17381.6238 // Work around LLVM bug. See https://github.com/ziglang/zig/issues/17381.
6216 const bit_size = operand_scalar_ty.bitSize(mod);6239 const bit_size = operand_scalar_ty.bitSize(pt);
6217 for ([_]u8{ 8, 16, 32, 64, 128 }) |b| {6240 for ([_]u8{ 8, 16, 32, 64, 128 }) |b| {
6218 if (bit_size < b) {6241 if (bit_size < b) {
6219 break :o try self.wip.cast(6242 break :o try self.wip.cast(
...@@ -6241,7 +6264,7 @@ pub const FuncGen = struct {...@@ -6241,7 +6264,7 @@ pub const FuncGen = struct {
6241 "",6264 "",
6242 );6265 );
62436266
6244 const rt_int_bits = compilerRtIntBits(@intCast(operand_scalar_ty.bitSize(mod)));6267 const rt_int_bits = compilerRtIntBits(@intCast(operand_scalar_ty.bitSize(pt)));
6245 const rt_int_ty = try o.builder.intType(rt_int_bits);6268 const rt_int_ty = try o.builder.intType(rt_int_bits);
6246 var extended = try self.wip.conv(6269 var extended = try self.wip.conv(
6247 if (is_signed_int) .signed else .unsigned,6270 if (is_signed_int) .signed else .unsigned,
...@@ -6287,7 +6310,8 @@ pub const FuncGen = struct {...@@ -6287,7 +6310,8 @@ pub const FuncGen = struct {
6287 _ = fast;6310 _ = fast;
62886311
6289 const o = self.dg.object;6312 const o = self.dg.object;
6290 const mod = o.module;6313 const pt = o.pt;
6314 const mod = pt.zcu;
6291 const target = mod.getTarget();6315 const target = mod.getTarget();
6292 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;6316 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
62936317
...@@ -6309,7 +6333,7 @@ pub const FuncGen = struct {...@@ -6309,7 +6333,7 @@ pub const FuncGen = struct {
6309 );6333 );
6310 }6334 }
63116335
6312 const rt_int_bits = compilerRtIntBits(@intCast(dest_scalar_ty.bitSize(mod)));6336 const rt_int_bits = compilerRtIntBits(@intCast(dest_scalar_ty.bitSize(pt)));
6313 const ret_ty = try o.builder.intType(rt_int_bits);6337 const ret_ty = try o.builder.intType(rt_int_bits);
6314 const libc_ret_ty = if (rt_int_bits == 128 and (target.os.tag == .windows and target.cpu.arch == .x86_64)) b: {6338 const libc_ret_ty = if (rt_int_bits == 128 and (target.os.tag == .windows and target.cpu.arch == .x86_64)) b: {
6315 // On Windows x86-64, "ti" functions must use Vector(2, u64) instead of the standard6339 // On Windows x86-64, "ti" functions must use Vector(2, u64) instead of the standard
...@@ -6348,19 +6372,20 @@ pub const FuncGen = struct {...@@ -6348,19 +6372,20 @@ pub const FuncGen = struct {
63486372
6349 fn sliceOrArrayPtr(fg: *FuncGen, ptr: Builder.Value, ty: Type) Allocator.Error!Builder.Value {6373 fn sliceOrArrayPtr(fg: *FuncGen, ptr: Builder.Value, ty: Type) Allocator.Error!Builder.Value {
6350 const o = fg.dg.object;6374 const o = fg.dg.object;
6351 const mod = o.module;6375 const mod = o.pt.zcu;
6352 return if (ty.isSlice(mod)) fg.wip.extractValue(ptr, &.{0}, "") else ptr;6376 return if (ty.isSlice(mod)) fg.wip.extractValue(ptr, &.{0}, "") else ptr;
6353 }6377 }
63546378
6355 fn sliceOrArrayLenInBytes(fg: *FuncGen, ptr: Builder.Value, ty: Type) Allocator.Error!Builder.Value {6379 fn sliceOrArrayLenInBytes(fg: *FuncGen, ptr: Builder.Value, ty: Type) Allocator.Error!Builder.Value {
6356 const o = fg.dg.object;6380 const o = fg.dg.object;
6357 const mod = o.module;6381 const pt = o.pt;
6382 const mod = pt.zcu;
6358 const llvm_usize = try o.lowerType(Type.usize);6383 const llvm_usize = try o.lowerType(Type.usize);
6359 switch (ty.ptrSize(mod)) {6384 switch (ty.ptrSize(mod)) {
6360 .Slice => {6385 .Slice => {
6361 const len = try fg.wip.extractValue(ptr, &.{1}, "");6386 const len = try fg.wip.extractValue(ptr, &.{1}, "");
6362 const elem_ty = ty.childType(mod);6387 const elem_ty = ty.childType(mod);
6363 const abi_size = elem_ty.abiSize(mod);6388 const abi_size = elem_ty.abiSize(pt);
6364 if (abi_size == 1) return len;6389 if (abi_size == 1) return len;
6365 const abi_size_llvm_val = try o.builder.intValue(llvm_usize, abi_size);6390 const abi_size_llvm_val = try o.builder.intValue(llvm_usize, abi_size);
6366 return fg.wip.bin(.@"mul nuw", len, abi_size_llvm_val, "");6391 return fg.wip.bin(.@"mul nuw", len, abi_size_llvm_val, "");
...@@ -6368,7 +6393,7 @@ pub const FuncGen = struct {...@@ -6368,7 +6393,7 @@ pub const FuncGen = struct {
6368 .One => {6393 .One => {
6369 const array_ty = ty.childType(mod);6394 const array_ty = ty.childType(mod);
6370 const elem_ty = array_ty.childType(mod);6395 const elem_ty = array_ty.childType(mod);
6371 const abi_size = elem_ty.abiSize(mod);6396 const abi_size = elem_ty.abiSize(pt);
6372 return o.builder.intValue(llvm_usize, array_ty.arrayLen(mod) * abi_size);6397 return o.builder.intValue(llvm_usize, array_ty.arrayLen(mod) * abi_size);
6373 },6398 },
6374 .Many, .C => unreachable,6399 .Many, .C => unreachable,
...@@ -6383,7 +6408,7 @@ pub const FuncGen = struct {...@@ -6383,7 +6408,7 @@ pub const FuncGen = struct {
63836408
6384 fn airPtrSliceFieldPtr(self: *FuncGen, inst: Air.Inst.Index, index: c_uint) !Builder.Value {6409 fn airPtrSliceFieldPtr(self: *FuncGen, inst: Air.Inst.Index, index: c_uint) !Builder.Value {
6385 const o = self.dg.object;6410 const o = self.dg.object;
6386 const mod = o.module;6411 const mod = o.pt.zcu;
6387 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;6412 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
6388 const slice_ptr = try self.resolveInst(ty_op.operand);6413 const slice_ptr = try self.resolveInst(ty_op.operand);
6389 const slice_ptr_ty = self.typeOf(ty_op.operand);6414 const slice_ptr_ty = self.typeOf(ty_op.operand);
...@@ -6394,7 +6419,8 @@ pub const FuncGen = struct {...@@ -6394,7 +6419,8 @@ pub const FuncGen = struct {
63946419
6395 fn airSliceElemVal(self: *FuncGen, body_tail: []const Air.Inst.Index) !Builder.Value {6420 fn airSliceElemVal(self: *FuncGen, body_tail: []const Air.Inst.Index) !Builder.Value {
6396 const o = self.dg.object;6421 const o = self.dg.object;
6397 const mod = o.module;6422 const pt = o.pt;
6423 const mod = pt.zcu;
6398 const inst = body_tail[0];6424 const inst = body_tail[0];
6399 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;6425 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
6400 const slice_ty = self.typeOf(bin_op.lhs);6426 const slice_ty = self.typeOf(bin_op.lhs);
...@@ -6404,11 +6430,11 @@ pub const FuncGen = struct {...@@ -6404,11 +6430,11 @@ pub const FuncGen = struct {
6404 const llvm_elem_ty = try o.lowerPtrElemTy(elem_ty);6430 const llvm_elem_ty = try o.lowerPtrElemTy(elem_ty);
6405 const base_ptr = try self.wip.extractValue(slice, &.{0}, "");6431 const base_ptr = try self.wip.extractValue(slice, &.{0}, "");
6406 const ptr = try self.wip.gep(.inbounds, llvm_elem_ty, base_ptr, &.{index}, "");6432 const ptr = try self.wip.gep(.inbounds, llvm_elem_ty, base_ptr, &.{index}, "");
6407 if (isByRef(elem_ty, mod)) {6433 if (isByRef(elem_ty, pt)) {
6408 if (self.canElideLoad(body_tail))6434 if (self.canElideLoad(body_tail))
6409 return ptr;6435 return ptr;
64106436
6411 const elem_alignment = elem_ty.abiAlignment(mod).toLlvm();6437 const elem_alignment = elem_ty.abiAlignment(pt).toLlvm();
6412 return self.loadByRef(ptr, elem_ty, elem_alignment, .normal);6438 return self.loadByRef(ptr, elem_ty, elem_alignment, .normal);
6413 }6439 }
64146440
...@@ -6417,7 +6443,7 @@ pub const FuncGen = struct {...@@ -6417,7 +6443,7 @@ pub const FuncGen = struct {
64176443
6418 fn airSliceElemPtr(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {6444 fn airSliceElemPtr(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
6419 const o = self.dg.object;6445 const o = self.dg.object;
6420 const mod = o.module;6446 const mod = o.pt.zcu;
6421 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;6447 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
6422 const bin_op = self.air.extraData(Air.Bin, ty_pl.payload).data;6448 const bin_op = self.air.extraData(Air.Bin, ty_pl.payload).data;
6423 const slice_ty = self.typeOf(bin_op.lhs);6449 const slice_ty = self.typeOf(bin_op.lhs);
...@@ -6431,7 +6457,8 @@ pub const FuncGen = struct {...@@ -6431,7 +6457,8 @@ pub const FuncGen = struct {
64316457
6432 fn airArrayElemVal(self: *FuncGen, body_tail: []const Air.Inst.Index) !Builder.Value {6458 fn airArrayElemVal(self: *FuncGen, body_tail: []const Air.Inst.Index) !Builder.Value {
6433 const o = self.dg.object;6459 const o = self.dg.object;
6434 const mod = o.module;6460 const pt = o.pt;
6461 const mod = pt.zcu;
6435 const inst = body_tail[0];6462 const inst = body_tail[0];
64366463
6437 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;6464 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
...@@ -6440,15 +6467,15 @@ pub const FuncGen = struct {...@@ -6440,15 +6467,15 @@ pub const FuncGen = struct {
6440 const rhs = try self.resolveInst(bin_op.rhs);6467 const rhs = try self.resolveInst(bin_op.rhs);
6441 const array_llvm_ty = try o.lowerType(array_ty);6468 const array_llvm_ty = try o.lowerType(array_ty);
6442 const elem_ty = array_ty.childType(mod);6469 const elem_ty = array_ty.childType(mod);
6443 if (isByRef(array_ty, mod)) {6470 if (isByRef(array_ty, pt)) {
6444 const indices: [2]Builder.Value = .{6471 const indices: [2]Builder.Value = .{
6445 try o.builder.intValue(try o.lowerType(Type.usize), 0), rhs,6472 try o.builder.intValue(try o.lowerType(Type.usize), 0), rhs,
6446 };6473 };
6447 if (isByRef(elem_ty, mod)) {6474 if (isByRef(elem_ty, pt)) {
6448 const elem_ptr =6475 const elem_ptr =
6449 try self.wip.gep(.inbounds, array_llvm_ty, array_llvm_val, &indices, "");6476 try self.wip.gep(.inbounds, array_llvm_ty, array_llvm_val, &indices, "");
6450 if (canElideLoad(self, body_tail)) return elem_ptr;6477 if (canElideLoad(self, body_tail)) return elem_ptr;
6451 const elem_alignment = elem_ty.abiAlignment(mod).toLlvm();6478 const elem_alignment = elem_ty.abiAlignment(pt).toLlvm();
6452 return self.loadByRef(elem_ptr, elem_ty, elem_alignment, .normal);6479 return self.loadByRef(elem_ptr, elem_ty, elem_alignment, .normal);
6453 } else {6480 } else {
6454 const elem_ptr =6481 const elem_ptr =
...@@ -6463,7 +6490,8 @@ pub const FuncGen = struct {...@@ -6463,7 +6490,8 @@ pub const FuncGen = struct {
64636490
6464 fn airPtrElemVal(self: *FuncGen, body_tail: []const Air.Inst.Index) !Builder.Value {6491 fn airPtrElemVal(self: *FuncGen, body_tail: []const Air.Inst.Index) !Builder.Value {
6465 const o = self.dg.object;6492 const o = self.dg.object;
6466 const mod = o.module;6493 const pt = o.pt;
6494 const mod = pt.zcu;
6467 const inst = body_tail[0];6495 const inst = body_tail[0];
6468 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;6496 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
6469 const ptr_ty = self.typeOf(bin_op.lhs);6497 const ptr_ty = self.typeOf(bin_op.lhs);
...@@ -6477,9 +6505,9 @@ pub const FuncGen = struct {...@@ -6477,9 +6505,9 @@ pub const FuncGen = struct {
6477 &.{ try o.builder.intValue(try o.lowerType(Type.usize), 0), rhs }6505 &.{ try o.builder.intValue(try o.lowerType(Type.usize), 0), rhs }
6478 else6506 else
6479 &.{rhs}, "");6507 &.{rhs}, "");
6480 if (isByRef(elem_ty, mod)) {6508 if (isByRef(elem_ty, pt)) {
6481 if (self.canElideLoad(body_tail)) return ptr;6509 if (self.canElideLoad(body_tail)) return ptr;
6482 const elem_alignment = elem_ty.abiAlignment(mod).toLlvm();6510 const elem_alignment = elem_ty.abiAlignment(pt).toLlvm();
6483 return self.loadByRef(ptr, elem_ty, elem_alignment, .normal);6511 return self.loadByRef(ptr, elem_ty, elem_alignment, .normal);
6484 }6512 }
64856513
...@@ -6488,12 +6516,13 @@ pub const FuncGen = struct {...@@ -6488,12 +6516,13 @@ pub const FuncGen = struct {
64886516
6489 fn airPtrElemPtr(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {6517 fn airPtrElemPtr(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
6490 const o = self.dg.object;6518 const o = self.dg.object;
6491 const mod = o.module;6519 const pt = o.pt;
6520 const mod = pt.zcu;
6492 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;6521 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
6493 const bin_op = self.air.extraData(Air.Bin, ty_pl.payload).data;6522 const bin_op = self.air.extraData(Air.Bin, ty_pl.payload).data;
6494 const ptr_ty = self.typeOf(bin_op.lhs);6523 const ptr_ty = self.typeOf(bin_op.lhs);
6495 const elem_ty = ptr_ty.childType(mod);6524 const elem_ty = ptr_ty.childType(mod);
6496 if (!elem_ty.hasRuntimeBitsIgnoreComptime(mod)) return self.resolveInst(bin_op.lhs);6525 if (!elem_ty.hasRuntimeBitsIgnoreComptime(pt)) return self.resolveInst(bin_op.lhs);
64976526
6498 const base_ptr = try self.resolveInst(bin_op.lhs);6527 const base_ptr = try self.resolveInst(bin_op.lhs);
6499 const rhs = try self.resolveInst(bin_op.rhs);6528 const rhs = try self.resolveInst(bin_op.rhs);
...@@ -6530,7 +6559,8 @@ pub const FuncGen = struct {...@@ -6530,7 +6559,8 @@ pub const FuncGen = struct {
65306559
6531 fn airStructFieldVal(self: *FuncGen, body_tail: []const Air.Inst.Index) !Builder.Value {6560 fn airStructFieldVal(self: *FuncGen, body_tail: []const Air.Inst.Index) !Builder.Value {
6532 const o = self.dg.object;6561 const o = self.dg.object;
6533 const mod = o.module;6562 const pt = o.pt;
6563 const mod = pt.zcu;
6534 const inst = body_tail[0];6564 const inst = body_tail[0];
6535 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;6565 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
6536 const struct_field = self.air.extraData(Air.StructField, ty_pl.payload).data;6566 const struct_field = self.air.extraData(Air.StructField, ty_pl.payload).data;
...@@ -6538,27 +6568,27 @@ pub const FuncGen = struct {...@@ -6538,27 +6568,27 @@ pub const FuncGen = struct {
6538 const struct_llvm_val = try self.resolveInst(struct_field.struct_operand);6568 const struct_llvm_val = try self.resolveInst(struct_field.struct_operand);
6539 const field_index = struct_field.field_index;6569 const field_index = struct_field.field_index;
6540 const field_ty = struct_ty.structFieldType(field_index, mod);6570 const field_ty = struct_ty.structFieldType(field_index, mod);
6541 if (!field_ty.hasRuntimeBitsIgnoreComptime(mod)) return .none;6571 if (!field_ty.hasRuntimeBitsIgnoreComptime(pt)) return .none;
65426572
6543 if (!isByRef(struct_ty, mod)) {6573 if (!isByRef(struct_ty, pt)) {
6544 assert(!isByRef(field_ty, mod));6574 assert(!isByRef(field_ty, pt));
6545 switch (struct_ty.zigTypeTag(mod)) {6575 switch (struct_ty.zigTypeTag(mod)) {
6546 .Struct => switch (struct_ty.containerLayout(mod)) {6576 .Struct => switch (struct_ty.containerLayout(mod)) {
6547 .@"packed" => {6577 .@"packed" => {
6548 const struct_type = mod.typeToStruct(struct_ty).?;6578 const struct_type = mod.typeToStruct(struct_ty).?;
6549 const bit_offset = mod.structPackedFieldBitOffset(struct_type, field_index);6579 const bit_offset = pt.structPackedFieldBitOffset(struct_type, field_index);
6550 const containing_int = struct_llvm_val;6580 const containing_int = struct_llvm_val;
6551 const shift_amt =6581 const shift_amt =
6552 try o.builder.intValue(containing_int.typeOfWip(&self.wip), bit_offset);6582 try o.builder.intValue(containing_int.typeOfWip(&self.wip), bit_offset);
6553 const shifted_value = try self.wip.bin(.lshr, containing_int, shift_amt, "");6583 const shifted_value = try self.wip.bin(.lshr, containing_int, shift_amt, "");
6554 const elem_llvm_ty = try o.lowerType(field_ty);6584 const elem_llvm_ty = try o.lowerType(field_ty);
6555 if (field_ty.zigTypeTag(mod) == .Float or field_ty.zigTypeTag(mod) == .Vector) {6585 if (field_ty.zigTypeTag(mod) == .Float or field_ty.zigTypeTag(mod) == .Vector) {
6556 const same_size_int = try o.builder.intType(@intCast(field_ty.bitSize(mod)));6586 const same_size_int = try o.builder.intType(@intCast(field_ty.bitSize(pt)));
6557 const truncated_int =6587 const truncated_int =
6558 try self.wip.cast(.trunc, shifted_value, same_size_int, "");6588 try self.wip.cast(.trunc, shifted_value, same_size_int, "");
6559 return self.wip.cast(.bitcast, truncated_int, elem_llvm_ty, "");6589 return self.wip.cast(.bitcast, truncated_int, elem_llvm_ty, "");
6560 } else if (field_ty.isPtrAtRuntime(mod)) {6590 } else if (field_ty.isPtrAtRuntime(mod)) {
6561 const same_size_int = try o.builder.intType(@intCast(field_ty.bitSize(mod)));6591 const same_size_int = try o.builder.intType(@intCast(field_ty.bitSize(pt)));
6562 const truncated_int =6592 const truncated_int =
6563 try self.wip.cast(.trunc, shifted_value, same_size_int, "");6593 try self.wip.cast(.trunc, shifted_value, same_size_int, "");
6564 return self.wip.cast(.inttoptr, truncated_int, elem_llvm_ty, "");6594 return self.wip.cast(.inttoptr, truncated_int, elem_llvm_ty, "");
...@@ -6575,12 +6605,12 @@ pub const FuncGen = struct {...@@ -6575,12 +6605,12 @@ pub const FuncGen = struct {
6575 const containing_int = struct_llvm_val;6605 const containing_int = struct_llvm_val;
6576 const elem_llvm_ty = try o.lowerType(field_ty);6606 const elem_llvm_ty = try o.lowerType(field_ty);
6577 if (field_ty.zigTypeTag(mod) == .Float or field_ty.zigTypeTag(mod) == .Vector) {6607 if (field_ty.zigTypeTag(mod) == .Float or field_ty.zigTypeTag(mod) == .Vector) {
6578 const same_size_int = try o.builder.intType(@intCast(field_ty.bitSize(mod)));6608 const same_size_int = try o.builder.intType(@intCast(field_ty.bitSize(pt)));
6579 const truncated_int =6609 const truncated_int =
6580 try self.wip.cast(.trunc, containing_int, same_size_int, "");6610 try self.wip.cast(.trunc, containing_int, same_size_int, "");
6581 return self.wip.cast(.bitcast, truncated_int, elem_llvm_ty, "");6611 return self.wip.cast(.bitcast, truncated_int, elem_llvm_ty, "");
6582 } else if (field_ty.isPtrAtRuntime(mod)) {6612 } else if (field_ty.isPtrAtRuntime(mod)) {
6583 const same_size_int = try o.builder.intType(@intCast(field_ty.bitSize(mod)));6613 const same_size_int = try o.builder.intType(@intCast(field_ty.bitSize(pt)));
6584 const truncated_int =6614 const truncated_int =
6585 try self.wip.cast(.trunc, containing_int, same_size_int, "");6615 try self.wip.cast(.trunc, containing_int, same_size_int, "");
6586 return self.wip.cast(.inttoptr, truncated_int, elem_llvm_ty, "");6616 return self.wip.cast(.inttoptr, truncated_int, elem_llvm_ty, "");
...@@ -6599,12 +6629,12 @@ pub const FuncGen = struct {...@@ -6599,12 +6629,12 @@ pub const FuncGen = struct {
6599 const llvm_field_index = o.llvmFieldIndex(struct_ty, field_index).?;6629 const llvm_field_index = o.llvmFieldIndex(struct_ty, field_index).?;
6600 const field_ptr =6630 const field_ptr =
6601 try self.wip.gepStruct(struct_llvm_ty, struct_llvm_val, llvm_field_index, "");6631 try self.wip.gepStruct(struct_llvm_ty, struct_llvm_val, llvm_field_index, "");
6602 const alignment = struct_ty.structFieldAlign(field_index, mod);6632 const alignment = struct_ty.structFieldAlign(field_index, pt);
6603 const field_ptr_ty = try mod.ptrType(.{6633 const field_ptr_ty = try pt.ptrType(.{
6604 .child = field_ty.toIntern(),6634 .child = field_ty.toIntern(),
6605 .flags = .{ .alignment = alignment },6635 .flags = .{ .alignment = alignment },
6606 });6636 });
6607 if (isByRef(field_ty, mod)) {6637 if (isByRef(field_ty, pt)) {
6608 if (canElideLoad(self, body_tail))6638 if (canElideLoad(self, body_tail))
6609 return field_ptr;6639 return field_ptr;
66106640
...@@ -6617,12 +6647,12 @@ pub const FuncGen = struct {...@@ -6617,12 +6647,12 @@ pub const FuncGen = struct {
6617 },6647 },
6618 .Union => {6648 .Union => {
6619 const union_llvm_ty = try o.lowerType(struct_ty);6649 const union_llvm_ty = try o.lowerType(struct_ty);
6620 const layout = struct_ty.unionGetLayout(mod);6650 const layout = struct_ty.unionGetLayout(pt);
6621 const payload_index = @intFromBool(layout.tag_align.compare(.gte, layout.payload_align));6651 const payload_index = @intFromBool(layout.tag_align.compare(.gte, layout.payload_align));
6622 const field_ptr =6652 const field_ptr =
6623 try self.wip.gepStruct(union_llvm_ty, struct_llvm_val, payload_index, "");6653 try self.wip.gepStruct(union_llvm_ty, struct_llvm_val, payload_index, "");
6624 const payload_alignment = layout.payload_align.toLlvm();6654 const payload_alignment = layout.payload_align.toLlvm();
6625 if (isByRef(field_ty, mod)) {6655 if (isByRef(field_ty, pt)) {
6626 if (canElideLoad(self, body_tail)) return field_ptr;6656 if (canElideLoad(self, body_tail)) return field_ptr;
6627 return self.loadByRef(field_ptr, field_ty, payload_alignment, .normal);6657 return self.loadByRef(field_ptr, field_ty, payload_alignment, .normal);
6628 } else {6658 } else {
...@@ -6635,14 +6665,15 @@ pub const FuncGen = struct {...@@ -6635,14 +6665,15 @@ pub const FuncGen = struct {
66356665
6636 fn airFieldParentPtr(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {6666 fn airFieldParentPtr(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
6637 const o = self.dg.object;6667 const o = self.dg.object;
6638 const mod = o.module;6668 const pt = o.pt;
6669 const mod = pt.zcu;
6639 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;6670 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
6640 const extra = self.air.extraData(Air.FieldParentPtr, ty_pl.payload).data;6671 const extra = self.air.extraData(Air.FieldParentPtr, ty_pl.payload).data;
66416672
6642 const field_ptr = try self.resolveInst(extra.field_ptr);6673 const field_ptr = try self.resolveInst(extra.field_ptr);
66436674
6644 const parent_ty = ty_pl.ty.toType().childType(mod);6675 const parent_ty = ty_pl.ty.toType().childType(mod);
6645 const field_offset = parent_ty.structFieldOffset(extra.field_index, mod);6676 const field_offset = parent_ty.structFieldOffset(extra.field_index, pt);
6646 if (field_offset == 0) return field_ptr;6677 if (field_offset == 0) return field_ptr;
66476678
6648 const res_ty = try o.lowerType(ty_pl.ty.toType());6679 const res_ty = try o.lowerType(ty_pl.ty.toType());
...@@ -6696,7 +6727,7 @@ pub const FuncGen = struct {...@@ -6696,7 +6727,7 @@ pub const FuncGen = struct {
66966727
6697 fn airDbgVarPtr(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {6728 fn airDbgVarPtr(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
6698 const o = self.dg.object;6729 const o = self.dg.object;
6699 const mod = o.module;6730 const mod = o.pt.zcu;
6700 const pl_op = self.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;6731 const pl_op = self.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;
6701 const operand = try self.resolveInst(pl_op.operand);6732 const operand = try self.resolveInst(pl_op.operand);
6702 const name = self.air.nullTerminatedString(pl_op.payload);6733 const name = self.air.nullTerminatedString(pl_op.payload);
...@@ -6743,9 +6774,9 @@ pub const FuncGen = struct {...@@ -6743,9 +6774,9 @@ pub const FuncGen = struct {
6743 try o.lowerDebugType(operand_ty),6774 try o.lowerDebugType(operand_ty),
6744 );6775 );
67456776
6746 const zcu = o.module;6777 const pt = o.pt;
6747 const owner_mod = self.dg.ownerModule();6778 const owner_mod = self.dg.ownerModule();
6748 if (isByRef(operand_ty, zcu)) {6779 if (isByRef(operand_ty, pt)) {
6749 _ = try self.wip.callIntrinsic(6780 _ = try self.wip.callIntrinsic(
6750 .normal,6781 .normal,
6751 .none,6782 .none,
...@@ -6759,7 +6790,7 @@ pub const FuncGen = struct {...@@ -6759,7 +6790,7 @@ pub const FuncGen = struct {
6759 "",6790 "",
6760 );6791 );
6761 } else if (owner_mod.optimize_mode == .Debug) {6792 } else if (owner_mod.optimize_mode == .Debug) {
6762 const alignment = operand_ty.abiAlignment(zcu).toLlvm();6793 const alignment = operand_ty.abiAlignment(pt).toLlvm();
6763 const alloca = try self.buildAlloca(operand.typeOfWip(&self.wip), alignment);6794 const alloca = try self.buildAlloca(operand.typeOfWip(&self.wip), alignment);
6764 _ = try self.wip.store(.normal, operand, alloca, alignment);6795 _ = try self.wip.store(.normal, operand, alloca, alignment);
6765 _ = try self.wip.callIntrinsic(6796 _ = try self.wip.callIntrinsic(
...@@ -6830,7 +6861,8 @@ pub const FuncGen = struct {...@@ -6830,7 +6861,8 @@ pub const FuncGen = struct {
6830 // This stores whether we need to add an elementtype attribute and6861 // This stores whether we need to add an elementtype attribute and
6831 // if so, the element type itself.6862 // if so, the element type itself.
6832 const llvm_param_attrs = try arena.alloc(Builder.Type, max_param_count);6863 const llvm_param_attrs = try arena.alloc(Builder.Type, max_param_count);
6833 const mod = o.module;6864 const pt = o.pt;
6865 const mod = pt.zcu;
6834 const target = mod.getTarget();6866 const target = mod.getTarget();
68356867
6836 var llvm_ret_i: usize = 0;6868 var llvm_ret_i: usize = 0;
...@@ -6930,13 +6962,13 @@ pub const FuncGen = struct {...@@ -6930,13 +6962,13 @@ pub const FuncGen = struct {
69306962
6931 const arg_llvm_value = try self.resolveInst(input);6963 const arg_llvm_value = try self.resolveInst(input);
6932 const arg_ty = self.typeOf(input);6964 const arg_ty = self.typeOf(input);
6933 const is_by_ref = isByRef(arg_ty, mod);6965 const is_by_ref = isByRef(arg_ty, pt);
6934 if (is_by_ref) {6966 if (is_by_ref) {
6935 if (constraintAllowsMemory(constraint)) {6967 if (constraintAllowsMemory(constraint)) {
6936 llvm_param_values[llvm_param_i] = arg_llvm_value;6968 llvm_param_values[llvm_param_i] = arg_llvm_value;
6937 llvm_param_types[llvm_param_i] = arg_llvm_value.typeOfWip(&self.wip);6969 llvm_param_types[llvm_param_i] = arg_llvm_value.typeOfWip(&self.wip);
6938 } else {6970 } else {
6939 const alignment = arg_ty.abiAlignment(mod).toLlvm();6971 const alignment = arg_ty.abiAlignment(pt).toLlvm();
6940 const arg_llvm_ty = try o.lowerType(arg_ty);6972 const arg_llvm_ty = try o.lowerType(arg_ty);
6941 const load_inst =6973 const load_inst =
6942 try self.wip.load(.normal, arg_llvm_ty, arg_llvm_value, alignment, "");6974 try self.wip.load(.normal, arg_llvm_ty, arg_llvm_value, alignment, "");
...@@ -6948,7 +6980,7 @@ pub const FuncGen = struct {...@@ -6948,7 +6980,7 @@ pub const FuncGen = struct {
6948 llvm_param_values[llvm_param_i] = arg_llvm_value;6980 llvm_param_values[llvm_param_i] = arg_llvm_value;
6949 llvm_param_types[llvm_param_i] = arg_llvm_value.typeOfWip(&self.wip);6981 llvm_param_types[llvm_param_i] = arg_llvm_value.typeOfWip(&self.wip);
6950 } else {6982 } else {
6951 const alignment = arg_ty.abiAlignment(mod).toLlvm();6983 const alignment = arg_ty.abiAlignment(pt).toLlvm();
6952 const arg_ptr = try self.buildAlloca(arg_llvm_value.typeOfWip(&self.wip), alignment);6984 const arg_ptr = try self.buildAlloca(arg_llvm_value.typeOfWip(&self.wip), alignment);
6953 _ = try self.wip.store(.normal, arg_llvm_value, arg_ptr, alignment);6985 _ = try self.wip.store(.normal, arg_llvm_value, arg_ptr, alignment);
6954 llvm_param_values[llvm_param_i] = arg_ptr;6986 llvm_param_values[llvm_param_i] = arg_ptr;
...@@ -7000,7 +7032,7 @@ pub const FuncGen = struct {...@@ -7000,7 +7032,7 @@ pub const FuncGen = struct {
7000 llvm_param_values[llvm_param_i] = llvm_rw_val;7032 llvm_param_values[llvm_param_i] = llvm_rw_val;
7001 llvm_param_types[llvm_param_i] = llvm_rw_val.typeOfWip(&self.wip);7033 llvm_param_types[llvm_param_i] = llvm_rw_val.typeOfWip(&self.wip);
7002 } else {7034 } else {
7003 const alignment = rw_ty.abiAlignment(mod).toLlvm();7035 const alignment = rw_ty.abiAlignment(pt).toLlvm();
7004 const loaded = try self.wip.load(.normal, llvm_elem_ty, llvm_rw_val, alignment, "");7036 const loaded = try self.wip.load(.normal, llvm_elem_ty, llvm_rw_val, alignment, "");
7005 llvm_param_values[llvm_param_i] = loaded;7037 llvm_param_values[llvm_param_i] = loaded;
7006 llvm_param_types[llvm_param_i] = llvm_elem_ty;7038 llvm_param_types[llvm_param_i] = llvm_elem_ty;
...@@ -7161,7 +7193,7 @@ pub const FuncGen = struct {...@@ -7161,7 +7193,7 @@ pub const FuncGen = struct {
7161 const output_ptr = try self.resolveInst(output);7193 const output_ptr = try self.resolveInst(output);
7162 const output_ptr_ty = self.typeOf(output);7194 const output_ptr_ty = self.typeOf(output);
71637195
7164 const alignment = output_ptr_ty.ptrAlignment(mod).toLlvm();7196 const alignment = output_ptr_ty.ptrAlignment(pt).toLlvm();
7165 _ = try self.wip.store(.normal, output_value, output_ptr, alignment);7197 _ = try self.wip.store(.normal, output_value, output_ptr, alignment);
7166 } else {7198 } else {
7167 ret_val = output_value;7199 ret_val = output_value;
...@@ -7179,7 +7211,8 @@ pub const FuncGen = struct {...@@ -7179,7 +7211,8 @@ pub const FuncGen = struct {
7179 cond: Builder.IntegerCondition,7211 cond: Builder.IntegerCondition,
7180 ) !Builder.Value {7212 ) !Builder.Value {
7181 const o = self.dg.object;7213 const o = self.dg.object;
7182 const mod = o.module;7214 const pt = o.pt;
7215 const mod = pt.zcu;
7183 const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op;7216 const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op;
7184 const operand = try self.resolveInst(un_op);7217 const operand = try self.resolveInst(un_op);
7185 const operand_ty = self.typeOf(un_op);7218 const operand_ty = self.typeOf(un_op);
...@@ -7204,7 +7237,7 @@ pub const FuncGen = struct {...@@ -7204,7 +7237,7 @@ pub const FuncGen = struct {
72047237
7205 comptime assert(optional_layout_version == 3);7238 comptime assert(optional_layout_version == 3);
72067239
7207 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) {7240 if (!payload_ty.hasRuntimeBitsIgnoreComptime(pt)) {
7208 const loaded = if (operand_is_ptr)7241 const loaded = if (operand_is_ptr)
7209 try self.wip.load(.normal, optional_llvm_ty, operand, .default, "")7242 try self.wip.load(.normal, optional_llvm_ty, operand, .default, "")
7210 else7243 else
...@@ -7212,7 +7245,7 @@ pub const FuncGen = struct {...@@ -7212,7 +7245,7 @@ pub const FuncGen = struct {
7212 return self.wip.icmp(cond, loaded, try o.builder.intValue(.i8, 0), "");7245 return self.wip.icmp(cond, loaded, try o.builder.intValue(.i8, 0), "");
7213 }7246 }
72147247
7215 const is_by_ref = operand_is_ptr or isByRef(optional_ty, mod);7248 const is_by_ref = operand_is_ptr or isByRef(optional_ty, pt);
7216 return self.optCmpNull(cond, optional_llvm_ty, operand, is_by_ref);7249 return self.optCmpNull(cond, optional_llvm_ty, operand, is_by_ref);
7217 }7250 }
72187251
...@@ -7223,7 +7256,8 @@ pub const FuncGen = struct {...@@ -7223,7 +7256,8 @@ pub const FuncGen = struct {
7223 operand_is_ptr: bool,7256 operand_is_ptr: bool,
7224 ) !Builder.Value {7257 ) !Builder.Value {
7225 const o = self.dg.object;7258 const o = self.dg.object;
7226 const mod = o.module;7259 const pt = o.pt;
7260 const mod = pt.zcu;
7227 const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op;7261 const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op;
7228 const operand = try self.resolveInst(un_op);7262 const operand = try self.resolveInst(un_op);
7229 const operand_ty = self.typeOf(un_op);7263 const operand_ty = self.typeOf(un_op);
...@@ -7241,7 +7275,7 @@ pub const FuncGen = struct {...@@ -7241,7 +7275,7 @@ pub const FuncGen = struct {
7241 return val.toValue();7275 return val.toValue();
7242 }7276 }
72437277
7244 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) {7278 if (!payload_ty.hasRuntimeBitsIgnoreComptime(pt)) {
7245 const loaded = if (operand_is_ptr)7279 const loaded = if (operand_is_ptr)
7246 try self.wip.load(.normal, try o.lowerType(err_union_ty), operand, .default, "")7280 try self.wip.load(.normal, try o.lowerType(err_union_ty), operand, .default, "")
7247 else7281 else
...@@ -7249,9 +7283,9 @@ pub const FuncGen = struct {...@@ -7249,9 +7283,9 @@ pub const FuncGen = struct {
7249 return self.wip.icmp(cond, loaded, zero, "");7283 return self.wip.icmp(cond, loaded, zero, "");
7250 }7284 }
72517285
7252 const err_field_index = try errUnionErrorOffset(payload_ty, mod);7286 const err_field_index = try errUnionErrorOffset(payload_ty, pt);
72537287
7254 const loaded = if (operand_is_ptr or isByRef(err_union_ty, mod)) loaded: {7288 const loaded = if (operand_is_ptr or isByRef(err_union_ty, pt)) loaded: {
7255 const err_union_llvm_ty = try o.lowerType(err_union_ty);7289 const err_union_llvm_ty = try o.lowerType(err_union_ty);
7256 const err_field_ptr =7290 const err_field_ptr =
7257 try self.wip.gepStruct(err_union_llvm_ty, operand, err_field_index, "");7291 try self.wip.gepStruct(err_union_llvm_ty, operand, err_field_index, "");
...@@ -7262,12 +7296,13 @@ pub const FuncGen = struct {...@@ -7262,12 +7296,13 @@ pub const FuncGen = struct {
72627296
7263 fn airOptionalPayloadPtr(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {7297 fn airOptionalPayloadPtr(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
7264 const o = self.dg.object;7298 const o = self.dg.object;
7265 const mod = o.module;7299 const pt = o.pt;
7300 const mod = pt.zcu;
7266 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;7301 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
7267 const operand = try self.resolveInst(ty_op.operand);7302 const operand = try self.resolveInst(ty_op.operand);
7268 const optional_ty = self.typeOf(ty_op.operand).childType(mod);7303 const optional_ty = self.typeOf(ty_op.operand).childType(mod);
7269 const payload_ty = optional_ty.optionalChild(mod);7304 const payload_ty = optional_ty.optionalChild(mod);
7270 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) {7305 if (!payload_ty.hasRuntimeBitsIgnoreComptime(pt)) {
7271 // We have a pointer to a zero-bit value and we need to return7306 // We have a pointer to a zero-bit value and we need to return
7272 // a pointer to a zero-bit value.7307 // a pointer to a zero-bit value.
7273 return operand;7308 return operand;
...@@ -7283,13 +7318,14 @@ pub const FuncGen = struct {...@@ -7283,13 +7318,14 @@ pub const FuncGen = struct {
7283 comptime assert(optional_layout_version == 3);7318 comptime assert(optional_layout_version == 3);
72847319
7285 const o = self.dg.object;7320 const o = self.dg.object;
7286 const mod = o.module;7321 const pt = o.pt;
7322 const mod = pt.zcu;
7287 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;7323 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
7288 const operand = try self.resolveInst(ty_op.operand);7324 const operand = try self.resolveInst(ty_op.operand);
7289 const optional_ty = self.typeOf(ty_op.operand).childType(mod);7325 const optional_ty = self.typeOf(ty_op.operand).childType(mod);
7290 const payload_ty = optional_ty.optionalChild(mod);7326 const payload_ty = optional_ty.optionalChild(mod);
7291 const non_null_bit = try o.builder.intValue(.i8, 1);7327 const non_null_bit = try o.builder.intValue(.i8, 1);
7292 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) {7328 if (!payload_ty.hasRuntimeBitsIgnoreComptime(pt)) {
7293 // We have a pointer to a i8. We need to set it to 1 and then return the same pointer.7329 // We have a pointer to a i8. We need to set it to 1 and then return the same pointer.
7294 _ = try self.wip.store(.normal, non_null_bit, operand, .default);7330 _ = try self.wip.store(.normal, non_null_bit, operand, .default);
7295 return operand;7331 return operand;
...@@ -7314,13 +7350,14 @@ pub const FuncGen = struct {...@@ -7314,13 +7350,14 @@ pub const FuncGen = struct {
73147350
7315 fn airOptionalPayload(self: *FuncGen, body_tail: []const Air.Inst.Index) !Builder.Value {7351 fn airOptionalPayload(self: *FuncGen, body_tail: []const Air.Inst.Index) !Builder.Value {
7316 const o = self.dg.object;7352 const o = self.dg.object;
7317 const mod = o.module;7353 const pt = o.pt;
7354 const mod = pt.zcu;
7318 const inst = body_tail[0];7355 const inst = body_tail[0];
7319 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;7356 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
7320 const operand = try self.resolveInst(ty_op.operand);7357 const operand = try self.resolveInst(ty_op.operand);
7321 const optional_ty = self.typeOf(ty_op.operand);7358 const optional_ty = self.typeOf(ty_op.operand);
7322 const payload_ty = self.typeOfIndex(inst);7359 const payload_ty = self.typeOfIndex(inst);
7323 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) return .none;7360 if (!payload_ty.hasRuntimeBitsIgnoreComptime(pt)) return .none;
73247361
7325 if (optional_ty.optionalReprIsPayload(mod)) {7362 if (optional_ty.optionalReprIsPayload(mod)) {
7326 // Payload value is the same as the optional value.7363 // Payload value is the same as the optional value.
...@@ -7328,7 +7365,7 @@ pub const FuncGen = struct {...@@ -7328,7 +7365,7 @@ pub const FuncGen = struct {
7328 }7365 }
73297366
7330 const opt_llvm_ty = try o.lowerType(optional_ty);7367 const opt_llvm_ty = try o.lowerType(optional_ty);
7331 const can_elide_load = if (isByRef(payload_ty, mod)) self.canElideLoad(body_tail) else false;7368 const can_elide_load = if (isByRef(payload_ty, pt)) self.canElideLoad(body_tail) else false;
7332 return self.optPayloadHandle(opt_llvm_ty, operand, optional_ty, can_elide_load);7369 return self.optPayloadHandle(opt_llvm_ty, operand, optional_ty, can_elide_load);
7333 }7370 }
73347371
...@@ -7338,7 +7375,8 @@ pub const FuncGen = struct {...@@ -7338,7 +7375,8 @@ pub const FuncGen = struct {
7338 operand_is_ptr: bool,7375 operand_is_ptr: bool,
7339 ) !Builder.Value {7376 ) !Builder.Value {
7340 const o = self.dg.object;7377 const o = self.dg.object;
7341 const mod = o.module;7378 const pt = o.pt;
7379 const mod = pt.zcu;
7342 const inst = body_tail[0];7380 const inst = body_tail[0];
7343 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;7381 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
7344 const operand = try self.resolveInst(ty_op.operand);7382 const operand = try self.resolveInst(ty_op.operand);
...@@ -7347,17 +7385,17 @@ pub const FuncGen = struct {...@@ -7347,17 +7385,17 @@ pub const FuncGen = struct {
7347 const result_ty = self.typeOfIndex(inst);7385 const result_ty = self.typeOfIndex(inst);
7348 const payload_ty = if (operand_is_ptr) result_ty.childType(mod) else result_ty;7386 const payload_ty = if (operand_is_ptr) result_ty.childType(mod) else result_ty;
73497387
7350 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) {7388 if (!payload_ty.hasRuntimeBitsIgnoreComptime(pt)) {
7351 return if (operand_is_ptr) operand else .none;7389 return if (operand_is_ptr) operand else .none;
7352 }7390 }
7353 const offset = try errUnionPayloadOffset(payload_ty, mod);7391 const offset = try errUnionPayloadOffset(payload_ty, pt);
7354 const err_union_llvm_ty = try o.lowerType(err_union_ty);7392 const err_union_llvm_ty = try o.lowerType(err_union_ty);
7355 if (operand_is_ptr) {7393 if (operand_is_ptr) {
7356 return self.wip.gepStruct(err_union_llvm_ty, operand, offset, "");7394 return self.wip.gepStruct(err_union_llvm_ty, operand, offset, "");
7357 } else if (isByRef(err_union_ty, mod)) {7395 } else if (isByRef(err_union_ty, pt)) {
7358 const payload_alignment = payload_ty.abiAlignment(mod).toLlvm();7396 const payload_alignment = payload_ty.abiAlignment(pt).toLlvm();
7359 const payload_ptr = try self.wip.gepStruct(err_union_llvm_ty, operand, offset, "");7397 const payload_ptr = try self.wip.gepStruct(err_union_llvm_ty, operand, offset, "");
7360 if (isByRef(payload_ty, mod)) {7398 if (isByRef(payload_ty, pt)) {
7361 if (self.canElideLoad(body_tail)) return payload_ptr;7399 if (self.canElideLoad(body_tail)) return payload_ptr;
7362 return self.loadByRef(payload_ptr, payload_ty, payload_alignment, .normal);7400 return self.loadByRef(payload_ptr, payload_ty, payload_alignment, .normal);
7363 }7401 }
...@@ -7373,7 +7411,8 @@ pub const FuncGen = struct {...@@ -7373,7 +7411,8 @@ pub const FuncGen = struct {
7373 operand_is_ptr: bool,7411 operand_is_ptr: bool,
7374 ) !Builder.Value {7412 ) !Builder.Value {
7375 const o = self.dg.object;7413 const o = self.dg.object;
7376 const mod = o.module;7414 const pt = o.pt;
7415 const mod = pt.zcu;
7377 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;7416 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
7378 const operand = try self.resolveInst(ty_op.operand);7417 const operand = try self.resolveInst(ty_op.operand);
7379 const operand_ty = self.typeOf(ty_op.operand);7418 const operand_ty = self.typeOf(ty_op.operand);
...@@ -7388,14 +7427,14 @@ pub const FuncGen = struct {...@@ -7388,14 +7427,14 @@ pub const FuncGen = struct {
7388 }7427 }
73897428
7390 const payload_ty = err_union_ty.errorUnionPayload(mod);7429 const payload_ty = err_union_ty.errorUnionPayload(mod);
7391 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) {7430 if (!payload_ty.hasRuntimeBitsIgnoreComptime(pt)) {
7392 if (!operand_is_ptr) return operand;7431 if (!operand_is_ptr) return operand;
7393 return self.wip.load(.normal, error_type, operand, .default, "");7432 return self.wip.load(.normal, error_type, operand, .default, "");
7394 }7433 }
73957434
7396 const offset = try errUnionErrorOffset(payload_ty, mod);7435 const offset = try errUnionErrorOffset(payload_ty, pt);
73977436
7398 if (operand_is_ptr or isByRef(err_union_ty, mod)) {7437 if (operand_is_ptr or isByRef(err_union_ty, pt)) {
7399 const err_union_llvm_ty = try o.lowerType(err_union_ty);7438 const err_union_llvm_ty = try o.lowerType(err_union_ty);
7400 const err_field_ptr = try self.wip.gepStruct(err_union_llvm_ty, operand, offset, "");7439 const err_field_ptr = try self.wip.gepStruct(err_union_llvm_ty, operand, offset, "");
7401 return self.wip.load(.normal, error_type, err_field_ptr, .default, "");7440 return self.wip.load(.normal, error_type, err_field_ptr, .default, "");
...@@ -7406,22 +7445,23 @@ pub const FuncGen = struct {...@@ -7406,22 +7445,23 @@ pub const FuncGen = struct {
74067445
7407 fn airErrUnionPayloadPtrSet(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {7446 fn airErrUnionPayloadPtrSet(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
7408 const o = self.dg.object;7447 const o = self.dg.object;
7409 const mod = o.module;7448 const pt = o.pt;
7449 const mod = pt.zcu;
7410 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;7450 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
7411 const operand = try self.resolveInst(ty_op.operand);7451 const operand = try self.resolveInst(ty_op.operand);
7412 const err_union_ty = self.typeOf(ty_op.operand).childType(mod);7452 const err_union_ty = self.typeOf(ty_op.operand).childType(mod);
74137453
7414 const payload_ty = err_union_ty.errorUnionPayload(mod);7454 const payload_ty = err_union_ty.errorUnionPayload(mod);
7415 const non_error_val = try o.builder.intValue(try o.errorIntType(), 0);7455 const non_error_val = try o.builder.intValue(try o.errorIntType(), 0);
7416 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) {7456 if (!payload_ty.hasRuntimeBitsIgnoreComptime(pt)) {
7417 _ = try self.wip.store(.normal, non_error_val, operand, .default);7457 _ = try self.wip.store(.normal, non_error_val, operand, .default);
7418 return operand;7458 return operand;
7419 }7459 }
7420 const err_union_llvm_ty = try o.lowerType(err_union_ty);7460 const err_union_llvm_ty = try o.lowerType(err_union_ty);
7421 {7461 {
7422 const err_int_ty = try mod.errorIntType();7462 const err_int_ty = try pt.errorIntType();
7423 const error_alignment = err_int_ty.abiAlignment(mod).toLlvm();7463 const error_alignment = err_int_ty.abiAlignment(pt).toLlvm();
7424 const error_offset = try errUnionErrorOffset(payload_ty, mod);7464 const error_offset = try errUnionErrorOffset(payload_ty, pt);
7425 // First set the non-error value.7465 // First set the non-error value.
7426 const non_null_ptr = try self.wip.gepStruct(err_union_llvm_ty, operand, error_offset, "");7466 const non_null_ptr = try self.wip.gepStruct(err_union_llvm_ty, operand, error_offset, "");
7427 _ = try self.wip.store(.normal, non_error_val, non_null_ptr, error_alignment);7467 _ = try self.wip.store(.normal, non_error_val, non_null_ptr, error_alignment);
...@@ -7429,7 +7469,7 @@ pub const FuncGen = struct {...@@ -7429,7 +7469,7 @@ pub const FuncGen = struct {
7429 // Then return the payload pointer (only if it is used).7469 // Then return the payload pointer (only if it is used).
7430 if (self.liveness.isUnused(inst)) return .none;7470 if (self.liveness.isUnused(inst)) return .none;
74317471
7432 const payload_offset = try errUnionPayloadOffset(payload_ty, mod);7472 const payload_offset = try errUnionPayloadOffset(payload_ty, pt);
7433 return self.wip.gepStruct(err_union_llvm_ty, operand, payload_offset, "");7473 return self.wip.gepStruct(err_union_llvm_ty, operand, payload_offset, "");
7434 }7474 }
74357475
...@@ -7446,19 +7486,21 @@ pub const FuncGen = struct {...@@ -7446,19 +7486,21 @@ pub const FuncGen = struct {
74467486
7447 fn airSaveErrReturnTraceIndex(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {7487 fn airSaveErrReturnTraceIndex(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
7448 const o = self.dg.object;7488 const o = self.dg.object;
7489 const pt = o.pt;
7490 const mod = pt.zcu;
7491
7449 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;7492 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
7450 const struct_ty = ty_pl.ty.toType();7493 const struct_ty = ty_pl.ty.toType();
7451 const field_index = ty_pl.payload;7494 const field_index = ty_pl.payload;
74527495
7453 const mod = o.module;
7454 const struct_llvm_ty = try o.lowerType(struct_ty);7496 const struct_llvm_ty = try o.lowerType(struct_ty);
7455 const llvm_field_index = o.llvmFieldIndex(struct_ty, field_index).?;7497 const llvm_field_index = o.llvmFieldIndex(struct_ty, field_index).?;
7456 assert(self.err_ret_trace != .none);7498 assert(self.err_ret_trace != .none);
7457 const field_ptr =7499 const field_ptr =
7458 try self.wip.gepStruct(struct_llvm_ty, self.err_ret_trace, llvm_field_index, "");7500 try self.wip.gepStruct(struct_llvm_ty, self.err_ret_trace, llvm_field_index, "");
7459 const field_alignment = struct_ty.structFieldAlign(field_index, mod);7501 const field_alignment = struct_ty.structFieldAlign(field_index, pt);
7460 const field_ty = struct_ty.structFieldType(field_index, mod);7502 const field_ty = struct_ty.structFieldType(field_index, mod);
7461 const field_ptr_ty = try mod.ptrType(.{7503 const field_ptr_ty = try pt.ptrType(.{
7462 .child = field_ty.toIntern(),7504 .child = field_ty.toIntern(),
7463 .flags = .{ .alignment = field_alignment },7505 .flags = .{ .alignment = field_alignment },
7464 });7506 });
...@@ -7490,29 +7532,30 @@ pub const FuncGen = struct {...@@ -7490,29 +7532,30 @@ pub const FuncGen = struct {
74907532
7491 fn airWrapOptional(self: *FuncGen, body_tail: []const Air.Inst.Index) !Builder.Value {7533 fn airWrapOptional(self: *FuncGen, body_tail: []const Air.Inst.Index) !Builder.Value {
7492 const o = self.dg.object;7534 const o = self.dg.object;
7493 const mod = o.module;7535 const pt = o.pt;
7536 const mod = pt.zcu;
7494 const inst = body_tail[0];7537 const inst = body_tail[0];
7495 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;7538 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
7496 const payload_ty = self.typeOf(ty_op.operand);7539 const payload_ty = self.typeOf(ty_op.operand);
7497 const non_null_bit = try o.builder.intValue(.i8, 1);7540 const non_null_bit = try o.builder.intValue(.i8, 1);
7498 comptime assert(optional_layout_version == 3);7541 comptime assert(optional_layout_version == 3);
7499 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) return non_null_bit;7542 if (!payload_ty.hasRuntimeBitsIgnoreComptime(pt)) return non_null_bit;
7500 const operand = try self.resolveInst(ty_op.operand);7543 const operand = try self.resolveInst(ty_op.operand);
7501 const optional_ty = self.typeOfIndex(inst);7544 const optional_ty = self.typeOfIndex(inst);
7502 if (optional_ty.optionalReprIsPayload(mod)) return operand;7545 if (optional_ty.optionalReprIsPayload(mod)) return operand;
7503 const llvm_optional_ty = try o.lowerType(optional_ty);7546 const llvm_optional_ty = try o.lowerType(optional_ty);
7504 if (isByRef(optional_ty, mod)) {7547 if (isByRef(optional_ty, pt)) {
7505 const directReturn = self.isNextRet(body_tail);7548 const directReturn = self.isNextRet(body_tail);
7506 const optional_ptr = if (directReturn)7549 const optional_ptr = if (directReturn)
7507 self.ret_ptr7550 self.ret_ptr
7508 else brk: {7551 else brk: {
7509 const alignment = optional_ty.abiAlignment(mod).toLlvm();7552 const alignment = optional_ty.abiAlignment(pt).toLlvm();
7510 const optional_ptr = try self.buildAllocaWorkaround(optional_ty, alignment);7553 const optional_ptr = try self.buildAllocaWorkaround(optional_ty, alignment);
7511 break :brk optional_ptr;7554 break :brk optional_ptr;
7512 };7555 };
75137556
7514 const payload_ptr = try self.wip.gepStruct(llvm_optional_ty, optional_ptr, 0, "");7557 const payload_ptr = try self.wip.gepStruct(llvm_optional_ty, optional_ptr, 0, "");
7515 const payload_ptr_ty = try mod.singleMutPtrType(payload_ty);7558 const payload_ptr_ty = try pt.singleMutPtrType(payload_ty);
7516 try self.store(payload_ptr, payload_ptr_ty, operand, .none);7559 try self.store(payload_ptr, payload_ptr_ty, operand, .none);
7517 const non_null_ptr = try self.wip.gepStruct(llvm_optional_ty, optional_ptr, 1, "");7560 const non_null_ptr = try self.wip.gepStruct(llvm_optional_ty, optional_ptr, 1, "");
7518 _ = try self.wip.store(.normal, non_null_bit, non_null_ptr, .default);7561 _ = try self.wip.store(.normal, non_null_bit, non_null_ptr, .default);
...@@ -7523,36 +7566,36 @@ pub const FuncGen = struct {...@@ -7523,36 +7566,36 @@ pub const FuncGen = struct {
75237566
7524 fn airWrapErrUnionPayload(self: *FuncGen, body_tail: []const Air.Inst.Index) !Builder.Value {7567 fn airWrapErrUnionPayload(self: *FuncGen, body_tail: []const Air.Inst.Index) !Builder.Value {
7525 const o = self.dg.object;7568 const o = self.dg.object;
7526 const mod = o.module;7569 const pt = o.pt;
7527 const inst = body_tail[0];7570 const inst = body_tail[0];
7528 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;7571 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
7529 const err_un_ty = self.typeOfIndex(inst);7572 const err_un_ty = self.typeOfIndex(inst);
7530 const operand = try self.resolveInst(ty_op.operand);7573 const operand = try self.resolveInst(ty_op.operand);
7531 const payload_ty = self.typeOf(ty_op.operand);7574 const payload_ty = self.typeOf(ty_op.operand);
7532 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) {7575 if (!payload_ty.hasRuntimeBitsIgnoreComptime(pt)) {
7533 return operand;7576 return operand;
7534 }7577 }
7535 const ok_err_code = try o.builder.intValue(try o.errorIntType(), 0);7578 const ok_err_code = try o.builder.intValue(try o.errorIntType(), 0);
7536 const err_un_llvm_ty = try o.lowerType(err_un_ty);7579 const err_un_llvm_ty = try o.lowerType(err_un_ty);
75377580
7538 const payload_offset = try errUnionPayloadOffset(payload_ty, mod);7581 const payload_offset = try errUnionPayloadOffset(payload_ty, pt);
7539 const error_offset = try errUnionErrorOffset(payload_ty, mod);7582 const error_offset = try errUnionErrorOffset(payload_ty, pt);
7540 if (isByRef(err_un_ty, mod)) {7583 if (isByRef(err_un_ty, pt)) {
7541 const directReturn = self.isNextRet(body_tail);7584 const directReturn = self.isNextRet(body_tail);
7542 const result_ptr = if (directReturn)7585 const result_ptr = if (directReturn)
7543 self.ret_ptr7586 self.ret_ptr
7544 else brk: {7587 else brk: {
7545 const alignment = err_un_ty.abiAlignment(mod).toLlvm();7588 const alignment = err_un_ty.abiAlignment(pt).toLlvm();
7546 const result_ptr = try self.buildAllocaWorkaround(err_un_ty, alignment);7589 const result_ptr = try self.buildAllocaWorkaround(err_un_ty, alignment);
7547 break :brk result_ptr;7590 break :brk result_ptr;
7548 };7591 };
75497592
7550 const err_ptr = try self.wip.gepStruct(err_un_llvm_ty, result_ptr, error_offset, "");7593 const err_ptr = try self.wip.gepStruct(err_un_llvm_ty, result_ptr, error_offset, "");
7551 const err_int_ty = try mod.errorIntType();7594 const err_int_ty = try pt.errorIntType();
7552 const error_alignment = err_int_ty.abiAlignment(mod).toLlvm();7595 const error_alignment = err_int_ty.abiAlignment(pt).toLlvm();
7553 _ = try self.wip.store(.normal, ok_err_code, err_ptr, error_alignment);7596 _ = try self.wip.store(.normal, ok_err_code, err_ptr, error_alignment);
7554 const payload_ptr = try self.wip.gepStruct(err_un_llvm_ty, result_ptr, payload_offset, "");7597 const payload_ptr = try self.wip.gepStruct(err_un_llvm_ty, result_ptr, payload_offset, "");
7555 const payload_ptr_ty = try mod.singleMutPtrType(payload_ty);7598 const payload_ptr_ty = try pt.singleMutPtrType(payload_ty);
7556 try self.store(payload_ptr, payload_ptr_ty, operand, .none);7599 try self.store(payload_ptr, payload_ptr_ty, operand, .none);
7557 return result_ptr;7600 return result_ptr;
7558 }7601 }
...@@ -7564,33 +7607,34 @@ pub const FuncGen = struct {...@@ -7564,33 +7607,34 @@ pub const FuncGen = struct {
75647607
7565 fn airWrapErrUnionErr(self: *FuncGen, body_tail: []const Air.Inst.Index) !Builder.Value {7608 fn airWrapErrUnionErr(self: *FuncGen, body_tail: []const Air.Inst.Index) !Builder.Value {
7566 const o = self.dg.object;7609 const o = self.dg.object;
7567 const mod = o.module;7610 const pt = o.pt;
7611 const mod = pt.zcu;
7568 const inst = body_tail[0];7612 const inst = body_tail[0];
7569 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;7613 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
7570 const err_un_ty = self.typeOfIndex(inst);7614 const err_un_ty = self.typeOfIndex(inst);
7571 const payload_ty = err_un_ty.errorUnionPayload(mod);7615 const payload_ty = err_un_ty.errorUnionPayload(mod);
7572 const operand = try self.resolveInst(ty_op.operand);7616 const operand = try self.resolveInst(ty_op.operand);
7573 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) return operand;7617 if (!payload_ty.hasRuntimeBitsIgnoreComptime(pt)) return operand;
7574 const err_un_llvm_ty = try o.lowerType(err_un_ty);7618 const err_un_llvm_ty = try o.lowerType(err_un_ty);
75757619
7576 const payload_offset = try errUnionPayloadOffset(payload_ty, mod);7620 const payload_offset = try errUnionPayloadOffset(payload_ty, pt);
7577 const error_offset = try errUnionErrorOffset(payload_ty, mod);7621 const error_offset = try errUnionErrorOffset(payload_ty, pt);
7578 if (isByRef(err_un_ty, mod)) {7622 if (isByRef(err_un_ty, pt)) {
7579 const directReturn = self.isNextRet(body_tail);7623 const directReturn = self.isNextRet(body_tail);
7580 const result_ptr = if (directReturn)7624 const result_ptr = if (directReturn)
7581 self.ret_ptr7625 self.ret_ptr
7582 else brk: {7626 else brk: {
7583 const alignment = err_un_ty.abiAlignment(mod).toLlvm();7627 const alignment = err_un_ty.abiAlignment(pt).toLlvm();
7584 const result_ptr = try self.buildAllocaWorkaround(err_un_ty, alignment);7628 const result_ptr = try self.buildAllocaWorkaround(err_un_ty, alignment);
7585 break :brk result_ptr;7629 break :brk result_ptr;
7586 };7630 };
75877631
7588 const err_ptr = try self.wip.gepStruct(err_un_llvm_ty, result_ptr, error_offset, "");7632 const err_ptr = try self.wip.gepStruct(err_un_llvm_ty, result_ptr, error_offset, "");
7589 const err_int_ty = try mod.errorIntType();7633 const err_int_ty = try pt.errorIntType();
7590 const error_alignment = err_int_ty.abiAlignment(mod).toLlvm();7634 const error_alignment = err_int_ty.abiAlignment(pt).toLlvm();
7591 _ = try self.wip.store(.normal, operand, err_ptr, error_alignment);7635 _ = try self.wip.store(.normal, operand, err_ptr, error_alignment);
7592 const payload_ptr = try self.wip.gepStruct(err_un_llvm_ty, result_ptr, payload_offset, "");7636 const payload_ptr = try self.wip.gepStruct(err_un_llvm_ty, result_ptr, payload_offset, "");
7593 const payload_ptr_ty = try mod.singleMutPtrType(payload_ty);7637 const payload_ptr_ty = try pt.singleMutPtrType(payload_ty);
7594 // TODO store undef to payload_ptr7638 // TODO store undef to payload_ptr
7595 _ = payload_ptr;7639 _ = payload_ptr;
7596 _ = payload_ptr_ty;7640 _ = payload_ptr_ty;
...@@ -7624,7 +7668,8 @@ pub const FuncGen = struct {...@@ -7624,7 +7668,8 @@ pub const FuncGen = struct {
76247668
7625 fn airVectorStoreElem(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {7669 fn airVectorStoreElem(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
7626 const o = self.dg.object;7670 const o = self.dg.object;
7627 const mod = o.module;7671 const pt = o.pt;
7672 const mod = pt.zcu;
7628 const data = self.air.instructions.items(.data)[@intFromEnum(inst)].vector_store_elem;7673 const data = self.air.instructions.items(.data)[@intFromEnum(inst)].vector_store_elem;
7629 const extra = self.air.extraData(Air.Bin, data.payload).data;7674 const extra = self.air.extraData(Air.Bin, data.payload).data;
76307675
...@@ -7636,7 +7681,7 @@ pub const FuncGen = struct {...@@ -7636,7 +7681,7 @@ pub const FuncGen = struct {
7636 const access_kind: Builder.MemoryAccessKind =7681 const access_kind: Builder.MemoryAccessKind =
7637 if (vector_ptr_ty.isVolatilePtr(mod)) .@"volatile" else .normal;7682 if (vector_ptr_ty.isVolatilePtr(mod)) .@"volatile" else .normal;
7638 const elem_llvm_ty = try o.lowerType(vector_ptr_ty.childType(mod));7683 const elem_llvm_ty = try o.lowerType(vector_ptr_ty.childType(mod));
7639 const alignment = vector_ptr_ty.ptrAlignment(mod).toLlvm();7684 const alignment = vector_ptr_ty.ptrAlignment(pt).toLlvm();
7640 const loaded = try self.wip.load(access_kind, elem_llvm_ty, vector_ptr, alignment, "");7685 const loaded = try self.wip.load(access_kind, elem_llvm_ty, vector_ptr, alignment, "");
76417686
7642 const new_vector = try self.wip.insertElement(loaded, operand, index, "");7687 const new_vector = try self.wip.insertElement(loaded, operand, index, "");
...@@ -7646,7 +7691,7 @@ pub const FuncGen = struct {...@@ -7646,7 +7691,7 @@ pub const FuncGen = struct {
76467691
7647 fn airMin(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {7692 fn airMin(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
7648 const o = self.dg.object;7693 const o = self.dg.object;
7649 const mod = o.module;7694 const mod = o.pt.zcu;
7650 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;7695 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
7651 const lhs = try self.resolveInst(bin_op.lhs);7696 const lhs = try self.resolveInst(bin_op.lhs);
7652 const rhs = try self.resolveInst(bin_op.rhs);7697 const rhs = try self.resolveInst(bin_op.rhs);
...@@ -7666,7 +7711,7 @@ pub const FuncGen = struct {...@@ -7666,7 +7711,7 @@ pub const FuncGen = struct {
76667711
7667 fn airMax(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {7712 fn airMax(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
7668 const o = self.dg.object;7713 const o = self.dg.object;
7669 const mod = o.module;7714 const mod = o.pt.zcu;
7670 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;7715 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
7671 const lhs = try self.resolveInst(bin_op.lhs);7716 const lhs = try self.resolveInst(bin_op.lhs);
7672 const rhs = try self.resolveInst(bin_op.rhs);7717 const rhs = try self.resolveInst(bin_op.rhs);
...@@ -7696,7 +7741,7 @@ pub const FuncGen = struct {...@@ -7696,7 +7741,7 @@ pub const FuncGen = struct {
76967741
7697 fn airAdd(self: *FuncGen, inst: Air.Inst.Index, fast: Builder.FastMathKind) !Builder.Value {7742 fn airAdd(self: *FuncGen, inst: Air.Inst.Index, fast: Builder.FastMathKind) !Builder.Value {
7698 const o = self.dg.object;7743 const o = self.dg.object;
7699 const mod = o.module;7744 const mod = o.pt.zcu;
7700 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;7745 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
7701 const lhs = try self.resolveInst(bin_op.lhs);7746 const lhs = try self.resolveInst(bin_op.lhs);
7702 const rhs = try self.resolveInst(bin_op.rhs);7747 const rhs = try self.resolveInst(bin_op.rhs);
...@@ -7714,7 +7759,7 @@ pub const FuncGen = struct {...@@ -7714,7 +7759,7 @@ pub const FuncGen = struct {
7714 unsigned_intrinsic: Builder.Intrinsic,7759 unsigned_intrinsic: Builder.Intrinsic,
7715 ) !Builder.Value {7760 ) !Builder.Value {
7716 const o = fg.dg.object;7761 const o = fg.dg.object;
7717 const mod = o.module;7762 const mod = o.pt.zcu;
77187763
7719 const bin_op = fg.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;7764 const bin_op = fg.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
7720 const lhs = try fg.resolveInst(bin_op.lhs);7765 const lhs = try fg.resolveInst(bin_op.lhs);
...@@ -7762,7 +7807,7 @@ pub const FuncGen = struct {...@@ -7762,7 +7807,7 @@ pub const FuncGen = struct {
77627807
7763 fn airAddSat(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {7808 fn airAddSat(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
7764 const o = self.dg.object;7809 const o = self.dg.object;
7765 const mod = o.module;7810 const mod = o.pt.zcu;
7766 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;7811 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
7767 const lhs = try self.resolveInst(bin_op.lhs);7812 const lhs = try self.resolveInst(bin_op.lhs);
7768 const rhs = try self.resolveInst(bin_op.rhs);7813 const rhs = try self.resolveInst(bin_op.rhs);
...@@ -7782,7 +7827,7 @@ pub const FuncGen = struct {...@@ -7782,7 +7827,7 @@ pub const FuncGen = struct {
77827827
7783 fn airSub(self: *FuncGen, inst: Air.Inst.Index, fast: Builder.FastMathKind) !Builder.Value {7828 fn airSub(self: *FuncGen, inst: Air.Inst.Index, fast: Builder.FastMathKind) !Builder.Value {
7784 const o = self.dg.object;7829 const o = self.dg.object;
7785 const mod = o.module;7830 const mod = o.pt.zcu;
7786 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;7831 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
7787 const lhs = try self.resolveInst(bin_op.lhs);7832 const lhs = try self.resolveInst(bin_op.lhs);
7788 const rhs = try self.resolveInst(bin_op.rhs);7833 const rhs = try self.resolveInst(bin_op.rhs);
...@@ -7803,7 +7848,7 @@ pub const FuncGen = struct {...@@ -7803,7 +7848,7 @@ pub const FuncGen = struct {
78037848
7804 fn airSubSat(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {7849 fn airSubSat(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
7805 const o = self.dg.object;7850 const o = self.dg.object;
7806 const mod = o.module;7851 const mod = o.pt.zcu;
7807 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;7852 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
7808 const lhs = try self.resolveInst(bin_op.lhs);7853 const lhs = try self.resolveInst(bin_op.lhs);
7809 const rhs = try self.resolveInst(bin_op.rhs);7854 const rhs = try self.resolveInst(bin_op.rhs);
...@@ -7823,7 +7868,7 @@ pub const FuncGen = struct {...@@ -7823,7 +7868,7 @@ pub const FuncGen = struct {
78237868
7824 fn airMul(self: *FuncGen, inst: Air.Inst.Index, fast: Builder.FastMathKind) !Builder.Value {7869 fn airMul(self: *FuncGen, inst: Air.Inst.Index, fast: Builder.FastMathKind) !Builder.Value {
7825 const o = self.dg.object;7870 const o = self.dg.object;
7826 const mod = o.module;7871 const mod = o.pt.zcu;
7827 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;7872 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
7828 const lhs = try self.resolveInst(bin_op.lhs);7873 const lhs = try self.resolveInst(bin_op.lhs);
7829 const rhs = try self.resolveInst(bin_op.rhs);7874 const rhs = try self.resolveInst(bin_op.rhs);
...@@ -7844,7 +7889,7 @@ pub const FuncGen = struct {...@@ -7844,7 +7889,7 @@ pub const FuncGen = struct {
78447889
7845 fn airMulSat(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {7890 fn airMulSat(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
7846 const o = self.dg.object;7891 const o = self.dg.object;
7847 const mod = o.module;7892 const mod = o.pt.zcu;
7848 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;7893 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
7849 const lhs = try self.resolveInst(bin_op.lhs);7894 const lhs = try self.resolveInst(bin_op.lhs);
7850 const rhs = try self.resolveInst(bin_op.rhs);7895 const rhs = try self.resolveInst(bin_op.rhs);
...@@ -7873,7 +7918,7 @@ pub const FuncGen = struct {...@@ -7873,7 +7918,7 @@ pub const FuncGen = struct {
78737918
7874 fn airDivTrunc(self: *FuncGen, inst: Air.Inst.Index, fast: Builder.FastMathKind) !Builder.Value {7919 fn airDivTrunc(self: *FuncGen, inst: Air.Inst.Index, fast: Builder.FastMathKind) !Builder.Value {
7875 const o = self.dg.object;7920 const o = self.dg.object;
7876 const mod = o.module;7921 const mod = o.pt.zcu;
7877 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;7922 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
7878 const lhs = try self.resolveInst(bin_op.lhs);7923 const lhs = try self.resolveInst(bin_op.lhs);
7879 const rhs = try self.resolveInst(bin_op.rhs);7924 const rhs = try self.resolveInst(bin_op.rhs);
...@@ -7889,7 +7934,7 @@ pub const FuncGen = struct {...@@ -7889,7 +7934,7 @@ pub const FuncGen = struct {
78897934
7890 fn airDivFloor(self: *FuncGen, inst: Air.Inst.Index, fast: Builder.FastMathKind) !Builder.Value {7935 fn airDivFloor(self: *FuncGen, inst: Air.Inst.Index, fast: Builder.FastMathKind) !Builder.Value {
7891 const o = self.dg.object;7936 const o = self.dg.object;
7892 const mod = o.module;7937 const mod = o.pt.zcu;
7893 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;7938 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
7894 const lhs = try self.resolveInst(bin_op.lhs);7939 const lhs = try self.resolveInst(bin_op.lhs);
7895 const rhs = try self.resolveInst(bin_op.rhs);7940 const rhs = try self.resolveInst(bin_op.rhs);
...@@ -7921,7 +7966,7 @@ pub const FuncGen = struct {...@@ -7921,7 +7966,7 @@ pub const FuncGen = struct {
79217966
7922 fn airDivExact(self: *FuncGen, inst: Air.Inst.Index, fast: Builder.FastMathKind) !Builder.Value {7967 fn airDivExact(self: *FuncGen, inst: Air.Inst.Index, fast: Builder.FastMathKind) !Builder.Value {
7923 const o = self.dg.object;7968 const o = self.dg.object;
7924 const mod = o.module;7969 const mod = o.pt.zcu;
7925 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;7970 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
7926 const lhs = try self.resolveInst(bin_op.lhs);7971 const lhs = try self.resolveInst(bin_op.lhs);
7927 const rhs = try self.resolveInst(bin_op.rhs);7972 const rhs = try self.resolveInst(bin_op.rhs);
...@@ -7939,7 +7984,7 @@ pub const FuncGen = struct {...@@ -7939,7 +7984,7 @@ pub const FuncGen = struct {
79397984
7940 fn airRem(self: *FuncGen, inst: Air.Inst.Index, fast: Builder.FastMathKind) !Builder.Value {7985 fn airRem(self: *FuncGen, inst: Air.Inst.Index, fast: Builder.FastMathKind) !Builder.Value {
7941 const o = self.dg.object;7986 const o = self.dg.object;
7942 const mod = o.module;7987 const mod = o.pt.zcu;
7943 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;7988 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
7944 const lhs = try self.resolveInst(bin_op.lhs);7989 const lhs = try self.resolveInst(bin_op.lhs);
7945 const rhs = try self.resolveInst(bin_op.rhs);7990 const rhs = try self.resolveInst(bin_op.rhs);
...@@ -7956,7 +8001,7 @@ pub const FuncGen = struct {...@@ -7956,7 +8001,7 @@ pub const FuncGen = struct {
79568001
7957 fn airMod(self: *FuncGen, inst: Air.Inst.Index, fast: Builder.FastMathKind) !Builder.Value {8002 fn airMod(self: *FuncGen, inst: Air.Inst.Index, fast: Builder.FastMathKind) !Builder.Value {
7958 const o = self.dg.object;8003 const o = self.dg.object;
7959 const mod = o.module;8004 const mod = o.pt.zcu;
7960 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;8005 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
7961 const lhs = try self.resolveInst(bin_op.lhs);8006 const lhs = try self.resolveInst(bin_op.lhs);
7962 const rhs = try self.resolveInst(bin_op.rhs);8007 const rhs = try self.resolveInst(bin_op.rhs);
...@@ -7992,7 +8037,7 @@ pub const FuncGen = struct {...@@ -7992,7 +8037,7 @@ pub const FuncGen = struct {
79928037
7993 fn airPtrAdd(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {8038 fn airPtrAdd(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
7994 const o = self.dg.object;8039 const o = self.dg.object;
7995 const mod = o.module;8040 const mod = o.pt.zcu;
7996 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;8041 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
7997 const bin_op = self.air.extraData(Air.Bin, ty_pl.payload).data;8042 const bin_op = self.air.extraData(Air.Bin, ty_pl.payload).data;
7998 const ptr = try self.resolveInst(bin_op.lhs);8043 const ptr = try self.resolveInst(bin_op.lhs);
...@@ -8014,7 +8059,7 @@ pub const FuncGen = struct {...@@ -8014,7 +8059,7 @@ pub const FuncGen = struct {
80148059
8015 fn airPtrSub(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {8060 fn airPtrSub(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
8016 const o = self.dg.object;8061 const o = self.dg.object;
8017 const mod = o.module;8062 const mod = o.pt.zcu;
8018 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;8063 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
8019 const bin_op = self.air.extraData(Air.Bin, ty_pl.payload).data;8064 const bin_op = self.air.extraData(Air.Bin, ty_pl.payload).data;
8020 const ptr = try self.resolveInst(bin_op.lhs);8065 const ptr = try self.resolveInst(bin_op.lhs);
...@@ -8042,7 +8087,8 @@ pub const FuncGen = struct {...@@ -8042,7 +8087,8 @@ pub const FuncGen = struct {
8042 unsigned_intrinsic: Builder.Intrinsic,8087 unsigned_intrinsic: Builder.Intrinsic,
8043 ) !Builder.Value {8088 ) !Builder.Value {
8044 const o = self.dg.object;8089 const o = self.dg.object;
8045 const mod = o.module;8090 const pt = o.pt;
8091 const mod = pt.zcu;
8046 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;8092 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
8047 const extra = self.air.extraData(Air.Bin, ty_pl.payload).data;8093 const extra = self.air.extraData(Air.Bin, ty_pl.payload).data;
80488094
...@@ -8065,8 +8111,8 @@ pub const FuncGen = struct {...@@ -8065,8 +8111,8 @@ pub const FuncGen = struct {
8065 const result_index = o.llvmFieldIndex(inst_ty, 0).?;8111 const result_index = o.llvmFieldIndex(inst_ty, 0).?;
8066 const overflow_index = o.llvmFieldIndex(inst_ty, 1).?;8112 const overflow_index = o.llvmFieldIndex(inst_ty, 1).?;
80678113
8068 if (isByRef(inst_ty, mod)) {8114 if (isByRef(inst_ty, pt)) {
8069 const result_alignment = inst_ty.abiAlignment(mod).toLlvm();8115 const result_alignment = inst_ty.abiAlignment(pt).toLlvm();
8070 const alloca_inst = try self.buildAllocaWorkaround(inst_ty, result_alignment);8116 const alloca_inst = try self.buildAllocaWorkaround(inst_ty, result_alignment);
8071 {8117 {
8072 const field_ptr = try self.wip.gepStruct(llvm_inst_ty, alloca_inst, result_index, "");8118 const field_ptr = try self.wip.gepStruct(llvm_inst_ty, alloca_inst, result_index, "");
...@@ -8135,7 +8181,7 @@ pub const FuncGen = struct {...@@ -8135,7 +8181,7 @@ pub const FuncGen = struct {
8135 return o.builder.addFunction(8181 return o.builder.addFunction(
8136 try o.builder.fnType(return_type, param_types, .normal),8182 try o.builder.fnType(return_type, param_types, .normal),
8137 fn_name,8183 fn_name,
8138 toLlvmAddressSpace(.generic, o.module.getTarget()),8184 toLlvmAddressSpace(.generic, o.pt.zcu.getTarget()),
8139 );8185 );
8140 }8186 }
81418187
...@@ -8149,8 +8195,8 @@ pub const FuncGen = struct {...@@ -8149,8 +8195,8 @@ pub const FuncGen = struct {
8149 params: [2]Builder.Value,8195 params: [2]Builder.Value,
8150 ) !Builder.Value {8196 ) !Builder.Value {
8151 const o = self.dg.object;8197 const o = self.dg.object;
8152 const mod = o.module;8198 const mod = o.pt.zcu;
8153 const target = o.module.getTarget();8199 const target = mod.getTarget();
8154 const scalar_ty = ty.scalarType(mod);8200 const scalar_ty = ty.scalarType(mod);
8155 const scalar_llvm_ty = try o.lowerType(scalar_ty);8201 const scalar_llvm_ty = try o.lowerType(scalar_ty);
81568202
...@@ -8255,7 +8301,7 @@ pub const FuncGen = struct {...@@ -8255,7 +8301,7 @@ pub const FuncGen = struct {
8255 params: [params_len]Builder.Value,8301 params: [params_len]Builder.Value,
8256 ) !Builder.Value {8302 ) !Builder.Value {
8257 const o = self.dg.object;8303 const o = self.dg.object;
8258 const mod = o.module;8304 const mod = o.pt.zcu;
8259 const target = mod.getTarget();8305 const target = mod.getTarget();
8260 const scalar_ty = ty.scalarType(mod);8306 const scalar_ty = ty.scalarType(mod);
8261 const llvm_ty = try o.lowerType(ty);8307 const llvm_ty = try o.lowerType(ty);
...@@ -8396,7 +8442,8 @@ pub const FuncGen = struct {...@@ -8396,7 +8442,8 @@ pub const FuncGen = struct {
83968442
8397 fn airShlWithOverflow(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {8443 fn airShlWithOverflow(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
8398 const o = self.dg.object;8444 const o = self.dg.object;
8399 const mod = o.module;8445 const pt = o.pt;
8446 const mod = pt.zcu;
8400 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;8447 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
8401 const extra = self.air.extraData(Air.Bin, ty_pl.payload).data;8448 const extra = self.air.extraData(Air.Bin, ty_pl.payload).data;
84028449
...@@ -8422,8 +8469,8 @@ pub const FuncGen = struct {...@@ -8422,8 +8469,8 @@ pub const FuncGen = struct {
8422 const result_index = o.llvmFieldIndex(dest_ty, 0).?;8469 const result_index = o.llvmFieldIndex(dest_ty, 0).?;
8423 const overflow_index = o.llvmFieldIndex(dest_ty, 1).?;8470 const overflow_index = o.llvmFieldIndex(dest_ty, 1).?;
84248471
8425 if (isByRef(dest_ty, mod)) {8472 if (isByRef(dest_ty, pt)) {
8426 const result_alignment = dest_ty.abiAlignment(mod).toLlvm();8473 const result_alignment = dest_ty.abiAlignment(pt).toLlvm();
8427 const alloca_inst = try self.buildAllocaWorkaround(dest_ty, result_alignment);8474 const alloca_inst = try self.buildAllocaWorkaround(dest_ty, result_alignment);
8428 {8475 {
8429 const field_ptr = try self.wip.gepStruct(llvm_dest_ty, alloca_inst, result_index, "");8476 const field_ptr = try self.wip.gepStruct(llvm_dest_ty, alloca_inst, result_index, "");
...@@ -8466,7 +8513,7 @@ pub const FuncGen = struct {...@@ -8466,7 +8513,7 @@ pub const FuncGen = struct {
84668513
8467 fn airShlExact(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {8514 fn airShlExact(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
8468 const o = self.dg.object;8515 const o = self.dg.object;
8469 const mod = o.module;8516 const mod = o.pt.zcu;
8470 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;8517 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
84718518
8472 const lhs = try self.resolveInst(bin_op.lhs);8519 const lhs = try self.resolveInst(bin_op.lhs);
...@@ -8497,7 +8544,8 @@ pub const FuncGen = struct {...@@ -8497,7 +8544,8 @@ pub const FuncGen = struct {
84978544
8498 fn airShlSat(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {8545 fn airShlSat(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
8499 const o = self.dg.object;8546 const o = self.dg.object;
8500 const mod = o.module;8547 const pt = o.pt;
8548 const mod = pt.zcu;
8501 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;8549 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
85028550
8503 const lhs = try self.resolveInst(bin_op.lhs);8551 const lhs = try self.resolveInst(bin_op.lhs);
...@@ -8505,7 +8553,7 @@ pub const FuncGen = struct {...@@ -8505,7 +8553,7 @@ pub const FuncGen = struct {
85058553
8506 const lhs_ty = self.typeOf(bin_op.lhs);8554 const lhs_ty = self.typeOf(bin_op.lhs);
8507 const lhs_scalar_ty = lhs_ty.scalarType(mod);8555 const lhs_scalar_ty = lhs_ty.scalarType(mod);
8508 const lhs_bits = lhs_scalar_ty.bitSize(mod);8556 const lhs_bits = lhs_scalar_ty.bitSize(pt);
85098557
8510 const casted_rhs = try self.wip.conv(.unsigned, rhs, try o.lowerType(lhs_ty), "");8558 const casted_rhs = try self.wip.conv(.unsigned, rhs, try o.lowerType(lhs_ty), "");
85118559
...@@ -8539,7 +8587,7 @@ pub const FuncGen = struct {...@@ -8539,7 +8587,7 @@ pub const FuncGen = struct {
85398587
8540 fn airShr(self: *FuncGen, inst: Air.Inst.Index, is_exact: bool) !Builder.Value {8588 fn airShr(self: *FuncGen, inst: Air.Inst.Index, is_exact: bool) !Builder.Value {
8541 const o = self.dg.object;8589 const o = self.dg.object;
8542 const mod = o.module;8590 const mod = o.pt.zcu;
8543 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;8591 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
85448592
8545 const lhs = try self.resolveInst(bin_op.lhs);8593 const lhs = try self.resolveInst(bin_op.lhs);
...@@ -8558,7 +8606,7 @@ pub const FuncGen = struct {...@@ -8558,7 +8606,7 @@ pub const FuncGen = struct {
85588606
8559 fn airAbs(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {8607 fn airAbs(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
8560 const o = self.dg.object;8608 const o = self.dg.object;
8561 const mod = o.module;8609 const mod = o.pt.zcu;
8562 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;8610 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
8563 const operand = try self.resolveInst(ty_op.operand);8611 const operand = try self.resolveInst(ty_op.operand);
8564 const operand_ty = self.typeOf(ty_op.operand);8612 const operand_ty = self.typeOf(ty_op.operand);
...@@ -8580,7 +8628,7 @@ pub const FuncGen = struct {...@@ -8580,7 +8628,7 @@ pub const FuncGen = struct {
85808628
8581 fn airIntCast(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {8629 fn airIntCast(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
8582 const o = self.dg.object;8630 const o = self.dg.object;
8583 const mod = o.module;8631 const mod = o.pt.zcu;
8584 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;8632 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
8585 const dest_ty = self.typeOfIndex(inst);8633 const dest_ty = self.typeOfIndex(inst);
8586 const dest_llvm_ty = try o.lowerType(dest_ty);8634 const dest_llvm_ty = try o.lowerType(dest_ty);
...@@ -8604,7 +8652,7 @@ pub const FuncGen = struct {...@@ -8604,7 +8652,7 @@ pub const FuncGen = struct {
86048652
8605 fn airFptrunc(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {8653 fn airFptrunc(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
8606 const o = self.dg.object;8654 const o = self.dg.object;
8607 const mod = o.module;8655 const mod = o.pt.zcu;
8608 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;8656 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
8609 const operand = try self.resolveInst(ty_op.operand);8657 const operand = try self.resolveInst(ty_op.operand);
8610 const operand_ty = self.typeOf(ty_op.operand);8658 const operand_ty = self.typeOf(ty_op.operand);
...@@ -8638,7 +8686,7 @@ pub const FuncGen = struct {...@@ -8638,7 +8686,7 @@ pub const FuncGen = struct {
86388686
8639 fn airFpext(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {8687 fn airFpext(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
8640 const o = self.dg.object;8688 const o = self.dg.object;
8641 const mod = o.module;8689 const mod = o.pt.zcu;
8642 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;8690 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
8643 const operand = try self.resolveInst(ty_op.operand);8691 const operand = try self.resolveInst(ty_op.operand);
8644 const operand_ty = self.typeOf(ty_op.operand);8692 const operand_ty = self.typeOf(ty_op.operand);
...@@ -8696,9 +8744,10 @@ pub const FuncGen = struct {...@@ -8696,9 +8744,10 @@ pub const FuncGen = struct {
86968744
8697 fn bitCast(self: *FuncGen, operand: Builder.Value, operand_ty: Type, inst_ty: Type) !Builder.Value {8745 fn bitCast(self: *FuncGen, operand: Builder.Value, operand_ty: Type, inst_ty: Type) !Builder.Value {
8698 const o = self.dg.object;8746 const o = self.dg.object;
8699 const mod = o.module;8747 const pt = o.pt;
8700 const operand_is_ref = isByRef(operand_ty, mod);8748 const mod = pt.zcu;
8701 const result_is_ref = isByRef(inst_ty, mod);8749 const operand_is_ref = isByRef(operand_ty, pt);
8750 const result_is_ref = isByRef(inst_ty, pt);
8702 const llvm_dest_ty = try o.lowerType(inst_ty);8751 const llvm_dest_ty = try o.lowerType(inst_ty);
87038752
8704 if (operand_is_ref and result_is_ref) {8753 if (operand_is_ref and result_is_ref) {
...@@ -8721,9 +8770,9 @@ pub const FuncGen = struct {...@@ -8721,9 +8770,9 @@ pub const FuncGen = struct {
8721 if (!result_is_ref) {8770 if (!result_is_ref) {
8722 return self.dg.todo("implement bitcast vector to non-ref array", .{});8771 return self.dg.todo("implement bitcast vector to non-ref array", .{});
8723 }8772 }
8724 const alignment = inst_ty.abiAlignment(mod).toLlvm();8773 const alignment = inst_ty.abiAlignment(pt).toLlvm();
8725 const array_ptr = try self.buildAllocaWorkaround(inst_ty, alignment);8774 const array_ptr = try self.buildAllocaWorkaround(inst_ty, alignment);
8726 const bitcast_ok = elem_ty.bitSize(mod) == elem_ty.abiSize(mod) * 8;8775 const bitcast_ok = elem_ty.bitSize(pt) == elem_ty.abiSize(pt) * 8;
8727 if (bitcast_ok) {8776 if (bitcast_ok) {
8728 _ = try self.wip.store(.normal, operand, array_ptr, alignment);8777 _ = try self.wip.store(.normal, operand, array_ptr, alignment);
8729 } else {8778 } else {
...@@ -8748,11 +8797,11 @@ pub const FuncGen = struct {...@@ -8748,11 +8797,11 @@ pub const FuncGen = struct {
8748 const llvm_vector_ty = try o.lowerType(inst_ty);8797 const llvm_vector_ty = try o.lowerType(inst_ty);
8749 if (!operand_is_ref) return self.dg.todo("implement bitcast non-ref array to vector", .{});8798 if (!operand_is_ref) return self.dg.todo("implement bitcast non-ref array to vector", .{});
87508799
8751 const bitcast_ok = elem_ty.bitSize(mod) == elem_ty.abiSize(mod) * 8;8800 const bitcast_ok = elem_ty.bitSize(pt) == elem_ty.abiSize(pt) * 8;
8752 if (bitcast_ok) {8801 if (bitcast_ok) {
8753 // The array is aligned to the element's alignment, while the vector might have a completely8802 // The array is aligned to the element's alignment, while the vector might have a completely
8754 // different alignment. This means we need to enforce the alignment of this load.8803 // different alignment. This means we need to enforce the alignment of this load.
8755 const alignment = elem_ty.abiAlignment(mod).toLlvm();8804 const alignment = elem_ty.abiAlignment(pt).toLlvm();
8756 return self.wip.load(.normal, llvm_vector_ty, operand, alignment, "");8805 return self.wip.load(.normal, llvm_vector_ty, operand, alignment, "");
8757 } else {8806 } else {
8758 // If the ABI size of the element type is not evenly divisible by size in bits;8807 // If the ABI size of the element type is not evenly divisible by size in bits;
...@@ -8777,24 +8826,25 @@ pub const FuncGen = struct {...@@ -8777,24 +8826,25 @@ pub const FuncGen = struct {
8777 }8826 }
87788827
8779 if (operand_is_ref) {8828 if (operand_is_ref) {
8780 const alignment = operand_ty.abiAlignment(mod).toLlvm();8829 const alignment = operand_ty.abiAlignment(pt).toLlvm();
8781 return self.wip.load(.normal, llvm_dest_ty, operand, alignment, "");8830 return self.wip.load(.normal, llvm_dest_ty, operand, alignment, "");
8782 }8831 }
87838832
8784 if (result_is_ref) {8833 if (result_is_ref) {
8785 const alignment = operand_ty.abiAlignment(mod).max(inst_ty.abiAlignment(mod)).toLlvm();8834 const alignment = operand_ty.abiAlignment(pt).max(inst_ty.abiAlignment(pt)).toLlvm();
8786 const result_ptr = try self.buildAllocaWorkaround(inst_ty, alignment);8835 const result_ptr = try self.buildAllocaWorkaround(inst_ty, alignment);
8787 _ = try self.wip.store(.normal, operand, result_ptr, alignment);8836 _ = try self.wip.store(.normal, operand, result_ptr, alignment);
8788 return result_ptr;8837 return result_ptr;
8789 }8838 }
87908839
8791 if (llvm_dest_ty.isStruct(&o.builder) or8840 if (llvm_dest_ty.isStruct(&o.builder) or
8792 ((operand_ty.zigTypeTag(mod) == .Vector or inst_ty.zigTypeTag(mod) == .Vector) and operand_ty.bitSize(mod) != inst_ty.bitSize(mod)))8841 ((operand_ty.zigTypeTag(mod) == .Vector or inst_ty.zigTypeTag(mod) == .Vector) and
8842 operand_ty.bitSize(pt) != inst_ty.bitSize(pt)))
8793 {8843 {
8794 // Both our operand and our result are values, not pointers,8844 // Both our operand and our result are values, not pointers,
8795 // but LLVM won't let us bitcast struct values or vectors with padding bits.8845 // but LLVM won't let us bitcast struct values or vectors with padding bits.
8796 // Therefore, we store operand to alloca, then load for result.8846 // Therefore, we store operand to alloca, then load for result.
8797 const alignment = operand_ty.abiAlignment(mod).max(inst_ty.abiAlignment(mod)).toLlvm();8847 const alignment = operand_ty.abiAlignment(pt).max(inst_ty.abiAlignment(pt)).toLlvm();
8798 const result_ptr = try self.buildAllocaWorkaround(inst_ty, alignment);8848 const result_ptr = try self.buildAllocaWorkaround(inst_ty, alignment);
8799 _ = try self.wip.store(.normal, operand, result_ptr, alignment);8849 _ = try self.wip.store(.normal, operand, result_ptr, alignment);
8800 return self.wip.load(.normal, llvm_dest_ty, result_ptr, alignment, "");8850 return self.wip.load(.normal, llvm_dest_ty, result_ptr, alignment, "");
...@@ -8811,7 +8861,8 @@ pub const FuncGen = struct {...@@ -8811,7 +8861,8 @@ pub const FuncGen = struct {
88118861
8812 fn airArg(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {8862 fn airArg(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
8813 const o = self.dg.object;8863 const o = self.dg.object;
8814 const mod = o.module;8864 const pt = o.pt;
8865 const mod = pt.zcu;
8815 const arg_val = self.args[self.arg_index];8866 const arg_val = self.args[self.arg_index];
8816 self.arg_index += 1;8867 self.arg_index += 1;
88178868
...@@ -8847,7 +8898,7 @@ pub const FuncGen = struct {...@@ -8847,7 +8898,7 @@ pub const FuncGen = struct {
8847 };8898 };
88488899
8849 const owner_mod = self.dg.ownerModule();8900 const owner_mod = self.dg.ownerModule();
8850 if (isByRef(inst_ty, mod)) {8901 if (isByRef(inst_ty, pt)) {
8851 _ = try self.wip.callIntrinsic(8902 _ = try self.wip.callIntrinsic(
8852 .normal,8903 .normal,
8853 .none,8904 .none,
...@@ -8861,7 +8912,7 @@ pub const FuncGen = struct {...@@ -8861,7 +8912,7 @@ pub const FuncGen = struct {
8861 "",8912 "",
8862 );8913 );
8863 } else if (owner_mod.optimize_mode == .Debug) {8914 } else if (owner_mod.optimize_mode == .Debug) {
8864 const alignment = inst_ty.abiAlignment(mod).toLlvm();8915 const alignment = inst_ty.abiAlignment(pt).toLlvm();
8865 const alloca = try self.buildAlloca(arg_val.typeOfWip(&self.wip), alignment);8916 const alloca = try self.buildAlloca(arg_val.typeOfWip(&self.wip), alignment);
8866 _ = try self.wip.store(.normal, arg_val, alloca, alignment);8917 _ = try self.wip.store(.normal, arg_val, alloca, alignment);
8867 _ = try self.wip.callIntrinsic(8918 _ = try self.wip.callIntrinsic(
...@@ -8897,27 +8948,29 @@ pub const FuncGen = struct {...@@ -8897,27 +8948,29 @@ pub const FuncGen = struct {
88978948
8898 fn airAlloc(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {8949 fn airAlloc(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
8899 const o = self.dg.object;8950 const o = self.dg.object;
8900 const mod = o.module;8951 const pt = o.pt;
8952 const mod = pt.zcu;
8901 const ptr_ty = self.typeOfIndex(inst);8953 const ptr_ty = self.typeOfIndex(inst);
8902 const pointee_type = ptr_ty.childType(mod);8954 const pointee_type = ptr_ty.childType(mod);
8903 if (!pointee_type.isFnOrHasRuntimeBitsIgnoreComptime(mod))8955 if (!pointee_type.isFnOrHasRuntimeBitsIgnoreComptime(pt))
8904 return (try o.lowerPtrToVoid(ptr_ty)).toValue();8956 return (try o.lowerPtrToVoid(ptr_ty)).toValue();
89058957
8906 //const pointee_llvm_ty = try o.lowerType(pointee_type);8958 //const pointee_llvm_ty = try o.lowerType(pointee_type);
8907 const alignment = ptr_ty.ptrAlignment(mod).toLlvm();8959 const alignment = ptr_ty.ptrAlignment(pt).toLlvm();
8908 return self.buildAllocaWorkaround(pointee_type, alignment);8960 return self.buildAllocaWorkaround(pointee_type, alignment);
8909 }8961 }
89108962
8911 fn airRetPtr(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {8963 fn airRetPtr(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
8912 const o = self.dg.object;8964 const o = self.dg.object;
8913 const mod = o.module;8965 const pt = o.pt;
8966 const mod = pt.zcu;
8914 const ptr_ty = self.typeOfIndex(inst);8967 const ptr_ty = self.typeOfIndex(inst);
8915 const ret_ty = ptr_ty.childType(mod);8968 const ret_ty = ptr_ty.childType(mod);
8916 if (!ret_ty.isFnOrHasRuntimeBitsIgnoreComptime(mod))8969 if (!ret_ty.isFnOrHasRuntimeBitsIgnoreComptime(pt))
8917 return (try o.lowerPtrToVoid(ptr_ty)).toValue();8970 return (try o.lowerPtrToVoid(ptr_ty)).toValue();
8918 if (self.ret_ptr != .none) return self.ret_ptr;8971 if (self.ret_ptr != .none) return self.ret_ptr;
8919 //const ret_llvm_ty = try o.lowerType(ret_ty);8972 //const ret_llvm_ty = try o.lowerType(ret_ty);
8920 const alignment = ptr_ty.ptrAlignment(mod).toLlvm();8973 const alignment = ptr_ty.ptrAlignment(pt).toLlvm();
8921 return self.buildAllocaWorkaround(ret_ty, alignment);8974 return self.buildAllocaWorkaround(ret_ty, alignment);
8922 }8975 }
89238976
...@@ -8928,7 +8981,7 @@ pub const FuncGen = struct {...@@ -8928,7 +8981,7 @@ pub const FuncGen = struct {
8928 llvm_ty: Builder.Type,8981 llvm_ty: Builder.Type,
8929 alignment: Builder.Alignment,8982 alignment: Builder.Alignment,
8930 ) Allocator.Error!Builder.Value {8983 ) Allocator.Error!Builder.Value {
8931 const target = self.dg.object.module.getTarget();8984 const target = self.dg.object.pt.zcu.getTarget();
8932 return buildAllocaInner(&self.wip, llvm_ty, alignment, target);8985 return buildAllocaInner(&self.wip, llvm_ty, alignment, target);
8933 }8986 }
89348987
...@@ -8939,18 +8992,19 @@ pub const FuncGen = struct {...@@ -8939,18 +8992,19 @@ pub const FuncGen = struct {
8939 alignment: Builder.Alignment,8992 alignment: Builder.Alignment,
8940 ) Allocator.Error!Builder.Value {8993 ) Allocator.Error!Builder.Value {
8941 const o = self.dg.object;8994 const o = self.dg.object;
8942 return self.buildAlloca(try o.builder.arrayType(ty.abiSize(o.module), .i8), alignment);8995 return self.buildAlloca(try o.builder.arrayType(ty.abiSize(o.pt), .i8), alignment);
8943 }8996 }
89448997
8945 fn airStore(self: *FuncGen, inst: Air.Inst.Index, safety: bool) !Builder.Value {8998 fn airStore(self: *FuncGen, inst: Air.Inst.Index, safety: bool) !Builder.Value {
8946 const o = self.dg.object;8999 const o = self.dg.object;
8947 const mod = o.module;9000 const pt = o.pt;
9001 const mod = pt.zcu;
8948 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;9002 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
8949 const dest_ptr = try self.resolveInst(bin_op.lhs);9003 const dest_ptr = try self.resolveInst(bin_op.lhs);
8950 const ptr_ty = self.typeOf(bin_op.lhs);9004 const ptr_ty = self.typeOf(bin_op.lhs);
8951 const operand_ty = ptr_ty.childType(mod);9005 const operand_ty = ptr_ty.childType(mod);
89529006
8953 const val_is_undef = if (try self.air.value(bin_op.rhs, mod)) |val| val.isUndefDeep(mod) else false;9007 const val_is_undef = if (try self.air.value(bin_op.rhs, pt)) |val| val.isUndefDeep(mod) else false;
8954 if (val_is_undef) {9008 if (val_is_undef) {
8955 const ptr_info = ptr_ty.ptrInfo(mod);9009 const ptr_info = ptr_ty.ptrInfo(mod);
8956 const needs_bitmask = (ptr_info.packed_offset.host_size != 0);9010 const needs_bitmask = (ptr_info.packed_offset.host_size != 0);
...@@ -8964,10 +9018,10 @@ pub const FuncGen = struct {...@@ -8964,10 +9018,10 @@ pub const FuncGen = struct {
8964 // Even if safety is disabled, we still emit a memset to undefined since it conveys9018 // Even if safety is disabled, we still emit a memset to undefined since it conveys
8965 // extra information to LLVM. However, safety makes the difference between using9019 // extra information to LLVM. However, safety makes the difference between using
8966 // 0xaa or actual undefined for the fill byte.9020 // 0xaa or actual undefined for the fill byte.
8967 const len = try o.builder.intValue(try o.lowerType(Type.usize), operand_ty.abiSize(mod));9021 const len = try o.builder.intValue(try o.lowerType(Type.usize), operand_ty.abiSize(pt));
8968 _ = try self.wip.callMemSet(9022 _ = try self.wip.callMemSet(
8969 dest_ptr,9023 dest_ptr,
8970 ptr_ty.ptrAlignment(mod).toLlvm(),9024 ptr_ty.ptrAlignment(pt).toLlvm(),
8971 if (safety) try o.builder.intValue(.i8, 0xaa) else try o.builder.undefValue(.i8),9025 if (safety) try o.builder.intValue(.i8, 0xaa) else try o.builder.undefValue(.i8),
8972 len,9026 len,
8973 if (ptr_ty.isVolatilePtr(mod)) .@"volatile" else .normal,9027 if (ptr_ty.isVolatilePtr(mod)) .@"volatile" else .normal,
...@@ -8992,7 +9046,7 @@ pub const FuncGen = struct {...@@ -8992,7 +9046,7 @@ pub const FuncGen = struct {
8992 /// The first instruction of `body_tail` is the one whose copy we want to elide.9046 /// The first instruction of `body_tail` is the one whose copy we want to elide.
8993 fn canElideLoad(fg: *FuncGen, body_tail: []const Air.Inst.Index) bool {9047 fn canElideLoad(fg: *FuncGen, body_tail: []const Air.Inst.Index) bool {
8994 const o = fg.dg.object;9048 const o = fg.dg.object;
8995 const mod = o.module;9049 const mod = o.pt.zcu;
8996 const ip = &mod.intern_pool;9050 const ip = &mod.intern_pool;
8997 for (body_tail[1..]) |body_inst| {9051 for (body_tail[1..]) |body_inst| {
8998 switch (fg.liveness.categorizeOperand(fg.air, body_inst, body_tail[0], ip)) {9052 switch (fg.liveness.categorizeOperand(fg.air, body_inst, body_tail[0], ip)) {
...@@ -9008,7 +9062,8 @@ pub const FuncGen = struct {...@@ -9008,7 +9062,8 @@ pub const FuncGen = struct {
90089062
9009 fn airLoad(fg: *FuncGen, body_tail: []const Air.Inst.Index) !Builder.Value {9063 fn airLoad(fg: *FuncGen, body_tail: []const Air.Inst.Index) !Builder.Value {
9010 const o = fg.dg.object;9064 const o = fg.dg.object;
9011 const mod = o.module;9065 const pt = o.pt;
9066 const mod = pt.zcu;
9012 const inst = body_tail[0];9067 const inst = body_tail[0];
9013 const ty_op = fg.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;9068 const ty_op = fg.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
9014 const ptr_ty = fg.typeOf(ty_op.operand);9069 const ptr_ty = fg.typeOf(ty_op.operand);
...@@ -9016,7 +9071,7 @@ pub const FuncGen = struct {...@@ -9016,7 +9071,7 @@ pub const FuncGen = struct {
9016 const ptr = try fg.resolveInst(ty_op.operand);9071 const ptr = try fg.resolveInst(ty_op.operand);
90179072
9018 elide: {9073 elide: {
9019 if (!isByRef(Type.fromInterned(ptr_info.child), mod)) break :elide;9074 if (!isByRef(Type.fromInterned(ptr_info.child), pt)) break :elide;
9020 if (!canElideLoad(fg, body_tail)) break :elide;9075 if (!canElideLoad(fg, body_tail)) break :elide;
9021 return ptr;9076 return ptr;
9022 }9077 }
...@@ -9040,7 +9095,7 @@ pub const FuncGen = struct {...@@ -9040,7 +9095,7 @@ pub const FuncGen = struct {
9040 _ = inst;9095 _ = inst;
9041 const o = self.dg.object;9096 const o = self.dg.object;
9042 const llvm_usize = try o.lowerType(Type.usize);9097 const llvm_usize = try o.lowerType(Type.usize);
9043 if (!target_util.supportsReturnAddress(o.module.getTarget())) {9098 if (!target_util.supportsReturnAddress(o.pt.zcu.getTarget())) {
9044 // https://github.com/ziglang/zig/issues/119469099 // https://github.com/ziglang/zig/issues/11946
9045 return o.builder.intValue(llvm_usize, 0);9100 return o.builder.intValue(llvm_usize, 0);
9046 }9101 }
...@@ -9068,7 +9123,8 @@ pub const FuncGen = struct {...@@ -9068,7 +9123,8 @@ pub const FuncGen = struct {
9068 kind: Builder.Function.Instruction.CmpXchg.Kind,9123 kind: Builder.Function.Instruction.CmpXchg.Kind,
9069 ) !Builder.Value {9124 ) !Builder.Value {
9070 const o = self.dg.object;9125 const o = self.dg.object;
9071 const mod = o.module;9126 const pt = o.pt;
9127 const mod = pt.zcu;
9072 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;9128 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
9073 const extra = self.air.extraData(Air.Cmpxchg, ty_pl.payload).data;9129 const extra = self.air.extraData(Air.Cmpxchg, ty_pl.payload).data;
9074 const ptr = try self.resolveInst(extra.ptr);9130 const ptr = try self.resolveInst(extra.ptr);
...@@ -9095,7 +9151,7 @@ pub const FuncGen = struct {...@@ -9095,7 +9151,7 @@ pub const FuncGen = struct {
9095 self.sync_scope,9151 self.sync_scope,
9096 toLlvmAtomicOrdering(extra.successOrder()),9152 toLlvmAtomicOrdering(extra.successOrder()),
9097 toLlvmAtomicOrdering(extra.failureOrder()),9153 toLlvmAtomicOrdering(extra.failureOrder()),
9098 ptr_ty.ptrAlignment(mod).toLlvm(),9154 ptr_ty.ptrAlignment(pt).toLlvm(),
9099 "",9155 "",
9100 );9156 );
91019157
...@@ -9118,7 +9174,8 @@ pub const FuncGen = struct {...@@ -9118,7 +9174,8 @@ pub const FuncGen = struct {
91189174
9119 fn airAtomicRmw(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {9175 fn airAtomicRmw(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
9120 const o = self.dg.object;9176 const o = self.dg.object;
9121 const mod = o.module;9177 const pt = o.pt;
9178 const mod = pt.zcu;
9122 const pl_op = self.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;9179 const pl_op = self.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;
9123 const extra = self.air.extraData(Air.AtomicRmw, pl_op.payload).data;9180 const extra = self.air.extraData(Air.AtomicRmw, pl_op.payload).data;
9124 const ptr = try self.resolveInst(pl_op.operand);9181 const ptr = try self.resolveInst(pl_op.operand);
...@@ -9134,7 +9191,7 @@ pub const FuncGen = struct {...@@ -9134,7 +9191,7 @@ pub const FuncGen = struct {
91349191
9135 const access_kind: Builder.MemoryAccessKind =9192 const access_kind: Builder.MemoryAccessKind =
9136 if (ptr_ty.isVolatilePtr(mod)) .@"volatile" else .normal;9193 if (ptr_ty.isVolatilePtr(mod)) .@"volatile" else .normal;
9137 const ptr_alignment = ptr_ty.ptrAlignment(mod).toLlvm();9194 const ptr_alignment = ptr_ty.ptrAlignment(pt).toLlvm();
91389195
9139 if (llvm_abi_ty != .none) {9196 if (llvm_abi_ty != .none) {
9140 // operand needs widening and truncating or bitcasting.9197 // operand needs widening and truncating or bitcasting.
...@@ -9181,19 +9238,20 @@ pub const FuncGen = struct {...@@ -9181,19 +9238,20 @@ pub const FuncGen = struct {
91819238
9182 fn airAtomicLoad(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {9239 fn airAtomicLoad(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
9183 const o = self.dg.object;9240 const o = self.dg.object;
9184 const mod = o.module;9241 const pt = o.pt;
9242 const mod = pt.zcu;
9185 const atomic_load = self.air.instructions.items(.data)[@intFromEnum(inst)].atomic_load;9243 const atomic_load = self.air.instructions.items(.data)[@intFromEnum(inst)].atomic_load;
9186 const ptr = try self.resolveInst(atomic_load.ptr);9244 const ptr = try self.resolveInst(atomic_load.ptr);
9187 const ptr_ty = self.typeOf(atomic_load.ptr);9245 const ptr_ty = self.typeOf(atomic_load.ptr);
9188 const info = ptr_ty.ptrInfo(mod);9246 const info = ptr_ty.ptrInfo(mod);
9189 const elem_ty = Type.fromInterned(info.child);9247 const elem_ty = Type.fromInterned(info.child);
9190 if (!elem_ty.hasRuntimeBitsIgnoreComptime(mod)) return .none;9248 if (!elem_ty.hasRuntimeBitsIgnoreComptime(pt)) return .none;
9191 const ordering = toLlvmAtomicOrdering(atomic_load.order);9249 const ordering = toLlvmAtomicOrdering(atomic_load.order);
9192 const llvm_abi_ty = try o.getAtomicAbiType(elem_ty, false);9250 const llvm_abi_ty = try o.getAtomicAbiType(elem_ty, false);
9193 const ptr_alignment = (if (info.flags.alignment != .none)9251 const ptr_alignment = (if (info.flags.alignment != .none)
9194 @as(InternPool.Alignment, info.flags.alignment)9252 @as(InternPool.Alignment, info.flags.alignment)
9195 else9253 else
9196 Type.fromInterned(info.child).abiAlignment(mod)).toLlvm();9254 Type.fromInterned(info.child).abiAlignment(pt)).toLlvm();
9197 const access_kind: Builder.MemoryAccessKind =9255 const access_kind: Builder.MemoryAccessKind =
9198 if (info.flags.is_volatile) .@"volatile" else .normal;9256 if (info.flags.is_volatile) .@"volatile" else .normal;
9199 const elem_llvm_ty = try o.lowerType(elem_ty);9257 const elem_llvm_ty = try o.lowerType(elem_ty);
...@@ -9228,11 +9286,12 @@ pub const FuncGen = struct {...@@ -9228,11 +9286,12 @@ pub const FuncGen = struct {
9228 ordering: Builder.AtomicOrdering,9286 ordering: Builder.AtomicOrdering,
9229 ) !Builder.Value {9287 ) !Builder.Value {
9230 const o = self.dg.object;9288 const o = self.dg.object;
9231 const mod = o.module;9289 const pt = o.pt;
9290 const mod = pt.zcu;
9232 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;9291 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
9233 const ptr_ty = self.typeOf(bin_op.lhs);9292 const ptr_ty = self.typeOf(bin_op.lhs);
9234 const operand_ty = ptr_ty.childType(mod);9293 const operand_ty = ptr_ty.childType(mod);
9235 if (!operand_ty.isFnOrHasRuntimeBitsIgnoreComptime(mod)) return .none;9294 if (!operand_ty.isFnOrHasRuntimeBitsIgnoreComptime(pt)) return .none;
9236 const ptr = try self.resolveInst(bin_op.lhs);9295 const ptr = try self.resolveInst(bin_op.lhs);
9237 var element = try self.resolveInst(bin_op.rhs);9296 var element = try self.resolveInst(bin_op.rhs);
9238 const llvm_abi_ty = try o.getAtomicAbiType(operand_ty, false);9297 const llvm_abi_ty = try o.getAtomicAbiType(operand_ty, false);
...@@ -9252,12 +9311,13 @@ pub const FuncGen = struct {...@@ -9252,12 +9311,13 @@ pub const FuncGen = struct {
92529311
9253 fn airMemset(self: *FuncGen, inst: Air.Inst.Index, safety: bool) !Builder.Value {9312 fn airMemset(self: *FuncGen, inst: Air.Inst.Index, safety: bool) !Builder.Value {
9254 const o = self.dg.object;9313 const o = self.dg.object;
9255 const mod = o.module;9314 const pt = o.pt;
9315 const mod = pt.zcu;
9256 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;9316 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
9257 const dest_slice = try self.resolveInst(bin_op.lhs);9317 const dest_slice = try self.resolveInst(bin_op.lhs);
9258 const ptr_ty = self.typeOf(bin_op.lhs);9318 const ptr_ty = self.typeOf(bin_op.lhs);
9259 const elem_ty = self.typeOf(bin_op.rhs);9319 const elem_ty = self.typeOf(bin_op.rhs);
9260 const dest_ptr_align = ptr_ty.ptrAlignment(mod).toLlvm();9320 const dest_ptr_align = ptr_ty.ptrAlignment(pt).toLlvm();
9261 const dest_ptr = try self.sliceOrArrayPtr(dest_slice, ptr_ty);9321 const dest_ptr = try self.sliceOrArrayPtr(dest_slice, ptr_ty);
9262 const access_kind: Builder.MemoryAccessKind =9322 const access_kind: Builder.MemoryAccessKind =
9263 if (ptr_ty.isVolatilePtr(mod)) .@"volatile" else .normal;9323 if (ptr_ty.isVolatilePtr(mod)) .@"volatile" else .normal;
...@@ -9270,7 +9330,7 @@ pub const FuncGen = struct {...@@ -9270,7 +9330,7 @@ pub const FuncGen = struct {
9270 ptr_ty.isSlice(mod) and9330 ptr_ty.isSlice(mod) and
9271 std.Target.wasm.featureSetHas(o.target.cpu.features, .bulk_memory);9331 std.Target.wasm.featureSetHas(o.target.cpu.features, .bulk_memory);
92729332
9273 if (try self.air.value(bin_op.rhs, mod)) |elem_val| {9333 if (try self.air.value(bin_op.rhs, pt)) |elem_val| {
9274 if (elem_val.isUndefDeep(mod)) {9334 if (elem_val.isUndefDeep(mod)) {
9275 // Even if safety is disabled, we still emit a memset to undefined since it conveys9335 // Even if safety is disabled, we still emit a memset to undefined since it conveys
9276 // extra information to LLVM. However, safety makes the difference between using9336 // extra information to LLVM. However, safety makes the difference between using
...@@ -9296,7 +9356,7 @@ pub const FuncGen = struct {...@@ -9296,7 +9356,7 @@ pub const FuncGen = struct {
9296 // repeating byte pattern, for example, `@as(u64, 0)` has a9356 // repeating byte pattern, for example, `@as(u64, 0)` has a
9297 // repeating byte pattern of 0 bytes. In such case, the memset9357 // repeating byte pattern of 0 bytes. In such case, the memset
9298 // intrinsic can be used.9358 // intrinsic can be used.
9299 if (try elem_val.hasRepeatedByteRepr(elem_ty, mod)) |byte_val| {9359 if (try elem_val.hasRepeatedByteRepr(elem_ty, pt)) |byte_val| {
9300 const fill_byte = try o.builder.intValue(.i8, byte_val);9360 const fill_byte = try o.builder.intValue(.i8, byte_val);
9301 const len = try self.sliceOrArrayLenInBytes(dest_slice, ptr_ty);9361 const len = try self.sliceOrArrayLenInBytes(dest_slice, ptr_ty);
9302 if (intrinsic_len0_traps) {9362 if (intrinsic_len0_traps) {
...@@ -9309,7 +9369,7 @@ pub const FuncGen = struct {...@@ -9309,7 +9369,7 @@ pub const FuncGen = struct {
9309 }9369 }
93109370
9311 const value = try self.resolveInst(bin_op.rhs);9371 const value = try self.resolveInst(bin_op.rhs);
9312 const elem_abi_size = elem_ty.abiSize(mod);9372 const elem_abi_size = elem_ty.abiSize(pt);
93139373
9314 if (elem_abi_size == 1) {9374 if (elem_abi_size == 1) {
9315 // In this case we can take advantage of LLVM's intrinsic.9375 // In this case we can take advantage of LLVM's intrinsic.
...@@ -9361,9 +9421,9 @@ pub const FuncGen = struct {...@@ -9361,9 +9421,9 @@ pub const FuncGen = struct {
9361 _ = try self.wip.brCond(end, body_block, end_block);9421 _ = try self.wip.brCond(end, body_block, end_block);
93629422
9363 self.wip.cursor = .{ .block = body_block };9423 self.wip.cursor = .{ .block = body_block };
9364 const elem_abi_align = elem_ty.abiAlignment(mod);9424 const elem_abi_align = elem_ty.abiAlignment(pt);
9365 const it_ptr_align = InternPool.Alignment.fromLlvm(dest_ptr_align).min(elem_abi_align).toLlvm();9425 const it_ptr_align = InternPool.Alignment.fromLlvm(dest_ptr_align).min(elem_abi_align).toLlvm();
9366 if (isByRef(elem_ty, mod)) {9426 if (isByRef(elem_ty, pt)) {
9367 _ = try self.wip.callMemCpy(9427 _ = try self.wip.callMemCpy(
9368 it_ptr.toValue(),9428 it_ptr.toValue(),
9369 it_ptr_align,9429 it_ptr_align,
...@@ -9405,7 +9465,8 @@ pub const FuncGen = struct {...@@ -9405,7 +9465,8 @@ pub const FuncGen = struct {
94059465
9406 fn airMemcpy(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {9466 fn airMemcpy(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
9407 const o = self.dg.object;9467 const o = self.dg.object;
9408 const mod = o.module;9468 const pt = o.pt;
9469 const mod = pt.zcu;
9409 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;9470 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
9410 const dest_slice = try self.resolveInst(bin_op.lhs);9471 const dest_slice = try self.resolveInst(bin_op.lhs);
9411 const dest_ptr_ty = self.typeOf(bin_op.lhs);9472 const dest_ptr_ty = self.typeOf(bin_op.lhs);
...@@ -9434,9 +9495,9 @@ pub const FuncGen = struct {...@@ -9434,9 +9495,9 @@ pub const FuncGen = struct {
9434 self.wip.cursor = .{ .block = memcpy_block };9495 self.wip.cursor = .{ .block = memcpy_block };
9435 _ = try self.wip.callMemCpy(9496 _ = try self.wip.callMemCpy(
9436 dest_ptr,9497 dest_ptr,
9437 dest_ptr_ty.ptrAlignment(mod).toLlvm(),9498 dest_ptr_ty.ptrAlignment(pt).toLlvm(),
9438 src_ptr,9499 src_ptr,
9439 src_ptr_ty.ptrAlignment(mod).toLlvm(),9500 src_ptr_ty.ptrAlignment(pt).toLlvm(),
9440 len,9501 len,
9441 access_kind,9502 access_kind,
9442 );9503 );
...@@ -9447,9 +9508,9 @@ pub const FuncGen = struct {...@@ -9447,9 +9508,9 @@ pub const FuncGen = struct {
94479508
9448 _ = try self.wip.callMemCpy(9509 _ = try self.wip.callMemCpy(
9449 dest_ptr,9510 dest_ptr,
9450 dest_ptr_ty.ptrAlignment(mod).toLlvm(),9511 dest_ptr_ty.ptrAlignment(pt).toLlvm(),
9451 src_ptr,9512 src_ptr,
9452 src_ptr_ty.ptrAlignment(mod).toLlvm(),9513 src_ptr_ty.ptrAlignment(pt).toLlvm(),
9453 len,9514 len,
9454 access_kind,9515 access_kind,
9455 );9516 );
...@@ -9458,10 +9519,11 @@ pub const FuncGen = struct {...@@ -9458,10 +9519,11 @@ pub const FuncGen = struct {
94589519
9459 fn airSetUnionTag(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {9520 fn airSetUnionTag(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
9460 const o = self.dg.object;9521 const o = self.dg.object;
9461 const mod = o.module;9522 const pt = o.pt;
9523 const mod = pt.zcu;
9462 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;9524 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
9463 const un_ty = self.typeOf(bin_op.lhs).childType(mod);9525 const un_ty = self.typeOf(bin_op.lhs).childType(mod);
9464 const layout = un_ty.unionGetLayout(mod);9526 const layout = un_ty.unionGetLayout(pt);
9465 if (layout.tag_size == 0) return .none;9527 if (layout.tag_size == 0) return .none;
9466 const union_ptr = try self.resolveInst(bin_op.lhs);9528 const union_ptr = try self.resolveInst(bin_op.lhs);
9467 const new_tag = try self.resolveInst(bin_op.rhs);9529 const new_tag = try self.resolveInst(bin_op.rhs);
...@@ -9479,13 +9541,13 @@ pub const FuncGen = struct {...@@ -9479,13 +9541,13 @@ pub const FuncGen = struct {
94799541
9480 fn airGetUnionTag(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {9542 fn airGetUnionTag(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
9481 const o = self.dg.object;9543 const o = self.dg.object;
9482 const mod = o.module;9544 const pt = o.pt;
9483 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;9545 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
9484 const un_ty = self.typeOf(ty_op.operand);9546 const un_ty = self.typeOf(ty_op.operand);
9485 const layout = un_ty.unionGetLayout(mod);9547 const layout = un_ty.unionGetLayout(pt);
9486 if (layout.tag_size == 0) return .none;9548 if (layout.tag_size == 0) return .none;
9487 const union_handle = try self.resolveInst(ty_op.operand);9549 const union_handle = try self.resolveInst(ty_op.operand);
9488 if (isByRef(un_ty, mod)) {9550 if (isByRef(un_ty, pt)) {
9489 const llvm_un_ty = try o.lowerType(un_ty);9551 const llvm_un_ty = try o.lowerType(un_ty);
9490 if (layout.payload_size == 0)9552 if (layout.payload_size == 0)
9491 return self.wip.load(.normal, llvm_un_ty, union_handle, .default, "");9553 return self.wip.load(.normal, llvm_un_ty, union_handle, .default, "");
...@@ -9554,7 +9616,7 @@ pub const FuncGen = struct {...@@ -9554,7 +9616,7 @@ pub const FuncGen = struct {
95549616
9555 fn airByteSwap(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {9617 fn airByteSwap(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
9556 const o = self.dg.object;9618 const o = self.dg.object;
9557 const mod = o.module;9619 const mod = o.pt.zcu;
9558 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;9620 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
9559 const operand_ty = self.typeOf(ty_op.operand);9621 const operand_ty = self.typeOf(ty_op.operand);
9560 var bits = operand_ty.intInfo(mod).bits;9622 var bits = operand_ty.intInfo(mod).bits;
...@@ -9588,7 +9650,7 @@ pub const FuncGen = struct {...@@ -9588,7 +9650,7 @@ pub const FuncGen = struct {
95889650
9589 fn airErrorSetHasValue(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {9651 fn airErrorSetHasValue(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
9590 const o = self.dg.object;9652 const o = self.dg.object;
9591 const mod = o.module;9653 const mod = o.pt.zcu;
9592 const ip = &mod.intern_pool;9654 const ip = &mod.intern_pool;
9593 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;9655 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
9594 const operand = try self.resolveInst(ty_op.operand);9656 const operand = try self.resolveInst(ty_op.operand);
...@@ -9638,7 +9700,8 @@ pub const FuncGen = struct {...@@ -9638,7 +9700,8 @@ pub const FuncGen = struct {
96389700
9639 fn getIsNamedEnumValueFunction(self: *FuncGen, enum_ty: Type) !Builder.Function.Index {9701 fn getIsNamedEnumValueFunction(self: *FuncGen, enum_ty: Type) !Builder.Function.Index {
9640 const o = self.dg.object;9702 const o = self.dg.object;
9641 const zcu = o.module;9703 const pt = o.pt;
9704 const zcu = pt.zcu;
9642 const enum_type = zcu.intern_pool.loadEnumType(enum_ty.toIntern());9705 const enum_type = zcu.intern_pool.loadEnumType(enum_ty.toIntern());
96439706
9644 // TODO: detect when the type changes and re-emit this function.9707 // TODO: detect when the type changes and re-emit this function.
...@@ -9646,7 +9709,7 @@ pub const FuncGen = struct {...@@ -9646,7 +9709,7 @@ pub const FuncGen = struct {
9646 if (gop.found_existing) return gop.value_ptr.*;9709 if (gop.found_existing) return gop.value_ptr.*;
9647 errdefer assert(o.named_enum_map.remove(enum_type.decl));9710 errdefer assert(o.named_enum_map.remove(enum_type.decl));
96489711
9649 const fqn = try zcu.declPtr(enum_type.decl).fullyQualifiedName(zcu);9712 const fqn = try zcu.declPtr(enum_type.decl).fullyQualifiedName(pt);
9650 const target = zcu.root_mod.resolved_target.result;9713 const target = zcu.root_mod.resolved_target.result;
9651 const function_index = try o.builder.addFunction(9714 const function_index = try o.builder.addFunction(
9652 try o.builder.fnType(.i1, &.{try o.lowerType(Type.fromInterned(enum_type.tag_ty))}, .normal),9715 try o.builder.fnType(.i1, &.{try o.lowerType(Type.fromInterned(enum_type.tag_ty))}, .normal),
...@@ -9678,7 +9741,7 @@ pub const FuncGen = struct {...@@ -9678,7 +9741,7 @@ pub const FuncGen = struct {
96789741
9679 for (0..enum_type.names.len) |field_index| {9742 for (0..enum_type.names.len) |field_index| {
9680 const this_tag_int_value = try o.lowerValue(9743 const this_tag_int_value = try o.lowerValue(
9681 (try zcu.enumValueFieldIndex(enum_ty, @intCast(field_index))).toIntern(),9744 (try pt.enumValueFieldIndex(enum_ty, @intCast(field_index))).toIntern(),
9682 );9745 );
9683 try wip_switch.addCase(this_tag_int_value, named_block, &wip);9746 try wip_switch.addCase(this_tag_int_value, named_block, &wip);
9684 }9747 }
...@@ -9745,7 +9808,8 @@ pub const FuncGen = struct {...@@ -9745,7 +9808,8 @@ pub const FuncGen = struct {
97459808
9746 fn airShuffle(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {9809 fn airShuffle(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
9747 const o = self.dg.object;9810 const o = self.dg.object;
9748 const mod = o.module;9811 const pt = o.pt;
9812 const mod = pt.zcu;
9749 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;9813 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
9750 const extra = self.air.extraData(Air.Shuffle, ty_pl.payload).data;9814 const extra = self.air.extraData(Air.Shuffle, ty_pl.payload).data;
9751 const a = try self.resolveInst(extra.a);9815 const a = try self.resolveInst(extra.a);
...@@ -9763,11 +9827,11 @@ pub const FuncGen = struct {...@@ -9763,11 +9827,11 @@ pub const FuncGen = struct {
9763 defer self.gpa.free(values);9827 defer self.gpa.free(values);
97649828
9765 for (values, 0..) |*val, i| {9829 for (values, 0..) |*val, i| {
9766 const elem = try mask.elemValue(mod, i);9830 const elem = try mask.elemValue(pt, i);
9767 if (elem.isUndef(mod)) {9831 if (elem.isUndef(mod)) {
9768 val.* = try o.builder.undefConst(.i32);9832 val.* = try o.builder.undefConst(.i32);
9769 } else {9833 } else {
9770 const int = elem.toSignedInt(mod);9834 const int = elem.toSignedInt(pt);
9771 const unsigned: u32 = @intCast(if (int >= 0) int else ~int + a_len);9835 const unsigned: u32 = @intCast(if (int >= 0) int else ~int + a_len);
9772 val.* = try o.builder.intConst(.i32, unsigned);9836 val.* = try o.builder.intConst(.i32, unsigned);
9773 }9837 }
...@@ -9854,7 +9918,7 @@ pub const FuncGen = struct {...@@ -9854,7 +9918,7 @@ pub const FuncGen = struct {
98549918
9855 fn airReduce(self: *FuncGen, inst: Air.Inst.Index, fast: Builder.FastMathKind) !Builder.Value {9919 fn airReduce(self: *FuncGen, inst: Air.Inst.Index, fast: Builder.FastMathKind) !Builder.Value {
9856 const o = self.dg.object;9920 const o = self.dg.object;
9857 const mod = o.module;9921 const mod = o.pt.zcu;
9858 const target = mod.getTarget();9922 const target = mod.getTarget();
98599923
9860 const reduce = self.air.instructions.items(.data)[@intFromEnum(inst)].reduce;9924 const reduce = self.air.instructions.items(.data)[@intFromEnum(inst)].reduce;
...@@ -9964,7 +10028,8 @@ pub const FuncGen = struct {...@@ -9964,7 +10028,8 @@ pub const FuncGen = struct {
996410028
9965 fn airAggregateInit(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {10029 fn airAggregateInit(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
9966 const o = self.dg.object;10030 const o = self.dg.object;
9967 const mod = o.module;10031 const pt = o.pt;
10032 const mod = pt.zcu;
9968 const ip = &mod.intern_pool;10033 const ip = &mod.intern_pool;
9969 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;10034 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
9970 const result_ty = self.typeOfIndex(inst);10035 const result_ty = self.typeOfIndex(inst);
...@@ -9986,16 +10051,16 @@ pub const FuncGen = struct {...@@ -9986,16 +10051,16 @@ pub const FuncGen = struct {
9986 if (mod.typeToPackedStruct(result_ty)) |struct_type| {10051 if (mod.typeToPackedStruct(result_ty)) |struct_type| {
9987 const backing_int_ty = struct_type.backingIntType(ip).*;10052 const backing_int_ty = struct_type.backingIntType(ip).*;
9988 assert(backing_int_ty != .none);10053 assert(backing_int_ty != .none);
9989 const big_bits = Type.fromInterned(backing_int_ty).bitSize(mod);10054 const big_bits = Type.fromInterned(backing_int_ty).bitSize(pt);
9990 const int_ty = try o.builder.intType(@intCast(big_bits));10055 const int_ty = try o.builder.intType(@intCast(big_bits));
9991 comptime assert(Type.packed_struct_layout_version == 2);10056 comptime assert(Type.packed_struct_layout_version == 2);
9992 var running_int = try o.builder.intValue(int_ty, 0);10057 var running_int = try o.builder.intValue(int_ty, 0);
9993 var running_bits: u16 = 0;10058 var running_bits: u16 = 0;
9994 for (elements, struct_type.field_types.get(ip)) |elem, field_ty| {10059 for (elements, struct_type.field_types.get(ip)) |elem, field_ty| {
9995 if (!Type.fromInterned(field_ty).hasRuntimeBitsIgnoreComptime(mod)) continue;10060 if (!Type.fromInterned(field_ty).hasRuntimeBitsIgnoreComptime(pt)) continue;
999610061
9997 const non_int_val = try self.resolveInst(elem);10062 const non_int_val = try self.resolveInst(elem);
9998 const ty_bit_size: u16 = @intCast(Type.fromInterned(field_ty).bitSize(mod));10063 const ty_bit_size: u16 = @intCast(Type.fromInterned(field_ty).bitSize(pt));
9999 const small_int_ty = try o.builder.intType(ty_bit_size);10064 const small_int_ty = try o.builder.intType(ty_bit_size);
10000 const small_int_val = if (Type.fromInterned(field_ty).isPtrAtRuntime(mod))10065 const small_int_val = if (Type.fromInterned(field_ty).isPtrAtRuntime(mod))
10001 try self.wip.cast(.ptrtoint, non_int_val, small_int_ty, "")10066 try self.wip.cast(.ptrtoint, non_int_val, small_int_ty, "")
...@@ -10013,23 +10078,23 @@ pub const FuncGen = struct {...@@ -10013,23 +10078,23 @@ pub const FuncGen = struct {
1001310078
10014 assert(result_ty.containerLayout(mod) != .@"packed");10079 assert(result_ty.containerLayout(mod) != .@"packed");
1001510080
10016 if (isByRef(result_ty, mod)) {10081 if (isByRef(result_ty, pt)) {
10017 // TODO in debug builds init to undef so that the padding will be 0xaa10082 // TODO in debug builds init to undef so that the padding will be 0xaa
10018 // even if we fully populate the fields.10083 // even if we fully populate the fields.
10019 const alignment = result_ty.abiAlignment(mod).toLlvm();10084 const alignment = result_ty.abiAlignment(pt).toLlvm();
10020 const alloca_inst = try self.buildAllocaWorkaround(result_ty, alignment);10085 const alloca_inst = try self.buildAllocaWorkaround(result_ty, alignment);
1002110086
10022 for (elements, 0..) |elem, i| {10087 for (elements, 0..) |elem, i| {
10023 if ((try result_ty.structFieldValueComptime(mod, i)) != null) continue;10088 if ((try result_ty.structFieldValueComptime(pt, i)) != null) continue;
1002410089
10025 const llvm_elem = try self.resolveInst(elem);10090 const llvm_elem = try self.resolveInst(elem);
10026 const llvm_i = o.llvmFieldIndex(result_ty, i).?;10091 const llvm_i = o.llvmFieldIndex(result_ty, i).?;
10027 const field_ptr =10092 const field_ptr =
10028 try self.wip.gepStruct(llvm_result_ty, alloca_inst, llvm_i, "");10093 try self.wip.gepStruct(llvm_result_ty, alloca_inst, llvm_i, "");
10029 const field_ptr_ty = try mod.ptrType(.{10094 const field_ptr_ty = try pt.ptrType(.{
10030 .child = self.typeOf(elem).toIntern(),10095 .child = self.typeOf(elem).toIntern(),
10031 .flags = .{10096 .flags = .{
10032 .alignment = result_ty.structFieldAlign(i, mod),10097 .alignment = result_ty.structFieldAlign(i, pt),
10033 },10098 },
10034 });10099 });
10035 try self.store(field_ptr, field_ptr_ty, llvm_elem, .none);10100 try self.store(field_ptr, field_ptr_ty, llvm_elem, .none);
...@@ -10039,7 +10104,7 @@ pub const FuncGen = struct {...@@ -10039,7 +10104,7 @@ pub const FuncGen = struct {
10039 } else {10104 } else {
10040 var result = try o.builder.poisonValue(llvm_result_ty);10105 var result = try o.builder.poisonValue(llvm_result_ty);
10041 for (elements, 0..) |elem, i| {10106 for (elements, 0..) |elem, i| {
10042 if ((try result_ty.structFieldValueComptime(mod, i)) != null) continue;10107 if ((try result_ty.structFieldValueComptime(pt, i)) != null) continue;
1004310108
10044 const llvm_elem = try self.resolveInst(elem);10109 const llvm_elem = try self.resolveInst(elem);
10045 const llvm_i = o.llvmFieldIndex(result_ty, i).?;10110 const llvm_i = o.llvmFieldIndex(result_ty, i).?;
...@@ -10049,15 +10114,15 @@ pub const FuncGen = struct {...@@ -10049,15 +10114,15 @@ pub const FuncGen = struct {
10049 }10114 }
10050 },10115 },
10051 .Array => {10116 .Array => {
10052 assert(isByRef(result_ty, mod));10117 assert(isByRef(result_ty, pt));
1005310118
10054 const llvm_usize = try o.lowerType(Type.usize);10119 const llvm_usize = try o.lowerType(Type.usize);
10055 const usize_zero = try o.builder.intValue(llvm_usize, 0);10120 const usize_zero = try o.builder.intValue(llvm_usize, 0);
10056 const alignment = result_ty.abiAlignment(mod).toLlvm();10121 const alignment = result_ty.abiAlignment(pt).toLlvm();
10057 const alloca_inst = try self.buildAllocaWorkaround(result_ty, alignment);10122 const alloca_inst = try self.buildAllocaWorkaround(result_ty, alignment);
1005810123
10059 const array_info = result_ty.arrayInfo(mod);10124 const array_info = result_ty.arrayInfo(mod);
10060 const elem_ptr_ty = try mod.ptrType(.{10125 const elem_ptr_ty = try pt.ptrType(.{
10061 .child = array_info.elem_type.toIntern(),10126 .child = array_info.elem_type.toIntern(),
10062 });10127 });
1006310128
...@@ -10084,21 +10149,22 @@ pub const FuncGen = struct {...@@ -10084,21 +10149,22 @@ pub const FuncGen = struct {
1008410149
10085 fn airUnionInit(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {10150 fn airUnionInit(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
10086 const o = self.dg.object;10151 const o = self.dg.object;
10087 const mod = o.module;10152 const pt = o.pt;
10153 const mod = pt.zcu;
10088 const ip = &mod.intern_pool;10154 const ip = &mod.intern_pool;
10089 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;10155 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
10090 const extra = self.air.extraData(Air.UnionInit, ty_pl.payload).data;10156 const extra = self.air.extraData(Air.UnionInit, ty_pl.payload).data;
10091 const union_ty = self.typeOfIndex(inst);10157 const union_ty = self.typeOfIndex(inst);
10092 const union_llvm_ty = try o.lowerType(union_ty);10158 const union_llvm_ty = try o.lowerType(union_ty);
10093 const layout = union_ty.unionGetLayout(mod);10159 const layout = union_ty.unionGetLayout(pt);
10094 const union_obj = mod.typeToUnion(union_ty).?;10160 const union_obj = mod.typeToUnion(union_ty).?;
1009510161
10096 if (union_obj.getLayout(ip) == .@"packed") {10162 if (union_obj.getLayout(ip) == .@"packed") {
10097 const big_bits = union_ty.bitSize(mod);10163 const big_bits = union_ty.bitSize(pt);
10098 const int_llvm_ty = try o.builder.intType(@intCast(big_bits));10164 const int_llvm_ty = try o.builder.intType(@intCast(big_bits));
10099 const field_ty = Type.fromInterned(union_obj.field_types.get(ip)[extra.field_index]);10165 const field_ty = Type.fromInterned(union_obj.field_types.get(ip)[extra.field_index]);
10100 const non_int_val = try self.resolveInst(extra.init);10166 const non_int_val = try self.resolveInst(extra.init);
10101 const small_int_ty = try o.builder.intType(@intCast(field_ty.bitSize(mod)));10167 const small_int_ty = try o.builder.intType(@intCast(field_ty.bitSize(pt)));
10102 const small_int_val = if (field_ty.isPtrAtRuntime(mod))10168 const small_int_val = if (field_ty.isPtrAtRuntime(mod))
10103 try self.wip.cast(.ptrtoint, non_int_val, small_int_ty, "")10169 try self.wip.cast(.ptrtoint, non_int_val, small_int_ty, "")
10104 else10170 else
...@@ -10110,19 +10176,19 @@ pub const FuncGen = struct {...@@ -10110,19 +10176,19 @@ pub const FuncGen = struct {
10110 const tag_ty = union_ty.unionTagTypeHypothetical(mod);10176 const tag_ty = union_ty.unionTagTypeHypothetical(mod);
10111 const union_field_name = union_obj.loadTagType(ip).names.get(ip)[extra.field_index];10177 const union_field_name = union_obj.loadTagType(ip).names.get(ip)[extra.field_index];
10112 const enum_field_index = tag_ty.enumFieldIndex(union_field_name, mod).?;10178 const enum_field_index = tag_ty.enumFieldIndex(union_field_name, mod).?;
10113 const tag_val = try mod.enumValueFieldIndex(tag_ty, enum_field_index);10179 const tag_val = try pt.enumValueFieldIndex(tag_ty, enum_field_index);
10114 break :blk try tag_val.intFromEnum(tag_ty, mod);10180 break :blk try tag_val.intFromEnum(tag_ty, pt);
10115 };10181 };
10116 if (layout.payload_size == 0) {10182 if (layout.payload_size == 0) {
10117 if (layout.tag_size == 0) {10183 if (layout.tag_size == 0) {
10118 return .none;10184 return .none;
10119 }10185 }
10120 assert(!isByRef(union_ty, mod));10186 assert(!isByRef(union_ty, pt));
10121 var big_int_space: Value.BigIntSpace = undefined;10187 var big_int_space: Value.BigIntSpace = undefined;
10122 const tag_big_int = tag_int_val.toBigInt(&big_int_space, mod);10188 const tag_big_int = tag_int_val.toBigInt(&big_int_space, pt);
10123 return try o.builder.bigIntValue(union_llvm_ty, tag_big_int);10189 return try o.builder.bigIntValue(union_llvm_ty, tag_big_int);
10124 }10190 }
10125 assert(isByRef(union_ty, mod));10191 assert(isByRef(union_ty, pt));
10126 // The llvm type of the alloca will be the named LLVM union type, and will not10192 // The llvm type of the alloca will be the named LLVM union type, and will not
10127 // necessarily match the format that we need, depending on which tag is active.10193 // necessarily match the format that we need, depending on which tag is active.
10128 // We must construct the correct unnamed struct type here, in order to then set10194 // We must construct the correct unnamed struct type here, in order to then set
...@@ -10132,14 +10198,14 @@ pub const FuncGen = struct {...@@ -10132,14 +10198,14 @@ pub const FuncGen = struct {
10132 const llvm_payload = try self.resolveInst(extra.init);10198 const llvm_payload = try self.resolveInst(extra.init);
10133 const field_ty = Type.fromInterned(union_obj.field_types.get(ip)[extra.field_index]);10199 const field_ty = Type.fromInterned(union_obj.field_types.get(ip)[extra.field_index]);
10134 const field_llvm_ty = try o.lowerType(field_ty);10200 const field_llvm_ty = try o.lowerType(field_ty);
10135 const field_size = field_ty.abiSize(mod);10201 const field_size = field_ty.abiSize(pt);
10136 const field_align = mod.unionFieldNormalAlignment(union_obj, extra.field_index);10202 const field_align = pt.unionFieldNormalAlignment(union_obj, extra.field_index);
10137 const llvm_usize = try o.lowerType(Type.usize);10203 const llvm_usize = try o.lowerType(Type.usize);
10138 const usize_zero = try o.builder.intValue(llvm_usize, 0);10204 const usize_zero = try o.builder.intValue(llvm_usize, 0);
1013910205
10140 const llvm_union_ty = t: {10206 const llvm_union_ty = t: {
10141 const payload_ty = p: {10207 const payload_ty = p: {
10142 if (!field_ty.hasRuntimeBitsIgnoreComptime(mod)) {10208 if (!field_ty.hasRuntimeBitsIgnoreComptime(pt)) {
10143 const padding_len = layout.payload_size;10209 const padding_len = layout.payload_size;
10144 break :p try o.builder.arrayType(padding_len, .i8);10210 break :p try o.builder.arrayType(padding_len, .i8);
10145 }10211 }
...@@ -10169,7 +10235,7 @@ pub const FuncGen = struct {...@@ -10169,7 +10235,7 @@ pub const FuncGen = struct {
1016910235
10170 // Now we follow the layout as expressed above with GEP instructions to set the10236 // Now we follow the layout as expressed above with GEP instructions to set the
10171 // tag and the payload.10237 // tag and the payload.
10172 const field_ptr_ty = try mod.ptrType(.{10238 const field_ptr_ty = try pt.ptrType(.{
10173 .child = field_ty.toIntern(),10239 .child = field_ty.toIntern(),
10174 .flags = .{ .alignment = field_align },10240 .flags = .{ .alignment = field_align },
10175 });10241 });
...@@ -10195,9 +10261,9 @@ pub const FuncGen = struct {...@@ -10195,9 +10261,9 @@ pub const FuncGen = struct {
10195 const field_ptr = try self.wip.gep(.inbounds, llvm_union_ty, result_ptr, &indices, "");10261 const field_ptr = try self.wip.gep(.inbounds, llvm_union_ty, result_ptr, &indices, "");
10196 const tag_ty = try o.lowerType(Type.fromInterned(union_obj.enum_tag_ty));10262 const tag_ty = try o.lowerType(Type.fromInterned(union_obj.enum_tag_ty));
10197 var big_int_space: Value.BigIntSpace = undefined;10263 var big_int_space: Value.BigIntSpace = undefined;
10198 const tag_big_int = tag_int_val.toBigInt(&big_int_space, mod);10264 const tag_big_int = tag_int_val.toBigInt(&big_int_space, pt);
10199 const llvm_tag = try o.builder.bigIntValue(tag_ty, tag_big_int);10265 const llvm_tag = try o.builder.bigIntValue(tag_ty, tag_big_int);
10200 const tag_alignment = Type.fromInterned(union_obj.enum_tag_ty).abiAlignment(mod).toLlvm();10266 const tag_alignment = Type.fromInterned(union_obj.enum_tag_ty).abiAlignment(pt).toLlvm();
10201 _ = try self.wip.store(.normal, llvm_tag, field_ptr, tag_alignment);10267 _ = try self.wip.store(.normal, llvm_tag, field_ptr, tag_alignment);
10202 }10268 }
1020310269
...@@ -10223,7 +10289,7 @@ pub const FuncGen = struct {...@@ -10223,7 +10289,7 @@ pub const FuncGen = struct {
10223 // by the target.10289 // by the target.
10224 // To work around this, don't emit llvm.prefetch in this case.10290 // To work around this, don't emit llvm.prefetch in this case.
10225 // See https://bugs.llvm.org/show_bug.cgi?id=2103710291 // See https://bugs.llvm.org/show_bug.cgi?id=21037
10226 const mod = o.module;10292 const mod = o.pt.zcu;
10227 const target = mod.getTarget();10293 const target = mod.getTarget();
10228 switch (prefetch.cache) {10294 switch (prefetch.cache) {
10229 .instruction => switch (target.cpu.arch) {10295 .instruction => switch (target.cpu.arch) {
...@@ -10279,7 +10345,7 @@ pub const FuncGen = struct {...@@ -10279,7 +10345,7 @@ pub const FuncGen = struct {
1027910345
10280 fn airWorkItemId(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {10346 fn airWorkItemId(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
10281 const o = self.dg.object;10347 const o = self.dg.object;
10282 const target = o.module.getTarget();10348 const target = o.pt.zcu.getTarget();
10283 assert(target.cpu.arch == .amdgcn); // TODO is to port this function to other GPU architectures10349 assert(target.cpu.arch == .amdgcn); // TODO is to port this function to other GPU architectures
1028410350
10285 const pl_op = self.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;10351 const pl_op = self.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;
...@@ -10289,7 +10355,7 @@ pub const FuncGen = struct {...@@ -10289,7 +10355,7 @@ pub const FuncGen = struct {
1028910355
10290 fn airWorkGroupSize(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {10356 fn airWorkGroupSize(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
10291 const o = self.dg.object;10357 const o = self.dg.object;
10292 const target = o.module.getTarget();10358 const target = o.pt.zcu.getTarget();
10293 assert(target.cpu.arch == .amdgcn); // TODO is to port this function to other GPU architectures10359 assert(target.cpu.arch == .amdgcn); // TODO is to port this function to other GPU architectures
1029410360
10295 const pl_op = self.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;10361 const pl_op = self.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;
...@@ -10312,7 +10378,7 @@ pub const FuncGen = struct {...@@ -10312,7 +10378,7 @@ pub const FuncGen = struct {
1031210378
10313 fn airWorkGroupId(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {10379 fn airWorkGroupId(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
10314 const o = self.dg.object;10380 const o = self.dg.object;
10315 const target = o.module.getTarget();10381 const target = o.pt.zcu.getTarget();
10316 assert(target.cpu.arch == .amdgcn); // TODO is to port this function to other GPU architectures10382 assert(target.cpu.arch == .amdgcn); // TODO is to port this function to other GPU architectures
1031710383
10318 const pl_op = self.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;10384 const pl_op = self.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;
...@@ -10322,7 +10388,7 @@ pub const FuncGen = struct {...@@ -10322,7 +10388,7 @@ pub const FuncGen = struct {
1032210388
10323 fn getErrorNameTable(self: *FuncGen) Allocator.Error!Builder.Variable.Index {10389 fn getErrorNameTable(self: *FuncGen) Allocator.Error!Builder.Variable.Index {
10324 const o = self.dg.object;10390 const o = self.dg.object;
10325 const mod = o.module;10391 const pt = o.pt;
1032610392
10327 const table = o.error_name_table;10393 const table = o.error_name_table;
10328 if (table != .none) return table;10394 if (table != .none) return table;
...@@ -10334,7 +10400,7 @@ pub const FuncGen = struct {...@@ -10334,7 +10400,7 @@ pub const FuncGen = struct {
10334 variable_index.setMutability(.constant, &o.builder);10400 variable_index.setMutability(.constant, &o.builder);
10335 variable_index.setUnnamedAddr(.unnamed_addr, &o.builder);10401 variable_index.setUnnamedAddr(.unnamed_addr, &o.builder);
10336 variable_index.setAlignment(10402 variable_index.setAlignment(
10337 Type.slice_const_u8_sentinel_0.abiAlignment(mod).toLlvm(),10403 Type.slice_const_u8_sentinel_0.abiAlignment(pt).toLlvm(),
10338 &o.builder,10404 &o.builder,
10339 );10405 );
1034010406
...@@ -10372,15 +10438,16 @@ pub const FuncGen = struct {...@@ -10372,15 +10438,16 @@ pub const FuncGen = struct {
10372 can_elide_load: bool,10438 can_elide_load: bool,
10373 ) !Builder.Value {10439 ) !Builder.Value {
10374 const o = fg.dg.object;10440 const o = fg.dg.object;
10375 const mod = o.module;10441 const pt = o.pt;
10442 const mod = pt.zcu;
10376 const payload_ty = opt_ty.optionalChild(mod);10443 const payload_ty = opt_ty.optionalChild(mod);
1037710444
10378 if (isByRef(opt_ty, mod)) {10445 if (isByRef(opt_ty, pt)) {
10379 // We have a pointer and we need to return a pointer to the first field.10446 // We have a pointer and we need to return a pointer to the first field.
10380 const payload_ptr = try fg.wip.gepStruct(opt_llvm_ty, opt_handle, 0, "");10447 const payload_ptr = try fg.wip.gepStruct(opt_llvm_ty, opt_handle, 0, "");
1038110448
10382 const payload_alignment = payload_ty.abiAlignment(mod).toLlvm();10449 const payload_alignment = payload_ty.abiAlignment(pt).toLlvm();
10383 if (isByRef(payload_ty, mod)) {10450 if (isByRef(payload_ty, pt)) {
10384 if (can_elide_load)10451 if (can_elide_load)
10385 return payload_ptr;10452 return payload_ptr;
1038610453
...@@ -10389,7 +10456,7 @@ pub const FuncGen = struct {...@@ -10389,7 +10456,7 @@ pub const FuncGen = struct {
10389 return fg.loadTruncate(.normal, payload_ty, payload_ptr, payload_alignment);10456 return fg.loadTruncate(.normal, payload_ty, payload_ptr, payload_alignment);
10390 }10457 }
1039110458
10392 assert(!isByRef(payload_ty, mod));10459 assert(!isByRef(payload_ty, pt));
10393 return fg.wip.extractValue(opt_handle, &.{0}, "");10460 return fg.wip.extractValue(opt_handle, &.{0}, "");
10394 }10461 }
1039510462
...@@ -10400,12 +10467,12 @@ pub const FuncGen = struct {...@@ -10400,12 +10467,12 @@ pub const FuncGen = struct {
10400 non_null_bit: Builder.Value,10467 non_null_bit: Builder.Value,
10401 ) !Builder.Value {10468 ) !Builder.Value {
10402 const o = self.dg.object;10469 const o = self.dg.object;
10470 const pt = o.pt;
10403 const optional_llvm_ty = try o.lowerType(optional_ty);10471 const optional_llvm_ty = try o.lowerType(optional_ty);
10404 const non_null_field = try self.wip.cast(.zext, non_null_bit, .i8, "");10472 const non_null_field = try self.wip.cast(.zext, non_null_bit, .i8, "");
10405 const mod = o.module;
1040610473
10407 if (isByRef(optional_ty, mod)) {10474 if (isByRef(optional_ty, pt)) {
10408 const payload_alignment = optional_ty.abiAlignment(mod).toLlvm();10475 const payload_alignment = optional_ty.abiAlignment(pt).toLlvm();
10409 const alloca_inst = try self.buildAllocaWorkaround(optional_ty, payload_alignment);10476 const alloca_inst = try self.buildAllocaWorkaround(optional_ty, payload_alignment);
1041010477
10411 {10478 {
...@@ -10432,7 +10499,8 @@ pub const FuncGen = struct {...@@ -10432,7 +10499,8 @@ pub const FuncGen = struct {
10432 field_index: u32,10499 field_index: u32,
10433 ) !Builder.Value {10500 ) !Builder.Value {
10434 const o = self.dg.object;10501 const o = self.dg.object;
10435 const mod = o.module;10502 const pt = o.pt;
10503 const mod = pt.zcu;
10436 const struct_ty = struct_ptr_ty.childType(mod);10504 const struct_ty = struct_ptr_ty.childType(mod);
10437 switch (struct_ty.zigTypeTag(mod)) {10505 switch (struct_ty.zigTypeTag(mod)) {
10438 .Struct => switch (struct_ty.containerLayout(mod)) {10506 .Struct => switch (struct_ty.containerLayout(mod)) {
...@@ -10452,7 +10520,7 @@ pub const FuncGen = struct {...@@ -10452,7 +10520,7 @@ pub const FuncGen = struct {
1045210520
10453 // We have a pointer to a packed struct field that happens to be byte-aligned.10521 // We have a pointer to a packed struct field that happens to be byte-aligned.
10454 // Offset our operand pointer by the correct number of bytes.10522 // Offset our operand pointer by the correct number of bytes.
10455 const byte_offset = @divExact(mod.structPackedFieldBitOffset(struct_type, field_index) + struct_ptr_ty_info.packed_offset.bit_offset, 8);10523 const byte_offset = @divExact(pt.structPackedFieldBitOffset(struct_type, field_index) + struct_ptr_ty_info.packed_offset.bit_offset, 8);
10456 if (byte_offset == 0) return struct_ptr;10524 if (byte_offset == 0) return struct_ptr;
10457 const usize_ty = try o.lowerType(Type.usize);10525 const usize_ty = try o.lowerType(Type.usize);
10458 const llvm_index = try o.builder.intValue(usize_ty, byte_offset);10526 const llvm_index = try o.builder.intValue(usize_ty, byte_offset);
...@@ -10470,14 +10538,14 @@ pub const FuncGen = struct {...@@ -10470,14 +10538,14 @@ pub const FuncGen = struct {
10470 // the struct.10538 // the struct.
10471 const llvm_index = try o.builder.intValue(10539 const llvm_index = try o.builder.intValue(
10472 try o.lowerType(Type.usize),10540 try o.lowerType(Type.usize),
10473 @intFromBool(struct_ty.hasRuntimeBitsIgnoreComptime(mod)),10541 @intFromBool(struct_ty.hasRuntimeBitsIgnoreComptime(pt)),
10474 );10542 );
10475 return self.wip.gep(.inbounds, struct_llvm_ty, struct_ptr, &.{llvm_index}, "");10543 return self.wip.gep(.inbounds, struct_llvm_ty, struct_ptr, &.{llvm_index}, "");
10476 }10544 }
10477 },10545 },
10478 },10546 },
10479 .Union => {10547 .Union => {
10480 const layout = struct_ty.unionGetLayout(mod);10548 const layout = struct_ty.unionGetLayout(pt);
10481 if (layout.payload_size == 0 or struct_ty.containerLayout(mod) == .@"packed") return struct_ptr;10549 if (layout.payload_size == 0 or struct_ty.containerLayout(mod) == .@"packed") return struct_ptr;
10482 const payload_index = @intFromBool(layout.tag_align.compare(.gte, layout.payload_align));10550 const payload_index = @intFromBool(layout.tag_align.compare(.gte, layout.payload_align));
10483 const union_llvm_ty = try o.lowerType(struct_ty);10551 const union_llvm_ty = try o.lowerType(struct_ty);
...@@ -10500,9 +10568,10 @@ pub const FuncGen = struct {...@@ -10500,9 +10568,10 @@ pub const FuncGen = struct {
10500 // => so load the byte aligned value and trunc the unwanted bits.10568 // => so load the byte aligned value and trunc the unwanted bits.
1050110569
10502 const o = fg.dg.object;10570 const o = fg.dg.object;
10503 const mod = o.module;10571 const pt = o.pt;
10572 const mod = pt.zcu;
10504 const payload_llvm_ty = try o.lowerType(payload_ty);10573 const payload_llvm_ty = try o.lowerType(payload_ty);
10505 const abi_size = payload_ty.abiSize(mod);10574 const abi_size = payload_ty.abiSize(pt);
1050610575
10507 // llvm bug workarounds:10576 // llvm bug workarounds:
10508 const workaround_explicit_mask = o.target.cpu.arch == .powerpc and abi_size >= 4;10577 const workaround_explicit_mask = o.target.cpu.arch == .powerpc and abi_size >= 4;
...@@ -10522,7 +10591,7 @@ pub const FuncGen = struct {...@@ -10522,7 +10591,7 @@ pub const FuncGen = struct {
10522 const shifted = if (payload_llvm_ty != load_llvm_ty and o.target.cpu.arch.endian() == .big)10591 const shifted = if (payload_llvm_ty != load_llvm_ty and o.target.cpu.arch.endian() == .big)
10523 try fg.wip.bin(.lshr, loaded, try o.builder.intValue(10592 try fg.wip.bin(.lshr, loaded, try o.builder.intValue(
10524 load_llvm_ty,10593 load_llvm_ty,
10525 (payload_ty.abiSize(mod) - (std.math.divCeil(u64, payload_ty.bitSize(mod), 8) catch unreachable)) * 8,10594 (payload_ty.abiSize(pt) - (std.math.divCeil(u64, payload_ty.bitSize(pt), 8) catch unreachable)) * 8,
10526 ), "")10595 ), "")
10527 else10596 else
10528 loaded;10597 loaded;
...@@ -10546,11 +10615,11 @@ pub const FuncGen = struct {...@@ -10546,11 +10615,11 @@ pub const FuncGen = struct {
10546 access_kind: Builder.MemoryAccessKind,10615 access_kind: Builder.MemoryAccessKind,
10547 ) !Builder.Value {10616 ) !Builder.Value {
10548 const o = fg.dg.object;10617 const o = fg.dg.object;
10549 const mod = o.module;10618 const pt = o.pt;
10550 //const pointee_llvm_ty = try o.lowerType(pointee_type);10619 //const pointee_llvm_ty = try o.lowerType(pointee_type);
10551 const result_align = InternPool.Alignment.fromLlvm(ptr_alignment).max(pointee_type.abiAlignment(mod)).toLlvm();10620 const result_align = InternPool.Alignment.fromLlvm(ptr_alignment).max(pointee_type.abiAlignment(pt)).toLlvm();
10552 const result_ptr = try fg.buildAllocaWorkaround(pointee_type, result_align);10621 const result_ptr = try fg.buildAllocaWorkaround(pointee_type, result_align);
10553 const size_bytes = pointee_type.abiSize(mod);10622 const size_bytes = pointee_type.abiSize(pt);
10554 _ = try fg.wip.callMemCpy(10623 _ = try fg.wip.callMemCpy(
10555 result_ptr,10624 result_ptr,
10556 result_align,10625 result_align,
...@@ -10567,15 +10636,16 @@ pub const FuncGen = struct {...@@ -10567,15 +10636,16 @@ pub const FuncGen = struct {
10567 /// For isByRef=false types, it creates a load instruction and returns it.10636 /// For isByRef=false types, it creates a load instruction and returns it.
10568 fn load(self: *FuncGen, ptr: Builder.Value, ptr_ty: Type) !Builder.Value {10637 fn load(self: *FuncGen, ptr: Builder.Value, ptr_ty: Type) !Builder.Value {
10569 const o = self.dg.object;10638 const o = self.dg.object;
10570 const mod = o.module;10639 const pt = o.pt;
10640 const mod = pt.zcu;
10571 const info = ptr_ty.ptrInfo(mod);10641 const info = ptr_ty.ptrInfo(mod);
10572 const elem_ty = Type.fromInterned(info.child);10642 const elem_ty = Type.fromInterned(info.child);
10573 if (!elem_ty.hasRuntimeBitsIgnoreComptime(mod)) return .none;10643 if (!elem_ty.hasRuntimeBitsIgnoreComptime(pt)) return .none;
1057410644
10575 const ptr_alignment = (if (info.flags.alignment != .none)10645 const ptr_alignment = (if (info.flags.alignment != .none)
10576 @as(InternPool.Alignment, info.flags.alignment)10646 @as(InternPool.Alignment, info.flags.alignment)
10577 else10647 else
10578 elem_ty.abiAlignment(mod)).toLlvm();10648 elem_ty.abiAlignment(pt)).toLlvm();
1057910649
10580 const access_kind: Builder.MemoryAccessKind =10650 const access_kind: Builder.MemoryAccessKind =
10581 if (info.flags.is_volatile) .@"volatile" else .normal;10651 if (info.flags.is_volatile) .@"volatile" else .normal;
...@@ -10591,7 +10661,7 @@ pub const FuncGen = struct {...@@ -10591,7 +10661,7 @@ pub const FuncGen = struct {
10591 }10661 }
1059210662
10593 if (info.packed_offset.host_size == 0) {10663 if (info.packed_offset.host_size == 0) {
10594 if (isByRef(elem_ty, mod)) {10664 if (isByRef(elem_ty, pt)) {
10595 return self.loadByRef(ptr, elem_ty, ptr_alignment, access_kind);10665 return self.loadByRef(ptr, elem_ty, ptr_alignment, access_kind);
10596 }10666 }
10597 return self.loadTruncate(access_kind, elem_ty, ptr, ptr_alignment);10667 return self.loadTruncate(access_kind, elem_ty, ptr, ptr_alignment);
...@@ -10601,13 +10671,13 @@ pub const FuncGen = struct {...@@ -10601,13 +10671,13 @@ pub const FuncGen = struct {
10601 const containing_int =10671 const containing_int =
10602 try self.wip.load(access_kind, containing_int_ty, ptr, ptr_alignment, "");10672 try self.wip.load(access_kind, containing_int_ty, ptr, ptr_alignment, "");
1060310673
10604 const elem_bits = ptr_ty.childType(mod).bitSize(mod);10674 const elem_bits = ptr_ty.childType(mod).bitSize(pt);
10605 const shift_amt = try o.builder.intValue(containing_int_ty, info.packed_offset.bit_offset);10675 const shift_amt = try o.builder.intValue(containing_int_ty, info.packed_offset.bit_offset);
10606 const shifted_value = try self.wip.bin(.lshr, containing_int, shift_amt, "");10676 const shifted_value = try self.wip.bin(.lshr, containing_int, shift_amt, "");
10607 const elem_llvm_ty = try o.lowerType(elem_ty);10677 const elem_llvm_ty = try o.lowerType(elem_ty);
1060810678
10609 if (isByRef(elem_ty, mod)) {10679 if (isByRef(elem_ty, pt)) {
10610 const result_align = elem_ty.abiAlignment(mod).toLlvm();10680 const result_align = elem_ty.abiAlignment(pt).toLlvm();
10611 const result_ptr = try self.buildAllocaWorkaround(elem_ty, result_align);10681 const result_ptr = try self.buildAllocaWorkaround(elem_ty, result_align);
1061210682
10613 const same_size_int = try o.builder.intType(@intCast(elem_bits));10683 const same_size_int = try o.builder.intType(@intCast(elem_bits));
...@@ -10639,13 +10709,14 @@ pub const FuncGen = struct {...@@ -10639,13 +10709,14 @@ pub const FuncGen = struct {
10639 ordering: Builder.AtomicOrdering,10709 ordering: Builder.AtomicOrdering,
10640 ) !void {10710 ) !void {
10641 const o = self.dg.object;10711 const o = self.dg.object;
10642 const mod = o.module;10712 const pt = o.pt;
10713 const mod = pt.zcu;
10643 const info = ptr_ty.ptrInfo(mod);10714 const info = ptr_ty.ptrInfo(mod);
10644 const elem_ty = Type.fromInterned(info.child);10715 const elem_ty = Type.fromInterned(info.child);
10645 if (!elem_ty.isFnOrHasRuntimeBitsIgnoreComptime(mod)) {10716 if (!elem_ty.isFnOrHasRuntimeBitsIgnoreComptime(pt)) {
10646 return;10717 return;
10647 }10718 }
10648 const ptr_alignment = ptr_ty.ptrAlignment(mod).toLlvm();10719 const ptr_alignment = ptr_ty.ptrAlignment(pt).toLlvm();
10649 const access_kind: Builder.MemoryAccessKind =10720 const access_kind: Builder.MemoryAccessKind =
10650 if (info.flags.is_volatile) .@"volatile" else .normal;10721 if (info.flags.is_volatile) .@"volatile" else .normal;
1065110722
...@@ -10669,7 +10740,7 @@ pub const FuncGen = struct {...@@ -10669,7 +10740,7 @@ pub const FuncGen = struct {
10669 assert(ordering == .none);10740 assert(ordering == .none);
10670 const containing_int =10741 const containing_int =
10671 try self.wip.load(access_kind, containing_int_ty, ptr, ptr_alignment, "");10742 try self.wip.load(access_kind, containing_int_ty, ptr, ptr_alignment, "");
10672 const elem_bits = ptr_ty.childType(mod).bitSize(mod);10743 const elem_bits = ptr_ty.childType(mod).bitSize(pt);
10673 const shift_amt = try o.builder.intConst(containing_int_ty, info.packed_offset.bit_offset);10744 const shift_amt = try o.builder.intConst(containing_int_ty, info.packed_offset.bit_offset);
10674 // Convert to equally-sized integer type in order to perform the bit10745 // Convert to equally-sized integer type in order to perform the bit
10675 // operations on the value to store10746 // operations on the value to store
...@@ -10704,7 +10775,7 @@ pub const FuncGen = struct {...@@ -10704,7 +10775,7 @@ pub const FuncGen = struct {
10704 _ = try self.wip.store(access_kind, ored_value, ptr, ptr_alignment);10775 _ = try self.wip.store(access_kind, ored_value, ptr, ptr_alignment);
10705 return;10776 return;
10706 }10777 }
10707 if (!isByRef(elem_ty, mod)) {10778 if (!isByRef(elem_ty, pt)) {
10708 _ = try self.wip.storeAtomic(10779 _ = try self.wip.storeAtomic(
10709 access_kind,10780 access_kind,
10710 elem,10781 elem,
...@@ -10720,8 +10791,8 @@ pub const FuncGen = struct {...@@ -10720,8 +10791,8 @@ pub const FuncGen = struct {
10720 ptr,10791 ptr,
10721 ptr_alignment,10792 ptr_alignment,
10722 elem,10793 elem,
10723 elem_ty.abiAlignment(mod).toLlvm(),10794 elem_ty.abiAlignment(pt).toLlvm(),
10724 try o.builder.intValue(try o.lowerType(Type.usize), elem_ty.abiSize(mod)),10795 try o.builder.intValue(try o.lowerType(Type.usize), elem_ty.abiSize(pt)),
10725 access_kind,10796 access_kind,
10726 );10797 );
10727 }10798 }
...@@ -10747,12 +10818,13 @@ pub const FuncGen = struct {...@@ -10747,12 +10818,13 @@ pub const FuncGen = struct {
10747 a5: Builder.Value,10818 a5: Builder.Value,
10748 ) Allocator.Error!Builder.Value {10819 ) Allocator.Error!Builder.Value {
10749 const o = fg.dg.object;10820 const o = fg.dg.object;
10750 const mod = o.module;10821 const pt = o.pt;
10822 const mod = pt.zcu;
10751 const target = mod.getTarget();10823 const target = mod.getTarget();
10752 if (!target_util.hasValgrindSupport(target)) return default_value;10824 if (!target_util.hasValgrindSupport(target)) return default_value;
1075310825
10754 const llvm_usize = try o.lowerType(Type.usize);10826 const llvm_usize = try o.lowerType(Type.usize);
10755 const usize_alignment = Type.usize.abiAlignment(mod).toLlvm();10827 const usize_alignment = Type.usize.abiAlignment(pt).toLlvm();
1075610828
10757 const array_llvm_ty = try o.builder.arrayType(6, llvm_usize);10829 const array_llvm_ty = try o.builder.arrayType(6, llvm_usize);
10758 const array_ptr = if (fg.valgrind_client_request_array == .none) a: {10830 const array_ptr = if (fg.valgrind_client_request_array == .none) a: {
...@@ -10813,13 +10885,13 @@ pub const FuncGen = struct {...@@ -10813,13 +10885,13 @@ pub const FuncGen = struct {
1081310885
10814 fn typeOf(fg: *FuncGen, inst: Air.Inst.Ref) Type {10886 fn typeOf(fg: *FuncGen, inst: Air.Inst.Ref) Type {
10815 const o = fg.dg.object;10887 const o = fg.dg.object;
10816 const mod = o.module;10888 const mod = o.pt.zcu;
10817 return fg.air.typeOf(inst, &mod.intern_pool);10889 return fg.air.typeOf(inst, &mod.intern_pool);
10818 }10890 }
1081910891
10820 fn typeOfIndex(fg: *FuncGen, inst: Air.Inst.Index) Type {10892 fn typeOfIndex(fg: *FuncGen, inst: Air.Inst.Index) Type {
10821 const o = fg.dg.object;10893 const o = fg.dg.object;
10822 const mod = o.module;10894 const mod = o.pt.zcu;
10823 return fg.air.typeOfIndex(inst, &mod.intern_pool);10895 return fg.air.typeOfIndex(inst, &mod.intern_pool);
10824 }10896 }
10825};10897};
...@@ -10990,12 +11062,12 @@ fn toLlvmGlobalAddressSpace(wanted_address_space: std.builtin.AddressSpace, targ...@@ -10990,12 +11062,12 @@ fn toLlvmGlobalAddressSpace(wanted_address_space: std.builtin.AddressSpace, targ
10990 };11062 };
10991}11063}
1099211064
10993fn returnTypeByRef(zcu: *Zcu, target: std.Target, ty: Type) bool {11065fn returnTypeByRef(pt: Zcu.PerThread, target: std.Target, ty: Type) bool {
10994 if (isByRef(ty, zcu)) {11066 if (isByRef(ty, pt)) {
10995 return true;11067 return true;
10996 } else if (target.cpu.arch.isX86() and11068 } else if (target.cpu.arch.isX86() and
10997 !std.Target.x86.featureSetHas(target.cpu.features, .evex512) and11069 !std.Target.x86.featureSetHas(target.cpu.features, .evex512) and
10998 ty.totalVectorBits(zcu) >= 512)11070 ty.totalVectorBits(pt) >= 512)
10999 {11071 {
11000 // As of LLVM 18, passing a vector byval with fastcc that is 512 bits or more returns11072 // As of LLVM 18, passing a vector byval with fastcc that is 512 bits or more returns
11001 // "512-bit vector arguments require 'evex512' for AVX512"11073 // "512-bit vector arguments require 'evex512' for AVX512"
...@@ -11005,38 +11077,38 @@ fn returnTypeByRef(zcu: *Zcu, target: std.Target, ty: Type) bool {...@@ -11005,38 +11077,38 @@ fn returnTypeByRef(zcu: *Zcu, target: std.Target, ty: Type) bool {
11005 }11077 }
11006}11078}
1100711079
11008fn firstParamSRet(fn_info: InternPool.Key.FuncType, zcu: *Zcu, target: std.Target) bool {11080fn firstParamSRet(fn_info: InternPool.Key.FuncType, pt: Zcu.PerThread, target: std.Target) bool {
11009 const return_type = Type.fromInterned(fn_info.return_type);11081 const return_type = Type.fromInterned(fn_info.return_type);
11010 if (!return_type.hasRuntimeBitsIgnoreComptime(zcu)) return false;11082 if (!return_type.hasRuntimeBitsIgnoreComptime(pt)) return false;
1101111083
11012 return switch (fn_info.cc) {11084 return switch (fn_info.cc) {
11013 .Unspecified, .Inline => returnTypeByRef(zcu, target, return_type),11085 .Unspecified, .Inline => returnTypeByRef(pt, target, return_type),
11014 .C => switch (target.cpu.arch) {11086 .C => switch (target.cpu.arch) {
11015 .mips, .mipsel => false,11087 .mips, .mipsel => false,
11016 .x86 => isByRef(return_type, zcu),11088 .x86 => isByRef(return_type, pt),
11017 .x86_64 => switch (target.os.tag) {11089 .x86_64 => switch (target.os.tag) {
11018 .windows => x86_64_abi.classifyWindows(return_type, zcu) == .memory,11090 .windows => x86_64_abi.classifyWindows(return_type, pt) == .memory,
11019 else => firstParamSRetSystemV(return_type, zcu, target),11091 else => firstParamSRetSystemV(return_type, pt, target),
11020 },11092 },
11021 .wasm32 => wasm_c_abi.classifyType(return_type, zcu)[0] == .indirect,11093 .wasm32 => wasm_c_abi.classifyType(return_type, pt)[0] == .indirect,
11022 .aarch64, .aarch64_be => aarch64_c_abi.classifyType(return_type, zcu) == .memory,11094 .aarch64, .aarch64_be => aarch64_c_abi.classifyType(return_type, pt) == .memory,
11023 .arm, .armeb => switch (arm_c_abi.classifyType(return_type, zcu, .ret)) {11095 .arm, .armeb => switch (arm_c_abi.classifyType(return_type, pt, .ret)) {
11024 .memory, .i64_array => true,11096 .memory, .i64_array => true,
11025 .i32_array => |size| size != 1,11097 .i32_array => |size| size != 1,
11026 .byval => false,11098 .byval => false,
11027 },11099 },
11028 .riscv32, .riscv64 => riscv_c_abi.classifyType(return_type, zcu) == .memory,11100 .riscv32, .riscv64 => riscv_c_abi.classifyType(return_type, pt) == .memory,
11029 else => false, // TODO investigate C ABI for other architectures11101 else => false, // TODO investigate C ABI for other architectures
11030 },11102 },
11031 .SysV => firstParamSRetSystemV(return_type, zcu, target),11103 .SysV => firstParamSRetSystemV(return_type, pt, target),
11032 .Win64 => x86_64_abi.classifyWindows(return_type, zcu) == .memory,11104 .Win64 => x86_64_abi.classifyWindows(return_type, pt) == .memory,
11033 .Stdcall => !isScalar(zcu, return_type),11105 .Stdcall => !isScalar(pt.zcu, return_type),
11034 else => false,11106 else => false,
11035 };11107 };
11036}11108}
1103711109
11038fn firstParamSRetSystemV(ty: Type, zcu: *Zcu, target: std.Target) bool {11110fn firstParamSRetSystemV(ty: Type, pt: Zcu.PerThread, target: std.Target) bool {
11039 const class = x86_64_abi.classifySystemV(ty, zcu, target, .ret);11111 const class = x86_64_abi.classifySystemV(ty, pt, target, .ret);
11040 if (class[0] == .memory) return true;11112 if (class[0] == .memory) return true;
11041 if (class[0] == .x87 and class[2] != .none) return true;11113 if (class[0] == .x87 and class[2] != .none) return true;
11042 return false;11114 return false;
...@@ -11046,9 +11118,10 @@ fn firstParamSRetSystemV(ty: Type, zcu: *Zcu, target: std.Target) bool {...@@ -11046,9 +11118,10 @@ fn firstParamSRetSystemV(ty: Type, zcu: *Zcu, target: std.Target) bool {
11046/// completely differently in the function prototype to honor the C ABI, and then11118/// completely differently in the function prototype to honor the C ABI, and then
11047/// be effectively bitcasted to the actual return type.11119/// be effectively bitcasted to the actual return type.
11048fn lowerFnRetTy(o: *Object, fn_info: InternPool.Key.FuncType) Allocator.Error!Builder.Type {11120fn lowerFnRetTy(o: *Object, fn_info: InternPool.Key.FuncType) Allocator.Error!Builder.Type {
11049 const mod = o.module;11121 const pt = o.pt;
11122 const mod = pt.zcu;
11050 const return_type = Type.fromInterned(fn_info.return_type);11123 const return_type = Type.fromInterned(fn_info.return_type);
11051 if (!return_type.hasRuntimeBitsIgnoreComptime(mod)) {11124 if (!return_type.hasRuntimeBitsIgnoreComptime(pt)) {
11052 // If the return type is an error set or an error union, then we make this11125 // If the return type is an error set or an error union, then we make this
11053 // anyerror return type instead, so that it can be coerced into a function11126 // anyerror return type instead, so that it can be coerced into a function
11054 // pointer type which has anyerror as the return type.11127 // pointer type which has anyerror as the return type.
...@@ -11058,12 +11131,12 @@ fn lowerFnRetTy(o: *Object, fn_info: InternPool.Key.FuncType) Allocator.Error!Bu...@@ -11058,12 +11131,12 @@ fn lowerFnRetTy(o: *Object, fn_info: InternPool.Key.FuncType) Allocator.Error!Bu
11058 switch (fn_info.cc) {11131 switch (fn_info.cc) {
11059 .Unspecified,11132 .Unspecified,
11060 .Inline,11133 .Inline,
11061 => return if (returnTypeByRef(mod, target, return_type)) .void else o.lowerType(return_type),11134 => return if (returnTypeByRef(pt, target, return_type)) .void else o.lowerType(return_type),
1106211135
11063 .C => {11136 .C => {
11064 switch (target.cpu.arch) {11137 switch (target.cpu.arch) {
11065 .mips, .mipsel => return o.lowerType(return_type),11138 .mips, .mipsel => return o.lowerType(return_type),
11066 .x86 => return if (isByRef(return_type, mod)) .void else o.lowerType(return_type),11139 .x86 => return if (isByRef(return_type, pt)) .void else o.lowerType(return_type),
11067 .x86_64 => switch (target.os.tag) {11140 .x86_64 => switch (target.os.tag) {
11068 .windows => return lowerWin64FnRetTy(o, fn_info),11141 .windows => return lowerWin64FnRetTy(o, fn_info),
11069 else => return lowerSystemVFnRetTy(o, fn_info),11142 else => return lowerSystemVFnRetTy(o, fn_info),
...@@ -11072,36 +11145,36 @@ fn lowerFnRetTy(o: *Object, fn_info: InternPool.Key.FuncType) Allocator.Error!Bu...@@ -11072,36 +11145,36 @@ fn lowerFnRetTy(o: *Object, fn_info: InternPool.Key.FuncType) Allocator.Error!Bu
11072 if (isScalar(mod, return_type)) {11145 if (isScalar(mod, return_type)) {
11073 return o.lowerType(return_type);11146 return o.lowerType(return_type);
11074 }11147 }
11075 const classes = wasm_c_abi.classifyType(return_type, mod);11148 const classes = wasm_c_abi.classifyType(return_type, pt);
11076 if (classes[0] == .indirect or classes[0] == .none) {11149 if (classes[0] == .indirect or classes[0] == .none) {
11077 return .void;11150 return .void;
11078 }11151 }
1107911152
11080 assert(classes[0] == .direct and classes[1] == .none);11153 assert(classes[0] == .direct and classes[1] == .none);
11081 const scalar_type = wasm_c_abi.scalarType(return_type, mod);11154 const scalar_type = wasm_c_abi.scalarType(return_type, pt);
11082 return o.builder.intType(@intCast(scalar_type.abiSize(mod) * 8));11155 return o.builder.intType(@intCast(scalar_type.abiSize(pt) * 8));
11083 },11156 },
11084 .aarch64, .aarch64_be => {11157 .aarch64, .aarch64_be => {
11085 switch (aarch64_c_abi.classifyType(return_type, mod)) {11158 switch (aarch64_c_abi.classifyType(return_type, pt)) {
11086 .memory => return .void,11159 .memory => return .void,
11087 .float_array => return o.lowerType(return_type),11160 .float_array => return o.lowerType(return_type),
11088 .byval => return o.lowerType(return_type),11161 .byval => return o.lowerType(return_type),
11089 .integer => return o.builder.intType(@intCast(return_type.bitSize(mod))),11162 .integer => return o.builder.intType(@intCast(return_type.bitSize(pt))),
11090 .double_integer => return o.builder.arrayType(2, .i64),11163 .double_integer => return o.builder.arrayType(2, .i64),
11091 }11164 }
11092 },11165 },
11093 .arm, .armeb => {11166 .arm, .armeb => {
11094 switch (arm_c_abi.classifyType(return_type, mod, .ret)) {11167 switch (arm_c_abi.classifyType(return_type, pt, .ret)) {
11095 .memory, .i64_array => return .void,11168 .memory, .i64_array => return .void,
11096 .i32_array => |len| return if (len == 1) .i32 else .void,11169 .i32_array => |len| return if (len == 1) .i32 else .void,
11097 .byval => return o.lowerType(return_type),11170 .byval => return o.lowerType(return_type),
11098 }11171 }
11099 },11172 },
11100 .riscv32, .riscv64 => {11173 .riscv32, .riscv64 => {
11101 switch (riscv_c_abi.classifyType(return_type, mod)) {11174 switch (riscv_c_abi.classifyType(return_type, pt)) {
11102 .memory => return .void,11175 .memory => return .void,
11103 .integer => {11176 .integer => {
11104 return o.builder.intType(@intCast(return_type.bitSize(mod)));11177 return o.builder.intType(@intCast(return_type.bitSize(pt)));
11105 },11178 },
11106 .double_integer => {11179 .double_integer => {
11107 return o.builder.structType(.normal, &.{ .i64, .i64 });11180 return o.builder.structType(.normal, &.{ .i64, .i64 });
...@@ -11112,7 +11185,7 @@ fn lowerFnRetTy(o: *Object, fn_info: InternPool.Key.FuncType) Allocator.Error!Bu...@@ -11112,7 +11185,7 @@ fn lowerFnRetTy(o: *Object, fn_info: InternPool.Key.FuncType) Allocator.Error!Bu
11112 var types: [8]Builder.Type = undefined;11185 var types: [8]Builder.Type = undefined;
11113 for (0..return_type.structFieldCount(mod)) |field_index| {11186 for (0..return_type.structFieldCount(mod)) |field_index| {
11114 const field_ty = return_type.structFieldType(field_index, mod);11187 const field_ty = return_type.structFieldType(field_index, mod);
11115 if (!field_ty.hasRuntimeBitsIgnoreComptime(mod)) continue;11188 if (!field_ty.hasRuntimeBitsIgnoreComptime(pt)) continue;
11116 types[types_len] = try o.lowerType(field_ty);11189 types[types_len] = try o.lowerType(field_ty);
11117 types_len += 1;11190 types_len += 1;
11118 }11191 }
...@@ -11132,14 +11205,14 @@ fn lowerFnRetTy(o: *Object, fn_info: InternPool.Key.FuncType) Allocator.Error!Bu...@@ -11132,14 +11205,14 @@ fn lowerFnRetTy(o: *Object, fn_info: InternPool.Key.FuncType) Allocator.Error!Bu
11132}11205}
1113311206
11134fn lowerWin64FnRetTy(o: *Object, fn_info: InternPool.Key.FuncType) Allocator.Error!Builder.Type {11207fn lowerWin64FnRetTy(o: *Object, fn_info: InternPool.Key.FuncType) Allocator.Error!Builder.Type {
11135 const mod = o.module;11208 const pt = o.pt;
11136 const return_type = Type.fromInterned(fn_info.return_type);11209 const return_type = Type.fromInterned(fn_info.return_type);
11137 switch (x86_64_abi.classifyWindows(return_type, mod)) {11210 switch (x86_64_abi.classifyWindows(return_type, pt)) {
11138 .integer => {11211 .integer => {
11139 if (isScalar(mod, return_type)) {11212 if (isScalar(pt.zcu, return_type)) {
11140 return o.lowerType(return_type);11213 return o.lowerType(return_type);
11141 } else {11214 } else {
11142 return o.builder.intType(@intCast(return_type.abiSize(mod) * 8));11215 return o.builder.intType(@intCast(return_type.abiSize(pt) * 8));
11143 }11216 }
11144 },11217 },
11145 .win_i128 => return o.builder.vectorType(.normal, 2, .i64),11218 .win_i128 => return o.builder.vectorType(.normal, 2, .i64),
...@@ -11150,14 +11223,15 @@ fn lowerWin64FnRetTy(o: *Object, fn_info: InternPool.Key.FuncType) Allocator.Err...@@ -11150,14 +11223,15 @@ fn lowerWin64FnRetTy(o: *Object, fn_info: InternPool.Key.FuncType) Allocator.Err
11150}11223}
1115111224
11152fn lowerSystemVFnRetTy(o: *Object, fn_info: InternPool.Key.FuncType) Allocator.Error!Builder.Type {11225fn lowerSystemVFnRetTy(o: *Object, fn_info: InternPool.Key.FuncType) Allocator.Error!Builder.Type {
11153 const mod = o.module;11226 const pt = o.pt;
11227 const mod = pt.zcu;
11154 const ip = &mod.intern_pool;11228 const ip = &mod.intern_pool;
11155 const return_type = Type.fromInterned(fn_info.return_type);11229 const return_type = Type.fromInterned(fn_info.return_type);
11156 if (isScalar(mod, return_type)) {11230 if (isScalar(mod, return_type)) {
11157 return o.lowerType(return_type);11231 return o.lowerType(return_type);
11158 }11232 }
11159 const target = mod.getTarget();11233 const target = mod.getTarget();
11160 const classes = x86_64_abi.classifySystemV(return_type, mod, target, .ret);11234 const classes = x86_64_abi.classifySystemV(return_type, pt, target, .ret);
11161 if (classes[0] == .memory) return .void;11235 if (classes[0] == .memory) return .void;
11162 var types_index: u32 = 0;11236 var types_index: u32 = 0;
11163 var types_buffer: [8]Builder.Type = undefined;11237 var types_buffer: [8]Builder.Type = undefined;
...@@ -11249,8 +11323,7 @@ const ParamTypeIterator = struct {...@@ -11249,8 +11323,7 @@ const ParamTypeIterator = struct {
1124911323
11250 pub fn next(it: *ParamTypeIterator) Allocator.Error!?Lowering {11324 pub fn next(it: *ParamTypeIterator) Allocator.Error!?Lowering {
11251 if (it.zig_index >= it.fn_info.param_types.len) return null;11325 if (it.zig_index >= it.fn_info.param_types.len) return null;
11252 const zcu = it.object.module;11326 const ip = &it.object.pt.zcu.intern_pool;
11253 const ip = &zcu.intern_pool;
11254 const ty = it.fn_info.param_types.get(ip)[it.zig_index];11327 const ty = it.fn_info.param_types.get(ip)[it.zig_index];
11255 it.byval_attr = false;11328 it.byval_attr = false;
11256 return nextInner(it, Type.fromInterned(ty));11329 return nextInner(it, Type.fromInterned(ty));
...@@ -11258,8 +11331,7 @@ const ParamTypeIterator = struct {...@@ -11258,8 +11331,7 @@ const ParamTypeIterator = struct {
1125811331
11259 /// `airCall` uses this instead of `next` so that it can take into account variadic functions.11332 /// `airCall` uses this instead of `next` so that it can take into account variadic functions.
11260 pub fn nextCall(it: *ParamTypeIterator, fg: *FuncGen, args: []const Air.Inst.Ref) Allocator.Error!?Lowering {11333 pub fn nextCall(it: *ParamTypeIterator, fg: *FuncGen, args: []const Air.Inst.Ref) Allocator.Error!?Lowering {
11261 const zcu = it.object.module;11334 const ip = &it.object.pt.zcu.intern_pool;
11262 const ip = &zcu.intern_pool;
11263 if (it.zig_index >= it.fn_info.param_types.len) {11335 if (it.zig_index >= it.fn_info.param_types.len) {
11264 if (it.zig_index >= args.len) {11336 if (it.zig_index >= args.len) {
11265 return null;11337 return null;
...@@ -11272,10 +11344,11 @@ const ParamTypeIterator = struct {...@@ -11272,10 +11344,11 @@ const ParamTypeIterator = struct {
11272 }11344 }
1127311345
11274 fn nextInner(it: *ParamTypeIterator, ty: Type) Allocator.Error!?Lowering {11346 fn nextInner(it: *ParamTypeIterator, ty: Type) Allocator.Error!?Lowering {
11275 const zcu = it.object.module;11347 const pt = it.object.pt;
11348 const zcu = pt.zcu;
11276 const target = zcu.getTarget();11349 const target = zcu.getTarget();
1127711350
11278 if (!ty.hasRuntimeBitsIgnoreComptime(zcu)) {11351 if (!ty.hasRuntimeBitsIgnoreComptime(pt)) {
11279 it.zig_index += 1;11352 it.zig_index += 1;
11280 return .no_bits;11353 return .no_bits;
11281 }11354 }
...@@ -11288,11 +11361,11 @@ const ParamTypeIterator = struct {...@@ -11288,11 +11361,11 @@ const ParamTypeIterator = struct {
11288 {11361 {
11289 it.llvm_index += 1;11362 it.llvm_index += 1;
11290 return .slice;11363 return .slice;
11291 } else if (isByRef(ty, zcu)) {11364 } else if (isByRef(ty, pt)) {
11292 return .byref;11365 return .byref;
11293 } else if (target.cpu.arch.isX86() and11366 } else if (target.cpu.arch.isX86() and
11294 !std.Target.x86.featureSetHas(target.cpu.features, .evex512) and11367 !std.Target.x86.featureSetHas(target.cpu.features, .evex512) and
11295 ty.totalVectorBits(zcu) >= 512)11368 ty.totalVectorBits(pt) >= 512)
11296 {11369 {
11297 // As of LLVM 18, passing a vector byval with fastcc that is 512 bits or more returns11370 // As of LLVM 18, passing a vector byval with fastcc that is 512 bits or more returns
11298 // "512-bit vector arguments require 'evex512' for AVX512"11371 // "512-bit vector arguments require 'evex512' for AVX512"
...@@ -11320,7 +11393,7 @@ const ParamTypeIterator = struct {...@@ -11320,7 +11393,7 @@ const ParamTypeIterator = struct {
11320 if (isScalar(zcu, ty)) {11393 if (isScalar(zcu, ty)) {
11321 return .byval;11394 return .byval;
11322 }11395 }
11323 const classes = wasm_c_abi.classifyType(ty, zcu);11396 const classes = wasm_c_abi.classifyType(ty, pt);
11324 if (classes[0] == .indirect) {11397 if (classes[0] == .indirect) {
11325 return .byref;11398 return .byref;
11326 }11399 }
...@@ -11329,7 +11402,7 @@ const ParamTypeIterator = struct {...@@ -11329,7 +11402,7 @@ const ParamTypeIterator = struct {
11329 .aarch64, .aarch64_be => {11402 .aarch64, .aarch64_be => {
11330 it.zig_index += 1;11403 it.zig_index += 1;
11331 it.llvm_index += 1;11404 it.llvm_index += 1;
11332 switch (aarch64_c_abi.classifyType(ty, zcu)) {11405 switch (aarch64_c_abi.classifyType(ty, pt)) {
11333 .memory => return .byref_mut,11406 .memory => return .byref_mut,
11334 .float_array => |len| return Lowering{ .float_array = len },11407 .float_array => |len| return Lowering{ .float_array = len },
11335 .byval => return .byval,11408 .byval => return .byval,
...@@ -11344,7 +11417,7 @@ const ParamTypeIterator = struct {...@@ -11344,7 +11417,7 @@ const ParamTypeIterator = struct {
11344 .arm, .armeb => {11417 .arm, .armeb => {
11345 it.zig_index += 1;11418 it.zig_index += 1;
11346 it.llvm_index += 1;11419 it.llvm_index += 1;
11347 switch (arm_c_abi.classifyType(ty, zcu, .arg)) {11420 switch (arm_c_abi.classifyType(ty, pt, .arg)) {
11348 .memory => {11421 .memory => {
11349 it.byval_attr = true;11422 it.byval_attr = true;
11350 return .byref;11423 return .byref;
...@@ -11359,7 +11432,7 @@ const ParamTypeIterator = struct {...@@ -11359,7 +11432,7 @@ const ParamTypeIterator = struct {
11359 it.llvm_index += 1;11432 it.llvm_index += 1;
11360 if (ty.toIntern() == .f16_type and11433 if (ty.toIntern() == .f16_type and
11361 !std.Target.riscv.featureSetHas(target.cpu.features, .d)) return .as_u16;11434 !std.Target.riscv.featureSetHas(target.cpu.features, .d)) return .as_u16;
11362 switch (riscv_c_abi.classifyType(ty, zcu)) {11435 switch (riscv_c_abi.classifyType(ty, pt)) {
11363 .memory => return .byref_mut,11436 .memory => return .byref_mut,
11364 .byval => return .byval,11437 .byval => return .byval,
11365 .integer => return .abi_sized_int,11438 .integer => return .abi_sized_int,
...@@ -11368,7 +11441,7 @@ const ParamTypeIterator = struct {...@@ -11368,7 +11441,7 @@ const ParamTypeIterator = struct {
11368 it.types_len = 0;11441 it.types_len = 0;
11369 for (0..ty.structFieldCount(zcu)) |field_index| {11442 for (0..ty.structFieldCount(zcu)) |field_index| {
11370 const field_ty = ty.structFieldType(field_index, zcu);11443 const field_ty = ty.structFieldType(field_index, zcu);
11371 if (!field_ty.hasRuntimeBitsIgnoreComptime(zcu)) continue;11444 if (!field_ty.hasRuntimeBitsIgnoreComptime(pt)) continue;
11372 it.types_buffer[it.types_len] = try it.object.lowerType(field_ty);11445 it.types_buffer[it.types_len] = try it.object.lowerType(field_ty);
11373 it.types_len += 1;11446 it.types_len += 1;
11374 }11447 }
...@@ -11406,10 +11479,10 @@ const ParamTypeIterator = struct {...@@ -11406,10 +11479,10 @@ const ParamTypeIterator = struct {
11406 }11479 }
1140711480
11408 fn nextWin64(it: *ParamTypeIterator, ty: Type) ?Lowering {11481 fn nextWin64(it: *ParamTypeIterator, ty: Type) ?Lowering {
11409 const zcu = it.object.module;11482 const pt = it.object.pt;
11410 switch (x86_64_abi.classifyWindows(ty, zcu)) {11483 switch (x86_64_abi.classifyWindows(ty, pt)) {
11411 .integer => {11484 .integer => {
11412 if (isScalar(zcu, ty)) {11485 if (isScalar(pt.zcu, ty)) {
11413 it.zig_index += 1;11486 it.zig_index += 1;
11414 it.llvm_index += 1;11487 it.llvm_index += 1;
11415 return .byval;11488 return .byval;
...@@ -11439,17 +11512,17 @@ const ParamTypeIterator = struct {...@@ -11439,17 +11512,17 @@ const ParamTypeIterator = struct {
11439 }11512 }
1144011513
11441 fn nextSystemV(it: *ParamTypeIterator, ty: Type) Allocator.Error!?Lowering {11514 fn nextSystemV(it: *ParamTypeIterator, ty: Type) Allocator.Error!?Lowering {
11442 const zcu = it.object.module;11515 const pt = it.object.pt;
11443 const ip = &zcu.intern_pool;11516 const ip = &pt.zcu.intern_pool;
11444 const target = zcu.getTarget();11517 const target = pt.zcu.getTarget();
11445 const classes = x86_64_abi.classifySystemV(ty, zcu, target, .arg);11518 const classes = x86_64_abi.classifySystemV(ty, pt, target, .arg);
11446 if (classes[0] == .memory) {11519 if (classes[0] == .memory) {
11447 it.zig_index += 1;11520 it.zig_index += 1;
11448 it.llvm_index += 1;11521 it.llvm_index += 1;
11449 it.byval_attr = true;11522 it.byval_attr = true;
11450 return .byref;11523 return .byref;
11451 }11524 }
11452 if (isScalar(zcu, ty)) {11525 if (isScalar(pt.zcu, ty)) {
11453 it.zig_index += 1;11526 it.zig_index += 1;
11454 it.llvm_index += 1;11527 it.llvm_index += 1;
11455 return .byval;11528 return .byval;
...@@ -11550,7 +11623,7 @@ fn iterateParamTypes(object: *Object, fn_info: InternPool.Key.FuncType) ParamTyp...@@ -11550,7 +11623,7 @@ fn iterateParamTypes(object: *Object, fn_info: InternPool.Key.FuncType) ParamTyp
1155011623
11551fn ccAbiPromoteInt(11624fn ccAbiPromoteInt(
11552 cc: std.builtin.CallingConvention,11625 cc: std.builtin.CallingConvention,
11553 mod: *Module,11626 mod: *Zcu,
11554 ty: Type,11627 ty: Type,
11555) ?std.builtin.Signedness {11628) ?std.builtin.Signedness {
11556 const target = mod.getTarget();11629 const target = mod.getTarget();
...@@ -11598,13 +11671,13 @@ fn ccAbiPromoteInt(...@@ -11598,13 +11671,13 @@ fn ccAbiPromoteInt(
1159811671
11599/// This is the one source of truth for whether a type is passed around as an LLVM pointer,11672/// This is the one source of truth for whether a type is passed around as an LLVM pointer,
11600/// or as an LLVM value.11673/// or as an LLVM value.
11601fn isByRef(ty: Type, mod: *Module) bool {11674fn isByRef(ty: Type, pt: Zcu.PerThread) bool {
11602 // For tuples and structs, if there are more than this many non-void11675 // For tuples and structs, if there are more than this many non-void
11603 // fields, then we make it byref, otherwise byval.11676 // fields, then we make it byref, otherwise byval.
11604 const max_fields_byval = 0;11677 const max_fields_byval = 0;
11605 const ip = &mod.intern_pool;11678 const ip = &pt.zcu.intern_pool;
1160611679
11607 switch (ty.zigTypeTag(mod)) {11680 switch (ty.zigTypeTag(pt.zcu)) {
11608 .Type,11681 .Type,
11609 .ComptimeInt,11682 .ComptimeInt,
11610 .ComptimeFloat,11683 .ComptimeFloat,
...@@ -11627,17 +11700,17 @@ fn isByRef(ty: Type, mod: *Module) bool {...@@ -11627,17 +11700,17 @@ fn isByRef(ty: Type, mod: *Module) bool {
11627 .AnyFrame,11700 .AnyFrame,
11628 => return false,11701 => return false,
1162911702
11630 .Array, .Frame => return ty.hasRuntimeBits(mod),11703 .Array, .Frame => return ty.hasRuntimeBits(pt),
11631 .Struct => {11704 .Struct => {
11632 const struct_type = switch (ip.indexToKey(ty.toIntern())) {11705 const struct_type = switch (ip.indexToKey(ty.toIntern())) {
11633 .anon_struct_type => |tuple| {11706 .anon_struct_type => |tuple| {
11634 var count: usize = 0;11707 var count: usize = 0;
11635 for (tuple.types.get(ip), tuple.values.get(ip)) |field_ty, field_val| {11708 for (tuple.types.get(ip), tuple.values.get(ip)) |field_ty, field_val| {
11636 if (field_val != .none or !Type.fromInterned(field_ty).hasRuntimeBits(mod)) continue;11709 if (field_val != .none or !Type.fromInterned(field_ty).hasRuntimeBits(pt)) continue;
1163711710
11638 count += 1;11711 count += 1;
11639 if (count > max_fields_byval) return true;11712 if (count > max_fields_byval) return true;
11640 if (isByRef(Type.fromInterned(field_ty), mod)) return true;11713 if (isByRef(Type.fromInterned(field_ty), pt)) return true;
11641 }11714 }
11642 return false;11715 return false;
11643 },11716 },
...@@ -11655,27 +11728,27 @@ fn isByRef(ty: Type, mod: *Module) bool {...@@ -11655,27 +11728,27 @@ fn isByRef(ty: Type, mod: *Module) bool {
11655 count += 1;11728 count += 1;
11656 if (count > max_fields_byval) return true;11729 if (count > max_fields_byval) return true;
11657 const field_ty = Type.fromInterned(field_types[field_index]);11730 const field_ty = Type.fromInterned(field_types[field_index]);
11658 if (isByRef(field_ty, mod)) return true;11731 if (isByRef(field_ty, pt)) return true;
11659 }11732 }
11660 return false;11733 return false;
11661 },11734 },
11662 .Union => switch (ty.containerLayout(mod)) {11735 .Union => switch (ty.containerLayout(pt.zcu)) {
11663 .@"packed" => return false,11736 .@"packed" => return false,
11664 else => return ty.hasRuntimeBits(mod),11737 else => return ty.hasRuntimeBits(pt),
11665 },11738 },
11666 .ErrorUnion => {11739 .ErrorUnion => {
11667 const payload_ty = ty.errorUnionPayload(mod);11740 const payload_ty = ty.errorUnionPayload(pt.zcu);
11668 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) {11741 if (!payload_ty.hasRuntimeBitsIgnoreComptime(pt)) {
11669 return false;11742 return false;
11670 }11743 }
11671 return true;11744 return true;
11672 },11745 },
11673 .Optional => {11746 .Optional => {
11674 const payload_ty = ty.optionalChild(mod);11747 const payload_ty = ty.optionalChild(pt.zcu);
11675 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) {11748 if (!payload_ty.hasRuntimeBitsIgnoreComptime(pt)) {
11676 return false;11749 return false;
11677 }11750 }
11678 if (ty.optionalReprIsPayload(mod)) {11751 if (ty.optionalReprIsPayload(pt.zcu)) {
11679 return false;11752 return false;
11680 }11753 }
11681 return true;11754 return true;
...@@ -11683,7 +11756,7 @@ fn isByRef(ty: Type, mod: *Module) bool {...@@ -11683,7 +11756,7 @@ fn isByRef(ty: Type, mod: *Module) bool {
11683 }11756 }
11684}11757}
1168511758
11686fn isScalar(mod: *Module, ty: Type) bool {11759fn isScalar(mod: *Zcu, ty: Type) bool {
11687 return switch (ty.zigTypeTag(mod)) {11760 return switch (ty.zigTypeTag(mod)) {
11688 .Void,11761 .Void,
11689 .Bool,11762 .Bool,
...@@ -11774,7 +11847,7 @@ const lt_errors_fn_name = "__zig_lt_errors_len";...@@ -11774,7 +11847,7 @@ const lt_errors_fn_name = "__zig_lt_errors_len";
11774/// Without this workaround, LLVM crashes with "unknown codeview register H1"11847/// Without this workaround, LLVM crashes with "unknown codeview register H1"
11775/// https://github.com/llvm/llvm-project/issues/5648411848/// https://github.com/llvm/llvm-project/issues/56484
11776fn needDbgVarWorkaround(o: *Object) bool {11849fn needDbgVarWorkaround(o: *Object) bool {
11777 const target = o.module.getTarget();11850 const target = o.pt.zcu.getTarget();
11778 if (target.os.tag == .windows and target.cpu.arch == .aarch64) {11851 if (target.os.tag == .windows and target.cpu.arch == .aarch64) {
11779 return true;11852 return true;
11780 }11853 }
...@@ -11817,14 +11890,14 @@ fn buildAllocaInner(...@@ -11817,14 +11890,14 @@ fn buildAllocaInner(
11817 return wip.conv(.unneeded, alloca, .ptr, "");11890 return wip.conv(.unneeded, alloca, .ptr, "");
11818}11891}
1181911892
11820fn errUnionPayloadOffset(payload_ty: Type, mod: *Module) !u1 {11893fn errUnionPayloadOffset(payload_ty: Type, pt: Zcu.PerThread) !u1 {
11821 const err_int_ty = try mod.errorIntType();11894 const err_int_ty = try pt.errorIntType();
11822 return @intFromBool(err_int_ty.abiAlignment(mod).compare(.gt, payload_ty.abiAlignment(mod)));11895 return @intFromBool(err_int_ty.abiAlignment(pt).compare(.gt, payload_ty.abiAlignment(pt)));
11823}11896}
1182411897
11825fn errUnionErrorOffset(payload_ty: Type, mod: *Module) !u1 {11898fn errUnionErrorOffset(payload_ty: Type, pt: Zcu.PerThread) !u1 {
11826 const err_int_ty = try mod.errorIntType();11899 const err_int_ty = try pt.errorIntType();
11827 return @intFromBool(err_int_ty.abiAlignment(mod).compare(.lte, payload_ty.abiAlignment(mod)));11900 return @intFromBool(err_int_ty.abiAlignment(pt).compare(.lte, payload_ty.abiAlignment(pt)));
11828}11901}
1182911902
11830/// Returns true for asm constraint (e.g. "=*m", "=r") if it accepts a memory location11903/// Returns true for asm constraint (e.g. "=*m", "=r") if it accepts a memory location
src/codegen/spirv.zig+240-212
...@@ -6,9 +6,7 @@ const assert = std.debug.assert;...@@ -6,9 +6,7 @@ const assert = std.debug.assert;
6const Signedness = std.builtin.Signedness;6const Signedness = std.builtin.Signedness;
77
8const Zcu = @import("../Zcu.zig");8const Zcu = @import("../Zcu.zig");
9/// Deprecated.9const Decl = Zcu.Decl;
10const Module = Zcu;
11const Decl = Module.Decl;
12const Type = @import("../Type.zig");10const Type = @import("../Type.zig");
13const Value = @import("../Value.zig");11const Value = @import("../Value.zig");
14const Air = @import("../Air.zig");12const Air = @import("../Air.zig");
...@@ -188,12 +186,13 @@ pub const Object = struct {...@@ -188,12 +186,13 @@ pub const Object = struct {
188186
189 fn genDecl(187 fn genDecl(
190 self: *Object,188 self: *Object,
191 zcu: *Zcu,189 pt: Zcu.PerThread,
192 decl_index: InternPool.DeclIndex,190 decl_index: InternPool.DeclIndex,
193 air: Air,191 air: Air,
194 liveness: Liveness,192 liveness: Liveness,
195 ) !void {193 ) !void {
196 const gpa = self.gpa;194 const zcu = pt.zcu;
195 const gpa = zcu.gpa;
197 const decl = zcu.declPtr(decl_index);196 const decl = zcu.declPtr(decl_index);
198 const namespace = zcu.namespacePtr(decl.src_namespace);197 const namespace = zcu.namespacePtr(decl.src_namespace);
199 const structured_cfg = namespace.fileScope(zcu).mod.structured_cfg;198 const structured_cfg = namespace.fileScope(zcu).mod.structured_cfg;
...@@ -201,7 +200,7 @@ pub const Object = struct {...@@ -201,7 +200,7 @@ pub const Object = struct {
201 var decl_gen = DeclGen{200 var decl_gen = DeclGen{
202 .gpa = gpa,201 .gpa = gpa,
203 .object = self,202 .object = self,
204 .module = zcu,203 .pt = pt,
205 .spv = &self.spv,204 .spv = &self.spv,
206 .decl_index = decl_index,205 .decl_index = decl_index,
207 .air = air,206 .air = air,
...@@ -235,34 +234,34 @@ pub const Object = struct {...@@ -235,34 +234,34 @@ pub const Object = struct {
235234
236 pub fn updateFunc(235 pub fn updateFunc(
237 self: *Object,236 self: *Object,
238 mod: *Module,237 pt: Zcu.PerThread,
239 func_index: InternPool.Index,238 func_index: InternPool.Index,
240 air: Air,239 air: Air,
241 liveness: Liveness,240 liveness: Liveness,
242 ) !void {241 ) !void {
243 const decl_index = mod.funcInfo(func_index).owner_decl;242 const decl_index = pt.zcu.funcInfo(func_index).owner_decl;
244 // TODO: Separate types for generating decls and functions?243 // TODO: Separate types for generating decls and functions?
245 try self.genDecl(mod, decl_index, air, liveness);244 try self.genDecl(pt, decl_index, air, liveness);
246 }245 }
247246
248 pub fn updateDecl(247 pub fn updateDecl(
249 self: *Object,248 self: *Object,
250 mod: *Module,249 pt: Zcu.PerThread,
251 decl_index: InternPool.DeclIndex,250 decl_index: InternPool.DeclIndex,
252 ) !void {251 ) !void {
253 try self.genDecl(mod, decl_index, undefined, undefined);252 try self.genDecl(pt, decl_index, undefined, undefined);
254 }253 }
255254
256 /// Fetch or allocate a result id for decl index. This function also marks the decl as alive.255 /// Fetch or allocate a result id for decl index. This function also marks the decl as alive.
257 /// Note: Function does not actually generate the decl, it just allocates an index.256 /// Note: Function does not actually generate the decl, it just allocates an index.
258 pub fn resolveDecl(self: *Object, mod: *Module, decl_index: InternPool.DeclIndex) !SpvModule.Decl.Index {257 pub fn resolveDecl(self: *Object, zcu: *Zcu, decl_index: InternPool.DeclIndex) !SpvModule.Decl.Index {
259 const decl = mod.declPtr(decl_index);258 const decl = zcu.declPtr(decl_index);
260 assert(decl.has_tv); // TODO: Do we need to handle a situation where this is false?259 assert(decl.has_tv); // TODO: Do we need to handle a situation where this is false?
261260
262 const entry = try self.decl_link.getOrPut(self.gpa, decl_index);261 const entry = try self.decl_link.getOrPut(self.gpa, decl_index);
263 if (!entry.found_existing) {262 if (!entry.found_existing) {
264 // TODO: Extern fn?263 // TODO: Extern fn?
265 const kind: SpvModule.Decl.Kind = if (decl.val.isFuncBody(mod))264 const kind: SpvModule.Decl.Kind = if (decl.val.isFuncBody(zcu))
266 .func265 .func
267 else switch (decl.@"addrspace") {266 else switch (decl.@"addrspace") {
268 .generic => .invocation_global,267 .generic => .invocation_global,
...@@ -285,7 +284,7 @@ const DeclGen = struct {...@@ -285,7 +284,7 @@ const DeclGen = struct {
285 object: *Object,284 object: *Object,
286285
287 /// The Zig module that we are generating decls for.286 /// The Zig module that we are generating decls for.
288 module: *Module,287 pt: Zcu.PerThread,
289288
290 /// The SPIR-V module that instructions should be emitted into.289 /// The SPIR-V module that instructions should be emitted into.
291 /// This is the same as `self.object.spv`, repeated here for brevity.290 /// This is the same as `self.object.spv`, repeated here for brevity.
...@@ -333,7 +332,7 @@ const DeclGen = struct {...@@ -333,7 +332,7 @@ const DeclGen = struct {
333332
334 /// If `gen` returned `Error.CodegenFail`, this contains an explanatory message.333 /// If `gen` returned `Error.CodegenFail`, this contains an explanatory message.
335 /// Memory is owned by `module.gpa`.334 /// Memory is owned by `module.gpa`.
336 error_msg: ?*Module.ErrorMsg = null,335 error_msg: ?*Zcu.ErrorMsg = null,
337336
338 /// Possible errors the `genDecl` function may return.337 /// Possible errors the `genDecl` function may return.
339 const Error = error{ CodegenFail, OutOfMemory };338 const Error = error{ CodegenFail, OutOfMemory };
...@@ -410,15 +409,15 @@ const DeclGen = struct {...@@ -410,15 +409,15 @@ const DeclGen = struct {
410409
411 /// Return the target which we are currently compiling for.410 /// Return the target which we are currently compiling for.
412 pub fn getTarget(self: *DeclGen) std.Target {411 pub fn getTarget(self: *DeclGen) std.Target {
413 return self.module.getTarget();412 return self.pt.zcu.getTarget();
414 }413 }
415414
416 pub fn fail(self: *DeclGen, comptime format: []const u8, args: anytype) Error {415 pub fn fail(self: *DeclGen, comptime format: []const u8, args: anytype) Error {
417 @setCold(true);416 @setCold(true);
418 const mod = self.module;417 const zcu = self.pt.zcu;
419 const src_loc = self.module.declPtr(self.decl_index).navSrcLoc(mod);418 const src_loc = zcu.declPtr(self.decl_index).navSrcLoc(zcu);
420 assert(self.error_msg == null);419 assert(self.error_msg == null);
421 self.error_msg = try Module.ErrorMsg.create(self.module.gpa, src_loc, format, args);420 self.error_msg = try Zcu.ErrorMsg.create(zcu.gpa, src_loc, format, args);
422 return error.CodegenFail;421 return error.CodegenFail;
423 }422 }
424423
...@@ -439,8 +438,9 @@ const DeclGen = struct {...@@ -439,8 +438,9 @@ const DeclGen = struct {
439438
440 /// Fetch the result-id for a previously generated instruction or constant.439 /// Fetch the result-id for a previously generated instruction or constant.
441 fn resolve(self: *DeclGen, inst: Air.Inst.Ref) !IdRef {440 fn resolve(self: *DeclGen, inst: Air.Inst.Ref) !IdRef {
442 const mod = self.module;441 const pt = self.pt;
443 if (try self.air.value(inst, mod)) |val| {442 const mod = pt.zcu;
443 if (try self.air.value(inst, pt)) |val| {
444 const ty = self.typeOf(inst);444 const ty = self.typeOf(inst);
445 if (ty.zigTypeTag(mod) == .Fn) {445 if (ty.zigTypeTag(mod) == .Fn) {
446 const fn_decl_index = switch (mod.intern_pool.indexToKey(val.ip_index)) {446 const fn_decl_index = switch (mod.intern_pool.indexToKey(val.ip_index)) {
...@@ -462,7 +462,7 @@ const DeclGen = struct {...@@ -462,7 +462,7 @@ const DeclGen = struct {
462 fn resolveAnonDecl(self: *DeclGen, val: InternPool.Index) !IdRef {462 fn resolveAnonDecl(self: *DeclGen, val: InternPool.Index) !IdRef {
463 // TODO: This cannot be a function at this point, but it should probably be handled anyway.463 // TODO: This cannot be a function at this point, but it should probably be handled anyway.
464464
465 const mod = self.module;465 const mod = self.pt.zcu;
466 const ty = Type.fromInterned(mod.intern_pool.typeOf(val));466 const ty = Type.fromInterned(mod.intern_pool.typeOf(val));
467 const decl_ptr_ty_id = try self.ptrType(ty, .Generic);467 const decl_ptr_ty_id = try self.ptrType(ty, .Generic);
468468
...@@ -642,7 +642,7 @@ const DeclGen = struct {...@@ -642,7 +642,7 @@ const DeclGen = struct {
642642
643 /// Checks whether the type can be directly translated to SPIR-V vectors643 /// Checks whether the type can be directly translated to SPIR-V vectors
644 fn isSpvVector(self: *DeclGen, ty: Type) bool {644 fn isSpvVector(self: *DeclGen, ty: Type) bool {
645 const mod = self.module;645 const mod = self.pt.zcu;
646 const target = self.getTarget();646 const target = self.getTarget();
647 if (ty.zigTypeTag(mod) != .Vector) return false;647 if (ty.zigTypeTag(mod) != .Vector) return false;
648648
...@@ -668,7 +668,7 @@ const DeclGen = struct {...@@ -668,7 +668,7 @@ const DeclGen = struct {
668 }668 }
669669
670 fn arithmeticTypeInfo(self: *DeclGen, ty: Type) ArithmeticTypeInfo {670 fn arithmeticTypeInfo(self: *DeclGen, ty: Type) ArithmeticTypeInfo {
671 const mod = self.module;671 const mod = self.pt.zcu;
672 const target = self.getTarget();672 const target = self.getTarget();
673 var scalar_ty = ty.scalarType(mod);673 var scalar_ty = ty.scalarType(mod);
674 if (scalar_ty.zigTypeTag(mod) == .Enum) {674 if (scalar_ty.zigTypeTag(mod) == .Enum) {
...@@ -744,7 +744,7 @@ const DeclGen = struct {...@@ -744,7 +744,7 @@ const DeclGen = struct {
744 /// the value to an unsigned int first for Kernels.744 /// the value to an unsigned int first for Kernels.
745 fn constInt(self: *DeclGen, ty: Type, value: anytype, repr: Repr) !IdRef {745 fn constInt(self: *DeclGen, ty: Type, value: anytype, repr: Repr) !IdRef {
746 // TODO: Cache?746 // TODO: Cache?
747 const mod = self.module;747 const mod = self.pt.zcu;
748 const scalar_ty = ty.scalarType(mod);748 const scalar_ty = ty.scalarType(mod);
749 const int_info = scalar_ty.intInfo(mod);749 const int_info = scalar_ty.intInfo(mod);
750 // Use backing bits so that negatives are sign extended750 // Use backing bits so that negatives are sign extended
...@@ -824,7 +824,7 @@ const DeclGen = struct {...@@ -824,7 +824,7 @@ const DeclGen = struct {
824 /// Construct a vector at runtime.824 /// Construct a vector at runtime.
825 /// ty must be an vector type.825 /// ty must be an vector type.
826 fn constructVector(self: *DeclGen, ty: Type, constituents: []const IdRef) !IdRef {826 fn constructVector(self: *DeclGen, ty: Type, constituents: []const IdRef) !IdRef {
827 const mod = self.module;827 const mod = self.pt.zcu;
828 assert(ty.vectorLen(mod) == constituents.len);828 assert(ty.vectorLen(mod) == constituents.len);
829829
830 // Note: older versions of the Khronos SPRIV-LLVM translator crash on this instruction830 // Note: older versions of the Khronos SPRIV-LLVM translator crash on this instruction
...@@ -848,7 +848,7 @@ const DeclGen = struct {...@@ -848,7 +848,7 @@ const DeclGen = struct {
848 /// Construct a vector at runtime with all lanes set to the same value.848 /// Construct a vector at runtime with all lanes set to the same value.
849 /// ty must be an vector type.849 /// ty must be an vector type.
850 fn constructVectorSplat(self: *DeclGen, ty: Type, constituent: IdRef) !IdRef {850 fn constructVectorSplat(self: *DeclGen, ty: Type, constituent: IdRef) !IdRef {
851 const mod = self.module;851 const mod = self.pt.zcu;
852 const n = ty.vectorLen(mod);852 const n = ty.vectorLen(mod);
853853
854 const constituents = try self.gpa.alloc(IdRef, n);854 const constituents = try self.gpa.alloc(IdRef, n);
...@@ -886,12 +886,13 @@ const DeclGen = struct {...@@ -886,12 +886,13 @@ const DeclGen = struct {
886 return id;886 return id;
887 }887 }
888888
889 const mod = self.module;889 const pt = self.pt;
890 const mod = pt.zcu;
890 const target = self.getTarget();891 const target = self.getTarget();
891 const result_ty_id = try self.resolveType(ty, repr);892 const result_ty_id = try self.resolveType(ty, repr);
892 const ip = &mod.intern_pool;893 const ip = &mod.intern_pool;
893894
894 log.debug("lowering constant: ty = {}, val = {}", .{ ty.fmt(mod), val.fmtValue(mod, null) });895 log.debug("lowering constant: ty = {}, val = {}", .{ ty.fmt(pt), val.fmtValue(pt, null) });
895 if (val.isUndefDeep(mod)) {896 if (val.isUndefDeep(mod)) {
896 return self.spv.constUndef(result_ty_id);897 return self.spv.constUndef(result_ty_id);
897 }898 }
...@@ -940,16 +941,16 @@ const DeclGen = struct {...@@ -940,16 +941,16 @@ const DeclGen = struct {
940 },941 },
941 .int => {942 .int => {
942 if (ty.isSignedInt(mod)) {943 if (ty.isSignedInt(mod)) {
943 break :cache try self.constInt(ty, val.toSignedInt(mod), repr);944 break :cache try self.constInt(ty, val.toSignedInt(pt), repr);
944 } else {945 } else {
945 break :cache try self.constInt(ty, val.toUnsignedInt(mod), repr);946 break :cache try self.constInt(ty, val.toUnsignedInt(pt), repr);
946 }947 }
947 },948 },
948 .float => {949 .float => {
949 const lit: spec.LiteralContextDependentNumber = switch (ty.floatBits(target)) {950 const lit: spec.LiteralContextDependentNumber = switch (ty.floatBits(target)) {
950 16 => .{ .uint32 = @as(u16, @bitCast(val.toFloat(f16, mod))) },951 16 => .{ .uint32 = @as(u16, @bitCast(val.toFloat(f16, pt))) },
951 32 => .{ .float32 = val.toFloat(f32, mod) },952 32 => .{ .float32 = val.toFloat(f32, pt) },
952 64 => .{ .float64 = val.toFloat(f64, mod) },953 64 => .{ .float64 = val.toFloat(f64, pt) },
953 80, 128 => unreachable, // TODO954 80, 128 => unreachable, // TODO
954 else => unreachable,955 else => unreachable,
955 };956 };
...@@ -968,17 +969,17 @@ const DeclGen = struct {...@@ -968,17 +969,17 @@ const DeclGen = struct {
968 .error_union => |error_union| {969 .error_union => |error_union| {
969 // TODO: Error unions may be constructed with constant instructions if the payload type970 // TODO: Error unions may be constructed with constant instructions if the payload type
970 // allows it. For now, just generate it here regardless.971 // allows it. For now, just generate it here regardless.
971 const err_int_ty = try mod.errorIntType();972 const err_int_ty = try pt.errorIntType();
972 const err_ty = switch (error_union.val) {973 const err_ty = switch (error_union.val) {
973 .err_name => ty.errorUnionSet(mod),974 .err_name => ty.errorUnionSet(mod),
974 .payload => err_int_ty,975 .payload => err_int_ty,
975 };976 };
976 const err_val = switch (error_union.val) {977 const err_val = switch (error_union.val) {
977 .err_name => |err_name| Value.fromInterned((try mod.intern(.{ .err = .{978 .err_name => |err_name| Value.fromInterned(try pt.intern(.{ .err = .{
978 .ty = ty.errorUnionSet(mod).toIntern(),979 .ty = ty.errorUnionSet(mod).toIntern(),
979 .name = err_name,980 .name = err_name,
980 } }))),981 } })),
981 .payload => try mod.intValue(err_int_ty, 0),982 .payload => try pt.intValue(err_int_ty, 0),
982 };983 };
983 const payload_ty = ty.errorUnionPayload(mod);984 const payload_ty = ty.errorUnionPayload(mod);
984 const eu_layout = self.errorUnionLayout(payload_ty);985 const eu_layout = self.errorUnionLayout(payload_ty);
...@@ -988,7 +989,7 @@ const DeclGen = struct {...@@ -988,7 +989,7 @@ const DeclGen = struct {
988 }989 }
989990
990 const payload_val = Value.fromInterned(switch (error_union.val) {991 const payload_val = Value.fromInterned(switch (error_union.val) {
991 .err_name => try mod.intern(.{ .undef = payload_ty.toIntern() }),992 .err_name => try pt.intern(.{ .undef = payload_ty.toIntern() }),
992 .payload => |payload| payload,993 .payload => |payload| payload,
993 });994 });
994995
...@@ -1007,7 +1008,7 @@ const DeclGen = struct {...@@ -1007,7 +1008,7 @@ const DeclGen = struct {
1007 return try self.constructStruct(ty, &types, &constituents);1008 return try self.constructStruct(ty, &types, &constituents);
1008 },1009 },
1009 .enum_tag => {1010 .enum_tag => {
1010 const int_val = try val.intFromEnum(ty, mod);1011 const int_val = try val.intFromEnum(ty, pt);
1011 const int_ty = ty.intTagType(mod);1012 const int_ty = ty.intTagType(mod);
1012 break :cache try self.constant(int_ty, int_val, repr);1013 break :cache try self.constant(int_ty, int_val, repr);
1013 },1014 },
...@@ -1026,7 +1027,7 @@ const DeclGen = struct {...@@ -1026,7 +1027,7 @@ const DeclGen = struct {
1026 const payload_ty = ty.optionalChild(mod);1027 const payload_ty = ty.optionalChild(mod);
1027 const maybe_payload_val = val.optionalValue(mod);1028 const maybe_payload_val = val.optionalValue(mod);
10281029
1029 if (!payload_ty.hasRuntimeBits(mod)) {1030 if (!payload_ty.hasRuntimeBits(pt)) {
1030 break :cache try self.constBool(maybe_payload_val != null, .indirect);1031 break :cache try self.constBool(maybe_payload_val != null, .indirect);
1031 } else if (ty.optionalReprIsPayload(mod)) {1032 } else if (ty.optionalReprIsPayload(mod)) {
1032 // Optional representation is a nullable pointer or slice.1033 // Optional representation is a nullable pointer or slice.
...@@ -1104,13 +1105,13 @@ const DeclGen = struct {...@@ -1104,13 +1105,13 @@ const DeclGen = struct {
1104 var it = struct_type.iterateRuntimeOrder(ip);1105 var it = struct_type.iterateRuntimeOrder(ip);
1105 while (it.next()) |field_index| {1106 while (it.next()) |field_index| {
1106 const field_ty = Type.fromInterned(struct_type.field_types.get(ip)[field_index]);1107 const field_ty = Type.fromInterned(struct_type.field_types.get(ip)[field_index]);
1107 if (!field_ty.hasRuntimeBitsIgnoreComptime(mod)) {1108 if (!field_ty.hasRuntimeBitsIgnoreComptime(pt)) {
1108 // This is a zero-bit field - we only needed it for the alignment.1109 // This is a zero-bit field - we only needed it for the alignment.
1109 continue;1110 continue;
1110 }1111 }
11111112
1112 // TODO: Padding?1113 // TODO: Padding?
1113 const field_val = try val.fieldValue(mod, field_index);1114 const field_val = try val.fieldValue(pt, field_index);
1114 const field_id = try self.constant(field_ty, field_val, .indirect);1115 const field_id = try self.constant(field_ty, field_val, .indirect);
11151116
1116 try types.append(field_ty);1117 try types.append(field_ty);
...@@ -1126,7 +1127,7 @@ const DeclGen = struct {...@@ -1126,7 +1127,7 @@ const DeclGen = struct {
1126 const active_field = ty.unionTagFieldIndex(Value.fromInterned(un.tag), mod).?;1127 const active_field = ty.unionTagFieldIndex(Value.fromInterned(un.tag), mod).?;
1127 const union_obj = mod.typeToUnion(ty).?;1128 const union_obj = mod.typeToUnion(ty).?;
1128 const field_ty = Type.fromInterned(union_obj.field_types.get(ip)[active_field]);1129 const field_ty = Type.fromInterned(union_obj.field_types.get(ip)[active_field]);
1129 const payload = if (field_ty.hasRuntimeBitsIgnoreComptime(mod))1130 const payload = if (field_ty.hasRuntimeBitsIgnoreComptime(pt))
1130 try self.constant(field_ty, Value.fromInterned(un.val), .direct)1131 try self.constant(field_ty, Value.fromInterned(un.val), .direct)
1131 else1132 else
1132 null;1133 null;
...@@ -1144,10 +1145,10 @@ const DeclGen = struct {...@@ -1144,10 +1145,10 @@ const DeclGen = struct {
1144 fn constantPtr(self: *DeclGen, ptr_val: Value) Error!IdRef {1145 fn constantPtr(self: *DeclGen, ptr_val: Value) Error!IdRef {
1145 // TODO: Caching??1146 // TODO: Caching??
11461147
1147 const zcu = self.module;1148 const pt = self.pt;
11481149
1149 if (ptr_val.isUndef(zcu)) {1150 if (ptr_val.isUndef(pt.zcu)) {
1150 const result_ty = ptr_val.typeOf(zcu);1151 const result_ty = ptr_val.typeOf(pt.zcu);
1151 const result_ty_id = try self.resolveType(result_ty, .direct);1152 const result_ty_id = try self.resolveType(result_ty, .direct);
1152 return self.spv.constUndef(result_ty_id);1153 return self.spv.constUndef(result_ty_id);
1153 }1154 }
...@@ -1155,12 +1156,13 @@ const DeclGen = struct {...@@ -1155,12 +1156,13 @@ const DeclGen = struct {
1155 var arena = std.heap.ArenaAllocator.init(self.gpa);1156 var arena = std.heap.ArenaAllocator.init(self.gpa);
1156 defer arena.deinit();1157 defer arena.deinit();
11571158
1158 const derivation = try ptr_val.pointerDerivation(arena.allocator(), zcu);1159 const derivation = try ptr_val.pointerDerivation(arena.allocator(), pt);
1159 return self.derivePtr(derivation);1160 return self.derivePtr(derivation);
1160 }1161 }
11611162
1162 fn derivePtr(self: *DeclGen, derivation: Value.PointerDeriveStep) Error!IdRef {1163 fn derivePtr(self: *DeclGen, derivation: Value.PointerDeriveStep) Error!IdRef {
1163 const zcu = self.module;1164 const pt = self.pt;
1165 const zcu = pt.zcu;
1164 switch (derivation) {1166 switch (derivation) {
1165 .comptime_alloc_ptr, .comptime_field_ptr => unreachable,1167 .comptime_alloc_ptr, .comptime_field_ptr => unreachable,
1166 .int => |int| {1168 .int => |int| {
...@@ -1172,12 +1174,12 @@ const DeclGen = struct {...@@ -1172,12 +1174,12 @@ const DeclGen = struct {
1172 try self.func.body.emit(self.spv.gpa, .OpConvertUToPtr, .{1174 try self.func.body.emit(self.spv.gpa, .OpConvertUToPtr, .{
1173 .id_result_type = result_ty_id,1175 .id_result_type = result_ty_id,
1174 .id_result = result_ptr_id,1176 .id_result = result_ptr_id,
1175 .integer_value = try self.constant(Type.usize, try zcu.intValue(Type.usize, int.addr), .direct),1177 .integer_value = try self.constant(Type.usize, try pt.intValue(Type.usize, int.addr), .direct),
1176 });1178 });
1177 return result_ptr_id;1179 return result_ptr_id;
1178 },1180 },
1179 .decl_ptr => |decl| {1181 .decl_ptr => |decl| {
1180 const result_ptr_ty = try zcu.declPtr(decl).declPtrType(zcu);1182 const result_ptr_ty = try zcu.declPtr(decl).declPtrType(pt);
1181 return self.constantDeclRef(result_ptr_ty, decl);1183 return self.constantDeclRef(result_ptr_ty, decl);
1182 },1184 },
1183 .anon_decl_ptr => |ad| {1185 .anon_decl_ptr => |ad| {
...@@ -1188,18 +1190,18 @@ const DeclGen = struct {...@@ -1188,18 +1190,18 @@ const DeclGen = struct {
1188 .opt_payload_ptr => @panic("TODO"),1190 .opt_payload_ptr => @panic("TODO"),
1189 .field_ptr => |field| {1191 .field_ptr => |field| {
1190 const parent_ptr_id = try self.derivePtr(field.parent.*);1192 const parent_ptr_id = try self.derivePtr(field.parent.*);
1191 const parent_ptr_ty = try field.parent.ptrType(zcu);1193 const parent_ptr_ty = try field.parent.ptrType(pt);
1192 return self.structFieldPtr(field.result_ptr_ty, parent_ptr_ty, parent_ptr_id, field.field_idx);1194 return self.structFieldPtr(field.result_ptr_ty, parent_ptr_ty, parent_ptr_id, field.field_idx);
1193 },1195 },
1194 .elem_ptr => |elem| {1196 .elem_ptr => |elem| {
1195 const parent_ptr_id = try self.derivePtr(elem.parent.*);1197 const parent_ptr_id = try self.derivePtr(elem.parent.*);
1196 const parent_ptr_ty = try elem.parent.ptrType(zcu);1198 const parent_ptr_ty = try elem.parent.ptrType(pt);
1197 const index_id = try self.constInt(Type.usize, elem.elem_idx, .direct);1199 const index_id = try self.constInt(Type.usize, elem.elem_idx, .direct);
1198 return self.ptrElemPtr(parent_ptr_ty, parent_ptr_id, index_id);1200 return self.ptrElemPtr(parent_ptr_ty, parent_ptr_id, index_id);
1199 },1201 },
1200 .offset_and_cast => |oac| {1202 .offset_and_cast => |oac| {
1201 const parent_ptr_id = try self.derivePtr(oac.parent.*);1203 const parent_ptr_id = try self.derivePtr(oac.parent.*);
1202 const parent_ptr_ty = try oac.parent.ptrType(zcu);1204 const parent_ptr_ty = try oac.parent.ptrType(pt);
1203 disallow: {1205 disallow: {
1204 if (oac.byte_offset != 0) break :disallow;1206 if (oac.byte_offset != 0) break :disallow;
1205 // Allow changing the pointer type child only to restructure arrays.1207 // Allow changing the pointer type child only to restructure arrays.
...@@ -1218,8 +1220,8 @@ const DeclGen = struct {...@@ -1218,8 +1220,8 @@ const DeclGen = struct {
1218 return result_ptr_id;1220 return result_ptr_id;
1219 }1221 }
1220 return self.fail("Cannot perform pointer cast: '{}' to '{}'", .{1222 return self.fail("Cannot perform pointer cast: '{}' to '{}'", .{
1221 parent_ptr_ty.fmt(zcu),1223 parent_ptr_ty.fmt(pt),
1222 oac.new_ptr_ty.fmt(zcu),1224 oac.new_ptr_ty.fmt(pt),
1223 });1225 });
1224 },1226 },
1225 }1227 }
...@@ -1232,7 +1234,8 @@ const DeclGen = struct {...@@ -1232,7 +1234,8 @@ const DeclGen = struct {
1232 ) !IdRef {1234 ) !IdRef {
1233 // TODO: Merge this function with constantDeclRef.1235 // TODO: Merge this function with constantDeclRef.
12341236
1235 const mod = self.module;1237 const pt = self.pt;
1238 const mod = pt.zcu;
1236 const ip = &mod.intern_pool;1239 const ip = &mod.intern_pool;
1237 const ty_id = try self.resolveType(ty, .direct);1240 const ty_id = try self.resolveType(ty, .direct);
1238 const decl_val = anon_decl.val;1241 const decl_val = anon_decl.val;
...@@ -1247,7 +1250,7 @@ const DeclGen = struct {...@@ -1247,7 +1250,7 @@ const DeclGen = struct {
1247 }1250 }
12481251
1249 // const is_fn_body = decl_ty.zigTypeTag(mod) == .Fn;1252 // const is_fn_body = decl_ty.zigTypeTag(mod) == .Fn;
1250 if (!decl_ty.isFnOrHasRuntimeBitsIgnoreComptime(mod)) {1253 if (!decl_ty.isFnOrHasRuntimeBitsIgnoreComptime(pt)) {
1251 // Pointer to nothing - return undefoined1254 // Pointer to nothing - return undefoined
1252 return self.spv.constUndef(ty_id);1255 return self.spv.constUndef(ty_id);
1253 }1256 }
...@@ -1276,7 +1279,8 @@ const DeclGen = struct {...@@ -1276,7 +1279,8 @@ const DeclGen = struct {
1276 }1279 }
12771280
1278 fn constantDeclRef(self: *DeclGen, ty: Type, decl_index: InternPool.DeclIndex) !IdRef {1281 fn constantDeclRef(self: *DeclGen, ty: Type, decl_index: InternPool.DeclIndex) !IdRef {
1279 const mod = self.module;1282 const pt = self.pt;
1283 const mod = pt.zcu;
1280 const ty_id = try self.resolveType(ty, .direct);1284 const ty_id = try self.resolveType(ty, .direct);
1281 const decl = mod.declPtr(decl_index);1285 const decl = mod.declPtr(decl_index);
12821286
...@@ -1290,7 +1294,7 @@ const DeclGen = struct {...@@ -1290,7 +1294,7 @@ const DeclGen = struct {
1290 else => {},1294 else => {},
1291 }1295 }
12921296
1293 if (!decl.typeOf(mod).isFnOrHasRuntimeBitsIgnoreComptime(mod)) {1297 if (!decl.typeOf(mod).isFnOrHasRuntimeBitsIgnoreComptime(pt)) {
1294 // Pointer to nothing - return undefined.1298 // Pointer to nothing - return undefined.
1295 return self.spv.constUndef(ty_id);1299 return self.spv.constUndef(ty_id);
1296 }1300 }
...@@ -1331,7 +1335,7 @@ const DeclGen = struct {...@@ -1331,7 +1335,7 @@ const DeclGen = struct {
1331 fn resolveTypeName(self: *DeclGen, ty: Type) ![]const u8 {1335 fn resolveTypeName(self: *DeclGen, ty: Type) ![]const u8 {
1332 var name = std.ArrayList(u8).init(self.gpa);1336 var name = std.ArrayList(u8).init(self.gpa);
1333 defer name.deinit();1337 defer name.deinit();
1334 try ty.print(name.writer(), self.module);1338 try ty.print(name.writer(), self.pt);
1335 return try name.toOwnedSlice();1339 return try name.toOwnedSlice();
1336 }1340 }
13371341
...@@ -1424,14 +1428,14 @@ const DeclGen = struct {...@@ -1424,14 +1428,14 @@ const DeclGen = struct {
1424 }1428 }
14251429
1426 fn zigScalarOrVectorTypeLike(self: *DeclGen, new_ty: Type, base_ty: Type) !Type {1430 fn zigScalarOrVectorTypeLike(self: *DeclGen, new_ty: Type, base_ty: Type) !Type {
1427 const mod = self.module;1431 const pt = self.pt;
1428 const new_scalar_ty = new_ty.scalarType(mod);1432 const new_scalar_ty = new_ty.scalarType(pt.zcu);
1429 if (!base_ty.isVector(mod)) {1433 if (!base_ty.isVector(pt.zcu)) {
1430 return new_scalar_ty;1434 return new_scalar_ty;
1431 }1435 }
14321436
1433 return try mod.vectorType(.{1437 return try pt.vectorType(.{
1434 .len = base_ty.vectorLen(mod),1438 .len = base_ty.vectorLen(pt.zcu),
1435 .child = new_scalar_ty.toIntern(),1439 .child = new_scalar_ty.toIntern(),
1436 });1440 });
1437 }1441 }
...@@ -1455,7 +1459,7 @@ const DeclGen = struct {...@@ -1455,7 +1459,7 @@ const DeclGen = struct {
1455 /// }1459 /// }
1456 /// If any of the fields' size is 0, it will be omitted.1460 /// If any of the fields' size is 0, it will be omitted.
1457 fn resolveUnionType(self: *DeclGen, ty: Type) !IdRef {1461 fn resolveUnionType(self: *DeclGen, ty: Type) !IdRef {
1458 const mod = self.module;1462 const mod = self.pt.zcu;
1459 const ip = &mod.intern_pool;1463 const ip = &mod.intern_pool;
1460 const union_obj = mod.typeToUnion(ty).?;1464 const union_obj = mod.typeToUnion(ty).?;
14611465
...@@ -1506,12 +1510,12 @@ const DeclGen = struct {...@@ -1506,12 +1510,12 @@ const DeclGen = struct {
1506 }1510 }
15071511
1508 fn resolveFnReturnType(self: *DeclGen, ret_ty: Type) !IdRef {1512 fn resolveFnReturnType(self: *DeclGen, ret_ty: Type) !IdRef {
1509 const mod = self.module;1513 const pt = self.pt;
1510 if (!ret_ty.hasRuntimeBitsIgnoreComptime(mod)) {1514 if (!ret_ty.hasRuntimeBitsIgnoreComptime(pt)) {
1511 // If the return type is an error set or an error union, then we make this1515 // If the return type is an error set or an error union, then we make this
1512 // anyerror return type instead, so that it can be coerced into a function1516 // anyerror return type instead, so that it can be coerced into a function
1513 // pointer type which has anyerror as the return type.1517 // pointer type which has anyerror as the return type.
1514 if (ret_ty.isError(mod)) {1518 if (ret_ty.isError(pt.zcu)) {
1515 return self.resolveType(Type.anyerror, .direct);1519 return self.resolveType(Type.anyerror, .direct);
1516 } else {1520 } else {
1517 return self.resolveType(Type.void, .direct);1521 return self.resolveType(Type.void, .direct);
...@@ -1533,9 +1537,10 @@ const DeclGen = struct {...@@ -1533,9 +1537,10 @@ const DeclGen = struct {
1533 }1537 }
15341538
1535 fn resolveTypeInner(self: *DeclGen, ty: Type, repr: Repr) Error!IdRef {1539 fn resolveTypeInner(self: *DeclGen, ty: Type, repr: Repr) Error!IdRef {
1536 const mod = self.module;1540 const pt = self.pt;
1541 const mod = pt.zcu;
1537 const ip = &mod.intern_pool;1542 const ip = &mod.intern_pool;
1538 log.debug("resolveType: ty = {}", .{ty.fmt(mod)});1543 log.debug("resolveType: ty = {}", .{ty.fmt(pt)});
1539 const target = self.getTarget();1544 const target = self.getTarget();
15401545
1541 const section = &self.spv.sections.types_globals_constants;1546 const section = &self.spv.sections.types_globals_constants;
...@@ -1607,7 +1612,7 @@ const DeclGen = struct {...@@ -1607,7 +1612,7 @@ const DeclGen = struct {
1607 return self.fail("array type of {} elements is too large", .{ty.arrayLenIncludingSentinel(mod)});1612 return self.fail("array type of {} elements is too large", .{ty.arrayLenIncludingSentinel(mod)});
1608 };1613 };
16091614
1610 if (!elem_ty.hasRuntimeBitsIgnoreComptime(mod)) {1615 if (!elem_ty.hasRuntimeBitsIgnoreComptime(pt)) {
1611 // The size of the array would be 0, but that is not allowed in SPIR-V.1616 // The size of the array would be 0, but that is not allowed in SPIR-V.
1612 // This path can be reached when the backend is asked to generate a pointer to1617 // This path can be reached when the backend is asked to generate a pointer to
1613 // an array of some zero-bit type. This should always be an indirect path.1618 // an array of some zero-bit type. This should always be an indirect path.
...@@ -1655,7 +1660,7 @@ const DeclGen = struct {...@@ -1655,7 +1660,7 @@ const DeclGen = struct {
1655 var param_index: usize = 0;1660 var param_index: usize = 0;
1656 for (fn_info.param_types.get(ip)) |param_ty_index| {1661 for (fn_info.param_types.get(ip)) |param_ty_index| {
1657 const param_ty = Type.fromInterned(param_ty_index);1662 const param_ty = Type.fromInterned(param_ty_index);
1658 if (!param_ty.hasRuntimeBitsIgnoreComptime(mod)) continue;1663 if (!param_ty.hasRuntimeBitsIgnoreComptime(pt)) continue;
16591664
1660 param_ty_ids[param_index] = try self.resolveType(param_ty, .direct);1665 param_ty_ids[param_index] = try self.resolveType(param_ty, .direct);
1661 param_index += 1;1666 param_index += 1;
...@@ -1713,7 +1718,7 @@ const DeclGen = struct {...@@ -1713,7 +1718,7 @@ const DeclGen = struct {
17131718
1714 var member_index: usize = 0;1719 var member_index: usize = 0;
1715 for (tuple.types.get(ip), tuple.values.get(ip)) |field_ty, field_val| {1720 for (tuple.types.get(ip), tuple.values.get(ip)) |field_ty, field_val| {
1716 if (field_val != .none or !Type.fromInterned(field_ty).hasRuntimeBits(mod)) continue;1721 if (field_val != .none or !Type.fromInterned(field_ty).hasRuntimeBits(pt)) continue;
17171722
1718 member_types[member_index] = try self.resolveType(Type.fromInterned(field_ty), .indirect);1723 member_types[member_index] = try self.resolveType(Type.fromInterned(field_ty), .indirect);
1719 member_index += 1;1724 member_index += 1;
...@@ -1742,13 +1747,13 @@ const DeclGen = struct {...@@ -1742,13 +1747,13 @@ const DeclGen = struct {
1742 var it = struct_type.iterateRuntimeOrder(ip);1747 var it = struct_type.iterateRuntimeOrder(ip);
1743 while (it.next()) |field_index| {1748 while (it.next()) |field_index| {
1744 const field_ty = Type.fromInterned(struct_type.field_types.get(ip)[field_index]);1749 const field_ty = Type.fromInterned(struct_type.field_types.get(ip)[field_index]);
1745 if (!field_ty.hasRuntimeBitsIgnoreComptime(mod)) {1750 if (!field_ty.hasRuntimeBitsIgnoreComptime(pt)) {
1746 // This is a zero-bit field - we only needed it for the alignment.1751 // This is a zero-bit field - we only needed it for the alignment.
1747 continue;1752 continue;
1748 }1753 }
17491754
1750 const field_name = struct_type.fieldName(ip, field_index).unwrap() orelse1755 const field_name = struct_type.fieldName(ip, field_index).unwrap() orelse
1751 try ip.getOrPutStringFmt(mod.gpa, "{d}", .{field_index}, .no_embedded_nulls);1756 try ip.getOrPutStringFmt(mod.gpa, pt.tid, "{d}", .{field_index}, .no_embedded_nulls);
1752 try member_types.append(try self.resolveType(field_ty, .indirect));1757 try member_types.append(try self.resolveType(field_ty, .indirect));
1753 try member_names.append(field_name.toSlice(ip));1758 try member_names.append(field_name.toSlice(ip));
1754 }1759 }
...@@ -1761,7 +1766,7 @@ const DeclGen = struct {...@@ -1761,7 +1766,7 @@ const DeclGen = struct {
1761 },1766 },
1762 .Optional => {1767 .Optional => {
1763 const payload_ty = ty.optionalChild(mod);1768 const payload_ty = ty.optionalChild(mod);
1764 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) {1769 if (!payload_ty.hasRuntimeBitsIgnoreComptime(pt)) {
1765 // Just use a bool.1770 // Just use a bool.
1766 // Note: Always generate the bool with indirect format, to save on some sanity1771 // Note: Always generate the bool with indirect format, to save on some sanity
1767 // Perform the conversion to a direct bool when the field is extracted.1772 // Perform the conversion to a direct bool when the field is extracted.
...@@ -1878,14 +1883,14 @@ const DeclGen = struct {...@@ -1878,14 +1883,14 @@ const DeclGen = struct {
1878 };1883 };
18791884
1880 fn errorUnionLayout(self: *DeclGen, payload_ty: Type) ErrorUnionLayout {1885 fn errorUnionLayout(self: *DeclGen, payload_ty: Type) ErrorUnionLayout {
1881 const mod = self.module;1886 const pt = self.pt;
18821887
1883 const error_align = Type.anyerror.abiAlignment(mod);1888 const error_align = Type.anyerror.abiAlignment(pt);
1884 const payload_align = payload_ty.abiAlignment(mod);1889 const payload_align = payload_ty.abiAlignment(pt);
18851890
1886 const error_first = error_align.compare(.gt, payload_align);1891 const error_first = error_align.compare(.gt, payload_align);
1887 return .{1892 return .{
1888 .payload_has_bits = payload_ty.hasRuntimeBitsIgnoreComptime(mod),1893 .payload_has_bits = payload_ty.hasRuntimeBitsIgnoreComptime(pt),
1889 .error_first = error_first,1894 .error_first = error_first,
1890 };1895 };
1891 }1896 }
...@@ -1909,9 +1914,10 @@ const DeclGen = struct {...@@ -1909,9 +1914,10 @@ const DeclGen = struct {
1909 };1914 };
19101915
1911 fn unionLayout(self: *DeclGen, ty: Type) UnionLayout {1916 fn unionLayout(self: *DeclGen, ty: Type) UnionLayout {
1912 const mod = self.module;1917 const pt = self.pt;
1918 const mod = pt.zcu;
1913 const ip = &mod.intern_pool;1919 const ip = &mod.intern_pool;
1914 const layout = ty.unionGetLayout(self.module);1920 const layout = ty.unionGetLayout(pt);
1915 const union_obj = mod.typeToUnion(ty).?;1921 const union_obj = mod.typeToUnion(ty).?;
19161922
1917 var union_layout = UnionLayout{1923 var union_layout = UnionLayout{
...@@ -1932,7 +1938,7 @@ const DeclGen = struct {...@@ -1932,7 +1938,7 @@ const DeclGen = struct {
1932 const most_aligned_field = layout.most_aligned_field;1938 const most_aligned_field = layout.most_aligned_field;
1933 const most_aligned_field_ty = Type.fromInterned(union_obj.field_types.get(ip)[most_aligned_field]);1939 const most_aligned_field_ty = Type.fromInterned(union_obj.field_types.get(ip)[most_aligned_field]);
1934 union_layout.payload_ty = most_aligned_field_ty;1940 union_layout.payload_ty = most_aligned_field_ty;
1935 union_layout.payload_size = @intCast(most_aligned_field_ty.abiSize(mod));1941 union_layout.payload_size = @intCast(most_aligned_field_ty.abiSize(pt));
1936 } else {1942 } else {
1937 union_layout.payload_size = 0;1943 union_layout.payload_size = 0;
1938 }1944 }
...@@ -1999,7 +2005,7 @@ const DeclGen = struct {...@@ -1999,7 +2005,7 @@ const DeclGen = struct {
1999 }2005 }
20002006
2001 fn materialize(self: Temporary, dg: *DeclGen) !IdResult {2007 fn materialize(self: Temporary, dg: *DeclGen) !IdResult {
2002 const mod = dg.module;2008 const mod = dg.pt.zcu;
2003 switch (self.value) {2009 switch (self.value) {
2004 .singleton => |id| return id,2010 .singleton => |id| return id,
2005 .exploded_vector => |range| {2011 .exploded_vector => |range| {
...@@ -2029,12 +2035,12 @@ const DeclGen = struct {...@@ -2029,12 +2035,12 @@ const DeclGen = struct {
2029 /// 'Explode' a temporary into separate elements. This turns a vector2035 /// 'Explode' a temporary into separate elements. This turns a vector
2030 /// into a bag of elements.2036 /// into a bag of elements.
2031 fn explode(self: Temporary, dg: *DeclGen) !IdRange {2037 fn explode(self: Temporary, dg: *DeclGen) !IdRange {
2032 const mod = dg.module;2038 const mod = dg.pt.zcu;
20332039
2034 // If the value is a scalar, then this is a no-op.2040 // If the value is a scalar, then this is a no-op.
2035 if (!self.ty.isVector(mod)) {2041 if (!self.ty.isVector(mod)) {
2036 return switch (self.value) {2042 return switch (self.value) {
2037 .singleton => |id| IdRange{ .base = @intFromEnum(id), .len = 1 },2043 .singleton => |id| .{ .base = @intFromEnum(id), .len = 1 },
2038 .exploded_vector => |range| range,2044 .exploded_vector => |range| range,
2039 };2045 };
2040 }2046 }
...@@ -2088,7 +2094,7 @@ const DeclGen = struct {...@@ -2088,7 +2094,7 @@ const DeclGen = struct {
2088 /// only checks the size, but the source-of-truth is implemented2094 /// only checks the size, but the source-of-truth is implemented
2089 /// by `isSpvVector()`.2095 /// by `isSpvVector()`.
2090 fn fromType(ty: Type, dg: *DeclGen) Vectorization {2096 fn fromType(ty: Type, dg: *DeclGen) Vectorization {
2091 const mod = dg.module;2097 const mod = dg.pt.zcu;
2092 if (!ty.isVector(mod)) {2098 if (!ty.isVector(mod)) {
2093 return .scalar;2099 return .scalar;
2094 } else if (dg.isSpvVector(ty)) {2100 } else if (dg.isSpvVector(ty)) {
...@@ -2164,11 +2170,11 @@ const DeclGen = struct {...@@ -2164,11 +2170,11 @@ const DeclGen = struct {
2164 /// Turns `ty` into the result-type of an individual vector operation.2170 /// Turns `ty` into the result-type of an individual vector operation.
2165 /// `ty` may be a scalar or vector, it doesn't matter.2171 /// `ty` may be a scalar or vector, it doesn't matter.
2166 fn operationType(self: Vectorization, dg: *DeclGen, ty: Type) !Type {2172 fn operationType(self: Vectorization, dg: *DeclGen, ty: Type) !Type {
2167 const mod = dg.module;2173 const pt = dg.pt;
2168 const scalar_ty = ty.scalarType(mod);2174 const scalar_ty = ty.scalarType(pt.zcu);
2169 return switch (self) {2175 return switch (self) {
2170 .scalar, .unrolled => scalar_ty,2176 .scalar, .unrolled => scalar_ty,
2171 .spv_vectorized => |n| try mod.vectorType(.{2177 .spv_vectorized => |n| try pt.vectorType(.{
2172 .len = n,2178 .len = n,
2173 .child = scalar_ty.toIntern(),2179 .child = scalar_ty.toIntern(),
2174 }),2180 }),
...@@ -2178,11 +2184,11 @@ const DeclGen = struct {...@@ -2178,11 +2184,11 @@ const DeclGen = struct {
2178 /// Turns `ty` into the result-type of the entire operation.2184 /// Turns `ty` into the result-type of the entire operation.
2179 /// `ty` may be a scalar or vector, it doesn't matter.2185 /// `ty` may be a scalar or vector, it doesn't matter.
2180 fn resultType(self: Vectorization, dg: *DeclGen, ty: Type) !Type {2186 fn resultType(self: Vectorization, dg: *DeclGen, ty: Type) !Type {
2181 const mod = dg.module;2187 const pt = dg.pt;
2182 const scalar_ty = ty.scalarType(mod);2188 const scalar_ty = ty.scalarType(pt.zcu);
2183 return switch (self) {2189 return switch (self) {
2184 .scalar => scalar_ty,2190 .scalar => scalar_ty,
2185 .unrolled, .spv_vectorized => |n| try mod.vectorType(.{2191 .unrolled, .spv_vectorized => |n| try pt.vectorType(.{
2186 .len = n,2192 .len = n,
2187 .child = scalar_ty.toIntern(),2193 .child = scalar_ty.toIntern(),
2188 }),2194 }),
...@@ -2193,8 +2199,8 @@ const DeclGen = struct {...@@ -2193,8 +2199,8 @@ const DeclGen = struct {
2193 /// this setup, and returns a new type that holds the relevant information on how to access2199 /// this setup, and returns a new type that holds the relevant information on how to access
2194 /// elements of the input.2200 /// elements of the input.
2195 fn prepare(self: Vectorization, dg: *DeclGen, tmp: Temporary) !PreparedOperand {2201 fn prepare(self: Vectorization, dg: *DeclGen, tmp: Temporary) !PreparedOperand {
2196 const mod = dg.module;2202 const pt = dg.pt;
2197 const is_vector = tmp.ty.isVector(mod);2203 const is_vector = tmp.ty.isVector(pt.zcu);
2198 const is_spv_vector = dg.isSpvVector(tmp.ty);2204 const is_spv_vector = dg.isSpvVector(tmp.ty);
2199 const value: PreparedOperand.Value = switch (tmp.value) {2205 const value: PreparedOperand.Value = switch (tmp.value) {
2200 .singleton => |id| switch (self) {2206 .singleton => |id| switch (self) {
...@@ -2209,7 +2215,7 @@ const DeclGen = struct {...@@ -2209,7 +2215,7 @@ const DeclGen = struct {
2209 }2215 }
22102216
2211 // Broadcast scalar into vector.2217 // Broadcast scalar into vector.
2212 const vector_ty = try mod.vectorType(.{2218 const vector_ty = try pt.vectorType(.{
2213 .len = self.components(),2219 .len = self.components(),
2214 .child = tmp.ty.toIntern(),2220 .child = tmp.ty.toIntern(),
2215 });2221 });
...@@ -2340,7 +2346,7 @@ const DeclGen = struct {...@@ -2340,7 +2346,7 @@ const DeclGen = struct {
2340 /// This function builds an OpSConvert of OpUConvert depending on the2346 /// This function builds an OpSConvert of OpUConvert depending on the
2341 /// signedness of the types.2347 /// signedness of the types.
2342 fn buildIntConvert(self: *DeclGen, dst_ty: Type, src: Temporary) !Temporary {2348 fn buildIntConvert(self: *DeclGen, dst_ty: Type, src: Temporary) !Temporary {
2343 const mod = self.module;2349 const mod = self.pt.zcu;
23442350
2345 const dst_ty_id = try self.resolveType(dst_ty.scalarType(mod), .direct);2351 const dst_ty_id = try self.resolveType(dst_ty.scalarType(mod), .direct);
2346 const src_ty_id = try self.resolveType(src.ty.scalarType(mod), .direct);2352 const src_ty_id = try self.resolveType(src.ty.scalarType(mod), .direct);
...@@ -2419,7 +2425,7 @@ const DeclGen = struct {...@@ -2419,7 +2425,7 @@ const DeclGen = struct {
2419 }2425 }
24202426
2421 fn buildSelect(self: *DeclGen, condition: Temporary, lhs: Temporary, rhs: Temporary) !Temporary {2427 fn buildSelect(self: *DeclGen, condition: Temporary, lhs: Temporary, rhs: Temporary) !Temporary {
2422 const mod = self.module;2428 const mod = self.pt.zcu;
24232429
2424 const v = self.vectorization(.{ condition, lhs, rhs });2430 const v = self.vectorization(.{ condition, lhs, rhs });
2425 const ops = v.operations();2431 const ops = v.operations();
...@@ -2764,7 +2770,8 @@ const DeclGen = struct {...@@ -2764,7 +2770,8 @@ const DeclGen = struct {
2764 lhs: Temporary,2770 lhs: Temporary,
2765 rhs: Temporary,2771 rhs: Temporary,
2766 ) !struct { Temporary, Temporary } {2772 ) !struct { Temporary, Temporary } {
2767 const mod = self.module;2773 const pt = self.pt;
2774 const mod = pt.zcu;
2768 const target = self.getTarget();2775 const target = self.getTarget();
2769 const ip = &mod.intern_pool;2776 const ip = &mod.intern_pool;
27702777
...@@ -2814,7 +2821,7 @@ const DeclGen = struct {...@@ -2814,7 +2821,7 @@ const DeclGen = struct {
2814 // where T is maybe vectorized.2821 // where T is maybe vectorized.
2815 const types = [2]InternPool.Index{ arith_op_ty.toIntern(), arith_op_ty.toIntern() };2822 const types = [2]InternPool.Index{ arith_op_ty.toIntern(), arith_op_ty.toIntern() };
2816 const values = [2]InternPool.Index{ .none, .none };2823 const values = [2]InternPool.Index{ .none, .none };
2817 const index = try ip.getAnonStructType(mod.gpa, .{2824 const index = try ip.getAnonStructType(mod.gpa, pt.tid, .{
2818 .types = &types,2825 .types = &types,
2819 .values = &values,2826 .values = &values,
2820 .names = &.{},2827 .names = &.{},
...@@ -2888,7 +2895,7 @@ const DeclGen = struct {...@@ -2888,7 +2895,7 @@ const DeclGen = struct {
2888 /// the name of an error in the text executor.2895 /// the name of an error in the text executor.
2889 fn generateTestEntryPoint(self: *DeclGen, name: []const u8, spv_test_decl_index: SpvModule.Decl.Index) !void {2896 fn generateTestEntryPoint(self: *DeclGen, name: []const u8, spv_test_decl_index: SpvModule.Decl.Index) !void {
2890 const anyerror_ty_id = try self.resolveType(Type.anyerror, .direct);2897 const anyerror_ty_id = try self.resolveType(Type.anyerror, .direct);
2891 const ptr_anyerror_ty = try self.module.ptrType(.{2898 const ptr_anyerror_ty = try self.pt.ptrType(.{
2892 .child = Type.anyerror.toIntern(),2899 .child = Type.anyerror.toIntern(),
2893 .flags = .{ .address_space = .global },2900 .flags = .{ .address_space = .global },
2894 });2901 });
...@@ -2940,7 +2947,8 @@ const DeclGen = struct {...@@ -2940,7 +2947,8 @@ const DeclGen = struct {
2940 }2947 }
29412948
2942 fn genDecl(self: *DeclGen) !void {2949 fn genDecl(self: *DeclGen) !void {
2943 const mod = self.module;2950 const pt = self.pt;
2951 const mod = pt.zcu;
2944 const ip = &mod.intern_pool;2952 const ip = &mod.intern_pool;
2945 const decl = mod.declPtr(self.decl_index);2953 const decl = mod.declPtr(self.decl_index);
2946 const spv_decl_index = try self.object.resolveDecl(mod, self.decl_index);2954 const spv_decl_index = try self.object.resolveDecl(mod, self.decl_index);
...@@ -2967,7 +2975,7 @@ const DeclGen = struct {...@@ -2967,7 +2975,7 @@ const DeclGen = struct {
2967 try self.args.ensureUnusedCapacity(self.gpa, fn_info.param_types.len);2975 try self.args.ensureUnusedCapacity(self.gpa, fn_info.param_types.len);
2968 for (fn_info.param_types.get(ip)) |param_ty_index| {2976 for (fn_info.param_types.get(ip)) |param_ty_index| {
2969 const param_ty = Type.fromInterned(param_ty_index);2977 const param_ty = Type.fromInterned(param_ty_index);
2970 if (!param_ty.hasRuntimeBitsIgnoreComptime(mod)) continue;2978 if (!param_ty.hasRuntimeBitsIgnoreComptime(pt)) continue;
29712979
2972 const param_type_id = try self.resolveType(param_ty, .direct);2980 const param_type_id = try self.resolveType(param_ty, .direct);
2973 const arg_result_id = self.spv.allocId();2981 const arg_result_id = self.spv.allocId();
...@@ -3004,11 +3012,11 @@ const DeclGen = struct {...@@ -3004,11 +3012,11 @@ const DeclGen = struct {
3004 // Append the actual code into the functions section.3012 // Append the actual code into the functions section.
3005 try self.spv.addFunction(spv_decl_index, self.func);3013 try self.spv.addFunction(spv_decl_index, self.func);
30063014
3007 const fqn = try decl.fullyQualifiedName(self.module);3015 const fqn = try decl.fullyQualifiedName(self.pt);
3008 try self.spv.debugName(result_id, fqn.toSlice(ip));3016 try self.spv.debugName(result_id, fqn.toSlice(ip));
30093017
3010 // Temporarily generate a test kernel declaration if this is a test function.3018 // Temporarily generate a test kernel declaration if this is a test function.
3011 if (self.module.test_functions.contains(self.decl_index)) {3019 if (self.pt.zcu.test_functions.contains(self.decl_index)) {
3012 try self.generateTestEntryPoint(fqn.toSlice(ip), spv_decl_index);3020 try self.generateTestEntryPoint(fqn.toSlice(ip), spv_decl_index);
3013 }3021 }
3014 },3022 },
...@@ -3033,7 +3041,7 @@ const DeclGen = struct {...@@ -3033,7 +3041,7 @@ const DeclGen = struct {
3033 .storage_class = final_storage_class,3041 .storage_class = final_storage_class,
3034 });3042 });
30353043
3036 const fqn = try decl.fullyQualifiedName(self.module);3044 const fqn = try decl.fullyQualifiedName(self.pt);
3037 try self.spv.debugName(result_id, fqn.toSlice(ip));3045 try self.spv.debugName(result_id, fqn.toSlice(ip));
3038 try self.spv.declareDeclDeps(spv_decl_index, &.{});3046 try self.spv.declareDeclDeps(spv_decl_index, &.{});
3039 },3047 },
...@@ -3078,7 +3086,7 @@ const DeclGen = struct {...@@ -3078,7 +3086,7 @@ const DeclGen = struct {
3078 try self.func.body.emit(self.spv.gpa, .OpFunctionEnd, {});3086 try self.func.body.emit(self.spv.gpa, .OpFunctionEnd, {});
3079 try self.spv.addFunction(spv_decl_index, self.func);3087 try self.spv.addFunction(spv_decl_index, self.func);
30803088
3081 const fqn = try decl.fullyQualifiedName(self.module);3089 const fqn = try decl.fullyQualifiedName(self.pt);
3082 try self.spv.debugNameFmt(initializer_id, "initializer of {}", .{fqn.fmt(ip)});3090 try self.spv.debugNameFmt(initializer_id, "initializer of {}", .{fqn.fmt(ip)});
30833091
3084 try self.spv.sections.types_globals_constants.emit(self.spv.gpa, .OpExtInst, .{3092 try self.spv.sections.types_globals_constants.emit(self.spv.gpa, .OpExtInst, .{
...@@ -3119,7 +3127,7 @@ const DeclGen = struct {...@@ -3119,7 +3127,7 @@ const DeclGen = struct {
3119 /// Convert representation from indirect (in memory) to direct (in 'register')3127 /// Convert representation from indirect (in memory) to direct (in 'register')
3120 /// This converts the argument type from resolveType(ty, .indirect) to resolveType(ty, .direct).3128 /// This converts the argument type from resolveType(ty, .indirect) to resolveType(ty, .direct).
3121 fn convertToDirect(self: *DeclGen, ty: Type, operand_id: IdRef) !IdRef {3129 fn convertToDirect(self: *DeclGen, ty: Type, operand_id: IdRef) !IdRef {
3122 const mod = self.module;3130 const mod = self.pt.zcu;
3123 switch (ty.scalarType(mod).zigTypeTag(mod)) {3131 switch (ty.scalarType(mod).zigTypeTag(mod)) {
3124 .Bool => {3132 .Bool => {
3125 const false_id = try self.constBool(false, .indirect);3133 const false_id = try self.constBool(false, .indirect);
...@@ -3145,7 +3153,7 @@ const DeclGen = struct {...@@ -3145,7 +3153,7 @@ const DeclGen = struct {
3145 /// Convert representation from direct (in 'register) to direct (in memory)3153 /// Convert representation from direct (in 'register) to direct (in memory)
3146 /// This converts the argument type from resolveType(ty, .direct) to resolveType(ty, .indirect).3154 /// This converts the argument type from resolveType(ty, .direct) to resolveType(ty, .indirect).
3147 fn convertToIndirect(self: *DeclGen, ty: Type, operand_id: IdRef) !IdRef {3155 fn convertToIndirect(self: *DeclGen, ty: Type, operand_id: IdRef) !IdRef {
3148 const mod = self.module;3156 const mod = self.pt.zcu;
3149 switch (ty.scalarType(mod).zigTypeTag(mod)) {3157 switch (ty.scalarType(mod).zigTypeTag(mod)) {
3150 .Bool => {3158 .Bool => {
3151 const result = try self.intFromBool(Temporary.init(ty, operand_id));3159 const result = try self.intFromBool(Temporary.init(ty, operand_id));
...@@ -3222,7 +3230,7 @@ const DeclGen = struct {...@@ -3222,7 +3230,7 @@ const DeclGen = struct {
3222 }3230 }
32233231
3224 fn genInst(self: *DeclGen, inst: Air.Inst.Index) !void {3232 fn genInst(self: *DeclGen, inst: Air.Inst.Index) !void {
3225 const mod = self.module;3233 const mod = self.pt.zcu;
3226 const ip = &mod.intern_pool;3234 const ip = &mod.intern_pool;
3227 if (self.liveness.isUnused(inst) and !self.air.mustLower(inst, ip))3235 if (self.liveness.isUnused(inst) and !self.air.mustLower(inst, ip))
3228 return;3236 return;
...@@ -3402,7 +3410,7 @@ const DeclGen = struct {...@@ -3402,7 +3410,7 @@ const DeclGen = struct {
3402 }3410 }
34033411
3404 fn airShift(self: *DeclGen, inst: Air.Inst.Index, unsigned: BinaryOp, signed: BinaryOp) !?IdRef {3412 fn airShift(self: *DeclGen, inst: Air.Inst.Index, unsigned: BinaryOp, signed: BinaryOp) !?IdRef {
3405 const mod = self.module;3413 const mod = self.pt.zcu;
3406 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;3414 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
34073415
3408 const base = try self.temporary(bin_op.lhs);3416 const base = try self.temporary(bin_op.lhs);
...@@ -3480,7 +3488,7 @@ const DeclGen = struct {...@@ -3480,7 +3488,7 @@ const DeclGen = struct {
3480 /// All other values are returned unmodified (this makes strange integer3488 /// All other values are returned unmodified (this makes strange integer
3481 /// wrapping easier to use in generic operations).3489 /// wrapping easier to use in generic operations).
3482 fn normalize(self: *DeclGen, value: Temporary, info: ArithmeticTypeInfo) !Temporary {3490 fn normalize(self: *DeclGen, value: Temporary, info: ArithmeticTypeInfo) !Temporary {
3483 const mod = self.module;3491 const mod = self.pt.zcu;
3484 const ty = value.ty;3492 const ty = value.ty;
3485 switch (info.class) {3493 switch (info.class) {
3486 .integer, .bool, .float => return value,3494 .integer, .bool, .float => return value,
...@@ -3721,7 +3729,7 @@ const DeclGen = struct {...@@ -3721,7 +3729,7 @@ const DeclGen = struct {
37213729
3722 fn airMulOverflow(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {3730 fn airMulOverflow(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {
3723 const target = self.getTarget();3731 const target = self.getTarget();
3724 const mod = self.module;3732 const pt = self.pt;
37253733
3726 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;3734 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
3727 const extra = self.air.extraData(Air.Bin, ty_pl.payload).data;3735 const extra = self.air.extraData(Air.Bin, ty_pl.payload).data;
...@@ -3758,7 +3766,7 @@ const DeclGen = struct {...@@ -3758,7 +3766,7 @@ const DeclGen = struct {
3758 const result, const overflowed = switch (info.signedness) {3766 const result, const overflowed = switch (info.signedness) {
3759 .unsigned => blk: {3767 .unsigned => blk: {
3760 if (maybe_op_ty_bits) |op_ty_bits| {3768 if (maybe_op_ty_bits) |op_ty_bits| {
3761 const op_ty = try mod.intType(.unsigned, op_ty_bits);3769 const op_ty = try pt.intType(.unsigned, op_ty_bits);
3762 const casted_lhs = try self.buildIntConvert(op_ty, lhs);3770 const casted_lhs = try self.buildIntConvert(op_ty, lhs);
3763 const casted_rhs = try self.buildIntConvert(op_ty, rhs);3771 const casted_rhs = try self.buildIntConvert(op_ty, rhs);
37643772
...@@ -3828,7 +3836,7 @@ const DeclGen = struct {...@@ -3828,7 +3836,7 @@ const DeclGen = struct {
3828 );3836 );
38293837
3830 if (maybe_op_ty_bits) |op_ty_bits| {3838 if (maybe_op_ty_bits) |op_ty_bits| {
3831 const op_ty = try mod.intType(.signed, op_ty_bits);3839 const op_ty = try pt.intType(.signed, op_ty_bits);
3832 // Assume normalized; sign bit is set. We want a sign extend.3840 // Assume normalized; sign bit is set. We want a sign extend.
3833 const casted_lhs = try self.buildIntConvert(op_ty, lhs);3841 const casted_lhs = try self.buildIntConvert(op_ty, lhs);
3834 const casted_rhs = try self.buildIntConvert(op_ty, rhs);3842 const casted_rhs = try self.buildIntConvert(op_ty, rhs);
...@@ -3900,7 +3908,7 @@ const DeclGen = struct {...@@ -3900,7 +3908,7 @@ const DeclGen = struct {
3900 }3908 }
39013909
3902 fn airShlOverflow(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {3910 fn airShlOverflow(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {
3903 const mod = self.module;3911 const mod = self.pt.zcu;
39043912
3905 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;3913 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
3906 const extra = self.air.extraData(Air.Bin, ty_pl.payload).data;3914 const extra = self.air.extraData(Air.Bin, ty_pl.payload).data;
...@@ -3958,7 +3966,7 @@ const DeclGen = struct {...@@ -3958,7 +3966,7 @@ const DeclGen = struct {
3958 fn airClzCtz(self: *DeclGen, inst: Air.Inst.Index, op: UnaryOp) !?IdRef {3966 fn airClzCtz(self: *DeclGen, inst: Air.Inst.Index, op: UnaryOp) !?IdRef {
3959 if (self.liveness.isUnused(inst)) return null;3967 if (self.liveness.isUnused(inst)) return null;
39603968
3961 const mod = self.module;3969 const mod = self.pt.zcu;
3962 const target = self.getTarget();3970 const target = self.getTarget();
3963 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;3971 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
3964 const operand = try self.temporary(ty_op.operand);3972 const operand = try self.temporary(ty_op.operand);
...@@ -4007,7 +4015,7 @@ const DeclGen = struct {...@@ -4007,7 +4015,7 @@ const DeclGen = struct {
4007 }4015 }
40084016
4009 fn airReduce(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {4017 fn airReduce(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {
4010 const mod = self.module;4018 const mod = self.pt.zcu;
4011 const reduce = self.air.instructions.items(.data)[@intFromEnum(inst)].reduce;4019 const reduce = self.air.instructions.items(.data)[@intFromEnum(inst)].reduce;
4012 const operand = try self.resolve(reduce.operand);4020 const operand = try self.resolve(reduce.operand);
4013 const operand_ty = self.typeOf(reduce.operand);4021 const operand_ty = self.typeOf(reduce.operand);
...@@ -4082,7 +4090,8 @@ const DeclGen = struct {...@@ -4082,7 +4090,8 @@ const DeclGen = struct {
4082 }4090 }
40834091
4084 fn airShuffle(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {4092 fn airShuffle(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {
4085 const mod = self.module;4093 const pt = self.pt;
4094 const mod = pt.zcu;
4086 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;4095 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
4087 const extra = self.air.extraData(Air.Shuffle, ty_pl.payload).data;4096 const extra = self.air.extraData(Air.Shuffle, ty_pl.payload).data;
4088 const a = try self.resolve(extra.a);4097 const a = try self.resolve(extra.a);
...@@ -4108,14 +4117,14 @@ const DeclGen = struct {...@@ -4108,14 +4117,14 @@ const DeclGen = struct {
4108 const a_len = a_ty.vectorLen(mod);4117 const a_len = a_ty.vectorLen(mod);
41094118
4110 for (components, 0..) |*component, i| {4119 for (components, 0..) |*component, i| {
4111 const elem = try mask.elemValue(mod, i);4120 const elem = try mask.elemValue(pt, i);
4112 if (elem.isUndef(mod)) {4121 if (elem.isUndef(mod)) {
4113 // This is explicitly valid for OpVectorShuffle, it indicates undefined.4122 // This is explicitly valid for OpVectorShuffle, it indicates undefined.
4114 component.* = 0xFFFF_FFFF;4123 component.* = 0xFFFF_FFFF;
4115 continue;4124 continue;
4116 }4125 }
41174126
4118 const index = elem.toSignedInt(mod);4127 const index = elem.toSignedInt(pt);
4119 if (index >= 0) {4128 if (index >= 0) {
4120 component.* = @intCast(index);4129 component.* = @intCast(index);
4121 } else {4130 } else {
...@@ -4140,13 +4149,13 @@ const DeclGen = struct {...@@ -4140,13 +4149,13 @@ const DeclGen = struct {
4140 defer self.gpa.free(components);4149 defer self.gpa.free(components);
41414150
4142 for (components, 0..) |*id, i| {4151 for (components, 0..) |*id, i| {
4143 const elem = try mask.elemValue(mod, i);4152 const elem = try mask.elemValue(pt, i);
4144 if (elem.isUndef(mod)) {4153 if (elem.isUndef(mod)) {
4145 id.* = try self.spv.constUndef(scalar_ty_id);4154 id.* = try self.spv.constUndef(scalar_ty_id);
4146 continue;4155 continue;
4147 }4156 }
41484157
4149 const index = elem.toSignedInt(mod);4158 const index = elem.toSignedInt(pt);
4150 if (index >= 0) {4159 if (index >= 0) {
4151 id.* = try self.extractVectorComponent(scalar_ty, a, @intCast(index));4160 id.* = try self.extractVectorComponent(scalar_ty, a, @intCast(index));
4152 } else {4161 } else {
...@@ -4220,7 +4229,7 @@ const DeclGen = struct {...@@ -4220,7 +4229,7 @@ const DeclGen = struct {
4220 }4229 }
42214230
4222 fn ptrAdd(self: *DeclGen, result_ty: Type, ptr_ty: Type, ptr_id: IdRef, offset_id: IdRef) !IdRef {4231 fn ptrAdd(self: *DeclGen, result_ty: Type, ptr_ty: Type, ptr_id: IdRef, offset_id: IdRef) !IdRef {
4223 const mod = self.module;4232 const mod = self.pt.zcu;
4224 const result_ty_id = try self.resolveType(result_ty, .direct);4233 const result_ty_id = try self.resolveType(result_ty, .direct);
42254234
4226 switch (ptr_ty.ptrSize(mod)) {4235 switch (ptr_ty.ptrSize(mod)) {
...@@ -4276,7 +4285,8 @@ const DeclGen = struct {...@@ -4276,7 +4285,8 @@ const DeclGen = struct {
4276 lhs: Temporary,4285 lhs: Temporary,
4277 rhs: Temporary,4286 rhs: Temporary,
4278 ) !Temporary {4287 ) !Temporary {
4279 const mod = self.module;4288 const pt = self.pt;
4289 const mod = pt.zcu;
4280 const scalar_ty = lhs.ty.scalarType(mod);4290 const scalar_ty = lhs.ty.scalarType(mod);
4281 const is_vector = lhs.ty.isVector(mod);4291 const is_vector = lhs.ty.isVector(mod);
42824292
...@@ -4324,7 +4334,7 @@ const DeclGen = struct {...@@ -4324,7 +4334,7 @@ const DeclGen = struct {
43244334
4325 const payload_ty = ty.optionalChild(mod);4335 const payload_ty = ty.optionalChild(mod);
4326 if (ty.optionalReprIsPayload(mod)) {4336 if (ty.optionalReprIsPayload(mod)) {
4327 assert(payload_ty.hasRuntimeBitsIgnoreComptime(mod));4337 assert(payload_ty.hasRuntimeBitsIgnoreComptime(pt));
4328 assert(!payload_ty.isSlice(mod));4338 assert(!payload_ty.isSlice(mod));
43294339
4330 return try self.cmp(op, lhs.pun(payload_ty), rhs.pun(payload_ty));4340 return try self.cmp(op, lhs.pun(payload_ty), rhs.pun(payload_ty));
...@@ -4333,12 +4343,12 @@ const DeclGen = struct {...@@ -4333,12 +4343,12 @@ const DeclGen = struct {
4333 const lhs_id = try lhs.materialize(self);4343 const lhs_id = try lhs.materialize(self);
4334 const rhs_id = try rhs.materialize(self);4344 const rhs_id = try rhs.materialize(self);
43354345
4336 const lhs_valid_id = if (payload_ty.hasRuntimeBitsIgnoreComptime(mod))4346 const lhs_valid_id = if (payload_ty.hasRuntimeBitsIgnoreComptime(pt))
4337 try self.extractField(Type.bool, lhs_id, 1)4347 try self.extractField(Type.bool, lhs_id, 1)
4338 else4348 else
4339 try self.convertToDirect(Type.bool, lhs_id);4349 try self.convertToDirect(Type.bool, lhs_id);
43404350
4341 const rhs_valid_id = if (payload_ty.hasRuntimeBitsIgnoreComptime(mod))4351 const rhs_valid_id = if (payload_ty.hasRuntimeBitsIgnoreComptime(pt))
4342 try self.extractField(Type.bool, rhs_id, 1)4352 try self.extractField(Type.bool, rhs_id, 1)
4343 else4353 else
4344 try self.convertToDirect(Type.bool, rhs_id);4354 try self.convertToDirect(Type.bool, rhs_id);
...@@ -4346,7 +4356,7 @@ const DeclGen = struct {...@@ -4346,7 +4356,7 @@ const DeclGen = struct {
4346 const lhs_valid = Temporary.init(Type.bool, lhs_valid_id);4356 const lhs_valid = Temporary.init(Type.bool, lhs_valid_id);
4347 const rhs_valid = Temporary.init(Type.bool, rhs_valid_id);4357 const rhs_valid = Temporary.init(Type.bool, rhs_valid_id);
43484358
4349 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) {4359 if (!payload_ty.hasRuntimeBitsIgnoreComptime(pt)) {
4350 return try self.cmp(op, lhs_valid, rhs_valid);4360 return try self.cmp(op, lhs_valid, rhs_valid);
4351 }4361 }
43524362
...@@ -4466,7 +4476,7 @@ const DeclGen = struct {...@@ -4466,7 +4476,7 @@ const DeclGen = struct {
4466 src_ty: Type,4476 src_ty: Type,
4467 src_id: IdRef,4477 src_id: IdRef,
4468 ) !IdRef {4478 ) !IdRef {
4469 const mod = self.module;4479 const mod = self.pt.zcu;
4470 const src_ty_id = try self.resolveType(src_ty, .direct);4480 const src_ty_id = try self.resolveType(src_ty, .direct);
4471 const dst_ty_id = try self.resolveType(dst_ty, .direct);4481 const dst_ty_id = try self.resolveType(dst_ty, .direct);
44724482
...@@ -4675,7 +4685,8 @@ const DeclGen = struct {...@@ -4675,7 +4685,8 @@ const DeclGen = struct {
4675 }4685 }
46764686
4677 fn airArrayToSlice(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {4687 fn airArrayToSlice(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {
4678 const mod = self.module;4688 const pt = self.pt;
4689 const mod = pt.zcu;
4679 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;4690 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
4680 const array_ptr_ty = self.typeOf(ty_op.operand);4691 const array_ptr_ty = self.typeOf(ty_op.operand);
4681 const array_ty = array_ptr_ty.childType(mod);4692 const array_ty = array_ptr_ty.childType(mod);
...@@ -4687,7 +4698,7 @@ const DeclGen = struct {...@@ -4687,7 +4698,7 @@ const DeclGen = struct {
4687 const array_ptr_id = try self.resolve(ty_op.operand);4698 const array_ptr_id = try self.resolve(ty_op.operand);
4688 const len_id = try self.constInt(Type.usize, array_ty.arrayLen(mod), .direct);4699 const len_id = try self.constInt(Type.usize, array_ty.arrayLen(mod), .direct);
46894700
4690 const elem_ptr_id = if (!array_ty.hasRuntimeBitsIgnoreComptime(mod))4701 const elem_ptr_id = if (!array_ty.hasRuntimeBitsIgnoreComptime(pt))
4691 // Note: The pointer is something like *opaque{}, so we need to bitcast it to the element type.4702 // Note: The pointer is something like *opaque{}, so we need to bitcast it to the element type.
4692 try self.bitCast(elem_ptr_ty, array_ptr_ty, array_ptr_id)4703 try self.bitCast(elem_ptr_ty, array_ptr_ty, array_ptr_id)
4693 else4704 else
...@@ -4719,7 +4730,8 @@ const DeclGen = struct {...@@ -4719,7 +4730,8 @@ const DeclGen = struct {
4719 }4730 }
47204731
4721 fn airAggregateInit(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {4732 fn airAggregateInit(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {
4722 const mod = self.module;4733 const pt = self.pt;
4734 const mod = pt.zcu;
4723 const ip = &mod.intern_pool;4735 const ip = &mod.intern_pool;
4724 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;4736 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
4725 const result_ty = self.typeOfIndex(inst);4737 const result_ty = self.typeOfIndex(inst);
...@@ -4742,8 +4754,8 @@ const DeclGen = struct {...@@ -4742,8 +4754,8 @@ const DeclGen = struct {
4742 switch (ip.indexToKey(result_ty.toIntern())) {4754 switch (ip.indexToKey(result_ty.toIntern())) {
4743 .anon_struct_type => |tuple| {4755 .anon_struct_type => |tuple| {
4744 for (tuple.types.get(ip), elements, 0..) |field_ty, element, i| {4756 for (tuple.types.get(ip), elements, 0..) |field_ty, element, i| {
4745 if ((try result_ty.structFieldValueComptime(mod, i)) != null) continue;4757 if ((try result_ty.structFieldValueComptime(pt, i)) != null) continue;
4746 assert(Type.fromInterned(field_ty).hasRuntimeBits(mod));4758 assert(Type.fromInterned(field_ty).hasRuntimeBits(pt));
47474759
4748 const id = try self.resolve(element);4760 const id = try self.resolve(element);
4749 types[index] = Type.fromInterned(field_ty);4761 types[index] = Type.fromInterned(field_ty);
...@@ -4756,9 +4768,9 @@ const DeclGen = struct {...@@ -4756,9 +4768,9 @@ const DeclGen = struct {
4756 var it = struct_type.iterateRuntimeOrder(ip);4768 var it = struct_type.iterateRuntimeOrder(ip);
4757 for (elements, 0..) |element, i| {4769 for (elements, 0..) |element, i| {
4758 const field_index = it.next().?;4770 const field_index = it.next().?;
4759 if ((try result_ty.structFieldValueComptime(mod, i)) != null) continue;4771 if ((try result_ty.structFieldValueComptime(pt, i)) != null) continue;
4760 const field_ty = Type.fromInterned(struct_type.field_types.get(ip)[field_index]);4772 const field_ty = Type.fromInterned(struct_type.field_types.get(ip)[field_index]);
4761 assert(field_ty.hasRuntimeBitsIgnoreComptime(mod));4773 assert(field_ty.hasRuntimeBitsIgnoreComptime(pt));
47624774
4763 const id = try self.resolve(element);4775 const id = try self.resolve(element);
4764 types[index] = field_ty;4776 types[index] = field_ty;
...@@ -4808,13 +4820,14 @@ const DeclGen = struct {...@@ -4808,13 +4820,14 @@ const DeclGen = struct {
4808 }4820 }
48094821
4810 fn sliceOrArrayLen(self: *DeclGen, operand_id: IdRef, ty: Type) !IdRef {4822 fn sliceOrArrayLen(self: *DeclGen, operand_id: IdRef, ty: Type) !IdRef {
4811 const mod = self.module;4823 const pt = self.pt;
4824 const mod = pt.zcu;
4812 switch (ty.ptrSize(mod)) {4825 switch (ty.ptrSize(mod)) {
4813 .Slice => return self.extractField(Type.usize, operand_id, 1),4826 .Slice => return self.extractField(Type.usize, operand_id, 1),
4814 .One => {4827 .One => {
4815 const array_ty = ty.childType(mod);4828 const array_ty = ty.childType(mod);
4816 const elem_ty = array_ty.childType(mod);4829 const elem_ty = array_ty.childType(mod);
4817 const abi_size = elem_ty.abiSize(mod);4830 const abi_size = elem_ty.abiSize(pt);
4818 const size = array_ty.arrayLenIncludingSentinel(mod) * abi_size;4831 const size = array_ty.arrayLenIncludingSentinel(mod) * abi_size;
4819 return try self.constInt(Type.usize, size, .direct);4832 return try self.constInt(Type.usize, size, .direct);
4820 },4833 },
...@@ -4823,7 +4836,7 @@ const DeclGen = struct {...@@ -4823,7 +4836,7 @@ const DeclGen = struct {
4823 }4836 }
48244837
4825 fn sliceOrArrayPtr(self: *DeclGen, operand_id: IdRef, ty: Type) !IdRef {4838 fn sliceOrArrayPtr(self: *DeclGen, operand_id: IdRef, ty: Type) !IdRef {
4826 const mod = self.module;4839 const mod = self.pt.zcu;
4827 if (ty.isSlice(mod)) {4840 if (ty.isSlice(mod)) {
4828 const ptr_ty = ty.slicePtrFieldType(mod);4841 const ptr_ty = ty.slicePtrFieldType(mod);
4829 return self.extractField(ptr_ty, operand_id, 0);4842 return self.extractField(ptr_ty, operand_id, 0);
...@@ -4855,7 +4868,7 @@ const DeclGen = struct {...@@ -4855,7 +4868,7 @@ const DeclGen = struct {
4855 }4868 }
48564869
4857 fn airSliceElemPtr(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {4870 fn airSliceElemPtr(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {
4858 const mod = self.module;4871 const mod = self.pt.zcu;
4859 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;4872 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
4860 const bin_op = self.air.extraData(Air.Bin, ty_pl.payload).data;4873 const bin_op = self.air.extraData(Air.Bin, ty_pl.payload).data;
4861 const slice_ty = self.typeOf(bin_op.lhs);4874 const slice_ty = self.typeOf(bin_op.lhs);
...@@ -4872,7 +4885,7 @@ const DeclGen = struct {...@@ -4872,7 +4885,7 @@ const DeclGen = struct {
4872 }4885 }
48734886
4874 fn airSliceElemVal(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {4887 fn airSliceElemVal(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {
4875 const mod = self.module;4888 const mod = self.pt.zcu;
4876 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;4889 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
4877 const slice_ty = self.typeOf(bin_op.lhs);4890 const slice_ty = self.typeOf(bin_op.lhs);
4878 if (!slice_ty.isVolatilePtr(mod) and self.liveness.isUnused(inst)) return null;4891 if (!slice_ty.isVolatilePtr(mod) and self.liveness.isUnused(inst)) return null;
...@@ -4889,7 +4902,7 @@ const DeclGen = struct {...@@ -4889,7 +4902,7 @@ const DeclGen = struct {
4889 }4902 }
48904903
4891 fn ptrElemPtr(self: *DeclGen, ptr_ty: Type, ptr_id: IdRef, index_id: IdRef) !IdRef {4904 fn ptrElemPtr(self: *DeclGen, ptr_ty: Type, ptr_id: IdRef, index_id: IdRef) !IdRef {
4892 const mod = self.module;4905 const mod = self.pt.zcu;
4893 // Construct new pointer type for the resulting pointer4906 // Construct new pointer type for the resulting pointer
4894 const elem_ty = ptr_ty.elemType2(mod); // use elemType() so that we get T for *[N]T.4907 const elem_ty = ptr_ty.elemType2(mod); // use elemType() so that we get T for *[N]T.
4895 const elem_ptr_ty_id = try self.ptrType(elem_ty, self.spvStorageClass(ptr_ty.ptrAddressSpace(mod)));4908 const elem_ptr_ty_id = try self.ptrType(elem_ty, self.spvStorageClass(ptr_ty.ptrAddressSpace(mod)));
...@@ -4904,14 +4917,15 @@ const DeclGen = struct {...@@ -4904,14 +4917,15 @@ const DeclGen = struct {
4904 }4917 }
49054918
4906 fn airPtrElemPtr(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {4919 fn airPtrElemPtr(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {
4907 const mod = self.module;4920 const pt = self.pt;
4921 const mod = pt.zcu;
4908 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;4922 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
4909 const bin_op = self.air.extraData(Air.Bin, ty_pl.payload).data;4923 const bin_op = self.air.extraData(Air.Bin, ty_pl.payload).data;
4910 const src_ptr_ty = self.typeOf(bin_op.lhs);4924 const src_ptr_ty = self.typeOf(bin_op.lhs);
4911 const elem_ty = src_ptr_ty.childType(mod);4925 const elem_ty = src_ptr_ty.childType(mod);
4912 const ptr_id = try self.resolve(bin_op.lhs);4926 const ptr_id = try self.resolve(bin_op.lhs);
49134927
4914 if (!elem_ty.hasRuntimeBitsIgnoreComptime(mod)) {4928 if (!elem_ty.hasRuntimeBitsIgnoreComptime(pt)) {
4915 const dst_ptr_ty = self.typeOfIndex(inst);4929 const dst_ptr_ty = self.typeOfIndex(inst);
4916 return try self.bitCast(dst_ptr_ty, src_ptr_ty, ptr_id);4930 return try self.bitCast(dst_ptr_ty, src_ptr_ty, ptr_id);
4917 }4931 }
...@@ -4921,7 +4935,7 @@ const DeclGen = struct {...@@ -4921,7 +4935,7 @@ const DeclGen = struct {
4921 }4935 }
49224936
4923 fn airArrayElemVal(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {4937 fn airArrayElemVal(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {
4924 const mod = self.module;4938 const mod = self.pt.zcu;
4925 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;4939 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
4926 const array_ty = self.typeOf(bin_op.lhs);4940 const array_ty = self.typeOf(bin_op.lhs);
4927 const elem_ty = array_ty.childType(mod);4941 const elem_ty = array_ty.childType(mod);
...@@ -4982,7 +4996,7 @@ const DeclGen = struct {...@@ -4982,7 +4996,7 @@ const DeclGen = struct {
4982 }4996 }
49834997
4984 fn airPtrElemVal(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {4998 fn airPtrElemVal(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {
4985 const mod = self.module;4999 const mod = self.pt.zcu;
4986 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;5000 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
4987 const ptr_ty = self.typeOf(bin_op.lhs);5001 const ptr_ty = self.typeOf(bin_op.lhs);
4988 const elem_ty = self.typeOfIndex(inst);5002 const elem_ty = self.typeOfIndex(inst);
...@@ -4993,7 +5007,7 @@ const DeclGen = struct {...@@ -4993,7 +5007,7 @@ const DeclGen = struct {
4993 }5007 }
49945008
4995 fn airVectorStoreElem(self: *DeclGen, inst: Air.Inst.Index) !void {5009 fn airVectorStoreElem(self: *DeclGen, inst: Air.Inst.Index) !void {
4996 const mod = self.module;5010 const mod = self.pt.zcu;
4997 const data = self.air.instructions.items(.data)[@intFromEnum(inst)].vector_store_elem;5011 const data = self.air.instructions.items(.data)[@intFromEnum(inst)].vector_store_elem;
4998 const extra = self.air.extraData(Air.Bin, data.payload).data;5012 const extra = self.air.extraData(Air.Bin, data.payload).data;
49995013
...@@ -5015,7 +5029,7 @@ const DeclGen = struct {...@@ -5015,7 +5029,7 @@ const DeclGen = struct {
5015 }5029 }
50165030
5017 fn airSetUnionTag(self: *DeclGen, inst: Air.Inst.Index) !void {5031 fn airSetUnionTag(self: *DeclGen, inst: Air.Inst.Index) !void {
5018 const mod = self.module;5032 const mod = self.pt.zcu;
5019 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;5033 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
5020 const un_ptr_ty = self.typeOf(bin_op.lhs);5034 const un_ptr_ty = self.typeOf(bin_op.lhs);
5021 const un_ty = un_ptr_ty.childType(mod);5035 const un_ty = un_ptr_ty.childType(mod);
...@@ -5041,7 +5055,7 @@ const DeclGen = struct {...@@ -5041,7 +5055,7 @@ const DeclGen = struct {
5041 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;5055 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
5042 const un_ty = self.typeOf(ty_op.operand);5056 const un_ty = self.typeOf(ty_op.operand);
50435057
5044 const mod = self.module;5058 const mod = self.pt.zcu;
5045 const layout = self.unionLayout(un_ty);5059 const layout = self.unionLayout(un_ty);
5046 if (layout.tag_size == 0) return null;5060 if (layout.tag_size == 0) return null;
50475061
...@@ -5064,7 +5078,8 @@ const DeclGen = struct {...@@ -5064,7 +5078,8 @@ const DeclGen = struct {
50645078
5065 // Note: The result here is not cached, because it generates runtime code.5079 // Note: The result here is not cached, because it generates runtime code.
50665080
5067 const mod = self.module;5081 const pt = self.pt;
5082 const mod = pt.zcu;
5068 const ip = &mod.intern_pool;5083 const ip = &mod.intern_pool;
5069 const union_ty = mod.typeToUnion(ty).?;5084 const union_ty = mod.typeToUnion(ty).?;
5070 const tag_ty = Type.fromInterned(union_ty.enum_tag_ty);5085 const tag_ty = Type.fromInterned(union_ty.enum_tag_ty);
...@@ -5076,9 +5091,9 @@ const DeclGen = struct {...@@ -5076,9 +5091,9 @@ const DeclGen = struct {
5076 const layout = self.unionLayout(ty);5091 const layout = self.unionLayout(ty);
50775092
5078 const tag_int = if (layout.tag_size != 0) blk: {5093 const tag_int = if (layout.tag_size != 0) blk: {
5079 const tag_val = try mod.enumValueFieldIndex(tag_ty, active_field);5094 const tag_val = try pt.enumValueFieldIndex(tag_ty, active_field);
5080 const tag_int_val = try tag_val.intFromEnum(tag_ty, mod);5095 const tag_int_val = try tag_val.intFromEnum(tag_ty, pt);
5081 break :blk tag_int_val.toUnsignedInt(mod);5096 break :blk tag_int_val.toUnsignedInt(pt);
5082 } else 0;5097 } else 0;
50835098
5084 if (!layout.has_payload) {5099 if (!layout.has_payload) {
...@@ -5095,7 +5110,7 @@ const DeclGen = struct {...@@ -5095,7 +5110,7 @@ const DeclGen = struct {
5095 }5110 }
50965111
5097 const payload_ty = Type.fromInterned(union_ty.field_types.get(ip)[active_field]);5112 const payload_ty = Type.fromInterned(union_ty.field_types.get(ip)[active_field]);
5098 if (payload_ty.hasRuntimeBitsIgnoreComptime(mod)) {5113 if (payload_ty.hasRuntimeBitsIgnoreComptime(pt)) {
5099 const pl_ptr_ty_id = try self.ptrType(layout.payload_ty, .Function);5114 const pl_ptr_ty_id = try self.ptrType(layout.payload_ty, .Function);
5100 const pl_ptr_id = try self.accessChain(pl_ptr_ty_id, tmp_id, &.{layout.payload_index});5115 const pl_ptr_id = try self.accessChain(pl_ptr_ty_id, tmp_id, &.{layout.payload_index});
5101 const active_pl_ptr_ty_id = try self.ptrType(payload_ty, .Function);5116 const active_pl_ptr_ty_id = try self.ptrType(payload_ty, .Function);
...@@ -5118,7 +5133,8 @@ const DeclGen = struct {...@@ -5118,7 +5133,8 @@ const DeclGen = struct {
5118 }5133 }
51195134
5120 fn airUnionInit(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {5135 fn airUnionInit(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {
5121 const mod = self.module;5136 const pt = self.pt;
5137 const mod = pt.zcu;
5122 const ip = &mod.intern_pool;5138 const ip = &mod.intern_pool;
5123 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;5139 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
5124 const extra = self.air.extraData(Air.UnionInit, ty_pl.payload).data;5140 const extra = self.air.extraData(Air.UnionInit, ty_pl.payload).data;
...@@ -5126,7 +5142,7 @@ const DeclGen = struct {...@@ -5126,7 +5142,7 @@ const DeclGen = struct {
51265142
5127 const union_obj = mod.typeToUnion(ty).?;5143 const union_obj = mod.typeToUnion(ty).?;
5128 const field_ty = Type.fromInterned(union_obj.field_types.get(ip)[extra.field_index]);5144 const field_ty = Type.fromInterned(union_obj.field_types.get(ip)[extra.field_index]);
5129 const payload = if (field_ty.hasRuntimeBitsIgnoreComptime(mod))5145 const payload = if (field_ty.hasRuntimeBitsIgnoreComptime(pt))
5130 try self.resolve(extra.init)5146 try self.resolve(extra.init)
5131 else5147 else
5132 null;5148 null;
...@@ -5134,7 +5150,8 @@ const DeclGen = struct {...@@ -5134,7 +5150,8 @@ const DeclGen = struct {
5134 }5150 }
51355151
5136 fn airStructFieldVal(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {5152 fn airStructFieldVal(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {
5137 const mod = self.module;5153 const pt = self.pt;
5154 const mod = pt.zcu;
5138 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;5155 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
5139 const struct_field = self.air.extraData(Air.StructField, ty_pl.payload).data;5156 const struct_field = self.air.extraData(Air.StructField, ty_pl.payload).data;
51405157
...@@ -5143,7 +5160,7 @@ const DeclGen = struct {...@@ -5143,7 +5160,7 @@ const DeclGen = struct {
5143 const field_index = struct_field.field_index;5160 const field_index = struct_field.field_index;
5144 const field_ty = object_ty.structFieldType(field_index, mod);5161 const field_ty = object_ty.structFieldType(field_index, mod);
51455162
5146 if (!field_ty.hasRuntimeBitsIgnoreComptime(mod)) return null;5163 if (!field_ty.hasRuntimeBitsIgnoreComptime(pt)) return null;
51475164
5148 switch (object_ty.zigTypeTag(mod)) {5165 switch (object_ty.zigTypeTag(mod)) {
5149 .Struct => switch (object_ty.containerLayout(mod)) {5166 .Struct => switch (object_ty.containerLayout(mod)) {
...@@ -5178,7 +5195,8 @@ const DeclGen = struct {...@@ -5178,7 +5195,8 @@ const DeclGen = struct {
5178 }5195 }
51795196
5180 fn airFieldParentPtr(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {5197 fn airFieldParentPtr(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {
5181 const mod = self.module;5198 const pt = self.pt;
5199 const mod = pt.zcu;
5182 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;5200 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
5183 const extra = self.air.extraData(Air.FieldParentPtr, ty_pl.payload).data;5201 const extra = self.air.extraData(Air.FieldParentPtr, ty_pl.payload).data;
51845202
...@@ -5187,7 +5205,7 @@ const DeclGen = struct {...@@ -5187,7 +5205,7 @@ const DeclGen = struct {
51875205
5188 const field_ptr = try self.resolve(extra.field_ptr);5206 const field_ptr = try self.resolve(extra.field_ptr);
5189 const field_ptr_int = try self.intFromPtr(field_ptr);5207 const field_ptr_int = try self.intFromPtr(field_ptr);
5190 const field_offset = parent_ty.structFieldOffset(extra.field_index, mod);5208 const field_offset = parent_ty.structFieldOffset(extra.field_index, pt);
51915209
5192 const base_ptr_int = base_ptr_int: {5210 const base_ptr_int = base_ptr_int: {
5193 if (field_offset == 0) break :base_ptr_int field_ptr_int;5211 if (field_offset == 0) break :base_ptr_int field_ptr_int;
...@@ -5218,7 +5236,7 @@ const DeclGen = struct {...@@ -5218,7 +5236,7 @@ const DeclGen = struct {
5218 ) !IdRef {5236 ) !IdRef {
5219 const result_ty_id = try self.resolveType(result_ptr_ty, .direct);5237 const result_ty_id = try self.resolveType(result_ptr_ty, .direct);
52205238
5221 const zcu = self.module;5239 const zcu = self.pt.zcu;
5222 const object_ty = object_ptr_ty.childType(zcu);5240 const object_ty = object_ptr_ty.childType(zcu);
5223 switch (object_ty.zigTypeTag(zcu)) {5241 switch (object_ty.zigTypeTag(zcu)) {
5224 .Pointer => {5242 .Pointer => {
...@@ -5312,7 +5330,7 @@ const DeclGen = struct {...@@ -5312,7 +5330,7 @@ const DeclGen = struct {
5312 }5330 }
53135331
5314 fn airAlloc(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {5332 fn airAlloc(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {
5315 const mod = self.module;5333 const mod = self.pt.zcu;
5316 const ptr_ty = self.typeOfIndex(inst);5334 const ptr_ty = self.typeOfIndex(inst);
5317 assert(ptr_ty.ptrAddressSpace(mod) == .generic);5335 assert(ptr_ty.ptrAddressSpace(mod) == .generic);
5318 const child_ty = ptr_ty.childType(mod);5336 const child_ty = ptr_ty.childType(mod);
...@@ -5486,9 +5504,10 @@ const DeclGen = struct {...@@ -5486,9 +5504,10 @@ const DeclGen = struct {
5486 // of the block, then a label, and then generate the rest of the current5504 // of the block, then a label, and then generate the rest of the current
5487 // ir.Block in a different SPIR-V block.5505 // ir.Block in a different SPIR-V block.
54885506
5489 const mod = self.module;5507 const pt = self.pt;
5508 const mod = pt.zcu;
5490 const ty = self.typeOfIndex(inst);5509 const ty = self.typeOfIndex(inst);
5491 const have_block_result = ty.isFnOrHasRuntimeBitsIgnoreComptime(mod);5510 const have_block_result = ty.isFnOrHasRuntimeBitsIgnoreComptime(pt);
54925511
5493 const cf = switch (self.control_flow) {5512 const cf = switch (self.control_flow) {
5494 .structured => |*cf| cf,5513 .structured => |*cf| cf,
...@@ -5618,13 +5637,13 @@ const DeclGen = struct {...@@ -5618,13 +5637,13 @@ const DeclGen = struct {
5618 }5637 }
56195638
5620 fn airBr(self: *DeclGen, inst: Air.Inst.Index) !void {5639 fn airBr(self: *DeclGen, inst: Air.Inst.Index) !void {
5621 const mod = self.module;5640 const pt = self.pt;
5622 const br = self.air.instructions.items(.data)[@intFromEnum(inst)].br;5641 const br = self.air.instructions.items(.data)[@intFromEnum(inst)].br;
5623 const operand_ty = self.typeOf(br.operand);5642 const operand_ty = self.typeOf(br.operand);
56245643
5625 switch (self.control_flow) {5644 switch (self.control_flow) {
5626 .structured => |*cf| {5645 .structured => |*cf| {
5627 if (operand_ty.isFnOrHasRuntimeBitsIgnoreComptime(mod)) {5646 if (operand_ty.isFnOrHasRuntimeBitsIgnoreComptime(pt)) {
5628 const operand_id = try self.resolve(br.operand);5647 const operand_id = try self.resolve(br.operand);
5629 const block_result_var_id = cf.block_results.get(br.block_inst).?;5648 const block_result_var_id = cf.block_results.get(br.block_inst).?;
5630 try self.store(operand_ty, block_result_var_id, operand_id, .{});5649 try self.store(operand_ty, block_result_var_id, operand_id, .{});
...@@ -5635,7 +5654,7 @@ const DeclGen = struct {...@@ -5635,7 +5654,7 @@ const DeclGen = struct {
5635 },5654 },
5636 .unstructured => |cf| {5655 .unstructured => |cf| {
5637 const block = cf.blocks.get(br.block_inst).?;5656 const block = cf.blocks.get(br.block_inst).?;
5638 if (operand_ty.isFnOrHasRuntimeBitsIgnoreComptime(mod)) {5657 if (operand_ty.isFnOrHasRuntimeBitsIgnoreComptime(pt)) {
5639 const operand_id = try self.resolve(br.operand);5658 const operand_id = try self.resolve(br.operand);
5640 // current_block_label should not be undefined here, lest there5659 // current_block_label should not be undefined here, lest there
5641 // is a br or br_void in the function's body.5660 // is a br or br_void in the function's body.
...@@ -5762,7 +5781,7 @@ const DeclGen = struct {...@@ -5762,7 +5781,7 @@ const DeclGen = struct {
5762 }5781 }
57635782
5764 fn airLoad(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {5783 fn airLoad(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {
5765 const mod = self.module;5784 const mod = self.pt.zcu;
5766 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;5785 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
5767 const ptr_ty = self.typeOf(ty_op.operand);5786 const ptr_ty = self.typeOf(ty_op.operand);
5768 const elem_ty = self.typeOfIndex(inst);5787 const elem_ty = self.typeOfIndex(inst);
...@@ -5773,20 +5792,22 @@ const DeclGen = struct {...@@ -5773,20 +5792,22 @@ const DeclGen = struct {
5773 }5792 }
57745793
5775 fn airStore(self: *DeclGen, inst: Air.Inst.Index) !void {5794 fn airStore(self: *DeclGen, inst: Air.Inst.Index) !void {
5795 const mod = self.pt.zcu;
5776 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;5796 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
5777 const ptr_ty = self.typeOf(bin_op.lhs);5797 const ptr_ty = self.typeOf(bin_op.lhs);
5778 const elem_ty = ptr_ty.childType(self.module);5798 const elem_ty = ptr_ty.childType(mod);
5779 const ptr = try self.resolve(bin_op.lhs);5799 const ptr = try self.resolve(bin_op.lhs);
5780 const value = try self.resolve(bin_op.rhs);5800 const value = try self.resolve(bin_op.rhs);
57815801
5782 try self.store(elem_ty, ptr, value, .{ .is_volatile = ptr_ty.isVolatilePtr(self.module) });5802 try self.store(elem_ty, ptr, value, .{ .is_volatile = ptr_ty.isVolatilePtr(mod) });
5783 }5803 }
57845804
5785 fn airRet(self: *DeclGen, inst: Air.Inst.Index) !void {5805 fn airRet(self: *DeclGen, inst: Air.Inst.Index) !void {
5806 const pt = self.pt;
5807 const mod = pt.zcu;
5786 const operand = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op;5808 const operand = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op;
5787 const ret_ty = self.typeOf(operand);5809 const ret_ty = self.typeOf(operand);
5788 const mod = self.module;5810 if (!ret_ty.hasRuntimeBitsIgnoreComptime(pt)) {
5789 if (!ret_ty.hasRuntimeBitsIgnoreComptime(mod)) {
5790 const decl = mod.declPtr(self.decl_index);5811 const decl = mod.declPtr(self.decl_index);
5791 const fn_info = mod.typeToFunc(decl.typeOf(mod)).?;5812 const fn_info = mod.typeToFunc(decl.typeOf(mod)).?;
5792 if (Type.fromInterned(fn_info.return_type).isError(mod)) {5813 if (Type.fromInterned(fn_info.return_type).isError(mod)) {
...@@ -5805,12 +5826,13 @@ const DeclGen = struct {...@@ -5805,12 +5826,13 @@ const DeclGen = struct {
5805 }5826 }
58065827
5807 fn airRetLoad(self: *DeclGen, inst: Air.Inst.Index) !void {5828 fn airRetLoad(self: *DeclGen, inst: Air.Inst.Index) !void {
5808 const mod = self.module;5829 const pt = self.pt;
5830 const mod = pt.zcu;
5809 const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op;5831 const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op;
5810 const ptr_ty = self.typeOf(un_op);5832 const ptr_ty = self.typeOf(un_op);
5811 const ret_ty = ptr_ty.childType(mod);5833 const ret_ty = ptr_ty.childType(mod);
58125834
5813 if (!ret_ty.hasRuntimeBitsIgnoreComptime(mod)) {5835 if (!ret_ty.hasRuntimeBitsIgnoreComptime(pt)) {
5814 const decl = mod.declPtr(self.decl_index);5836 const decl = mod.declPtr(self.decl_index);
5815 const fn_info = mod.typeToFunc(decl.typeOf(mod)).?;5837 const fn_info = mod.typeToFunc(decl.typeOf(mod)).?;
5816 if (Type.fromInterned(fn_info.return_type).isError(mod)) {5838 if (Type.fromInterned(fn_info.return_type).isError(mod)) {
...@@ -5832,7 +5854,7 @@ const DeclGen = struct {...@@ -5832,7 +5854,7 @@ const DeclGen = struct {
5832 }5854 }
58335855
5834 fn airTry(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {5856 fn airTry(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {
5835 const mod = self.module;5857 const mod = self.pt.zcu;
5836 const pl_op = self.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;5858 const pl_op = self.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;
5837 const err_union_id = try self.resolve(pl_op.operand);5859 const err_union_id = try self.resolve(pl_op.operand);
5838 const extra = self.air.extraData(Air.Try, pl_op.payload);5860 const extra = self.air.extraData(Air.Try, pl_op.payload);
...@@ -5902,7 +5924,7 @@ const DeclGen = struct {...@@ -5902,7 +5924,7 @@ const DeclGen = struct {
5902 }5924 }
59035925
5904 fn airErrUnionErr(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {5926 fn airErrUnionErr(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {
5905 const mod = self.module;5927 const mod = self.pt.zcu;
5906 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;5928 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
5907 const operand_id = try self.resolve(ty_op.operand);5929 const operand_id = try self.resolve(ty_op.operand);
5908 const err_union_ty = self.typeOf(ty_op.operand);5930 const err_union_ty = self.typeOf(ty_op.operand);
...@@ -5938,7 +5960,7 @@ const DeclGen = struct {...@@ -5938,7 +5960,7 @@ const DeclGen = struct {
5938 }5960 }
59395961
5940 fn airWrapErrUnionErr(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {5962 fn airWrapErrUnionErr(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {
5941 const mod = self.module;5963 const mod = self.pt.zcu;
5942 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;5964 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
5943 const err_union_ty = self.typeOfIndex(inst);5965 const err_union_ty = self.typeOfIndex(inst);
5944 const payload_ty = err_union_ty.errorUnionPayload(mod);5966 const payload_ty = err_union_ty.errorUnionPayload(mod);
...@@ -5985,7 +6007,8 @@ const DeclGen = struct {...@@ -5985,7 +6007,8 @@ const DeclGen = struct {
5985 }6007 }
59866008
5987 fn airIsNull(self: *DeclGen, inst: Air.Inst.Index, is_pointer: bool, pred: enum { is_null, is_non_null }) !?IdRef {6009 fn airIsNull(self: *DeclGen, inst: Air.Inst.Index, is_pointer: bool, pred: enum { is_null, is_non_null }) !?IdRef {
5988 const mod = self.module;6010 const pt = self.pt;
6011 const mod = pt.zcu;
5989 const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op;6012 const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op;
5990 const operand_id = try self.resolve(un_op);6013 const operand_id = try self.resolve(un_op);
5991 const operand_ty = self.typeOf(un_op);6014 const operand_ty = self.typeOf(un_op);
...@@ -6026,7 +6049,7 @@ const DeclGen = struct {...@@ -6026,7 +6049,7 @@ const DeclGen = struct {
60266049
6027 const is_non_null_id = blk: {6050 const is_non_null_id = blk: {
6028 if (is_pointer) {6051 if (is_pointer) {
6029 if (payload_ty.hasRuntimeBitsIgnoreComptime(mod)) {6052 if (payload_ty.hasRuntimeBitsIgnoreComptime(pt)) {
6030 const storage_class = self.spvStorageClass(operand_ty.ptrAddressSpace(mod));6053 const storage_class = self.spvStorageClass(operand_ty.ptrAddressSpace(mod));
6031 const bool_ptr_ty_id = try self.ptrType(Type.bool, storage_class);6054 const bool_ptr_ty_id = try self.ptrType(Type.bool, storage_class);
6032 const tag_ptr_id = try self.accessChain(bool_ptr_ty_id, operand_id, &.{1});6055 const tag_ptr_id = try self.accessChain(bool_ptr_ty_id, operand_id, &.{1});
...@@ -6036,7 +6059,7 @@ const DeclGen = struct {...@@ -6036,7 +6059,7 @@ const DeclGen = struct {
6036 break :blk try self.load(Type.bool, operand_id, .{});6059 break :blk try self.load(Type.bool, operand_id, .{});
6037 }6060 }
60386061
6039 break :blk if (payload_ty.hasRuntimeBitsIgnoreComptime(mod))6062 break :blk if (payload_ty.hasRuntimeBitsIgnoreComptime(pt))
6040 try self.extractField(Type.bool, operand_id, 1)6063 try self.extractField(Type.bool, operand_id, 1)
6041 else6064 else
6042 // Optional representation is bool indicating whether the optional is set6065 // Optional representation is bool indicating whether the optional is set
...@@ -6061,7 +6084,7 @@ const DeclGen = struct {...@@ -6061,7 +6084,7 @@ const DeclGen = struct {
6061 }6084 }
60626085
6063 fn airIsErr(self: *DeclGen, inst: Air.Inst.Index, pred: enum { is_err, is_non_err }) !?IdRef {6086 fn airIsErr(self: *DeclGen, inst: Air.Inst.Index, pred: enum { is_err, is_non_err }) !?IdRef {
6064 const mod = self.module;6087 const mod = self.pt.zcu;
6065 const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op;6088 const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op;
6066 const operand_id = try self.resolve(un_op);6089 const operand_id = try self.resolve(un_op);
6067 const err_union_ty = self.typeOf(un_op);6090 const err_union_ty = self.typeOf(un_op);
...@@ -6094,13 +6117,14 @@ const DeclGen = struct {...@@ -6094,13 +6117,14 @@ const DeclGen = struct {
6094 }6117 }
60956118
6096 fn airUnwrapOptional(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {6119 fn airUnwrapOptional(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {
6097 const mod = self.module;6120 const pt = self.pt;
6121 const mod = pt.zcu;
6098 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;6122 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
6099 const operand_id = try self.resolve(ty_op.operand);6123 const operand_id = try self.resolve(ty_op.operand);
6100 const optional_ty = self.typeOf(ty_op.operand);6124 const optional_ty = self.typeOf(ty_op.operand);
6101 const payload_ty = self.typeOfIndex(inst);6125 const payload_ty = self.typeOfIndex(inst);
61026126
6103 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) return null;6127 if (!payload_ty.hasRuntimeBitsIgnoreComptime(pt)) return null;
61046128
6105 if (optional_ty.optionalReprIsPayload(mod)) {6129 if (optional_ty.optionalReprIsPayload(mod)) {
6106 return operand_id;6130 return operand_id;
...@@ -6110,7 +6134,8 @@ const DeclGen = struct {...@@ -6110,7 +6134,8 @@ const DeclGen = struct {
6110 }6134 }
61116135
6112 fn airUnwrapOptionalPtr(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {6136 fn airUnwrapOptionalPtr(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {
6113 const mod = self.module;6137 const pt = self.pt;
6138 const mod = pt.zcu;
6114 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;6139 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
6115 const operand_id = try self.resolve(ty_op.operand);6140 const operand_id = try self.resolve(ty_op.operand);
6116 const operand_ty = self.typeOf(ty_op.operand);6141 const operand_ty = self.typeOf(ty_op.operand);
...@@ -6119,7 +6144,7 @@ const DeclGen = struct {...@@ -6119,7 +6144,7 @@ const DeclGen = struct {
6119 const result_ty = self.typeOfIndex(inst);6144 const result_ty = self.typeOfIndex(inst);
6120 const result_ty_id = try self.resolveType(result_ty, .direct);6145 const result_ty_id = try self.resolveType(result_ty, .direct);
61216146
6122 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) {6147 if (!payload_ty.hasRuntimeBitsIgnoreComptime(pt)) {
6123 // There is no payload, but we still need to return a valid pointer.6148 // There is no payload, but we still need to return a valid pointer.
6124 // We can just return anything here, so just return a pointer to the operand.6149 // We can just return anything here, so just return a pointer to the operand.
6125 return try self.bitCast(result_ty, operand_ty, operand_id);6150 return try self.bitCast(result_ty, operand_ty, operand_id);
...@@ -6134,11 +6159,12 @@ const DeclGen = struct {...@@ -6134,11 +6159,12 @@ const DeclGen = struct {
6134 }6159 }
61356160
6136 fn airWrapOptional(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {6161 fn airWrapOptional(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {
6137 const mod = self.module;6162 const pt = self.pt;
6163 const mod = pt.zcu;
6138 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;6164 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
6139 const payload_ty = self.typeOf(ty_op.operand);6165 const payload_ty = self.typeOf(ty_op.operand);
61406166
6141 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) {6167 if (!payload_ty.hasRuntimeBitsIgnoreComptime(pt)) {
6142 return try self.constBool(true, .indirect);6168 return try self.constBool(true, .indirect);
6143 }6169 }
61446170
...@@ -6156,7 +6182,8 @@ const DeclGen = struct {...@@ -6156,7 +6182,8 @@ const DeclGen = struct {
6156 }6182 }
61576183
6158 fn airSwitchBr(self: *DeclGen, inst: Air.Inst.Index) !void {6184 fn airSwitchBr(self: *DeclGen, inst: Air.Inst.Index) !void {
6159 const mod = self.module;6185 const pt = self.pt;
6186 const mod = pt.zcu;
6160 const target = self.getTarget();6187 const target = self.getTarget();
6161 const pl_op = self.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;6188 const pl_op = self.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;
6162 const cond_ty = self.typeOf(pl_op.operand);6189 const cond_ty = self.typeOf(pl_op.operand);
...@@ -6240,15 +6267,15 @@ const DeclGen = struct {...@@ -6240,15 +6267,15 @@ const DeclGen = struct {
6240 const label = case_labels.at(case_i);6267 const label = case_labels.at(case_i);
62416268
6242 for (items) |item| {6269 for (items) |item| {
6243 const value = (try self.air.value(item, mod)) orelse unreachable;6270 const value = (try self.air.value(item, pt)) orelse unreachable;
6244 const int_val: u64 = switch (cond_ty.zigTypeTag(mod)) {6271 const int_val: u64 = switch (cond_ty.zigTypeTag(mod)) {
6245 .Bool, .Int => if (cond_ty.isSignedInt(mod)) @bitCast(value.toSignedInt(mod)) else value.toUnsignedInt(mod),6272 .Bool, .Int => if (cond_ty.isSignedInt(mod)) @bitCast(value.toSignedInt(pt)) else value.toUnsignedInt(pt),
6246 .Enum => blk: {6273 .Enum => blk: {
6247 // TODO: figure out of cond_ty is correct (something with enum literals)6274 // TODO: figure out of cond_ty is correct (something with enum literals)
6248 break :blk (try value.intFromEnum(cond_ty, mod)).toUnsignedInt(mod); // TODO: composite integer constants6275 break :blk (try value.intFromEnum(cond_ty, pt)).toUnsignedInt(pt); // TODO: composite integer constants
6249 },6276 },
6250 .ErrorSet => value.getErrorInt(mod),6277 .ErrorSet => value.getErrorInt(mod),
6251 .Pointer => value.toUnsignedInt(mod),6278 .Pointer => value.toUnsignedInt(pt),
6252 else => unreachable,6279 else => unreachable,
6253 };6280 };
6254 const int_lit: spec.LiteralContextDependentNumber = switch (cond_words) {6281 const int_lit: spec.LiteralContextDependentNumber = switch (cond_words) {
...@@ -6328,8 +6355,9 @@ const DeclGen = struct {...@@ -6328,8 +6355,9 @@ const DeclGen = struct {
6328 }6355 }
63296356
6330 fn airDbgStmt(self: *DeclGen, inst: Air.Inst.Index) !void {6357 fn airDbgStmt(self: *DeclGen, inst: Air.Inst.Index) !void {
6358 const pt = self.pt;
6359 const mod = pt.zcu;
6331 const dbg_stmt = self.air.instructions.items(.data)[@intFromEnum(inst)].dbg_stmt;6360 const dbg_stmt = self.air.instructions.items(.data)[@intFromEnum(inst)].dbg_stmt;
6332 const mod = self.module;
6333 const decl = mod.declPtr(self.decl_index);6361 const decl = mod.declPtr(self.decl_index);
6334 const path = decl.getFileScope(mod).sub_file_path;6362 const path = decl.getFileScope(mod).sub_file_path;
6335 try self.func.body.emit(self.spv.gpa, .OpLine, .{6363 try self.func.body.emit(self.spv.gpa, .OpLine, .{
...@@ -6340,7 +6368,7 @@ const DeclGen = struct {...@@ -6340,7 +6368,7 @@ const DeclGen = struct {
6340 }6368 }
63416369
6342 fn airDbgInlineBlock(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {6370 fn airDbgInlineBlock(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {
6343 const mod = self.module;6371 const mod = self.pt.zcu;
6344 const inst_datas = self.air.instructions.items(.data);6372 const inst_datas = self.air.instructions.items(.data);
6345 const extra = self.air.extraData(Air.DbgInlineBlock, inst_datas[@intFromEnum(inst)].ty_pl.payload);6373 const extra = self.air.extraData(Air.DbgInlineBlock, inst_datas[@intFromEnum(inst)].ty_pl.payload);
6346 const decl = mod.funcOwnerDeclPtr(extra.data.func);6374 const decl = mod.funcOwnerDeclPtr(extra.data.func);
...@@ -6358,7 +6386,7 @@ const DeclGen = struct {...@@ -6358,7 +6386,7 @@ const DeclGen = struct {
6358 }6386 }
63596387
6360 fn airAssembly(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {6388 fn airAssembly(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {
6361 const mod = self.module;6389 const mod = self.pt.zcu;
6362 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;6390 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
6363 const extra = self.air.extraData(Air.Asm, ty_pl.payload);6391 const extra = self.air.extraData(Air.Asm, ty_pl.payload);
63646392
...@@ -6440,20 +6468,20 @@ const DeclGen = struct {...@@ -6440,20 +6468,20 @@ const DeclGen = struct {
6440 // TODO: Translate proper error locations.6468 // TODO: Translate proper error locations.
6441 assert(as.errors.items.len != 0);6469 assert(as.errors.items.len != 0);
6442 assert(self.error_msg == null);6470 assert(self.error_msg == null);
6443 const src_loc = self.module.declPtr(self.decl_index).navSrcLoc(mod);6471 const src_loc = mod.declPtr(self.decl_index).navSrcLoc(mod);
6444 self.error_msg = try Module.ErrorMsg.create(self.module.gpa, src_loc, "failed to assemble SPIR-V inline assembly", .{});6472 self.error_msg = try Zcu.ErrorMsg.create(mod.gpa, src_loc, "failed to assemble SPIR-V inline assembly", .{});
6445 const notes = try self.module.gpa.alloc(Module.ErrorMsg, as.errors.items.len);6473 const notes = try mod.gpa.alloc(Zcu.ErrorMsg, as.errors.items.len);
64466474
6447 // Sub-scope to prevent `return error.CodegenFail` from running the errdefers.6475 // Sub-scope to prevent `return error.CodegenFail` from running the errdefers.
6448 {6476 {
6449 errdefer self.module.gpa.free(notes);6477 errdefer mod.gpa.free(notes);
6450 var i: usize = 0;6478 var i: usize = 0;
6451 errdefer for (notes[0..i]) |*note| {6479 errdefer for (notes[0..i]) |*note| {
6452 note.deinit(self.module.gpa);6480 note.deinit(mod.gpa);
6453 };6481 };
64546482
6455 while (i < as.errors.items.len) : (i += 1) {6483 while (i < as.errors.items.len) : (i += 1) {
6456 notes[i] = try Module.ErrorMsg.init(self.module.gpa, src_loc, "{s}", .{as.errors.items[i].msg});6484 notes[i] = try Zcu.ErrorMsg.init(mod.gpa, src_loc, "{s}", .{as.errors.items[i].msg});
6457 }6485 }
6458 }6486 }
6459 self.error_msg.?.notes = notes;6487 self.error_msg.?.notes = notes;
...@@ -6489,7 +6517,8 @@ const DeclGen = struct {...@@ -6489,7 +6517,8 @@ const DeclGen = struct {
6489 fn airCall(self: *DeclGen, inst: Air.Inst.Index, modifier: std.builtin.CallModifier) !?IdRef {6517 fn airCall(self: *DeclGen, inst: Air.Inst.Index, modifier: std.builtin.CallModifier) !?IdRef {
6490 _ = modifier;6518 _ = modifier;
64916519
6492 const mod = self.module;6520 const pt = self.pt;
6521 const mod = pt.zcu;
6493 const pl_op = self.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;6522 const pl_op = self.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;
6494 const extra = self.air.extraData(Air.Call, pl_op.payload);6523 const extra = self.air.extraData(Air.Call, pl_op.payload);
6495 const args: []const Air.Inst.Ref = @ptrCast(self.air.extra[extra.end..][0..extra.data.args_len]);6524 const args: []const Air.Inst.Ref = @ptrCast(self.air.extra[extra.end..][0..extra.data.args_len]);
...@@ -6515,7 +6544,7 @@ const DeclGen = struct {...@@ -6515,7 +6544,7 @@ const DeclGen = struct {
6515 // before starting to emit OpFunctionCall instructions. Hence the6544 // before starting to emit OpFunctionCall instructions. Hence the
6516 // temporary params buffer.6545 // temporary params buffer.
6517 const arg_ty = self.typeOf(arg);6546 const arg_ty = self.typeOf(arg);
6518 if (!arg_ty.hasRuntimeBitsIgnoreComptime(mod)) continue;6547 if (!arg_ty.hasRuntimeBitsIgnoreComptime(pt)) continue;
6519 const arg_id = try self.resolve(arg);6548 const arg_id = try self.resolve(arg);
65206549
6521 params[n_params] = arg_id;6550 params[n_params] = arg_id;
...@@ -6533,7 +6562,7 @@ const DeclGen = struct {...@@ -6533,7 +6562,7 @@ const DeclGen = struct {
6533 try self.func.body.emit(self.spv.gpa, .OpUnreachable, {});6562 try self.func.body.emit(self.spv.gpa, .OpUnreachable, {});
6534 }6563 }
65356564
6536 if (self.liveness.isUnused(inst) or !Type.fromInterned(return_type).hasRuntimeBitsIgnoreComptime(mod)) {6565 if (self.liveness.isUnused(inst) or !Type.fromInterned(return_type).hasRuntimeBitsIgnoreComptime(pt)) {
6537 return null;6566 return null;
6538 }6567 }
65396568
...@@ -6541,11 +6570,10 @@ const DeclGen = struct {...@@ -6541,11 +6570,10 @@ const DeclGen = struct {
6541 }6570 }
65426571
6543 fn builtin3D(self: *DeclGen, result_ty: Type, builtin: spec.BuiltIn, dimension: u32, out_of_range_value: anytype) !IdRef {6572 fn builtin3D(self: *DeclGen, result_ty: Type, builtin: spec.BuiltIn, dimension: u32, out_of_range_value: anytype) !IdRef {
6544 const mod = self.module;
6545 if (dimension >= 3) {6573 if (dimension >= 3) {
6546 return try self.constInt(result_ty, out_of_range_value, .direct);6574 return try self.constInt(result_ty, out_of_range_value, .direct);
6547 }6575 }
6548 const vec_ty = try mod.vectorType(.{6576 const vec_ty = try self.pt.vectorType(.{
6549 .len = 3,6577 .len = 3,
6550 .child = result_ty.toIntern(),6578 .child = result_ty.toIntern(),
6551 });6579 });
...@@ -6591,12 +6619,12 @@ const DeclGen = struct {...@@ -6591,12 +6619,12 @@ const DeclGen = struct {
6591 }6619 }
65926620
6593 fn typeOf(self: *DeclGen, inst: Air.Inst.Ref) Type {6621 fn typeOf(self: *DeclGen, inst: Air.Inst.Ref) Type {
6594 const mod = self.module;6622 const mod = self.pt.zcu;
6595 return self.air.typeOf(inst, &mod.intern_pool);6623 return self.air.typeOf(inst, &mod.intern_pool);
6596 }6624 }
65976625
6598 fn typeOfIndex(self: *DeclGen, inst: Air.Inst.Index) Type {6626 fn typeOfIndex(self: *DeclGen, inst: Air.Inst.Index) Type {
6599 const mod = self.module;6627 const mod = self.pt.zcu;
6600 return self.air.typeOfIndex(inst, &mod.intern_pool);6628 return self.air.typeOfIndex(inst, &mod.intern_pool);
6601 }6629 }
6602};6630};
src/crash_report.zig+3-3
...@@ -76,9 +76,9 @@ fn dumpStatusReport() !void {...@@ -76,9 +76,9 @@ fn dumpStatusReport() !void {
7676
77 const stderr = io.getStdErr().writer();77 const stderr = io.getStdErr().writer();
78 const block: *Sema.Block = anal.block;78 const block: *Sema.Block = anal.block;
79 const mod = anal.sema.mod;79 const zcu = anal.sema.pt.zcu;
8080
81 const file, const src_base_node = Zcu.LazySrcLoc.resolveBaseNode(block.src_base_inst, mod);81 const file, const src_base_node = Zcu.LazySrcLoc.resolveBaseNode(block.src_base_inst, zcu);
8282
83 try stderr.writeAll("Analyzing ");83 try stderr.writeAll("Analyzing ");
84 try writeFilePath(file, stderr);84 try writeFilePath(file, stderr);
...@@ -104,7 +104,7 @@ fn dumpStatusReport() !void {...@@ -104,7 +104,7 @@ fn dumpStatusReport() !void {
104 while (parent) |curr| {104 while (parent) |curr| {
105 fba.reset();105 fba.reset();
106 try stderr.writeAll(" in ");106 try stderr.writeAll(" in ");
107 const cur_block_file, const cur_block_src_base_node = Zcu.LazySrcLoc.resolveBaseNode(curr.block.src_base_inst, mod);107 const cur_block_file, const cur_block_src_base_node = Zcu.LazySrcLoc.resolveBaseNode(curr.block.src_base_inst, zcu);
108 try writeFilePath(cur_block_file, stderr);108 try writeFilePath(cur_block_file, stderr);
109 try stderr.writeAll("\n > ");109 try stderr.writeAll("\n > ");
110 print_zir.renderSingleInstruction(110 print_zir.renderSingleInstruction(
src/link.zig+29-30
...@@ -15,8 +15,6 @@ const Compilation = @import("Compilation.zig");...@@ -15,8 +15,6 @@ const Compilation = @import("Compilation.zig");
15const LibCInstallation = std.zig.LibCInstallation;15const LibCInstallation = std.zig.LibCInstallation;
16const Liveness = @import("Liveness.zig");16const Liveness = @import("Liveness.zig");
17const Zcu = @import("Zcu.zig");17const Zcu = @import("Zcu.zig");
18/// Deprecated.
19const Module = Zcu;
20const InternPool = @import("InternPool.zig");18const InternPool = @import("InternPool.zig");
21const Type = @import("Type.zig");19const Type = @import("Type.zig");
22const Value = @import("Value.zig");20const Value = @import("Value.zig");
...@@ -367,14 +365,14 @@ pub const File = struct {...@@ -367,14 +365,14 @@ pub const File = struct {
367 /// Called from within the CodeGen to lower a local variable instantion as an unnamed365 /// Called from within the CodeGen to lower a local variable instantion as an unnamed
368 /// constant. Returns the symbol index of the lowered constant in the read-only section366 /// constant. Returns the symbol index of the lowered constant in the read-only section
369 /// of the final binary.367 /// of the final binary.
370 pub fn lowerUnnamedConst(base: *File, val: Value, decl_index: InternPool.DeclIndex) UpdateDeclError!u32 {368 pub fn lowerUnnamedConst(base: *File, pt: Zcu.PerThread, val: Value, decl_index: InternPool.DeclIndex) UpdateDeclError!u32 {
371 if (build_options.only_c) @compileError("unreachable");369 if (build_options.only_c) @compileError("unreachable");
372 switch (base.tag) {370 switch (base.tag) {
373 .spirv => unreachable,371 .spirv => unreachable,
374 .c => unreachable,372 .c => unreachable,
375 .nvptx => unreachable,373 .nvptx => unreachable,
376 inline else => |t| {374 inline else => |t| {
377 return @as(*t.Type(), @fieldParentPtr("base", base)).lowerUnnamedConst(val, decl_index);375 return @as(*t.Type(), @fieldParentPtr("base", base)).lowerUnnamedConst(pt, val, decl_index);
378 },376 },
379 }377 }
380 }378 }
...@@ -399,13 +397,13 @@ pub const File = struct {...@@ -399,13 +397,13 @@ pub const File = struct {
399 }397 }
400398
401 /// May be called before or after updateExports for any given Decl.399 /// May be called before or after updateExports for any given Decl.
402 pub fn updateDecl(base: *File, module: *Module, decl_index: InternPool.DeclIndex) UpdateDeclError!void {400 pub fn updateDecl(base: *File, pt: Zcu.PerThread, decl_index: InternPool.DeclIndex) UpdateDeclError!void {
403 const decl = module.declPtr(decl_index);401 const decl = pt.zcu.declPtr(decl_index);
404 assert(decl.has_tv);402 assert(decl.has_tv);
405 switch (base.tag) {403 switch (base.tag) {
406 inline else => |tag| {404 inline else => |tag| {
407 if (tag != .c and build_options.only_c) unreachable;405 if (tag != .c and build_options.only_c) unreachable;
408 return @as(*tag.Type(), @fieldParentPtr("base", base)).updateDecl(module, decl_index);406 return @as(*tag.Type(), @fieldParentPtr("base", base)).updateDecl(pt, decl_index);
409 },407 },
410 }408 }
411 }409 }
...@@ -413,7 +411,7 @@ pub const File = struct {...@@ -413,7 +411,7 @@ pub const File = struct {
413 /// May be called before or after updateExports for any given Decl.411 /// May be called before or after updateExports for any given Decl.
414 pub fn updateFunc(412 pub fn updateFunc(
415 base: *File,413 base: *File,
416 module: *Module,414 pt: Zcu.PerThread,
417 func_index: InternPool.Index,415 func_index: InternPool.Index,
418 air: Air,416 air: Air,
419 liveness: Liveness,417 liveness: Liveness,
...@@ -421,19 +419,19 @@ pub const File = struct {...@@ -421,19 +419,19 @@ pub const File = struct {
421 switch (base.tag) {419 switch (base.tag) {
422 inline else => |tag| {420 inline else => |tag| {
423 if (tag != .c and build_options.only_c) unreachable;421 if (tag != .c and build_options.only_c) unreachable;
424 return @as(*tag.Type(), @fieldParentPtr("base", base)).updateFunc(module, func_index, air, liveness);422 return @as(*tag.Type(), @fieldParentPtr("base", base)).updateFunc(pt, func_index, air, liveness);
425 },423 },
426 }424 }
427 }425 }
428426
429 pub fn updateDeclLineNumber(base: *File, module: *Module, decl_index: InternPool.DeclIndex) UpdateDeclError!void {427 pub fn updateDeclLineNumber(base: *File, pt: Zcu.PerThread, decl_index: InternPool.DeclIndex) UpdateDeclError!void {
430 const decl = module.declPtr(decl_index);428 const decl = pt.zcu.declPtr(decl_index);
431 assert(decl.has_tv);429 assert(decl.has_tv);
432 switch (base.tag) {430 switch (base.tag) {
433 .spirv, .nvptx => {},431 .spirv, .nvptx => {},
434 inline else => |tag| {432 inline else => |tag| {
435 if (tag != .c and build_options.only_c) unreachable;433 if (tag != .c and build_options.only_c) unreachable;
436 return @as(*tag.Type(), @fieldParentPtr("base", base)).updateDeclLineNumber(module, decl_index);434 return @as(*tag.Type(), @fieldParentPtr("base", base)).updateDeclLineNumber(pt, decl_index);
437 },435 },
438 }436 }
439 }437 }
...@@ -537,10 +535,10 @@ pub const File = struct {...@@ -537,10 +535,10 @@ pub const File = struct {
537 /// Commit pending changes and write headers. Takes into account final output mode535 /// Commit pending changes and write headers. Takes into account final output mode
538 /// and `use_lld`, not only `effectiveOutputMode`.536 /// and `use_lld`, not only `effectiveOutputMode`.
539 /// `arena` has the lifetime of the call to `Compilation.update`.537 /// `arena` has the lifetime of the call to `Compilation.update`.
540 pub fn flush(base: *File, arena: Allocator, prog_node: std.Progress.Node) FlushError!void {538 pub fn flush(base: *File, arena: Allocator, tid: Zcu.PerThread.Id, prog_node: std.Progress.Node) FlushError!void {
541 if (build_options.only_c) {539 if (build_options.only_c) {
542 assert(base.tag == .c);540 assert(base.tag == .c);
543 return @as(*C, @fieldParentPtr("base", base)).flush(arena, prog_node);541 return @as(*C, @fieldParentPtr("base", base)).flush(arena, tid, prog_node);
544 }542 }
545 const comp = base.comp;543 const comp = base.comp;
546 if (comp.clang_preprocessor_mode == .yes or comp.clang_preprocessor_mode == .pch) {544 if (comp.clang_preprocessor_mode == .yes or comp.clang_preprocessor_mode == .pch) {
...@@ -563,27 +561,27 @@ pub const File = struct {...@@ -563,27 +561,27 @@ pub const File = struct {
563 const output_mode = comp.config.output_mode;561 const output_mode = comp.config.output_mode;
564 const link_mode = comp.config.link_mode;562 const link_mode = comp.config.link_mode;
565 if (use_lld and output_mode == .Lib and link_mode == .static) {563 if (use_lld and output_mode == .Lib and link_mode == .static) {
566 return base.linkAsArchive(arena, prog_node);564 return base.linkAsArchive(arena, tid, prog_node);
567 }565 }
568 switch (base.tag) {566 switch (base.tag) {
569 inline else => |tag| {567 inline else => |tag| {
570 return @as(*tag.Type(), @fieldParentPtr("base", base)).flush(arena, prog_node);568 return @as(*tag.Type(), @fieldParentPtr("base", base)).flush(arena, tid, prog_node);
571 },569 },
572 }570 }
573 }571 }
574572
575 /// Commit pending changes and write headers. Works based on `effectiveOutputMode`573 /// Commit pending changes and write headers. Works based on `effectiveOutputMode`
576 /// rather than final output mode.574 /// rather than final output mode.
577 pub fn flushModule(base: *File, arena: Allocator, prog_node: std.Progress.Node) FlushError!void {575 pub fn flushModule(base: *File, arena: Allocator, tid: Zcu.PerThread.Id, prog_node: std.Progress.Node) FlushError!void {
578 switch (base.tag) {576 switch (base.tag) {
579 inline else => |tag| {577 inline else => |tag| {
580 if (tag != .c and build_options.only_c) unreachable;578 if (tag != .c and build_options.only_c) unreachable;
581 return @as(*tag.Type(), @fieldParentPtr("base", base)).flushModule(arena, prog_node);579 return @as(*tag.Type(), @fieldParentPtr("base", base)).flushModule(arena, tid, prog_node);
582 },580 },
583 }581 }
584 }582 }
585583
586 /// Called when a Decl is deleted from the Module.584 /// Called when a Decl is deleted from the Zcu.
587 pub fn freeDecl(base: *File, decl_index: InternPool.DeclIndex) void {585 pub fn freeDecl(base: *File, decl_index: InternPool.DeclIndex) void {
588 switch (base.tag) {586 switch (base.tag) {
589 inline else => |tag| {587 inline else => |tag| {
...@@ -604,14 +602,14 @@ pub const File = struct {...@@ -604,14 +602,14 @@ pub const File = struct {
604 /// May be called before or after updateDecl for any given Decl.602 /// May be called before or after updateDecl for any given Decl.
605 pub fn updateExports(603 pub fn updateExports(
606 base: *File,604 base: *File,
607 module: *Module,605 pt: Zcu.PerThread,
608 exported: Module.Exported,606 exported: Zcu.Exported,
609 export_indices: []const u32,607 export_indices: []const u32,
610 ) UpdateExportsError!void {608 ) UpdateExportsError!void {
611 switch (base.tag) {609 switch (base.tag) {
612 inline else => |tag| {610 inline else => |tag| {
613 if (tag != .c and build_options.only_c) unreachable;611 if (tag != .c and build_options.only_c) unreachable;
614 return @as(*tag.Type(), @fieldParentPtr("base", base)).updateExports(module, exported, export_indices);612 return @as(*tag.Type(), @fieldParentPtr("base", base)).updateExports(pt, exported, export_indices);
615 },613 },
616 }614 }
617 }615 }
...@@ -628,14 +626,14 @@ pub const File = struct {...@@ -628,14 +626,14 @@ pub const File = struct {
628 /// `Decl`'s address was not yet resolved, or the containing atom gets moved in virtual memory.626 /// `Decl`'s address was not yet resolved, or the containing atom gets moved in virtual memory.
629 /// May be called before or after updateFunc/updateDecl therefore it is up to the linker to allocate627 /// May be called before or after updateFunc/updateDecl therefore it is up to the linker to allocate
630 /// the block/atom.628 /// the block/atom.
631 pub fn getDeclVAddr(base: *File, decl_index: InternPool.DeclIndex, reloc_info: RelocInfo) !u64 {629 pub fn getDeclVAddr(base: *File, pt: Zcu.PerThread, decl_index: InternPool.DeclIndex, reloc_info: RelocInfo) !u64 {
632 if (build_options.only_c) @compileError("unreachable");630 if (build_options.only_c) @compileError("unreachable");
633 switch (base.tag) {631 switch (base.tag) {
634 .c => unreachable,632 .c => unreachable,
635 .spirv => unreachable,633 .spirv => unreachable,
636 .nvptx => unreachable,634 .nvptx => unreachable,
637 inline else => |tag| {635 inline else => |tag| {
638 return @as(*tag.Type(), @fieldParentPtr("base", base)).getDeclVAddr(decl_index, reloc_info);636 return @as(*tag.Type(), @fieldParentPtr("base", base)).getDeclVAddr(pt, decl_index, reloc_info);
639 },637 },
640 }638 }
641 }639 }
...@@ -644,9 +642,10 @@ pub const File = struct {...@@ -644,9 +642,10 @@ pub const File = struct {
644642
645 pub fn lowerAnonDecl(643 pub fn lowerAnonDecl(
646 base: *File,644 base: *File,
645 pt: Zcu.PerThread,
647 decl_val: InternPool.Index,646 decl_val: InternPool.Index,
648 decl_align: InternPool.Alignment,647 decl_align: InternPool.Alignment,
649 src_loc: Module.LazySrcLoc,648 src_loc: Zcu.LazySrcLoc,
650 ) !LowerResult {649 ) !LowerResult {
651 if (build_options.only_c) @compileError("unreachable");650 if (build_options.only_c) @compileError("unreachable");
652 switch (base.tag) {651 switch (base.tag) {
...@@ -654,7 +653,7 @@ pub const File = struct {...@@ -654,7 +653,7 @@ pub const File = struct {
654 .spirv => unreachable,653 .spirv => unreachable,
655 .nvptx => unreachable,654 .nvptx => unreachable,
656 inline else => |tag| {655 inline else => |tag| {
657 return @as(*tag.Type(), @fieldParentPtr("base", base)).lowerAnonDecl(decl_val, decl_align, src_loc);656 return @as(*tag.Type(), @fieldParentPtr("base", base)).lowerAnonDecl(pt, decl_val, decl_align, src_loc);
658 },657 },
659 }658 }
660 }659 }
...@@ -689,7 +688,7 @@ pub const File = struct {...@@ -689,7 +688,7 @@ pub const File = struct {
689 }688 }
690 }689 }
691690
692 pub fn linkAsArchive(base: *File, arena: Allocator, prog_node: std.Progress.Node) FlushError!void {691 pub fn linkAsArchive(base: *File, arena: Allocator, tid: Zcu.PerThread.Id, prog_node: std.Progress.Node) FlushError!void {
693 const tracy = trace(@src());692 const tracy = trace(@src());
694 defer tracy.end();693 defer tracy.end();
695694
...@@ -704,7 +703,7 @@ pub const File = struct {...@@ -704,7 +703,7 @@ pub const File = struct {
704 // If there is no Zig code to compile, then we should skip flushing the output file703 // If there is no Zig code to compile, then we should skip flushing the output file
705 // because it will not be part of the linker line anyway.704 // because it will not be part of the linker line anyway.
706 const zcu_obj_path: ?[]const u8 = if (opt_zcu != null) blk: {705 const zcu_obj_path: ?[]const u8 = if (opt_zcu != null) blk: {
707 try base.flushModule(arena, prog_node);706 try base.flushModule(arena, tid, prog_node);
708707
709 const dirname = fs.path.dirname(full_out_path_z) orelse ".";708 const dirname = fs.path.dirname(full_out_path_z) orelse ".";
710 break :blk try fs.path.join(arena, &.{ dirname, base.zcu_object_sub_path.? });709 break :blk try fs.path.join(arena, &.{ dirname, base.zcu_object_sub_path.? });
...@@ -896,14 +895,14 @@ pub const File = struct {...@@ -896,14 +895,14 @@ pub const File = struct {
896 kind: Kind,895 kind: Kind,
897 ty: Type,896 ty: Type,
898897
899 pub fn initDecl(kind: Kind, decl: ?InternPool.DeclIndex, mod: *Module) LazySymbol {898 pub fn initDecl(kind: Kind, decl: ?InternPool.DeclIndex, mod: *Zcu) LazySymbol {
900 return .{ .kind = kind, .ty = if (decl) |decl_index|899 return .{ .kind = kind, .ty = if (decl) |decl_index|
901 mod.declPtr(decl_index).val.toType()900 mod.declPtr(decl_index).val.toType()
902 else901 else
903 Type.anyerror };902 Type.anyerror };
904 }903 }
905904
906 pub fn getDecl(self: LazySymbol, mod: *Module) InternPool.OptionalDeclIndex {905 pub fn getDecl(self: LazySymbol, mod: *Zcu) InternPool.OptionalDeclIndex {
907 return InternPool.OptionalDeclIndex.init(self.ty.getOwnerDeclOrNull(mod));906 return InternPool.OptionalDeclIndex.init(self.ty.getOwnerDeclOrNull(mod));
908 }907 }
909 };908 };
src/link/C.zig+33-30
...@@ -186,13 +186,13 @@ pub fn freeDecl(self: *C, decl_index: InternPool.DeclIndex) void {...@@ -186,13 +186,13 @@ pub fn freeDecl(self: *C, decl_index: InternPool.DeclIndex) void {
186186
187pub fn updateFunc(187pub fn updateFunc(
188 self: *C,188 self: *C,
189 zcu: *Zcu,189 pt: Zcu.PerThread,
190 func_index: InternPool.Index,190 func_index: InternPool.Index,
191 air: Air,191 air: Air,
192 liveness: Liveness,192 liveness: Liveness,
193) !void {193) !void {
194 const gpa = self.base.comp.gpa;194 const zcu = pt.zcu;
195195 const gpa = zcu.gpa;
196 const func = zcu.funcInfo(func_index);196 const func = zcu.funcInfo(func_index);
197 const decl_index = func.owner_decl;197 const decl_index = func.owner_decl;
198 const decl = zcu.declPtr(decl_index);198 const decl = zcu.declPtr(decl_index);
...@@ -218,7 +218,7 @@ pub fn updateFunc(...@@ -218,7 +218,7 @@ pub fn updateFunc(
218 .object = .{218 .object = .{
219 .dg = .{219 .dg = .{
220 .gpa = gpa,220 .gpa = gpa,
221 .zcu = zcu,221 .pt = pt,
222 .mod = file_scope.mod,222 .mod = file_scope.mod,
223 .error_msg = null,223 .error_msg = null,
224 .pass = .{ .decl = decl_index },224 .pass = .{ .decl = decl_index },
...@@ -263,7 +263,7 @@ pub fn updateFunc(...@@ -263,7 +263,7 @@ pub fn updateFunc(
263 gop.value_ptr.code = try self.addString(function.object.code.items);263 gop.value_ptr.code = try self.addString(function.object.code.items);
264}264}
265265
266fn updateAnonDecl(self: *C, zcu: *Zcu, i: usize) !void {266fn updateAnonDecl(self: *C, pt: Zcu.PerThread, i: usize) !void {
267 const gpa = self.base.comp.gpa;267 const gpa = self.base.comp.gpa;
268 const anon_decl = self.anon_decls.keys()[i];268 const anon_decl = self.anon_decls.keys()[i];
269269
...@@ -275,8 +275,8 @@ fn updateAnonDecl(self: *C, zcu: *Zcu, i: usize) !void {...@@ -275,8 +275,8 @@ fn updateAnonDecl(self: *C, zcu: *Zcu, i: usize) !void {
275 var object: codegen.Object = .{275 var object: codegen.Object = .{
276 .dg = .{276 .dg = .{
277 .gpa = gpa,277 .gpa = gpa,
278 .zcu = zcu,278 .pt = pt,
279 .mod = zcu.root_mod,279 .mod = pt.zcu.root_mod,
280 .error_msg = null,280 .error_msg = null,
281 .pass = .{ .anon = anon_decl },281 .pass = .{ .anon = anon_decl },
282 .is_naked_fn = false,282 .is_naked_fn = false,
...@@ -319,12 +319,13 @@ fn updateAnonDecl(self: *C, zcu: *Zcu, i: usize) !void {...@@ -319,12 +319,13 @@ fn updateAnonDecl(self: *C, zcu: *Zcu, i: usize) !void {
319 };319 };
320}320}
321321
322pub fn updateDecl(self: *C, zcu: *Zcu, decl_index: InternPool.DeclIndex) !void {322pub fn updateDecl(self: *C, pt: Zcu.PerThread, decl_index: InternPool.DeclIndex) !void {
323 const tracy = trace(@src());323 const tracy = trace(@src());
324 defer tracy.end();324 defer tracy.end();
325325
326 const gpa = self.base.comp.gpa;326 const gpa = self.base.comp.gpa;
327327
328 const zcu = pt.zcu;
328 const decl = zcu.declPtr(decl_index);329 const decl = zcu.declPtr(decl_index);
329 const gop = try self.decl_table.getOrPut(gpa, decl_index);330 const gop = try self.decl_table.getOrPut(gpa, decl_index);
330 errdefer _ = self.decl_table.pop();331 errdefer _ = self.decl_table.pop();
...@@ -342,7 +343,7 @@ pub fn updateDecl(self: *C, zcu: *Zcu, decl_index: InternPool.DeclIndex) !void {...@@ -342,7 +343,7 @@ pub fn updateDecl(self: *C, zcu: *Zcu, decl_index: InternPool.DeclIndex) !void {
342 var object: codegen.Object = .{343 var object: codegen.Object = .{
343 .dg = .{344 .dg = .{
344 .gpa = gpa,345 .gpa = gpa,
345 .zcu = zcu,346 .pt = pt,
346 .mod = file_scope.mod,347 .mod = file_scope.mod,
347 .error_msg = null,348 .error_msg = null,
348 .pass = .{ .decl = decl_index },349 .pass = .{ .decl = decl_index },
...@@ -382,16 +383,16 @@ pub fn updateDecl(self: *C, zcu: *Zcu, decl_index: InternPool.DeclIndex) !void {...@@ -382,16 +383,16 @@ pub fn updateDecl(self: *C, zcu: *Zcu, decl_index: InternPool.DeclIndex) !void {
382 gop.value_ptr.fwd_decl = try self.addString(object.dg.fwd_decl.items);383 gop.value_ptr.fwd_decl = try self.addString(object.dg.fwd_decl.items);
383}384}
384385
385pub fn updateDeclLineNumber(self: *C, zcu: *Zcu, decl_index: InternPool.DeclIndex) !void {386pub fn updateDeclLineNumber(self: *C, pt: Zcu.PerThread, decl_index: InternPool.DeclIndex) !void {
386 // The C backend does not have the ability to fix line numbers without re-generating387 // The C backend does not have the ability to fix line numbers without re-generating
387 // the entire Decl.388 // the entire Decl.
388 _ = self;389 _ = self;
389 _ = zcu;390 _ = pt;
390 _ = decl_index;391 _ = decl_index;
391}392}
392393
393pub fn flush(self: *C, arena: Allocator, prog_node: std.Progress.Node) !void {394pub fn flush(self: *C, arena: Allocator, tid: Zcu.PerThread.Id, prog_node: std.Progress.Node) !void {
394 return self.flushModule(arena, prog_node);395 return self.flushModule(arena, tid, prog_node);
395}396}
396397
397fn abiDefines(self: *C, target: std.Target) !std.ArrayList(u8) {398fn abiDefines(self: *C, target: std.Target) !std.ArrayList(u8) {
...@@ -409,7 +410,7 @@ fn abiDefines(self: *C, target: std.Target) !std.ArrayList(u8) {...@@ -409,7 +410,7 @@ fn abiDefines(self: *C, target: std.Target) !std.ArrayList(u8) {
409 return defines;410 return defines;
410}411}
411412
412pub fn flushModule(self: *C, arena: Allocator, prog_node: std.Progress.Node) !void {413pub fn flushModule(self: *C, arena: Allocator, tid: Zcu.PerThread.Id, prog_node: std.Progress.Node) !void {
413 _ = arena; // Has the same lifetime as the call to Compilation.update.414 _ = arena; // Has the same lifetime as the call to Compilation.update.
414415
415 const tracy = trace(@src());416 const tracy = trace(@src());
...@@ -421,11 +422,12 @@ pub fn flushModule(self: *C, arena: Allocator, prog_node: std.Progress.Node) !vo...@@ -421,11 +422,12 @@ pub fn flushModule(self: *C, arena: Allocator, prog_node: std.Progress.Node) !vo
421 const comp = self.base.comp;422 const comp = self.base.comp;
422 const gpa = comp.gpa;423 const gpa = comp.gpa;
423 const zcu = self.base.comp.module.?;424 const zcu = self.base.comp.module.?;
425 const pt: Zcu.PerThread = .{ .zcu = zcu, .tid = tid };
424426
425 {427 {
426 var i: usize = 0;428 var i: usize = 0;
427 while (i < self.anon_decls.count()) : (i += 1) {429 while (i < self.anon_decls.count()) : (i += 1) {
428 try updateAnonDecl(self, zcu, i);430 try updateAnonDecl(self, pt, i);
429 }431 }
430 }432 }
431433
...@@ -463,7 +465,7 @@ pub fn flushModule(self: *C, arena: Allocator, prog_node: std.Progress.Node) !vo...@@ -463,7 +465,7 @@ pub fn flushModule(self: *C, arena: Allocator, prog_node: std.Progress.Node) !vo
463 self.lazy_fwd_decl_buf.clearRetainingCapacity();465 self.lazy_fwd_decl_buf.clearRetainingCapacity();
464 self.lazy_code_buf.clearRetainingCapacity();466 self.lazy_code_buf.clearRetainingCapacity();
465 try f.lazy_ctype_pool.init(gpa);467 try f.lazy_ctype_pool.init(gpa);
466 try self.flushErrDecls(zcu, &f.lazy_ctype_pool);468 try self.flushErrDecls(pt, &f.lazy_ctype_pool);
467469
468 // Unlike other backends, the .c code we are emitting has order-dependent decls.470 // Unlike other backends, the .c code we are emitting has order-dependent decls.
469 // `CType`s, forward decls, and non-functions first.471 // `CType`s, forward decls, and non-functions first.
...@@ -483,7 +485,7 @@ pub fn flushModule(self: *C, arena: Allocator, prog_node: std.Progress.Node) !vo...@@ -483,7 +485,7 @@ pub fn flushModule(self: *C, arena: Allocator, prog_node: std.Progress.Node) !vo
483 }485 }
484486
485 for (self.anon_decls.keys(), self.anon_decls.values()) |value, *decl_block| try self.flushDeclBlock(487 for (self.anon_decls.keys(), self.anon_decls.values()) |value, *decl_block| try self.flushDeclBlock(
486 zcu,488 pt,
487 zcu.root_mod,489 zcu.root_mod,
488 &f,490 &f,
489 decl_block,491 decl_block,
...@@ -497,7 +499,7 @@ pub fn flushModule(self: *C, arena: Allocator, prog_node: std.Progress.Node) !vo...@@ -497,7 +499,7 @@ pub fn flushModule(self: *C, arena: Allocator, prog_node: std.Progress.Node) !vo
497 const extern_name = if (decl.isExtern(zcu)) decl.name.toOptional() else .none;499 const extern_name = if (decl.isExtern(zcu)) decl.name.toOptional() else .none;
498 const mod = zcu.namespacePtr(decl.src_namespace).fileScope(zcu).mod;500 const mod = zcu.namespacePtr(decl.src_namespace).fileScope(zcu).mod;
499 try self.flushDeclBlock(501 try self.flushDeclBlock(
500 zcu,502 pt,
501 mod,503 mod,
502 &f,504 &f,
503 decl_block,505 decl_block,
...@@ -670,7 +672,7 @@ fn flushCTypes(...@@ -670,7 +672,7 @@ fn flushCTypes(
670 }672 }
671}673}
672674
673fn flushErrDecls(self: *C, zcu: *Zcu, ctype_pool: *codegen.CType.Pool) FlushDeclError!void {675fn flushErrDecls(self: *C, pt: Zcu.PerThread, ctype_pool: *codegen.CType.Pool) FlushDeclError!void {
674 const gpa = self.base.comp.gpa;676 const gpa = self.base.comp.gpa;
675677
676 const fwd_decl = &self.lazy_fwd_decl_buf;678 const fwd_decl = &self.lazy_fwd_decl_buf;
...@@ -679,8 +681,8 @@ fn flushErrDecls(self: *C, zcu: *Zcu, ctype_pool: *codegen.CType.Pool) FlushDecl...@@ -679,8 +681,8 @@ fn flushErrDecls(self: *C, zcu: *Zcu, ctype_pool: *codegen.CType.Pool) FlushDecl
679 var object = codegen.Object{681 var object = codegen.Object{
680 .dg = .{682 .dg = .{
681 .gpa = gpa,683 .gpa = gpa,
682 .zcu = zcu,684 .pt = pt,
683 .mod = zcu.root_mod,685 .mod = pt.zcu.root_mod,
684 .error_msg = null,686 .error_msg = null,
685 .pass = .flush,687 .pass = .flush,
686 .is_naked_fn = false,688 .is_naked_fn = false,
...@@ -712,7 +714,7 @@ fn flushErrDecls(self: *C, zcu: *Zcu, ctype_pool: *codegen.CType.Pool) FlushDecl...@@ -712,7 +714,7 @@ fn flushErrDecls(self: *C, zcu: *Zcu, ctype_pool: *codegen.CType.Pool) FlushDecl
712714
713fn flushLazyFn(715fn flushLazyFn(
714 self: *C,716 self: *C,
715 zcu: *Zcu,717 pt: Zcu.PerThread,
716 mod: *Module,718 mod: *Module,
717 ctype_pool: *codegen.CType.Pool,719 ctype_pool: *codegen.CType.Pool,
718 lazy_ctype_pool: *const codegen.CType.Pool,720 lazy_ctype_pool: *const codegen.CType.Pool,
...@@ -726,7 +728,7 @@ fn flushLazyFn(...@@ -726,7 +728,7 @@ fn flushLazyFn(
726 var object = codegen.Object{728 var object = codegen.Object{
727 .dg = .{729 .dg = .{
728 .gpa = gpa,730 .gpa = gpa,
729 .zcu = zcu,731 .pt = pt,
730 .mod = mod,732 .mod = mod,
731 .error_msg = null,733 .error_msg = null,
732 .pass = .flush,734 .pass = .flush,
...@@ -761,7 +763,7 @@ fn flushLazyFn(...@@ -761,7 +763,7 @@ fn flushLazyFn(
761763
762fn flushLazyFns(764fn flushLazyFns(
763 self: *C,765 self: *C,
764 zcu: *Zcu,766 pt: Zcu.PerThread,
765 mod: *Module,767 mod: *Module,
766 f: *Flush,768 f: *Flush,
767 lazy_ctype_pool: *const codegen.CType.Pool,769 lazy_ctype_pool: *const codegen.CType.Pool,
...@@ -775,13 +777,13 @@ fn flushLazyFns(...@@ -775,13 +777,13 @@ fn flushLazyFns(
775 const gop = f.lazy_fns.getOrPutAssumeCapacity(entry.key_ptr.*);777 const gop = f.lazy_fns.getOrPutAssumeCapacity(entry.key_ptr.*);
776 if (gop.found_existing) continue;778 if (gop.found_existing) continue;
777 gop.value_ptr.* = {};779 gop.value_ptr.* = {};
778 try self.flushLazyFn(zcu, mod, &f.lazy_ctype_pool, lazy_ctype_pool, entry);780 try self.flushLazyFn(pt, mod, &f.lazy_ctype_pool, lazy_ctype_pool, entry);
779 }781 }
780}782}
781783
782fn flushDeclBlock(784fn flushDeclBlock(
783 self: *C,785 self: *C,
784 zcu: *Zcu,786 pt: Zcu.PerThread,
785 mod: *Module,787 mod: *Module,
786 f: *Flush,788 f: *Flush,
787 decl_block: *const DeclBlock,789 decl_block: *const DeclBlock,
...@@ -790,7 +792,7 @@ fn flushDeclBlock(...@@ -790,7 +792,7 @@ fn flushDeclBlock(
790 extern_name: InternPool.OptionalNullTerminatedString,792 extern_name: InternPool.OptionalNullTerminatedString,
791) FlushDeclError!void {793) FlushDeclError!void {
792 const gpa = self.base.comp.gpa;794 const gpa = self.base.comp.gpa;
793 try self.flushLazyFns(zcu, mod, f, &decl_block.ctype_pool, decl_block.lazy_fns);795 try self.flushLazyFns(pt, mod, f, &decl_block.ctype_pool, decl_block.lazy_fns);
794 try f.all_buffers.ensureUnusedCapacity(gpa, 1);796 try f.all_buffers.ensureUnusedCapacity(gpa, 1);
795 // avoid emitting extern decls that are already exported797 // avoid emitting extern decls that are already exported
796 if (extern_name.unwrap()) |name| if (export_names.contains(name)) return;798 if (extern_name.unwrap()) |name| if (export_names.contains(name)) return;
...@@ -845,11 +847,12 @@ pub fn flushEmitH(zcu: *Zcu) !void {...@@ -845,11 +847,12 @@ pub fn flushEmitH(zcu: *Zcu) !void {
845847
846pub fn updateExports(848pub fn updateExports(
847 self: *C,849 self: *C,
848 zcu: *Zcu,850 pt: Zcu.PerThread,
849 exported: Zcu.Exported,851 exported: Zcu.Exported,
850 export_indices: []const u32,852 export_indices: []const u32,
851) !void {853) !void {
852 const gpa = self.base.comp.gpa;854 const zcu = pt.zcu;
855 const gpa = zcu.gpa;
853 const mod, const pass: codegen.DeclGen.Pass, const decl_block, const exported_block = switch (exported) {856 const mod, const pass: codegen.DeclGen.Pass, const decl_block, const exported_block = switch (exported) {
854 .decl_index => |decl_index| .{857 .decl_index => |decl_index| .{
855 zcu.namespacePtr(zcu.declPtr(decl_index).src_namespace).fileScope(zcu).mod,858 zcu.namespacePtr(zcu.declPtr(decl_index).src_namespace).fileScope(zcu).mod,
...@@ -869,7 +872,7 @@ pub fn updateExports(...@@ -869,7 +872,7 @@ pub fn updateExports(
869 fwd_decl.clearRetainingCapacity();872 fwd_decl.clearRetainingCapacity();
870 var dg: codegen.DeclGen = .{873 var dg: codegen.DeclGen = .{
871 .gpa = gpa,874 .gpa = gpa,
872 .zcu = zcu,875 .pt = pt,
873 .mod = mod,876 .mod = mod,
874 .error_msg = null,877 .error_msg = null,
875 .pass = pass,878 .pass = pass,
src/link/Coff.zig+58-37
...@@ -1120,16 +1120,17 @@ fn freeAtom(self: *Coff, atom_index: Atom.Index) void {...@@ -1120,16 +1120,17 @@ fn freeAtom(self: *Coff, atom_index: Atom.Index) void {
1120 self.getAtomPtr(atom_index).sym_index = 0;1120 self.getAtomPtr(atom_index).sym_index = 0;
1121}1121}
11221122
1123pub fn updateFunc(self: *Coff, mod: *Module, func_index: InternPool.Index, air: Air, liveness: Liveness) !void {1123pub fn updateFunc(self: *Coff, pt: Zcu.PerThread, func_index: InternPool.Index, air: Air, liveness: Liveness) !void {
1124 if (build_options.skip_non_native and builtin.object_format != .coff) {1124 if (build_options.skip_non_native and builtin.object_format != .coff) {
1125 @panic("Attempted to compile for object format that was disabled by build configuration");1125 @panic("Attempted to compile for object format that was disabled by build configuration");
1126 }1126 }
1127 if (self.llvm_object) |llvm_object| {1127 if (self.llvm_object) |llvm_object| {
1128 return llvm_object.updateFunc(mod, func_index, air, liveness);1128 return llvm_object.updateFunc(pt, func_index, air, liveness);
1129 }1129 }
1130 const tracy = trace(@src());1130 const tracy = trace(@src());
1131 defer tracy.end();1131 defer tracy.end();
11321132
1133 const mod = pt.zcu;
1133 const func = mod.funcInfo(func_index);1134 const func = mod.funcInfo(func_index);
1134 const decl_index = func.owner_decl;1135 const decl_index = func.owner_decl;
1135 const decl = mod.declPtr(decl_index);1136 const decl = mod.declPtr(decl_index);
...@@ -1144,6 +1145,7 @@ pub fn updateFunc(self: *Coff, mod: *Module, func_index: InternPool.Index, air:...@@ -1144,6 +1145,7 @@ pub fn updateFunc(self: *Coff, mod: *Module, func_index: InternPool.Index, air:
11441145
1145 const res = try codegen.generateFunction(1146 const res = try codegen.generateFunction(
1146 &self.base,1147 &self.base,
1148 pt,
1147 decl.navSrcLoc(mod),1149 decl.navSrcLoc(mod),
1148 func_index,1150 func_index,
1149 air,1151 air,
...@@ -1160,26 +1162,26 @@ pub fn updateFunc(self: *Coff, mod: *Module, func_index: InternPool.Index, air:...@@ -1160,26 +1162,26 @@ pub fn updateFunc(self: *Coff, mod: *Module, func_index: InternPool.Index, air:
1160 },1162 },
1161 };1163 };
11621164
1163 try self.updateDeclCode(decl_index, code, .FUNCTION);1165 try self.updateDeclCode(pt, decl_index, code, .FUNCTION);
11641166
1165 // Exports will be updated by `Zcu.processExports` after the update.1167 // Exports will be updated by `Zcu.processExports` after the update.
1166}1168}
11671169
1168pub fn lowerUnnamedConst(self: *Coff, val: Value, decl_index: InternPool.DeclIndex) !u32 {1170pub fn lowerUnnamedConst(self: *Coff, pt: Zcu.PerThread, val: Value, decl_index: InternPool.DeclIndex) !u32 {
1169 const gpa = self.base.comp.gpa;1171 const mod = pt.zcu;
1170 const mod = self.base.comp.module.?;1172 const gpa = mod.gpa;
1171 const decl = mod.declPtr(decl_index);1173 const decl = mod.declPtr(decl_index);
1172 const gop = try self.unnamed_const_atoms.getOrPut(gpa, decl_index);1174 const gop = try self.unnamed_const_atoms.getOrPut(gpa, decl_index);
1173 if (!gop.found_existing) {1175 if (!gop.found_existing) {
1174 gop.value_ptr.* = .{};1176 gop.value_ptr.* = .{};
1175 }1177 }
1176 const unnamed_consts = gop.value_ptr;1178 const unnamed_consts = gop.value_ptr;
1177 const decl_name = try decl.fullyQualifiedName(mod);1179 const decl_name = try decl.fullyQualifiedName(pt);
1178 const index = unnamed_consts.items.len;1180 const index = unnamed_consts.items.len;
1179 const sym_name = try std.fmt.allocPrint(gpa, "__unnamed_{}_{d}", .{ decl_name.fmt(&mod.intern_pool), index });1181 const sym_name = try std.fmt.allocPrint(gpa, "__unnamed_{}_{d}", .{ decl_name.fmt(&mod.intern_pool), index });
1180 defer gpa.free(sym_name);1182 defer gpa.free(sym_name);
1181 const ty = val.typeOf(mod);1183 const ty = val.typeOf(mod);
1182 const atom_index = switch (try self.lowerConst(sym_name, val, ty.abiAlignment(mod), self.rdata_section_index.?, decl.navSrcLoc(mod))) {1184 const atom_index = switch (try self.lowerConst(pt, sym_name, val, ty.abiAlignment(pt), self.rdata_section_index.?, decl.navSrcLoc(mod))) {
1183 .ok => |atom_index| atom_index,1185 .ok => |atom_index| atom_index,
1184 .fail => |em| {1186 .fail => |em| {
1185 decl.analysis = .codegen_failure;1187 decl.analysis = .codegen_failure;
...@@ -1197,7 +1199,15 @@ const LowerConstResult = union(enum) {...@@ -1197,7 +1199,15 @@ const LowerConstResult = union(enum) {
1197 fail: *Module.ErrorMsg,1199 fail: *Module.ErrorMsg,
1198};1200};
11991201
1200fn lowerConst(self: *Coff, name: []const u8, val: Value, required_alignment: InternPool.Alignment, sect_id: u16, src_loc: Module.LazySrcLoc) !LowerConstResult {1202fn lowerConst(
1203 self: *Coff,
1204 pt: Zcu.PerThread,
1205 name: []const u8,
1206 val: Value,
1207 required_alignment: InternPool.Alignment,
1208 sect_id: u16,
1209 src_loc: Module.LazySrcLoc,
1210) !LowerConstResult {
1201 const gpa = self.base.comp.gpa;1211 const gpa = self.base.comp.gpa;
12021212
1203 var code_buffer = std.ArrayList(u8).init(gpa);1213 var code_buffer = std.ArrayList(u8).init(gpa);
...@@ -1208,7 +1218,7 @@ fn lowerConst(self: *Coff, name: []const u8, val: Value, required_alignment: Int...@@ -1208,7 +1218,7 @@ fn lowerConst(self: *Coff, name: []const u8, val: Value, required_alignment: Int
1208 try self.setSymbolName(sym, name);1218 try self.setSymbolName(sym, name);
1209 sym.section_number = @as(coff.SectionNumber, @enumFromInt(sect_id + 1));1219 sym.section_number = @as(coff.SectionNumber, @enumFromInt(sect_id + 1));
12101220
1211 const res = try codegen.generateSymbol(&self.base, src_loc, val, &code_buffer, .none, .{1221 const res = try codegen.generateSymbol(&self.base, pt, src_loc, val, &code_buffer, .none, .{
1212 .parent_atom_index = self.getAtom(atom_index).getSymbolIndex().?,1222 .parent_atom_index = self.getAtom(atom_index).getSymbolIndex().?,
1213 });1223 });
1214 const code = switch (res) {1224 const code = switch (res) {
...@@ -1235,13 +1245,14 @@ fn lowerConst(self: *Coff, name: []const u8, val: Value, required_alignment: Int...@@ -1235,13 +1245,14 @@ fn lowerConst(self: *Coff, name: []const u8, val: Value, required_alignment: Int
12351245
1236pub fn updateDecl(1246pub fn updateDecl(
1237 self: *Coff,1247 self: *Coff,
1238 mod: *Module,1248 pt: Zcu.PerThread,
1239 decl_index: InternPool.DeclIndex,1249 decl_index: InternPool.DeclIndex,
1240) link.File.UpdateDeclError!void {1250) link.File.UpdateDeclError!void {
1251 const mod = pt.zcu;
1241 if (build_options.skip_non_native and builtin.object_format != .coff) {1252 if (build_options.skip_non_native and builtin.object_format != .coff) {
1242 @panic("Attempted to compile for object format that was disabled by build configuration");1253 @panic("Attempted to compile for object format that was disabled by build configuration");
1243 }1254 }
1244 if (self.llvm_object) |llvm_object| return llvm_object.updateDecl(mod, decl_index);1255 if (self.llvm_object) |llvm_object| return llvm_object.updateDecl(pt, decl_index);
1245 const tracy = trace(@src());1256 const tracy = trace(@src());
1246 defer tracy.end();1257 defer tracy.end();
12471258
...@@ -1270,7 +1281,7 @@ pub fn updateDecl(...@@ -1270,7 +1281,7 @@ pub fn updateDecl(
1270 defer code_buffer.deinit();1281 defer code_buffer.deinit();
12711282
1272 const decl_val = if (decl.val.getVariable(mod)) |variable| Value.fromInterned(variable.init) else decl.val;1283 const decl_val = if (decl.val.getVariable(mod)) |variable| Value.fromInterned(variable.init) else decl.val;
1273 const res = try codegen.generateSymbol(&self.base, decl.navSrcLoc(mod), decl_val, &code_buffer, .none, .{1284 const res = try codegen.generateSymbol(&self.base, pt, decl.navSrcLoc(mod), decl_val, &code_buffer, .none, .{
1274 .parent_atom_index = atom.getSymbolIndex().?,1285 .parent_atom_index = atom.getSymbolIndex().?,
1275 });1286 });
1276 const code = switch (res) {1287 const code = switch (res) {
...@@ -1282,19 +1293,20 @@ pub fn updateDecl(...@@ -1282,19 +1293,20 @@ pub fn updateDecl(
1282 },1293 },
1283 };1294 };
12841295
1285 try self.updateDeclCode(decl_index, code, .NULL);1296 try self.updateDeclCode(pt, decl_index, code, .NULL);
12861297
1287 // Exports will be updated by `Zcu.processExports` after the update.1298 // Exports will be updated by `Zcu.processExports` after the update.
1288}1299}
12891300
1290fn updateLazySymbolAtom(1301fn updateLazySymbolAtom(
1291 self: *Coff,1302 self: *Coff,
1303 pt: Zcu.PerThread,
1292 sym: link.File.LazySymbol,1304 sym: link.File.LazySymbol,
1293 atom_index: Atom.Index,1305 atom_index: Atom.Index,
1294 section_index: u16,1306 section_index: u16,
1295) !void {1307) !void {
1296 const gpa = self.base.comp.gpa;1308 const mod = pt.zcu;
1297 const mod = self.base.comp.module.?;1309 const gpa = mod.gpa;
12981310
1299 var required_alignment: InternPool.Alignment = .none;1311 var required_alignment: InternPool.Alignment = .none;
1300 var code_buffer = std.ArrayList(u8).init(gpa);1312 var code_buffer = std.ArrayList(u8).init(gpa);
...@@ -1302,7 +1314,7 @@ fn updateLazySymbolAtom(...@@ -1302,7 +1314,7 @@ fn updateLazySymbolAtom(
13021314
1303 const name = try std.fmt.allocPrint(gpa, "__lazy_{s}_{}", .{1315 const name = try std.fmt.allocPrint(gpa, "__lazy_{s}_{}", .{
1304 @tagName(sym.kind),1316 @tagName(sym.kind),
1305 sym.ty.fmt(mod),1317 sym.ty.fmt(pt),
1306 });1318 });
1307 defer gpa.free(name);1319 defer gpa.free(name);
13081320
...@@ -1312,6 +1324,7 @@ fn updateLazySymbolAtom(...@@ -1312,6 +1324,7 @@ fn updateLazySymbolAtom(
1312 const src = sym.ty.srcLocOrNull(mod) orelse Module.LazySrcLoc.unneeded;1324 const src = sym.ty.srcLocOrNull(mod) orelse Module.LazySrcLoc.unneeded;
1313 const res = try codegen.generateLazySymbol(1325 const res = try codegen.generateLazySymbol(
1314 &self.base,1326 &self.base,
1327 pt,
1315 src,1328 src,
1316 sym,1329 sym,
1317 &required_alignment,1330 &required_alignment,
...@@ -1346,7 +1359,7 @@ fn updateLazySymbolAtom(...@@ -1346,7 +1359,7 @@ fn updateLazySymbolAtom(
1346 try self.writeAtom(atom_index, code);1359 try self.writeAtom(atom_index, code);
1347}1360}
13481361
1349pub fn getOrCreateAtomForLazySymbol(self: *Coff, sym: link.File.LazySymbol) !Atom.Index {1362pub fn getOrCreateAtomForLazySymbol(self: *Coff, pt: Zcu.PerThread, sym: link.File.LazySymbol) !Atom.Index {
1350 const gpa = self.base.comp.gpa;1363 const gpa = self.base.comp.gpa;
1351 const mod = self.base.comp.module.?;1364 const mod = self.base.comp.module.?;
1352 const gop = try self.lazy_syms.getOrPut(gpa, sym.getDecl(mod));1365 const gop = try self.lazy_syms.getOrPut(gpa, sym.getDecl(mod));
...@@ -1364,7 +1377,7 @@ pub fn getOrCreateAtomForLazySymbol(self: *Coff, sym: link.File.LazySymbol) !Ato...@@ -1364,7 +1377,7 @@ pub fn getOrCreateAtomForLazySymbol(self: *Coff, sym: link.File.LazySymbol) !Ato
1364 metadata.state.* = .pending_flush;1377 metadata.state.* = .pending_flush;
1365 const atom = metadata.atom.*;1378 const atom = metadata.atom.*;
1366 // anyerror needs to be deferred until flushModule1379 // anyerror needs to be deferred until flushModule
1367 if (sym.getDecl(mod) != .none) try self.updateLazySymbolAtom(sym, atom, switch (sym.kind) {1380 if (sym.getDecl(mod) != .none) try self.updateLazySymbolAtom(pt, sym, atom, switch (sym.kind) {
1368 .code => self.text_section_index.?,1381 .code => self.text_section_index.?,
1369 .const_data => self.rdata_section_index.?,1382 .const_data => self.rdata_section_index.?,
1370 });1383 });
...@@ -1410,14 +1423,14 @@ fn getDeclOutputSection(self: *Coff, decl_index: InternPool.DeclIndex) u16 {...@@ -1410,14 +1423,14 @@ fn getDeclOutputSection(self: *Coff, decl_index: InternPool.DeclIndex) u16 {
1410 return index;1423 return index;
1411}1424}
14121425
1413fn updateDeclCode(self: *Coff, decl_index: InternPool.DeclIndex, code: []u8, complex_type: coff.ComplexType) !void {1426fn updateDeclCode(self: *Coff, pt: Zcu.PerThread, decl_index: InternPool.DeclIndex, code: []u8, complex_type: coff.ComplexType) !void {
1414 const mod = self.base.comp.module.?;1427 const mod = pt.zcu;
1415 const decl = mod.declPtr(decl_index);1428 const decl = mod.declPtr(decl_index);
14161429
1417 const decl_name = try decl.fullyQualifiedName(mod);1430 const decl_name = try decl.fullyQualifiedName(pt);
14181431
1419 log.debug("updateDeclCode {}{*}", .{ decl_name.fmt(&mod.intern_pool), decl });1432 log.debug("updateDeclCode {}{*}", .{ decl_name.fmt(&mod.intern_pool), decl });
1420 const required_alignment: u32 = @intCast(decl.getAlignment(mod).toByteUnits() orelse 0);1433 const required_alignment: u32 = @intCast(decl.getAlignment(pt).toByteUnits() orelse 0);
14211434
1422 const decl_metadata = self.decls.get(decl_index).?;1435 const decl_metadata = self.decls.get(decl_index).?;
1423 const atom_index = decl_metadata.atom;1436 const atom_index = decl_metadata.atom;
...@@ -1496,7 +1509,7 @@ pub fn freeDecl(self: *Coff, decl_index: InternPool.DeclIndex) void {...@@ -1496,7 +1509,7 @@ pub fn freeDecl(self: *Coff, decl_index: InternPool.DeclIndex) void {
14961509
1497pub fn updateExports(1510pub fn updateExports(
1498 self: *Coff,1511 self: *Coff,
1499 mod: *Module,1512 pt: Zcu.PerThread,
1500 exported: Module.Exported,1513 exported: Module.Exported,
1501 export_indices: []const u32,1514 export_indices: []const u32,
1502) link.File.UpdateExportsError!void {1515) link.File.UpdateExportsError!void {
...@@ -1504,6 +1517,7 @@ pub fn updateExports(...@@ -1504,6 +1517,7 @@ pub fn updateExports(
1504 @panic("Attempted to compile for object format that was disabled by build configuration");1517 @panic("Attempted to compile for object format that was disabled by build configuration");
1505 }1518 }
15061519
1520 const mod = pt.zcu;
1507 const ip = &mod.intern_pool;1521 const ip = &mod.intern_pool;
1508 const comp = self.base.comp;1522 const comp = self.base.comp;
1509 const target = comp.root_mod.resolved_target.result;1523 const target = comp.root_mod.resolved_target.result;
...@@ -1542,7 +1556,7 @@ pub fn updateExports(...@@ -1542,7 +1556,7 @@ pub fn updateExports(
1542 }1556 }
1543 }1557 }
15441558
1545 if (self.llvm_object) |llvm_object| return llvm_object.updateExports(mod, exported, export_indices);1559 if (self.llvm_object) |llvm_object| return llvm_object.updateExports(pt, exported, export_indices);
15461560
1547 const gpa = comp.gpa;1561 const gpa = comp.gpa;
15481562
...@@ -1553,7 +1567,7 @@ pub fn updateExports(...@@ -1553,7 +1567,7 @@ pub fn updateExports(
1553 },1567 },
1554 .value => |value| self.anon_decls.getPtr(value) orelse blk: {1568 .value => |value| self.anon_decls.getPtr(value) orelse blk: {
1555 const first_exp = mod.all_exports.items[export_indices[0]];1569 const first_exp = mod.all_exports.items[export_indices[0]];
1556 const res = try self.lowerAnonDecl(value, .none, first_exp.src);1570 const res = try self.lowerAnonDecl(pt, value, .none, first_exp.src);
1557 switch (res) {1571 switch (res) {
1558 .ok => {},1572 .ok => {},
1559 .fail => |em| {1573 .fail => |em| {
...@@ -1696,19 +1710,19 @@ fn resolveGlobalSymbol(self: *Coff, current: SymbolWithLoc) !void {...@@ -1696,19 +1710,19 @@ fn resolveGlobalSymbol(self: *Coff, current: SymbolWithLoc) !void {
1696 gop.value_ptr.* = current;1710 gop.value_ptr.* = current;
1697}1711}
16981712
1699pub fn flush(self: *Coff, arena: Allocator, prog_node: std.Progress.Node) link.File.FlushError!void {1713pub fn flush(self: *Coff, arena: Allocator, tid: Zcu.PerThread.Id, prog_node: std.Progress.Node) link.File.FlushError!void {
1700 const comp = self.base.comp;1714 const comp = self.base.comp;
1701 const use_lld = build_options.have_llvm and comp.config.use_lld;1715 const use_lld = build_options.have_llvm and comp.config.use_lld;
1702 if (use_lld) {1716 if (use_lld) {
1703 return lld.linkWithLLD(self, arena, prog_node);1717 return lld.linkWithLLD(self, arena, tid, prog_node);
1704 }1718 }
1705 switch (comp.config.output_mode) {1719 switch (comp.config.output_mode) {
1706 .Exe, .Obj => return self.flushModule(arena, prog_node),1720 .Exe, .Obj => return self.flushModule(arena, tid, prog_node),
1707 .Lib => return error.TODOImplementWritingLibFiles,1721 .Lib => return error.TODOImplementWritingLibFiles,
1708 }1722 }
1709}1723}
17101724
1711pub fn flushModule(self: *Coff, arena: Allocator, prog_node: std.Progress.Node) link.File.FlushError!void {1725pub fn flushModule(self: *Coff, arena: Allocator, tid: Zcu.PerThread.Id, prog_node: std.Progress.Node) link.File.FlushError!void {
1712 const tracy = trace(@src());1726 const tracy = trace(@src());
1713 defer tracy.end();1727 defer tracy.end();
17141728
...@@ -1723,13 +1737,17 @@ pub fn flushModule(self: *Coff, arena: Allocator, prog_node: std.Progress.Node)...@@ -1723,13 +1737,17 @@ pub fn flushModule(self: *Coff, arena: Allocator, prog_node: std.Progress.Node)
1723 const sub_prog_node = prog_node.start("COFF Flush", 0);1737 const sub_prog_node = prog_node.start("COFF Flush", 0);
1724 defer sub_prog_node.end();1738 defer sub_prog_node.end();
17251739
1726 const module = comp.module orelse return error.LinkingWithoutZigSourceUnimplemented;1740 const pt: Zcu.PerThread = .{
1741 .zcu = comp.module orelse return error.LinkingWithoutZigSourceUnimplemented,
1742 .tid = tid,
1743 };
17271744
1728 if (self.lazy_syms.getPtr(.none)) |metadata| {1745 if (self.lazy_syms.getPtr(.none)) |metadata| {
1729 // Most lazy symbols can be updated on first use, but1746 // Most lazy symbols can be updated on first use, but
1730 // anyerror needs to wait for everything to be flushed.1747 // anyerror needs to wait for everything to be flushed.
1731 if (metadata.text_state != .unused) self.updateLazySymbolAtom(1748 if (metadata.text_state != .unused) self.updateLazySymbolAtom(
1732 link.File.LazySymbol.initDecl(.code, null, module),1749 pt,
1750 link.File.LazySymbol.initDecl(.code, null, pt.zcu),
1733 metadata.text_atom,1751 metadata.text_atom,
1734 self.text_section_index.?,1752 self.text_section_index.?,
1735 ) catch |err| return switch (err) {1753 ) catch |err| return switch (err) {
...@@ -1737,7 +1755,8 @@ pub fn flushModule(self: *Coff, arena: Allocator, prog_node: std.Progress.Node)...@@ -1737,7 +1755,8 @@ pub fn flushModule(self: *Coff, arena: Allocator, prog_node: std.Progress.Node)
1737 else => |e| e,1755 else => |e| e,
1738 };1756 };
1739 if (metadata.rdata_state != .unused) self.updateLazySymbolAtom(1757 if (metadata.rdata_state != .unused) self.updateLazySymbolAtom(
1740 link.File.LazySymbol.initDecl(.const_data, null, module),1758 pt,
1759 link.File.LazySymbol.initDecl(.const_data, null, pt.zcu),
1741 metadata.rdata_atom,1760 metadata.rdata_atom,
1742 self.rdata_section_index.?,1761 self.rdata_section_index.?,
1743 ) catch |err| return switch (err) {1762 ) catch |err| return switch (err) {
...@@ -1836,7 +1855,7 @@ pub fn flushModule(self: *Coff, arena: Allocator, prog_node: std.Progress.Node)...@@ -1836,7 +1855,7 @@ pub fn flushModule(self: *Coff, arena: Allocator, prog_node: std.Progress.Node)
1836 assert(!self.imports_count_dirty);1855 assert(!self.imports_count_dirty);
1837}1856}
18381857
1839pub fn getDeclVAddr(self: *Coff, decl_index: InternPool.DeclIndex, reloc_info: link.File.RelocInfo) !u64 {1858pub fn getDeclVAddr(self: *Coff, _: Zcu.PerThread, decl_index: InternPool.DeclIndex, reloc_info: link.File.RelocInfo) !u64 {
1840 assert(self.llvm_object == null);1859 assert(self.llvm_object == null);
18411860
1842 const this_atom_index = try self.getOrCreateAtomForDecl(decl_index);1861 const this_atom_index = try self.getOrCreateAtomForDecl(decl_index);
...@@ -1858,6 +1877,7 @@ pub fn getDeclVAddr(self: *Coff, decl_index: InternPool.DeclIndex, reloc_info: l...@@ -1858,6 +1877,7 @@ pub fn getDeclVAddr(self: *Coff, decl_index: InternPool.DeclIndex, reloc_info: l
18581877
1859pub fn lowerAnonDecl(1878pub fn lowerAnonDecl(
1860 self: *Coff,1879 self: *Coff,
1880 pt: Zcu.PerThread,
1861 decl_val: InternPool.Index,1881 decl_val: InternPool.Index,
1862 explicit_alignment: InternPool.Alignment,1882 explicit_alignment: InternPool.Alignment,
1863 src_loc: Module.LazySrcLoc,1883 src_loc: Module.LazySrcLoc,
...@@ -1866,7 +1886,7 @@ pub fn lowerAnonDecl(...@@ -1866,7 +1886,7 @@ pub fn lowerAnonDecl(
1866 const mod = self.base.comp.module.?;1886 const mod = self.base.comp.module.?;
1867 const ty = Type.fromInterned(mod.intern_pool.typeOf(decl_val));1887 const ty = Type.fromInterned(mod.intern_pool.typeOf(decl_val));
1868 const decl_alignment = switch (explicit_alignment) {1888 const decl_alignment = switch (explicit_alignment) {
1869 .none => ty.abiAlignment(mod),1889 .none => ty.abiAlignment(pt),
1870 else => explicit_alignment,1890 else => explicit_alignment,
1871 };1891 };
1872 if (self.anon_decls.get(decl_val)) |metadata| {1892 if (self.anon_decls.get(decl_val)) |metadata| {
...@@ -1881,6 +1901,7 @@ pub fn lowerAnonDecl(...@@ -1881,6 +1901,7 @@ pub fn lowerAnonDecl(
1881 @intFromEnum(decl_val),1901 @intFromEnum(decl_val),
1882 }) catch unreachable;1902 }) catch unreachable;
1883 const res = self.lowerConst(1903 const res = self.lowerConst(
1904 pt,
1884 name,1905 name,
1885 val,1906 val,
1886 decl_alignment,1907 decl_alignment,
...@@ -1951,9 +1972,9 @@ pub fn getGlobalSymbol(self: *Coff, name: []const u8, lib_name_name: ?[]const u8...@@ -1951,9 +1972,9 @@ pub fn getGlobalSymbol(self: *Coff, name: []const u8, lib_name_name: ?[]const u8
1951 return global_index;1972 return global_index;
1952}1973}
19531974
1954pub fn updateDeclLineNumber(self: *Coff, module: *Module, decl_index: InternPool.DeclIndex) !void {1975pub fn updateDeclLineNumber(self: *Coff, pt: Zcu.PerThread, decl_index: InternPool.DeclIndex) !void {
1955 _ = self;1976 _ = self;
1956 _ = module;1977 _ = pt;
1957 _ = decl_index;1978 _ = decl_index;
1958 log.debug("TODO implement updateDeclLineNumber", .{});1979 log.debug("TODO implement updateDeclLineNumber", .{});
1959}1980}
src/link/Coff/lld.zig+3-2
...@@ -15,8 +15,9 @@ const Allocator = mem.Allocator;...@@ -15,8 +15,9 @@ const Allocator = mem.Allocator;
1515
16const Coff = @import("../Coff.zig");16const Coff = @import("../Coff.zig");
17const Compilation = @import("../../Compilation.zig");17const Compilation = @import("../../Compilation.zig");
18const Zcu = @import("../../Zcu.zig");
1819
19pub fn linkWithLLD(self: *Coff, arena: Allocator, prog_node: std.Progress.Node) !void {20pub fn linkWithLLD(self: *Coff, arena: Allocator, tid: Zcu.PerThread.Id, prog_node: std.Progress.Node) !void {
20 const tracy = trace(@src());21 const tracy = trace(@src());
21 defer tracy.end();22 defer tracy.end();
2223
...@@ -29,7 +30,7 @@ pub fn linkWithLLD(self: *Coff, arena: Allocator, prog_node: std.Progress.Node)...@@ -29,7 +30,7 @@ pub fn linkWithLLD(self: *Coff, arena: Allocator, prog_node: std.Progress.Node)
29 // If there is no Zig code to compile, then we should skip flushing the output file because it30 // If there is no Zig code to compile, then we should skip flushing the output file because it
30 // will not be part of the linker line anyway.31 // will not be part of the linker line anyway.
31 const module_obj_path: ?[]const u8 = if (comp.module != null) blk: {32 const module_obj_path: ?[]const u8 = if (comp.module != null) blk: {
32 try self.flushModule(arena, prog_node);33 try self.flushModule(arena, tid, prog_node);
3334
34 if (fs.path.dirname(full_out_path)) |dirname| {35 if (fs.path.dirname(full_out_path)) |dirname| {
35 break :blk try fs.path.join(arena, &.{ dirname, self.base.zcu_object_sub_path.? });36 break :blk try fs.path.join(arena, &.{ dirname, self.base.zcu_object_sub_path.? });
src/link/Dwarf.zig+112-110
...@@ -31,7 +31,7 @@ strtab: StringTable = .{},...@@ -31,7 +31,7 @@ strtab: StringTable = .{},
31/// They will end up in the DWARF debug_line header as two lists:31/// They will end up in the DWARF debug_line header as two lists:
32/// * []include_directory32/// * []include_directory
33/// * []file_names33/// * []file_names
34di_files: std.AutoArrayHashMapUnmanaged(*const Module.File, void) = .{},34di_files: std.AutoArrayHashMapUnmanaged(*const Zcu.File, void) = .{},
3535
36global_abbrev_relocs: std.ArrayListUnmanaged(AbbrevRelocation) = .{},36global_abbrev_relocs: std.ArrayListUnmanaged(AbbrevRelocation) = .{},
3737
...@@ -67,7 +67,7 @@ const DbgLineHeader = struct {...@@ -67,7 +67,7 @@ const DbgLineHeader = struct {
67/// Decl's inner Atom is assigned an offset within the DWARF section.67/// Decl's inner Atom is assigned an offset within the DWARF section.
68pub const DeclState = struct {68pub const DeclState = struct {
69 dwarf: *Dwarf,69 dwarf: *Dwarf,
70 mod: *Module,70 pt: Zcu.PerThread,
71 di_atom_decls: *const AtomTable,71 di_atom_decls: *const AtomTable,
72 dbg_line_func: InternPool.Index,72 dbg_line_func: InternPool.Index,
73 dbg_line: std.ArrayList(u8),73 dbg_line: std.ArrayList(u8),
...@@ -113,7 +113,7 @@ pub const DeclState = struct {...@@ -113,7 +113,7 @@ pub const DeclState = struct {
113 .type = ty,113 .type = ty,
114 .offset = undefined,114 .offset = undefined,
115 });115 });
116 log.debug("%{d}: {}", .{ sym_index, ty.fmt(self.mod) });116 log.debug("%{d}: {}", .{ sym_index, ty.fmt(self.pt) });
117 try self.abbrev_resolver.putNoClobber(gpa, ty.toIntern(), sym_index);117 try self.abbrev_resolver.putNoClobber(gpa, ty.toIntern(), sym_index);
118 break :blk sym_index;118 break :blk sym_index;
119 };119 };
...@@ -128,16 +128,17 @@ pub const DeclState = struct {...@@ -128,16 +128,17 @@ pub const DeclState = struct {
128128
129 fn addDbgInfoType(129 fn addDbgInfoType(
130 self: *DeclState,130 self: *DeclState,
131 mod: *Module,131 pt: Zcu.PerThread,
132 atom_index: Atom.Index,132 atom_index: Atom.Index,
133 ty: Type,133 ty: Type,
134 ) error{OutOfMemory}!void {134 ) error{OutOfMemory}!void {
135 const zcu = pt.zcu;
135 const dbg_info_buffer = &self.dbg_info;136 const dbg_info_buffer = &self.dbg_info;
136 const target = mod.getTarget();137 const target = zcu.getTarget();
137 const target_endian = target.cpu.arch.endian();138 const target_endian = target.cpu.arch.endian();
138 const ip = &mod.intern_pool;139 const ip = &zcu.intern_pool;
139140
140 switch (ty.zigTypeTag(mod)) {141 switch (ty.zigTypeTag(zcu)) {
141 .NoReturn => unreachable,142 .NoReturn => unreachable,
142 .Void => {143 .Void => {
143 try dbg_info_buffer.append(@intFromEnum(AbbrevCode.zero_bit_type));144 try dbg_info_buffer.append(@intFromEnum(AbbrevCode.zero_bit_type));
...@@ -148,12 +149,12 @@ pub const DeclState = struct {...@@ -148,12 +149,12 @@ pub const DeclState = struct {
148 // DW.AT.encoding, DW.FORM.data1149 // DW.AT.encoding, DW.FORM.data1
149 dbg_info_buffer.appendAssumeCapacity(DW.ATE.boolean);150 dbg_info_buffer.appendAssumeCapacity(DW.ATE.boolean);
150 // DW.AT.byte_size, DW.FORM.udata151 // DW.AT.byte_size, DW.FORM.udata
151 try leb128.writeUleb128(dbg_info_buffer.writer(), ty.abiSize(mod));152 try leb128.writeUleb128(dbg_info_buffer.writer(), ty.abiSize(pt));
152 // DW.AT.name, DW.FORM.string153 // DW.AT.name, DW.FORM.string
153 try dbg_info_buffer.writer().print("{}\x00", .{ty.fmt(mod)});154 try dbg_info_buffer.writer().print("{}\x00", .{ty.fmt(pt)});
154 },155 },
155 .Int => {156 .Int => {
156 const info = ty.intInfo(mod);157 const info = ty.intInfo(zcu);
157 try dbg_info_buffer.ensureUnusedCapacity(12);158 try dbg_info_buffer.ensureUnusedCapacity(12);
158 dbg_info_buffer.appendAssumeCapacity(@intFromEnum(AbbrevCode.base_type));159 dbg_info_buffer.appendAssumeCapacity(@intFromEnum(AbbrevCode.base_type));
159 // DW.AT.encoding, DW.FORM.data1160 // DW.AT.encoding, DW.FORM.data1
...@@ -162,30 +163,30 @@ pub const DeclState = struct {...@@ -162,30 +163,30 @@ pub const DeclState = struct {
162 .unsigned => DW.ATE.unsigned,163 .unsigned => DW.ATE.unsigned,
163 });164 });
164 // DW.AT.byte_size, DW.FORM.udata165 // DW.AT.byte_size, DW.FORM.udata
165 try leb128.writeUleb128(dbg_info_buffer.writer(), ty.abiSize(mod));166 try leb128.writeUleb128(dbg_info_buffer.writer(), ty.abiSize(pt));
166 // DW.AT.name, DW.FORM.string167 // DW.AT.name, DW.FORM.string
167 try dbg_info_buffer.writer().print("{}\x00", .{ty.fmt(mod)});168 try dbg_info_buffer.writer().print("{}\x00", .{ty.fmt(pt)});
168 },169 },
169 .Optional => {170 .Optional => {
170 if (ty.isPtrLikeOptional(mod)) {171 if (ty.isPtrLikeOptional(zcu)) {
171 try dbg_info_buffer.ensureUnusedCapacity(12);172 try dbg_info_buffer.ensureUnusedCapacity(12);
172 dbg_info_buffer.appendAssumeCapacity(@intFromEnum(AbbrevCode.base_type));173 dbg_info_buffer.appendAssumeCapacity(@intFromEnum(AbbrevCode.base_type));
173 // DW.AT.encoding, DW.FORM.data1174 // DW.AT.encoding, DW.FORM.data1
174 dbg_info_buffer.appendAssumeCapacity(DW.ATE.address);175 dbg_info_buffer.appendAssumeCapacity(DW.ATE.address);
175 // DW.AT.byte_size, DW.FORM.udata176 // DW.AT.byte_size, DW.FORM.udata
176 try leb128.writeUleb128(dbg_info_buffer.writer(), ty.abiSize(mod));177 try leb128.writeUleb128(dbg_info_buffer.writer(), ty.abiSize(pt));
177 // DW.AT.name, DW.FORM.string178 // DW.AT.name, DW.FORM.string
178 try dbg_info_buffer.writer().print("{}\x00", .{ty.fmt(mod)});179 try dbg_info_buffer.writer().print("{}\x00", .{ty.fmt(pt)});
179 } else {180 } else {
180 // Non-pointer optionals are structs: struct { .maybe = *, .val = * }181 // Non-pointer optionals are structs: struct { .maybe = *, .val = * }
181 const payload_ty = ty.optionalChild(mod);182 const payload_ty = ty.optionalChild(zcu);
182 // DW.AT.structure_type183 // DW.AT.structure_type
183 try dbg_info_buffer.append(@intFromEnum(AbbrevCode.struct_type));184 try dbg_info_buffer.append(@intFromEnum(AbbrevCode.struct_type));
184 // DW.AT.byte_size, DW.FORM.udata185 // DW.AT.byte_size, DW.FORM.udata
185 const abi_size = ty.abiSize(mod);186 const abi_size = ty.abiSize(pt);
186 try leb128.writeUleb128(dbg_info_buffer.writer(), abi_size);187 try leb128.writeUleb128(dbg_info_buffer.writer(), abi_size);
187 // DW.AT.name, DW.FORM.string188 // DW.AT.name, DW.FORM.string
188 try dbg_info_buffer.writer().print("{}\x00", .{ty.fmt(mod)});189 try dbg_info_buffer.writer().print("{}\x00", .{ty.fmt(pt)});
189 // DW.AT.member190 // DW.AT.member
190 try dbg_info_buffer.ensureUnusedCapacity(21);191 try dbg_info_buffer.ensureUnusedCapacity(21);
191 dbg_info_buffer.appendAssumeCapacity(@intFromEnum(AbbrevCode.struct_member));192 dbg_info_buffer.appendAssumeCapacity(@intFromEnum(AbbrevCode.struct_member));
...@@ -208,14 +209,14 @@ pub const DeclState = struct {...@@ -208,14 +209,14 @@ pub const DeclState = struct {
208 dbg_info_buffer.appendNTimesAssumeCapacity(0, 4);209 dbg_info_buffer.appendNTimesAssumeCapacity(0, 4);
209 try self.addTypeRelocGlobal(atom_index, payload_ty, @intCast(index));210 try self.addTypeRelocGlobal(atom_index, payload_ty, @intCast(index));
210 // DW.AT.data_member_location, DW.FORM.udata211 // DW.AT.data_member_location, DW.FORM.udata
211 const offset = abi_size - payload_ty.abiSize(mod);212 const offset = abi_size - payload_ty.abiSize(pt);
212 try leb128.writeUleb128(dbg_info_buffer.writer(), offset);213 try leb128.writeUleb128(dbg_info_buffer.writer(), offset);
213 // DW.AT.structure_type delimit children214 // DW.AT.structure_type delimit children
214 try dbg_info_buffer.append(0);215 try dbg_info_buffer.append(0);
215 }216 }
216 },217 },
217 .Pointer => {218 .Pointer => {
218 if (ty.isSlice(mod)) {219 if (ty.isSlice(zcu)) {
219 // Slices are structs: struct { .ptr = *, .len = N }220 // Slices are structs: struct { .ptr = *, .len = N }
220 const ptr_bits = target.ptrBitWidth();221 const ptr_bits = target.ptrBitWidth();
221 const ptr_bytes: u8 = @intCast(@divExact(ptr_bits, 8));222 const ptr_bytes: u8 = @intCast(@divExact(ptr_bits, 8));
...@@ -223,9 +224,9 @@ pub const DeclState = struct {...@@ -223,9 +224,9 @@ pub const DeclState = struct {
223 try dbg_info_buffer.ensureUnusedCapacity(2);224 try dbg_info_buffer.ensureUnusedCapacity(2);
224 dbg_info_buffer.appendAssumeCapacity(@intFromEnum(AbbrevCode.struct_type));225 dbg_info_buffer.appendAssumeCapacity(@intFromEnum(AbbrevCode.struct_type));
225 // DW.AT.byte_size, DW.FORM.udata226 // DW.AT.byte_size, DW.FORM.udata
226 try leb128.writeUleb128(dbg_info_buffer.writer(), ty.abiSize(mod));227 try leb128.writeUleb128(dbg_info_buffer.writer(), ty.abiSize(pt));
227 // DW.AT.name, DW.FORM.string228 // DW.AT.name, DW.FORM.string
228 try dbg_info_buffer.writer().print("{}\x00", .{ty.fmt(mod)});229 try dbg_info_buffer.writer().print("{}\x00", .{ty.fmt(pt)});
229 // DW.AT.member230 // DW.AT.member
230 try dbg_info_buffer.ensureUnusedCapacity(21);231 try dbg_info_buffer.ensureUnusedCapacity(21);
231 dbg_info_buffer.appendAssumeCapacity(@intFromEnum(AbbrevCode.struct_member));232 dbg_info_buffer.appendAssumeCapacity(@intFromEnum(AbbrevCode.struct_member));
...@@ -235,7 +236,7 @@ pub const DeclState = struct {...@@ -235,7 +236,7 @@ pub const DeclState = struct {
235 // DW.AT.type, DW.FORM.ref4236 // DW.AT.type, DW.FORM.ref4
236 var index = dbg_info_buffer.items.len;237 var index = dbg_info_buffer.items.len;
237 dbg_info_buffer.appendNTimesAssumeCapacity(0, 4);238 dbg_info_buffer.appendNTimesAssumeCapacity(0, 4);
238 const ptr_ty = ty.slicePtrFieldType(mod);239 const ptr_ty = ty.slicePtrFieldType(zcu);
239 try self.addTypeRelocGlobal(atom_index, ptr_ty, @intCast(index));240 try self.addTypeRelocGlobal(atom_index, ptr_ty, @intCast(index));
240 // DW.AT.data_member_location, DW.FORM.udata241 // DW.AT.data_member_location, DW.FORM.udata
241 dbg_info_buffer.appendAssumeCapacity(0);242 dbg_info_buffer.appendAssumeCapacity(0);
...@@ -258,19 +259,19 @@ pub const DeclState = struct {...@@ -258,19 +259,19 @@ pub const DeclState = struct {
258 // DW.AT.type, DW.FORM.ref4259 // DW.AT.type, DW.FORM.ref4
259 const index = dbg_info_buffer.items.len;260 const index = dbg_info_buffer.items.len;
260 dbg_info_buffer.appendNTimesAssumeCapacity(0, 4);261 dbg_info_buffer.appendNTimesAssumeCapacity(0, 4);
261 try self.addTypeRelocGlobal(atom_index, ty.childType(mod), @intCast(index));262 try self.addTypeRelocGlobal(atom_index, ty.childType(zcu), @intCast(index));
262 }263 }
263 },264 },
264 .Array => {265 .Array => {
265 // DW.AT.array_type266 // DW.AT.array_type
266 try dbg_info_buffer.append(@intFromEnum(AbbrevCode.array_type));267 try dbg_info_buffer.append(@intFromEnum(AbbrevCode.array_type));
267 // DW.AT.name, DW.FORM.string268 // DW.AT.name, DW.FORM.string
268 try dbg_info_buffer.writer().print("{}\x00", .{ty.fmt(mod)});269 try dbg_info_buffer.writer().print("{}\x00", .{ty.fmt(pt)});
269 // DW.AT.type, DW.FORM.ref4270 // DW.AT.type, DW.FORM.ref4
270 var index = dbg_info_buffer.items.len;271 var index = dbg_info_buffer.items.len;
271 try dbg_info_buffer.ensureUnusedCapacity(9);272 try dbg_info_buffer.ensureUnusedCapacity(9);
272 dbg_info_buffer.appendNTimesAssumeCapacity(0, 4);273 dbg_info_buffer.appendNTimesAssumeCapacity(0, 4);
273 try self.addTypeRelocGlobal(atom_index, ty.childType(mod), @intCast(index));274 try self.addTypeRelocGlobal(atom_index, ty.childType(zcu), @intCast(index));
274 // DW.AT.subrange_type275 // DW.AT.subrange_type
275 dbg_info_buffer.appendAssumeCapacity(@intFromEnum(AbbrevCode.array_dim));276 dbg_info_buffer.appendAssumeCapacity(@intFromEnum(AbbrevCode.array_dim));
276 // DW.AT.type, DW.FORM.ref4277 // DW.AT.type, DW.FORM.ref4
...@@ -278,7 +279,7 @@ pub const DeclState = struct {...@@ -278,7 +279,7 @@ pub const DeclState = struct {
278 dbg_info_buffer.appendNTimesAssumeCapacity(0, 4);279 dbg_info_buffer.appendNTimesAssumeCapacity(0, 4);
279 try self.addTypeRelocGlobal(atom_index, Type.usize, @intCast(index));280 try self.addTypeRelocGlobal(atom_index, Type.usize, @intCast(index));
280 // DW.AT.count, DW.FORM.udata281 // DW.AT.count, DW.FORM.udata
281 const len = ty.arrayLenIncludingSentinel(mod);282 const len = ty.arrayLenIncludingSentinel(pt.zcu);
282 try leb128.writeUleb128(dbg_info_buffer.writer(), len);283 try leb128.writeUleb128(dbg_info_buffer.writer(), len);
283 // DW.AT.array_type delimit children284 // DW.AT.array_type delimit children
284 try dbg_info_buffer.append(0);285 try dbg_info_buffer.append(0);
...@@ -287,13 +288,13 @@ pub const DeclState = struct {...@@ -287,13 +288,13 @@ pub const DeclState = struct {
287 // DW.AT.structure_type288 // DW.AT.structure_type
288 try dbg_info_buffer.append(@intFromEnum(AbbrevCode.struct_type));289 try dbg_info_buffer.append(@intFromEnum(AbbrevCode.struct_type));
289 // DW.AT.byte_size, DW.FORM.udata290 // DW.AT.byte_size, DW.FORM.udata
290 try leb128.writeUleb128(dbg_info_buffer.writer(), ty.abiSize(mod));291 try leb128.writeUleb128(dbg_info_buffer.writer(), ty.abiSize(pt));
291292
292 blk: {293 blk: {
293 switch (ip.indexToKey(ty.ip_index)) {294 switch (ip.indexToKey(ty.ip_index)) {
294 .anon_struct_type => |fields| {295 .anon_struct_type => |fields| {
295 // DW.AT.name, DW.FORM.string296 // DW.AT.name, DW.FORM.string
296 try dbg_info_buffer.writer().print("{}\x00", .{ty.fmt(mod)});297 try dbg_info_buffer.writer().print("{}\x00", .{ty.fmt(pt)});
297298
298 for (fields.types.get(ip), 0..) |field_ty, field_index| {299 for (fields.types.get(ip), 0..) |field_ty, field_index| {
299 // DW.AT.member300 // DW.AT.member
...@@ -305,14 +306,14 @@ pub const DeclState = struct {...@@ -305,14 +306,14 @@ pub const DeclState = struct {
305 try dbg_info_buffer.appendNTimes(0, 4);306 try dbg_info_buffer.appendNTimes(0, 4);
306 try self.addTypeRelocGlobal(atom_index, Type.fromInterned(field_ty), @intCast(index));307 try self.addTypeRelocGlobal(atom_index, Type.fromInterned(field_ty), @intCast(index));
307 // DW.AT.data_member_location, DW.FORM.udata308 // DW.AT.data_member_location, DW.FORM.udata
308 const field_off = ty.structFieldOffset(field_index, mod);309 const field_off = ty.structFieldOffset(field_index, pt);
309 try leb128.writeUleb128(dbg_info_buffer.writer(), field_off);310 try leb128.writeUleb128(dbg_info_buffer.writer(), field_off);
310 }311 }
311 },312 },
312 .struct_type => {313 .struct_type => {
313 const struct_type = ip.loadStructType(ty.toIntern());314 const struct_type = ip.loadStructType(ty.toIntern());
314 // DW.AT.name, DW.FORM.string315 // DW.AT.name, DW.FORM.string
315 try ty.print(dbg_info_buffer.writer(), mod);316 try ty.print(dbg_info_buffer.writer(), pt);
316 try dbg_info_buffer.append(0);317 try dbg_info_buffer.append(0);
317318
318 if (struct_type.layout == .@"packed") {319 if (struct_type.layout == .@"packed") {
...@@ -322,7 +323,7 @@ pub const DeclState = struct {...@@ -322,7 +323,7 @@ pub const DeclState = struct {
322323
323 if (struct_type.isTuple(ip)) {324 if (struct_type.isTuple(ip)) {
324 for (struct_type.field_types.get(ip), struct_type.offsets.get(ip), 0..) |field_ty, field_off, field_index| {325 for (struct_type.field_types.get(ip), struct_type.offsets.get(ip), 0..) |field_ty, field_off, field_index| {
325 if (!Type.fromInterned(field_ty).hasRuntimeBits(mod)) continue;326 if (!Type.fromInterned(field_ty).hasRuntimeBits(pt)) continue;
326 // DW.AT.member327 // DW.AT.member
327 try dbg_info_buffer.append(@intFromEnum(AbbrevCode.struct_member));328 try dbg_info_buffer.append(@intFromEnum(AbbrevCode.struct_member));
328 // DW.AT.name, DW.FORM.string329 // DW.AT.name, DW.FORM.string
...@@ -340,7 +341,7 @@ pub const DeclState = struct {...@@ -340,7 +341,7 @@ pub const DeclState = struct {
340 struct_type.field_types.get(ip),341 struct_type.field_types.get(ip),
341 struct_type.offsets.get(ip),342 struct_type.offsets.get(ip),
342 ) |field_name, field_ty, field_off| {343 ) |field_name, field_ty, field_off| {
343 if (!Type.fromInterned(field_ty).hasRuntimeBits(mod)) continue;344 if (!Type.fromInterned(field_ty).hasRuntimeBits(pt)) continue;
344 const field_name_slice = field_name.toSlice(ip);345 const field_name_slice = field_name.toSlice(ip);
345 // DW.AT.member346 // DW.AT.member
346 try dbg_info_buffer.ensureUnusedCapacity(field_name_slice.len + 2);347 try dbg_info_buffer.ensureUnusedCapacity(field_name_slice.len + 2);
...@@ -367,9 +368,9 @@ pub const DeclState = struct {...@@ -367,9 +368,9 @@ pub const DeclState = struct {
367 // DW.AT.enumeration_type368 // DW.AT.enumeration_type
368 try dbg_info_buffer.append(@intFromEnum(AbbrevCode.enum_type));369 try dbg_info_buffer.append(@intFromEnum(AbbrevCode.enum_type));
369 // DW.AT.byte_size, DW.FORM.udata370 // DW.AT.byte_size, DW.FORM.udata
370 try leb128.writeUleb128(dbg_info_buffer.writer(), ty.abiSize(mod));371 try leb128.writeUleb128(dbg_info_buffer.writer(), ty.abiSize(pt));
371 // DW.AT.name, DW.FORM.string372 // DW.AT.name, DW.FORM.string
372 try ty.print(dbg_info_buffer.writer(), mod);373 try ty.print(dbg_info_buffer.writer(), pt);
373 try dbg_info_buffer.append(0);374 try dbg_info_buffer.append(0);
374375
375 const enum_type = ip.loadEnumType(ty.ip_index);376 const enum_type = ip.loadEnumType(ty.ip_index);
...@@ -386,8 +387,8 @@ pub const DeclState = struct {...@@ -386,8 +387,8 @@ pub const DeclState = struct {
386 const value = enum_type.values.get(ip)[field_i];387 const value = enum_type.values.get(ip)[field_i];
387 // TODO do not assume a 64bit enum value - could be bigger.388 // TODO do not assume a 64bit enum value - could be bigger.
388 // See https://github.com/ziglang/zig/issues/645389 // See https://github.com/ziglang/zig/issues/645
389 const field_int_val = try Value.fromInterned(value).intFromEnum(ty, mod);390 const field_int_val = try Value.fromInterned(value).intFromEnum(ty, pt);
390 break :value @bitCast(field_int_val.toSignedInt(mod));391 break :value @bitCast(field_int_val.toSignedInt(pt));
391 };392 };
392 mem.writeInt(u64, dbg_info_buffer.addManyAsArrayAssumeCapacity(8), value, target_endian);393 mem.writeInt(u64, dbg_info_buffer.addManyAsArrayAssumeCapacity(8), value, target_endian);
393 }394 }
...@@ -396,8 +397,8 @@ pub const DeclState = struct {...@@ -396,8 +397,8 @@ pub const DeclState = struct {
396 try dbg_info_buffer.append(0);397 try dbg_info_buffer.append(0);
397 },398 },
398 .Union => {399 .Union => {
399 const union_obj = mod.typeToUnion(ty).?;400 const union_obj = zcu.typeToUnion(ty).?;
400 const layout = mod.getUnionLayout(union_obj);401 const layout = pt.getUnionLayout(union_obj);
401 const payload_offset = if (layout.tag_align.compare(.gte, layout.payload_align)) layout.tag_size else 0;402 const payload_offset = if (layout.tag_align.compare(.gte, layout.payload_align)) layout.tag_size else 0;
402 const tag_offset = if (layout.tag_align.compare(.gte, layout.payload_align)) 0 else layout.payload_size;403 const tag_offset = if (layout.tag_align.compare(.gte, layout.payload_align)) 0 else layout.payload_size;
403 // TODO this is temporary to match current state of unions in Zig - we don't yet have404 // TODO this is temporary to match current state of unions in Zig - we don't yet have
...@@ -410,7 +411,7 @@ pub const DeclState = struct {...@@ -410,7 +411,7 @@ pub const DeclState = struct {
410 // DW.AT.byte_size, DW.FORM.udata411 // DW.AT.byte_size, DW.FORM.udata
411 try leb128.writeUleb128(dbg_info_buffer.writer(), layout.abi_size);412 try leb128.writeUleb128(dbg_info_buffer.writer(), layout.abi_size);
412 // DW.AT.name, DW.FORM.string413 // DW.AT.name, DW.FORM.string
413 try ty.print(dbg_info_buffer.writer(), mod);414 try ty.print(dbg_info_buffer.writer(), pt);
414 try dbg_info_buffer.append(0);415 try dbg_info_buffer.append(0);
415416
416 // DW.AT.member417 // DW.AT.member
...@@ -435,12 +436,12 @@ pub const DeclState = struct {...@@ -435,12 +436,12 @@ pub const DeclState = struct {
435 if (is_tagged) {436 if (is_tagged) {
436 try dbg_info_buffer.writer().print("AnonUnion\x00", .{});437 try dbg_info_buffer.writer().print("AnonUnion\x00", .{});
437 } else {438 } else {
438 try ty.print(dbg_info_buffer.writer(), mod);439 try ty.print(dbg_info_buffer.writer(), pt);
439 try dbg_info_buffer.append(0);440 try dbg_info_buffer.append(0);
440 }441 }
441442
442 for (union_obj.field_types.get(ip), union_obj.loadTagType(ip).names.get(ip)) |field_ty, field_name| {443 for (union_obj.field_types.get(ip), union_obj.loadTagType(ip).names.get(ip)) |field_ty, field_name| {
443 if (!Type.fromInterned(field_ty).hasRuntimeBits(mod)) continue;444 if (!Type.fromInterned(field_ty).hasRuntimeBits(pt)) continue;
444 const field_name_slice = field_name.toSlice(ip);445 const field_name_slice = field_name.toSlice(ip);
445 // DW.AT.member446 // DW.AT.member
446 try dbg_info_buffer.append(@intFromEnum(AbbrevCode.struct_member));447 try dbg_info_buffer.append(@intFromEnum(AbbrevCode.struct_member));
...@@ -474,25 +475,25 @@ pub const DeclState = struct {...@@ -474,25 +475,25 @@ pub const DeclState = struct {
474 try dbg_info_buffer.append(0);475 try dbg_info_buffer.append(0);
475 }476 }
476 },477 },
477 .ErrorSet => try addDbgInfoErrorSet(mod, ty, target, &self.dbg_info),478 .ErrorSet => try addDbgInfoErrorSet(pt, ty, target, &self.dbg_info),
478 .ErrorUnion => {479 .ErrorUnion => {
479 const error_ty = ty.errorUnionSet(mod);480 const error_ty = ty.errorUnionSet(zcu);
480 const payload_ty = ty.errorUnionPayload(mod);481 const payload_ty = ty.errorUnionPayload(zcu);
481 const payload_align = if (payload_ty.isNoReturn(mod)) .none else payload_ty.abiAlignment(mod);482 const payload_align = if (payload_ty.isNoReturn(zcu)) .none else payload_ty.abiAlignment(pt);
482 const error_align = Type.anyerror.abiAlignment(mod);483 const error_align = Type.anyerror.abiAlignment(pt);
483 const abi_size = ty.abiSize(mod);484 const abi_size = ty.abiSize(pt);
484 const payload_off = if (error_align.compare(.gte, payload_align)) Type.anyerror.abiSize(mod) else 0;485 const payload_off = if (error_align.compare(.gte, payload_align)) Type.anyerror.abiSize(pt) else 0;
485 const error_off = if (error_align.compare(.gte, payload_align)) 0 else payload_ty.abiSize(mod);486 const error_off = if (error_align.compare(.gte, payload_align)) 0 else payload_ty.abiSize(pt);
486487
487 // DW.AT.structure_type488 // DW.AT.structure_type
488 try dbg_info_buffer.append(@intFromEnum(AbbrevCode.struct_type));489 try dbg_info_buffer.append(@intFromEnum(AbbrevCode.struct_type));
489 // DW.AT.byte_size, DW.FORM.udata490 // DW.AT.byte_size, DW.FORM.udata
490 try leb128.writeUleb128(dbg_info_buffer.writer(), abi_size);491 try leb128.writeUleb128(dbg_info_buffer.writer(), abi_size);
491 // DW.AT.name, DW.FORM.string492 // DW.AT.name, DW.FORM.string
492 try ty.print(dbg_info_buffer.writer(), mod);493 try ty.print(dbg_info_buffer.writer(), pt);
493 try dbg_info_buffer.append(0);494 try dbg_info_buffer.append(0);
494495
495 if (!payload_ty.isNoReturn(mod)) {496 if (!payload_ty.isNoReturn(zcu)) {
496 // DW.AT.member497 // DW.AT.member
497 try dbg_info_buffer.ensureUnusedCapacity(11);498 try dbg_info_buffer.ensureUnusedCapacity(11);
498 dbg_info_buffer.appendAssumeCapacity(@intFromEnum(AbbrevCode.struct_member));499 dbg_info_buffer.appendAssumeCapacity(@intFromEnum(AbbrevCode.struct_member));
...@@ -526,7 +527,7 @@ pub const DeclState = struct {...@@ -526,7 +527,7 @@ pub const DeclState = struct {
526 try dbg_info_buffer.append(0);527 try dbg_info_buffer.append(0);
527 },528 },
528 else => {529 else => {
529 log.debug("TODO implement .debug_info for type '{}'", .{ty.fmt(self.mod)});530 log.debug("TODO implement .debug_info for type '{}'", .{ty.fmt(pt)});
530 try dbg_info_buffer.append(@intFromEnum(AbbrevCode.zero_bit_type));531 try dbg_info_buffer.append(@intFromEnum(AbbrevCode.zero_bit_type));
531 },532 },
532 }533 }
...@@ -555,6 +556,7 @@ pub const DeclState = struct {...@@ -555,6 +556,7 @@ pub const DeclState = struct {
555 owner_decl: InternPool.DeclIndex,556 owner_decl: InternPool.DeclIndex,
556 loc: DbgInfoLoc,557 loc: DbgInfoLoc,
557 ) error{OutOfMemory}!void {558 ) error{OutOfMemory}!void {
559 const pt = self.pt;
558 const dbg_info = &self.dbg_info;560 const dbg_info = &self.dbg_info;
559 const atom_index = self.di_atom_decls.get(owner_decl).?;561 const atom_index = self.di_atom_decls.get(owner_decl).?;
560 const name_with_null = name.ptr[0 .. name.len + 1];562 const name_with_null = name.ptr[0 .. name.len + 1];
...@@ -580,9 +582,9 @@ pub const DeclState = struct {...@@ -580,9 +582,9 @@ pub const DeclState = struct {
580 }582 }
581 },583 },
582 .register_pair => |regs| {584 .register_pair => |regs| {
583 const reg_bits = self.mod.getTarget().ptrBitWidth();585 const reg_bits = pt.zcu.getTarget().ptrBitWidth();
584 const reg_bytes: u8 = @intCast(@divExact(reg_bits, 8));586 const reg_bytes: u8 = @intCast(@divExact(reg_bits, 8));
585 const abi_size = ty.abiSize(self.mod);587 const abi_size = ty.abiSize(pt);
586 try dbg_info.ensureUnusedCapacity(10);588 try dbg_info.ensureUnusedCapacity(10);
587 dbg_info.appendAssumeCapacity(@intFromEnum(AbbrevCode.parameter));589 dbg_info.appendAssumeCapacity(@intFromEnum(AbbrevCode.parameter));
588 // DW.AT.location, DW.FORM.exprloc590 // DW.AT.location, DW.FORM.exprloc
...@@ -675,10 +677,10 @@ pub const DeclState = struct {...@@ -675,10 +677,10 @@ pub const DeclState = struct {
675 const name_with_null = name.ptr[0 .. name.len + 1];677 const name_with_null = name.ptr[0 .. name.len + 1];
676 try dbg_info.append(@intFromEnum(AbbrevCode.variable));678 try dbg_info.append(@intFromEnum(AbbrevCode.variable));
677 const gpa = self.dwarf.allocator;679 const gpa = self.dwarf.allocator;
678 const mod = self.mod;680 const pt = self.pt;
679 const target = mod.getTarget();681 const target = pt.zcu.getTarget();
680 const endian = target.cpu.arch.endian();682 const endian = target.cpu.arch.endian();
681 const child_ty = if (is_ptr) ty.childType(mod) else ty;683 const child_ty = if (is_ptr) ty.childType(pt.zcu) else ty;
682684
683 switch (loc) {685 switch (loc) {
684 .register => |reg| {686 .register => |reg| {
...@@ -701,9 +703,9 @@ pub const DeclState = struct {...@@ -701,9 +703,9 @@ pub const DeclState = struct {
701 },703 },
702704
703 .register_pair => |regs| {705 .register_pair => |regs| {
704 const reg_bits = self.mod.getTarget().ptrBitWidth();706 const reg_bits = pt.zcu.getTarget().ptrBitWidth();
705 const reg_bytes: u8 = @intCast(@divExact(reg_bits, 8));707 const reg_bytes: u8 = @intCast(@divExact(reg_bits, 8));
706 const abi_size = child_ty.abiSize(self.mod);708 const abi_size = child_ty.abiSize(pt);
707 try dbg_info.ensureUnusedCapacity(9);709 try dbg_info.ensureUnusedCapacity(9);
708 // DW.AT.location, DW.FORM.exprloc710 // DW.AT.location, DW.FORM.exprloc
709 var expr_len = std.io.countingWriter(std.io.null_writer);711 var expr_len = std.io.countingWriter(std.io.null_writer);
...@@ -829,9 +831,9 @@ pub const DeclState = struct {...@@ -829,9 +831,9 @@ pub const DeclState = struct {
829 const fixup = dbg_info.items.len;831 const fixup = dbg_info.items.len;
830 dbg_info.appendSliceAssumeCapacity(&[2]u8{ // DW.AT.location, DW.FORM.exprloc832 dbg_info.appendSliceAssumeCapacity(&[2]u8{ // DW.AT.location, DW.FORM.exprloc
831 1,833 1,
832 if (child_ty.isSignedInt(mod)) DW.OP.consts else DW.OP.constu,834 if (child_ty.isSignedInt(pt.zcu)) DW.OP.consts else DW.OP.constu,
833 });835 });
834 if (child_ty.isSignedInt(mod)) {836 if (child_ty.isSignedInt(pt.zcu)) {
835 try leb128.writeIleb128(dbg_info.writer(), @as(i64, @bitCast(x)));837 try leb128.writeIleb128(dbg_info.writer(), @as(i64, @bitCast(x)));
836 } else {838 } else {
837 try leb128.writeUleb128(dbg_info.writer(), x);839 try leb128.writeUleb128(dbg_info.writer(), x);
...@@ -844,7 +846,7 @@ pub const DeclState = struct {...@@ -844,7 +846,7 @@ pub const DeclState = struct {
844 // DW.AT.location, DW.FORM.exprloc846 // DW.AT.location, DW.FORM.exprloc
845 // uleb128(exprloc_len)847 // uleb128(exprloc_len)
846 // DW.OP.implicit_value uleb128(len_of_bytes) bytes848 // DW.OP.implicit_value uleb128(len_of_bytes) bytes
847 const abi_size: u32 = @intCast(child_ty.abiSize(mod));849 const abi_size: u32 = @intCast(child_ty.abiSize(self.pt));
848 var implicit_value_len = std.ArrayList(u8).init(gpa);850 var implicit_value_len = std.ArrayList(u8).init(gpa);
849 defer implicit_value_len.deinit();851 defer implicit_value_len.deinit();
850 try leb128.writeUleb128(implicit_value_len.writer(), abi_size);852 try leb128.writeUleb128(implicit_value_len.writer(), abi_size);
...@@ -934,22 +936,23 @@ pub const DeclState = struct {...@@ -934,22 +936,23 @@ pub const DeclState = struct {
934 }936 }
935937
936 pub fn setInlineFunc(self: *DeclState, func: InternPool.Index) error{OutOfMemory}!void {938 pub fn setInlineFunc(self: *DeclState, func: InternPool.Index) error{OutOfMemory}!void {
939 const zcu = self.pt.zcu;
937 if (self.dbg_line_func == func) return;940 if (self.dbg_line_func == func) return;
938941
939 try self.dbg_line.ensureUnusedCapacity((1 + 4) + (1 + 5));942 try self.dbg_line.ensureUnusedCapacity((1 + 4) + (1 + 5));
940943
941 const old_func_info = self.mod.funcInfo(self.dbg_line_func);944 const old_func_info = zcu.funcInfo(self.dbg_line_func);
942 const new_func_info = self.mod.funcInfo(func);945 const new_func_info = zcu.funcInfo(func);
943946
944 const old_file = try self.dwarf.addDIFile(self.mod, old_func_info.owner_decl);947 const old_file = try self.dwarf.addDIFile(zcu, old_func_info.owner_decl);
945 const new_file = try self.dwarf.addDIFile(self.mod, new_func_info.owner_decl);948 const new_file = try self.dwarf.addDIFile(zcu, new_func_info.owner_decl);
946 if (old_file != new_file) {949 if (old_file != new_file) {
947 self.dbg_line.appendAssumeCapacity(DW.LNS.set_file);950 self.dbg_line.appendAssumeCapacity(DW.LNS.set_file);
948 leb128.writeUnsignedFixed(4, self.dbg_line.addManyAsArrayAssumeCapacity(4), new_file);951 leb128.writeUnsignedFixed(4, self.dbg_line.addManyAsArrayAssumeCapacity(4), new_file);
949 }952 }
950953
951 const old_src_line: i33 = self.mod.declPtr(old_func_info.owner_decl).navSrcLine(self.mod);954 const old_src_line: i33 = zcu.declPtr(old_func_info.owner_decl).navSrcLine(zcu);
952 const new_src_line: i33 = self.mod.declPtr(new_func_info.owner_decl).navSrcLine(self.mod);955 const new_src_line: i33 = zcu.declPtr(new_func_info.owner_decl).navSrcLine(zcu);
953 if (new_src_line != old_src_line) {956 if (new_src_line != old_src_line) {
954 self.dbg_line.appendAssumeCapacity(DW.LNS.advance_line);957 self.dbg_line.appendAssumeCapacity(DW.LNS.advance_line);
955 leb128.writeSignedFixed(5, self.dbg_line.addManyAsArrayAssumeCapacity(5), new_src_line - old_src_line);958 leb128.writeSignedFixed(5, self.dbg_line.addManyAsArrayAssumeCapacity(5), new_src_line - old_src_line);
...@@ -1074,19 +1077,19 @@ pub fn deinit(self: *Dwarf) void {...@@ -1074,19 +1077,19 @@ pub fn deinit(self: *Dwarf) void {
10741077
1075/// Initializes Decl's state and its matching output buffers.1078/// Initializes Decl's state and its matching output buffers.
1076/// Call this before `commitDeclState`.1079/// Call this before `commitDeclState`.
1077pub fn initDeclState(self: *Dwarf, mod: *Module, decl_index: InternPool.DeclIndex) !DeclState {1080pub fn initDeclState(self: *Dwarf, pt: Zcu.PerThread, decl_index: InternPool.DeclIndex) !DeclState {
1078 const tracy = trace(@src());1081 const tracy = trace(@src());
1079 defer tracy.end();1082 defer tracy.end();
10801083
1081 const decl = mod.declPtr(decl_index);1084 const decl = pt.zcu.declPtr(decl_index);
1082 const decl_linkage_name = try decl.fullyQualifiedName(mod);1085 const decl_linkage_name = try decl.fullyQualifiedName(pt);
10831086
1084 log.debug("initDeclState {}{*}", .{ decl_linkage_name.fmt(&mod.intern_pool), decl });1087 log.debug("initDeclState {}{*}", .{ decl_linkage_name.fmt(&pt.zcu.intern_pool), decl });
10851088
1086 const gpa = self.allocator;1089 const gpa = self.allocator;
1087 var decl_state: DeclState = .{1090 var decl_state: DeclState = .{
1088 .dwarf = self,1091 .dwarf = self,
1089 .mod = mod,1092 .pt = pt,
1090 .di_atom_decls = &self.di_atom_decls,1093 .di_atom_decls = &self.di_atom_decls,
1091 .dbg_line_func = undefined,1094 .dbg_line_func = undefined,
1092 .dbg_line = std.ArrayList(u8).init(gpa),1095 .dbg_line = std.ArrayList(u8).init(gpa),
...@@ -1105,7 +1108,7 @@ pub fn initDeclState(self: *Dwarf, mod: *Module, decl_index: InternPool.DeclInde...@@ -1105,7 +1108,7 @@ pub fn initDeclState(self: *Dwarf, mod: *Module, decl_index: InternPool.DeclInde
11051108
1106 assert(decl.has_tv);1109 assert(decl.has_tv);
11071110
1108 switch (decl.typeOf(mod).zigTypeTag(mod)) {1111 switch (decl.typeOf(pt.zcu).zigTypeTag(pt.zcu)) {
1109 .Fn => {1112 .Fn => {
1110 _ = try self.getOrCreateAtomForDecl(.src_fn, decl_index);1113 _ = try self.getOrCreateAtomForDecl(.src_fn, decl_index);
11111114
...@@ -1114,13 +1117,13 @@ pub fn initDeclState(self: *Dwarf, mod: *Module, decl_index: InternPool.DeclInde...@@ -1114,13 +1117,13 @@ pub fn initDeclState(self: *Dwarf, mod: *Module, decl_index: InternPool.DeclInde
1114 try dbg_line_buffer.ensureTotalCapacity((3 + ptr_width_bytes) + (1 + 4) + (1 + 4) + (1 + 5) + 1);1117 try dbg_line_buffer.ensureTotalCapacity((3 + ptr_width_bytes) + (1 + 4) + (1 + 4) + (1 + 5) + 1);
11151118
1116 decl_state.dbg_line_func = decl.val.toIntern();1119 decl_state.dbg_line_func = decl.val.toIntern();
1117 const func = decl.val.getFunction(mod).?;1120 const func = decl.val.getFunction(pt.zcu).?;
1118 log.debug("decl.src_line={d}, func.lbrace_line={d}, func.rbrace_line={d}", .{1121 log.debug("decl.src_line={d}, func.lbrace_line={d}, func.rbrace_line={d}", .{
1119 decl.navSrcLine(mod),1122 decl.navSrcLine(pt.zcu),
1120 func.lbrace_line,1123 func.lbrace_line,
1121 func.rbrace_line,1124 func.rbrace_line,
1122 });1125 });
1123 const line: u28 = @intCast(decl.navSrcLine(mod) + func.lbrace_line);1126 const line: u28 = @intCast(decl.navSrcLine(pt.zcu) + func.lbrace_line);
11241127
1125 dbg_line_buffer.appendSliceAssumeCapacity(&.{1128 dbg_line_buffer.appendSliceAssumeCapacity(&.{
1126 DW.LNS.extended_op,1129 DW.LNS.extended_op,
...@@ -1142,7 +1145,7 @@ pub fn initDeclState(self: *Dwarf, mod: *Module, decl_index: InternPool.DeclInde...@@ -1142,7 +1145,7 @@ pub fn initDeclState(self: *Dwarf, mod: *Module, decl_index: InternPool.DeclInde
1142 assert(self.getRelocDbgFileIndex() == dbg_line_buffer.items.len);1145 assert(self.getRelocDbgFileIndex() == dbg_line_buffer.items.len);
1143 // Once we support more than one source file, this will have the ability to be more1146 // Once we support more than one source file, this will have the ability to be more
1144 // than one possible value.1147 // than one possible value.
1145 const file_index = try self.addDIFile(mod, decl_index);1148 const file_index = try self.addDIFile(pt.zcu, decl_index);
1146 leb128.writeUnsignedFixed(4, dbg_line_buffer.addManyAsArrayAssumeCapacity(4), file_index);1149 leb128.writeUnsignedFixed(4, dbg_line_buffer.addManyAsArrayAssumeCapacity(4), file_index);
11471150
1148 dbg_line_buffer.appendAssumeCapacity(DW.LNS.set_column);1151 dbg_line_buffer.appendAssumeCapacity(DW.LNS.set_column);
...@@ -1153,13 +1156,13 @@ pub fn initDeclState(self: *Dwarf, mod: *Module, decl_index: InternPool.DeclInde...@@ -1153,13 +1156,13 @@ pub fn initDeclState(self: *Dwarf, mod: *Module, decl_index: InternPool.DeclInde
1153 dbg_line_buffer.appendAssumeCapacity(DW.LNS.copy);1156 dbg_line_buffer.appendAssumeCapacity(DW.LNS.copy);
11541157
1155 // .debug_info subprogram1158 // .debug_info subprogram
1156 const decl_name_slice = decl.name.toSlice(&mod.intern_pool);1159 const decl_name_slice = decl.name.toSlice(&pt.zcu.intern_pool);
1157 const decl_linkage_name_slice = decl_linkage_name.toSlice(&mod.intern_pool);1160 const decl_linkage_name_slice = decl_linkage_name.toSlice(&pt.zcu.intern_pool);
1158 try dbg_info_buffer.ensureUnusedCapacity(1 + ptr_width_bytes + 4 + 4 +1161 try dbg_info_buffer.ensureUnusedCapacity(1 + ptr_width_bytes + 4 + 4 +
1159 (decl_name_slice.len + 1) + (decl_linkage_name_slice.len + 1));1162 (decl_name_slice.len + 1) + (decl_linkage_name_slice.len + 1));
11601163
1161 const fn_ret_type = decl.typeOf(mod).fnReturnType(mod);1164 const fn_ret_type = decl.typeOf(pt.zcu).fnReturnType(pt.zcu);
1162 const fn_ret_has_bits = fn_ret_type.hasRuntimeBits(mod);1165 const fn_ret_has_bits = fn_ret_type.hasRuntimeBits(pt);
1163 dbg_info_buffer.appendAssumeCapacity(@intFromEnum(1166 dbg_info_buffer.appendAssumeCapacity(@intFromEnum(
1164 @as(AbbrevCode, if (fn_ret_has_bits) .subprogram else .subprogram_retvoid),1167 @as(AbbrevCode, if (fn_ret_has_bits) .subprogram else .subprogram_retvoid),
1165 ));1168 ));
...@@ -1191,7 +1194,7 @@ pub fn initDeclState(self: *Dwarf, mod: *Module, decl_index: InternPool.DeclInde...@@ -1191,7 +1194,7 @@ pub fn initDeclState(self: *Dwarf, mod: *Module, decl_index: InternPool.DeclInde
11911194
1192pub fn commitDeclState(1195pub fn commitDeclState(
1193 self: *Dwarf,1196 self: *Dwarf,
1194 zcu: *Module,1197 pt: Zcu.PerThread,
1195 decl_index: InternPool.DeclIndex,1198 decl_index: InternPool.DeclIndex,
1196 sym_addr: u64,1199 sym_addr: u64,
1197 sym_size: u64,1200 sym_size: u64,
...@@ -1201,6 +1204,7 @@ pub fn commitDeclState(...@@ -1201,6 +1204,7 @@ pub fn commitDeclState(
1201 defer tracy.end();1204 defer tracy.end();
12021205
1203 const gpa = self.allocator;1206 const gpa = self.allocator;
1207 const zcu = pt.zcu;
1204 const decl = zcu.declPtr(decl_index);1208 const decl = zcu.declPtr(decl_index);
1205 const ip = &zcu.intern_pool;1209 const ip = &zcu.intern_pool;
1206 const namespace = zcu.namespacePtr(decl.src_namespace);1210 const namespace = zcu.namespacePtr(decl.src_namespace);
...@@ -1432,7 +1436,7 @@ pub fn commitDeclState(...@@ -1432,7 +1436,7 @@ pub fn commitDeclState(
1432 if (ip.isErrorSetType(ty.toIntern())) continue;1436 if (ip.isErrorSetType(ty.toIntern())) continue;
14331437
1434 symbol.offset = @intCast(dbg_info_buffer.items.len);1438 symbol.offset = @intCast(dbg_info_buffer.items.len);
1435 try decl_state.addDbgInfoType(zcu, di_atom_index, ty);1439 try decl_state.addDbgInfoType(pt, di_atom_index, ty);
1436 }1440 }
1437 }1441 }
14381442
...@@ -1457,7 +1461,7 @@ pub fn commitDeclState(...@@ -1457,7 +1461,7 @@ pub fn commitDeclState(
1457 reloc.offset,1461 reloc.offset,
1458 value,1462 value,
1459 reloc_target,1463 reloc_target,
1460 ty.fmt(zcu),1464 ty.fmt(pt),
1461 });1465 });
1462 mem.writeInt(1466 mem.writeInt(
1463 u32,1467 u32,
...@@ -1691,7 +1695,7 @@ fn writeDeclDebugInfo(self: *Dwarf, atom_index: Atom.Index, dbg_info_buf: []cons...@@ -1691,7 +1695,7 @@ fn writeDeclDebugInfo(self: *Dwarf, atom_index: Atom.Index, dbg_info_buf: []cons
1691 }1695 }
1692}1696}
16931697
1694pub fn updateDeclLineNumber(self: *Dwarf, mod: *Module, decl_index: InternPool.DeclIndex) !void {1698pub fn updateDeclLineNumber(self: *Dwarf, zcu: *Zcu, decl_index: InternPool.DeclIndex) !void {
1695 const tracy = trace(@src());1699 const tracy = trace(@src());
1696 defer tracy.end();1700 defer tracy.end();
16971701
...@@ -1699,14 +1703,14 @@ pub fn updateDeclLineNumber(self: *Dwarf, mod: *Module, decl_index: InternPool.D...@@ -1699,14 +1703,14 @@ pub fn updateDeclLineNumber(self: *Dwarf, mod: *Module, decl_index: InternPool.D
1699 const atom = self.getAtom(.src_fn, atom_index);1703 const atom = self.getAtom(.src_fn, atom_index);
1700 if (atom.len == 0) return;1704 if (atom.len == 0) return;
17011705
1702 const decl = mod.declPtr(decl_index);1706 const decl = zcu.declPtr(decl_index);
1703 const func = decl.val.getFunction(mod).?;1707 const func = decl.val.getFunction(zcu).?;
1704 log.debug("decl.src_line={d}, func.lbrace_line={d}, func.rbrace_line={d}", .{1708 log.debug("decl.src_line={d}, func.lbrace_line={d}, func.rbrace_line={d}", .{
1705 decl.navSrcLine(mod),1709 decl.navSrcLine(zcu),
1706 func.lbrace_line,1710 func.lbrace_line,
1707 func.rbrace_line,1711 func.rbrace_line,
1708 });1712 });
1709 const line: u28 = @intCast(decl.navSrcLine(mod) + func.lbrace_line);1713 const line: u28 = @intCast(decl.navSrcLine(zcu) + func.lbrace_line);
1710 var data: [4]u8 = undefined;1714 var data: [4]u8 = undefined;
1711 leb128.writeUnsignedFixed(4, &data, line);1715 leb128.writeUnsignedFixed(4, &data, line);
17121716
...@@ -1969,7 +1973,7 @@ fn dbgInfoHeaderBytes(self: *Dwarf) usize {...@@ -1969,7 +1973,7 @@ fn dbgInfoHeaderBytes(self: *Dwarf) usize {
1969 return 120;1973 return 120;
1970}1974}
19711975
1972pub fn writeDbgInfoHeader(self: *Dwarf, zcu: *Module, low_pc: u64, high_pc: u64) !void {1976pub fn writeDbgInfoHeader(self: *Dwarf, zcu: *Zcu, low_pc: u64, high_pc: u64) !void {
1973 // If this value is null it means there is an error in the module;1977 // If this value is null it means there is an error in the module;
1974 // leave debug_info_header_dirty=true.1978 // leave debug_info_header_dirty=true.
1975 const first_dbg_info_off = self.getDebugInfoOff() orelse return;1979 const first_dbg_info_off = self.getDebugInfoOff() orelse return;
...@@ -2058,14 +2062,14 @@ pub fn writeDbgInfoHeader(self: *Dwarf, zcu: *Module, low_pc: u64, high_pc: u64)...@@ -2058,14 +2062,14 @@ pub fn writeDbgInfoHeader(self: *Dwarf, zcu: *Module, low_pc: u64, high_pc: u64)
2058 }2062 }
2059}2063}
20602064
2061fn resolveCompilationDir(module: *Module, buffer: *[std.fs.max_path_bytes]u8) []const u8 {2065fn resolveCompilationDir(zcu: *Zcu, buffer: *[std.fs.max_path_bytes]u8) []const u8 {
2062 // We fully resolve all paths at this point to avoid lack of source line info in stack2066 // We fully resolve all paths at this point to avoid lack of source line info in stack
2063 // traces or lack of debugging information which, if relative paths were used, would2067 // traces or lack of debugging information which, if relative paths were used, would
2064 // be very location dependent.2068 // be very location dependent.
2065 // TODO: the only concern I have with this is WASI as either host or target, should2069 // TODO: the only concern I have with this is WASI as either host or target, should
2066 // we leave the paths as relative then?2070 // we leave the paths as relative then?
2067 const root_dir_path = module.root_mod.root.root_dir.path orelse ".";2071 const root_dir_path = zcu.root_mod.root.root_dir.path orelse ".";
2068 const sub_path = module.root_mod.root.sub_path;2072 const sub_path = zcu.root_mod.root.sub_path;
2069 const realpath = if (std.fs.path.isAbsolute(root_dir_path)) r: {2073 const realpath = if (std.fs.path.isAbsolute(root_dir_path)) r: {
2070 @memcpy(buffer[0..root_dir_path.len], root_dir_path);2074 @memcpy(buffer[0..root_dir_path.len], root_dir_path);
2071 break :r root_dir_path;2075 break :r root_dir_path;
...@@ -2682,7 +2686,7 @@ fn padToIdeal(actual_size: anytype) @TypeOf(actual_size) {...@@ -2682,7 +2686,7 @@ fn padToIdeal(actual_size: anytype) @TypeOf(actual_size) {
2682 return actual_size +| (actual_size / ideal_factor);2686 return actual_size +| (actual_size / ideal_factor);
2683}2687}
26842688
2685pub fn flushModule(self: *Dwarf, module: *Module) !void {2689pub fn flushModule(self: *Dwarf, pt: Zcu.PerThread) !void {
2686 const comp = self.bin_file.comp;2690 const comp = self.bin_file.comp;
2687 const target = comp.root_mod.resolved_target.result;2691 const target = comp.root_mod.resolved_target.result;
26882692
...@@ -2694,9 +2698,9 @@ pub fn flushModule(self: *Dwarf, module: *Module) !void {...@@ -2694,9 +2698,9 @@ pub fn flushModule(self: *Dwarf, module: *Module) !void {
26942698
2695 var dbg_info_buffer = std.ArrayList(u8).init(arena);2699 var dbg_info_buffer = std.ArrayList(u8).init(arena);
2696 try addDbgInfoErrorSetNames(2700 try addDbgInfoErrorSetNames(
2697 module,2701 pt,
2698 Type.anyerror,2702 Type.anyerror,
2699 module.global_error_set.keys(),2703 pt.zcu.global_error_set.keys(),
2700 target,2704 target,
2701 &dbg_info_buffer,2705 &dbg_info_buffer,
2702 );2706 );
...@@ -2759,9 +2763,9 @@ pub fn flushModule(self: *Dwarf, module: *Module) !void {...@@ -2759,9 +2763,9 @@ pub fn flushModule(self: *Dwarf, module: *Module) !void {
2759 }2763 }
2760}2764}
27612765
2762fn addDIFile(self: *Dwarf, mod: *Module, decl_index: InternPool.DeclIndex) !u28 {2766fn addDIFile(self: *Dwarf, zcu: *Zcu, decl_index: InternPool.DeclIndex) !u28 {
2763 const decl = mod.declPtr(decl_index);2767 const decl = zcu.declPtr(decl_index);
2764 const file_scope = decl.getFileScope(mod);2768 const file_scope = decl.getFileScope(zcu);
2765 const gop = try self.di_files.getOrPut(self.allocator, file_scope);2769 const gop = try self.di_files.getOrPut(self.allocator, file_scope);
2766 if (!gop.found_existing) {2770 if (!gop.found_existing) {
2767 switch (self.bin_file.tag) {2771 switch (self.bin_file.tag) {
...@@ -2827,16 +2831,16 @@ fn genIncludeDirsAndFileNames(self: *Dwarf, arena: Allocator) !struct {...@@ -2827,16 +2831,16 @@ fn genIncludeDirsAndFileNames(self: *Dwarf, arena: Allocator) !struct {
2827}2831}
28282832
2829fn addDbgInfoErrorSet(2833fn addDbgInfoErrorSet(
2830 mod: *Module,2834 pt: Zcu.PerThread,
2831 ty: Type,2835 ty: Type,
2832 target: std.Target,2836 target: std.Target,
2833 dbg_info_buffer: *std.ArrayList(u8),2837 dbg_info_buffer: *std.ArrayList(u8),
2834) !void {2838) !void {
2835 return addDbgInfoErrorSetNames(mod, ty, ty.errorSetNames(mod).get(&mod.intern_pool), target, dbg_info_buffer);2839 return addDbgInfoErrorSetNames(pt, ty, ty.errorSetNames(pt.zcu).get(&pt.zcu.intern_pool), target, dbg_info_buffer);
2836}2840}
28372841
2838fn addDbgInfoErrorSetNames(2842fn addDbgInfoErrorSetNames(
2839 mod: *Module,2843 pt: Zcu.PerThread,
2840 /// Used for printing the type name only.2844 /// Used for printing the type name only.
2841 ty: Type,2845 ty: Type,
2842 error_names: []const InternPool.NullTerminatedString,2846 error_names: []const InternPool.NullTerminatedString,
...@@ -2848,10 +2852,10 @@ fn addDbgInfoErrorSetNames(...@@ -2848,10 +2852,10 @@ fn addDbgInfoErrorSetNames(
2848 // DW.AT.enumeration_type2852 // DW.AT.enumeration_type
2849 try dbg_info_buffer.append(@intFromEnum(AbbrevCode.enum_type));2853 try dbg_info_buffer.append(@intFromEnum(AbbrevCode.enum_type));
2850 // DW.AT.byte_size, DW.FORM.udata2854 // DW.AT.byte_size, DW.FORM.udata
2851 const abi_size = Type.anyerror.abiSize(mod);2855 const abi_size = Type.anyerror.abiSize(pt);
2852 try leb128.writeUleb128(dbg_info_buffer.writer(), abi_size);2856 try leb128.writeUleb128(dbg_info_buffer.writer(), abi_size);
2853 // DW.AT.name, DW.FORM.string2857 // DW.AT.name, DW.FORM.string
2854 try ty.print(dbg_info_buffer.writer(), mod);2858 try ty.print(dbg_info_buffer.writer(), pt);
2855 try dbg_info_buffer.append(0);2859 try dbg_info_buffer.append(0);
28562860
2857 // DW.AT.enumerator2861 // DW.AT.enumerator
...@@ -2865,8 +2869,8 @@ fn addDbgInfoErrorSetNames(...@@ -2865,8 +2869,8 @@ fn addDbgInfoErrorSetNames(
2865 mem.writeInt(u64, dbg_info_buffer.addManyAsArrayAssumeCapacity(8), 0, target_endian);2869 mem.writeInt(u64, dbg_info_buffer.addManyAsArrayAssumeCapacity(8), 0, target_endian);
28662870
2867 for (error_names) |error_name| {2871 for (error_names) |error_name| {
2868 const int = try mod.getErrorValue(error_name);2872 const int = try pt.zcu.getErrorValue(error_name);
2869 const error_name_slice = error_name.toSlice(&mod.intern_pool);2873 const error_name_slice = error_name.toSlice(&pt.zcu.intern_pool);
2870 // DW.AT.enumerator2874 // DW.AT.enumerator
2871 try dbg_info_buffer.ensureUnusedCapacity(error_name_slice.len + 2 + @sizeOf(u64));2875 try dbg_info_buffer.ensureUnusedCapacity(error_name_slice.len + 2 + @sizeOf(u64));
2872 dbg_info_buffer.appendAssumeCapacity(@intFromEnum(AbbrevCode.enum_variant));2876 dbg_info_buffer.appendAssumeCapacity(@intFromEnum(AbbrevCode.enum_variant));
...@@ -2965,8 +2969,6 @@ const LinkBlock = File.LinkBlock;...@@ -2965,8 +2969,6 @@ const LinkBlock = File.LinkBlock;
2965const LinkFn = File.LinkFn;2969const LinkFn = File.LinkFn;
2966const LinkerLoad = @import("../codegen.zig").LinkerLoad;2970const LinkerLoad = @import("../codegen.zig").LinkerLoad;
2967const Zcu = @import("../Zcu.zig");2971const Zcu = @import("../Zcu.zig");
2968/// Deprecated.
2969const Module = Zcu;
2970const InternPool = @import("../InternPool.zig");2972const InternPool = @import("../InternPool.zig");
2971const StringTable = @import("StringTable.zig");2973const StringTable = @import("StringTable.zig");
2972const Type = @import("../Type.zig");2974const Type = @import("../Type.zig");
src/link/Elf.zig+23-22
...@@ -543,18 +543,19 @@ pub fn deinit(self: *Elf) void {...@@ -543,18 +543,19 @@ pub fn deinit(self: *Elf) void {
543 self.comdat_group_sections.deinit(gpa);543 self.comdat_group_sections.deinit(gpa);
544}544}
545545
546pub fn getDeclVAddr(self: *Elf, decl_index: InternPool.DeclIndex, reloc_info: link.File.RelocInfo) !u64 {546pub fn getDeclVAddr(self: *Elf, _: Zcu.PerThread, decl_index: InternPool.DeclIndex, reloc_info: link.File.RelocInfo) !u64 {
547 assert(self.llvm_object == null);547 assert(self.llvm_object == null);
548 return self.zigObjectPtr().?.getDeclVAddr(self, decl_index, reloc_info);548 return self.zigObjectPtr().?.getDeclVAddr(self, decl_index, reloc_info);
549}549}
550550
551pub fn lowerAnonDecl(551pub fn lowerAnonDecl(
552 self: *Elf,552 self: *Elf,
553 pt: Zcu.PerThread,
553 decl_val: InternPool.Index,554 decl_val: InternPool.Index,
554 explicit_alignment: InternPool.Alignment,555 explicit_alignment: InternPool.Alignment,
555 src_loc: Module.LazySrcLoc,556 src_loc: Module.LazySrcLoc,
556) !codegen.Result {557) !codegen.Result {
557 return self.zigObjectPtr().?.lowerAnonDecl(self, decl_val, explicit_alignment, src_loc);558 return self.zigObjectPtr().?.lowerAnonDecl(self, pt, decl_val, explicit_alignment, src_loc);
558}559}
559560
560pub fn getAnonDeclVAddr(self: *Elf, decl_val: InternPool.Index, reloc_info: link.File.RelocInfo) !u64 {561pub fn getAnonDeclVAddr(self: *Elf, decl_val: InternPool.Index, reloc_info: link.File.RelocInfo) !u64 {
...@@ -1064,15 +1065,15 @@ pub fn markDirty(self: *Elf, shdr_index: u32) void {...@@ -1064,15 +1065,15 @@ pub fn markDirty(self: *Elf, shdr_index: u32) void {
1064 }1065 }
1065}1066}
10661067
1067pub fn flush(self: *Elf, arena: Allocator, prog_node: std.Progress.Node) link.File.FlushError!void {1068pub fn flush(self: *Elf, arena: Allocator, tid: Zcu.PerThread.Id, prog_node: std.Progress.Node) link.File.FlushError!void {
1068 const use_lld = build_options.have_llvm and self.base.comp.config.use_lld;1069 const use_lld = build_options.have_llvm and self.base.comp.config.use_lld;
1069 if (use_lld) {1070 if (use_lld) {
1070 return self.linkWithLLD(arena, prog_node);1071 return self.linkWithLLD(arena, tid, prog_node);
1071 }1072 }
1072 try self.flushModule(arena, prog_node);1073 try self.flushModule(arena, tid, prog_node);
1073}1074}
10741075
1075pub fn flushModule(self: *Elf, arena: Allocator, prog_node: std.Progress.Node) link.File.FlushError!void {1076pub fn flushModule(self: *Elf, arena: Allocator, tid: Zcu.PerThread.Id, prog_node: std.Progress.Node) link.File.FlushError!void {
1076 const tracy = trace(@src());1077 const tracy = trace(@src());
1077 defer tracy.end();1078 defer tracy.end();
10781079
...@@ -1103,7 +1104,7 @@ pub fn flushModule(self: *Elf, arena: Allocator, prog_node: std.Progress.Node) l...@@ -1103,7 +1104,7 @@ pub fn flushModule(self: *Elf, arena: Allocator, prog_node: std.Progress.Node) l
1103 // --verbose-link1104 // --verbose-link
1104 if (comp.verbose_link) try self.dumpArgv(comp);1105 if (comp.verbose_link) try self.dumpArgv(comp);
11051106
1106 if (self.zigObjectPtr()) |zig_object| try zig_object.flushModule(self);1107 if (self.zigObjectPtr()) |zig_object| try zig_object.flushModule(self, tid);
1107 if (self.base.isStaticLib()) return relocatable.flushStaticLib(self, comp, module_obj_path);1108 if (self.base.isStaticLib()) return relocatable.flushStaticLib(self, comp, module_obj_path);
1108 if (self.base.isObject()) return relocatable.flushObject(self, comp, module_obj_path);1109 if (self.base.isObject()) return relocatable.flushObject(self, comp, module_obj_path);
11091110
...@@ -2146,7 +2147,7 @@ fn scanRelocs(self: *Elf) !void {...@@ -2146,7 +2147,7 @@ fn scanRelocs(self: *Elf) !void {
2146 }2147 }
2147}2148}
21482149
2149fn linkWithLLD(self: *Elf, arena: Allocator, prog_node: std.Progress.Node) !void {2150fn linkWithLLD(self: *Elf, arena: Allocator, tid: Zcu.PerThread.Id, prog_node: std.Progress.Node) !void {
2150 const tracy = trace(@src());2151 const tracy = trace(@src());
2151 defer tracy.end();2152 defer tracy.end();
21522153
...@@ -2159,7 +2160,7 @@ fn linkWithLLD(self: *Elf, arena: Allocator, prog_node: std.Progress.Node) !void...@@ -2159,7 +2160,7 @@ fn linkWithLLD(self: *Elf, arena: Allocator, prog_node: std.Progress.Node) !void
2159 // If there is no Zig code to compile, then we should skip flushing the output file because it2160 // If there is no Zig code to compile, then we should skip flushing the output file because it
2160 // will not be part of the linker line anyway.2161 // will not be part of the linker line anyway.
2161 const module_obj_path: ?[]const u8 = if (comp.module != null) blk: {2162 const module_obj_path: ?[]const u8 = if (comp.module != null) blk: {
2162 try self.flushModule(arena, prog_node);2163 try self.flushModule(arena, tid, prog_node);
21632164
2164 if (fs.path.dirname(full_out_path)) |dirname| {2165 if (fs.path.dirname(full_out_path)) |dirname| {
2165 break :blk try fs.path.join(arena, &.{ dirname, self.base.zcu_object_sub_path.? });2166 break :blk try fs.path.join(arena, &.{ dirname, self.base.zcu_object_sub_path.? });
...@@ -2983,46 +2984,46 @@ pub fn freeDecl(self: *Elf, decl_index: InternPool.DeclIndex) void {...@@ -2983,46 +2984,46 @@ pub fn freeDecl(self: *Elf, decl_index: InternPool.DeclIndex) void {
2983 return self.zigObjectPtr().?.freeDecl(self, decl_index);2984 return self.zigObjectPtr().?.freeDecl(self, decl_index);
2984}2985}
29852986
2986pub fn updateFunc(self: *Elf, mod: *Module, func_index: InternPool.Index, air: Air, liveness: Liveness) !void {2987pub fn updateFunc(self: *Elf, pt: Zcu.PerThread, func_index: InternPool.Index, air: Air, liveness: Liveness) !void {
2987 if (build_options.skip_non_native and builtin.object_format != .elf) {2988 if (build_options.skip_non_native and builtin.object_format != .elf) {
2988 @panic("Attempted to compile for object format that was disabled by build configuration");2989 @panic("Attempted to compile for object format that was disabled by build configuration");
2989 }2990 }
2990 if (self.llvm_object) |llvm_object| return llvm_object.updateFunc(mod, func_index, air, liveness);2991 if (self.llvm_object) |llvm_object| return llvm_object.updateFunc(pt, func_index, air, liveness);
2991 return self.zigObjectPtr().?.updateFunc(self, mod, func_index, air, liveness);2992 return self.zigObjectPtr().?.updateFunc(self, pt, func_index, air, liveness);
2992}2993}
29932994
2994pub fn updateDecl(2995pub fn updateDecl(
2995 self: *Elf,2996 self: *Elf,
2996 mod: *Module,2997 pt: Zcu.PerThread,
2997 decl_index: InternPool.DeclIndex,2998 decl_index: InternPool.DeclIndex,
2998) link.File.UpdateDeclError!void {2999) link.File.UpdateDeclError!void {
2999 if (build_options.skip_non_native and builtin.object_format != .elf) {3000 if (build_options.skip_non_native and builtin.object_format != .elf) {
3000 @panic("Attempted to compile for object format that was disabled by build configuration");3001 @panic("Attempted to compile for object format that was disabled by build configuration");
3001 }3002 }
3002 if (self.llvm_object) |llvm_object| return llvm_object.updateDecl(mod, decl_index);3003 if (self.llvm_object) |llvm_object| return llvm_object.updateDecl(pt, decl_index);
3003 return self.zigObjectPtr().?.updateDecl(self, mod, decl_index);3004 return self.zigObjectPtr().?.updateDecl(self, pt, decl_index);
3004}3005}
30053006
3006pub fn lowerUnnamedConst(self: *Elf, val: Value, decl_index: InternPool.DeclIndex) !u32 {3007pub fn lowerUnnamedConst(self: *Elf, pt: Zcu.PerThread, val: Value, decl_index: InternPool.DeclIndex) !u32 {
3007 return self.zigObjectPtr().?.lowerUnnamedConst(self, val, decl_index);3008 return self.zigObjectPtr().?.lowerUnnamedConst(self, pt, val, decl_index);
3008}3009}
30093010
3010pub fn updateExports(3011pub fn updateExports(
3011 self: *Elf,3012 self: *Elf,
3012 mod: *Module,3013 pt: Zcu.PerThread,
3013 exported: Module.Exported,3014 exported: Module.Exported,
3014 export_indices: []const u32,3015 export_indices: []const u32,
3015) link.File.UpdateExportsError!void {3016) link.File.UpdateExportsError!void {
3016 if (build_options.skip_non_native and builtin.object_format != .elf) {3017 if (build_options.skip_non_native and builtin.object_format != .elf) {
3017 @panic("Attempted to compile for object format that was disabled by build configuration");3018 @panic("Attempted to compile for object format that was disabled by build configuration");
3018 }3019 }
3019 if (self.llvm_object) |llvm_object| return llvm_object.updateExports(mod, exported, export_indices);3020 if (self.llvm_object) |llvm_object| return llvm_object.updateExports(pt, exported, export_indices);
3020 return self.zigObjectPtr().?.updateExports(self, mod, exported, export_indices);3021 return self.zigObjectPtr().?.updateExports(self, pt, exported, export_indices);
3021}3022}
30223023
3023pub fn updateDeclLineNumber(self: *Elf, mod: *Module, decl_index: InternPool.DeclIndex) !void {3024pub fn updateDeclLineNumber(self: *Elf, pt: Zcu.PerThread, decl_index: InternPool.DeclIndex) !void {
3024 if (self.llvm_object) |_| return;3025 if (self.llvm_object) |_| return;
3025 return self.zigObjectPtr().?.updateDeclLineNumber(mod, decl_index);3026 return self.zigObjectPtr().?.updateDeclLineNumber(pt, decl_index);
3026}3027}
30273028
3028pub fn deleteExport(3029pub fn deleteExport(
src/link/Elf/ZigObject.zig+68-63
...@@ -158,16 +158,17 @@ pub fn deinit(self: *ZigObject, allocator: Allocator) void {...@@ -158,16 +158,17 @@ pub fn deinit(self: *ZigObject, allocator: Allocator) void {
158 }158 }
159}159}
160160
161pub fn flushModule(self: *ZigObject, elf_file: *Elf) !void {161pub fn flushModule(self: *ZigObject, elf_file: *Elf, tid: Zcu.PerThread.Id) !void {
162 // Handle any lazy symbols that were emitted by incremental compilation.162 // Handle any lazy symbols that were emitted by incremental compilation.
163 if (self.lazy_syms.getPtr(.none)) |metadata| {163 if (self.lazy_syms.getPtr(.none)) |metadata| {
164 const zcu = elf_file.base.comp.module.?;164 const pt: Zcu.PerThread = .{ .zcu = elf_file.base.comp.module.?, .tid = tid };
165165
166 // Most lazy symbols can be updated on first use, but166 // Most lazy symbols can be updated on first use, but
167 // anyerror needs to wait for everything to be flushed.167 // anyerror needs to wait for everything to be flushed.
168 if (metadata.text_state != .unused) self.updateLazySymbol(168 if (metadata.text_state != .unused) self.updateLazySymbol(
169 elf_file,169 elf_file,
170 link.File.LazySymbol.initDecl(.code, null, zcu),170 pt,
171 link.File.LazySymbol.initDecl(.code, null, pt.zcu),
171 metadata.text_symbol_index,172 metadata.text_symbol_index,
172 ) catch |err| return switch (err) {173 ) catch |err| return switch (err) {
173 error.CodegenFail => error.FlushFailure,174 error.CodegenFail => error.FlushFailure,
...@@ -175,7 +176,8 @@ pub fn flushModule(self: *ZigObject, elf_file: *Elf) !void {...@@ -175,7 +176,8 @@ pub fn flushModule(self: *ZigObject, elf_file: *Elf) !void {
175 };176 };
176 if (metadata.rodata_state != .unused) self.updateLazySymbol(177 if (metadata.rodata_state != .unused) self.updateLazySymbol(
177 elf_file,178 elf_file,
178 link.File.LazySymbol.initDecl(.const_data, null, zcu),179 pt,
180 link.File.LazySymbol.initDecl(.const_data, null, pt.zcu),
179 metadata.rodata_symbol_index,181 metadata.rodata_symbol_index,
180 ) catch |err| return switch (err) {182 ) catch |err| return switch (err) {
181 error.CodegenFail => error.FlushFailure,183 error.CodegenFail => error.FlushFailure,
...@@ -188,8 +190,8 @@ pub fn flushModule(self: *ZigObject, elf_file: *Elf) !void {...@@ -188,8 +190,8 @@ pub fn flushModule(self: *ZigObject, elf_file: *Elf) !void {
188 }190 }
189191
190 if (self.dwarf) |*dw| {192 if (self.dwarf) |*dw| {
191 const zcu = elf_file.base.comp.module.?;193 const pt: Zcu.PerThread = .{ .zcu = elf_file.base.comp.module.?, .tid = tid };
192 try dw.flushModule(zcu);194 try dw.flushModule(pt);
193195
194 // TODO I need to re-think how to handle ZigObject's debug sections AND debug sections196 // TODO I need to re-think how to handle ZigObject's debug sections AND debug sections
195 // extracted from input object files correctly.197 // extracted from input object files correctly.
...@@ -202,7 +204,7 @@ pub fn flushModule(self: *ZigObject, elf_file: *Elf) !void {...@@ -202,7 +204,7 @@ pub fn flushModule(self: *ZigObject, elf_file: *Elf) !void {
202 const text_shdr = elf_file.shdrs.items[elf_file.zig_text_section_index.?];204 const text_shdr = elf_file.shdrs.items[elf_file.zig_text_section_index.?];
203 const low_pc = text_shdr.sh_addr;205 const low_pc = text_shdr.sh_addr;
204 const high_pc = text_shdr.sh_addr + text_shdr.sh_size;206 const high_pc = text_shdr.sh_addr + text_shdr.sh_size;
205 try dw.writeDbgInfoHeader(zcu, low_pc, high_pc);207 try dw.writeDbgInfoHeader(pt.zcu, low_pc, high_pc);
206 self.debug_info_header_dirty = false;208 self.debug_info_header_dirty = false;
207 }209 }
208210
...@@ -684,6 +686,7 @@ pub fn getAnonDeclVAddr(...@@ -684,6 +686,7 @@ pub fn getAnonDeclVAddr(
684pub fn lowerAnonDecl(686pub fn lowerAnonDecl(
685 self: *ZigObject,687 self: *ZigObject,
686 elf_file: *Elf,688 elf_file: *Elf,
689 pt: Zcu.PerThread,
687 decl_val: InternPool.Index,690 decl_val: InternPool.Index,
688 explicit_alignment: InternPool.Alignment,691 explicit_alignment: InternPool.Alignment,
689 src_loc: Module.LazySrcLoc,692 src_loc: Module.LazySrcLoc,
...@@ -692,7 +695,7 @@ pub fn lowerAnonDecl(...@@ -692,7 +695,7 @@ pub fn lowerAnonDecl(
692 const mod = elf_file.base.comp.module.?;695 const mod = elf_file.base.comp.module.?;
693 const ty = Type.fromInterned(mod.intern_pool.typeOf(decl_val));696 const ty = Type.fromInterned(mod.intern_pool.typeOf(decl_val));
694 const decl_alignment = switch (explicit_alignment) {697 const decl_alignment = switch (explicit_alignment) {
695 .none => ty.abiAlignment(mod),698 .none => ty.abiAlignment(pt),
696 else => explicit_alignment,699 else => explicit_alignment,
697 };700 };
698 if (self.anon_decls.get(decl_val)) |metadata| {701 if (self.anon_decls.get(decl_val)) |metadata| {
...@@ -708,6 +711,7 @@ pub fn lowerAnonDecl(...@@ -708,6 +711,7 @@ pub fn lowerAnonDecl(
708 }) catch unreachable;711 }) catch unreachable;
709 const res = self.lowerConst(712 const res = self.lowerConst(
710 elf_file,713 elf_file,
714 pt,
711 name,715 name,
712 val,716 val,
713 decl_alignment,717 decl_alignment,
...@@ -733,10 +737,11 @@ pub fn lowerAnonDecl(...@@ -733,10 +737,11 @@ pub fn lowerAnonDecl(
733pub fn getOrCreateMetadataForLazySymbol(737pub fn getOrCreateMetadataForLazySymbol(
734 self: *ZigObject,738 self: *ZigObject,
735 elf_file: *Elf,739 elf_file: *Elf,
740 pt: Zcu.PerThread,
736 lazy_sym: link.File.LazySymbol,741 lazy_sym: link.File.LazySymbol,
737) !Symbol.Index {742) !Symbol.Index {
738 const gpa = elf_file.base.comp.gpa;743 const mod = pt.zcu;
739 const mod = elf_file.base.comp.module.?;744 const gpa = mod.gpa;
740 const gop = try self.lazy_syms.getOrPut(gpa, lazy_sym.getDecl(mod));745 const gop = try self.lazy_syms.getOrPut(gpa, lazy_sym.getDecl(mod));
741 errdefer _ = if (!gop.found_existing) self.lazy_syms.pop();746 errdefer _ = if (!gop.found_existing) self.lazy_syms.pop();
742 if (!gop.found_existing) gop.value_ptr.* = .{};747 if (!gop.found_existing) gop.value_ptr.* = .{};
...@@ -766,7 +771,7 @@ pub fn getOrCreateMetadataForLazySymbol(...@@ -766,7 +771,7 @@ pub fn getOrCreateMetadataForLazySymbol(
766 metadata.state.* = .pending_flush;771 metadata.state.* = .pending_flush;
767 const symbol_index = metadata.symbol_index.*;772 const symbol_index = metadata.symbol_index.*;
768 // anyerror needs to be deferred until flushModule773 // anyerror needs to be deferred until flushModule
769 if (lazy_sym.getDecl(mod) != .none) try self.updateLazySymbol(elf_file, lazy_sym, symbol_index);774 if (lazy_sym.getDecl(mod) != .none) try self.updateLazySymbol(elf_file, pt, lazy_sym, symbol_index);
770 return symbol_index;775 return symbol_index;
771}776}
772777
...@@ -893,6 +898,7 @@ fn getDeclShdrIndex(...@@ -893,6 +898,7 @@ fn getDeclShdrIndex(
893fn updateDeclCode(898fn updateDeclCode(
894 self: *ZigObject,899 self: *ZigObject,
895 elf_file: *Elf,900 elf_file: *Elf,
901 pt: Zcu.PerThread,
896 decl_index: InternPool.DeclIndex,902 decl_index: InternPool.DeclIndex,
897 sym_index: Symbol.Index,903 sym_index: Symbol.Index,
898 shdr_index: u32,904 shdr_index: u32,
...@@ -900,13 +906,13 @@ fn updateDeclCode(...@@ -900,13 +906,13 @@ fn updateDeclCode(
900 stt_bits: u8,906 stt_bits: u8,
901) !void {907) !void {
902 const gpa = elf_file.base.comp.gpa;908 const gpa = elf_file.base.comp.gpa;
903 const mod = elf_file.base.comp.module.?;909 const mod = pt.zcu;
904 const decl = mod.declPtr(decl_index);910 const decl = mod.declPtr(decl_index);
905 const decl_name = try decl.fullyQualifiedName(mod);911 const decl_name = try decl.fullyQualifiedName(pt);
906912
907 log.debug("updateDeclCode {}{*}", .{ decl_name.fmt(&mod.intern_pool), decl });913 log.debug("updateDeclCode {}{*}", .{ decl_name.fmt(&mod.intern_pool), decl });
908914
909 const required_alignment = decl.getAlignment(mod).max(915 const required_alignment = decl.getAlignment(pt).max(
910 target_util.minFunctionAlignment(mod.getTarget()),916 target_util.minFunctionAlignment(mod.getTarget()),
911 );917 );
912918
...@@ -994,19 +1000,20 @@ fn updateDeclCode(...@@ -994,19 +1000,20 @@ fn updateDeclCode(
994fn updateTlv(1000fn updateTlv(
995 self: *ZigObject,1001 self: *ZigObject,
996 elf_file: *Elf,1002 elf_file: *Elf,
1003 pt: Zcu.PerThread,
997 decl_index: InternPool.DeclIndex,1004 decl_index: InternPool.DeclIndex,
998 sym_index: Symbol.Index,1005 sym_index: Symbol.Index,
999 shndx: u32,1006 shndx: u32,
1000 code: []const u8,1007 code: []const u8,
1001) !void {1008) !void {
1002 const gpa = elf_file.base.comp.gpa;1009 const mod = pt.zcu;
1003 const mod = elf_file.base.comp.module.?;1010 const gpa = mod.gpa;
1004 const decl = mod.declPtr(decl_index);1011 const decl = mod.declPtr(decl_index);
1005 const decl_name = try decl.fullyQualifiedName(mod);1012 const decl_name = try decl.fullyQualifiedName(pt);
10061013
1007 log.debug("updateTlv {} ({*})", .{ decl_name.fmt(&mod.intern_pool), decl });1014 log.debug("updateTlv {} ({*})", .{ decl_name.fmt(&mod.intern_pool), decl });
10081015
1009 const required_alignment = decl.getAlignment(mod);1016 const required_alignment = decl.getAlignment(pt);
10101017
1011 const sym = elf_file.symbol(sym_index);1018 const sym = elf_file.symbol(sym_index);
1012 const esym = &self.local_esyms.items(.elf_sym)[sym.esym_index];1019 const esym = &self.local_esyms.items(.elf_sym)[sym.esym_index];
...@@ -1048,7 +1055,7 @@ fn updateTlv(...@@ -1048,7 +1055,7 @@ fn updateTlv(
1048pub fn updateFunc(1055pub fn updateFunc(
1049 self: *ZigObject,1056 self: *ZigObject,
1050 elf_file: *Elf,1057 elf_file: *Elf,
1051 mod: *Module,1058 pt: Zcu.PerThread,
1052 func_index: InternPool.Index,1059 func_index: InternPool.Index,
1053 air: Air,1060 air: Air,
1054 liveness: Liveness,1061 liveness: Liveness,
...@@ -1056,6 +1063,7 @@ pub fn updateFunc(...@@ -1056,6 +1063,7 @@ pub fn updateFunc(
1056 const tracy = trace(@src());1063 const tracy = trace(@src());
1057 defer tracy.end();1064 defer tracy.end();
10581065
1066 const mod = pt.zcu;
1059 const gpa = elf_file.base.comp.gpa;1067 const gpa = elf_file.base.comp.gpa;
1060 const func = mod.funcInfo(func_index);1068 const func = mod.funcInfo(func_index);
1061 const decl_index = func.owner_decl;1069 const decl_index = func.owner_decl;
...@@ -1068,29 +1076,19 @@ pub fn updateFunc(...@@ -1068,29 +1076,19 @@ pub fn updateFunc(
1068 var code_buffer = std.ArrayList(u8).init(gpa);1076 var code_buffer = std.ArrayList(u8).init(gpa);
1069 defer code_buffer.deinit();1077 defer code_buffer.deinit();
10701078
1071 var decl_state: ?Dwarf.DeclState = if (self.dwarf) |*dw| try dw.initDeclState(mod, decl_index) else null;1079 var decl_state: ?Dwarf.DeclState = if (self.dwarf) |*dw| try dw.initDeclState(pt, decl_index) else null;
1072 defer if (decl_state) |*ds| ds.deinit();1080 defer if (decl_state) |*ds| ds.deinit();
10731081
1074 const res = if (decl_state) |*ds|1082 const res = try codegen.generateFunction(
1075 try codegen.generateFunction(1083 &elf_file.base,
1076 &elf_file.base,1084 pt,
1077 decl.navSrcLoc(mod),1085 decl.navSrcLoc(mod),
1078 func_index,1086 func_index,
1079 air,1087 air,
1080 liveness,1088 liveness,
1081 &code_buffer,1089 &code_buffer,
1082 .{ .dwarf = ds },1090 if (decl_state) |*ds| .{ .dwarf = ds } else .none,
1083 )1091 );
1084 else
1085 try codegen.generateFunction(
1086 &elf_file.base,
1087 decl.navSrcLoc(mod),
1088 func_index,
1089 air,
1090 liveness,
1091 &code_buffer,
1092 .none,
1093 );
10941092
1095 const code = switch (res) {1093 const code = switch (res) {
1096 .ok => code_buffer.items,1094 .ok => code_buffer.items,
...@@ -1102,12 +1100,12 @@ pub fn updateFunc(...@@ -1102,12 +1100,12 @@ pub fn updateFunc(
1102 };1100 };
11031101
1104 const shndx = try self.getDeclShdrIndex(elf_file, decl, code);1102 const shndx = try self.getDeclShdrIndex(elf_file, decl, code);
1105 try self.updateDeclCode(elf_file, decl_index, sym_index, shndx, code, elf.STT_FUNC);1103 try self.updateDeclCode(elf_file, pt, decl_index, sym_index, shndx, code, elf.STT_FUNC);
11061104
1107 if (decl_state) |*ds| {1105 if (decl_state) |*ds| {
1108 const sym = elf_file.symbol(sym_index);1106 const sym = elf_file.symbol(sym_index);
1109 try self.dwarf.?.commitDeclState(1107 try self.dwarf.?.commitDeclState(
1110 mod,1108 pt,
1111 decl_index,1109 decl_index,
1112 @intCast(sym.address(.{}, elf_file)),1110 @intCast(sym.address(.{}, elf_file)),
1113 sym.atom(elf_file).?.size,1111 sym.atom(elf_file).?.size,
...@@ -1121,12 +1119,13 @@ pub fn updateFunc(...@@ -1121,12 +1119,13 @@ pub fn updateFunc(
1121pub fn updateDecl(1119pub fn updateDecl(
1122 self: *ZigObject,1120 self: *ZigObject,
1123 elf_file: *Elf,1121 elf_file: *Elf,
1124 mod: *Module,1122 pt: Zcu.PerThread,
1125 decl_index: InternPool.DeclIndex,1123 decl_index: InternPool.DeclIndex,
1126) link.File.UpdateDeclError!void {1124) link.File.UpdateDeclError!void {
1127 const tracy = trace(@src());1125 const tracy = trace(@src());
1128 defer tracy.end();1126 defer tracy.end();
11291127
1128 const mod = pt.zcu;
1130 const decl = mod.declPtr(decl_index);1129 const decl = mod.declPtr(decl_index);
11311130
1132 if (decl.val.getExternFunc(mod)) |_| {1131 if (decl.val.getExternFunc(mod)) |_| {
...@@ -1150,19 +1149,19 @@ pub fn updateDecl(...@@ -1150,19 +1149,19 @@ pub fn updateDecl(
1150 var code_buffer = std.ArrayList(u8).init(gpa);1149 var code_buffer = std.ArrayList(u8).init(gpa);
1151 defer code_buffer.deinit();1150 defer code_buffer.deinit();
11521151
1153 var decl_state: ?Dwarf.DeclState = if (self.dwarf) |*dw| try dw.initDeclState(mod, decl_index) else null;1152 var decl_state: ?Dwarf.DeclState = if (self.dwarf) |*dw| try dw.initDeclState(pt, decl_index) else null;
1154 defer if (decl_state) |*ds| ds.deinit();1153 defer if (decl_state) |*ds| ds.deinit();
11551154
1156 // TODO implement .debug_info for global variables1155 // TODO implement .debug_info for global variables
1157 const decl_val = if (decl.val.getVariable(mod)) |variable| Value.fromInterned(variable.init) else decl.val;1156 const decl_val = if (decl.val.getVariable(mod)) |variable| Value.fromInterned(variable.init) else decl.val;
1158 const res = if (decl_state) |*ds|1157 const res = if (decl_state) |*ds|
1159 try codegen.generateSymbol(&elf_file.base, decl.navSrcLoc(mod), decl_val, &code_buffer, .{1158 try codegen.generateSymbol(&elf_file.base, pt, decl.navSrcLoc(mod), decl_val, &code_buffer, .{
1160 .dwarf = ds,1159 .dwarf = ds,
1161 }, .{1160 }, .{
1162 .parent_atom_index = sym_index,1161 .parent_atom_index = sym_index,
1163 })1162 })
1164 else1163 else
1165 try codegen.generateSymbol(&elf_file.base, decl.navSrcLoc(mod), decl_val, &code_buffer, .none, .{1164 try codegen.generateSymbol(&elf_file.base, pt, decl.navSrcLoc(mod), decl_val, &code_buffer, .none, .{
1166 .parent_atom_index = sym_index,1165 .parent_atom_index = sym_index,
1167 });1166 });
11681167
...@@ -1177,14 +1176,14 @@ pub fn updateDecl(...@@ -1177,14 +1176,14 @@ pub fn updateDecl(
11771176
1178 const shndx = try self.getDeclShdrIndex(elf_file, decl, code);1177 const shndx = try self.getDeclShdrIndex(elf_file, decl, code);
1179 if (elf_file.shdrs.items[shndx].sh_flags & elf.SHF_TLS != 0)1178 if (elf_file.shdrs.items[shndx].sh_flags & elf.SHF_TLS != 0)
1180 try self.updateTlv(elf_file, decl_index, sym_index, shndx, code)1179 try self.updateTlv(elf_file, pt, decl_index, sym_index, shndx, code)
1181 else1180 else
1182 try self.updateDeclCode(elf_file, decl_index, sym_index, shndx, code, elf.STT_OBJECT);1181 try self.updateDeclCode(elf_file, pt, decl_index, sym_index, shndx, code, elf.STT_OBJECT);
11831182
1184 if (decl_state) |*ds| {1183 if (decl_state) |*ds| {
1185 const sym = elf_file.symbol(sym_index);1184 const sym = elf_file.symbol(sym_index);
1186 try self.dwarf.?.commitDeclState(1185 try self.dwarf.?.commitDeclState(
1187 mod,1186 pt,
1188 decl_index,1187 decl_index,
1189 @intCast(sym.address(.{}, elf_file)),1188 @intCast(sym.address(.{}, elf_file)),
1190 sym.atom(elf_file).?.size,1189 sym.atom(elf_file).?.size,
...@@ -1198,11 +1197,12 @@ pub fn updateDecl(...@@ -1198,11 +1197,12 @@ pub fn updateDecl(
1198fn updateLazySymbol(1197fn updateLazySymbol(
1199 self: *ZigObject,1198 self: *ZigObject,
1200 elf_file: *Elf,1199 elf_file: *Elf,
1200 pt: Zcu.PerThread,
1201 sym: link.File.LazySymbol,1201 sym: link.File.LazySymbol,
1202 symbol_index: Symbol.Index,1202 symbol_index: Symbol.Index,
1203) !void {1203) !void {
1204 const gpa = elf_file.base.comp.gpa;1204 const mod = pt.zcu;
1205 const mod = elf_file.base.comp.module.?;1205 const gpa = mod.gpa;
12061206
1207 var required_alignment: InternPool.Alignment = .none;1207 var required_alignment: InternPool.Alignment = .none;
1208 var code_buffer = std.ArrayList(u8).init(gpa);1208 var code_buffer = std.ArrayList(u8).init(gpa);
...@@ -1211,7 +1211,7 @@ fn updateLazySymbol(...@@ -1211,7 +1211,7 @@ fn updateLazySymbol(
1211 const name_str_index = blk: {1211 const name_str_index = blk: {
1212 const name = try std.fmt.allocPrint(gpa, "__lazy_{s}_{}", .{1212 const name = try std.fmt.allocPrint(gpa, "__lazy_{s}_{}", .{
1213 @tagName(sym.kind),1213 @tagName(sym.kind),
1214 sym.ty.fmt(mod),1214 sym.ty.fmt(pt),
1215 });1215 });
1216 defer gpa.free(name);1216 defer gpa.free(name);
1217 break :blk try self.strtab.insert(gpa, name);1217 break :blk try self.strtab.insert(gpa, name);
...@@ -1220,6 +1220,7 @@ fn updateLazySymbol(...@@ -1220,6 +1220,7 @@ fn updateLazySymbol(
1220 const src = sym.ty.srcLocOrNull(mod) orelse Module.LazySrcLoc.unneeded;1220 const src = sym.ty.srcLocOrNull(mod) orelse Module.LazySrcLoc.unneeded;
1221 const res = try codegen.generateLazySymbol(1221 const res = try codegen.generateLazySymbol(
1222 &elf_file.base,1222 &elf_file.base,
1223 pt,
1223 src,1224 src,
1224 sym,1225 sym,
1225 &required_alignment,1226 &required_alignment,
...@@ -1273,6 +1274,7 @@ fn updateLazySymbol(...@@ -1273,6 +1274,7 @@ fn updateLazySymbol(
1273pub fn lowerUnnamedConst(1274pub fn lowerUnnamedConst(
1274 self: *ZigObject,1275 self: *ZigObject,
1275 elf_file: *Elf,1276 elf_file: *Elf,
1277 pt: Zcu.PerThread,
1276 val: Value,1278 val: Value,
1277 decl_index: InternPool.DeclIndex,1279 decl_index: InternPool.DeclIndex,
1278) !u32 {1280) !u32 {
...@@ -1284,16 +1286,17 @@ pub fn lowerUnnamedConst(...@@ -1284,16 +1286,17 @@ pub fn lowerUnnamedConst(
1284 }1286 }
1285 const unnamed_consts = gop.value_ptr;1287 const unnamed_consts = gop.value_ptr;
1286 const decl = mod.declPtr(decl_index);1288 const decl = mod.declPtr(decl_index);
1287 const decl_name = try decl.fullyQualifiedName(mod);1289 const decl_name = try decl.fullyQualifiedName(pt);
1288 const index = unnamed_consts.items.len;1290 const index = unnamed_consts.items.len;
1289 const name = try std.fmt.allocPrint(gpa, "__unnamed_{}_{d}", .{ decl_name.fmt(&mod.intern_pool), index });1291 const name = try std.fmt.allocPrint(gpa, "__unnamed_{}_{d}", .{ decl_name.fmt(&mod.intern_pool), index });
1290 defer gpa.free(name);1292 defer gpa.free(name);
1291 const ty = val.typeOf(mod);1293 const ty = val.typeOf(mod);
1292 const sym_index = switch (try self.lowerConst(1294 const sym_index = switch (try self.lowerConst(
1293 elf_file,1295 elf_file,
1296 pt,
1294 name,1297 name,
1295 val,1298 val,
1296 ty.abiAlignment(mod),1299 ty.abiAlignment(pt),
1297 elf_file.zig_data_rel_ro_section_index.?,1300 elf_file.zig_data_rel_ro_section_index.?,
1298 decl.navSrcLoc(mod),1301 decl.navSrcLoc(mod),
1299 )) {1302 )) {
...@@ -1318,20 +1321,21 @@ const LowerConstResult = union(enum) {...@@ -1318,20 +1321,21 @@ const LowerConstResult = union(enum) {
1318fn lowerConst(1321fn lowerConst(
1319 self: *ZigObject,1322 self: *ZigObject,
1320 elf_file: *Elf,1323 elf_file: *Elf,
1324 pt: Zcu.PerThread,
1321 name: []const u8,1325 name: []const u8,
1322 val: Value,1326 val: Value,
1323 required_alignment: InternPool.Alignment,1327 required_alignment: InternPool.Alignment,
1324 output_section_index: u32,1328 output_section_index: u32,
1325 src_loc: Module.LazySrcLoc,1329 src_loc: Module.LazySrcLoc,
1326) !LowerConstResult {1330) !LowerConstResult {
1327 const gpa = elf_file.base.comp.gpa;1331 const gpa = pt.zcu.gpa;
13281332
1329 var code_buffer = std.ArrayList(u8).init(gpa);1333 var code_buffer = std.ArrayList(u8).init(gpa);
1330 defer code_buffer.deinit();1334 defer code_buffer.deinit();
13311335
1332 const sym_index = try self.addAtom(elf_file);1336 const sym_index = try self.addAtom(elf_file);
13331337
1334 const res = try codegen.generateSymbol(&elf_file.base, src_loc, val, &code_buffer, .{1338 const res = try codegen.generateSymbol(&elf_file.base, pt, src_loc, val, &code_buffer, .{
1335 .none = {},1339 .none = {},
1336 }, .{1340 }, .{
1337 .parent_atom_index = sym_index,1341 .parent_atom_index = sym_index,
...@@ -1373,13 +1377,14 @@ fn lowerConst(...@@ -1373,13 +1377,14 @@ fn lowerConst(
1373pub fn updateExports(1377pub fn updateExports(
1374 self: *ZigObject,1378 self: *ZigObject,
1375 elf_file: *Elf,1379 elf_file: *Elf,
1376 mod: *Module,1380 pt: Zcu.PerThread,
1377 exported: Module.Exported,1381 exported: Module.Exported,
1378 export_indices: []const u32,1382 export_indices: []const u32,
1379) link.File.UpdateExportsError!void {1383) link.File.UpdateExportsError!void {
1380 const tracy = trace(@src());1384 const tracy = trace(@src());
1381 defer tracy.end();1385 defer tracy.end();
13821386
1387 const mod = pt.zcu;
1383 const gpa = elf_file.base.comp.gpa;1388 const gpa = elf_file.base.comp.gpa;
1384 const metadata = switch (exported) {1389 const metadata = switch (exported) {
1385 .decl_index => |decl_index| blk: {1390 .decl_index => |decl_index| blk: {
...@@ -1388,7 +1393,7 @@ pub fn updateExports(...@@ -1388,7 +1393,7 @@ pub fn updateExports(
1388 },1393 },
1389 .value => |value| self.anon_decls.getPtr(value) orelse blk: {1394 .value => |value| self.anon_decls.getPtr(value) orelse blk: {
1390 const first_exp = mod.all_exports.items[export_indices[0]];1395 const first_exp = mod.all_exports.items[export_indices[0]];
1391 const res = try self.lowerAnonDecl(elf_file, value, .none, first_exp.src);1396 const res = try self.lowerAnonDecl(elf_file, pt, value, .none, first_exp.src);
1392 switch (res) {1397 switch (res) {
1393 .ok => {},1398 .ok => {},
1394 .fail => |em| {1399 .fail => |em| {
...@@ -1461,19 +1466,19 @@ pub fn updateExports(...@@ -1461,19 +1466,19 @@ pub fn updateExports(
1461/// Must be called only after a successful call to `updateDecl`.1466/// Must be called only after a successful call to `updateDecl`.
1462pub fn updateDeclLineNumber(1467pub fn updateDeclLineNumber(
1463 self: *ZigObject,1468 self: *ZigObject,
1464 mod: *Module,1469 pt: Zcu.PerThread,
1465 decl_index: InternPool.DeclIndex,1470 decl_index: InternPool.DeclIndex,
1466) !void {1471) !void {
1467 const tracy = trace(@src());1472 const tracy = trace(@src());
1468 defer tracy.end();1473 defer tracy.end();
14691474
1470 const decl = mod.declPtr(decl_index);1475 const decl = pt.zcu.declPtr(decl_index);
1471 const decl_name = try decl.fullyQualifiedName(mod);1476 const decl_name = try decl.fullyQualifiedName(pt);
14721477
1473 log.debug("updateDeclLineNumber {}{*}", .{ decl_name.fmt(&mod.intern_pool), decl });1478 log.debug("updateDeclLineNumber {}{*}", .{ decl_name.fmt(&pt.zcu.intern_pool), decl });
14741479
1475 if (self.dwarf) |*dw| {1480 if (self.dwarf) |*dw| {
1476 try dw.updateDeclLineNumber(mod, decl_index);1481 try dw.updateDeclLineNumber(pt.zcu, decl_index);
1477 }1482 }
1478}1483}
14791484
src/link/MachO.zig+20-19
...@@ -360,11 +360,11 @@ pub fn deinit(self: *MachO) void {...@@ -360,11 +360,11 @@ pub fn deinit(self: *MachO) void {
360 self.unwind_records.deinit(gpa);360 self.unwind_records.deinit(gpa);
361}361}
362362
363pub fn flush(self: *MachO, arena: Allocator, prog_node: std.Progress.Node) link.File.FlushError!void {363pub fn flush(self: *MachO, arena: Allocator, tid: Zcu.PerThread.Id, prog_node: std.Progress.Node) link.File.FlushError!void {
364 try self.flushModule(arena, prog_node);364 try self.flushModule(arena, tid, prog_node);
365}365}
366366
367pub fn flushModule(self: *MachO, arena: Allocator, prog_node: std.Progress.Node) link.File.FlushError!void {367pub fn flushModule(self: *MachO, arena: Allocator, tid: Zcu.PerThread.Id, prog_node: std.Progress.Node) link.File.FlushError!void {
368 const tracy = trace(@src());368 const tracy = trace(@src());
369 defer tracy.end();369 defer tracy.end();
370370
...@@ -391,7 +391,7 @@ pub fn flushModule(self: *MachO, arena: Allocator, prog_node: std.Progress.Node)...@@ -391,7 +391,7 @@ pub fn flushModule(self: *MachO, arena: Allocator, prog_node: std.Progress.Node)
391 // --verbose-link391 // --verbose-link
392 if (comp.verbose_link) try self.dumpArgv(comp);392 if (comp.verbose_link) try self.dumpArgv(comp);
393393
394 if (self.getZigObject()) |zo| try zo.flushModule(self);394 if (self.getZigObject()) |zo| try zo.flushModule(self, tid);
395 if (self.base.isStaticLib()) return relocatable.flushStaticLib(self, comp, module_obj_path);395 if (self.base.isStaticLib()) return relocatable.flushStaticLib(self, comp, module_obj_path);
396 if (self.base.isObject()) return relocatable.flushObject(self, comp, module_obj_path);396 if (self.base.isObject()) return relocatable.flushObject(self, comp, module_obj_path);
397397
...@@ -3178,42 +3178,42 @@ pub fn writeCodeSignature(self: *MachO, code_sig: *CodeSignature) !void {...@@ -3178,42 +3178,42 @@ pub fn writeCodeSignature(self: *MachO, code_sig: *CodeSignature) !void {
3178 try self.base.file.?.pwriteAll(buffer.items, offset);3178 try self.base.file.?.pwriteAll(buffer.items, offset);
3179}3179}
31803180
3181pub fn updateFunc(self: *MachO, mod: *Module, func_index: InternPool.Index, air: Air, liveness: Liveness) !void {3181pub fn updateFunc(self: *MachO, pt: Zcu.PerThread, func_index: InternPool.Index, air: Air, liveness: Liveness) !void {
3182 if (build_options.skip_non_native and builtin.object_format != .macho) {3182 if (build_options.skip_non_native and builtin.object_format != .macho) {
3183 @panic("Attempted to compile for object format that was disabled by build configuration");3183 @panic("Attempted to compile for object format that was disabled by build configuration");
3184 }3184 }
3185 if (self.llvm_object) |llvm_object| return llvm_object.updateFunc(mod, func_index, air, liveness);3185 if (self.llvm_object) |llvm_object| return llvm_object.updateFunc(pt, func_index, air, liveness);
3186 return self.getZigObject().?.updateFunc(self, mod, func_index, air, liveness);3186 return self.getZigObject().?.updateFunc(self, pt, func_index, air, liveness);
3187}3187}
31883188
3189pub fn lowerUnnamedConst(self: *MachO, val: Value, decl_index: InternPool.DeclIndex) !u32 {3189pub fn lowerUnnamedConst(self: *MachO, pt: Zcu.PerThread, val: Value, decl_index: InternPool.DeclIndex) !u32 {
3190 return self.getZigObject().?.lowerUnnamedConst(self, val, decl_index);3190 return self.getZigObject().?.lowerUnnamedConst(self, pt, val, decl_index);
3191}3191}
31923192
3193pub fn updateDecl(self: *MachO, mod: *Module, decl_index: InternPool.DeclIndex) !void {3193pub fn updateDecl(self: *MachO, pt: Zcu.PerThread, decl_index: InternPool.DeclIndex) !void {
3194 if (build_options.skip_non_native and builtin.object_format != .macho) {3194 if (build_options.skip_non_native and builtin.object_format != .macho) {
3195 @panic("Attempted to compile for object format that was disabled by build configuration");3195 @panic("Attempted to compile for object format that was disabled by build configuration");
3196 }3196 }
3197 if (self.llvm_object) |llvm_object| return llvm_object.updateDecl(mod, decl_index);3197 if (self.llvm_object) |llvm_object| return llvm_object.updateDecl(pt, decl_index);
3198 return self.getZigObject().?.updateDecl(self, mod, decl_index);3198 return self.getZigObject().?.updateDecl(self, pt, decl_index);
3199}3199}
32003200
3201pub fn updateDeclLineNumber(self: *MachO, module: *Module, decl_index: InternPool.DeclIndex) !void {3201pub fn updateDeclLineNumber(self: *MachO, pt: Zcu.PerThread, decl_index: InternPool.DeclIndex) !void {
3202 if (self.llvm_object) |_| return;3202 if (self.llvm_object) |_| return;
3203 return self.getZigObject().?.updateDeclLineNumber(module, decl_index);3203 return self.getZigObject().?.updateDeclLineNumber(pt, decl_index);
3204}3204}
32053205
3206pub fn updateExports(3206pub fn updateExports(
3207 self: *MachO,3207 self: *MachO,
3208 mod: *Module,3208 pt: Zcu.PerThread,
3209 exported: Module.Exported,3209 exported: Module.Exported,
3210 export_indices: []const u32,3210 export_indices: []const u32,
3211) link.File.UpdateExportsError!void {3211) link.File.UpdateExportsError!void {
3212 if (build_options.skip_non_native and builtin.object_format != .macho) {3212 if (build_options.skip_non_native and builtin.object_format != .macho) {
3213 @panic("Attempted to compile for object format that was disabled by build configuration");3213 @panic("Attempted to compile for object format that was disabled by build configuration");
3214 }3214 }
3215 if (self.llvm_object) |llvm_object| return llvm_object.updateExports(mod, exported, export_indices);3215 if (self.llvm_object) |llvm_object| return llvm_object.updateExports(pt, exported, export_indices);
3216 return self.getZigObject().?.updateExports(self, mod, exported, export_indices);3216 return self.getZigObject().?.updateExports(self, pt, exported, export_indices);
3217}3217}
32183218
3219pub fn deleteExport(3219pub fn deleteExport(
...@@ -3230,18 +3230,19 @@ pub fn freeDecl(self: *MachO, decl_index: InternPool.DeclIndex) void {...@@ -3230,18 +3230,19 @@ pub fn freeDecl(self: *MachO, decl_index: InternPool.DeclIndex) void {
3230 return self.getZigObject().?.freeDecl(decl_index);3230 return self.getZigObject().?.freeDecl(decl_index);
3231}3231}
32323232
3233pub fn getDeclVAddr(self: *MachO, decl_index: InternPool.DeclIndex, reloc_info: link.File.RelocInfo) !u64 {3233pub fn getDeclVAddr(self: *MachO, _: Zcu.PerThread, decl_index: InternPool.DeclIndex, reloc_info: link.File.RelocInfo) !u64 {
3234 assert(self.llvm_object == null);3234 assert(self.llvm_object == null);
3235 return self.getZigObject().?.getDeclVAddr(self, decl_index, reloc_info);3235 return self.getZigObject().?.getDeclVAddr(self, decl_index, reloc_info);
3236}3236}
32373237
3238pub fn lowerAnonDecl(3238pub fn lowerAnonDecl(
3239 self: *MachO,3239 self: *MachO,
3240 pt: Zcu.PerThread,
3240 decl_val: InternPool.Index,3241 decl_val: InternPool.Index,
3241 explicit_alignment: InternPool.Alignment,3242 explicit_alignment: InternPool.Alignment,
3242 src_loc: Module.LazySrcLoc,3243 src_loc: Module.LazySrcLoc,
3243) !codegen.Result {3244) !codegen.Result {
3244 return self.getZigObject().?.lowerAnonDecl(self, decl_val, explicit_alignment, src_loc);3245 return self.getZigObject().?.lowerAnonDecl(self, pt, decl_val, explicit_alignment, src_loc);
3245}3246}
32463247
3247pub fn getAnonDeclVAddr(self: *MachO, decl_val: InternPool.Index, reloc_info: link.File.RelocInfo) !u64 {3248pub fn getAnonDeclVAddr(self: *MachO, decl_val: InternPool.Index, reloc_info: link.File.RelocInfo) !u64 {
src/link/MachO/ZigObject.zig+56-41
...@@ -425,16 +425,17 @@ pub fn getInputSection(self: ZigObject, atom: Atom, macho_file: *MachO) macho.se...@@ -425,16 +425,17 @@ pub fn getInputSection(self: ZigObject, atom: Atom, macho_file: *MachO) macho.se
425 return sect;425 return sect;
426}426}
427427
428pub fn flushModule(self: *ZigObject, macho_file: *MachO) !void {428pub fn flushModule(self: *ZigObject, macho_file: *MachO, tid: Zcu.PerThread.Id) !void {
429 // Handle any lazy symbols that were emitted by incremental compilation.429 // Handle any lazy symbols that were emitted by incremental compilation.
430 if (self.lazy_syms.getPtr(.none)) |metadata| {430 if (self.lazy_syms.getPtr(.none)) |metadata| {
431 const zcu = macho_file.base.comp.module.?;431 const pt: Zcu.PerThread = .{ .zcu = macho_file.base.comp.module.?, .tid = tid };
432432
433 // Most lazy symbols can be updated on first use, but433 // Most lazy symbols can be updated on first use, but
434 // anyerror needs to wait for everything to be flushed.434 // anyerror needs to wait for everything to be flushed.
435 if (metadata.text_state != .unused) self.updateLazySymbol(435 if (metadata.text_state != .unused) self.updateLazySymbol(
436 macho_file,436 macho_file,
437 link.File.LazySymbol.initDecl(.code, null, zcu),437 pt,
438 link.File.LazySymbol.initDecl(.code, null, pt.zcu),
438 metadata.text_symbol_index,439 metadata.text_symbol_index,
439 ) catch |err| return switch (err) {440 ) catch |err| return switch (err) {
440 error.CodegenFail => error.FlushFailure,441 error.CodegenFail => error.FlushFailure,
...@@ -442,7 +443,8 @@ pub fn flushModule(self: *ZigObject, macho_file: *MachO) !void {...@@ -442,7 +443,8 @@ pub fn flushModule(self: *ZigObject, macho_file: *MachO) !void {
442 };443 };
443 if (metadata.const_state != .unused) self.updateLazySymbol(444 if (metadata.const_state != .unused) self.updateLazySymbol(
444 macho_file,445 macho_file,
445 link.File.LazySymbol.initDecl(.const_data, null, zcu),446 pt,
447 link.File.LazySymbol.initDecl(.const_data, null, pt.zcu),
446 metadata.const_symbol_index,448 metadata.const_symbol_index,
447 ) catch |err| return switch (err) {449 ) catch |err| return switch (err) {
448 error.CodegenFail => error.FlushFailure,450 error.CodegenFail => error.FlushFailure,
...@@ -455,8 +457,8 @@ pub fn flushModule(self: *ZigObject, macho_file: *MachO) !void {...@@ -455,8 +457,8 @@ pub fn flushModule(self: *ZigObject, macho_file: *MachO) !void {
455 }457 }
456458
457 if (self.dwarf) |*dw| {459 if (self.dwarf) |*dw| {
458 const zcu = macho_file.base.comp.module.?;460 const pt: Zcu.PerThread = .{ .zcu = macho_file.base.comp.module.?, .tid = tid };
459 try dw.flushModule(zcu);461 try dw.flushModule(pt);
460462
461 if (self.debug_abbrev_dirty) {463 if (self.debug_abbrev_dirty) {
462 try dw.writeDbgAbbrev();464 try dw.writeDbgAbbrev();
...@@ -469,7 +471,7 @@ pub fn flushModule(self: *ZigObject, macho_file: *MachO) !void {...@@ -469,7 +471,7 @@ pub fn flushModule(self: *ZigObject, macho_file: *MachO) !void {
469 const text_section = macho_file.sections.items(.header)[macho_file.zig_text_sect_index.?];471 const text_section = macho_file.sections.items(.header)[macho_file.zig_text_sect_index.?];
470 const low_pc = text_section.addr;472 const low_pc = text_section.addr;
471 const high_pc = text_section.addr + text_section.size;473 const high_pc = text_section.addr + text_section.size;
472 try dw.writeDbgInfoHeader(zcu, low_pc, high_pc);474 try dw.writeDbgInfoHeader(pt.zcu, low_pc, high_pc);
473 self.debug_info_header_dirty = false;475 self.debug_info_header_dirty = false;
474 }476 }
475477
...@@ -570,6 +572,7 @@ pub fn getAnonDeclVAddr(...@@ -570,6 +572,7 @@ pub fn getAnonDeclVAddr(
570pub fn lowerAnonDecl(572pub fn lowerAnonDecl(
571 self: *ZigObject,573 self: *ZigObject,
572 macho_file: *MachO,574 macho_file: *MachO,
575 pt: Zcu.PerThread,
573 decl_val: InternPool.Index,576 decl_val: InternPool.Index,
574 explicit_alignment: Atom.Alignment,577 explicit_alignment: Atom.Alignment,
575 src_loc: Module.LazySrcLoc,578 src_loc: Module.LazySrcLoc,
...@@ -578,7 +581,7 @@ pub fn lowerAnonDecl(...@@ -578,7 +581,7 @@ pub fn lowerAnonDecl(
578 const mod = macho_file.base.comp.module.?;581 const mod = macho_file.base.comp.module.?;
579 const ty = Type.fromInterned(mod.intern_pool.typeOf(decl_val));582 const ty = Type.fromInterned(mod.intern_pool.typeOf(decl_val));
580 const decl_alignment = switch (explicit_alignment) {583 const decl_alignment = switch (explicit_alignment) {
581 .none => ty.abiAlignment(mod),584 .none => ty.abiAlignment(pt),
582 else => explicit_alignment,585 else => explicit_alignment,
583 };586 };
584 if (self.anon_decls.get(decl_val)) |metadata| {587 if (self.anon_decls.get(decl_val)) |metadata| {
...@@ -593,6 +596,7 @@ pub fn lowerAnonDecl(...@@ -593,6 +596,7 @@ pub fn lowerAnonDecl(
593 }) catch unreachable;596 }) catch unreachable;
594 const res = self.lowerConst(597 const res = self.lowerConst(
595 macho_file,598 macho_file,
599 pt,
596 name,600 name,
597 Value.fromInterned(decl_val),601 Value.fromInterned(decl_val),
598 decl_alignment,602 decl_alignment,
...@@ -656,7 +660,7 @@ pub fn freeDecl(self: *ZigObject, macho_file: *MachO, decl_index: InternPool.Dec...@@ -656,7 +660,7 @@ pub fn freeDecl(self: *ZigObject, macho_file: *MachO, decl_index: InternPool.Dec
656pub fn updateFunc(660pub fn updateFunc(
657 self: *ZigObject,661 self: *ZigObject,
658 macho_file: *MachO,662 macho_file: *MachO,
659 mod: *Module,663 pt: Zcu.PerThread,
660 func_index: InternPool.Index,664 func_index: InternPool.Index,
661 air: Air,665 air: Air,
662 liveness: Liveness,666 liveness: Liveness,
...@@ -664,7 +668,8 @@ pub fn updateFunc(...@@ -664,7 +668,8 @@ pub fn updateFunc(
664 const tracy = trace(@src());668 const tracy = trace(@src());
665 defer tracy.end();669 defer tracy.end();
666670
667 const gpa = macho_file.base.comp.gpa;671 const mod = pt.zcu;
672 const gpa = mod.gpa;
668 const func = mod.funcInfo(func_index);673 const func = mod.funcInfo(func_index);
669 const decl_index = func.owner_decl;674 const decl_index = func.owner_decl;
670 const decl = mod.declPtr(decl_index);675 const decl = mod.declPtr(decl_index);
...@@ -676,12 +681,13 @@ pub fn updateFunc(...@@ -676,12 +681,13 @@ pub fn updateFunc(
676 var code_buffer = std.ArrayList(u8).init(gpa);681 var code_buffer = std.ArrayList(u8).init(gpa);
677 defer code_buffer.deinit();682 defer code_buffer.deinit();
678683
679 var decl_state: ?Dwarf.DeclState = if (self.dwarf) |*dw| try dw.initDeclState(mod, decl_index) else null;684 var decl_state: ?Dwarf.DeclState = if (self.dwarf) |*dw| try dw.initDeclState(pt, decl_index) else null;
680 defer if (decl_state) |*ds| ds.deinit();685 defer if (decl_state) |*ds| ds.deinit();
681686
682 const dio: codegen.DebugInfoOutput = if (decl_state) |*ds| .{ .dwarf = ds } else .none;687 const dio: codegen.DebugInfoOutput = if (decl_state) |*ds| .{ .dwarf = ds } else .none;
683 const res = try codegen.generateFunction(688 const res = try codegen.generateFunction(
684 &macho_file.base,689 &macho_file.base,
690 pt,
685 decl.navSrcLoc(mod),691 decl.navSrcLoc(mod),
686 func_index,692 func_index,
687 air,693 air,
...@@ -700,12 +706,12 @@ pub fn updateFunc(...@@ -700,12 +706,12 @@ pub fn updateFunc(
700 };706 };
701707
702 const sect_index = try self.getDeclOutputSection(macho_file, decl, code);708 const sect_index = try self.getDeclOutputSection(macho_file, decl, code);
703 try self.updateDeclCode(macho_file, decl_index, sym_index, sect_index, code);709 try self.updateDeclCode(macho_file, pt, decl_index, sym_index, sect_index, code);
704710
705 if (decl_state) |*ds| {711 if (decl_state) |*ds| {
706 const sym = macho_file.getSymbol(sym_index);712 const sym = macho_file.getSymbol(sym_index);
707 try self.dwarf.?.commitDeclState(713 try self.dwarf.?.commitDeclState(
708 mod,714 pt,
709 decl_index,715 decl_index,
710 sym.getAddress(.{}, macho_file),716 sym.getAddress(.{}, macho_file),
711 sym.getAtom(macho_file).?.size,717 sym.getAtom(macho_file).?.size,
...@@ -719,12 +725,13 @@ pub fn updateFunc(...@@ -719,12 +725,13 @@ pub fn updateFunc(
719pub fn updateDecl(725pub fn updateDecl(
720 self: *ZigObject,726 self: *ZigObject,
721 macho_file: *MachO,727 macho_file: *MachO,
722 mod: *Module,728 pt: Zcu.PerThread,
723 decl_index: InternPool.DeclIndex,729 decl_index: InternPool.DeclIndex,
724) link.File.UpdateDeclError!void {730) link.File.UpdateDeclError!void {
725 const tracy = trace(@src());731 const tracy = trace(@src());
726 defer tracy.end();732 defer tracy.end();
727733
734 const mod = pt.zcu;
728 const decl = mod.declPtr(decl_index);735 const decl = mod.declPtr(decl_index);
729736
730 if (decl.val.getExternFunc(mod)) |_| {737 if (decl.val.getExternFunc(mod)) |_| {
...@@ -749,12 +756,12 @@ pub fn updateDecl(...@@ -749,12 +756,12 @@ pub fn updateDecl(
749 var code_buffer = std.ArrayList(u8).init(gpa);756 var code_buffer = std.ArrayList(u8).init(gpa);
750 defer code_buffer.deinit();757 defer code_buffer.deinit();
751758
752 var decl_state: ?Dwarf.DeclState = if (self.dwarf) |*dw| try dw.initDeclState(mod, decl_index) else null;759 var decl_state: ?Dwarf.DeclState = if (self.dwarf) |*dw| try dw.initDeclState(pt, decl_index) else null;
753 defer if (decl_state) |*ds| ds.deinit();760 defer if (decl_state) |*ds| ds.deinit();
754761
755 const decl_val = if (decl.val.getVariable(mod)) |variable| Value.fromInterned(variable.init) else decl.val;762 const decl_val = if (decl.val.getVariable(mod)) |variable| Value.fromInterned(variable.init) else decl.val;
756 const dio: codegen.DebugInfoOutput = if (decl_state) |*ds| .{ .dwarf = ds } else .none;763 const dio: codegen.DebugInfoOutput = if (decl_state) |*ds| .{ .dwarf = ds } else .none;
757 const res = try codegen.generateSymbol(&macho_file.base, decl.navSrcLoc(mod), decl_val, &code_buffer, dio, .{764 const res = try codegen.generateSymbol(&macho_file.base, pt, decl.navSrcLoc(mod), decl_val, &code_buffer, dio, .{
758 .parent_atom_index = sym_index,765 .parent_atom_index = sym_index,
759 });766 });
760767
...@@ -772,15 +779,15 @@ pub fn updateDecl(...@@ -772,15 +779,15 @@ pub fn updateDecl(
772 else => false,779 else => false,
773 };780 };
774 if (is_threadlocal) {781 if (is_threadlocal) {
775 try self.updateTlv(macho_file, decl_index, sym_index, sect_index, code);782 try self.updateTlv(macho_file, pt, decl_index, sym_index, sect_index, code);
776 } else {783 } else {
777 try self.updateDeclCode(macho_file, decl_index, sym_index, sect_index, code);784 try self.updateDeclCode(macho_file, pt, decl_index, sym_index, sect_index, code);
778 }785 }
779786
780 if (decl_state) |*ds| {787 if (decl_state) |*ds| {
781 const sym = macho_file.getSymbol(sym_index);788 const sym = macho_file.getSymbol(sym_index);
782 try self.dwarf.?.commitDeclState(789 try self.dwarf.?.commitDeclState(
783 mod,790 pt,
784 decl_index,791 decl_index,
785 sym.getAddress(.{}, macho_file),792 sym.getAddress(.{}, macho_file),
786 sym.getAtom(macho_file).?.size,793 sym.getAtom(macho_file).?.size,
...@@ -794,19 +801,20 @@ pub fn updateDecl(...@@ -794,19 +801,20 @@ pub fn updateDecl(
794fn updateDeclCode(801fn updateDeclCode(
795 self: *ZigObject,802 self: *ZigObject,
796 macho_file: *MachO,803 macho_file: *MachO,
804 pt: Zcu.PerThread,
797 decl_index: InternPool.DeclIndex,805 decl_index: InternPool.DeclIndex,
798 sym_index: Symbol.Index,806 sym_index: Symbol.Index,
799 sect_index: u8,807 sect_index: u8,
800 code: []const u8,808 code: []const u8,
801) !void {809) !void {
802 const gpa = macho_file.base.comp.gpa;810 const gpa = macho_file.base.comp.gpa;
803 const mod = macho_file.base.comp.module.?;811 const mod = pt.zcu;
804 const decl = mod.declPtr(decl_index);812 const decl = mod.declPtr(decl_index);
805 const decl_name = try decl.fullyQualifiedName(mod);813 const decl_name = try decl.fullyQualifiedName(pt);
806814
807 log.debug("updateDeclCode {}{*}", .{ decl_name.fmt(&mod.intern_pool), decl });815 log.debug("updateDeclCode {}{*}", .{ decl_name.fmt(&mod.intern_pool), decl });
808816
809 const required_alignment = decl.getAlignment(mod);817 const required_alignment = decl.getAlignment(pt);
810818
811 const sect = &macho_file.sections.items(.header)[sect_index];819 const sect = &macho_file.sections.items(.header)[sect_index];
812 const sym = macho_file.getSymbol(sym_index);820 const sym = macho_file.getSymbol(sym_index);
...@@ -879,19 +887,19 @@ fn updateDeclCode(...@@ -879,19 +887,19 @@ fn updateDeclCode(
879fn updateTlv(887fn updateTlv(
880 self: *ZigObject,888 self: *ZigObject,
881 macho_file: *MachO,889 macho_file: *MachO,
890 pt: Zcu.PerThread,
882 decl_index: InternPool.DeclIndex,891 decl_index: InternPool.DeclIndex,
883 sym_index: Symbol.Index,892 sym_index: Symbol.Index,
884 sect_index: u8,893 sect_index: u8,
885 code: []const u8,894 code: []const u8,
886) !void {895) !void {
887 const mod = macho_file.base.comp.module.?;896 const decl = pt.zcu.declPtr(decl_index);
888 const decl = mod.declPtr(decl_index);897 const decl_name = try decl.fullyQualifiedName(pt);
889 const decl_name = try decl.fullyQualifiedName(mod);
890898
891 log.debug("updateTlv {} ({*})", .{ decl_name.fmt(&mod.intern_pool), decl });899 log.debug("updateTlv {} ({*})", .{ decl_name.fmt(&pt.zcu.intern_pool), decl });
892900
893 const decl_name_slice = decl_name.toSlice(&mod.intern_pool);901 const decl_name_slice = decl_name.toSlice(&pt.zcu.intern_pool);
894 const required_alignment = decl.getAlignment(mod);902 const required_alignment = decl.getAlignment(pt);
895903
896 // 1. Lower TLV initializer904 // 1. Lower TLV initializer
897 const init_sym_index = try self.createTlvInitializer(905 const init_sym_index = try self.createTlvInitializer(
...@@ -1079,26 +1087,28 @@ fn getDeclOutputSection(...@@ -1079,26 +1087,28 @@ fn getDeclOutputSection(
1079pub fn lowerUnnamedConst(1087pub fn lowerUnnamedConst(
1080 self: *ZigObject,1088 self: *ZigObject,
1081 macho_file: *MachO,1089 macho_file: *MachO,
1090 pt: Zcu.PerThread,
1082 val: Value,1091 val: Value,
1083 decl_index: InternPool.DeclIndex,1092 decl_index: InternPool.DeclIndex,
1084) !u32 {1093) !u32 {
1085 const gpa = macho_file.base.comp.gpa;1094 const mod = pt.zcu;
1086 const mod = macho_file.base.comp.module.?;1095 const gpa = mod.gpa;
1087 const gop = try self.unnamed_consts.getOrPut(gpa, decl_index);1096 const gop = try self.unnamed_consts.getOrPut(gpa, decl_index);
1088 if (!gop.found_existing) {1097 if (!gop.found_existing) {
1089 gop.value_ptr.* = .{};1098 gop.value_ptr.* = .{};
1090 }1099 }
1091 const unnamed_consts = gop.value_ptr;1100 const unnamed_consts = gop.value_ptr;
1092 const decl = mod.declPtr(decl_index);1101 const decl = mod.declPtr(decl_index);
1093 const decl_name = try decl.fullyQualifiedName(mod);1102 const decl_name = try decl.fullyQualifiedName(pt);
1094 const index = unnamed_consts.items.len;1103 const index = unnamed_consts.items.len;
1095 const name = try std.fmt.allocPrint(gpa, "__unnamed_{}_{d}", .{ decl_name.fmt(&mod.intern_pool), index });1104 const name = try std.fmt.allocPrint(gpa, "__unnamed_{}_{d}", .{ decl_name.fmt(&mod.intern_pool), index });
1096 defer gpa.free(name);1105 defer gpa.free(name);
1097 const sym_index = switch (try self.lowerConst(1106 const sym_index = switch (try self.lowerConst(
1098 macho_file,1107 macho_file,
1108 pt,
1099 name,1109 name,
1100 val,1110 val,
1101 val.typeOf(mod).abiAlignment(mod),1111 val.typeOf(mod).abiAlignment(pt),
1102 macho_file.zig_const_sect_index.?,1112 macho_file.zig_const_sect_index.?,
1103 decl.navSrcLoc(mod),1113 decl.navSrcLoc(mod),
1104 )) {1114 )) {
...@@ -1123,6 +1133,7 @@ const LowerConstResult = union(enum) {...@@ -1123,6 +1133,7 @@ const LowerConstResult = union(enum) {
1123fn lowerConst(1133fn lowerConst(
1124 self: *ZigObject,1134 self: *ZigObject,
1125 macho_file: *MachO,1135 macho_file: *MachO,
1136 pt: Zcu.PerThread,
1126 name: []const u8,1137 name: []const u8,
1127 val: Value,1138 val: Value,
1128 required_alignment: Atom.Alignment,1139 required_alignment: Atom.Alignment,
...@@ -1136,7 +1147,7 @@ fn lowerConst(...@@ -1136,7 +1147,7 @@ fn lowerConst(
11361147
1137 const sym_index = try self.addAtom(macho_file);1148 const sym_index = try self.addAtom(macho_file);
11381149
1139 const res = try codegen.generateSymbol(&macho_file.base, src_loc, val, &code_buffer, .{1150 const res = try codegen.generateSymbol(&macho_file.base, pt, src_loc, val, &code_buffer, .{
1140 .none = {},1151 .none = {},
1141 }, .{1152 }, .{
1142 .parent_atom_index = sym_index,1153 .parent_atom_index = sym_index,
...@@ -1181,13 +1192,14 @@ fn lowerConst(...@@ -1181,13 +1192,14 @@ fn lowerConst(
1181pub fn updateExports(1192pub fn updateExports(
1182 self: *ZigObject,1193 self: *ZigObject,
1183 macho_file: *MachO,1194 macho_file: *MachO,
1184 mod: *Module,1195 pt: Zcu.PerThread,
1185 exported: Module.Exported,1196 exported: Module.Exported,
1186 export_indices: []const u32,1197 export_indices: []const u32,
1187) link.File.UpdateExportsError!void {1198) link.File.UpdateExportsError!void {
1188 const tracy = trace(@src());1199 const tracy = trace(@src());
1189 defer tracy.end();1200 defer tracy.end();
11901201
1202 const mod = pt.zcu;
1191 const gpa = macho_file.base.comp.gpa;1203 const gpa = macho_file.base.comp.gpa;
1192 const metadata = switch (exported) {1204 const metadata = switch (exported) {
1193 .decl_index => |decl_index| blk: {1205 .decl_index => |decl_index| blk: {
...@@ -1196,7 +1208,7 @@ pub fn updateExports(...@@ -1196,7 +1208,7 @@ pub fn updateExports(
1196 },1208 },
1197 .value => |value| self.anon_decls.getPtr(value) orelse blk: {1209 .value => |value| self.anon_decls.getPtr(value) orelse blk: {
1198 const first_exp = mod.all_exports.items[export_indices[0]];1210 const first_exp = mod.all_exports.items[export_indices[0]];
1199 const res = try self.lowerAnonDecl(macho_file, value, .none, first_exp.src);1211 const res = try self.lowerAnonDecl(macho_file, pt, value, .none, first_exp.src);
1200 switch (res) {1212 switch (res) {
1201 .ok => {},1213 .ok => {},
1202 .fail => |em| {1214 .fail => |em| {
...@@ -1272,6 +1284,7 @@ pub fn updateExports(...@@ -1272,6 +1284,7 @@ pub fn updateExports(
1272fn updateLazySymbol(1284fn updateLazySymbol(
1273 self: *ZigObject,1285 self: *ZigObject,
1274 macho_file: *MachO,1286 macho_file: *MachO,
1287 pt: Zcu.PerThread,
1275 lazy_sym: link.File.LazySymbol,1288 lazy_sym: link.File.LazySymbol,
1276 symbol_index: Symbol.Index,1289 symbol_index: Symbol.Index,
1277) !void {1290) !void {
...@@ -1285,7 +1298,7 @@ fn updateLazySymbol(...@@ -1285,7 +1298,7 @@ fn updateLazySymbol(
1285 const name_str_index = blk: {1298 const name_str_index = blk: {
1286 const name = try std.fmt.allocPrint(gpa, "__lazy_{s}_{}", .{1299 const name = try std.fmt.allocPrint(gpa, "__lazy_{s}_{}", .{
1287 @tagName(lazy_sym.kind),1300 @tagName(lazy_sym.kind),
1288 lazy_sym.ty.fmt(mod),1301 lazy_sym.ty.fmt(pt),
1289 });1302 });
1290 defer gpa.free(name);1303 defer gpa.free(name);
1291 break :blk try self.strtab.insert(gpa, name);1304 break :blk try self.strtab.insert(gpa, name);
...@@ -1294,6 +1307,7 @@ fn updateLazySymbol(...@@ -1294,6 +1307,7 @@ fn updateLazySymbol(
1294 const src = lazy_sym.ty.srcLocOrNull(mod) orelse Module.LazySrcLoc.unneeded;1307 const src = lazy_sym.ty.srcLocOrNull(mod) orelse Module.LazySrcLoc.unneeded;
1295 const res = try codegen.generateLazySymbol(1308 const res = try codegen.generateLazySymbol(
1296 &macho_file.base,1309 &macho_file.base,
1310 pt,
1297 src,1311 src,
1298 lazy_sym,1312 lazy_sym,
1299 &required_alignment,1313 &required_alignment,
...@@ -1348,9 +1362,9 @@ fn updateLazySymbol(...@@ -1348,9 +1362,9 @@ fn updateLazySymbol(
1348}1362}
13491363
1350/// Must be called only after a successful call to `updateDecl`.1364/// Must be called only after a successful call to `updateDecl`.
1351pub fn updateDeclLineNumber(self: *ZigObject, mod: *Module, decl_index: InternPool.DeclIndex) !void {1365pub fn updateDeclLineNumber(self: *ZigObject, pt: Zcu.PerThread, decl_index: InternPool.DeclIndex) !void {
1352 if (self.dwarf) |*dw| {1366 if (self.dwarf) |*dw| {
1353 try dw.updateDeclLineNumber(mod, decl_index);1367 try dw.updateDeclLineNumber(pt.zcu, decl_index);
1354 }1368 }
1355}1369}
13561370
...@@ -1431,10 +1445,11 @@ pub fn getOrCreateMetadataForDecl(...@@ -1431,10 +1445,11 @@ pub fn getOrCreateMetadataForDecl(
1431pub fn getOrCreateMetadataForLazySymbol(1445pub fn getOrCreateMetadataForLazySymbol(
1432 self: *ZigObject,1446 self: *ZigObject,
1433 macho_file: *MachO,1447 macho_file: *MachO,
1448 pt: Zcu.PerThread,
1434 lazy_sym: link.File.LazySymbol,1449 lazy_sym: link.File.LazySymbol,
1435) !Symbol.Index {1450) !Symbol.Index {
1436 const gpa = macho_file.base.comp.gpa;1451 const mod = pt.zcu;
1437 const mod = macho_file.base.comp.module.?;1452 const gpa = mod.gpa;
1438 const gop = try self.lazy_syms.getOrPut(gpa, lazy_sym.getDecl(mod));1453 const gop = try self.lazy_syms.getOrPut(gpa, lazy_sym.getDecl(mod));
1439 errdefer _ = if (!gop.found_existing) self.lazy_syms.pop();1454 errdefer _ = if (!gop.found_existing) self.lazy_syms.pop();
1440 if (!gop.found_existing) gop.value_ptr.* = .{};1455 if (!gop.found_existing) gop.value_ptr.* = .{};
...@@ -1464,7 +1479,7 @@ pub fn getOrCreateMetadataForLazySymbol(...@@ -1464,7 +1479,7 @@ pub fn getOrCreateMetadataForLazySymbol(
1464 metadata.state.* = .pending_flush;1479 metadata.state.* = .pending_flush;
1465 const symbol_index = metadata.symbol_index.*;1480 const symbol_index = metadata.symbol_index.*;
1466 // anyerror needs to be deferred until flushModule1481 // anyerror needs to be deferred until flushModule
1467 if (lazy_sym.getDecl(mod) != .none) try self.updateLazySymbol(macho_file, lazy_sym, symbol_index);1482 if (lazy_sym.getDecl(mod) != .none) try self.updateLazySymbol(macho_file, pt, lazy_sym, symbol_index);
1468 return symbol_index;1483 return symbol_index;
1469}1484}
14701485
src/link/NvPtx.zig+11-12
...@@ -13,8 +13,6 @@ const assert = std.debug.assert;...@@ -13,8 +13,6 @@ const assert = std.debug.assert;
13const log = std.log.scoped(.link);13const log = std.log.scoped(.link);
1414
15const Zcu = @import("../Zcu.zig");15const Zcu = @import("../Zcu.zig");
16/// Deprecated.
17const Module = Zcu;
18const InternPool = @import("../InternPool.zig");16const InternPool = @import("../InternPool.zig");
19const Compilation = @import("../Compilation.zig");17const Compilation = @import("../Compilation.zig");
20const link = @import("../link.zig");18const link = @import("../link.zig");
...@@ -84,35 +82,35 @@ pub fn deinit(self: *NvPtx) void {...@@ -84,35 +82,35 @@ pub fn deinit(self: *NvPtx) void {
84 self.llvm_object.deinit();82 self.llvm_object.deinit();
85}83}
8684
87pub fn updateFunc(self: *NvPtx, module: *Module, func_index: InternPool.Index, air: Air, liveness: Liveness) !void {85pub fn updateFunc(self: *NvPtx, pt: Zcu.PerThread, func_index: InternPool.Index, air: Air, liveness: Liveness) !void {
88 try self.llvm_object.updateFunc(module, func_index, air, liveness);86 try self.llvm_object.updateFunc(pt, func_index, air, liveness);
89}87}
9088
91pub fn updateDecl(self: *NvPtx, module: *Module, decl_index: InternPool.DeclIndex) !void {89pub fn updateDecl(self: *NvPtx, pt: Zcu.PerThread, decl_index: InternPool.DeclIndex) !void {
92 return self.llvm_object.updateDecl(module, decl_index);90 return self.llvm_object.updateDecl(pt, decl_index);
93}91}
9492
95pub fn updateExports(93pub fn updateExports(
96 self: *NvPtx,94 self: *NvPtx,
97 module: *Module,95 pt: Zcu.PerThread,
98 exported: Module.Exported,96 exported: Zcu.Exported,
99 export_indices: []const u32,97 export_indices: []const u32,
100) !void {98) !void {
101 if (build_options.skip_non_native and builtin.object_format != .nvptx)99 if (build_options.skip_non_native and builtin.object_format != .nvptx)
102 @panic("Attempted to compile for object format that was disabled by build configuration");100 @panic("Attempted to compile for object format that was disabled by build configuration");
103101
104 return self.llvm_object.updateExports(module, exported, export_indices);102 return self.llvm_object.updateExports(pt, exported, export_indices);
105}103}
106104
107pub fn freeDecl(self: *NvPtx, decl_index: InternPool.DeclIndex) void {105pub fn freeDecl(self: *NvPtx, decl_index: InternPool.DeclIndex) void {
108 return self.llvm_object.freeDecl(decl_index);106 return self.llvm_object.freeDecl(decl_index);
109}107}
110108
111pub fn flush(self: *NvPtx, arena: Allocator, prog_node: std.Progress.Node) link.File.FlushError!void {109pub fn flush(self: *NvPtx, arena: Allocator, tid: Zcu.PerThread.Id, prog_node: std.Progress.Node) link.File.FlushError!void {
112 return self.flushModule(arena, prog_node);110 return self.flushModule(arena, tid, prog_node);
113}111}
114112
115pub fn flushModule(self: *NvPtx, arena: Allocator, prog_node: std.Progress.Node) link.File.FlushError!void {113pub fn flushModule(self: *NvPtx, arena: Allocator, tid: Zcu.PerThread.Id, prog_node: std.Progress.Node) link.File.FlushError!void {
116 if (build_options.skip_non_native)114 if (build_options.skip_non_native)
117 @panic("Attempted to compile for architecture that was disabled by build configuration");115 @panic("Attempted to compile for architecture that was disabled by build configuration");
118116
...@@ -121,5 +119,6 @@ pub fn flushModule(self: *NvPtx, arena: Allocator, prog_node: std.Progress.Node)...@@ -121,5 +119,6 @@ pub fn flushModule(self: *NvPtx, arena: Allocator, prog_node: std.Progress.Node)
121 _ = arena;119 _ = arena;
122 _ = self;120 _ = self;
123 _ = prog_node;121 _ = prog_node;
122 _ = tid;
124 @panic("TODO: rewrite the NvPtx.flushModule function");123 @panic("TODO: rewrite the NvPtx.flushModule function");
125}124}
src/link/Plan9.zig+53-46
...@@ -4,8 +4,6 @@...@@ -4,8 +4,6 @@
4const Plan9 = @This();4const Plan9 = @This();
5const link = @import("../link.zig");5const link = @import("../link.zig");
6const Zcu = @import("../Zcu.zig");6const Zcu = @import("../Zcu.zig");
7/// Deprecated.
8const Module = Zcu;
9const InternPool = @import("../InternPool.zig");7const InternPool = @import("../InternPool.zig");
10const Compilation = @import("../Compilation.zig");8const Compilation = @import("../Compilation.zig");
11const aout = @import("Plan9/aout.zig");9const aout = @import("Plan9/aout.zig");
...@@ -56,7 +54,7 @@ path_arena: std.heap.ArenaAllocator,...@@ -56,7 +54,7 @@ path_arena: std.heap.ArenaAllocator,
56/// of the function to know what file it came from.54/// of the function to know what file it came from.
57/// If we group the decls by file, it makes it really easy to do this (put the symbol in the correct place)55/// If we group the decls by file, it makes it really easy to do this (put the symbol in the correct place)
58fn_decl_table: std.AutoArrayHashMapUnmanaged(56fn_decl_table: std.AutoArrayHashMapUnmanaged(
59 *Module.File,57 *Zcu.File,
60 struct { sym_index: u32, functions: std.AutoArrayHashMapUnmanaged(InternPool.DeclIndex, FnDeclOutput) = .{} },58 struct { sym_index: u32, functions: std.AutoArrayHashMapUnmanaged(InternPool.DeclIndex, FnDeclOutput) = .{} },
61) = .{},59) = .{},
62/// the code is modified when relocated, so that is why it is mutable60/// the code is modified when relocated, so that is why it is mutable
...@@ -411,12 +409,13 @@ fn addPathComponents(self: *Plan9, path: []const u8, a: *std.ArrayList(u8)) !voi...@@ -411,12 +409,13 @@ fn addPathComponents(self: *Plan9, path: []const u8, a: *std.ArrayList(u8)) !voi
411 }409 }
412}410}
413411
414pub fn updateFunc(self: *Plan9, mod: *Module, func_index: InternPool.Index, air: Air, liveness: Liveness) !void {412pub fn updateFunc(self: *Plan9, pt: Zcu.PerThread, func_index: InternPool.Index, air: Air, liveness: Liveness) !void {
415 if (build_options.skip_non_native and builtin.object_format != .plan9) {413 if (build_options.skip_non_native and builtin.object_format != .plan9) {
416 @panic("Attempted to compile for object format that was disabled by build configuration");414 @panic("Attempted to compile for object format that was disabled by build configuration");
417 }415 }
418416
419 const gpa = self.base.comp.gpa;417 const mod = pt.zcu;
418 const gpa = mod.gpa;
420 const target = self.base.comp.root_mod.resolved_target.result;419 const target = self.base.comp.root_mod.resolved_target.result;
421 const func = mod.funcInfo(func_index);420 const func = mod.funcInfo(func_index);
422 const decl_index = func.owner_decl;421 const decl_index = func.owner_decl;
...@@ -439,6 +438,7 @@ pub fn updateFunc(self: *Plan9, mod: *Module, func_index: InternPool.Index, air:...@@ -439,6 +438,7 @@ pub fn updateFunc(self: *Plan9, mod: *Module, func_index: InternPool.Index, air:
439438
440 const res = try codegen.generateFunction(439 const res = try codegen.generateFunction(
441 &self.base,440 &self.base,
441 pt,
442 decl.navSrcLoc(mod),442 decl.navSrcLoc(mod),
443 func_index,443 func_index,
444 air,444 air,
...@@ -468,13 +468,13 @@ pub fn updateFunc(self: *Plan9, mod: *Module, func_index: InternPool.Index, air:...@@ -468,13 +468,13 @@ pub fn updateFunc(self: *Plan9, mod: *Module, func_index: InternPool.Index, air:
468 return self.updateFinish(decl_index);468 return self.updateFinish(decl_index);
469}469}
470470
471pub fn lowerUnnamedConst(self: *Plan9, val: Value, decl_index: InternPool.DeclIndex) !u32 {471pub fn lowerUnnamedConst(self: *Plan9, pt: Zcu.PerThread, val: Value, decl_index: InternPool.DeclIndex) !u32 {
472 const gpa = self.base.comp.gpa;472 const mod = pt.zcu;
473 const gpa = mod.gpa;
473 _ = try self.seeDecl(decl_index);474 _ = try self.seeDecl(decl_index);
474 var code_buffer = std.ArrayList(u8).init(gpa);475 var code_buffer = std.ArrayList(u8).init(gpa);
475 defer code_buffer.deinit();476 defer code_buffer.deinit();
476477
477 const mod = self.base.comp.module.?;
478 const decl = mod.declPtr(decl_index);478 const decl = mod.declPtr(decl_index);
479479
480 const gop = try self.unnamed_const_atoms.getOrPut(gpa, decl_index);480 const gop = try self.unnamed_const_atoms.getOrPut(gpa, decl_index);
...@@ -483,7 +483,7 @@ pub fn lowerUnnamedConst(self: *Plan9, val: Value, decl_index: InternPool.DeclIn...@@ -483,7 +483,7 @@ pub fn lowerUnnamedConst(self: *Plan9, val: Value, decl_index: InternPool.DeclIn
483 }483 }
484 const unnamed_consts = gop.value_ptr;484 const unnamed_consts = gop.value_ptr;
485485
486 const decl_name = try decl.fullyQualifiedName(mod);486 const decl_name = try decl.fullyQualifiedName(pt);
487487
488 const index = unnamed_consts.items.len;488 const index = unnamed_consts.items.len;
489 // name is freed when the unnamed const is freed489 // name is freed when the unnamed const is freed
...@@ -505,7 +505,7 @@ pub fn lowerUnnamedConst(self: *Plan9, val: Value, decl_index: InternPool.DeclIn...@@ -505,7 +505,7 @@ pub fn lowerUnnamedConst(self: *Plan9, val: Value, decl_index: InternPool.DeclIn
505 };505 };
506 self.syms.items[info.sym_index.?] = sym;506 self.syms.items[info.sym_index.?] = sym;
507507
508 const res = try codegen.generateSymbol(&self.base, decl.navSrcLoc(mod), val, &code_buffer, .{508 const res = try codegen.generateSymbol(&self.base, pt, decl.navSrcLoc(mod), val, &code_buffer, .{
509 .none = {},509 .none = {},
510 }, .{510 }, .{
511 .parent_atom_index = new_atom_idx,511 .parent_atom_index = new_atom_idx,
...@@ -530,8 +530,9 @@ pub fn lowerUnnamedConst(self: *Plan9, val: Value, decl_index: InternPool.DeclIn...@@ -530,8 +530,9 @@ pub fn lowerUnnamedConst(self: *Plan9, val: Value, decl_index: InternPool.DeclIn
530 return new_atom_idx;530 return new_atom_idx;
531}531}
532532
533pub fn updateDecl(self: *Plan9, mod: *Module, decl_index: InternPool.DeclIndex) !void {533pub fn updateDecl(self: *Plan9, pt: Zcu.PerThread, decl_index: InternPool.DeclIndex) !void {
534 const gpa = self.base.comp.gpa;534 const gpa = self.base.comp.gpa;
535 const mod = pt.zcu;
535 const decl = mod.declPtr(decl_index);536 const decl = mod.declPtr(decl_index);
536537
537 if (decl.isExtern(mod)) {538 if (decl.isExtern(mod)) {
...@@ -544,7 +545,7 @@ pub fn updateDecl(self: *Plan9, mod: *Module, decl_index: InternPool.DeclIndex)...@@ -544,7 +545,7 @@ pub fn updateDecl(self: *Plan9, mod: *Module, decl_index: InternPool.DeclIndex)
544 defer code_buffer.deinit();545 defer code_buffer.deinit();
545 const decl_val = if (decl.val.getVariable(mod)) |variable| Value.fromInterned(variable.init) else decl.val;546 const decl_val = if (decl.val.getVariable(mod)) |variable| Value.fromInterned(variable.init) else decl.val;
546 // TODO we need the symbol index for symbol in the table of locals for the containing atom547 // TODO we need the symbol index for symbol in the table of locals for the containing atom
547 const res = try codegen.generateSymbol(&self.base, decl.navSrcLoc(mod), decl_val, &code_buffer, .{ .none = {} }, .{548 const res = try codegen.generateSymbol(&self.base, pt, decl.navSrcLoc(mod), decl_val, &code_buffer, .{ .none = {} }, .{
548 .parent_atom_index = @as(Atom.Index, @intCast(atom_idx)),549 .parent_atom_index = @as(Atom.Index, @intCast(atom_idx)),
549 });550 });
550 const code = switch (res) {551 const code = switch (res) {
...@@ -610,7 +611,7 @@ fn allocateGotIndex(self: *Plan9) usize {...@@ -610,7 +611,7 @@ fn allocateGotIndex(self: *Plan9) usize {
610 }611 }
611}612}
612613
613pub fn flush(self: *Plan9, arena: Allocator, prog_node: std.Progress.Node) link.File.FlushError!void {614pub fn flush(self: *Plan9, arena: Allocator, tid: Zcu.PerThread.Id, prog_node: std.Progress.Node) link.File.FlushError!void {
614 const comp = self.base.comp;615 const comp = self.base.comp;
615 const use_lld = build_options.have_llvm and comp.config.use_lld;616 const use_lld = build_options.have_llvm and comp.config.use_lld;
616 assert(!use_lld);617 assert(!use_lld);
...@@ -621,7 +622,7 @@ pub fn flush(self: *Plan9, arena: Allocator, prog_node: std.Progress.Node) link....@@ -621,7 +622,7 @@ pub fn flush(self: *Plan9, arena: Allocator, prog_node: std.Progress.Node) link.
621 .Obj => return error.TODOImplementPlan9Objs,622 .Obj => return error.TODOImplementPlan9Objs,
622 .Lib => return error.TODOImplementWritingLibFiles,623 .Lib => return error.TODOImplementWritingLibFiles,
623 }624 }
624 return self.flushModule(arena, prog_node);625 return self.flushModule(arena, tid, prog_node);
625}626}
626627
627pub fn changeLine(l: *std.ArrayList(u8), delta_line: i32) !void {628pub fn changeLine(l: *std.ArrayList(u8), delta_line: i32) !void {
...@@ -669,20 +670,20 @@ fn atomCount(self: *Plan9) usize {...@@ -669,20 +670,20 @@ fn atomCount(self: *Plan9) usize {
669 return data_decl_count + fn_decl_count + unnamed_const_count + lazy_atom_count + extern_atom_count + anon_atom_count;670 return data_decl_count + fn_decl_count + unnamed_const_count + lazy_atom_count + extern_atom_count + anon_atom_count;
670}671}
671672
672pub fn flushModule(self: *Plan9, arena: Allocator, prog_node: std.Progress.Node) link.File.FlushError!void {673pub fn flushModule(self: *Plan9, arena: Allocator, tid: Zcu.PerThread.Id, prog_node: std.Progress.Node) link.File.FlushError!void {
673 if (build_options.skip_non_native and builtin.object_format != .plan9) {674 if (build_options.skip_non_native and builtin.object_format != .plan9) {
674 @panic("Attempted to compile for object format that was disabled by build configuration");675 @panic("Attempted to compile for object format that was disabled by build configuration");
675 }676 }
676677
678 const tracy = trace(@src());
679 defer tracy.end();
680
677 _ = arena; // Has the same lifetime as the call to Compilation.update.681 _ = arena; // Has the same lifetime as the call to Compilation.update.
678682
679 const comp = self.base.comp;683 const comp = self.base.comp;
680 const gpa = comp.gpa;684 const gpa = comp.gpa;
681 const target = comp.root_mod.resolved_target.result;685 const target = comp.root_mod.resolved_target.result;
682686
683 const tracy = trace(@src());
684 defer tracy.end();
685
686 const sub_prog_node = prog_node.start("Flush Module", 0);687 const sub_prog_node = prog_node.start("Flush Module", 0);
687 defer sub_prog_node.end();688 defer sub_prog_node.end();
688689
...@@ -690,21 +691,26 @@ pub fn flushModule(self: *Plan9, arena: Allocator, prog_node: std.Progress.Node)...@@ -690,21 +691,26 @@ pub fn flushModule(self: *Plan9, arena: Allocator, prog_node: std.Progress.Node)
690691
691 defer assert(self.hdr.entry != 0x0);692 defer assert(self.hdr.entry != 0x0);
692693
693 const mod = self.base.comp.module orelse return error.LinkingWithoutZigSourceUnimplemented;694 const pt: Zcu.PerThread = .{
695 .zcu = self.base.comp.module orelse return error.LinkingWithoutZigSourceUnimplemented,
696 .tid = tid,
697 };
694698
695 // finish up the lazy syms699 // finish up the lazy syms
696 if (self.lazy_syms.getPtr(.none)) |metadata| {700 if (self.lazy_syms.getPtr(.none)) |metadata| {
697 // Most lazy symbols can be updated on first use, but701 // Most lazy symbols can be updated on first use, but
698 // anyerror needs to wait for everything to be flushed.702 // anyerror needs to wait for everything to be flushed.
699 if (metadata.text_state != .unused) self.updateLazySymbolAtom(703 if (metadata.text_state != .unused) self.updateLazySymbolAtom(
700 File.LazySymbol.initDecl(.code, null, mod),704 pt,
705 File.LazySymbol.initDecl(.code, null, pt.zcu),
701 metadata.text_atom,706 metadata.text_atom,
702 ) catch |err| return switch (err) {707 ) catch |err| return switch (err) {
703 error.CodegenFail => error.FlushFailure,708 error.CodegenFail => error.FlushFailure,
704 else => |e| e,709 else => |e| e,
705 };710 };
706 if (metadata.rodata_state != .unused) self.updateLazySymbolAtom(711 if (metadata.rodata_state != .unused) self.updateLazySymbolAtom(
707 File.LazySymbol.initDecl(.const_data, null, mod),712 pt,
713 File.LazySymbol.initDecl(.const_data, null, pt.zcu),
708 metadata.rodata_atom,714 metadata.rodata_atom,
709 ) catch |err| return switch (err) {715 ) catch |err| return switch (err) {
710 error.CodegenFail => error.FlushFailure,716 error.CodegenFail => error.FlushFailure,
...@@ -747,7 +753,7 @@ pub fn flushModule(self: *Plan9, arena: Allocator, prog_node: std.Progress.Node)...@@ -747,7 +753,7 @@ pub fn flushModule(self: *Plan9, arena: Allocator, prog_node: std.Progress.Node)
747 var it = fentry.value_ptr.functions.iterator();753 var it = fentry.value_ptr.functions.iterator();
748 while (it.next()) |entry| {754 while (it.next()) |entry| {
749 const decl_index = entry.key_ptr.*;755 const decl_index = entry.key_ptr.*;
750 const decl = mod.declPtr(decl_index);756 const decl = pt.zcu.declPtr(decl_index);
751 const atom = self.getAtomPtr(self.decls.get(decl_index).?.index);757 const atom = self.getAtomPtr(self.decls.get(decl_index).?.index);
752 const out = entry.value_ptr.*;758 const out = entry.value_ptr.*;
753 {759 {
...@@ -767,7 +773,7 @@ pub fn flushModule(self: *Plan9, arena: Allocator, prog_node: std.Progress.Node)...@@ -767,7 +773,7 @@ pub fn flushModule(self: *Plan9, arena: Allocator, prog_node: std.Progress.Node)
767 const off = self.getAddr(text_i, .t);773 const off = self.getAddr(text_i, .t);
768 text_i += out.code.len;774 text_i += out.code.len;
769 atom.offset = off;775 atom.offset = off;
770 log.debug("write text decl {*} ({}), lines {d} to {d}.;__GOT+0x{x} vaddr: 0x{x}", .{ decl, decl.name.fmt(&mod.intern_pool), out.start_line + 1, out.end_line, atom.got_index.? * 8, off });776 log.debug("write text decl {*} ({}), lines {d} to {d}.;__GOT+0x{x} vaddr: 0x{x}", .{ decl, decl.name.fmt(&pt.zcu.intern_pool), out.start_line + 1, out.end_line, atom.got_index.? * 8, off });
771 if (!self.sixtyfour_bit) {777 if (!self.sixtyfour_bit) {
772 mem.writeInt(u32, got_table[atom.got_index.? * 4 ..][0..4], @as(u32, @intCast(off)), target.cpu.arch.endian());778 mem.writeInt(u32, got_table[atom.got_index.? * 4 ..][0..4], @as(u32, @intCast(off)), target.cpu.arch.endian());
773 } else {779 } else {
...@@ -775,7 +781,7 @@ pub fn flushModule(self: *Plan9, arena: Allocator, prog_node: std.Progress.Node)...@@ -775,7 +781,7 @@ pub fn flushModule(self: *Plan9, arena: Allocator, prog_node: std.Progress.Node)
775 }781 }
776 self.syms.items[atom.sym_index.?].value = off;782 self.syms.items[atom.sym_index.?].value = off;
777 if (self.decl_exports.get(decl_index)) |export_indices| {783 if (self.decl_exports.get(decl_index)) |export_indices| {
778 try self.addDeclExports(mod, decl_index, export_indices);784 try self.addDeclExports(pt.zcu, decl_index, export_indices);
779 }785 }
780 }786 }
781 }787 }
...@@ -841,7 +847,7 @@ pub fn flushModule(self: *Plan9, arena: Allocator, prog_node: std.Progress.Node)...@@ -841,7 +847,7 @@ pub fn flushModule(self: *Plan9, arena: Allocator, prog_node: std.Progress.Node)
841 }847 }
842 self.syms.items[atom.sym_index.?].value = off;848 self.syms.items[atom.sym_index.?].value = off;
843 if (self.decl_exports.get(decl_index)) |export_indices| {849 if (self.decl_exports.get(decl_index)) |export_indices| {
844 try self.addDeclExports(mod, decl_index, export_indices);850 try self.addDeclExports(pt.zcu, decl_index, export_indices);
845 }851 }
846 }852 }
847 // write the unnamed constants after the other data decls853 // write the unnamed constants after the other data decls
...@@ -1009,7 +1015,7 @@ pub fn flushModule(self: *Plan9, arena: Allocator, prog_node: std.Progress.Node)...@@ -1009,7 +1015,7 @@ pub fn flushModule(self: *Plan9, arena: Allocator, prog_node: std.Progress.Node)
1009}1015}
1010fn addDeclExports(1016fn addDeclExports(
1011 self: *Plan9,1017 self: *Plan9,
1012 mod: *Module,1018 mod: *Zcu,
1013 decl_index: InternPool.DeclIndex,1019 decl_index: InternPool.DeclIndex,
1014 export_indices: []const u32,1020 export_indices: []const u32,
1015) !void {1021) !void {
...@@ -1025,7 +1031,7 @@ fn addDeclExports(...@@ -1025,7 +1031,7 @@ fn addDeclExports(
1025 if (!section_name.eqlSlice(".text", &mod.intern_pool) and1031 if (!section_name.eqlSlice(".text", &mod.intern_pool) and
1026 !section_name.eqlSlice(".data", &mod.intern_pool))1032 !section_name.eqlSlice(".data", &mod.intern_pool))
1027 {1033 {
1028 try mod.failed_exports.put(mod.gpa, export_idx, try Module.ErrorMsg.create(1034 try mod.failed_exports.put(mod.gpa, export_idx, try Zcu.ErrorMsg.create(
1029 gpa,1035 gpa,
1030 mod.declPtr(decl_index).navSrcLoc(mod),1036 mod.declPtr(decl_index).navSrcLoc(mod),
1031 "plan9 does not support extra sections",1037 "plan9 does not support extra sections",
...@@ -1155,8 +1161,8 @@ pub fn seeDecl(self: *Plan9, decl_index: InternPool.DeclIndex) !Atom.Index {...@@ -1155,8 +1161,8 @@ pub fn seeDecl(self: *Plan9, decl_index: InternPool.DeclIndex) !Atom.Index {
11551161
1156pub fn updateExports(1162pub fn updateExports(
1157 self: *Plan9,1163 self: *Plan9,
1158 module: *Module,1164 pt: Zcu.PerThread,
1159 exported: Module.Exported,1165 exported: Zcu.Exported,
1160 export_indices: []const u32,1166 export_indices: []const u32,
1161) !void {1167) !void {
1162 const gpa = self.base.comp.gpa;1168 const gpa = self.base.comp.gpa;
...@@ -1173,11 +1179,11 @@ pub fn updateExports(...@@ -1173,11 +1179,11 @@ pub fn updateExports(
1173 },1179 },
1174 }1180 }
1175 // all proper work is done in flush1181 // all proper work is done in flush
1176 _ = module;1182 _ = pt;
1177}1183}
11781184
1179pub fn getOrCreateAtomForLazySymbol(self: *Plan9, sym: File.LazySymbol) !Atom.Index {1185pub fn getOrCreateAtomForLazySymbol(self: *Plan9, pt: Zcu.PerThread, sym: File.LazySymbol) !Atom.Index {
1180 const gpa = self.base.comp.gpa;1186 const gpa = pt.zcu.gpa;
1181 const gop = try self.lazy_syms.getOrPut(gpa, sym.getDecl(self.base.comp.module.?));1187 const gop = try self.lazy_syms.getOrPut(gpa, sym.getDecl(self.base.comp.module.?));
1182 errdefer _ = if (!gop.found_existing) self.lazy_syms.pop();1188 errdefer _ = if (!gop.found_existing) self.lazy_syms.pop();
11831189
...@@ -1198,14 +1204,13 @@ pub fn getOrCreateAtomForLazySymbol(self: *Plan9, sym: File.LazySymbol) !Atom.In...@@ -1198,14 +1204,13 @@ pub fn getOrCreateAtomForLazySymbol(self: *Plan9, sym: File.LazySymbol) !Atom.In
1198 _ = self.getAtomPtr(atom).getOrCreateOffsetTableEntry(self);1204 _ = self.getAtomPtr(atom).getOrCreateOffsetTableEntry(self);
1199 // anyerror needs to be deferred until flushModule1205 // anyerror needs to be deferred until flushModule
1200 if (sym.getDecl(self.base.comp.module.?) != .none) {1206 if (sym.getDecl(self.base.comp.module.?) != .none) {
1201 try self.updateLazySymbolAtom(sym, atom);1207 try self.updateLazySymbolAtom(pt, sym, atom);
1202 }1208 }
1203 return atom;1209 return atom;
1204}1210}
12051211
1206fn updateLazySymbolAtom(self: *Plan9, sym: File.LazySymbol, atom_index: Atom.Index) !void {1212fn updateLazySymbolAtom(self: *Plan9, pt: Zcu.PerThread, sym: File.LazySymbol, atom_index: Atom.Index) !void {
1207 const gpa = self.base.comp.gpa;1213 const gpa = pt.zcu.gpa;
1208 const mod = self.base.comp.module.?;
12091214
1210 var required_alignment: InternPool.Alignment = .none;1215 var required_alignment: InternPool.Alignment = .none;
1211 var code_buffer = std.ArrayList(u8).init(gpa);1216 var code_buffer = std.ArrayList(u8).init(gpa);
...@@ -1214,7 +1219,7 @@ fn updateLazySymbolAtom(self: *Plan9, sym: File.LazySymbol, atom_index: Atom.Ind...@@ -1214,7 +1219,7 @@ fn updateLazySymbolAtom(self: *Plan9, sym: File.LazySymbol, atom_index: Atom.Ind
1214 // create the symbol for the name1219 // create the symbol for the name
1215 const name = try std.fmt.allocPrint(gpa, "__lazy_{s}_{}", .{1220 const name = try std.fmt.allocPrint(gpa, "__lazy_{s}_{}", .{
1216 @tagName(sym.kind),1221 @tagName(sym.kind),
1217 sym.ty.fmt(mod),1222 sym.ty.fmt(pt),
1218 });1223 });
12191224
1220 const symbol: aout.Sym = .{1225 const symbol: aout.Sym = .{
...@@ -1225,9 +1230,10 @@ fn updateLazySymbolAtom(self: *Plan9, sym: File.LazySymbol, atom_index: Atom.Ind...@@ -1225,9 +1230,10 @@ fn updateLazySymbolAtom(self: *Plan9, sym: File.LazySymbol, atom_index: Atom.Ind
1225 self.syms.items[self.getAtomPtr(atom_index).sym_index.?] = symbol;1230 self.syms.items[self.getAtomPtr(atom_index).sym_index.?] = symbol;
12261231
1227 // generate the code1232 // generate the code
1228 const src = sym.ty.srcLocOrNull(mod) orelse Module.LazySrcLoc.unneeded;1233 const src = sym.ty.srcLocOrNull(pt.zcu) orelse Zcu.LazySrcLoc.unneeded;
1229 const res = try codegen.generateLazySymbol(1234 const res = try codegen.generateLazySymbol(
1230 &self.base,1235 &self.base,
1236 pt,
1231 src,1237 src,
1232 sym,1238 sym,
1233 &required_alignment,1239 &required_alignment,
...@@ -1490,22 +1496,22 @@ pub fn writeSyms(self: *Plan9, buf: *std.ArrayList(u8)) !void {...@@ -1490,22 +1496,22 @@ pub fn writeSyms(self: *Plan9, buf: *std.ArrayList(u8)) !void {
1490}1496}
14911497
1492/// Must be called only after a successful call to `updateDecl`.1498/// Must be called only after a successful call to `updateDecl`.
1493pub fn updateDeclLineNumber(self: *Plan9, mod: *Module, decl_index: InternPool.DeclIndex) !void {1499pub fn updateDeclLineNumber(self: *Plan9, pt: Zcu.PerThread, decl_index: InternPool.DeclIndex) !void {
1494 _ = self;1500 _ = self;
1495 _ = mod;1501 _ = pt;
1496 _ = decl_index;1502 _ = decl_index;
1497}1503}
14981504
1499pub fn getDeclVAddr(1505pub fn getDeclVAddr(
1500 self: *Plan9,1506 self: *Plan9,
1507 pt: Zcu.PerThread,
1501 decl_index: InternPool.DeclIndex,1508 decl_index: InternPool.DeclIndex,
1502 reloc_info: link.File.RelocInfo,1509 reloc_info: link.File.RelocInfo,
1503) !u64 {1510) !u64 {
1504 const mod = self.base.comp.module.?;1511 const ip = &pt.zcu.intern_pool;
1505 const ip = &mod.intern_pool;1512 const decl = pt.zcu.declPtr(decl_index);
1506 const decl = mod.declPtr(decl_index);
1507 log.debug("getDeclVAddr for {}", .{decl.name.fmt(ip)});1513 log.debug("getDeclVAddr for {}", .{decl.name.fmt(ip)});
1508 if (decl.isExtern(mod)) {1514 if (decl.isExtern(pt.zcu)) {
1509 if (decl.name.eqlSlice("etext", ip)) {1515 if (decl.name.eqlSlice("etext", ip)) {
1510 try self.addReloc(reloc_info.parent_atom_index, .{1516 try self.addReloc(reloc_info.parent_atom_index, .{
1511 .target = undefined,1517 .target = undefined,
...@@ -1544,9 +1550,10 @@ pub fn getDeclVAddr(...@@ -1544,9 +1550,10 @@ pub fn getDeclVAddr(
15441550
1545pub fn lowerAnonDecl(1551pub fn lowerAnonDecl(
1546 self: *Plan9,1552 self: *Plan9,
1553 pt: Zcu.PerThread,
1547 decl_val: InternPool.Index,1554 decl_val: InternPool.Index,
1548 explicit_alignment: InternPool.Alignment,1555 explicit_alignment: InternPool.Alignment,
1549 src_loc: Module.LazySrcLoc,1556 src_loc: Zcu.LazySrcLoc,
1550) !codegen.Result {1557) !codegen.Result {
1551 _ = explicit_alignment;1558 _ = explicit_alignment;
1552 // This is basically the same as lowerUnnamedConst.1559 // This is basically the same as lowerUnnamedConst.
...@@ -1569,7 +1576,7 @@ pub fn lowerAnonDecl(...@@ -1569,7 +1576,7 @@ pub fn lowerAnonDecl(
1569 gop.value_ptr.* = index;1576 gop.value_ptr.* = index;
1570 // we need to free name latex1577 // we need to free name latex
1571 var code_buffer = std.ArrayList(u8).init(gpa);1578 var code_buffer = std.ArrayList(u8).init(gpa);
1572 const res = try codegen.generateSymbol(&self.base, src_loc, val, &code_buffer, .{ .none = {} }, .{ .parent_atom_index = index });1579 const res = try codegen.generateSymbol(&self.base, pt, src_loc, val, &code_buffer, .{ .none = {} }, .{ .parent_atom_index = index });
1573 const code = switch (res) {1580 const code = switch (res) {
1574 .ok => code_buffer.items,1581 .ok => code_buffer.items,
1575 .fail => |em| return .{ .fail = em },1582 .fail => |em| return .{ .fail = em },
src/link/SpirV.zig+16-16
...@@ -28,8 +28,6 @@ const assert = std.debug.assert;...@@ -28,8 +28,6 @@ const assert = std.debug.assert;
28const log = std.log.scoped(.link);28const log = std.log.scoped(.link);
2929
30const Zcu = @import("../Zcu.zig");30const Zcu = @import("../Zcu.zig");
31/// Deprecated.
32const Module = Zcu;
33const InternPool = @import("../InternPool.zig");31const InternPool = @import("../InternPool.zig");
34const Compilation = @import("../Compilation.zig");32const Compilation = @import("../Compilation.zig");
35const link = @import("../link.zig");33const link = @import("../link.zig");
...@@ -125,35 +123,36 @@ pub fn deinit(self: *SpirV) void {...@@ -125,35 +123,36 @@ pub fn deinit(self: *SpirV) void {
125 self.object.deinit();123 self.object.deinit();
126}124}
127125
128pub fn updateFunc(self: *SpirV, module: *Module, func_index: InternPool.Index, air: Air, liveness: Liveness) !void {126pub fn updateFunc(self: *SpirV, pt: Zcu.PerThread, func_index: InternPool.Index, air: Air, liveness: Liveness) !void {
129 if (build_options.skip_non_native) {127 if (build_options.skip_non_native) {
130 @panic("Attempted to compile for architecture that was disabled by build configuration");128 @panic("Attempted to compile for architecture that was disabled by build configuration");
131 }129 }
132130
133 const func = module.funcInfo(func_index);131 const func = pt.zcu.funcInfo(func_index);
134 const decl = module.declPtr(func.owner_decl);132 const decl = pt.zcu.declPtr(func.owner_decl);
135 log.debug("lowering function {}", .{decl.name.fmt(&module.intern_pool)});133 log.debug("lowering function {}", .{decl.name.fmt(&pt.zcu.intern_pool)});
136134
137 try self.object.updateFunc(module, func_index, air, liveness);135 try self.object.updateFunc(pt, func_index, air, liveness);
138}136}
139137
140pub fn updateDecl(self: *SpirV, module: *Module, decl_index: InternPool.DeclIndex) !void {138pub fn updateDecl(self: *SpirV, pt: Zcu.PerThread, decl_index: InternPool.DeclIndex) !void {
141 if (build_options.skip_non_native) {139 if (build_options.skip_non_native) {
142 @panic("Attempted to compile for architecture that was disabled by build configuration");140 @panic("Attempted to compile for architecture that was disabled by build configuration");
143 }141 }
144142
145 const decl = module.declPtr(decl_index);143 const decl = pt.zcu.declPtr(decl_index);
146 log.debug("lowering declaration {}", .{decl.name.fmt(&module.intern_pool)});144 log.debug("lowering declaration {}", .{decl.name.fmt(&pt.zcu.intern_pool)});
147145
148 try self.object.updateDecl(module, decl_index);146 try self.object.updateDecl(pt, decl_index);
149}147}
150148
151pub fn updateExports(149pub fn updateExports(
152 self: *SpirV,150 self: *SpirV,
153 mod: *Module,151 pt: Zcu.PerThread,
154 exported: Module.Exported,152 exported: Zcu.Exported,
155 export_indices: []const u32,153 export_indices: []const u32,
156) !void {154) !void {
155 const mod = pt.zcu;
157 const decl_index = switch (exported) {156 const decl_index = switch (exported) {
158 .decl_index => |i| i,157 .decl_index => |i| i,
159 .value => |val| {158 .value => |val| {
...@@ -196,11 +195,11 @@ pub fn freeDecl(self: *SpirV, decl_index: InternPool.DeclIndex) void {...@@ -196,11 +195,11 @@ pub fn freeDecl(self: *SpirV, decl_index: InternPool.DeclIndex) void {
196 _ = decl_index;195 _ = decl_index;
197}196}
198197
199pub fn flush(self: *SpirV, arena: Allocator, prog_node: std.Progress.Node) link.File.FlushError!void {198pub fn flush(self: *SpirV, arena: Allocator, tid: Zcu.PerThread.Id, prog_node: std.Progress.Node) link.File.FlushError!void {
200 return self.flushModule(arena, prog_node);199 return self.flushModule(arena, tid, prog_node);
201}200}
202201
203pub fn flushModule(self: *SpirV, arena: Allocator, prog_node: std.Progress.Node) link.File.FlushError!void {202pub fn flushModule(self: *SpirV, arena: Allocator, tid: Zcu.PerThread.Id, prog_node: std.Progress.Node) link.File.FlushError!void {
204 if (build_options.skip_non_native) {203 if (build_options.skip_non_native) {
205 @panic("Attempted to compile for architecture that was disabled by build configuration");204 @panic("Attempted to compile for architecture that was disabled by build configuration");
206 }205 }
...@@ -216,6 +215,7 @@ pub fn flushModule(self: *SpirV, arena: Allocator, prog_node: std.Progress.Node)...@@ -216,6 +215,7 @@ pub fn flushModule(self: *SpirV, arena: Allocator, prog_node: std.Progress.Node)
216 const comp = self.base.comp;215 const comp = self.base.comp;
217 const gpa = comp.gpa;216 const gpa = comp.gpa;
218 const target = comp.getTarget();217 const target = comp.getTarget();
218 _ = tid;
219219
220 try writeCapabilities(spv, target);220 try writeCapabilities(spv, target);
221 try writeMemoryModel(spv, target);221 try writeMemoryModel(spv, target);
src/link/Wasm.zig+30-30
...@@ -29,8 +29,6 @@ const InternPool = @import("../InternPool.zig");...@@ -29,8 +29,6 @@ const InternPool = @import("../InternPool.zig");
29const Liveness = @import("../Liveness.zig");29const Liveness = @import("../Liveness.zig");
30const LlvmObject = @import("../codegen/llvm.zig").Object;30const LlvmObject = @import("../codegen/llvm.zig").Object;
31const Zcu = @import("../Zcu.zig");31const Zcu = @import("../Zcu.zig");
32/// Deprecated.
33const Module = Zcu;
34const Object = @import("Wasm/Object.zig");32const Object = @import("Wasm/Object.zig");
35const Symbol = @import("Wasm/Symbol.zig");33const Symbol = @import("Wasm/Symbol.zig");
36const Type = @import("../Type.zig");34const Type = @import("../Type.zig");
...@@ -1441,27 +1439,27 @@ pub fn deinit(wasm: *Wasm) void {...@@ -1441,27 +1439,27 @@ pub fn deinit(wasm: *Wasm) void {
1441 wasm.files.deinit(gpa);1439 wasm.files.deinit(gpa);
1442}1440}
14431441
1444pub fn updateFunc(wasm: *Wasm, mod: *Module, func_index: InternPool.Index, air: Air, liveness: Liveness) !void {1442pub fn updateFunc(wasm: *Wasm, pt: Zcu.PerThread, func_index: InternPool.Index, air: Air, liveness: Liveness) !void {
1445 if (build_options.skip_non_native and builtin.object_format != .wasm) {1443 if (build_options.skip_non_native and builtin.object_format != .wasm) {
1446 @panic("Attempted to compile for object format that was disabled by build configuration");1444 @panic("Attempted to compile for object format that was disabled by build configuration");
1447 }1445 }
1448 if (wasm.llvm_object) |llvm_object| return llvm_object.updateFunc(mod, func_index, air, liveness);1446 if (wasm.llvm_object) |llvm_object| return llvm_object.updateFunc(pt, func_index, air, liveness);
1449 try wasm.zigObjectPtr().?.updateFunc(wasm, mod, func_index, air, liveness);1447 try wasm.zigObjectPtr().?.updateFunc(wasm, pt, func_index, air, liveness);
1450}1448}
14511449
1452// Generate code for the Decl, storing it in memory to be later written to1450// Generate code for the Decl, storing it in memory to be later written to
1453// the file on flush().1451// the file on flush().
1454pub fn updateDecl(wasm: *Wasm, mod: *Module, decl_index: InternPool.DeclIndex) !void {1452pub fn updateDecl(wasm: *Wasm, pt: Zcu.PerThread, decl_index: InternPool.DeclIndex) !void {
1455 if (build_options.skip_non_native and builtin.object_format != .wasm) {1453 if (build_options.skip_non_native and builtin.object_format != .wasm) {
1456 @panic("Attempted to compile for object format that was disabled by build configuration");1454 @panic("Attempted to compile for object format that was disabled by build configuration");
1457 }1455 }
1458 if (wasm.llvm_object) |llvm_object| return llvm_object.updateDecl(mod, decl_index);1456 if (wasm.llvm_object) |llvm_object| return llvm_object.updateDecl(pt, decl_index);
1459 try wasm.zigObjectPtr().?.updateDecl(wasm, mod, decl_index);1457 try wasm.zigObjectPtr().?.updateDecl(wasm, pt, decl_index);
1460}1458}
14611459
1462pub fn updateDeclLineNumber(wasm: *Wasm, mod: *Module, decl_index: InternPool.DeclIndex) !void {1460pub fn updateDeclLineNumber(wasm: *Wasm, pt: Zcu.PerThread, decl_index: InternPool.DeclIndex) !void {
1463 if (wasm.llvm_object) |_| return;1461 if (wasm.llvm_object) |_| return;
1464 try wasm.zigObjectPtr().?.updateDeclLineNumber(mod, decl_index);1462 try wasm.zigObjectPtr().?.updateDeclLineNumber(pt, decl_index);
1465}1463}
14661464
1467/// From a given symbol location, returns its `wasm.GlobalType`.1465/// From a given symbol location, returns its `wasm.GlobalType`.
...@@ -1506,8 +1504,8 @@ fn getFunctionSignature(wasm: *const Wasm, loc: SymbolLoc) std.wasm.Type {...@@ -1506,8 +1504,8 @@ fn getFunctionSignature(wasm: *const Wasm, loc: SymbolLoc) std.wasm.Type {
1506/// Lowers a constant typed value to a local symbol and atom.1504/// Lowers a constant typed value to a local symbol and atom.
1507/// Returns the symbol index of the local1505/// Returns the symbol index of the local
1508/// The given `decl` is the parent decl whom owns the constant.1506/// The given `decl` is the parent decl whom owns the constant.
1509pub fn lowerUnnamedConst(wasm: *Wasm, val: Value, decl_index: InternPool.DeclIndex) !u32 {1507pub fn lowerUnnamedConst(wasm: *Wasm, pt: Zcu.PerThread, val: Value, decl_index: InternPool.DeclIndex) !u32 {
1510 return wasm.zigObjectPtr().?.lowerUnnamedConst(wasm, val, decl_index);1508 return wasm.zigObjectPtr().?.lowerUnnamedConst(wasm, pt, val, decl_index);
1511}1509}
15121510
1513/// Returns the symbol index from a symbol of which its flag is set global,1511/// Returns the symbol index from a symbol of which its flag is set global,
...@@ -1523,19 +1521,21 @@ pub fn getGlobalSymbol(wasm: *Wasm, name: []const u8, lib_name: ?[]const u8) !Sy...@@ -1523,19 +1521,21 @@ pub fn getGlobalSymbol(wasm: *Wasm, name: []const u8, lib_name: ?[]const u8) !Sy
1523/// Returns the given pointer address1521/// Returns the given pointer address
1524pub fn getDeclVAddr(1522pub fn getDeclVAddr(
1525 wasm: *Wasm,1523 wasm: *Wasm,
1524 pt: Zcu.PerThread,
1526 decl_index: InternPool.DeclIndex,1525 decl_index: InternPool.DeclIndex,
1527 reloc_info: link.File.RelocInfo,1526 reloc_info: link.File.RelocInfo,
1528) !u64 {1527) !u64 {
1529 return wasm.zigObjectPtr().?.getDeclVAddr(wasm, decl_index, reloc_info);1528 return wasm.zigObjectPtr().?.getDeclVAddr(wasm, pt, decl_index, reloc_info);
1530}1529}
15311530
1532pub fn lowerAnonDecl(1531pub fn lowerAnonDecl(
1533 wasm: *Wasm,1532 wasm: *Wasm,
1533 pt: Zcu.PerThread,
1534 decl_val: InternPool.Index,1534 decl_val: InternPool.Index,
1535 explicit_alignment: Alignment,1535 explicit_alignment: Alignment,
1536 src_loc: Module.LazySrcLoc,1536 src_loc: Zcu.LazySrcLoc,
1537) !codegen.Result {1537) !codegen.Result {
1538 return wasm.zigObjectPtr().?.lowerAnonDecl(wasm, decl_val, explicit_alignment, src_loc);1538 return wasm.zigObjectPtr().?.lowerAnonDecl(wasm, pt, decl_val, explicit_alignment, src_loc);
1539}1539}
15401540
1541pub fn getAnonDeclVAddr(wasm: *Wasm, decl_val: InternPool.Index, reloc_info: link.File.RelocInfo) !u64 {1541pub fn getAnonDeclVAddr(wasm: *Wasm, decl_val: InternPool.Index, reloc_info: link.File.RelocInfo) !u64 {
...@@ -1553,15 +1553,15 @@ pub fn deleteExport(...@@ -1553,15 +1553,15 @@ pub fn deleteExport(
15531553
1554pub fn updateExports(1554pub fn updateExports(
1555 wasm: *Wasm,1555 wasm: *Wasm,
1556 mod: *Module,1556 pt: Zcu.PerThread,
1557 exported: Module.Exported,1557 exported: Zcu.Exported,
1558 export_indices: []const u32,1558 export_indices: []const u32,
1559) !void {1559) !void {
1560 if (build_options.skip_non_native and builtin.object_format != .wasm) {1560 if (build_options.skip_non_native and builtin.object_format != .wasm) {
1561 @panic("Attempted to compile for object format that was disabled by build configuration");1561 @panic("Attempted to compile for object format that was disabled by build configuration");
1562 }1562 }
1563 if (wasm.llvm_object) |llvm_object| return llvm_object.updateExports(mod, exported, export_indices);1563 if (wasm.llvm_object) |llvm_object| return llvm_object.updateExports(pt, exported, export_indices);
1564 return wasm.zigObjectPtr().?.updateExports(wasm, mod, exported, export_indices);1564 return wasm.zigObjectPtr().?.updateExports(wasm, pt, exported, export_indices);
1565}1565}
15661566
1567pub fn freeDecl(wasm: *Wasm, decl_index: InternPool.DeclIndex) void {1567pub fn freeDecl(wasm: *Wasm, decl_index: InternPool.DeclIndex) void {
...@@ -2466,18 +2466,18 @@ fn appendDummySegment(wasm: *Wasm) !void {...@@ -2466,18 +2466,18 @@ fn appendDummySegment(wasm: *Wasm) !void {
2466 });2466 });
2467}2467}
24682468
2469pub fn flush(wasm: *Wasm, arena: Allocator, prog_node: std.Progress.Node) link.File.FlushError!void {2469pub fn flush(wasm: *Wasm, arena: Allocator, tid: Zcu.PerThread.Id, prog_node: std.Progress.Node) link.File.FlushError!void {
2470 const comp = wasm.base.comp;2470 const comp = wasm.base.comp;
2471 const use_lld = build_options.have_llvm and comp.config.use_lld;2471 const use_lld = build_options.have_llvm and comp.config.use_lld;
24722472
2473 if (use_lld) {2473 if (use_lld) {
2474 return wasm.linkWithLLD(arena, prog_node);2474 return wasm.linkWithLLD(arena, tid, prog_node);
2475 }2475 }
2476 return wasm.flushModule(arena, prog_node);2476 return wasm.flushModule(arena, tid, prog_node);
2477}2477}
24782478
2479/// Uses the in-house linker to link one or multiple object -and archive files into a WebAssembly binary.2479/// Uses the in-house linker to link one or multiple object -and archive files into a WebAssembly binary.
2480pub fn flushModule(wasm: *Wasm, arena: Allocator, prog_node: std.Progress.Node) link.File.FlushError!void {2480pub fn flushModule(wasm: *Wasm, arena: Allocator, tid: Zcu.PerThread.Id, prog_node: std.Progress.Node) link.File.FlushError!void {
2481 const tracy = trace(@src());2481 const tracy = trace(@src());
2482 defer tracy.end();2482 defer tracy.end();
24832483
...@@ -2513,7 +2513,7 @@ pub fn flushModule(wasm: *Wasm, arena: Allocator, prog_node: std.Progress.Node)...@@ -2513,7 +2513,7 @@ pub fn flushModule(wasm: *Wasm, arena: Allocator, prog_node: std.Progress.Node)
2513 const wasi_exec_model = comp.config.wasi_exec_model;2513 const wasi_exec_model = comp.config.wasi_exec_model;
25142514
2515 if (wasm.zigObjectPtr()) |zig_object| {2515 if (wasm.zigObjectPtr()) |zig_object| {
2516 try zig_object.flushModule(wasm);2516 try zig_object.flushModule(wasm, tid);
2517 }2517 }
25182518
2519 // When the target os is WASI, we allow linking with WASI-LIBC2519 // When the target os is WASI, we allow linking with WASI-LIBC
...@@ -3324,7 +3324,7 @@ fn emitImport(wasm: *Wasm, writer: anytype, import: types.Import) !void {...@@ -3324,7 +3324,7 @@ fn emitImport(wasm: *Wasm, writer: anytype, import: types.Import) !void {
3324 }3324 }
3325}3325}
33263326
3327fn linkWithLLD(wasm: *Wasm, arena: Allocator, prog_node: std.Progress.Node) !void {3327fn linkWithLLD(wasm: *Wasm, arena: Allocator, tid: Zcu.PerThread.Id, prog_node: std.Progress.Node) !void {
3328 const tracy = trace(@src());3328 const tracy = trace(@src());
3329 defer tracy.end();3329 defer tracy.end();
33303330
...@@ -3342,7 +3342,7 @@ fn linkWithLLD(wasm: *Wasm, arena: Allocator, prog_node: std.Progress.Node) !voi...@@ -3342,7 +3342,7 @@ fn linkWithLLD(wasm: *Wasm, arena: Allocator, prog_node: std.Progress.Node) !voi
3342 // If there is no Zig code to compile, then we should skip flushing the output file because it3342 // If there is no Zig code to compile, then we should skip flushing the output file because it
3343 // will not be part of the linker line anyway.3343 // will not be part of the linker line anyway.
3344 const module_obj_path: ?[]const u8 = if (comp.module != null) blk: {3344 const module_obj_path: ?[]const u8 = if (comp.module != null) blk: {
3345 try wasm.flushModule(arena, prog_node);3345 try wasm.flushModule(arena, tid, prog_node);
33463346
3347 if (fs.path.dirname(full_out_path)) |dirname| {3347 if (fs.path.dirname(full_out_path)) |dirname| {
3348 break :blk try fs.path.join(arena, &.{ dirname, wasm.base.zcu_object_sub_path.? });3348 break :blk try fs.path.join(arena, &.{ dirname, wasm.base.zcu_object_sub_path.? });
...@@ -4009,16 +4009,16 @@ pub fn storeDeclType(wasm: *Wasm, decl_index: InternPool.DeclIndex, func_type: s...@@ -4009,16 +4009,16 @@ pub fn storeDeclType(wasm: *Wasm, decl_index: InternPool.DeclIndex, func_type: s
4009/// Returns the symbol index of the error name table.4009/// Returns the symbol index of the error name table.
4010///4010///
4011/// When the symbol does not yet exist, it will create a new one instead.4011/// When the symbol does not yet exist, it will create a new one instead.
4012pub fn getErrorTableSymbol(wasm_file: *Wasm) !u32 {4012pub fn getErrorTableSymbol(wasm_file: *Wasm, pt: Zcu.PerThread) !u32 {
4013 const sym_index = try wasm_file.zigObjectPtr().?.getErrorTableSymbol(wasm_file);4013 const sym_index = try wasm_file.zigObjectPtr().?.getErrorTableSymbol(wasm_file, pt);
4014 return @intFromEnum(sym_index);4014 return @intFromEnum(sym_index);
4015}4015}
40164016
4017/// For a given `InternPool.DeclIndex` returns its corresponding `Atom.Index`.4017/// For a given `InternPool.DeclIndex` returns its corresponding `Atom.Index`.
4018/// When the index was not found, a new `Atom` will be created, and its index will be returned.4018/// When the index was not found, a new `Atom` will be created, and its index will be returned.
4019/// The newly created Atom is empty with default fields as specified by `Atom.empty`.4019/// The newly created Atom is empty with default fields as specified by `Atom.empty`.
4020pub fn getOrCreateAtomForDecl(wasm_file: *Wasm, decl_index: InternPool.DeclIndex) !Atom.Index {4020pub fn getOrCreateAtomForDecl(wasm_file: *Wasm, pt: Zcu.PerThread, decl_index: InternPool.DeclIndex) !Atom.Index {
4021 return wasm_file.zigObjectPtr().?.getOrCreateAtomForDecl(wasm_file, decl_index);4021 return wasm_file.zigObjectPtr().?.getOrCreateAtomForDecl(wasm_file, pt, decl_index);
4022}4022}
40234023
4024/// Verifies all resolved symbols and checks whether itself needs to be marked alive,4024/// Verifies all resolved symbols and checks whether itself needs to be marked alive,
src/link/Wasm/ZigObject.zig+88-62
...@@ -241,9 +241,10 @@ pub fn allocateSymbol(zig_object: *ZigObject, gpa: std.mem.Allocator) !Symbol.In...@@ -241,9 +241,10 @@ pub fn allocateSymbol(zig_object: *ZigObject, gpa: std.mem.Allocator) !Symbol.In
241pub fn updateDecl(241pub fn updateDecl(
242 zig_object: *ZigObject,242 zig_object: *ZigObject,
243 wasm_file: *Wasm,243 wasm_file: *Wasm,
244 mod: *Module,244 pt: Zcu.PerThread,
245 decl_index: InternPool.DeclIndex,245 decl_index: InternPool.DeclIndex,
246) !void {246) !void {
247 const mod = pt.zcu;
247 const decl = mod.declPtr(decl_index);248 const decl = mod.declPtr(decl_index);
248 if (decl.val.getFunction(mod)) |_| {249 if (decl.val.getFunction(mod)) |_| {
249 return;250 return;
...@@ -252,7 +253,7 @@ pub fn updateDecl(...@@ -252,7 +253,7 @@ pub fn updateDecl(
252 }253 }
253254
254 const gpa = wasm_file.base.comp.gpa;255 const gpa = wasm_file.base.comp.gpa;
255 const atom_index = try zig_object.getOrCreateAtomForDecl(wasm_file, decl_index);256 const atom_index = try zig_object.getOrCreateAtomForDecl(wasm_file, pt, decl_index);
256 const atom = wasm_file.getAtomPtr(atom_index);257 const atom = wasm_file.getAtomPtr(atom_index);
257 atom.clear();258 atom.clear();
258259
...@@ -269,6 +270,7 @@ pub fn updateDecl(...@@ -269,6 +270,7 @@ pub fn updateDecl(
269270
270 const res = try codegen.generateSymbol(271 const res = try codegen.generateSymbol(
271 &wasm_file.base,272 &wasm_file.base,
273 pt,
272 decl.navSrcLoc(mod),274 decl.navSrcLoc(mod),
273 val,275 val,
274 &code_writer,276 &code_writer,
...@@ -285,22 +287,22 @@ pub fn updateDecl(...@@ -285,22 +287,22 @@ pub fn updateDecl(
285 },287 },
286 };288 };
287289
288 return zig_object.finishUpdateDecl(wasm_file, decl_index, code);290 return zig_object.finishUpdateDecl(wasm_file, pt, decl_index, code);
289}291}
290292
291pub fn updateFunc(293pub fn updateFunc(
292 zig_object: *ZigObject,294 zig_object: *ZigObject,
293 wasm_file: *Wasm,295 wasm_file: *Wasm,
294 mod: *Module,296 pt: Zcu.PerThread,
295 func_index: InternPool.Index,297 func_index: InternPool.Index,
296 air: Air,298 air: Air,
297 liveness: Liveness,299 liveness: Liveness,
298) !void {300) !void {
299 const gpa = wasm_file.base.comp.gpa;301 const gpa = wasm_file.base.comp.gpa;
300 const func = mod.funcInfo(func_index);302 const func = pt.zcu.funcInfo(func_index);
301 const decl_index = func.owner_decl;303 const decl_index = func.owner_decl;
302 const decl = mod.declPtr(decl_index);304 const decl = pt.zcu.declPtr(decl_index);
303 const atom_index = try zig_object.getOrCreateAtomForDecl(wasm_file, decl_index);305 const atom_index = try zig_object.getOrCreateAtomForDecl(wasm_file, pt, decl_index);
304 const atom = wasm_file.getAtomPtr(atom_index);306 const atom = wasm_file.getAtomPtr(atom_index);
305 atom.clear();307 atom.clear();
306308
...@@ -308,7 +310,8 @@ pub fn updateFunc(...@@ -308,7 +310,8 @@ pub fn updateFunc(
308 defer code_writer.deinit();310 defer code_writer.deinit();
309 const result = try codegen.generateFunction(311 const result = try codegen.generateFunction(
310 &wasm_file.base,312 &wasm_file.base,
311 decl.navSrcLoc(mod),313 pt,
314 decl.navSrcLoc(pt.zcu),
312 func_index,315 func_index,
313 air,316 air,
314 liveness,317 liveness,
...@@ -320,29 +323,31 @@ pub fn updateFunc(...@@ -320,29 +323,31 @@ pub fn updateFunc(
320 .ok => code_writer.items,323 .ok => code_writer.items,
321 .fail => |em| {324 .fail => |em| {
322 decl.analysis = .codegen_failure;325 decl.analysis = .codegen_failure;
323 try mod.failed_analysis.put(mod.gpa, AnalUnit.wrap(.{ .decl = decl_index }), em);326 try pt.zcu.failed_analysis.put(gpa, AnalUnit.wrap(.{ .decl = decl_index }), em);
324 return;327 return;
325 },328 },
326 };329 };
327330
328 return zig_object.finishUpdateDecl(wasm_file, decl_index, code);331 return zig_object.finishUpdateDecl(wasm_file, pt, decl_index, code);
329}332}
330333
331fn finishUpdateDecl(334fn finishUpdateDecl(
332 zig_object: *ZigObject,335 zig_object: *ZigObject,
333 wasm_file: *Wasm,336 wasm_file: *Wasm,
337 pt: Zcu.PerThread,
334 decl_index: InternPool.DeclIndex,338 decl_index: InternPool.DeclIndex,
335 code: []const u8,339 code: []const u8,
336) !void {340) !void {
337 const gpa = wasm_file.base.comp.gpa;341 const zcu = pt.zcu;
338 const zcu = wasm_file.base.comp.module.?;342 const ip = &zcu.intern_pool;
343 const gpa = zcu.gpa;
339 const decl = zcu.declPtr(decl_index);344 const decl = zcu.declPtr(decl_index);
340 const decl_info = zig_object.decls_map.get(decl_index).?;345 const decl_info = zig_object.decls_map.get(decl_index).?;
341 const atom_index = decl_info.atom;346 const atom_index = decl_info.atom;
342 const atom = wasm_file.getAtomPtr(atom_index);347 const atom = wasm_file.getAtomPtr(atom_index);
343 const sym = zig_object.symbol(atom.sym_index);348 const sym = zig_object.symbol(atom.sym_index);
344 const full_name = try decl.fullyQualifiedName(zcu);349 const full_name = try decl.fullyQualifiedName(pt);
345 sym.name = try zig_object.string_table.insert(gpa, full_name.toSlice(&zcu.intern_pool));350 sym.name = try zig_object.string_table.insert(gpa, full_name.toSlice(ip));
346 try atom.code.appendSlice(gpa, code);351 try atom.code.appendSlice(gpa, code);
347 atom.size = @intCast(code.len);352 atom.size = @intCast(code.len);
348353
...@@ -382,7 +387,7 @@ fn finishUpdateDecl(...@@ -382,7 +387,7 @@ fn finishUpdateDecl(
382 // Will be freed upon freeing of decl or after cleanup of Wasm binary.387 // Will be freed upon freeing of decl or after cleanup of Wasm binary.
383 const full_segment_name = try std.mem.concat(gpa, u8, &.{388 const full_segment_name = try std.mem.concat(gpa, u8, &.{
384 segment_name,389 segment_name,
385 full_name.toSlice(&zcu.intern_pool),390 full_name.toSlice(ip),
386 });391 });
387 errdefer gpa.free(full_segment_name);392 errdefer gpa.free(full_segment_name);
388 sym.tag = .data;393 sym.tag = .data;
...@@ -390,7 +395,7 @@ fn finishUpdateDecl(...@@ -390,7 +395,7 @@ fn finishUpdateDecl(
390 },395 },
391 }396 }
392 if (code.len == 0) return;397 if (code.len == 0) return;
393 atom.alignment = decl.getAlignment(zcu);398 atom.alignment = decl.getAlignment(pt);
394}399}
395400
396/// Creates and initializes a new segment in the 'Data' section.401/// Creates and initializes a new segment in the 'Data' section.
...@@ -419,17 +424,21 @@ fn createDataSegment(...@@ -419,17 +424,21 @@ fn createDataSegment(
419/// For a given `InternPool.DeclIndex` returns its corresponding `Atom.Index`.424/// For a given `InternPool.DeclIndex` returns its corresponding `Atom.Index`.
420/// When the index was not found, a new `Atom` will be created, and its index will be returned.425/// When the index was not found, a new `Atom` will be created, and its index will be returned.
421/// The newly created Atom is empty with default fields as specified by `Atom.empty`.426/// The newly created Atom is empty with default fields as specified by `Atom.empty`.
422pub fn getOrCreateAtomForDecl(zig_object: *ZigObject, wasm_file: *Wasm, decl_index: InternPool.DeclIndex) !Atom.Index {427pub fn getOrCreateAtomForDecl(
423 const gpa = wasm_file.base.comp.gpa;428 zig_object: *ZigObject,
429 wasm_file: *Wasm,
430 pt: Zcu.PerThread,
431 decl_index: InternPool.DeclIndex,
432) !Atom.Index {
433 const gpa = pt.zcu.gpa;
424 const gop = try zig_object.decls_map.getOrPut(gpa, decl_index);434 const gop = try zig_object.decls_map.getOrPut(gpa, decl_index);
425 if (!gop.found_existing) {435 if (!gop.found_existing) {
426 const sym_index = try zig_object.allocateSymbol(gpa);436 const sym_index = try zig_object.allocateSymbol(gpa);
427 gop.value_ptr.* = .{ .atom = try wasm_file.createAtom(sym_index, zig_object.index) };437 gop.value_ptr.* = .{ .atom = try wasm_file.createAtom(sym_index, zig_object.index) };
428 const mod = wasm_file.base.comp.module.?;438 const decl = pt.zcu.declPtr(decl_index);
429 const decl = mod.declPtr(decl_index);439 const full_name = try decl.fullyQualifiedName(pt);
430 const full_name = try decl.fullyQualifiedName(mod);
431 const sym = zig_object.symbol(sym_index);440 const sym = zig_object.symbol(sym_index);
432 sym.name = try zig_object.string_table.insert(gpa, full_name.toSlice(&mod.intern_pool));441 sym.name = try zig_object.string_table.insert(gpa, full_name.toSlice(&pt.zcu.intern_pool));
433 }442 }
434 return gop.value_ptr.atom;443 return gop.value_ptr.atom;
435}444}
...@@ -437,9 +446,10 @@ pub fn getOrCreateAtomForDecl(zig_object: *ZigObject, wasm_file: *Wasm, decl_ind...@@ -437,9 +446,10 @@ pub fn getOrCreateAtomForDecl(zig_object: *ZigObject, wasm_file: *Wasm, decl_ind
437pub fn lowerAnonDecl(446pub fn lowerAnonDecl(
438 zig_object: *ZigObject,447 zig_object: *ZigObject,
439 wasm_file: *Wasm,448 wasm_file: *Wasm,
449 pt: Zcu.PerThread,
440 decl_val: InternPool.Index,450 decl_val: InternPool.Index,
441 explicit_alignment: InternPool.Alignment,451 explicit_alignment: InternPool.Alignment,
442 src_loc: Module.LazySrcLoc,452 src_loc: Zcu.LazySrcLoc,
443) !codegen.Result {453) !codegen.Result {
444 const gpa = wasm_file.base.comp.gpa;454 const gpa = wasm_file.base.comp.gpa;
445 const gop = try zig_object.anon_decls.getOrPut(gpa, decl_val);455 const gop = try zig_object.anon_decls.getOrPut(gpa, decl_val);
...@@ -449,7 +459,7 @@ pub fn lowerAnonDecl(...@@ -449,7 +459,7 @@ pub fn lowerAnonDecl(
449 @intFromEnum(decl_val),459 @intFromEnum(decl_val),
450 }) catch unreachable;460 }) catch unreachable;
451461
452 switch (try zig_object.lowerConst(wasm_file, name, Value.fromInterned(decl_val), src_loc)) {462 switch (try zig_object.lowerConst(wasm_file, pt, name, Value.fromInterned(decl_val), src_loc)) {
453 .ok => |atom_index| zig_object.anon_decls.values()[gop.index] = atom_index,463 .ok => |atom_index| zig_object.anon_decls.values()[gop.index] = atom_index,
454 .fail => |em| return .{ .fail = em },464 .fail => |em| return .{ .fail = em },
455 }465 }
...@@ -469,16 +479,22 @@ pub fn lowerAnonDecl(...@@ -469,16 +479,22 @@ pub fn lowerAnonDecl(
469/// Lowers a constant typed value to a local symbol and atom.479/// Lowers a constant typed value to a local symbol and atom.
470/// Returns the symbol index of the local480/// Returns the symbol index of the local
471/// The given `decl` is the parent decl whom owns the constant.481/// The given `decl` is the parent decl whom owns the constant.
472pub fn lowerUnnamedConst(zig_object: *ZigObject, wasm_file: *Wasm, val: Value, decl_index: InternPool.DeclIndex) !u32 {482pub fn lowerUnnamedConst(
473 const gpa = wasm_file.base.comp.gpa;483 zig_object: *ZigObject,
474 const mod = wasm_file.base.comp.module.?;484 wasm_file: *Wasm,
485 pt: Zcu.PerThread,
486 val: Value,
487 decl_index: InternPool.DeclIndex,
488) !u32 {
489 const mod = pt.zcu;
490 const gpa = mod.gpa;
475 std.debug.assert(val.typeOf(mod).zigTypeTag(mod) != .Fn); // cannot create local symbols for functions491 std.debug.assert(val.typeOf(mod).zigTypeTag(mod) != .Fn); // cannot create local symbols for functions
476 const decl = mod.declPtr(decl_index);492 const decl = mod.declPtr(decl_index);
477493
478 const parent_atom_index = try zig_object.getOrCreateAtomForDecl(wasm_file, decl_index);494 const parent_atom_index = try zig_object.getOrCreateAtomForDecl(wasm_file, pt, decl_index);
479 const parent_atom = wasm_file.getAtom(parent_atom_index);495 const parent_atom = wasm_file.getAtom(parent_atom_index);
480 const local_index = parent_atom.locals.items.len;496 const local_index = parent_atom.locals.items.len;
481 const fqn = try decl.fullyQualifiedName(mod);497 const fqn = try decl.fullyQualifiedName(pt);
482 const name = try std.fmt.allocPrintZ(gpa, "__unnamed_{}_{d}", .{498 const name = try std.fmt.allocPrintZ(gpa, "__unnamed_{}_{d}", .{
483 fqn.fmt(&mod.intern_pool), local_index,499 fqn.fmt(&mod.intern_pool), local_index,
484 });500 });
...@@ -494,7 +510,7 @@ pub fn lowerUnnamedConst(zig_object: *ZigObject, wasm_file: *Wasm, val: Value, d...@@ -494,7 +510,7 @@ pub fn lowerUnnamedConst(zig_object: *ZigObject, wasm_file: *Wasm, val: Value, d
494 else510 else
495 decl.navSrcLoc(mod);511 decl.navSrcLoc(mod);
496512
497 switch (try zig_object.lowerConst(wasm_file, name, val, decl_src)) {513 switch (try zig_object.lowerConst(wasm_file, pt, name, val, decl_src)) {
498 .ok => |atom_index| {514 .ok => |atom_index| {
499 try wasm_file.getAtomPtr(parent_atom_index).locals.append(gpa, atom_index);515 try wasm_file.getAtomPtr(parent_atom_index).locals.append(gpa, atom_index);
500 return @intFromEnum(wasm_file.getAtom(atom_index).sym_index);516 return @intFromEnum(wasm_file.getAtom(atom_index).sym_index);
...@@ -509,10 +525,17 @@ pub fn lowerUnnamedConst(zig_object: *ZigObject, wasm_file: *Wasm, val: Value, d...@@ -509,10 +525,17 @@ pub fn lowerUnnamedConst(zig_object: *ZigObject, wasm_file: *Wasm, val: Value, d
509525
510const LowerConstResult = union(enum) {526const LowerConstResult = union(enum) {
511 ok: Atom.Index,527 ok: Atom.Index,
512 fail: *Module.ErrorMsg,528 fail: *Zcu.ErrorMsg,
513};529};
514530
515fn lowerConst(zig_object: *ZigObject, wasm_file: *Wasm, name: []const u8, val: Value, src_loc: Module.LazySrcLoc) !LowerConstResult {531fn lowerConst(
532 zig_object: *ZigObject,
533 wasm_file: *Wasm,
534 pt: Zcu.PerThread,
535 name: []const u8,
536 val: Value,
537 src_loc: Zcu.LazySrcLoc,
538) !LowerConstResult {
516 const gpa = wasm_file.base.comp.gpa;539 const gpa = wasm_file.base.comp.gpa;
517 const mod = wasm_file.base.comp.module.?;540 const mod = wasm_file.base.comp.module.?;
518541
...@@ -526,7 +549,7 @@ fn lowerConst(zig_object: *ZigObject, wasm_file: *Wasm, name: []const u8, val: V...@@ -526,7 +549,7 @@ fn lowerConst(zig_object: *ZigObject, wasm_file: *Wasm, name: []const u8, val: V
526549
527 const code = code: {550 const code = code: {
528 const atom = wasm_file.getAtomPtr(atom_index);551 const atom = wasm_file.getAtomPtr(atom_index);
529 atom.alignment = ty.abiAlignment(mod);552 atom.alignment = ty.abiAlignment(pt);
530 const segment_name = try std.mem.concat(gpa, u8, &.{ ".rodata.", name });553 const segment_name = try std.mem.concat(gpa, u8, &.{ ".rodata.", name });
531 errdefer gpa.free(segment_name);554 errdefer gpa.free(segment_name);
532 zig_object.symbol(sym_index).* = .{555 zig_object.symbol(sym_index).* = .{
...@@ -536,13 +559,14 @@ fn lowerConst(zig_object: *ZigObject, wasm_file: *Wasm, name: []const u8, val: V...@@ -536,13 +559,14 @@ fn lowerConst(zig_object: *ZigObject, wasm_file: *Wasm, name: []const u8, val: V
536 .index = try zig_object.createDataSegment(559 .index = try zig_object.createDataSegment(
537 gpa,560 gpa,
538 segment_name,561 segment_name,
539 ty.abiAlignment(mod),562 ty.abiAlignment(pt),
540 ),563 ),
541 .virtual_address = undefined,564 .virtual_address = undefined,
542 };565 };
543566
544 const result = try codegen.generateSymbol(567 const result = try codegen.generateSymbol(
545 &wasm_file.base,568 &wasm_file.base,
569 pt,
546 src_loc,570 src_loc,
547 val,571 val,
548 &value_bytes,572 &value_bytes,
...@@ -568,7 +592,7 @@ fn lowerConst(zig_object: *ZigObject, wasm_file: *Wasm, name: []const u8, val: V...@@ -568,7 +592,7 @@ fn lowerConst(zig_object: *ZigObject, wasm_file: *Wasm, name: []const u8, val: V
568/// Returns the symbol index of the error name table.592/// Returns the symbol index of the error name table.
569///593///
570/// When the symbol does not yet exist, it will create a new one instead.594/// When the symbol does not yet exist, it will create a new one instead.
571pub fn getErrorTableSymbol(zig_object: *ZigObject, wasm_file: *Wasm) !Symbol.Index {595pub fn getErrorTableSymbol(zig_object: *ZigObject, wasm_file: *Wasm, pt: Zcu.PerThread) !Symbol.Index {
572 if (zig_object.error_table_symbol != .null) {596 if (zig_object.error_table_symbol != .null) {
573 return zig_object.error_table_symbol;597 return zig_object.error_table_symbol;
574 }598 }
...@@ -581,8 +605,7 @@ pub fn getErrorTableSymbol(zig_object: *ZigObject, wasm_file: *Wasm) !Symbol.Ind...@@ -581,8 +605,7 @@ pub fn getErrorTableSymbol(zig_object: *ZigObject, wasm_file: *Wasm) !Symbol.Ind
581 const atom_index = try wasm_file.createAtom(sym_index, zig_object.index);605 const atom_index = try wasm_file.createAtom(sym_index, zig_object.index);
582 const atom = wasm_file.getAtomPtr(atom_index);606 const atom = wasm_file.getAtomPtr(atom_index);
583 const slice_ty = Type.slice_const_u8_sentinel_0;607 const slice_ty = Type.slice_const_u8_sentinel_0;
584 const mod = wasm_file.base.comp.module.?;608 atom.alignment = slice_ty.abiAlignment(pt);
585 atom.alignment = slice_ty.abiAlignment(mod);
586609
587 const sym_name = try zig_object.string_table.insert(gpa, "__zig_err_name_table");610 const sym_name = try zig_object.string_table.insert(gpa, "__zig_err_name_table");
588 const segment_name = try gpa.dupe(u8, ".rodata.__zig_err_name_table");611 const segment_name = try gpa.dupe(u8, ".rodata.__zig_err_name_table");
...@@ -604,7 +627,7 @@ pub fn getErrorTableSymbol(zig_object: *ZigObject, wasm_file: *Wasm) !Symbol.Ind...@@ -604,7 +627,7 @@ pub fn getErrorTableSymbol(zig_object: *ZigObject, wasm_file: *Wasm) !Symbol.Ind
604///627///
605/// This creates a table that consists of pointers and length to each error name.628/// This creates a table that consists of pointers and length to each error name.
606/// The table is what is being pointed to within the runtime bodies that are generated.629/// The table is what is being pointed to within the runtime bodies that are generated.
607fn populateErrorNameTable(zig_object: *ZigObject, wasm_file: *Wasm) !void {630fn populateErrorNameTable(zig_object: *ZigObject, wasm_file: *Wasm, tid: Zcu.PerThread.Id) !void {
608 if (zig_object.error_table_symbol == .null) return;631 if (zig_object.error_table_symbol == .null) return;
609 const gpa = wasm_file.base.comp.gpa;632 const gpa = wasm_file.base.comp.gpa;
610 const atom_index = wasm_file.symbol_atom.get(.{ .file = zig_object.index, .index = zig_object.error_table_symbol }).?;633 const atom_index = wasm_file.symbol_atom.get(.{ .file = zig_object.index, .index = zig_object.error_table_symbol }).?;
...@@ -631,11 +654,11 @@ fn populateErrorNameTable(zig_object: *ZigObject, wasm_file: *Wasm) !void {...@@ -631,11 +654,11 @@ fn populateErrorNameTable(zig_object: *ZigObject, wasm_file: *Wasm) !void {
631654
632 // Addend for each relocation to the table655 // Addend for each relocation to the table
633 var addend: u32 = 0;656 var addend: u32 = 0;
634 const mod = wasm_file.base.comp.module.?;657 const pt: Zcu.PerThread = .{ .zcu = wasm_file.base.comp.module.?, .tid = tid };
635 for (mod.global_error_set.keys()) |error_name| {658 for (pt.zcu.global_error_set.keys()) |error_name| {
636 const atom = wasm_file.getAtomPtr(atom_index);659 const atom = wasm_file.getAtomPtr(atom_index);
637660
638 const error_name_slice = error_name.toSlice(&mod.intern_pool);661 const error_name_slice = error_name.toSlice(&pt.zcu.intern_pool);
639 const len: u32 = @intCast(error_name_slice.len + 1); // names are 0-terminated662 const len: u32 = @intCast(error_name_slice.len + 1); // names are 0-terminated
640663
641 const slice_ty = Type.slice_const_u8_sentinel_0;664 const slice_ty = Type.slice_const_u8_sentinel_0;
...@@ -650,14 +673,14 @@ fn populateErrorNameTable(zig_object: *ZigObject, wasm_file: *Wasm) !void {...@@ -650,14 +673,14 @@ fn populateErrorNameTable(zig_object: *ZigObject, wasm_file: *Wasm) !void {
650 .offset = offset,673 .offset = offset,
651 .addend = @intCast(addend),674 .addend = @intCast(addend),
652 });675 });
653 atom.size += @intCast(slice_ty.abiSize(mod));676 atom.size += @intCast(slice_ty.abiSize(pt));
654 addend += len;677 addend += len;
655678
656 // as we updated the error name table, we now store the actual name within the names atom679 // as we updated the error name table, we now store the actual name within the names atom
657 try names_atom.code.ensureUnusedCapacity(gpa, len);680 try names_atom.code.ensureUnusedCapacity(gpa, len);
658 names_atom.code.appendSliceAssumeCapacity(error_name_slice[0..len]);681 names_atom.code.appendSliceAssumeCapacity(error_name_slice[0..len]);
659682
660 log.debug("Populated error name: '{}'", .{error_name.fmt(&mod.intern_pool)});683 log.debug("Populated error name: '{}'", .{error_name.fmt(&pt.zcu.intern_pool)});
661 }684 }
662 names_atom.size = addend;685 names_atom.size = addend;
663 zig_object.error_names_atom = names_atom_index;686 zig_object.error_names_atom = names_atom_index;
...@@ -756,22 +779,22 @@ pub fn getGlobalSymbol(zig_object: *ZigObject, gpa: std.mem.Allocator, name: []c...@@ -756,22 +779,22 @@ pub fn getGlobalSymbol(zig_object: *ZigObject, gpa: std.mem.Allocator, name: []c
756pub fn getDeclVAddr(779pub fn getDeclVAddr(
757 zig_object: *ZigObject,780 zig_object: *ZigObject,
758 wasm_file: *Wasm,781 wasm_file: *Wasm,
782 pt: Zcu.PerThread,
759 decl_index: InternPool.DeclIndex,783 decl_index: InternPool.DeclIndex,
760 reloc_info: link.File.RelocInfo,784 reloc_info: link.File.RelocInfo,
761) !u64 {785) !u64 {
762 const target = wasm_file.base.comp.root_mod.resolved_target.result;786 const target = wasm_file.base.comp.root_mod.resolved_target.result;
763 const gpa = wasm_file.base.comp.gpa;787 const gpa = pt.zcu.gpa;
764 const mod = wasm_file.base.comp.module.?;788 const decl = pt.zcu.declPtr(decl_index);
765 const decl = mod.declPtr(decl_index);
766789
767 const target_atom_index = try zig_object.getOrCreateAtomForDecl(wasm_file, decl_index);790 const target_atom_index = try zig_object.getOrCreateAtomForDecl(wasm_file, pt, decl_index);
768 const target_symbol_index = @intFromEnum(wasm_file.getAtom(target_atom_index).sym_index);791 const target_symbol_index = @intFromEnum(wasm_file.getAtom(target_atom_index).sym_index);
769792
770 std.debug.assert(reloc_info.parent_atom_index != 0);793 std.debug.assert(reloc_info.parent_atom_index != 0);
771 const atom_index = wasm_file.symbol_atom.get(.{ .file = zig_object.index, .index = @enumFromInt(reloc_info.parent_atom_index) }).?;794 const atom_index = wasm_file.symbol_atom.get(.{ .file = zig_object.index, .index = @enumFromInt(reloc_info.parent_atom_index) }).?;
772 const atom = wasm_file.getAtomPtr(atom_index);795 const atom = wasm_file.getAtomPtr(atom_index);
773 const is_wasm32 = target.cpu.arch == .wasm32;796 const is_wasm32 = target.cpu.arch == .wasm32;
774 if (decl.typeOf(mod).zigTypeTag(mod) == .Fn) {797 if (decl.typeOf(pt.zcu).zigTypeTag(pt.zcu) == .Fn) {
775 std.debug.assert(reloc_info.addend == 0); // addend not allowed for function relocations798 std.debug.assert(reloc_info.addend == 0); // addend not allowed for function relocations
776 try atom.relocs.append(gpa, .{799 try atom.relocs.append(gpa, .{
777 .index = target_symbol_index,800 .index = target_symbol_index,
...@@ -858,10 +881,11 @@ pub fn deleteExport(...@@ -858,10 +881,11 @@ pub fn deleteExport(
858pub fn updateExports(881pub fn updateExports(
859 zig_object: *ZigObject,882 zig_object: *ZigObject,
860 wasm_file: *Wasm,883 wasm_file: *Wasm,
861 mod: *Module,884 pt: Zcu.PerThread,
862 exported: Module.Exported,885 exported: Zcu.Exported,
863 export_indices: []const u32,886 export_indices: []const u32,
864) !void {887) !void {
888 const mod = pt.zcu;
865 const decl_index = switch (exported) {889 const decl_index = switch (exported) {
866 .decl_index => |i| i,890 .decl_index => |i| i,
867 .value => |val| {891 .value => |val| {
...@@ -870,7 +894,7 @@ pub fn updateExports(...@@ -870,7 +894,7 @@ pub fn updateExports(
870 },894 },
871 };895 };
872 const decl = mod.declPtr(decl_index);896 const decl = mod.declPtr(decl_index);
873 const atom_index = try zig_object.getOrCreateAtomForDecl(wasm_file, decl_index);897 const atom_index = try zig_object.getOrCreateAtomForDecl(wasm_file, pt, decl_index);
874 const decl_info = zig_object.decls_map.getPtr(decl_index).?;898 const decl_info = zig_object.decls_map.getPtr(decl_index).?;
875 const atom = wasm_file.getAtom(atom_index);899 const atom = wasm_file.getAtom(atom_index);
876 const atom_sym = atom.symbolLoc().getSymbol(wasm_file).*;900 const atom_sym = atom.symbolLoc().getSymbol(wasm_file).*;
...@@ -880,7 +904,7 @@ pub fn updateExports(...@@ -880,7 +904,7 @@ pub fn updateExports(
880 for (export_indices) |export_idx| {904 for (export_indices) |export_idx| {
881 const exp = mod.all_exports.items[export_idx];905 const exp = mod.all_exports.items[export_idx];
882 if (exp.opts.section.toSlice(&mod.intern_pool)) |section| {906 if (exp.opts.section.toSlice(&mod.intern_pool)) |section| {
883 try mod.failed_exports.putNoClobber(gpa, export_idx, try Module.ErrorMsg.create(907 try mod.failed_exports.putNoClobber(gpa, export_idx, try Zcu.ErrorMsg.create(
884 gpa,908 gpa,
885 decl.navSrcLoc(mod),909 decl.navSrcLoc(mod),
886 "Unimplemented: ExportOptions.section '{s}'",910 "Unimplemented: ExportOptions.section '{s}'",
...@@ -913,7 +937,7 @@ pub fn updateExports(...@@ -913,7 +937,7 @@ pub fn updateExports(
913 },937 },
914 .strong => {}, // symbols are strong by default938 .strong => {}, // symbols are strong by default
915 .link_once => {939 .link_once => {
916 try mod.failed_exports.putNoClobber(gpa, export_idx, try Module.ErrorMsg.create(940 try mod.failed_exports.putNoClobber(gpa, export_idx, try Zcu.ErrorMsg.create(
917 gpa,941 gpa,
918 decl.navSrcLoc(mod),942 decl.navSrcLoc(mod),
919 "Unimplemented: LinkOnce",943 "Unimplemented: LinkOnce",
...@@ -1096,13 +1120,17 @@ pub fn createDebugSectionForIndex(zig_object: *ZigObject, wasm_file: *Wasm, inde...@@ -1096,13 +1120,17 @@ pub fn createDebugSectionForIndex(zig_object: *ZigObject, wasm_file: *Wasm, inde
1096 return atom_index;1120 return atom_index;
1097}1121}
10981122
1099pub fn updateDeclLineNumber(zig_object: *ZigObject, mod: *Module, decl_index: InternPool.DeclIndex) !void {1123pub fn updateDeclLineNumber(
1124 zig_object: *ZigObject,
1125 pt: Zcu.PerThread,
1126 decl_index: InternPool.DeclIndex,
1127) !void {
1100 if (zig_object.dwarf) |*dw| {1128 if (zig_object.dwarf) |*dw| {
1101 const decl = mod.declPtr(decl_index);1129 const decl = pt.zcu.declPtr(decl_index);
1102 const decl_name = try decl.fullyQualifiedName(mod);1130 const decl_name = try decl.fullyQualifiedName(pt);
11031131
1104 log.debug("updateDeclLineNumber {}{*}", .{ decl_name.fmt(&mod.intern_pool), decl });1132 log.debug("updateDeclLineNumber {}{*}", .{ decl_name.fmt(&pt.zcu.intern_pool), decl });
1105 try dw.updateDeclLineNumber(mod, decl_index);1133 try dw.updateDeclLineNumber(pt.zcu, decl_index);
1106 }1134 }
1107}1135}
11081136
...@@ -1228,8 +1256,8 @@ fn appendFunction(zig_object: *ZigObject, gpa: std.mem.Allocator, func: std.wasm...@@ -1228,8 +1256,8 @@ fn appendFunction(zig_object: *ZigObject, gpa: std.mem.Allocator, func: std.wasm
1228 return index;1256 return index;
1229}1257}
12301258
1231pub fn flushModule(zig_object: *ZigObject, wasm_file: *Wasm) !void {1259pub fn flushModule(zig_object: *ZigObject, wasm_file: *Wasm, tid: Zcu.PerThread.Id) !void {
1232 try zig_object.populateErrorNameTable(wasm_file);1260 try zig_object.populateErrorNameTable(wasm_file, tid);
1233 try zig_object.setupErrorsLen(wasm_file);1261 try zig_object.setupErrorsLen(wasm_file);
1234}1262}
12351263
...@@ -1248,8 +1276,6 @@ const File = @import("file.zig").File;...@@ -1248,8 +1276,6 @@ const File = @import("file.zig").File;
1248const InternPool = @import("../../InternPool.zig");1276const InternPool = @import("../../InternPool.zig");
1249const Liveness = @import("../../Liveness.zig");1277const Liveness = @import("../../Liveness.zig");
1250const Zcu = @import("../../Zcu.zig");1278const Zcu = @import("../../Zcu.zig");
1251/// Deprecated.
1252const Module = Zcu;
1253const StringTable = @import("../StringTable.zig");1279const StringTable = @import("../StringTable.zig");
1254const Symbol = @import("Symbol.zig");1280const Symbol = @import("Symbol.zig");
1255const Type = @import("../../Type.zig");1281const Type = @import("../../Type.zig");
src/main.zig+42-4
...@@ -172,7 +172,7 @@ pub fn main() anyerror!void {...@@ -172,7 +172,7 @@ pub fn main() anyerror!void {
172 }172 }
173 // We would prefer to use raw libc allocator here, but cannot173 // We would prefer to use raw libc allocator here, but cannot
174 // use it if it won't support the alignment we need.174 // use it if it won't support the alignment we need.
175 if (@alignOf(std.c.max_align_t) < @alignOf(i128)) {175 if (@alignOf(std.c.max_align_t) < @max(@alignOf(i128), std.atomic.cache_line)) {
176 break :gpa std.heap.c_allocator;176 break :gpa std.heap.c_allocator;
177 }177 }
178 break :gpa std.heap.raw_c_allocator;178 break :gpa std.heap.raw_c_allocator;
...@@ -403,6 +403,7 @@ const usage_build_generic =...@@ -403,6 +403,7 @@ const usage_build_generic =
403 \\General Options:403 \\General Options:
404 \\ -h, --help Print this help and exit404 \\ -h, --help Print this help and exit
405 \\ --color [auto|off|on] Enable or disable colored error messages405 \\ --color [auto|off|on] Enable or disable colored error messages
406 \\ -j<N> Limit concurrent jobs (default is to use all CPU cores)
406 \\ -femit-bin[=path] (default) Output machine code407 \\ -femit-bin[=path] (default) Output machine code
407 \\ -fno-emit-bin Do not output machine code408 \\ -fno-emit-bin Do not output machine code
408 \\ -femit-asm[=path] Output .s (assembly code)409 \\ -femit-asm[=path] Output .s (assembly code)
...@@ -1004,6 +1005,7 @@ fn buildOutputType(...@@ -1004,6 +1005,7 @@ fn buildOutputType(
1004 .on1005 .on
1005 else1006 else
1006 .auto;1007 .auto;
1008 var n_jobs: ?u32 = null;
10071009
1008 switch (arg_mode) {1010 switch (arg_mode) {
1009 .build, .translate_c, .zig_test, .run => {1011 .build, .translate_c, .zig_test, .run => {
...@@ -1141,6 +1143,17 @@ fn buildOutputType(...@@ -1141,6 +1143,17 @@ fn buildOutputType(
1141 color = std.meta.stringToEnum(Color, next_arg) orelse {1143 color = std.meta.stringToEnum(Color, next_arg) orelse {
1142 fatal("expected [auto|on|off] after --color, found '{s}'", .{next_arg});1144 fatal("expected [auto|on|off] after --color, found '{s}'", .{next_arg});
1143 };1145 };
1146 } else if (mem.startsWith(u8, arg, "-j")) {
1147 const str = arg["-j".len..];
1148 const num = std.fmt.parseUnsigned(u32, str, 10) catch |err| {
1149 fatal("unable to parse jobs count '{s}': {s}", .{
1150 str, @errorName(err),
1151 });
1152 };
1153 if (num < 1) {
1154 fatal("number of jobs must be at least 1\n", .{});
1155 }
1156 n_jobs = num;
1144 } else if (mem.eql(u8, arg, "--subsystem")) {1157 } else if (mem.eql(u8, arg, "--subsystem")) {
1145 subsystem = try parseSubSystem(args_iter.nextOrFatal());1158 subsystem = try parseSubSystem(args_iter.nextOrFatal());
1146 } else if (mem.eql(u8, arg, "-O")) {1159 } else if (mem.eql(u8, arg, "-O")) {
...@@ -3092,7 +3105,11 @@ fn buildOutputType(...@@ -3092,7 +3105,11 @@ fn buildOutputType(
3092 defer emit_implib_resolved.deinit();3105 defer emit_implib_resolved.deinit();
30933106
3094 var thread_pool: ThreadPool = undefined;3107 var thread_pool: ThreadPool = undefined;
3095 try thread_pool.init(.{ .allocator = gpa });3108 try thread_pool.init(.{
3109 .allocator = gpa,
3110 .n_jobs = @min(@max(n_jobs orelse std.Thread.getCpuCount() catch 1, 1), std.math.maxInt(u8)),
3111 .track_ids = true,
3112 });
3096 defer thread_pool.deinit();3113 defer thread_pool.deinit();
30973114
3098 var cleanup_local_cache_dir: ?fs.Dir = null;3115 var cleanup_local_cache_dir: ?fs.Dir = null;
...@@ -4644,6 +4661,7 @@ const usage_build =...@@ -4644,6 +4661,7 @@ const usage_build =
4644 \\ all Print the build summary in its entirety4661 \\ all Print the build summary in its entirety
4645 \\ failures (Default) Only print failed steps4662 \\ failures (Default) Only print failed steps
4646 \\ none Do not print the build summary4663 \\ none Do not print the build summary
4664 \\ -j<N> Limit concurrent jobs (default is to use all CPU cores)
4647 \\ --build-file [file] Override path to build.zig4665 \\ --build-file [file] Override path to build.zig
4648 \\ --cache-dir [path] Override path to local Zig cache directory4666 \\ --cache-dir [path] Override path to local Zig cache directory
4649 \\ --global-cache-dir [path] Override path to global Zig cache directory4667 \\ --global-cache-dir [path] Override path to global Zig cache directory
...@@ -4718,6 +4736,7 @@ fn cmdBuild(gpa: Allocator, arena: Allocator, args: []const []const u8) !void {...@@ -4718,6 +4736,7 @@ fn cmdBuild(gpa: Allocator, arena: Allocator, args: []const []const u8) !void {
4718 try child_argv.append("-Z" ++ results_tmp_file_nonce);4736 try child_argv.append("-Z" ++ results_tmp_file_nonce);
47194737
4720 var color: Color = .auto;4738 var color: Color = .auto;
4739 var n_jobs: ?u32 = null;
47214740
4722 {4741 {
4723 var i: usize = 0;4742 var i: usize = 0;
...@@ -4811,6 +4830,17 @@ fn cmdBuild(gpa: Allocator, arena: Allocator, args: []const []const u8) !void {...@@ -4811,6 +4830,17 @@ fn cmdBuild(gpa: Allocator, arena: Allocator, args: []const []const u8) !void {
4811 };4830 };
4812 try child_argv.appendSlice(&.{ arg, args[i] });4831 try child_argv.appendSlice(&.{ arg, args[i] });
4813 continue;4832 continue;
4833 } else if (mem.startsWith(u8, arg, "-j")) {
4834 const str = arg["-j".len..];
4835 const num = std.fmt.parseUnsigned(u32, str, 10) catch |err| {
4836 fatal("unable to parse jobs count '{s}': {s}", .{
4837 str, @errorName(err),
4838 });
4839 };
4840 if (num < 1) {
4841 fatal("number of jobs must be at least 1\n", .{});
4842 }
4843 n_jobs = num;
4814 } else if (mem.eql(u8, arg, "--seed")) {4844 } else if (mem.eql(u8, arg, "--seed")) {
4815 if (i + 1 >= args.len) fatal("expected argument after '{s}'", .{arg});4845 if (i + 1 >= args.len) fatal("expected argument after '{s}'", .{arg});
4816 i += 1;4846 i += 1;
...@@ -4895,7 +4925,11 @@ fn cmdBuild(gpa: Allocator, arena: Allocator, args: []const []const u8) !void {...@@ -4895,7 +4925,11 @@ fn cmdBuild(gpa: Allocator, arena: Allocator, args: []const []const u8) !void {
4895 child_argv.items[argv_index_cache_dir] = local_cache_directory.path orelse cwd_path;4925 child_argv.items[argv_index_cache_dir] = local_cache_directory.path orelse cwd_path;
48964926
4897 var thread_pool: ThreadPool = undefined;4927 var thread_pool: ThreadPool = undefined;
4898 try thread_pool.init(.{ .allocator = gpa });4928 try thread_pool.init(.{
4929 .allocator = gpa,
4930 .n_jobs = @min(@max(n_jobs orelse std.Thread.getCpuCount() catch 1, 1), std.math.maxInt(u8)),
4931 .track_ids = true,
4932 });
4899 defer thread_pool.deinit();4933 defer thread_pool.deinit();
49004934
4901 // Dummy http client that is not actually used when only_core_functionality is enabled.4935 // Dummy http client that is not actually used when only_core_functionality is enabled.
...@@ -5329,7 +5363,11 @@ fn jitCmd(...@@ -5329,7 +5363,11 @@ fn jitCmd(
5329 defer global_cache_directory.handle.close();5363 defer global_cache_directory.handle.close();
53305364
5331 var thread_pool: ThreadPool = undefined;5365 var thread_pool: ThreadPool = undefined;
5332 try thread_pool.init(.{ .allocator = gpa });5366 try thread_pool.init(.{
5367 .allocator = gpa,
5368 .n_jobs = @min(@max(std.Thread.getCpuCount() catch 1, 1), std.math.maxInt(u8)),
5369 .track_ids = true,
5370 });
5333 defer thread_pool.deinit();5371 defer thread_pool.deinit();
53345372
5335 var child_argv: std.ArrayListUnmanaged([]const u8) = .{};5373 var child_argv: std.ArrayListUnmanaged([]const u8) = .{};
src/mutable_value.zig+48-52
...@@ -54,46 +54,44 @@ pub const MutableValue = union(enum) {...@@ -54,46 +54,44 @@ pub const MutableValue = union(enum) {
54 payload: *MutableValue,54 payload: *MutableValue,
55 };55 };
5656
57 pub fn intern(mv: MutableValue, zcu: *Zcu, arena: Allocator) Allocator.Error!Value {57 pub fn intern(mv: MutableValue, pt: Zcu.PerThread, arena: Allocator) Allocator.Error!Value {
58 const ip = &zcu.intern_pool;
59 const gpa = zcu.gpa;
60 return Value.fromInterned(switch (mv) {58 return Value.fromInterned(switch (mv) {
61 .interned => |ip_index| ip_index,59 .interned => |ip_index| ip_index,
62 .eu_payload => |sv| try ip.get(gpa, .{ .error_union = .{60 .eu_payload => |sv| try pt.intern(.{ .error_union = .{
63 .ty = sv.ty,61 .ty = sv.ty,
64 .val = .{ .payload = (try sv.child.intern(zcu, arena)).toIntern() },62 .val = .{ .payload = (try sv.child.intern(pt, arena)).toIntern() },
65 } }),63 } }),
66 .opt_payload => |sv| try ip.get(gpa, .{ .opt = .{64 .opt_payload => |sv| try pt.intern(.{ .opt = .{
67 .ty = sv.ty,65 .ty = sv.ty,
68 .val = (try sv.child.intern(zcu, arena)).toIntern(),66 .val = (try sv.child.intern(pt, arena)).toIntern(),
69 } }),67 } }),
70 .repeated => |sv| try ip.get(gpa, .{ .aggregate = .{68 .repeated => |sv| try pt.intern(.{ .aggregate = .{
71 .ty = sv.ty,69 .ty = sv.ty,
72 .storage = .{ .repeated_elem = (try sv.child.intern(zcu, arena)).toIntern() },70 .storage = .{ .repeated_elem = (try sv.child.intern(pt, arena)).toIntern() },
73 } }),71 } }),
74 .bytes => |b| try ip.get(gpa, .{ .aggregate = .{72 .bytes => |b| try pt.intern(.{ .aggregate = .{
75 .ty = b.ty,73 .ty = b.ty,
76 .storage = .{ .bytes = try ip.getOrPutString(gpa, b.data, .maybe_embedded_nulls) },74 .storage = .{ .bytes = try pt.zcu.intern_pool.getOrPutString(pt.zcu.gpa, pt.tid, b.data, .maybe_embedded_nulls) },
77 } }),75 } }),
78 .aggregate => |a| {76 .aggregate => |a| {
79 const elems = try arena.alloc(InternPool.Index, a.elems.len);77 const elems = try arena.alloc(InternPool.Index, a.elems.len);
80 for (a.elems, elems) |mut_elem, *interned_elem| {78 for (a.elems, elems) |mut_elem, *interned_elem| {
81 interned_elem.* = (try mut_elem.intern(zcu, arena)).toIntern();79 interned_elem.* = (try mut_elem.intern(pt, arena)).toIntern();
82 }80 }
83 return Value.fromInterned(try ip.get(gpa, .{ .aggregate = .{81 return Value.fromInterned(try pt.intern(.{ .aggregate = .{
84 .ty = a.ty,82 .ty = a.ty,
85 .storage = .{ .elems = elems },83 .storage = .{ .elems = elems },
86 } }));84 } }));
87 },85 },
88 .slice => |s| try ip.get(gpa, .{ .slice = .{86 .slice => |s| try pt.intern(.{ .slice = .{
89 .ty = s.ty,87 .ty = s.ty,
90 .ptr = (try s.ptr.intern(zcu, arena)).toIntern(),88 .ptr = (try s.ptr.intern(pt, arena)).toIntern(),
91 .len = (try s.len.intern(zcu, arena)).toIntern(),89 .len = (try s.len.intern(pt, arena)).toIntern(),
92 } }),90 } }),
93 .un => |u| try ip.get(gpa, .{ .un = .{91 .un => |u| try pt.intern(.{ .un = .{
94 .ty = u.ty,92 .ty = u.ty,
95 .tag = u.tag,93 .tag = u.tag,
96 .val = (try u.payload.intern(zcu, arena)).toIntern(),94 .val = (try u.payload.intern(pt, arena)).toIntern(),
97 } }),95 } }),
98 });96 });
99 }97 }
...@@ -108,13 +106,13 @@ pub const MutableValue = union(enum) {...@@ -108,13 +106,13 @@ pub const MutableValue = union(enum) {
108 /// If `!allow_repeated`, the `repeated` representation will not be used.106 /// If `!allow_repeated`, the `repeated` representation will not be used.
109 pub fn unintern(107 pub fn unintern(
110 mv: *MutableValue,108 mv: *MutableValue,
111 zcu: *Zcu,109 pt: Zcu.PerThread,
112 arena: Allocator,110 arena: Allocator,
113 allow_bytes: bool,111 allow_bytes: bool,
114 allow_repeated: bool,112 allow_repeated: bool,
115 ) Allocator.Error!void {113 ) Allocator.Error!void {
114 const zcu = pt.zcu;
116 const ip = &zcu.intern_pool;115 const ip = &zcu.intern_pool;
117 const gpa = zcu.gpa;
118 switch (mv.*) {116 switch (mv.*) {
119 .interned => |ip_index| switch (ip.indexToKey(ip_index)) {117 .interned => |ip_index| switch (ip.indexToKey(ip_index)) {
120 .opt => |opt| if (opt.val != .none) {118 .opt => |opt| if (opt.val != .none) {
...@@ -170,7 +168,7 @@ pub const MutableValue = union(enum) {...@@ -170,7 +168,7 @@ pub const MutableValue = union(enum) {
170 } else {168 } else {
171 const mut_elems = try arena.alloc(MutableValue, len);169 const mut_elems = try arena.alloc(MutableValue, len);
172 for (bytes.toSlice(len, ip), mut_elems) |b, *mut_elem| {170 for (bytes.toSlice(len, ip), mut_elems) |b, *mut_elem| {
173 mut_elem.* = .{ .interned = try ip.get(gpa, .{ .int = .{171 mut_elem.* = .{ .interned = try pt.intern(.{ .int = .{
174 .ty = .u8_type,172 .ty = .u8_type,
175 .storage = .{ .u64 = b },173 .storage = .{ .u64 = b },
176 } }) };174 } }) };
...@@ -221,12 +219,12 @@ pub const MutableValue = union(enum) {...@@ -221,12 +219,12 @@ pub const MutableValue = union(enum) {
221 switch (type_tag) {219 switch (type_tag) {
222 .Array, .Vector => {220 .Array, .Vector => {
223 const elem_ty = ip.childType(ty_ip);221 const elem_ty = ip.childType(ty_ip);
224 const undef_elem = try ip.get(gpa, .{ .undef = elem_ty });222 const undef_elem = try pt.intern(.{ .undef = elem_ty });
225 @memset(elems[0..@intCast(len_no_sent)], .{ .interned = undef_elem });223 @memset(elems[0..@intCast(len_no_sent)], .{ .interned = undef_elem });
226 },224 },
227 .Struct => for (elems[0..@intCast(len_no_sent)], 0..) |*mut_elem, i| {225 .Struct => for (elems[0..@intCast(len_no_sent)], 0..) |*mut_elem, i| {
228 const field_ty = ty.structFieldType(i, zcu).toIntern();226 const field_ty = ty.structFieldType(i, zcu).toIntern();
229 mut_elem.* = .{ .interned = try ip.get(gpa, .{ .undef = field_ty }) };227 mut_elem.* = .{ .interned = try pt.intern(.{ .undef = field_ty }) };
230 },228 },
231 else => unreachable,229 else => unreachable,
232 }230 }
...@@ -238,7 +236,7 @@ pub const MutableValue = union(enum) {...@@ -238,7 +236,7 @@ pub const MutableValue = union(enum) {
238 } else {236 } else {
239 const repeated_val = try arena.create(MutableValue);237 const repeated_val = try arena.create(MutableValue);
240 repeated_val.* = .{238 repeated_val.* = .{
241 .interned = try ip.get(gpa, .{ .undef = ip.childType(ty_ip) }),239 .interned = try pt.intern(.{ .undef = ip.childType(ty_ip) }),
242 };240 };
243 mv.* = .{ .repeated = .{241 mv.* = .{ .repeated = .{
244 .ty = ty_ip,242 .ty = ty_ip,
...@@ -248,11 +246,8 @@ pub const MutableValue = union(enum) {...@@ -248,11 +246,8 @@ pub const MutableValue = union(enum) {
248 },246 },
249 .Union => {247 .Union => {
250 const payload = try arena.create(MutableValue);248 const payload = try arena.create(MutableValue);
251 const backing_ty = try Type.fromInterned(ty_ip).unionBackingType(zcu);249 const backing_ty = try Type.fromInterned(ty_ip).unionBackingType(pt);
252 payload.* = .{ .interned = try ip.get(250 payload.* = .{ .interned = try pt.intern(.{ .undef = backing_ty.toIntern() }) };
253 gpa,
254 .{ .undef = backing_ty.toIntern() },
255 ) };
256 mv.* = .{ .un = .{251 mv.* = .{ .un = .{
257 .ty = ty_ip,252 .ty = ty_ip,
258 .tag = .none,253 .tag = .none,
...@@ -264,8 +259,8 @@ pub const MutableValue = union(enum) {...@@ -264,8 +259,8 @@ pub const MutableValue = union(enum) {
264 if (ptr_ty.flags.size != .Slice) return;259 if (ptr_ty.flags.size != .Slice) return;
265 const ptr = try arena.create(MutableValue);260 const ptr = try arena.create(MutableValue);
266 const len = try arena.create(MutableValue);261 const len = try arena.create(MutableValue);
267 ptr.* = .{ .interned = try ip.get(gpa, .{ .undef = ip.slicePtrType(ty_ip) }) };262 ptr.* = .{ .interned = try pt.intern(.{ .undef = ip.slicePtrType(ty_ip) }) };
268 len.* = .{ .interned = try ip.get(gpa, .{ .undef = .usize_type }) };263 len.* = .{ .interned = try pt.intern(.{ .undef = .usize_type }) };
269 mv.* = .{ .slice = .{264 mv.* = .{ .slice = .{
270 .ty = ty_ip,265 .ty = ty_ip,
271 .ptr = ptr,266 .ptr = ptr,
...@@ -279,7 +274,7 @@ pub const MutableValue = union(enum) {...@@ -279,7 +274,7 @@ pub const MutableValue = union(enum) {
279 .bytes => |bytes| if (!allow_bytes) {274 .bytes => |bytes| if (!allow_bytes) {
280 const elems = try arena.alloc(MutableValue, bytes.data.len);275 const elems = try arena.alloc(MutableValue, bytes.data.len);
281 for (bytes.data, elems) |byte, *interned_byte| {276 for (bytes.data, elems) |byte, *interned_byte| {
282 interned_byte.* = .{ .interned = try ip.get(gpa, .{ .int = .{277 interned_byte.* = .{ .interned = try pt.intern(.{ .int = .{
283 .ty = .u8_type,278 .ty = .u8_type,
284 .storage = .{ .u64 = byte },279 .storage = .{ .u64 = byte },
285 } }) };280 } }) };
...@@ -298,22 +293,22 @@ pub const MutableValue = union(enum) {...@@ -298,22 +293,22 @@ pub const MutableValue = union(enum) {
298 /// The returned pointer is valid until the representation of `mv` changes.293 /// The returned pointer is valid until the representation of `mv` changes.
299 pub fn elem(294 pub fn elem(
300 mv: *MutableValue,295 mv: *MutableValue,
301 zcu: *Zcu,296 pt: Zcu.PerThread,
302 arena: Allocator,297 arena: Allocator,
303 field_idx: usize,298 field_idx: usize,
304 ) Allocator.Error!*MutableValue {299 ) Allocator.Error!*MutableValue {
300 const zcu = pt.zcu;
305 const ip = &zcu.intern_pool;301 const ip = &zcu.intern_pool;
306 const gpa = zcu.gpa;
307 // Convert to the `aggregate` representation.302 // Convert to the `aggregate` representation.
308 switch (mv.*) {303 switch (mv.*) {
309 .eu_payload, .opt_payload, .un => unreachable,304 .eu_payload, .opt_payload, .un => unreachable,
310 .interned => {305 .interned => {
311 try mv.unintern(zcu, arena, false, false);306 try mv.unintern(pt, arena, false, false);
312 },307 },
313 .bytes => |bytes| {308 .bytes => |bytes| {
314 const elems = try arena.alloc(MutableValue, bytes.data.len);309 const elems = try arena.alloc(MutableValue, bytes.data.len);
315 for (bytes.data, elems) |byte, *interned_byte| {310 for (bytes.data, elems) |byte, *interned_byte| {
316 interned_byte.* = .{ .interned = try ip.get(gpa, .{ .int = .{311 interned_byte.* = .{ .interned = try pt.intern(.{ .int = .{
317 .ty = .u8_type,312 .ty = .u8_type,
318 .storage = .{ .u64 = byte },313 .storage = .{ .u64 = byte },
319 } }) };314 } }) };
...@@ -351,14 +346,15 @@ pub const MutableValue = union(enum) {...@@ -351,14 +346,15 @@ pub const MutableValue = union(enum) {
351 /// For slices, uses `Value.slice_ptr_index` and `Value.slice_len_index`.346 /// For slices, uses `Value.slice_ptr_index` and `Value.slice_len_index`.
352 pub fn setElem(347 pub fn setElem(
353 mv: *MutableValue,348 mv: *MutableValue,
354 zcu: *Zcu,349 pt: Zcu.PerThread,
355 arena: Allocator,350 arena: Allocator,
356 field_idx: usize,351 field_idx: usize,
357 field_val: MutableValue,352 field_val: MutableValue,
358 ) Allocator.Error!void {353 ) Allocator.Error!void {
354 const zcu = pt.zcu;
359 const ip = &zcu.intern_pool;355 const ip = &zcu.intern_pool;
360 const is_trivial_int = field_val.isTrivialInt(zcu);356 const is_trivial_int = field_val.isTrivialInt(zcu);
361 try mv.unintern(zcu, arena, is_trivial_int, true);357 try mv.unintern(pt, arena, is_trivial_int, true);
362 switch (mv.*) {358 switch (mv.*) {
363 .interned,359 .interned,
364 .eu_payload,360 .eu_payload,
...@@ -373,7 +369,7 @@ pub const MutableValue = union(enum) {...@@ -373,7 +369,7 @@ pub const MutableValue = union(enum) {
373 .bytes => |b| {369 .bytes => |b| {
374 assert(is_trivial_int);370 assert(is_trivial_int);
375 assert(field_val.typeOf(zcu).toIntern() == .u8_type);371 assert(field_val.typeOf(zcu).toIntern() == .u8_type);
376 b.data[field_idx] = @intCast(Value.fromInterned(field_val.interned).toUnsignedInt(zcu));372 b.data[field_idx] = @intCast(Value.fromInterned(field_val.interned).toUnsignedInt(pt));
377 },373 },
378 .repeated => |r| {374 .repeated => |r| {
379 if (field_val.eqlTrivial(r.child.*)) return;375 if (field_val.eqlTrivial(r.child.*)) return;
...@@ -386,9 +382,9 @@ pub const MutableValue = union(enum) {...@@ -386,9 +382,9 @@ pub const MutableValue = union(enum) {
386 {382 {
387 // We can use the `bytes` representation.383 // We can use the `bytes` representation.
388 const bytes = try arena.alloc(u8, @intCast(len_inc_sent));384 const bytes = try arena.alloc(u8, @intCast(len_inc_sent));
389 const repeated_byte = Value.fromInterned(r.child.interned).toUnsignedInt(zcu);385 const repeated_byte = Value.fromInterned(r.child.interned).toUnsignedInt(pt);
390 @memset(bytes, @intCast(repeated_byte));386 @memset(bytes, @intCast(repeated_byte));
391 bytes[field_idx] = @intCast(Value.fromInterned(field_val.interned).toUnsignedInt(zcu));387 bytes[field_idx] = @intCast(Value.fromInterned(field_val.interned).toUnsignedInt(pt));
392 mv.* = .{ .bytes = .{388 mv.* = .{ .bytes = .{
393 .ty = r.ty,389 .ty = r.ty,
394 .data = bytes,390 .data = bytes,
...@@ -435,7 +431,7 @@ pub const MutableValue = union(enum) {...@@ -435,7 +431,7 @@ pub const MutableValue = union(enum) {
435 } else {431 } else {
436 const bytes = try arena.alloc(u8, a.elems.len);432 const bytes = try arena.alloc(u8, a.elems.len);
437 for (a.elems, bytes) |elem_val, *b| {433 for (a.elems, bytes) |elem_val, *b| {
438 b.* = @intCast(Value.fromInterned(elem_val.interned).toUnsignedInt(zcu));434 b.* = @intCast(Value.fromInterned(elem_val.interned).toUnsignedInt(pt));
439 }435 }
440 mv.* = .{ .bytes = .{436 mv.* = .{ .bytes = .{
441 .ty = a.ty,437 .ty = a.ty,
...@@ -451,7 +447,7 @@ pub const MutableValue = union(enum) {...@@ -451,7 +447,7 @@ pub const MutableValue = union(enum) {
451 /// For slices, uses `Value.slice_ptr_index` and `Value.slice_len_index`.447 /// For slices, uses `Value.slice_ptr_index` and `Value.slice_len_index`.
452 pub fn getElem(448 pub fn getElem(
453 mv: MutableValue,449 mv: MutableValue,
454 zcu: *Zcu,450 pt: Zcu.PerThread,
455 field_idx: usize,451 field_idx: usize,
456 ) Allocator.Error!MutableValue {452 ) Allocator.Error!MutableValue {
457 return switch (mv) {453 return switch (mv) {
...@@ -459,16 +455,16 @@ pub const MutableValue = union(enum) {...@@ -459,16 +455,16 @@ pub const MutableValue = union(enum) {
459 .opt_payload,455 .opt_payload,
460 => unreachable,456 => unreachable,
461 .interned => |ip_index| {457 .interned => |ip_index| {
462 const ty = Type.fromInterned(zcu.intern_pool.typeOf(ip_index));458 const ty = Type.fromInterned(pt.zcu.intern_pool.typeOf(ip_index));
463 switch (ty.zigTypeTag(zcu)) {459 switch (ty.zigTypeTag(pt.zcu)) {
464 .Array, .Vector => return .{ .interned = (try Value.fromInterned(ip_index).elemValue(zcu, field_idx)).toIntern() },460 .Array, .Vector => return .{ .interned = (try Value.fromInterned(ip_index).elemValue(pt, field_idx)).toIntern() },
465 .Struct, .Union => return .{ .interned = (try Value.fromInterned(ip_index).fieldValue(zcu, field_idx)).toIntern() },461 .Struct, .Union => return .{ .interned = (try Value.fromInterned(ip_index).fieldValue(pt, field_idx)).toIntern() },
466 .Pointer => {462 .Pointer => {
467 assert(ty.isSlice(zcu));463 assert(ty.isSlice(pt.zcu));
468 return switch (field_idx) {464 return switch (field_idx) {
469 Value.slice_ptr_index => .{ .interned = Value.fromInterned(ip_index).slicePtr(zcu).toIntern() },465 Value.slice_ptr_index => .{ .interned = Value.fromInterned(ip_index).slicePtr(pt.zcu).toIntern() },
470 Value.slice_len_index => .{ .interned = switch (zcu.intern_pool.indexToKey(ip_index)) {466 Value.slice_len_index => .{ .interned = switch (pt.zcu.intern_pool.indexToKey(ip_index)) {
471 .undef => try zcu.intern(.{ .undef = .usize_type }),467 .undef => try pt.intern(.{ .undef = .usize_type }),
472 .slice => |s| s.len,468 .slice => |s| s.len,
473 else => unreachable,469 else => unreachable,
474 } },470 } },
...@@ -487,7 +483,7 @@ pub const MutableValue = union(enum) {...@@ -487,7 +483,7 @@ pub const MutableValue = union(enum) {
487 Value.slice_len_index => s.len.*,483 Value.slice_len_index => s.len.*,
488 else => unreachable,484 else => unreachable,
489 },485 },
490 .bytes => |b| .{ .interned = try zcu.intern(.{ .int = .{486 .bytes => |b| .{ .interned = try pt.intern(.{ .int = .{
491 .ty = .u8_type,487 .ty = .u8_type,
492 .storage = .{ .u64 = b.data[field_idx] },488 .storage = .{ .u64 = b.data[field_idx] },
493 } }) },489 } }) },
src/print_air.zig+19-19
...@@ -9,7 +9,7 @@ const Air = @import("Air.zig");...@@ -9,7 +9,7 @@ const Air = @import("Air.zig");
9const Liveness = @import("Liveness.zig");9const Liveness = @import("Liveness.zig");
10const InternPool = @import("InternPool.zig");10const InternPool = @import("InternPool.zig");
1111
12pub fn write(stream: anytype, module: *Zcu, air: Air, liveness: ?Liveness) void {12pub fn write(stream: anytype, pt: Zcu.PerThread, air: Air, liveness: ?Liveness) void {
13 const instruction_bytes = air.instructions.len *13 const instruction_bytes = air.instructions.len *
14 // Here we don't use @sizeOf(Air.Inst.Data) because it would include14 // Here we don't use @sizeOf(Air.Inst.Data) because it would include
15 // the debug safety tag but we want to measure release size.15 // the debug safety tag but we want to measure release size.
...@@ -42,8 +42,8 @@ pub fn write(stream: anytype, module: *Zcu, air: Air, liveness: ?Liveness) void...@@ -42,8 +42,8 @@ pub fn write(stream: anytype, module: *Zcu, air: Air, liveness: ?Liveness) void
42 // zig fmt: on42 // zig fmt: on
4343
44 var writer: Writer = .{44 var writer: Writer = .{
45 .module = module,45 .pt = pt,
46 .gpa = module.gpa,46 .gpa = pt.zcu.gpa,
47 .air = air,47 .air = air,
48 .liveness = liveness,48 .liveness = liveness,
49 .indent = 2,49 .indent = 2,
...@@ -55,13 +55,13 @@ pub fn write(stream: anytype, module: *Zcu, air: Air, liveness: ?Liveness) void...@@ -55,13 +55,13 @@ pub fn write(stream: anytype, module: *Zcu, air: Air, liveness: ?Liveness) void
55pub fn writeInst(55pub fn writeInst(
56 stream: anytype,56 stream: anytype,
57 inst: Air.Inst.Index,57 inst: Air.Inst.Index,
58 module: *Zcu,58 pt: Zcu.PerThread,
59 air: Air,59 air: Air,
60 liveness: ?Liveness,60 liveness: ?Liveness,
61) void {61) void {
62 var writer: Writer = .{62 var writer: Writer = .{
63 .module = module,63 .pt = pt,
64 .gpa = module.gpa,64 .gpa = pt.zcu.gpa,
65 .air = air,65 .air = air,
66 .liveness = liveness,66 .liveness = liveness,
67 .indent = 2,67 .indent = 2,
...@@ -70,16 +70,16 @@ pub fn writeInst(...@@ -70,16 +70,16 @@ pub fn writeInst(
70 writer.writeInst(stream, inst) catch return;70 writer.writeInst(stream, inst) catch return;
71}71}
7272
73pub fn dump(module: *Zcu, air: Air, liveness: ?Liveness) void {73pub fn dump(pt: Zcu.PerThread, air: Air, liveness: ?Liveness) void {
74 write(std.io.getStdErr().writer(), module, air, liveness);74 write(std.io.getStdErr().writer(), pt, air, liveness);
75}75}
7676
77pub fn dumpInst(inst: Air.Inst.Index, module: *Zcu, air: Air, liveness: ?Liveness) void {77pub fn dumpInst(inst: Air.Inst.Index, pt: Zcu.PerThread, air: Air, liveness: ?Liveness) void {
78 writeInst(std.io.getStdErr().writer(), inst, module, air, liveness);78 writeInst(std.io.getStdErr().writer(), inst, pt, air, liveness);
79}79}
8080
81const Writer = struct {81const Writer = struct {
82 module: *Zcu,82 pt: Zcu.PerThread,
83 gpa: Allocator,83 gpa: Allocator,
84 air: Air,84 air: Air,
85 liveness: ?Liveness,85 liveness: ?Liveness,
...@@ -345,7 +345,7 @@ const Writer = struct {...@@ -345,7 +345,7 @@ const Writer = struct {
345 }345 }
346346
347 fn writeType(w: *Writer, s: anytype, ty: Type) !void {347 fn writeType(w: *Writer, s: anytype, ty: Type) !void {
348 return ty.print(s, w.module);348 return ty.print(s, w.pt);
349 }349 }
350350
351 fn writeTy(w: *Writer, s: anytype, inst: Air.Inst.Index) @TypeOf(s).Error!void {351 fn writeTy(w: *Writer, s: anytype, inst: Air.Inst.Index) @TypeOf(s).Error!void {
...@@ -424,7 +424,7 @@ const Writer = struct {...@@ -424,7 +424,7 @@ const Writer = struct {
424 }424 }
425425
426 fn writeAggregateInit(w: *Writer, s: anytype, inst: Air.Inst.Index) @TypeOf(s).Error!void {426 fn writeAggregateInit(w: *Writer, s: anytype, inst: Air.Inst.Index) @TypeOf(s).Error!void {
427 const mod = w.module;427 const mod = w.pt.zcu;
428 const ty_pl = w.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;428 const ty_pl = w.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
429 const vector_ty = ty_pl.ty.toType();429 const vector_ty = ty_pl.ty.toType();
430 const len = @as(usize, @intCast(vector_ty.arrayLen(mod)));430 const len = @as(usize, @intCast(vector_ty.arrayLen(mod)));
...@@ -504,7 +504,7 @@ const Writer = struct {...@@ -504,7 +504,7 @@ const Writer = struct {
504 }504 }
505505
506 fn writeSelect(w: *Writer, s: anytype, inst: Air.Inst.Index) @TypeOf(s).Error!void {506 fn writeSelect(w: *Writer, s: anytype, inst: Air.Inst.Index) @TypeOf(s).Error!void {
507 const mod = w.module;507 const mod = w.pt.zcu;
508 const pl_op = w.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;508 const pl_op = w.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;
509 const extra = w.air.extraData(Air.Bin, pl_op.payload).data;509 const extra = w.air.extraData(Air.Bin, pl_op.payload).data;
510510
...@@ -947,11 +947,11 @@ const Writer = struct {...@@ -947,11 +947,11 @@ const Writer = struct {
947 if (@intFromEnum(operand) < InternPool.static_len) {947 if (@intFromEnum(operand) < InternPool.static_len) {
948 return s.print("@{}", .{operand});948 return s.print("@{}", .{operand});
949 } else if (operand.toInterned()) |ip_index| {949 } else if (operand.toInterned()) |ip_index| {
950 const mod = w.module;950 const pt = w.pt;
951 const ty = Type.fromInterned(mod.intern_pool.indexToKey(ip_index).typeOf());951 const ty = Type.fromInterned(pt.zcu.intern_pool.indexToKey(ip_index).typeOf());
952 try s.print("<{}, {}>", .{952 try s.print("<{}, {}>", .{
953 ty.fmt(mod),953 ty.fmt(pt),
954 Value.fromInterned(ip_index).fmtValue(mod, null),954 Value.fromInterned(ip_index).fmtValue(pt, null),
955 });955 });
956 } else {956 } else {
957 return w.writeInstIndex(s, operand.toIndex().?, dies);957 return w.writeInstIndex(s, operand.toIndex().?, dies);
...@@ -970,7 +970,7 @@ const Writer = struct {...@@ -970,7 +970,7 @@ const Writer = struct {
970 }970 }
971971
972 fn typeOfIndex(w: *Writer, inst: Air.Inst.Index) Type {972 fn typeOfIndex(w: *Writer, inst: Air.Inst.Index) Type {
973 const mod = w.module;973 const mod = w.pt.zcu;
974 return w.air.typeOfIndex(inst, &mod.intern_pool);974 return w.air.typeOfIndex(inst, &mod.intern_pool);
975 }975 }
976};976};
src/print_value.zig+53-52
...@@ -5,8 +5,6 @@ const std = @import("std");...@@ -5,8 +5,6 @@ const std = @import("std");
5const Type = @import("Type.zig");5const Type = @import("Type.zig");
6const Value = @import("Value.zig");6const Value = @import("Value.zig");
7const Zcu = @import("Zcu.zig");7const Zcu = @import("Zcu.zig");
8/// Deprecated.
9const Module = Zcu;
10const Sema = @import("Sema.zig");8const Sema = @import("Sema.zig");
11const InternPool = @import("InternPool.zig");9const InternPool = @import("InternPool.zig");
12const Allocator = std.mem.Allocator;10const Allocator = std.mem.Allocator;
...@@ -17,7 +15,7 @@ const max_string_len = 256;...@@ -17,7 +15,7 @@ const max_string_len = 256;
1715
18pub const FormatContext = struct {16pub const FormatContext = struct {
19 val: Value,17 val: Value,
20 mod: *Module,18 pt: Zcu.PerThread,
21 opt_sema: ?*Sema,19 opt_sema: ?*Sema,
22 depth: u8,20 depth: u8,
23};21};
...@@ -30,7 +28,7 @@ pub fn format(...@@ -30,7 +28,7 @@ pub fn format(
30) !void {28) !void {
31 _ = options;29 _ = options;
32 comptime std.debug.assert(fmt.len == 0);30 comptime std.debug.assert(fmt.len == 0);
33 return print(ctx.val, writer, ctx.depth, ctx.mod, ctx.opt_sema) catch |err| switch (err) {31 return print(ctx.val, writer, ctx.depth, ctx.pt, ctx.opt_sema) catch |err| switch (err) {
34 error.OutOfMemory => @panic("OOM"), // We're not allowed to return this from a format function32 error.OutOfMemory => @panic("OOM"), // We're not allowed to return this from a format function
35 error.ComptimeBreak, error.ComptimeReturn => unreachable,33 error.ComptimeBreak, error.ComptimeReturn => unreachable,
36 error.AnalysisFail => unreachable, // TODO: re-evaluate when we use `opt_sema` more fully34 error.AnalysisFail => unreachable, // TODO: re-evaluate when we use `opt_sema` more fully
...@@ -42,10 +40,11 @@ pub fn print(...@@ -42,10 +40,11 @@ pub fn print(
42 val: Value,40 val: Value,
43 writer: anytype,41 writer: anytype,
44 level: u8,42 level: u8,
45 mod: *Module,43 pt: Zcu.PerThread,
46 /// If this `Sema` is provided, we will recurse through pointers where possible to provide friendly output.44 /// If this `Sema` is provided, we will recurse through pointers where possible to provide friendly output.
47 opt_sema: ?*Sema,45 opt_sema: ?*Sema,
48) (@TypeOf(writer).Error || Module.CompileError)!void {46) (@TypeOf(writer).Error || Zcu.CompileError)!void {
47 const mod = pt.zcu;
49 const ip = &mod.intern_pool;48 const ip = &mod.intern_pool;
50 switch (ip.indexToKey(val.toIntern())) {49 switch (ip.indexToKey(val.toIntern())) {
51 .int_type,50 .int_type,
...@@ -64,7 +63,7 @@ pub fn print(...@@ -64,7 +63,7 @@ pub fn print(
64 .func_type,63 .func_type,
65 .error_set_type,64 .error_set_type,
66 .inferred_error_set_type,65 .inferred_error_set_type,
67 => try Type.print(val.toType(), writer, mod),66 => try Type.print(val.toType(), writer, pt),
68 .undef => try writer.writeAll("undefined"),67 .undef => try writer.writeAll("undefined"),
69 .simple_value => |simple_value| switch (simple_value) {68 .simple_value => |simple_value| switch (simple_value) {
70 .void => try writer.writeAll("{}"),69 .void => try writer.writeAll("{}"),
...@@ -82,13 +81,13 @@ pub fn print(...@@ -82,13 +81,13 @@ pub fn print(
82 .int => |int| switch (int.storage) {81 .int => |int| switch (int.storage) {
83 inline .u64, .i64, .big_int => |x| try writer.print("{}", .{x}),82 inline .u64, .i64, .big_int => |x| try writer.print("{}", .{x}),
84 .lazy_align => |ty| if (opt_sema != null) {83 .lazy_align => |ty| if (opt_sema != null) {
85 const a = (try Type.fromInterned(ty).abiAlignmentAdvanced(mod, .sema)).scalar;84 const a = (try Type.fromInterned(ty).abiAlignmentAdvanced(pt, .sema)).scalar;
86 try writer.print("{}", .{a.toByteUnits() orelse 0});85 try writer.print("{}", .{a.toByteUnits() orelse 0});
87 } else try writer.print("@alignOf({})", .{Type.fromInterned(ty).fmt(mod)}),86 } else try writer.print("@alignOf({})", .{Type.fromInterned(ty).fmt(pt)}),
88 .lazy_size => |ty| if (opt_sema != null) {87 .lazy_size => |ty| if (opt_sema != null) {
89 const s = (try Type.fromInterned(ty).abiSizeAdvanced(mod, .sema)).scalar;88 const s = (try Type.fromInterned(ty).abiSizeAdvanced(pt, .sema)).scalar;
90 try writer.print("{}", .{s});89 try writer.print("{}", .{s});
91 } else try writer.print("@sizeOf({})", .{Type.fromInterned(ty).fmt(mod)}),90 } else try writer.print("@sizeOf({})", .{Type.fromInterned(ty).fmt(pt)}),
92 },91 },
93 .err => |err| try writer.print("error.{}", .{92 .err => |err| try writer.print("error.{}", .{
94 err.name.fmt(ip),93 err.name.fmt(ip),
...@@ -97,7 +96,7 @@ pub fn print(...@@ -97,7 +96,7 @@ pub fn print(
97 .err_name => |err_name| try writer.print("error.{}", .{96 .err_name => |err_name| try writer.print("error.{}", .{
98 err_name.fmt(ip),97 err_name.fmt(ip),
99 }),98 }),
100 .payload => |payload| try print(Value.fromInterned(payload), writer, level, mod, opt_sema),99 .payload => |payload| try print(Value.fromInterned(payload), writer, level, pt, opt_sema),
101 },100 },
102 .enum_literal => |enum_literal| try writer.print(".{}", .{101 .enum_literal => |enum_literal| try writer.print(".{}", .{
103 enum_literal.fmt(ip),102 enum_literal.fmt(ip),
...@@ -111,7 +110,7 @@ pub fn print(...@@ -111,7 +110,7 @@ pub fn print(
111 return writer.writeAll("@enumFromInt(...)");110 return writer.writeAll("@enumFromInt(...)");
112 }111 }
113 try writer.writeAll("@enumFromInt(");112 try writer.writeAll("@enumFromInt(");
114 try print(Value.fromInterned(enum_tag.int), writer, level - 1, mod, opt_sema);113 try print(Value.fromInterned(enum_tag.int), writer, level - 1, pt, opt_sema);
115 try writer.writeAll(")");114 try writer.writeAll(")");
116 },115 },
117 .empty_enum_value => try writer.writeAll("(empty enum value)"),116 .empty_enum_value => try writer.writeAll("(empty enum value)"),
...@@ -128,12 +127,12 @@ pub fn print(...@@ -128,12 +127,12 @@ pub fn print(
128 // TODO: eventually we want to load the slice as an array with `opt_sema`, but that's127 // TODO: eventually we want to load the slice as an array with `opt_sema`, but that's
129 // currently not possible without e.g. triggering compile errors.128 // currently not possible without e.g. triggering compile errors.
130 }129 }
131 try printPtr(Value.fromInterned(slice.ptr), writer, level, mod, opt_sema);130 try printPtr(Value.fromInterned(slice.ptr), writer, level, pt, opt_sema);
132 try writer.writeAll("[0..");131 try writer.writeAll("[0..");
133 if (level == 0) {132 if (level == 0) {
134 try writer.writeAll("(...)");133 try writer.writeAll("(...)");
135 } else {134 } else {
136 try print(Value.fromInterned(slice.len), writer, level - 1, mod, opt_sema);135 try print(Value.fromInterned(slice.len), writer, level - 1, pt, opt_sema);
137 }136 }
138 try writer.writeAll("]");137 try writer.writeAll("]");
139 },138 },
...@@ -147,28 +146,28 @@ pub fn print(...@@ -147,28 +146,28 @@ pub fn print(
147 // TODO: eventually we want to load the pointer with `opt_sema`, but that's146 // TODO: eventually we want to load the pointer with `opt_sema`, but that's
148 // currently not possible without e.g. triggering compile errors.147 // currently not possible without e.g. triggering compile errors.
149 }148 }
150 try printPtr(val, writer, level, mod, opt_sema);149 try printPtr(val, writer, level, pt, opt_sema);
151 },150 },
152 .opt => |opt| switch (opt.val) {151 .opt => |opt| switch (opt.val) {
153 .none => try writer.writeAll("null"),152 .none => try writer.writeAll("null"),
154 else => |payload| try print(Value.fromInterned(payload), writer, level, mod, opt_sema),153 else => |payload| try print(Value.fromInterned(payload), writer, level, pt, opt_sema),
155 },154 },
156 .aggregate => |aggregate| try printAggregate(val, aggregate, false, writer, level, mod, opt_sema),155 .aggregate => |aggregate| try printAggregate(val, aggregate, false, writer, level, pt, opt_sema),
157 .un => |un| {156 .un => |un| {
158 if (level == 0) {157 if (level == 0) {
159 try writer.writeAll(".{ ... }");158 try writer.writeAll(".{ ... }");
160 return;159 return;
161 }160 }
162 if (un.tag == .none) {161 if (un.tag == .none) {
163 const backing_ty = try val.typeOf(mod).unionBackingType(mod);162 const backing_ty = try val.typeOf(mod).unionBackingType(pt);
164 try writer.print("@bitCast(@as({}, ", .{backing_ty.fmt(mod)});163 try writer.print("@bitCast(@as({}, ", .{backing_ty.fmt(pt)});
165 try print(Value.fromInterned(un.val), writer, level - 1, mod, opt_sema);164 try print(Value.fromInterned(un.val), writer, level - 1, pt, opt_sema);
166 try writer.writeAll("))");165 try writer.writeAll("))");
167 } else {166 } else {
168 try writer.writeAll(".{ ");167 try writer.writeAll(".{ ");
169 try print(Value.fromInterned(un.tag), writer, level - 1, mod, opt_sema);168 try print(Value.fromInterned(un.tag), writer, level - 1, pt, opt_sema);
170 try writer.writeAll(" = ");169 try writer.writeAll(" = ");
171 try print(Value.fromInterned(un.val), writer, level - 1, mod, opt_sema);170 try print(Value.fromInterned(un.val), writer, level - 1, pt, opt_sema);
172 try writer.writeAll(" }");171 try writer.writeAll(" }");
173 }172 }
174 },173 },
...@@ -182,13 +181,14 @@ fn printAggregate(...@@ -182,13 +181,14 @@ fn printAggregate(
182 is_ref: bool,181 is_ref: bool,
183 writer: anytype,182 writer: anytype,
184 level: u8,183 level: u8,
185 zcu: *Zcu,184 pt: Zcu.PerThread,
186 opt_sema: ?*Sema,185 opt_sema: ?*Sema,
187) (@TypeOf(writer).Error || Module.CompileError)!void {186) (@TypeOf(writer).Error || Zcu.CompileError)!void {
188 if (level == 0) {187 if (level == 0) {
189 if (is_ref) try writer.writeByte('&');188 if (is_ref) try writer.writeByte('&');
190 return writer.writeAll(".{ ... }");189 return writer.writeAll(".{ ... }");
191 }190 }
191 const zcu = pt.zcu;
192 const ip = &zcu.intern_pool;192 const ip = &zcu.intern_pool;
193 const ty = Type.fromInterned(aggregate.ty);193 const ty = Type.fromInterned(aggregate.ty);
194 switch (ty.zigTypeTag(zcu)) {194 switch (ty.zigTypeTag(zcu)) {
...@@ -203,7 +203,7 @@ fn printAggregate(...@@ -203,7 +203,7 @@ fn printAggregate(
203 if (i != 0) try writer.writeAll(", ");203 if (i != 0) try writer.writeAll(", ");
204 const field_name = ty.structFieldName(@intCast(i), zcu).unwrap().?;204 const field_name = ty.structFieldName(@intCast(i), zcu).unwrap().?;
205 try writer.print(".{i} = ", .{field_name.fmt(ip)});205 try writer.print(".{i} = ", .{field_name.fmt(ip)});
206 try print(try val.fieldValue(zcu, i), writer, level - 1, zcu, opt_sema);206 try print(try val.fieldValue(pt, i), writer, level - 1, pt, opt_sema);
207 }207 }
208 try writer.writeAll(" }");208 try writer.writeAll(" }");
209 return;209 return;
...@@ -230,7 +230,7 @@ fn printAggregate(...@@ -230,7 +230,7 @@ fn printAggregate(
230 if (ty.childType(zcu).toIntern() != .u8_type) break :one_byte_str;230 if (ty.childType(zcu).toIntern() != .u8_type) break :one_byte_str;
231 const elem_val = Value.fromInterned(aggregate.storage.values()[0]);231 const elem_val = Value.fromInterned(aggregate.storage.values()[0]);
232 if (elem_val.isUndef(zcu)) break :one_byte_str;232 if (elem_val.isUndef(zcu)) break :one_byte_str;
233 const byte = elem_val.toUnsignedInt(zcu);233 const byte = elem_val.toUnsignedInt(pt);
234 try writer.print("\"{}\"", .{std.zig.fmtEscapes(&.{@intCast(byte)})});234 try writer.print("\"{}\"", .{std.zig.fmtEscapes(&.{@intCast(byte)})});
235 if (!is_ref) try writer.writeAll(".*");235 if (!is_ref) try writer.writeAll(".*");
236 return;236 return;
...@@ -253,7 +253,7 @@ fn printAggregate(...@@ -253,7 +253,7 @@ fn printAggregate(
253 const max_len = @min(len, max_aggregate_items);253 const max_len = @min(len, max_aggregate_items);
254 for (0..max_len) |i| {254 for (0..max_len) |i| {
255 if (i != 0) try writer.writeAll(", ");255 if (i != 0) try writer.writeAll(", ");
256 try print(try val.fieldValue(zcu, i), writer, level - 1, zcu, opt_sema);256 try print(try val.fieldValue(pt, i), writer, level - 1, pt, opt_sema);
257 }257 }
258 if (len > max_aggregate_items) {258 if (len > max_aggregate_items) {
259 try writer.writeAll(", ...");259 try writer.writeAll(", ...");
...@@ -261,8 +261,8 @@ fn printAggregate(...@@ -261,8 +261,8 @@ fn printAggregate(
261 return writer.writeAll(" }");261 return writer.writeAll(" }");
262}262}
263263
264fn printPtr(ptr_val: Value, writer: anytype, level: u8, zcu: *Zcu, opt_sema: ?*Sema) (@TypeOf(writer).Error || Module.CompileError)!void {264fn printPtr(ptr_val: Value, writer: anytype, level: u8, pt: Zcu.PerThread, opt_sema: ?*Sema) (@TypeOf(writer).Error || Zcu.CompileError)!void {
265 const ptr = switch (zcu.intern_pool.indexToKey(ptr_val.toIntern())) {265 const ptr = switch (pt.zcu.intern_pool.indexToKey(ptr_val.toIntern())) {
266 .undef => return writer.writeAll("undefined"),266 .undef => return writer.writeAll("undefined"),
267 .ptr => |ptr| ptr,267 .ptr => |ptr| ptr,
268 else => unreachable,268 else => unreachable,
...@@ -270,32 +270,33 @@ fn printPtr(ptr_val: Value, writer: anytype, level: u8, zcu: *Zcu, opt_sema: ?*S...@@ -270,32 +270,33 @@ fn printPtr(ptr_val: Value, writer: anytype, level: u8, zcu: *Zcu, opt_sema: ?*S
270270
271 if (ptr.base_addr == .anon_decl) {271 if (ptr.base_addr == .anon_decl) {
272 // If the value is an aggregate, we can potentially print it more nicely.272 // If the value is an aggregate, we can potentially print it more nicely.
273 switch (zcu.intern_pool.indexToKey(ptr.base_addr.anon_decl.val)) {273 switch (pt.zcu.intern_pool.indexToKey(ptr.base_addr.anon_decl.val)) {
274 .aggregate => |agg| return printAggregate(274 .aggregate => |agg| return printAggregate(
275 Value.fromInterned(ptr.base_addr.anon_decl.val),275 Value.fromInterned(ptr.base_addr.anon_decl.val),
276 agg,276 agg,
277 true,277 true,
278 writer,278 writer,
279 level,279 level,
280 zcu,280 pt,
281 opt_sema,281 opt_sema,
282 ),282 ),
283 else => {},283 else => {},
284 }284 }
285 }285 }
286286
287 var arena = std.heap.ArenaAllocator.init(zcu.gpa);287 var arena = std.heap.ArenaAllocator.init(pt.zcu.gpa);
288 defer arena.deinit();288 defer arena.deinit();
289 const derivation = try ptr_val.pointerDerivationAdvanced(arena.allocator(), zcu, opt_sema);289 const derivation = try ptr_val.pointerDerivationAdvanced(arena.allocator(), pt, opt_sema);
290 try printPtrDerivation(derivation, writer, level, zcu, opt_sema);290 try printPtrDerivation(derivation, writer, level, pt, opt_sema);
291}291}
292292
293/// Print `derivation` as an lvalue, i.e. such that writing `&` before this gives the pointer value.293/// Print `derivation` as an lvalue, i.e. such that writing `&` before this gives the pointer value.
294fn printPtrDerivation(derivation: Value.PointerDeriveStep, writer: anytype, level: u8, zcu: *Zcu, opt_sema: ?*Sema) (@TypeOf(writer).Error || Module.CompileError)!void {294fn printPtrDerivation(derivation: Value.PointerDeriveStep, writer: anytype, level: u8, pt: Zcu.PerThread, opt_sema: ?*Sema) (@TypeOf(writer).Error || Zcu.CompileError)!void {
295 const zcu = pt.zcu;
295 const ip = &zcu.intern_pool;296 const ip = &zcu.intern_pool;
296 switch (derivation) {297 switch (derivation) {
297 .int => |int| try writer.print("@as({}, @ptrFromInt({x})).*", .{298 .int => |int| try writer.print("@as({}, @ptrFromInt({x})).*", .{
298 int.ptr_ty.fmt(zcu),299 int.ptr_ty.fmt(pt),
299 int.addr,300 int.addr,
300 }),301 }),
301 .decl_ptr => |decl| {302 .decl_ptr => |decl| {
...@@ -303,33 +304,33 @@ fn printPtrDerivation(derivation: Value.PointerDeriveStep, writer: anytype, leve...@@ -303,33 +304,33 @@ fn printPtrDerivation(derivation: Value.PointerDeriveStep, writer: anytype, leve
303 },304 },
304 .anon_decl_ptr => |anon| {305 .anon_decl_ptr => |anon| {
305 const ty = Value.fromInterned(anon.val).typeOf(zcu);306 const ty = Value.fromInterned(anon.val).typeOf(zcu);
306 try writer.print("@as({}, ", .{ty.fmt(zcu)});307 try writer.print("@as({}, ", .{ty.fmt(pt)});
307 try print(Value.fromInterned(anon.val), writer, level - 1, zcu, opt_sema);308 try print(Value.fromInterned(anon.val), writer, level - 1, pt, opt_sema);
308 try writer.writeByte(')');309 try writer.writeByte(')');
309 },310 },
310 .comptime_alloc_ptr => |info| {311 .comptime_alloc_ptr => |info| {
311 try writer.print("@as({}, ", .{info.val.typeOf(zcu).fmt(zcu)});312 try writer.print("@as({}, ", .{info.val.typeOf(zcu).fmt(pt)});
312 try print(info.val, writer, level - 1, zcu, opt_sema);313 try print(info.val, writer, level - 1, pt, opt_sema);
313 try writer.writeByte(')');314 try writer.writeByte(')');
314 },315 },
315 .comptime_field_ptr => |val| {316 .comptime_field_ptr => |val| {
316 const ty = val.typeOf(zcu);317 const ty = val.typeOf(zcu);
317 try writer.print("@as({}, ", .{ty.fmt(zcu)});318 try writer.print("@as({}, ", .{ty.fmt(pt)});
318 try print(val, writer, level - 1, zcu, opt_sema);319 try print(val, writer, level - 1, pt, opt_sema);
319 try writer.writeByte(')');320 try writer.writeByte(')');
320 },321 },
321 .eu_payload_ptr => |info| {322 .eu_payload_ptr => |info| {
322 try writer.writeByte('(');323 try writer.writeByte('(');
323 try printPtrDerivation(info.parent.*, writer, level, zcu, opt_sema);324 try printPtrDerivation(info.parent.*, writer, level, pt, opt_sema);
324 try writer.writeAll(" catch unreachable)");325 try writer.writeAll(" catch unreachable)");
325 },326 },
326 .opt_payload_ptr => |info| {327 .opt_payload_ptr => |info| {
327 try printPtrDerivation(info.parent.*, writer, level, zcu, opt_sema);328 try printPtrDerivation(info.parent.*, writer, level, pt, opt_sema);
328 try writer.writeAll(".?");329 try writer.writeAll(".?");
329 },330 },
330 .field_ptr => |field| {331 .field_ptr => |field| {
331 try printPtrDerivation(field.parent.*, writer, level, zcu, opt_sema);332 try printPtrDerivation(field.parent.*, writer, level, pt, opt_sema);
332 const agg_ty = (try field.parent.ptrType(zcu)).childType(zcu);333 const agg_ty = (try field.parent.ptrType(pt)).childType(zcu);
333 switch (agg_ty.zigTypeTag(zcu)) {334 switch (agg_ty.zigTypeTag(zcu)) {
334 .Struct => if (agg_ty.structFieldName(field.field_idx, zcu).unwrap()) |field_name| {335 .Struct => if (agg_ty.structFieldName(field.field_idx, zcu).unwrap()) |field_name| {
335 try writer.print(".{i}", .{field_name.fmt(ip)});336 try writer.print(".{i}", .{field_name.fmt(ip)});
...@@ -350,16 +351,16 @@ fn printPtrDerivation(derivation: Value.PointerDeriveStep, writer: anytype, leve...@@ -350,16 +351,16 @@ fn printPtrDerivation(derivation: Value.PointerDeriveStep, writer: anytype, leve
350 }351 }
351 },352 },
352 .elem_ptr => |elem| {353 .elem_ptr => |elem| {
353 try printPtrDerivation(elem.parent.*, writer, level, zcu, opt_sema);354 try printPtrDerivation(elem.parent.*, writer, level, pt, opt_sema);
354 try writer.print("[{d}]", .{elem.elem_idx});355 try writer.print("[{d}]", .{elem.elem_idx});
355 },356 },
356 .offset_and_cast => |oac| if (oac.byte_offset == 0) {357 .offset_and_cast => |oac| if (oac.byte_offset == 0) {
357 try writer.print("@as({}, @ptrCast(", .{oac.new_ptr_ty.fmt(zcu)});358 try writer.print("@as({}, @ptrCast(", .{oac.new_ptr_ty.fmt(pt)});
358 try printPtrDerivation(oac.parent.*, writer, level, zcu, opt_sema);359 try printPtrDerivation(oac.parent.*, writer, level, pt, opt_sema);
359 try writer.writeAll("))");360 try writer.writeAll("))");
360 } else {361 } else {
361 try writer.print("@as({}, @ptrFromInt(@intFromPtr(", .{oac.new_ptr_ty.fmt(zcu)});362 try writer.print("@as({}, @ptrFromInt(@intFromPtr(", .{oac.new_ptr_ty.fmt(pt)});
362 try printPtrDerivation(oac.parent.*, writer, level, zcu, opt_sema);363 try printPtrDerivation(oac.parent.*, writer, level, pt, opt_sema);
363 try writer.print(") + {d}))", .{oac.byte_offset});364 try writer.print(") + {d}))", .{oac.byte_offset});
364 },365 },
365 }366 }
src/print_zir.zig+4-5
...@@ -7,13 +7,12 @@ const InternPool = @import("InternPool.zig");...@@ -7,13 +7,12 @@ const InternPool = @import("InternPool.zig");
77
8const Zir = std.zig.Zir;8const Zir = std.zig.Zir;
9const Zcu = @import("Zcu.zig");9const Zcu = @import("Zcu.zig");
10const Module = Zcu;
11const LazySrcLoc = Zcu.LazySrcLoc;10const LazySrcLoc = Zcu.LazySrcLoc;
1211
13/// Write human-readable, debug formatted ZIR code to a file.12/// Write human-readable, debug formatted ZIR code to a file.
14pub fn renderAsTextToFile(13pub fn renderAsTextToFile(
15 gpa: Allocator,14 gpa: Allocator,
16 scope_file: *Module.File,15 scope_file: *Zcu.File,
17 fs_file: std.fs.File,16 fs_file: std.fs.File,
18) !void {17) !void {
19 var arena = std.heap.ArenaAllocator.init(gpa);18 var arena = std.heap.ArenaAllocator.init(gpa);
...@@ -64,7 +63,7 @@ pub fn renderInstructionContext(...@@ -64,7 +63,7 @@ pub fn renderInstructionContext(
64 gpa: Allocator,63 gpa: Allocator,
65 block: []const Zir.Inst.Index,64 block: []const Zir.Inst.Index,
66 block_index: usize,65 block_index: usize,
67 scope_file: *Module.File,66 scope_file: *Zcu.File,
68 parent_decl_node: Ast.Node.Index,67 parent_decl_node: Ast.Node.Index,
69 indent: u32,68 indent: u32,
70 stream: anytype,69 stream: anytype,
...@@ -96,7 +95,7 @@ pub fn renderInstructionContext(...@@ -96,7 +95,7 @@ pub fn renderInstructionContext(
96pub fn renderSingleInstruction(95pub fn renderSingleInstruction(
97 gpa: Allocator,96 gpa: Allocator,
98 inst: Zir.Inst.Index,97 inst: Zir.Inst.Index,
99 scope_file: *Module.File,98 scope_file: *Zcu.File,
100 parent_decl_node: Ast.Node.Index,99 parent_decl_node: Ast.Node.Index,
101 indent: u32,100 indent: u32,
102 stream: anytype,101 stream: anytype,
...@@ -122,7 +121,7 @@ pub fn renderSingleInstruction(...@@ -122,7 +121,7 @@ pub fn renderSingleInstruction(
122const Writer = struct {121const Writer = struct {
123 gpa: Allocator,122 gpa: Allocator,
124 arena: Allocator,123 arena: Allocator,
125 file: *Module.File,124 file: *Zcu.File,
126 code: Zir,125 code: Zir,
127 indent: u32,126 indent: u32,
128 parent_decl_node: Ast.Node.Index,127 parent_decl_node: Ast.Node.Index,
src/register_manager.zig-2
...@@ -7,8 +7,6 @@ const Air = @import("Air.zig");...@@ -7,8 +7,6 @@ const Air = @import("Air.zig");
7const StaticBitSet = std.bit_set.StaticBitSet;7const StaticBitSet = std.bit_set.StaticBitSet;
8const Type = @import("Type.zig");8const Type = @import("Type.zig");
9const Zcu = @import("Zcu.zig");9const Zcu = @import("Zcu.zig");
10/// Deprecated.
11const Module = Zcu;
12const expect = std.testing.expect;10const expect = std.testing.expect;
13const expectEqual = std.testing.expectEqual;11const expectEqual = std.testing.expectEqual;
14const expectEqualSlices = std.testing.expectEqualSlices;12const expectEqualSlices = std.testing.expectEqualSlices;
src/target.zig+36-14
...@@ -537,20 +537,42 @@ pub fn zigBackend(target: std.Target, use_llvm: bool) std.builtin.CompilerBacken...@@ -537,20 +537,42 @@ pub fn zigBackend(target: std.Target, use_llvm: bool) std.builtin.CompilerBacken
537 };537 };
538}538}
539539
540pub fn backendSupportsFeature(540pub inline fn backendSupportsFeature(backend: std.builtin.CompilerBackend, comptime feature: Feature) bool {
541 cpu_arch: std.Target.Cpu.Arch,
542 ofmt: std.Target.ObjectFormat,
543 use_llvm: bool,
544 feature: Feature,
545) bool {
546 return switch (feature) {541 return switch (feature) {
547 .panic_fn => ofmt == .c or use_llvm or cpu_arch == .x86_64 or cpu_arch == .riscv64,542 .panic_fn => switch (backend) {
548 .panic_unwrap_error => ofmt == .c or use_llvm,543 .stage2_c, .stage2_llvm, .stage2_x86_64, .stage2_riscv64 => true,
549 .safety_check_formatted => ofmt == .c or use_llvm,544 else => false,
550 .error_return_trace => use_llvm,545 },
551 .is_named_enum_value => use_llvm,546 .panic_unwrap_error => switch (backend) {
552 .error_set_has_value => use_llvm or cpu_arch.isWasm(),547 .stage2_c, .stage2_llvm => true,
553 .field_reordering => ofmt == .c or use_llvm,548 else => false,
554 .safety_checked_instructions => use_llvm,549 },
550 .safety_check_formatted => switch (backend) {
551 .stage2_c, .stage2_llvm => true,
552 else => false,
553 },
554 .error_return_trace => switch (backend) {
555 .stage2_llvm => true,
556 else => false,
557 },
558 .is_named_enum_value => switch (backend) {
559 .stage2_llvm => true,
560 else => false,
561 },
562 .error_set_has_value => switch (backend) {
563 .stage2_llvm, .stage2_wasm => true,
564 else => false,
565 },
566 .field_reordering => switch (backend) {
567 .stage2_c, .stage2_llvm => true,
568 else => false,
569 },
570 .safety_checked_instructions => switch (backend) {
571 .stage2_llvm => true,
572 else => false,
573 },
574 .separate_thread => switch (backend) {
575 else => false,
576 },
555 };577 };
556}578}